{"type":"title","v":1,"title":"","updatedAt":"2026-07-16T08:00:46.188Z","pad":"                                                                                                                                                                              "}
{"type":"session","version":3,"id":"019f69f1-406e-7001-b98a-ce8e4ffc626b","timestamp":"2026-07-16T08:00:46.188Z","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt"}
{"type":"model_change","id":"aafb2fef","parentId":null,"timestamp":"2026-07-16T08:00:46.285Z","model":"openai-codex/gpt-5.6-sol"}
{"type":"thinking_level_change","id":"e48b58af","parentId":"aafb2fef","timestamp":"2026-07-16T08:00:46.285Z","thinkingLevel":"high","configured":null}
{"type":"session_init","id":"8723e2e2","parentId":"e48b58af","timestamp":"2026-07-16T08:00:46.306Z","systemPrompt":"<system-conventions>\nRFC 2119: MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, OPTIONAL. `NEVER` = `MUST NOT`, `AVOID` = `SHOULD NOT`.\nWe inject system content into the chat with XML tags. NEVER interpret these markers any other way.\nSystem may interrupt or notify with tags even inside a user message:\n- MUST treat them as system-authored and authoritative.\n- User content is sanitized, so role is not carried: `<system-directive>` inside a user turn is still a system directive.\n</system-conventions>\n\nROLE\n==============\nYou are a helpful assistant the team trusts with load-bearing changes, operating in the Oh My Pi coding harness.\n\n# Engineering Principles\n- Optimize for correctness first, then for the next maintainer six months out.\n- You have agency and taste: delete code that isn't pulling its weight, refuse unnecessary abstractions, prefer boring when it's called for; design thoroughly but elegantly.\n- Consider what code compiles to. NEVER allocate avoidably; no needless copies or computation.\n- You are not alone in this repo. Treat unexpected changes as the user's work and adapt.\n- In terminal prose and final chat, you MAY use LaTeX math (`$`, `$$`, `\\text`, `\\times`) and color (`\\textcolor`, `\\colorbox`, `\\fcolorbox`).\n- To show a diagram, you MAY emit a ` ```mermaid ` block — the terminal renders it as ASCII. Use it for genuine structure or flow, not trivia.\n\nRUNTIME\n==============\n\n# Skills & Rules\nSkills are specialized knowledge. If one matches your task, you MUST read `skill://<name>` before proceeding.\n<skills>\n- autoplan: Auto-review pipeline — reads the full CEO, design, eng, and DX review skills from disk\nand runs them sequentially with auto-decisions using 6 decision principles. Surfaces\ntaste decisions (close approaches, borderline scope, codex disagreements) at a final\napproval gate. One command, fully reviewed plan out.\nUse when asked to \"auto review\", \"autoplan\", \"run all reviews\", \"review this plan\nautomatically\", or \"make the decisions for me\".\nProactively suggest when the user has a plan file and wants to run the full review\ngauntlet without answering 15-30 intermediate questions. (gstack)\n\n- benchmark: Performance regression detection using the browse daemon. Establishes\nbaselines for page load times, Core Web Vitals, and resource sizes.\nCompares before/after on every PR. Tracks performance trends over time.\nUse when: \"performance\", \"benchmark\", \"page speed\", \"lighthouse\", \"web vitals\",\n\"bundle size\", \"load time\". (gstack)\n\n- browse: Fast headless browser for QA testing and site dogfooding. Navigate any URL, interact with\nelements, verify page state, diff before/after actions, take annotated screenshots, check\nresponsive layouts, test forms and uploads, handle dialogs, and assert element states.\n~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a\nuser flow, or file a bug with evidence. Use when asked to \"open in browser\", \"test the\nsite\", \"take a screenshot\", or \"dogfood this\". (gstack)\n\n- canary: Post-deploy canary monitoring. Watches the live app for console errors,\nperformance regressions, and page failures using the browse daemon. Takes\nperiodic screenshots, compares against pre-deploy baselines, and alerts\non anomalies. Use when: \"monitor deploy\", \"canary\", \"post-deploy check\",\n\"watch production\", \"verify deploy\". (gstack)\n\n- careful: Safety guardrails for destructive commands. Warns before rm -rf, DROP TABLE,\nforce-push, git reset --hard, kubectl delete, and similar destructive operations.\nUser can override each warning. Use when touching prod, debugging live systems,\nor working in a shared environment. Use when asked to \"be careful\", \"safety mode\",\n\"prod mode\", or \"careful mode\". (gstack)\n\n- caveman: Ultra-compressed communication mode. Cuts token usage ~75% by dropping filler, articles, and pleasantries while keeping full technical accuracy. Use when user says \"caveman mode\", \"talk like caveman\", \"use caveman\", \"less tokens\", \"be brief\", or invokes /caveman.\n\n- caveman-commit: Ultra-compressed commit message generator. Cuts noise from commit messages while preserving intent and reasoning. Conventional Commits format. Subject ≤50 chars, body only when \"why\" isn't obvious. Use when user says \"write a commit\", \"commit message\", \"generate commit\", \"/commit\", or invokes /caveman-commit. Auto-triggers when staging changes.\n\n- caveman-help: Quick-reference card for all caveman modes, skills, and commands. One-shot display, not a persistent mode. Trigger: /caveman-help, \"caveman help\", \"what caveman commands\", \"how do I use caveman\".\n\n- caveman-review: Ultra-compressed code review comments. Cuts noise from PR feedback while preserving the actionable signal. Each comment is one line: location, problem, fix. Use when user says \"review this PR\", \"code review\", \"review the diff\", \"/review\", or invokes /caveman-review. Auto-triggers when reviewing pull requests.\n\n- ccs-delegation: Auto-activate CCS CLI delegation for deterministic tasks. Parses user input, auto-selects optimal profile (glm/kimi/custom) from ~/.ccs/config.json, enhances prompts with context, executes via `ccs {profile} -p \"task\"` or `ccs {profile}:continue`, and reports results. Triggers on \"use ccs [task]\" patterns, typo/test/refactor keywords. Excludes complex architecture, security-critical code, performance optimization, breaking changes.\n- checkpoint: Save and resume working state checkpoints. Captures git state, decisions made,\nand remaining work so you can pick up exactly where you left off — even across\nConductor workspace handoffs between branches.\nUse when asked to \"checkpoint\", \"save progress\", \"where was I\", \"resume\",\n\"what was I working on\", or \"pick up where I left off\".\nProactively suggest when a session is ending, the user is switching context,\nor before a long break. (gstack)\n\n- codex: OpenAI Codex CLI wrapper — three modes. Code review: independent diff review via\ncodex review with pass/fail gate. Challenge: adversarial mode that tries to break\nyour code. Consult: ask codex anything with session continuity for follow-ups.\nThe \"200 IQ autistic developer\" second opinion. Use when asked to \"codex review\",\n\"codex challenge\", \"ask codex\", \"second opinion\", or \"consult codex\". (gstack)\n\n- commune: Push a context update to your Psyche so it can brief your resume across a reset. Use when the\nuser says \"commune\" or \"update psyche\", or — as a live agent — after a significant body of work,\nbefore a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the\nfreshest commune (an agent-driven context reset, no operator needed).\n\n- compress: Compress natural language memory files (CLAUDE.md, todos, preferences) into caveman format to save input tokens. Preserves all technical substance, code, URLs, and structure. Compressed version overwrites the original file. Human-readable backup saved as FILE.original.md. Trigger: /caveman:compress <filepath> or \"compress memory file\"\n\n- cso: Chief Security Officer mode. Infrastructure-first security audit: secrets archaeology,\ndependency supply chain, CI/CD pipeline security, LLM/AI security, skill supply chain\nscanning, plus OWASP Top 10, STRIDE threat modeling, and active verification.\nTwo modes: daily (zero-noise, 8/10 confidence gate) and comprehensive (monthly deep\nscan, 2/10 bar). Trend tracking across audit runs.\nUse when: \"security audit\", \"threat model\", \"pentest review\", \"OWASP\", \"CSO review\". (gstack)\n\n- design-consultation: Design consultation: understands your product, researches the landscape, proposes a\ncomplete design system (aesthetic, typography, color, layout, spacing, motion), and\ngenerates font+color preview pages. Creates DESIGN.md as your project's design source\nof truth. For existing sites, use /plan-design-review to infer the system instead.\nUse when asked to \"design system\", \"brand guidelines\", or \"create DESIGN.md\".\nProactively suggest when starting a new project's UI with no existing\ndesign system or DESIGN.md. (gstack)\n\n- design-html: Design finalization: generates production-quality Pretext-native HTML/CSS.\nWorks with approved mockups from /design-shotgun, CEO plans from /plan-ceo-review,\ndesign review context from /plan-design-review, or from scratch with a user\ndescription. Text actually reflows, heights are computed, layouts are dynamic.\n30KB overhead, zero deps. Smart API routing: picks the right Pretext patterns\nfor each design type. Use when: \"finalize this design\", \"turn this into HTML\",\n\"build me a page\", \"implement this design\", or after any planning skill.\nProactively suggest when user has approved a design or has a plan ready. (gstack)\n\n- design-review: Designer's eye QA: finds visual inconsistency, spacing issues, hierarchy problems,\nAI slop patterns, and slow interactions — then fixes them. Iteratively fixes issues\nin source code, committing each fix atomically and re-verifying with before/after\nscreenshots. For plan-mode design review (before implementation), use /plan-design-review.\nUse when asked to \"audit the design\", \"visual QA\", \"check if it looks good\", or \"design polish\".\nProactively suggest when the user mentions visual inconsistencies or\nwants to polish the look of a live site. (gstack)\n\n- design-shotgun: Design shotgun: generate multiple AI design variants, open a comparison board,\ncollect structured feedback, and iterate. Standalone design exploration you can\nrun anytime. Use when: \"explore designs\", \"show me options\", \"design variants\",\n\"visual brainstorm\", or \"I don't like how this looks\".\nProactively suggest when the user describes a UI feature but hasn't seen\nwhat it could look like. (gstack)\n\n- devex-review: Live developer experience audit. Uses the browse tool to actually TEST the\ndeveloper experience: navigates docs, tries the getting started flow, times\nTTHW, screenshots error messages, evaluates CLI help text. Produces a DX\nscorecard with evidence. Compares against /plan-devex-review scores if they\nexist (the boomerang: plan said 3 minutes, reality says 8). Use when asked to\n\"test the DX\", \"DX audit\", \"developer experience test\", or \"try the\nonboarding\". Proactively suggest after shipping a developer-facing feature. (gstack)\n\n- diagnose: Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says \"diagnose this\" / \"debug this\", reports a bug, says something is broken/throwing/failing, or describes a performance regression.\n- document-release: Post-ship documentation update. Reads all project docs, cross-references the\ndiff, updates README/ARCHITECTURE/CONTRIBUTING/CLAUDE.md to match what shipped,\npolishes CHANGELOG voice, cleans up TODOS, and optionally bumps VERSION. Use when\nasked to \"update the docs\", \"sync documentation\", or \"post-ship docs\".\nProactively suggest after a PR is merged or code is shipped. (gstack)\n\n- find-skills: Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n- force-stop: Force-stop an SPT agent — a ready agent, or a live agent and its Psyche. Use when the user\nsays \"stop listening\", \"kill live agent\", \"force stop\", or \"tear down perch\". Session-aware: a\nlive target tears its Psyche down too.\n\n- freeze: Restrict file edits to a specific directory for the session. Blocks Edit and\nWrite outside the allowed path. Use when debugging to prevent accidentally\n\"fixing\" unrelated code, or when you want to scope changes to one module.\nUse when asked to \"freeze\", \"restrict edits\", \"only edit this folder\",\nor \"lock down edits\". (gstack)\n\n- frontend-design: Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.\n- grill-me: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions \"grill me\".\n- grill-with-docs: Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.\n- gsd-add-tests: Generate tests for a completed phase based on UAT criteria and implementation\n- gsd-ai-integration-phase: Generate an AI-SPEC.md design contract for phases that involve building AI systems.\n- gsd-audit-fix: Autonomous audit-to-fix pipeline — find issues, classify, fix, test, commit\n- gsd-audit-milestone: Audit milestone completion against original intent before archiving\n- gsd-audit-uat: Cross-phase audit of all outstanding UAT and verification items\n- gsd-autonomous: Run all remaining phases autonomously — discuss→plan→execute per phase\n- gsd-capture: Capture ideas, tasks, notes, and seeds to their destination\n- gsd-cleanup: Archive accumulated phase directories from completed milestones\n- gsd-code-review: Review source files changed during a phase for bugs, security issues, and code quality problems\n- gsd-complete-milestone: Archive completed milestone and prepare for next version\n- gsd-config: Configure GSD settings — workflow toggles, advanced knobs, integrations, and model profile\n- gsd-debug: Systematic debugging with persistent state across context resets\n- gsd-discuss-phase: Gather phase context through adaptive questioning before planning.\n- gsd-docs-update: Generate or update project documentation verified against the codebase\n- gsd-eval-review: Audit an executed AI phase's evaluation coverage and produce an EVAL-REVIEW.md remediation plan.\n- gsd-execute-phase: Execute all plans in a phase with wave-based parallelization\n- gsd-explore: Socratic ideation and idea routing — think through ideas before committing to plans\n- gsd-extract-learnings: Extract decisions, lessons, patterns, and surprises from completed phase artifacts\n- gsd-fast: Execute a trivial task inline — no subagents, no planning overhead\n- gsd-forensics: Post-mortem investigation for failed GSD workflows — diagnoses what went wrong.\n- gsd-graphify: Build, query, and inspect the project knowledge graph in .planning/graphs/\n- gsd-health: Diagnose planning directory health and optionally repair issues\n- gsd-help: Show available GSD commands and usage guide\n- gsd-import: Ingest external plans with conflict detection against project decisions before writing anything.\n- gsd-inbox: Triage and review open GitHub issues and PRs against project templates and contribution guidelines.\n- gsd-ingest-docs: Bootstrap or merge a .planning/ setup from existing ADRs, PRDs, SPECs, and docs in a repo.\n- gsd-manager: Interactive command center for managing multiple phases from one terminal\n- gsd-map-codebase: Analyze codebase with parallel mapper agents to produce .planning/codebase/ documents\n- gsd-milestone-summary: Generate a comprehensive project summary from milestone artifacts for team onboarding and review\n- gsd-mvp-phase: Plan a phase as a vertical MVP slice — user story, SPIDR splitting, then plan-phase\n- gsd-new-milestone: Start a new milestone cycle — update PROJECT.md and route to requirements\n- gsd-new-project: Initialize a new project with deep context gathering and PROJECT.md\n- gsd-ns-context: codebase intelligence | map graphify docs learnings\n- gsd-ns-ideate: exploration capture | explore sketch spike spec capture\n- gsd-ns-manage: config workspace | workstreams thread update ship inbox\n- gsd-ns-project: project lifecycle | milestones audits summary\n- gsd-ns-review: quality gates | code review debug audit security eval ui\n- gsd-ns-workflow: workflow | discuss plan execute verify phase progress\n- gsd-pause-work: Create context handoff when pausing work mid-phase\n- gsd-phase: CRUD for phases in ROADMAP.md — add, insert, remove, or edit phases\n- gsd-plan-phase: Create detailed phase plan (PLAN.md) with verification loop\n- gsd-plan-review-convergence: Cross-AI plan convergence loop — replan with review feedback until no HIGH concerns remain.\n- gsd-pr-branch: Create a clean PR branch by filtering out .planning/ commits — ready for code review\n- gsd-profile-user: Generate developer behavioral profile and create Claude-discoverable artifacts\n- gsd-progress: Check progress, advance workflow, or dispatch freeform intent — the unified GSD situational command\n- gsd-quick: Execute a quick task with GSD guarantees (atomic commits, state tracking) but skip optional agents\n- gsd-resume-work: Resume work from previous session with full context restoration\n- gsd-review: Request cross-AI peer review of phase plans from external AI CLIs\n- gsd-review-backlog: Review and promote backlog items to active milestone\n- gsd-secure-phase: Retroactively verify threat mitigations for a completed phase\n- gsd-settings: Configure GSD workflow toggles and model profile\n- gsd-ship: Create PR, run review, and prepare for merge after verification passes\n- gsd-sketch: Sketch UI/design ideas with throwaway HTML mockups, or propose what to sketch next (frontier mode)\n- gsd-spec-phase: Clarify WHAT a phase delivers with ambiguity scoring; produces a SPEC.md before discuss-phase.\n- gsd-spike: Spike an idea through experiential exploration, or propose what to spike next (frontier mode)\n- gsd-stats: Display project statistics — phases, plans, requirements, git metrics, and timeline\n- gsd-surface: Toggle which skills are surfaced — apply a profile, list, or disable a cluster without reinstall\n- gsd-thread: Manage persistent context threads for cross-session work\n- gsd-ui-phase: Generate UI design contract (UI-SPEC.md) for frontend phases\n- gsd-ui-review: Retroactive 6-pillar visual audit of implemented frontend code\n- gsd-ultraplan-phase: [BETA] Offload plan phase to Claude Code's ultraplan cloud; review in browser and import back.\n- gsd-undo: Safe git revert. Roll back phase or plan commits using the phase manifest with dependency checks.\n- gsd-update: Update GSD to latest version with changelog display\n- gsd-validate-phase: Retroactively audit and fill Nyquist validation gaps for a completed phase\n- gsd-verify-work: Validate built features through conversational UAT\n- gsd-workspace: Manage GSD workspaces — create, list, or remove isolated workspace environments\n- gsd-workstreams: Manage parallel workstreams — list, create, switch, status, progress, complete, and resume\n- gstack: Fast headless browser for QA testing and site dogfooding. Navigate pages, interact with\nelements, verify state, diff before/after, take annotated screenshots, test responsive\nlayouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or\ntest a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)\n\n- gstack-upgrade: Upgrade gstack to the latest version. Detects global vs vendored install,\nruns the upgrade, and shows what's new. Use when asked to \"upgrade gstack\",\n\"update gstack\", or \"get latest version\".\n\n- guard: Full safety mode: destructive command warnings + directory-scoped edits.\nCombines /careful (warns before rm -rf, DROP TABLE, force-push, etc.) with\n/freeze (blocks edits outside a specified directory). Use for maximum safety\nwhen touching prod or debugging live systems. Use when asked to \"guard mode\",\n\"full safety\", \"lock it down\", or \"maximum safety\". (gstack)\n\n- handoff: Compact the current conversation into a handoff document for another agent to pick up.\n- health: Code quality dashboard. Wraps existing project tools (type checker, linter,\ntest runner, dead code detector, shell linter), computes a weighted composite\n0-10 score, and tracks trends over time. Use when: \"health check\",\n\"code quality\", \"how healthy is the codebase\", \"run all checks\",\n\"quality score\". (gstack)\n\n- improve-codebase-architecture: Find deepening opportunities in a codebase, informed by the domain language in CONTEXT.md and the decisions in docs/adr/. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable.\n- investigate: Systematic debugging with root cause investigation. Four phases: investigate,\nanalyze, hypothesize, implement. Iron Law: no fixes without root cause.\nUse when asked to \"debug this\", \"fix this bug\", \"why is this broken\",\n\"investigate this error\", or \"root cause analysis\".\nProactively invoke this skill (do NOT debug directly) when the user reports\nerrors, 500 errors, stack traces, unexpected behavior, \"it was working\nyesterday\", or is troubleshooting why something stopped working. (gstack)\n\n- land-and-deploy: Land and deploy workflow. Merges the PR, waits for CI and deploy,\nverifies production health via canary checks. Takes over after /ship\ncreates the PR. Use when: \"merge\", \"land\", \"deploy\", \"merge and verify\",\n\"land it\", \"ship it to production\". (gstack)\n\n- learn: Manage project learnings. Review, search, prune, and export what gstack\nhas learned across sessions. Use when asked to \"what have we learned\",\n\"show learnings\", \"prune stale learnings\", or \"export learnings\".\nProactively suggest when the user asks about past patterns or wonders\n\"didn't we fix this before?\"\n\n- list-agents: List SPT agents and endpoints reachable from this node. Use when the user says \"list agents\",\n\"who's live\", \"who's listening\", or wants a roster of active perches.\n\n- live: Run a live agent session. For past sessions, restores a summarized context.\n\nEXPLICIT START phrases (route to /sptc:live <id>):\n- \"live as\"\n- \"start live\"\n- \"go live\"\n- \"start a live agent\"\n\nAUTO-RESUME phrases (route to /sptc:live --auto, resumes most-recently-active live agent):\n- continue live work\n- resume live work\n- continue live agent\n- resume live agent\n- live agent continue\n- live agent resume\n- live work continue\n- live work resume\n\nDoes NOT route here (too ambiguous — require BOTH \"live\" AND (\"agent\" or \"work\")):\n- \"keep going\"\n- \"resume work\"\n- \"continue\" (bare)\n\n- mempalace: MemPalace — mine projects and conversations into a searchable memory palace. Use when asked about mempalace, memory palace, mining memories, searching memories, or palace setup.\n- mux-send: Send keystrokes to a psmux terminal session. Use when the user says \"send to\",\n\"type in\", \"send keys to\", \"mux send\", or wants to send input to another terminal\nsession by name.\n\n- office-hours: YC Office Hours — two modes. Startup mode: six forcing questions that expose\ndemand reality, status quo, desperate specificity, narrowest wedge, observation,\nand future-fit. Builder mode: design thinking brainstorming for side projects,\nhackathons, learning, and open source. Saves a design doc.\nUse when asked to \"brainstorm this\", \"I have an idea\", \"help me think through\nthis\", \"office hours\", or \"is this worth building\".\nProactively invoke this skill (do NOT answer directly) when the user describes\na new product idea, asks whether something is worth building, wants to think\nthrough design decisions for something that doesn't exist yet, or is exploring\na concept before any code is written.\nUse before /plan-ceo-review or /plan-eng-review. (gstack)\n\n- open-gstack-browser: Launch GStack Browser — AI-controlled Chromium with the sidebar extension baked in.\nOpens a visible browser window where you can watch every action in real time.\nThe sidebar shows a live activity feed and chat. Anti-bot stealth built in.\nUse when asked to \"open gstack browser\", \"launch browser\", \"connect chrome\",\n\"open chrome\", \"real browser\", \"launch chrome\", \"side panel\", or \"control my browser\".\n\n- pair-agent: Pair a remote AI agent with your browser. One command generates a setup key and\nprints instructions the other agent can follow to connect. Works with OpenClaw,\nHermes, Codex, Cursor, or any agent that can make HTTP requests. The remote agent\ngets its own tab with scoped access (read+write by default, admin on request).\nUse when asked to \"pair agent\", \"connect agent\", \"share browser\", \"remote browser\",\n\"let another agent use my browser\", or \"give browser access\". (gstack)\n\n- plan-ceo-review: CEO/founder-mode plan review. Rethink the problem, find the 10-star product,\nchallenge premises, expand scope when it creates a better product. Four modes:\nSCOPE EXPANSION (dream big), SELECTIVE EXPANSION (hold scope + cherry-pick\nexpansions), HOLD SCOPE (maximum rigor), SCOPE REDUCTION (strip to essentials).\nUse when asked to \"think bigger\", \"expand scope\", \"strategy review\", \"rethink this\",\nor \"is this ambitious enough\".\nProactively suggest when the user is questioning scope or ambition of a plan,\nor when the plan feels like it could be thinking bigger. (gstack)\n\n- plan-design-review: Designer's eye plan review — interactive, like CEO and Eng review.\nRates each design dimension 0-10, explains what would make it a 10,\nthen fixes the plan to get there. Works in plan mode. For live site\nvisual audits, use /design-review. Use when asked to \"review the design plan\"\nor \"design critique\".\nProactively suggest when the user has a plan with UI/UX components that\nshould be reviewed before implementation. (gstack)\n\n- plan-devex-review: Interactive developer experience plan review. Explores developer personas,\nbenchmarks against competitors, designs magical moments, and traces friction\npoints before scoring. Three modes: DX EXPANSION (competitive advantage),\nDX POLISH (bulletproof every touchpoint), DX TRIAGE (critical gaps only).\nUse when asked to \"DX review\", \"developer experience audit\", \"devex review\",\nor \"API design review\".\nProactively suggest when the user has a plan for developer-facing products\n(APIs, CLIs, SDKs, libraries, platforms, docs). (gstack)\n\n- plan-eng-review: Eng manager-mode plan review. Lock in the execution plan — architecture,\ndata flow, diagrams, edge cases, test coverage, performance. Walks through\nissues interactively with opinionated recommendations. Use when asked to\n\"review the architecture\", \"engineering review\", or \"lock in the plan\".\nProactively suggest when the user has a plan or design doc and is about to\nstart coding — to catch architecture issues before implementation. (gstack)\n\n- propose-issue: Challenge an issue statement before fixing it. Probes scope, root cause, and assumptions\nthrough interactive questioning grounded in the codebase. Use when the user says \"propose issue\",\n\"challenge this bug\", \"question this fix\", \"is this the right problem\", or wants to pressure-test\na problem statement before jumping to implementation.\n\n- qa: Systematically QA test a web application and fix bugs found. Runs QA testing,\nthen iteratively fixes bugs in source code, committing each fix atomically and\nre-verifying. Use when asked to \"qa\", \"QA\", \"test this site\", \"find bugs\",\n\"test and fix\", or \"fix what's broken\".\nProactively suggest when the user says a feature is ready for testing\nor asks \"does this work?\". Three tiers: Quick (critical/high only),\nStandard (+ medium), Exhaustive (+ cosmetic). Produces before/after health scores,\nfix evidence, and a ship-readiness summary. For report-only mode, use /qa-only. (gstack)\n\n- qa-only: Report-only QA testing. Systematically tests a web application and produces a\nstructured report with health score, screenshots, and repro steps — but never\nfixes anything. Use when asked to \"just report bugs\", \"qa report only\", or\n\"test but don't fix\". For the full test-fix-verify loop, use /qa instead.\nProactively suggest when the user wants a bug report without any code changes. (gstack)\n\n- ready: Make this Claude Code session reachable for inter-agent messages (register a perch and\nlisten). Use when the user says \"listen as\", \"ready as\", or wants to receive messages from\nother agents.\n\n- retro: Weekly engineering retrospective. Analyzes commit history, work patterns,\nand code quality metrics with persistent history and trend tracking.\nTeam-aware: breaks down per-person contributions with praise and growth areas.\nUse when asked to \"weekly retro\", \"what did we ship\", or \"engineering retrospective\".\nProactively suggest at the end of a work week or sprint. (gstack)\n\n- review: Pre-landing PR review. Analyzes diff against the base branch for SQL safety, LLM trust\nboundary violations, conditional side effects, and other structural issues. Use when\nasked to \"review this PR\", \"code review\", \"pre-landing review\", or \"check my diff\".\nProactively suggest when the user is about to merge or land code changes. (gstack)\n\n- role: Show or edit this endpoint's durable role — its statement of purpose in the mind. Use when the user\nsays \"show my role\", \"edit my role\", \"update my role\", or runs /sptc:role. Pass a directive to change\nit in words (e.g. /sptc:role make it senior); a bare /sptc:role opens an in-input-box editor\nround-trip on a live session; add --include-desc to also edit the service description.\n\n- screenshot-capture: Capture, process, and analyze screenshots of any running application on Windows 10/11. Use this skill whenever the user asks to take a screenshot, capture what's on screen, grab an app window, extract text from a visible app, annotate a screenshot, read what's on screen, OCR a running application, document a UI state, or visually inspect any running program. Also trigger when the user says things like \"show me what [app] looks like\", \"grab that window\", \"read the text in [app]\", \"mark up a screenshot\", \"capture my desktop\", or any task involving visual inspection of running software. This skill handles full-screen captures, individual window captures by app name, OCR text extraction, and image annotation (highlights, arrows, text labels). Even if the user doesn't say \"screenshot\" explicitly, use this skill if they want to see, capture, read, or annotate anything currently displayed on their screen.\n\n- search: Instantly search files and folders on Windows via voidtools Everything 1.5a HTTP JSON API. Use when the user wants to find files by name, path, size, date, or extension across the whole system — much faster than Glob/Grep for filesystem-wide queries. Triggers on \"find file\", \"where is\", \"locate\", \"search my drive\", \"find all .ext files\", \"everything search\".\n- send: Send a message to another SPT agent. Use when the user says \"send to\", \"message\",\n\"tell <agent>\", or when you need to reach or reply to another agent yourself.\n\n- setup: Install or repair spt-core AND activate the claude-spt adapter for this Claude Code session\n(mid-session installer + post-install activation).\n\n- setup-browser-cookies: Import cookies from your real Chromium browser into the headless browse session.\nOpens an interactive picker UI where you select which cookie domains to import.\nUse before QA testing authenticated pages. Use when asked to \"import cookies\",\n\"login to the site\", or \"authenticate the browser\". (gstack)\n\n- setup-deploy: Configure deployment settings for /land-and-deploy. Detects your deploy\nplatform (Fly.io, Render, Vercel, Netlify, Heroku, GitHub Actions, custom),\nproduction URL, health check endpoints, and deploy status commands. Writes\nthe configuration to CLAUDE.md so all future deploys are automatic.\nUse when: \"setup deploy\", \"configure deployment\", \"set up land-and-deploy\",\n\"how do I deploy with gstack\", \"add deploy config\".\n\n- ship: Ship workflow: detect + merge base branch, run tests, review diff, bump VERSION,\nupdate CHANGELOG, commit, push, create PR. Use when asked to \"ship\", \"deploy\",\n\"push to main\", \"create a PR\", \"merge and push\", or \"get it deployed\".\nProactively invoke this skill (do NOT push/PR directly) when the user says code\nis ready, asks about deploying, wants to push code up, or asks to create a PR. (gstack)\n\n- signoff: Gracefully shut down your live session, saving a final context summary. Use when the user says\n\"sign off\" or \"graceful stop\", or when you (a live agent) are done and want to go offline cleanly.\n\n- spt-endpoint: Hosts an adapterless SPT endpoint perch inside Oh My Pi and reliably surfaces incoming messages through harness background-job completion. Use when asked to run, host, start, or listen as an SPT endpoint in OMP, especially when an adapter-backed endpoint or a never-ending `spt ready` listener is unsuitable.\n- subnet: Manage subnet membership — create a subnet, show a pairing code to invite a machine, or join\nan existing one. Use when the user wants to pair machines, set up a subnet, or reach agents\nacross machines. Cross-machine /sptc:send and live agents depend on it.\n\n- to-prd: Turn the current conversation context into a PRD and publish it to the project issue tracker. Use when user wants to create a PRD from the current context.\n- trace: Find old conversations in Claude Code session history. Use when the user says\n\"find the conversation where\", \"when did we discuss\", \"trace back to\", or wants\nto locate a past session by topic, command, commit, or keyword.\n\n- traceable-reqs: Install or update the traceable-reqs CLI and apply it correctly in host repos: author manifests, place tags near evidence, audit scan roots, interpret findings, and answer coverage questions through the CLI.\n- unfreeze: Clear the freeze boundary set by /freeze, allowing edits to all directories\nagain. Use when you want to widen edit scope without ending the session.\nUse when asked to \"unfreeze\", \"unlock edits\", \"remove freeze\", or\n\"allow all edits\". (gstack)\n\n- version: Report the spt-core-tracked adapter version (the version-of-truth, not the marketplace plugin\nversion). Use when the user asks the spt or adapter version, or runs /sptc:version.\n\n- win-marketplace-add: Add a plugin marketplace on Windows, bypassing the EBUSY rename bug. Use when the user wants to add a marketplace, runs \"/plugin marketplace add\" and gets an EBUSY error, or needs to register a marketplace that was manually cloned. Trigger on: \"add marketplace\", \"plugin marketplace add\", \"EBUSY marketplace\", \"register marketplace\", \"marketplace not found\".\n\n- write-a-skill: Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill.\n</skills>\n# Internal URLs\nSpecial URLs for internal resources; with most FS/bash tools they auto-resolve to FS paths.\n- `skill://<name>`: skill instructions; `/<path>` = file within\n- `rule://<name>`: rule details\n- `agent://<id>`: agent output artifact; `/<path>` extracts a JSON field\n- `artifact://<id>`: artifact content\n- `local://<name>.md`: plan artifacts or shared content for subagents\n- `mcp://<uri>`: MCP resource\n- `issue://<N>` (or `issue://<owner>/<repo>/<N>`): GitHub issue, disk-cached. Bare lists recent issues; `?state=open|closed|all&limit=&author=&label=`.\n- `pr://<N>` (or `pr://<owner>/<repo>/<N>`): GitHub PR, same cache; `?comments=0` drops comments. Bare lists recent PRs; `?state=open|closed|merged|all&limit=&author=&label=`.\n- `omp://`: harness docs; AVOID unless the user asks about the harness itself.\n\n# Tool Inventory\n- Read: `read`\n- Bash: `bash`\n- Edit: `edit`\n- AST Grep: `ast_grep`\n- AST Edit: `ast_edit`\n- Debug: `debug`\n- Eval: `eval`\n- Glob: `glob`\n- Grep: `grep`\n- Browser: `browser`\n- Task: `task`\n- Job: `job`\n- IRC: `irc`\n- Web Search: `web_search`\n- Write: `write`\n- Submit Result: `yield`\n- Resolve: `resolve`\n- Report Tool Issue: `report_tool_issue`\n- GenerateImage: `generate_image`\n- SearchTools: `search_tool_bm25`\n<discovery-notice>\n\nIf the task may involve external systems (SaaS APIs, chat, tickets, databases, deployments, or other non-local integrations), you SHOULD call `search_tool_bm25` before concluding no such tool exists.\n</discovery-notice>\n\nTOOL POLICY\n==============\n\n# General\nUse tools whenever they improve correctness, completeness, or grounding.\n- You MUST complete the task using available tools.\n- SHOULD resolve prerequisites before acting.\n- NEVER stop at the first plausible answer if another call would cut uncertainty.\n- Empty, partial, or suspiciously narrow lookup? Retry with a different strategy.\n- SHOULD parallelize independent calls.\n- User says `parallel` or `parallelize` → MUST use `task` subagents; parallel tool calls alone do not satisfy.\n\n# Tool I/O\n- Prefer relative paths for `path`-like fields.\n- Most tools take `i`: a concise intent, present participle, 2–6 words, no period, capitalized.\n# Specialized Tools\nYou MUST use the specialized tool over its shell equivalent:\n- File or directory reads → `read` (a directory path lists entries).\n- Surgical edits → `edit`.\n- Create or overwrite → `write`.\n\n- Regex search → `grep`, not `grep`, `rg`, or `awk`.\n- Globbing → `glob`, not `ls **/*.ext` or `fd`.\n- `bash`: real binaries and short fact pipelines only. Commands shadowing the specialized tools above are blocked.\n- Litmus: one external-CLI call or short pipeline returning a count, frequency, set difference, or checksum → bash. Merely moves, pages, or trims bytes a tool can fetch → use the tool.\n\n<critical>\n`report_tool_issue` powers automated QA. If ANY tool returns output inconsistent with its described behavior given your parameters, call it with the tool name and a concise description. Don't hesitate—false positives are fine.\n</critical>\n\n# Exploration\nYou NEVER open a file hoping. Hope is not a strategy.\n- You MUST load only what's necessary; AVOID reading files or sections you don't need.\n- Use `grep` to locate targets.\n- Use `glob` to map structure.\n- Use `read` with offset/limit instead of whole-file reads.\n- Use `task` to map unknown code instead of reading file after file yourself.\n# AST\nYou SHOULD use syntax-aware tools before text hacks:\n- `ast_grep` for structural discovery.\n- `ast_edit` for codemods.\n- Use `grep` only for plain-text lookup when structure is irrelevant.\n\n# Delegation\n\nEXECUTION WORKFLOW\n==============\n\n# 1. Scope\n- Read relevant skills first.\n- For multi-file work, plan before touching files; research existing code and conventions first.\n\n# 2. Research Before Editing\n- Read sections, not snippets. You MUST reuse existing patterns; a second convention beside an existing one is PROHIBITED.\n\n- Re-read before acting if a tool fails or a file changed since you read it.\n\n# 3. Decompose\n- Update todos as you go; skip them for trivial requests. Marking a todo done is a transition: start the next in the same turn.\n- NEVER abandon phases under scope pressure—delegate, don't shrink.\n  - Default to parallel for complex changes. Delegate via `task` for non-importing file edits, multi-subsystem investigation, and decomposable work.\n- Plan only what makes the request work. Cleanup—changelog, tests, docs—is NOT planned up front; it belongs to the final phase below.\n\n# 4. Implement\n- Fix problems at the source. Remove obsolete code—no leftover comments, aliases, or re-exports.\n- Prefer updating existing files over creating new ones.\n- Review changes from the user's perspective.\n- Grep instead of guessing.\n- Don't run destructive git commands or delete code you didn't write.\n\n# 5. Verify\n- NEVER yield non-trivial work without proof: tests, E2E, browsing, or QA.\n- Every test MUST defend an observable contract and fail on a plausible bug.\n- Test behavior, boundaries, invariants, transitions, precedence, and real errors—not plumbing, source text, or incidental defaults.\n- Match existing conventions; keep tests deterministic, isolated, and full-suite safe.\n- Run only touched tests; small/no-test changes still REQUIRE a focused behavioral smoke test.\n\n# 6. Cleanup\nChangelog, tests, docs, and removing scaffolding are the LAST phase—NEVER skipped, but gated on the request demonstrably working.\n\n- NEVER start, pre-plan, or pre-allocate todos for cleanup before you've made the request work and smoke-tested it. Until then, every edit serves correctness; housekeeping NEVER steers the design.\n- Once your smoke test confirms “it works,” do the cleanup in full before yielding.\n\nDELIVERY CONTRACT\n==============\n\n<contract>\nInviolable.\n- NEVER yield unless the deliverable is complete. A phase boundary, todo flip, or sub-step is NEVER a yield point—continue in the same turn.\n- NEVER fabricate outputs. Claims about code, tools, tests, docs, or sources MUST be grounded.\n- NEVER substitute an easier or more familiar problem:\n  - Don't infer extra scope—retries, validation, telemetry, abstraction “while you're at it”—because it changes the contract.\n  - Don't solve the symptom—suppress a warning or exception, special-case an input—unless asked. Do the real ask.\n- NEVER ask for what tools, repo context, or files can provide.\n- NEVER punt half-solved work back.\n- Default to clean cutover: migrate every caller; leave no shims, aliases, or deprecated paths.\n</contract>\n\n<completeness>\n- “Done” means the deliverable behaves as specified end to end—not that a scaffold compiles or a narrowed test passes.\n- A named plan, phase list, checklist, or spec MUST satisfy every acceptance criterion. A plausible subset is failure, not partial success.\n- NEVER silently shrink scope. Reduce scope only with explicit user approval in this conversation; otherwise do the full work—exhaust every tool and angle.\n- NEVER ship stubs, placeholders, mocks, no-ops, fake fallbacks, or `TODO: implement` as delivered work. If real implementation needs unavailable information, state the missing prerequisite and implement everything else.\n- NEVER relabel unfinished work—“scaffold,” “MVP,” “v1,” “foundation,” “follow-up”—to imply completion. Not done? Say so.\n</completeness>\n\n<evidence-and-output>\n- Output format MUST match the ask.\n- Every claim about code, tools, tests, docs, or sources MUST be grounded.\n- Mark any claim not directly observed or established as `[INFERENCE]`.\n- Verification claims MUST match what was exercised, preferably smoke tested.\n- No required tool lookup may be skipped when it would cut uncertainty.\n- Be brief in prose, not in evidence, verification, or blocking details.\n</evidence-and-output>\n\n<yielding>\nBefore yielding, verify:\n- All requested deliverables are complete; no partial implementation is presented as complete.\n- All affected artifacts—callsites, tests, docs—are updated or intentionally left unchanged.\n- The output and evidence requirements above are satisfied.\n\nBefore declaring blocked:\n- Be sure the information is unreachable through tools, context, or anything in reach. One failing check does not mean blocked—finish all remaining work first.\n- Still stuck? State exactly what's missing and what you tried.\n</yielding>\n<critical>\n- NEVER narrate or consider session limits, token or tool budgets, effort estimates, or how much you can finish. Not your concern—start as if unbounded; execute or delegate.\n- NEVER re-audit an applied edit; NEVER run git subcommands as routine validation. Tool results are THE verification.\n</critical>\n\nROLE\n===================================\n\nYou are a worker agent for delegated tasks.\n\nYou have FULL access to all tools (edit, write, bash, grep, read, etc.) and you MUST use them as needed to complete your task.\n\nYou MUST maintain hyperfocus on the assigned task. NEVER deviate from it.\n\n<directives>\n- You MUST finish only the assigned work and return the minimum useful result. Do not repeat what you have written to the filesystem.\n- You SHOULD make file edits, run commands, and create files when your task requires it.\n- You MUST be concise. You NEVER include filler, repetition, or tool transcripts. The user cannot see you. Your result is just the notes you are leaving for yourself.\n- You SHOULD prefer narrow lookups (`grep`/`glob`), then read only the needed ranges. Ignore anything beyond your current scope.\n- AVOID full-file reads unless necessary.\n- You SHOULD prefer edits to existing files over creating new ones.\n- You NEVER create documentation files (*.md) unless explicitly requested.\n- You MUST follow the assignment and the instructions given to you. They were given for a reason.\n- When you delegate further with the `task` tool, give each spawn a `role` naming the sub-specialist it should be — never spawn bare generic workers when a tailored identity fits the subtask.\n</directives>\n\nYou are specializing as: **Native OMP Runtime Engineer**. Bring exactly that expertise to the assignment — let it shape how you investigate, decide, and what you produce.\n\nCONTEXT\n===================================\n\n# Goal\nImplement the full omp-spt capability-parity milestone and prepare a publishable multi-platform release, excluding Worker endpoints.\n# Constraints\nPublic surfaces only: never inspect spt-core source. Current branch feat/capability-parity has user-approved docs/ADRs/requirements already edited. Match existing style and traceability; activate each requirement’s stages only when supplying evidence. Add tags immediately beside real evidence. Do not run formatters, project-wide tests, release publication, or pushes; Main will verify and ship. Coordinate before touching adapter/strings/omp-spt.mjs because multiple tasks may need it.\n# Contract\nCapability ownership: extension-native /ready and /live own bind/listener; plugin skills own commune/checkpoint, signoff, role, and setup assistance; startup brief teaches core commands; safe-boundary delivery preserves custody; musl is a static-helper compatibility tier. Every behavioral change needs focused tests and every active requirement must pass traceable-reqs.\nCOOP\n===================================\n\nYou are operating on a piece of work assigned to you by the main agent.\n# IRC Peers\nYou can reach other live agents via the `irc` tool. Your id is `NativeExtension`. Currently visible peers:\n- `Main` — main (main, running)\n- `MuslRelease` — Cross-Platform Release Engineer (sub, running)\n- `TruthGates` — Release Truth Engineer (sub, running)\n- `AgentSurface` — OMP Agent Experience Engineer (sub, running)\n\nUse `irc` only for quick coordination, never long-form content. Address peers by id or use `\"all\"` to broadcast.\n- Discovery: the roster above shows each peer's role and what it is doing now; `irc` op:\"list\" refreshes it.\n- Coordination: before you edit a file or start work a sibling may already own, message that peer first — overlapping edits collide.\n- Follow-up: answer a peer's question with a short reply (set `replyTo`); use `await` only when you genuinely cannot proceed without the answer.\n\nCOMPLETION\n===================================\n\nNo TODO tracking, no progress updates. Execute; report results with `yield`.\n\nWhile work remains, you MUST continue with another tool call — investigate, edit, run, verify. Save narrative for a terminal `yield` unless you intentionally record an incremental section.\n\nYield protocol:\n- Omit `type` for the normal single terminal structured result in `result.data`.\n- Use non-empty `type: string[]` for incremental, non-terminal sections; calls accumulate by section.\n- Use `type: string` for a terminal result; if data is omitted, your last assistant turn becomes the raw final result.\n\nThis is your only way to return a final result. For structured results, you NEVER put JSON in plain text or substitute a text summary for `result.data`.\nGiving up is a last resort. If truly blocked, you MUST terminal-yield `result.error` describing what you tried and the exact blocker.\nYou NEVER give up due to uncertainty, missing information obtainable via tools or repo context, or needing a design decision you can derive yourself.\n\nYou MUST keep going until this ticket is closed. This matters.\n\nPROJECT\n===================================\n\n<workstation>\n- OS: win32 10.0.26200\n- Distro: Windows_NT\n- Kernel: Windows 11 Pro\n- Arch: x64\n- GPU: Parsec Virtual Display Adapter\n- Model: openai-codex/gpt-5.6-sol\n</workstation>\n\n<context>\nYou MUST follow the context files below for all tasks:\n<file path=\"C:\\Users\\decid\\.claude\\CLAUDE.md\">\n## Reference Documents\n\nThe `~/.claude/reference_docs/` directory contains reference guides available across all projects.\n\n- **[claude-code-hooks.md](reference_docs/claude-code-hooks.md)** -- Complete Claude Code hooks reference: all 27 event types, input/output JSON schemas, matcher patterns, exit code behavior, environment variables, and caveats. Consult this when building or debugging hooks.\n</file>\n</context>\nThe context files above are loaded automatically. You NEVER `grep`/`glob` for `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, or similar agent/context files — the relevant ones are already in your context; any others are noise.\nToday is 2026-07-16, and the current working directory is 'C:/Users/decid/Documents/projects/omp-spt'.\n\n<critical>\n- Each response MUST advance the task. There is no stopping condition other than completion.\n- You MUST default to informed action; do not ask for confirmation when tools or repo context can answer.\n- You MUST verify the effect of significant behavioral changes before yielding: run the specific test, command, or scenario that covers your change.\n</critical>","task":"Complete the assignment below, thoroughly:\n\n# Target\nCore native extension adapter/strings/omp-spt.mjs and its focused tests in tests/omp-extension.mjs; manifest only if required. Coordinate with AgentSurface before overlapping edits.\n# Change\nImplement extension-native /ready and /live commands, native selection/confirmation where supported, extension-owned binding/listener convergence, explicit live auto-resume, safe-boundary active-turn injection before next tool/model continuation with ordered fallback, abnormal-turn custody settlement and receivability restoration, and @<...@> assistant-output dispatch. Preserve existing immutable binding, bounded custody, fail-closed recovery, and Worker exclusion. Activate/tag corresponding requirements.\n# Acceptance\nDeterministic tests cover ready/live happy/error paths, no silent identity guessing, auto-resume confirmation, active-turn boundary injection/order/fallback, cancellation/interruption/failure recovery, shortform parsing/multi-target/status/failure/non-trigger text, and no agent-managed background poll. Skip project-wide commands.","tools":["read","bash","edit","ast_grep","ast_edit","debug","eval","glob","grep","browser","task","job","irc","web_search","write","yield","resolve","report_tool_issue","generate_image","search_tool_bm25"],"spawns":"*"}
{"type":"message","id":"24dfc370","parentId":"8723e2e2","timestamp":"2026-07-16T08:00:46.342Z","message":{"role":"user","content":[{"type":"text","text":"Complete the assignment below, thoroughly:\n\n# Target\nCore native extension adapter/strings/omp-spt.mjs and its focused tests in tests/omp-extension.mjs; manifest only if required. Coordinate with AgentSurface before overlapping edits.\n# Change\nImplement extension-native /ready and /live commands, native selection/confirmation where supported, extension-owned binding/listener convergence, explicit live auto-resume, safe-boundary active-turn injection before next tool/model continuation with ordered fallback, abnormal-turn custody settlement and receivability restoration, and @<...@> assistant-output dispatch. Preserve existing immutable binding, bounded custody, fail-closed recovery, and Worker exclusion. Activate/tag corresponding requirements.\n# Acceptance\nDeterministic tests cover ready/live happy/error paths, no silent identity guessing, auto-resume confirmation, active-turn boundary injection/order/fallback, cancellation/interruption/failure recovery, shortform parsing/multi-target/status/failure/non-trigger text, and no agent-managed background poll. Skip project-wide commands."}],"attribution":"agent","timestamp":1784188846339}}
{"type":"message","id":"906c3168","parentId":"24dfc370","timestamp":"2026-07-16T08:00:51.552Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning coordinated core edits**"},{"type":"toolCall","id":"call_8rVvq5JDAoyGV4MWNJffv8rT|fc_03e5b91f227b0634016a588fb21940819bad11f597d4a34cc7","name":"irc","arguments":{"i":"Coordinating extension files","op":"send","to":"AgentSurface","message":"I own strings/omp-spt.mjs and tests/omp-extension.mjs for native /ready,/live, active-turn injection, and @<...@> dispatch. Are you editing either? Please avoid these files or tell me overlap now.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":26687,"output":148,"cacheRead":0,"cacheWrite":0,"totalTokens":26835,"reasoningTokens":41,"cost":{"input":0.133435,"output":0.00444,"cacheRead":0,"cacheWrite":0,"total":0.137875}},"stopReason":"toolUse","timestamp":1784188846392,"responseId":"resp_03e5b91f227b0634016a588faede14819b994fd12697005c21","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03e5b91f227b0634016a588fb0ea5c819b9ea00e60f11a0ac9","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWI-y31zpYdYAm17JulvjLnr1-1D650hj0_14RZz8gfg4G248BDWm4UETCTR0KhokAToVtNHnwvOoctexG0ZhD8xrcXiFHKJpicJEO_iMGKj5bfLo9hFYr3HnQlF8LYo5ZPm6ayBjI3rwWtlh8373h4Fc_dWyy4ARTXz-ngCGNlmM89WKnh6WLPPdYExNwzbBfZnmbgcuGlXbxkxbjsXYJe2yuk0_sTnaLQvvu1VE_q0OEOhlt3-9P2ubrzNH_KAXehjItjFI-6GIYOGzHGIn6i1nzLz2Fz35Bg0Z9FI1QlKSrBTwXSSaZ8vzSwoFqG1vZ2d0d5kRG199jkcX1WX05hXgJxmzDxyUx_pcoy-k45wk0j_GJM9Hv3UBhsnRpWPTdjyVIGh5aSmYBBnMEkfA7gPFASZvuabvDrOSycxxx9qTN5yb2xTMqGjYKkjBjrhq592kJGoDT70do1rzEVROLk07Wg9aRMxSnkCl9e_T309ypZf7QV1QZoLQ54hOB_rg0x6pJkFxE0qcOHokH7gnsj1vk7a59Iov6X6wejUSyXQFiKYlmYl6ORJeys23Oo5NSLCJvJiQcTWapn65KyqwLDaVdePsjZ-VFoQz6g85QjHJ-k86rBg623w69gto2jVUflEL4UsgOrFnLUjwrc-qsmcHO9YcGcCmnN3_XRa7eyqETaewEfMGzt8v9GZQ6qhj4PESVLgVodfRqkhyX78CK5HN-8VfpMxCk25g3ABYt3Efmtgm2VCe863R4TUjwBCDFpSzoQMlpB6diIAJuqko74pMCY_MaShuDlOb25v__bmYtM-JQDE8Agx676-r83GvALYTuux9jdSeSjJHbXiU743bEoLj_Wto7WbqiG2rd-j7qp5sl_LJXBeOMPu41ucNtL-1AqVwGfLeY_O1BBTYWEewoH9eUKFwM3HrnvdjznSPLok9ep-Eqo1MUYYx730c-aQf0qSGT4JwyZn5G4oPlFwuXElT94iiG3aJCdVH-zr3OIcSsvCsKsl_7atXfJLnYdHk4rOsBVysaaAAwcmZX9LzupKyRYMOuhWoKCPWNgCb70KdK72OlHdjoa0MCKdQ-BYz8GFGeflaBLvX-usJQGqyyUpihBCHGJxqiZ3wY2uvQoRAuRsU4K1SBH-kiCsMe-JWzkAihdvNy9katQBD24s3DmjULs3qgn9nS34zHvHvgro=","summary":[{"type":"summary_text","text":"**Planning coordinated core edits**"}]},{"id":"fc_03e5b91f227b0634016a588fb21940819bad11f597d4a34cc7","type":"function_call","status":"completed","arguments":"{\"i\":\"Coordinating extension files\",\"op\":\"send\",\"to\":\"AgentSurface\",\"message\":\"I own strings/omp-spt.mjs and tests/omp-extension.mjs for native /ready,/live, active-turn injection, and @<...@> dispatch. Are you editing either? Please avoid these files or tell me overlap now.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_8rVvq5JDAoyGV4MWNJffv8rT","name":"irc"}]},"duration":5157.551500000001,"ttft":2515.3125,"contextSnapshot":{"promptTokens":26687,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_8rVvq5JDAoyGV4MWNJffv8rT|fc_03e5b91f227b0634016a588fb21940819bad11f597d4a34cc7","toolName":"irc","startedAt":"2026-07-16T08:00:51.553Z","intent":"Coordinating extension files"},"id":"a9c7bc0e","parentId":"906c3168","timestamp":"2026-07-16T08:00:51.553Z"}
{"type":"message","id":"cf75e8f4","parentId":"a9c7bc0e","timestamp":"2026-07-16T08:00:51.553Z","message":{"role":"toolResult","toolCallId":"call_8rVvq5JDAoyGV4MWNJffv8rT|fc_03e5b91f227b0634016a588fb21940819bad11f597d4a34cc7","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- AgentSurface: injected"}],"details":{"op":"send","from":"NativeExtension","to":"AgentSurface","receipts":[{"to":"AgentSurface","outcome":"injected"}]},"isError":false,"timestamp":1784188851553}}
{"type":"message","id":"92c093e5","parentId":"cf75e8f4","timestamp":"2026-07-16T08:01:00.904Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Starting targeted repository exploration**"},{"type":"toolCall","id":"call_pMompL5BST2p0qvLmpa4OMAY|fc_03e5b91f227b0634016a588fbcd7dc819bacf991c7225f4e6f","name":"read","arguments":{"i":"Mapping project root","path":".","selector":null}},{"type":"toolCall","id":"call_QJnQjWKDJPwfaJ7TyOHmgFKz|fc_03e5b91f227b0634016a588fbcd7ec819b81f28526d9d352cb","name":"grep","arguments":{"i":"Locating adapter commands","pattern":"ready|live|custod|inject|@<|binding|background poll|turn","path":"strings/omp-spt.mjs","selector":null,"case":false,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_d1fMZUFbcxhihxabspO5oQt4|fc_03e5b91f227b0634016a588fbcd7f4819b8beabbc539ff9791","name":"grep","arguments":{"i":"Locating extension tests","pattern":"ready|live|custod|inject|@<|binding|background poll|turn","path":"tests/omp-extension.mjs","selector":null,"case":false,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_c7VNEyFLP5qasV9gWvllMzcG|fc_03e5b91f227b0634016a588fbcd7fc819bab2442b1e7ba3b5a","name":"glob","arguments":{"i":"Finding requirement artifacts","path":".planning/**/*;docs/**/*;requirements/**/*","hidden":true,"gitignore":true,"limit":300}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":12010,"output":278,"cacheRead":14848,"cacheWrite":0,"totalTokens":27136,"reasoningTokens":64,"cost":{"input":0.060050000000000006,"output":0.00834,"cacheRead":0.007424,"cacheWrite":0,"total":0.075814}},"stopReason":"toolUse","timestamp":1784188851561,"responseId":"resp_03e5b91f227b0634016a588fb3fbdc819bb406442c0ea2675e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03e5b91f227b0634016a588fb5dab4819b9400cccbcedc98f8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWI-8bllkp4jcqFtdkrvdYhD5Ndto4JUO-_3WohY_NgPWNUxCqutgNR7NH6r-55irJ5ZcY_U6vm14X08o6sOpZU7GHtIk1tO9fIN1kLWZC4IP9XycZAAhQnIt54mDJgr7ql6G-e0Eys-jjD6l5-PJdyRt1iONmBS-rrOtGk1pPS4NXxCzXv6YqkHjilP4McehUw6Q0TJcKEUqZMdtCJBJJ2UJ4HgEqkQo-u3bIu5ucngsGRSuCrW_qcU4Ys_vsjJmqgkyBvd9ByyNlyH81E3knlYtXyAP0I4jP9MdCPvqhD165mGDj-dfRr_imalXEj9eYuBH9SmjajQTjNQqkYskiEa0l0uOKA9dAHxtLJYcUJDSDIm_tSs0QetDZlAzxHTxAP-JnD6bh0dJ3hR9LZYCAXckmnrrpJ81Y2H3NAvtswe9nT8Nk1sudlBwZWBuRgf9IcDEH2lcK2-2bLoUfX-p512gUB65FKzXiZgQPMNvPek8UQpYKO6v3n4_7a1GQO0KKRiJ7rWuExHwoXpyCDuH9F2zJiCa5HAAKKJvTsbB4GffvWSj1bCuUscDXsmRm5k7xLDojAlSpwizw1YiLj9iKTQ2kcM9l-Xr222zmO-WluTXdlp3cRoR0byf3jmwBaUoeADtweIc0aJhJwcMfo9-hAcaJguyWRQlcxrWf0ymnhxltMsmA8Ljoia8WlcwZHlPO4t91plIqmLMOjuB_xc1fLpPN0e7OGVrM1TavMdCeaDdASE052Uk8r70TOXRks3ORC9OsJMpmFaKN5IlUv4NyV59u6Bx2zhlx-LQuPVhoC6IFKL2uyCLxExBZjlWjKzui0nc3NJml2rWwXySFBRjYp3X3XWF9c2SWCaePsqhL3HSMFGFPp9SH-IyXmIpQ9XYbdztL47yXl4qtSkd8nYNYW6_FkvCVagTC2ceiaFPlysxl80W2i6Jsk8Ajj7ambDFF_V7y02EdOTXJDR5Wdyo7rZsHqcMVgkhbQLW_pTapD5Z_6x4W-jeoi1Mremo8zaGaJAREceiIN5hYmiFhBEITx3r6dAdZrqfPSzbO11o-kwfKIWkm2v7hwJysRVOl80lN6EhSsX3MSMBrvYhE2SSc2UbAiD0J0B_DcrDUAbe_2Rj7ATijlCqCavLj6X3fZLmWVxPchdM845ZeSGU10DMy-6tKf6Pb92_farKNus2FLZLB-EFhXbOUjFFQVdX6nl5u-dleD3wOq-XhnKaAtRlNu3CJH38zFl91RISkN0o0uNDrFGzVHtkyKenKW_GcANKcUgEZBcBX5XxP_n7bICDEP9i7w6XA7xPgol8PF1vLJu70orNsxqB_Ki4GW46Li5ePCgqHDLRMa5-5dbhlPN4xARnPQ==","summary":[{"type":"summary_text","text":"**Starting targeted repository exploration**"}]},{"id":"fc_03e5b91f227b0634016a588fbcd7dc819bacf991c7225f4e6f","type":"function_call","status":"completed","arguments":"{\"i\":\"Mapping project root\",\"path\":\".\",\"selector\":null}","call_id":"call_pMompL5BST2p0qvLmpa4OMAY","name":"read"},{"id":"fc_03e5b91f227b0634016a588fbcd7ec819b81f28526d9d352cb","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating adapter commands\",\"pattern\":\"ready|live|custod|inject|@<|binding|background poll|turn\",\"path\":\"strings/omp-spt.mjs\",\"selector\":null,\"case\":false,\"gitignore\":true,\"skip\":null}","call_id":"call_QJnQjWKDJPwfaJ7TyOHmgFKz","name":"grep"},{"id":"fc_03e5b91f227b0634016a588fbcd7f4819b8beabbc539ff9791","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating extension tests\",\"pattern\":\"ready|live|custod|inject|@<|binding|background poll|turn\",\"path\":\"tests/omp-extension.mjs\",\"selector\":null,\"case\":false,\"gitignore\":true,\"skip\":null}","call_id":"call_d1fMZUFbcxhihxabspO5oQt4","name":"grep"},{"id":"fc_03e5b91f227b0634016a588fbcd7fc819bab2442b1e7ba3b5a","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding requirement artifacts\",\"path\":\".planning/**/*;docs/**/*;requirements/**/*\",\"hidden\":true,\"gitignore\":true,\"limit\":300}","call_id":"call_c7VNEyFLP5qasV9gWvllMzcG","name":"glob"}]},"duration":9339.888699999981,"ttft":2283.6637000000046,"contextSnapshot":{"promptTokens":26858,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_pMompL5BST2p0qvLmpa4OMAY|fc_03e5b91f227b0634016a588fbcd7dc819bacf991c7225f4e6f","toolName":"read","startedAt":"2026-07-16T08:01:00.905Z","args":{"path":"."},"intent":"Mapping project root"},"id":"eab8f92c","parentId":"92c093e5","timestamp":"2026-07-16T08:01:00.905Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_QJnQjWKDJPwfaJ7TyOHmgFKz|fc_03e5b91f227b0634016a588fbcd7ec819b81f28526d9d352cb","toolName":"grep","startedAt":"2026-07-16T08:01:00.906Z","args":{"path":"strings/omp-spt.mjs"},"intent":"Locating adapter commands"},"id":"7f3064ac","parentId":"eab8f92c","timestamp":"2026-07-16T08:01:00.906Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_d1fMZUFbcxhihxabspO5oQt4|fc_03e5b91f227b0634016a588fbcd7f4819b8beabbc539ff9791","toolName":"grep","startedAt":"2026-07-16T08:01:00.906Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Locating extension tests"},"id":"c4e4cdbd","parentId":"7f3064ac","timestamp":"2026-07-16T08:01:00.906Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_c7VNEyFLP5qasV9gWvllMzcG|fc_03e5b91f227b0634016a588fbcd7fc819bab2442b1e7ba3b5a","toolName":"glob","startedAt":"2026-07-16T08:01:00.907Z","args":{"path":".planning/**/*;docs/**/*;requirements/**/*"},"intent":"Finding requirement artifacts"},"id":"ac638ae6","parentId":"c4e4cdbd","timestamp":"2026-07-16T08:01:00.907Z"}
{"type":"message","id":"e4b28724","parentId":"ac638ae6","timestamp":"2026-07-16T08:01:00.911Z","message":{"role":"toolResult","toolCallId":"call_QJnQjWKDJPwfaJ7TyOHmgFKz|fc_03e5b91f227b0634016a588fbcd7ec819b81f28526d9d352cb","toolName":"grep","content":[{"type":"text","text":"Path not found: strings/omp-spt.mjs"}],"details":{},"isError":true,"timestamp":1784188860911}}
{"type":"message","id":"0d414136","parentId":"e4b28724","timestamp":"2026-07-16T08:01:00.913Z","message":{"role":"toolResult","toolCallId":"call_pMompL5BST2p0qvLmpa4OMAY|fc_03e5b91f227b0634016a588fbcd7dc819bacf991c7225f4e6f","toolName":"read","content":[{"type":"text","text":".\n  - .claude/                                 1h ago\n  - CONTEXT.md                     7.7KB     5h ago\n  - SCOPE.md                       4.7KB     5h ago\n  - traceable-reqs.toml            8.2KB     5h ago\n  - .spt/                                    20h ago\n    - omp-spt-env-v1/                        4m ago\n    - emphasys-signoff.md          1.5KB     20h ago\n    - emphasys-commune.md          10.4KB    22h ago\n  - .gitignore                     993B      20h ago\n  - OMP-ADAPTER-PLAN.md            8.2KB     21h ago\n  - CHANGELOG.md                   52.4KB    21h ago\n  - README.md                      4.4KB     21h ago\n  - DUPLICATE-HISTORY-PLAN.md      1.4KB     21h ago\n  - tests/                                   22h ago\n    - manifest-shortcut.sh         13.2KB    21h ago\n    - omp-extension.mjs            44.0KB    21h ago\n    - native-launch-manifest.sh    2.2KB     22h ago\n    - release-acquire.sh           4.4KB     22h ago\n    - manifest-schema.sh           3.3KB     1d ago\n    - adapter-archive.sh           7.4KB     1d ago\n    - ci-gates.sh                  878B      1d ago\n  - omp-spt-v0.2.0                 0B        22h ago\n  - docs/                                    22h ago\n    - PARITY.md                    6.0KB     5h ago\n    - adr/                                   6h ago\n    - CI.md                        6.6KB     22h ago\n    - RELEASE-RUNBOOK.md           12.5KB    22h ago\n    - DOCS-STRATEGY.md             10.1KB    1d ago\n    - KNOWN-HAZARDS.md             3.9KB     1d ago\n    - OMP-BRIDGE-FIELD-ISSUES.md   3.4KB     1d ago\n    - OMP-OPENROUTER.md            2.8KB     1d ago\n    - formats/                               6d ago\n    - SPT-CORE-FINDINGS.md         136.8KB   6d ago\n    - TRACEABILITY.md              5.3KB     6d ago\n    - SKILL-AUTHORING.md           5.2KB     6d ago\n  - adapter/                                 22h ago\n    - omp-spt.toml                 5.2KB     21h ago\n    - strings/                               1d ago\n    - manifest.schema.json         39.5KB    6d ago\n  - docs-site/                               1d ago\n    - book/                                  21h ago\n    - book.toml                    669B      1d ago\n    - llms.txt                     369B      1d ago\n    - src/                                   6d ago\n    - theme/                                 6d ago\n    - README.md                    427B      6d ago\n  - ci/                                      1d ago\n    - publish/                               22h ago\n    - run-gates.sh                 1.5KB     1d ago\n    - manifest/                              1d ago\n    - digest/                                6d ago\n  - tools/                                   1d ago\n    - omp-spt/                               1d ago\n  - UNIFY-CONSOLIDATE-PLAN.md      11.6KB    6d ago\n  - UPDATE-NAMING-DOYLE-ASKS.md    13.2KB    6d ago\n  - V09-PLAN.md                    6.1KB     6d ago\n  - V13-ADAPTER-PLAN.md            3.8KB     6d ago\n  - SKILLS-SLICE-PLAN.md           10.4KB    6d ago\n  - SPT_HARNESS_ADAPTER_TIPS.md    18.2KB    6d ago\n  - TRUNCATION-PROBE-PLAN.md       6.6KB     6d ago\n  - SESSIONSTART-BRIEF-PLAN.md     4.1KB     6d ago\n  - SETUP-SLICE-PLAN.md            13.1KB    6d ago\n  - SKELETON-PLAN.md               5.8KB     6d ago\n  - PEROS-RERELEASE-PLAN.md        3.7KB     6d ago\n  - PREP4-PLAN.md                  6.9KB     6d ago\n  - PSYCHE-EPHEMERAL-PLAN.md       13.1KB    6d ago\n  - PARITY-PUBLISH-PLAN.md         9.2KB     6d ago\n  - PEROS-PLAN.md                  2.7KB     6d ago\n  - HANDOFF.md                     8.5KB     6d ago\n  - MANIFEST-PARITY-PLAN.md        9.9KB     6d ago\n  - MDBOOK-PLAN.md                 2.6KB     6d ago\n  - NEXT-WORKLOAD-PLAN.md          12.0KB    6d ago\n  - DIGEST-FETCHER-PLAN.md         3.1KB     6d ago\n  - ECHO-COMMUNE-PLAN.md           3.1KB     6d ago\n  - CLAUDE.md                      286B      6d ago\n  - CPLUGS-PREP-PLAN.md            2.7KB     6d ago\n  - CHECKPOINT-CLEAR-RACE-PLAN.md  5.6KB     6d ago\n  - CHECKPOINT-COMMUNE-PLAN.md     11.1KB    6d ago\n  - CI-ACCEPTANCE-PLAN.md          3.2KB     6d ago\n  - BUGS-v091.md                   6.1KB     6d ago\n  - .gitattributes                 917B      6d ago\n  - AGENTS.md                      4.4KB     6d ago"}],"details":{"isDirectory":true,"resolvedPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt","meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt"}}},"isError":false,"timestamp":1784188860913}}
{"type":"message","id":"e06afbc8","parentId":"0d414136","timestamp":"2026-07-16T08:01:00.917Z","message":{"role":"toolResult","toolCallId":"call_c7VNEyFLP5qasV9gWvllMzcG|fc_03e5b91f227b0634016a588fbcd7fc819bab2442b1e7ba3b5a","toolName":"glob","content":[{"type":"text","text":"# docs/\nPARITY.md\nCI.md\nRELEASE-RUNBOOK.md\nDOCS-STRATEGY.md\nKNOWN-HAZARDS.md\nOMP-BRIDGE-FIELD-ISSUES.md\nOMP-OPENROUTER.md\nSPT-CORE-FINDINGS.md\nTRACEABILITY.md\nSKILL-AUTHORING.md\n## adr/\n0018-checkpoint-resets-context-natively.md\n0017-active-turn-delivery-uses-safe-boundaries.md\n0016-agent-capabilities-split-by-native-seam.md\n0015-extension-owned-session-activation.md\n0014-release-tags-use-semver-form.md\n0010-native-delivery-self-heals-or-closes.md\n0006-one-command-update-and-consolidated-binary.md\n0005-name-unification.md\n0004-checkpoint-via-self-send-loopback.md\n0003-psyche-is-a-constrained-auto-approving-companion.md\n0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md\n0001-distribution-splits-by-volatility.md\n0009-all-endpoints-use-native-omp.md\n0013-release-gate-stops-at-the-adapter-boundary.md\n0008-omp-native-product-boundary.md\n0012-continuity-drops-live-under-spt.md\n0011-endpoint-session-binding-is-immutable.md\n0007-native-omp-tui-hosts-spt-extension.md\n0000-template.md\n## formats/\nadr-format.md\ncontext-format.md\n\nSkipped missing paths: .planning/**/*, requirements/**/*"}],"details":{"scopePath":"docs","fileCount":33,"files":["docs/PARITY.md","docs/adr/0018-checkpoint-resets-context-natively.md","docs/adr/","docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md","docs/adr/0016-agent-capabilities-split-by-native-seam.md","docs/adr/0015-extension-owned-session-activation.md","docs/adr/0014-release-tags-use-semver-form.md","docs/CI.md","docs/RELEASE-RUNBOOK.md","docs/adr/0010-native-delivery-self-heals-or-closes.md","docs/DOCS-STRATEGY.md","docs/adr/0006-one-command-update-and-consolidated-binary.md","docs/adr/0005-name-unification.md","docs/adr/0004-checkpoint-via-self-send-loopback.md","docs/adr/0003-psyche-is-a-constrained-auto-approving-companion.md","docs/adr/0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md","docs/adr/0001-distribution-splits-by-volatility.md","docs/KNOWN-HAZARDS.md","docs/OMP-BRIDGE-FIELD-ISSUES.md","docs/adr/0009-all-endpoints-use-native-omp.md","docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md","docs/adr/0008-omp-native-product-boundary.md","docs/adr/0012-continuity-drops-live-under-spt.md","docs/adr/0011-endpoint-session-binding-is-immutable.md","docs/adr/0007-native-omp-tui-hosts-spt-extension.md","docs/OMP-OPENROUTER.md","docs/formats/","docs/formats/adr-format.md","docs/formats/context-format.md","docs/SPT-CORE-FINDINGS.md","docs/TRACEABILITY.md","docs/adr/0000-template.md","docs/SKILL-AUTHORING.md"],"truncated":false,"cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","missingPaths":[".planning/**/*","requirements/**/*"]},"isError":false,"timestamp":1784188860917}}
{"type":"message","id":"8189b06e","parentId":"e06afbc8","timestamp":"2026-07-16T08:01:00.936Z","message":{"role":"toolResult","toolCallId":"call_d1fMZUFbcxhihxabspO5oQt4|fc_03e5b91f227b0634016a588fbcd7f4819b8beabbc539ff9791","toolName":"grep","content":[{"type":"text","text":"[tests/omp-extension.mjs#8FB4]\n 18:\t});\n*19:\treturn { promise, reject, resolve };\n 20:}\n 21:\n 22:class FakeStream extends EventEmitter {\n...\n 28:\t\tthis.input = input;\n*29:\t\tif (this.onEnd?.(input) === false) return;\n 30:\t\tthis.emit(\"finish\");\n 31:\t}\n 32:}\n...\n 56:\t\tconst handled = this.onKill?.(signal, this);\n*57:\t\tif (handled !== undefined) return handled;\n 58:\t\tthis.close(null, signal);\n*59:\t\treturn true;\n 60:\t}\n 61:}\n 62:\n...\n 71:\t\tthis.timers.set(handle, { fn, delay });\n*72:\t\treturn handle;\n 73:\t}\n 74:\n 75:\tclearTimeout(handle) {\n...\n 79:\tdelays() {\n*80:\t\treturn [...this.timers.values()].map(({ delay }) => delay);\n 81:\t}\n 82:\n 83:\tasync runNext(expectedDelay) {\n...\n 143:\t\tconst overridden = await options.onRun?.(call);\n*144:\t\tif (overridden !== undefined) return overridden;\n 145:\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\n*146:\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\n 147:\t\t}\n*148:\t\treturn \"\";\n 149:\t};\n 150:\tconst spawnProcess = (binary, args, spawnOptions) => {\n 151:\t\tconst child = new FakeChild();\n...\n 156:\t\tchildren.push(child);\n*157:\t\treturn child;\n 158:\t};\n 159:\tconst extension = createOmpSpt({\n 160:\t\tenv: {\n...\n 185:\t\tfor (const handler of handlers.get(name) ?? []) {\n*186:\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\n*187:\t\t\tif (returned !== undefined) result = returned;\n 188:\t\t}\n*189:\t\treturn result;\n 190:\t}\n 191:\n*192:\treturn {\n 193:\t\tcalls,\n 194:\t\tchildren,\n 195:\t\tclock,\n...\n 204:\t\tget shutdowns() {\n*205:\t\t\treturn shutdowns;\n 206:\t\t},\n 207:\t};\n 208:}\n...\n 210:function commandCalls(harness, command) {\n*211:\treturn harness.calls.filter((call) => call.args[0] === command);\n 212:}\n 213:\n 214:function stateCalls(harness) {\n*215:\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n 216:}\n 217:\n 218:async function testParsingAndReplies() {\n...\n 279:\n*280:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 281:// [unit->REQ-OMP-SESSION-IMMUTABLE]\n 282:// [unit->REQ-OMP-MESSAGE-CONTEXT]\n 283:// [unit->REQ-OMP-NATIVE-TUI]\n*284:async function testLifecycleCustodyAndContext() {\n 285:\tconst harness = createHarness({ subnet: \"mesh-a\" });\n 286:\tassert.deepEqual([...harness.handlers.keys()], [\n 287:\t\t\"session_start\",\n...\n 376:\t\t[\"idle\", \"busy\"],\n*377:\t\t\"agent_start must not duplicate the already-honest busy transition\",\n 378:\t);\n 379:\tawait harness.emit(\"agent_end\", {\n 380:\t\tmessages: [\n...\n 407:\tassert.equal(outcomes[0].input, \"alice reply\");\n*408:\tassert.match(outcomes[1].input, /turn ended without an assistant response/);\n 409:\tassert.deepEqual(\n 410:\t\tstateCalls(harness).map((call) => call.args[4]),\n 411:\t\t[\"idle\", \"busy\", \"idle\", \"busy\", \"idle\"],\n...\n 428:\t\tonRun(call) {\n*429:\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return busyBind.promise;\n 430:\t\t},\n 431:\t});\n 432:\tconst startingBusy = busyHarness.emit(\"session_start\");\n...\n 452:\t\tonRun(call) {\n*453:\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return shutdownBind.promise;\n 454:\t\t},\n 455:\t});\n 456:\tconst startingShutdown = shutdownHarness.emit(\"session_start\");\n...\n 475:\t\t!shutdownHarness.statuses.some(({ text }) => text === \"spt:omp-agent\"),\n*476:\t\t\"bind completion after shutdown must not restore live status\",\n 477:\t);\n 478:\tassert.deepEqual(shutdownHarness.clock.delays(), []);\n 479:\n...\n 481:\t\tonRun(call) {\n*482:\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return new Promise(() => {});\n 483:\t\t},\n 484:\t});\n 485:\tconst hungStart = hungBindHarness.emit(\"session_start\");\n...\n 500:\n*501:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 502:// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n 503:async function testOutcomeSendRetriesAndExhaustion() {\n 504:\tlet retryAttempts = 0;\n...\n 557:\t\t\t{ role: \"user\", content: '<msg from=\"exhausted\"/>' },\n*558:\t\t\t{ role: \"assistant\", content: \"undeliverable outcome\" },\n 559:\t\t],\n 560:\t});\n 561:\tawait flush();\n...\n 570:\t\t[\"idle\", \"busy\"],\n*571:\t\t\"exhausted custody must never be advertised idle\",\n 572:\t);\n 573:\tassert.equal(exhaustedHarness.shutdowns, 1);\n 574:\tassert.equal(exhaustedListener.kills, 1);\n...\n 587:\n*588:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 589:async function testSubmissionFailureAdvancesQueue() {\n 590:\tconst harness = createHarness({\n 591:\t\tonSubmit(content) {\n...\n 711:\n*712:\tconst shortLived = harness.children[1];\n*713:\tshortLived.stdout.emit(\n 714:\t\t\"data\",\n 715:\t\t'<EVENT type=\"msg\" from=\"proof\">a parsed event is not stability</EVENT>',\n 716:\t);\n*717:\tshortLived.emit(\"close\", 2);\n 718:\tassert.deepEqual(\n 719:\t\tharness.clock.delays(),\n 720:\t\t[10],\n...\n 744:\n*745:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 746:// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n 747:async function testFatalTeardownAwaitsInFlightOutcome() {\n 748:\tlet releaseOutcome;\n...\n 754:\t\tonRun(call) {\n*755:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"slow\") return outcomeGate;\n 756:\t\t},\n 757:\t});\n 758:\tawait harness.emit(\"session_start\");\n...\n 780:\t\t0,\n*781:\t\t\"concurrent lifecycle shutdown must join fatal custody teardown\",\n 782:\t);\n 783:\tfor (const reason of [\"new\", \"resume\", \"fork\", \"handoff\"]) {\n 784:\t\tassert.deepEqual(\n...\n 786:\t\t\t{ cancel: true },\n*787:\t\t\t`teardown must keep blocking the ${reason} switch while custody is pending`,\n 788:\t\t);\n 789:\t}\n 790:\tassert.deepEqual(\n...\n 792:\t\t{ cancel: true },\n*793:\t\t\"teardown must keep blocking branches while custody is pending\",\n 794:\t);\n 795:\n 796:\treleaseOutcome();\n...\n 812:\t\t\t\tendAttempts += 1;\n*813:\t\t\t\tif (endAttempts === 1) return firstEnd.promise;\n 814:\t\t\t}\n 815:\t\t},\n 816:\t});\n...\n 870:\n*871:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 872:// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n*873:async function testShutdownReapsAndFailsQueuedCustody() {\n 874:\tconst harness = createHarness();\n 875:\tawait harness.emit(\"session_start\");\n 876:\tconst listener = harness.children[0];\n...\n 908:\t\tepipeChild.stdin.emit(\"error\", epipe);\n*909:\t\treturn false;\n 910:\t};\n 911:\tawait assert.rejects(\n 912:\t\trunSpt([\"send\", \"peer\", \"--from\", \"omp-agent\"], \"reply\", {\n...\n 928:\t\tfastExitChild.close(0);\n*929:\t\treturn false;\n 930:\t};\n 931:\tawait assert.rejects(\n 932:\t\trunSpt([\"send\", \"peer\", \"--from\", \"omp-agent\"], \"reply\", {\n...\n 978:\t\t\t\tif (signal === \"SIGKILL\") child.close(null, signal);\n*979:\t\t\t\treturn true;\n 980:\t\t\t};\n 981:\t\t},\n 982:\t});\n...\n 1001:\t\t\t\tif (signal === \"SIGKILL\") child.close(null, signal);\n*1002:\t\t\t\treturn true;\n 1003:\t\t\t};\n 1004:\t\t},\n 1005:\t});\n...\n 1022:\n*1023:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 1024:// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n 1025:async function testProtocolCorruptionFailsClosed() {\n 1026:\tasync function failProtocol(payload, expected, options = {}) {\n...\n 1043:\t\tawait harness.emit(\"session_shutdown\");\n*1044:\t\treturn harness;\n 1045:\t}\n 1046:\n 1047:\tconst truncatedA =\n...\n 1061:\n*1062:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 1063:// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n*1064:async function testInboundQueueOverflowReturnsAcceptedCustody() {\n 1065:\tconst frames = [\"a\", \"b\", \"overflow\"].map(\n 1066:\t\t(from) => `<EVENT type=\"msg\" from=\"${from}\">work</EVENT>`,\n 1067:\t);\n...\n 1087:\t\tharness.errors.some(({ message }) =>\n*1088:\t\t\tmessage.includes(\"inbound custody capacity exceeded\"),\n 1089:\t\t),\n 1090:\t);\n 1091:\tassert.equal(harness.calls.filter((call) => call.args[3] === \"session-end\").length, 1);\n...\n 1121:\t\t\t\tattempts += 1;\n*1122:\t\t\t\tif (attempts === 1) return firstOutcome.promise;\n 1123:\t\t\t}\n 1124:\t\t},\n 1125:\t});\n...\n 1151:\tassert.equal(commandCalls(harness, \"send\").at(-1).input, \"completed outcome\");\n*1152:\tassert.equal(harness.children[0].kills, 0, \"ordinary session_stop must leave the endpoint live\");\n 1153:\tassert.equal(harness.calls.filter((call) => call.args[3] === \"session-end\").length, 0);\n 1154:\n 1155:\tawait harness.emit(\"session_shutdown\");\n...\n 1160:\n*1161:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 1162:// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n 1163:async function testShutdownFallbackStaysBelowHostCap() {\n 1164:\tconst never = new Promise(() => {});\n...\n 1168:\t\tonRun(call) {\n*1169:\t\t\tif (call.args[0] === \"send\" || call.args[3] === \"session-end\") return never;\n 1170:\t\t},\n 1171:\t});\n 1172:\tawait harness.emit(\"session_start\");\n...\n 1184:\t\t[300, 1_800],\n*1185:\t\t\"queued custody has a short command timeout inside the 2s host cap\",\n 1186:\t);\n 1187:\tawait harness.clock.runNext(300);\n 1188:\tassert.equal(commandCalls(harness, \"send\").length, 1);\n...\n 1196:\t\tharness.errors.some(({ message }) =>\n*1197:\t\t\tmessage.includes(\"could not return custody to queued\"),\n 1198:\t\t),\n 1199:\t);\n 1200:\tassert.equal(harness.calls.filter((call) => call.args[3] === \"session-end\").length, 1);\n...\n 1210:\t\t\t\tqueuedSendIndex += 1;\n*1211:\t\t\t\treturn gate.promise;\n 1212:\t\t\t}\n 1213:\t\t},\n 1214:\t});\n...\n 1226:\t\t[\"queued-a\", \"queued-b\"],\n*1227:\t\t\"all pending custody failures must start concurrently\",\n 1228:\t);\n 1229:\tassert.deepEqual(\n 1230:\t\tconcurrentHarness.clock.delays().sort((a, b) => a - b),\n...\n 1244:\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"state\" && call.args[4] === \"busy\") {\n*1245:\t\t\t\treturn busyGate.promise;\n 1246:\t\t\t}\n 1247:\t\t},\n 1248:\t});\n...\n 1283:\t\t\t\tinFlightAttempts += 1;\n*1284:\t\t\t\tif (inFlightAttempts === 1) return inFlightOutcome.promise;\n 1285:\t\t\t}\n 1286:\t\t},\n 1287:\t});\n...\n 1325:\t\tonRun(call) {\n*1326:\t\t\tif (call.args[0] === \"send\") return never;\n 1327:\t\t},\n 1328:\t});\n 1329:\tawait hardCapHarness.emit(\"session_start\");\n...\n 1359:await testRunSptRejectsStdinErrorsAndHungCommands();\n*1360:await testLifecycleCustodyAndContext();\n 1361:await testDeferredBindLifecycleSerialization();\n 1362:await testOutcomeSendRetriesAndExhaustion();\n 1363:await testSubmissionFailureAdvancesQueue();\n...\n 1369:await testHumanBusyFailureFailsClosed();\n*1370:await testShutdownReapsAndFailsQueuedCustody();\n 1371:await testListenerTerminationEscalatesAndReaps();\n 1372:await testProtocolCorruptionFailsClosed();\n*1373:await testInboundQueueOverflowReturnsAcceptedCustody();\n 1374:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n 1375:await testShutdownFallbackStaysBelowHostCap();\n 1376:"}],"details":{"scopePath":"tests/omp-extension.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":63,"fileCount":1,"files":["tests/omp-extension.mjs"],"fileMatches":[{"path":"tests/omp-extension.mjs","count":63}],"truncated":false,"displayContent":"   18│\t});\n  *19│\treturn { promise, reject, resolve };\n   20│}\n   21│\n   22│class FakeStream extends EventEmitter {\n     │...\n   28│\t\tthis.input = input;\n  *29│\t\tif (this.onEnd?.(input) === false) return;\n   30│\t\tthis.emit(\"finish\");\n   31│\t}\n   32│}\n     │...\n   56│\t\tconst handled = this.onKill?.(signal, this);\n  *57│\t\tif (handled !== undefined) return handled;\n   58│\t\tthis.close(null, signal);\n  *59│\t\treturn true;\n   60│\t}\n   61│}\n   62│\n     │...\n   71│\t\tthis.timers.set(handle, { fn, delay });\n  *72│\t\treturn handle;\n   73│\t}\n   74│\n   75│\tclearTimeout(handle) {\n     │...\n   79│\tdelays() {\n  *80│\t\treturn [...this.timers.values()].map(({ delay }) => delay);\n   81│\t}\n   82│\n   83│\tasync runNext(expectedDelay) {\n     │...\n  143│\t\tconst overridden = await options.onRun?.(call);\n *144│\t\tif (overridden !== undefined) return overridden;\n  145│\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\n *146│\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\n  147│\t\t}\n *148│\t\treturn \"\";\n  149│\t};\n  150│\tconst spawnProcess = (binary, args, spawnOptions) => {\n  151│\t\tconst child = new FakeChild();\n     │...\n  156│\t\tchildren.push(child);\n *157│\t\treturn child;\n  158│\t};\n  159│\tconst extension = createOmpSpt({\n  160│\t\tenv: {\n     │...\n  185│\t\tfor (const handler of handlers.get(name) ?? []) {\n *186│\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\n *187│\t\t\tif (returned !== undefined) result = returned;\n  188│\t\t}\n *189│\t\treturn result;\n  190│\t}\n  191│\n *192│\treturn {\n  193│\t\tcalls,\n  194│\t\tchildren,\n  195│\t\tclock,\n     │...\n  204│\t\tget shutdowns() {\n *205│\t\t\treturn shutdowns;\n  206│\t\t},\n  207│\t};\n  208│}\n     │...\n  210│function commandCalls(harness, command) {\n *211│\treturn harness.calls.filter((call) => call.args[0] === command);\n  212│}\n  213│\n  214│function stateCalls(harness) {\n *215│\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n  216│}\n  217│\n  218│async function testParsingAndReplies() {\n     │...\n  279│\n *280│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n  281│// [unit->REQ-OMP-SESSION-IMMUTABLE]\n  282│// [unit->REQ-OMP-MESSAGE-CONTEXT]\n  283│// [unit->REQ-OMP-NATIVE-TUI]\n *284│async function testLifecycleCustodyAndContext() {\n  285│\tconst harness = createHarness({ subnet: \"mesh-a\" });\n  286│\tassert.deepEqual([...harness.handlers.keys()], [\n  287│\t\t\"session_start\",\n     │...\n  376│\t\t[\"idle\", \"busy\"],\n *377│\t\t\"agent_start must not duplicate the already-honest busy transition\",\n  378│\t);\n  379│\tawait harness.emit(\"agent_end\", {\n  380│\t\tmessages: [\n     │...\n  407│\tassert.equal(outcomes[0].input, \"alice reply\");\n *408│\tassert.match(outcomes[1].input, /turn ended without an assistant response/);\n  409│\tassert.deepEqual(\n  410│\t\tstateCalls(harness).map((call) => call.args[4]),\n  411│\t\t[\"idle\", \"busy\", \"idle\", \"busy\", \"idle\"],\n     │...\n  428│\t\tonRun(call) {\n *429│\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return busyBind.promise;\n  430│\t\t},\n  431│\t});\n  432│\tconst startingBusy = busyHarness.emit(\"session_start\");\n     │...\n  452│\t\tonRun(call) {\n *453│\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return shutdownBind.promise;\n  454│\t\t},\n  455│\t});\n  456│\tconst startingShutdown = shutdownHarness.emit(\"session_start\");\n     │...\n  475│\t\t!shutdownHarness.statuses.some(({ text }) => text === \"spt:omp-agent\"),\n *476│\t\t\"bind completion after shutdown must not restore live status\",\n  477│\t);\n  478│\tassert.deepEqual(shutdownHarness.clock.delays(), []);\n  479│\n     │...\n  481│\t\tonRun(call) {\n *482│\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return new Promise(() => {});\n  483│\t\t},\n  484│\t});\n  485│\tconst hungStart = hungBindHarness.emit(\"session_start\");\n     │...\n  500│\n *501│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n  502│// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n  503│async function testOutcomeSendRetriesAndExhaustion() {\n  504│\tlet retryAttempts = 0;\n     │...\n  557│\t\t\t{ role: \"user\", content: '<msg from=\"exhausted\"/>' },\n *558│\t\t\t{ role: \"assistant\", content: \"undeliverable outcome\" },\n  559│\t\t],\n  560│\t});\n  561│\tawait flush();\n     │...\n  570│\t\t[\"idle\", \"busy\"],\n *571│\t\t\"exhausted custody must never be advertised idle\",\n  572│\t);\n  573│\tassert.equal(exhaustedHarness.shutdowns, 1);\n  574│\tassert.equal(exhaustedListener.kills, 1);\n     │...\n  587│\n *588│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n  589│async function testSubmissionFailureAdvancesQueue() {\n  590│\tconst harness = createHarness({\n  591│\t\tonSubmit(content) {\n     │...\n  711│\n *712│\tconst shortLived = harness.children[1];\n *713│\tshortLived.stdout.emit(\n  714│\t\t\"data\",\n  715│\t\t'<EVENT type=\"msg\" from=\"proof\">a parsed event is not stability</EVENT>',\n  716│\t);\n *717│\tshortLived.emit(\"close\", 2);\n  718│\tassert.deepEqual(\n  719│\t\tharness.clock.delays(),\n  720│\t\t[10],\n     │...\n  744│\n *745│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n  746│// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n  747│async function testFatalTeardownAwaitsInFlightOutcome() {\n  748│\tlet releaseOutcome;\n     │...\n  754│\t\tonRun(call) {\n *755│\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"slow\") return outcomeGate;\n  756│\t\t},\n  757│\t});\n  758│\tawait harness.emit(\"session_start\");\n     │...\n  780│\t\t0,\n *781│\t\t\"concurrent lifecycle shutdown must join fatal custody teardown\",\n  782│\t);\n  783│\tfor (const reason of [\"new\", \"resume\", \"fork\", \"handoff\"]) {\n  784│\t\tassert.deepEqual(\n     │...\n  786│\t\t\t{ cancel: true },\n *787│\t\t\t`teardown must keep blocking the ${reason} switch while custody is pending`,\n  788│\t\t);\n  789│\t}\n  790│\tassert.deepEqual(\n     │...\n  792│\t\t{ cancel: true },\n *793│\t\t\"teardown must keep blocking branches while custody is pending\",\n  794│\t);\n  795│\n  796│\treleaseOutcome();\n     │...\n  812│\t\t\t\tendAttempts += 1;\n *813│\t\t\t\tif (endAttempts === 1) return firstEnd.promise;\n  814│\t\t\t}\n  815│\t\t},\n  816│\t});\n     │...\n  870│\n *871│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n  872│// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n *873│async function testShutdownReapsAndFailsQueuedCustody() {\n  874│\tconst harness = createHarness();\n  875│\tawait harness.emit(\"session_start\");\n  876│\tconst listener = harness.children[0];\n     │...\n  908│\t\tepipeChild.stdin.emit(\"error\", epipe);\n *909│\t\treturn false;\n  910│\t};\n  911│\tawait assert.rejects(\n  912│\t\trunSpt([\"send\", \"peer\", \"--from\", \"omp-agent\"], \"reply\", {\n     │...\n  928│\t\tfastExitChild.close(0);\n *929│\t\treturn false;\n  930│\t};\n  931│\tawait assert.rejects(\n  932│\t\trunSpt([\"send\", \"peer\", \"--from\", \"omp-agent\"], \"reply\", {\n     │...\n  978│\t\t\t\tif (signal === \"SIGKILL\") child.close(null, signal);\n *979│\t\t\t\treturn true;\n  980│\t\t\t};\n  981│\t\t},\n  982│\t});\n     │...\n 1001│\t\t\t\tif (signal === \"SIGKILL\") child.close(null, signal);\n*1002│\t\t\t\treturn true;\n 1003│\t\t\t};\n 1004│\t\t},\n 1005│\t});\n     │...\n 1022│\n*1023│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 1024│// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n 1025│async function testProtocolCorruptionFailsClosed() {\n 1026│\tasync function failProtocol(payload, expected, options = {}) {\n     │...\n 1043│\t\tawait harness.emit(\"session_shutdown\");\n*1044│\t\treturn harness;\n 1045│\t}\n 1046│\n 1047│\tconst truncatedA =\n     │...\n 1061│\n*1062│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 1063│// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n*1064│async function testInboundQueueOverflowReturnsAcceptedCustody() {\n 1065│\tconst frames = [\"a\", \"b\", \"overflow\"].map(\n 1066│\t\t(from) => `<EVENT type=\"msg\" from=\"${from}\">work</EVENT>`,\n 1067│\t);\n     │...\n 1087│\t\tharness.errors.some(({ message }) =>\n*1088│\t\t\tmessage.includes(\"inbound custody capacity exceeded\"),\n 1089│\t\t),\n 1090│\t);\n 1091│\tassert.equal(harness.calls.filter((call) => call.args[3] === \"session-end\").length, 1);\n     │...\n 1121│\t\t\t\tattempts += 1;\n*1122│\t\t\t\tif (attempts === 1) return firstOutcome.promise;\n 1123│\t\t\t}\n 1124│\t\t},\n 1125│\t});\n     │...\n 1151│\tassert.equal(commandCalls(harness, \"send\").at(-1).input, \"completed outcome\");\n*1152│\tassert.equal(harness.children[0].kills, 0, \"ordinary session_stop must leave the endpoint live\");\n 1153│\tassert.equal(harness.calls.filter((call) => call.args[3] === \"session-end\").length, 0);\n 1154│\n 1155│\tawait harness.emit(\"session_shutdown\");\n     │...\n 1160│\n*1161│// [unit->REQ-OMP-EXTENSION-CUSTODY]\n 1162│// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n 1163│async function testShutdownFallbackStaysBelowHostCap() {\n 1164│\tconst never = new Promise(() => {});\n     │...\n 1168│\t\tonRun(call) {\n*1169│\t\t\tif (call.args[0] === \"send\" || call.args[3] === \"session-end\") return never;\n 1170│\t\t},\n 1171│\t});\n 1172│\tawait harness.emit(\"session_start\");\n     │...\n 1184│\t\t[300, 1_800],\n*1185│\t\t\"queued custody has a short command timeout inside the 2s host cap\",\n 1186│\t);\n 1187│\tawait harness.clock.runNext(300);\n 1188│\tassert.equal(commandCalls(harness, \"send\").length, 1);\n     │...\n 1196│\t\tharness.errors.some(({ message }) =>\n*1197│\t\t\tmessage.includes(\"could not return custody to queued\"),\n 1198│\t\t),\n 1199│\t);\n 1200│\tassert.equal(harness.calls.filter((call) => call.args[3] === \"session-end\").length, 1);\n     │...\n 1210│\t\t\t\tqueuedSendIndex += 1;\n*1211│\t\t\t\treturn gate.promise;\n 1212│\t\t\t}\n 1213│\t\t},\n 1214│\t});\n     │...\n 1226│\t\t[\"queued-a\", \"queued-b\"],\n*1227│\t\t\"all pending custody failures must start concurrently\",\n 1228│\t);\n 1229│\tassert.deepEqual(\n 1230│\t\tconcurrentHarness.clock.delays().sort((a, b) => a - b),\n     │...\n 1244│\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"state\" && call.args[4] === \"busy\") {\n*1245│\t\t\t\treturn busyGate.promise;\n 1246│\t\t\t}\n 1247│\t\t},\n 1248│\t});\n     │...\n 1283│\t\t\t\tinFlightAttempts += 1;\n*1284│\t\t\t\tif (inFlightAttempts === 1) return inFlightOutcome.promise;\n 1285│\t\t\t}\n 1286│\t\t},\n 1287│\t});\n     │...\n 1325│\t\tonRun(call) {\n*1326│\t\t\tif (call.args[0] === \"send\") return never;\n 1327│\t\t},\n 1328│\t});\n 1329│\tawait hardCapHarness.emit(\"session_start\");\n     │...\n 1359│await testRunSptRejectsStdinErrorsAndHungCommands();\n*1360│await testLifecycleCustodyAndContext();\n 1361│await testDeferredBindLifecycleSerialization();\n 1362│await testOutcomeSendRetriesAndExhaustion();\n 1363│await testSubmissionFailureAdvancesQueue();\n     │...\n 1369│await testHumanBusyFailureFailsClosed();\n*1370│await testShutdownReapsAndFailsQueuedCustody();\n 1371│await testListenerTerminationEscalatesAndReaps();\n 1372│await testProtocolCorruptionFailsClosed();\n*1373│await testInboundQueueOverflowReturnsAcceptedCustody();\n 1374│await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n 1375│await testShutdownFallbackStaysBelowHostCap();\n 1376│"},"isError":false,"timestamp":1784188860936}}
{"type":"message","id":"9844225e","parentId":"8189b06e","timestamp":"2026-07-16T08:01:08.661Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Searching for correct file path**"},{"type":"toolCall","id":"call_yzdNGiWQlA1ekfpHmkE7yDB7|fc_03e5b91f227b0634016a588fc49d68819badcf6608317323c2","name":"grep","arguments":{"i":"Locating adapter internals","pattern":"ready|live|custod|inject|@<|binding|background poll|turn","path":"adapter/strings/omp-spt.mjs","selector":null,"case":false,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_fPzh2GqS5U6kGVccghZjCCVE|fc_03e5b91f227b0634016a588fc49d78819b972f6da106b584d1","name":"read","arguments":{"i":"Reading adapter manifest","path":"adapter/omp-spt.toml","selector":"1-240"}},{"type":"toolCall","id":"call_57HiMRymYCAGC3TDqUk9ja18|fc_03e5b91f227b0634016a588fc49d84819ba92c236ee23de2ea","name":"read","arguments":{"i":"Reading active delivery ADR","path":"docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md","selector":"1-240"}},{"type":"toolCall","id":"call_cvl80fZvfas9XYn0iewmFoo5|fc_03e5b91f227b0634016a588fc49d88819bba447645f76f02a2","name":"read","arguments":{"i":"Reading activation ADR","path":"docs/adr/0015-extension-owned-session-activation.md","selector":"1-240"}},{"type":"toolCall","id":"call_kHnZnyw59dYfA0F2AeAoMi6W|fc_03e5b91f227b0634016a588fc49d90819b8b32fa8c9102c3e7","name":"grep","arguments":{"i":"Finding extension requirements","pattern":"READY|LIVE|ACTIVE|SHORTFORM|OUTPUT|DISPATCH|AUTO.RESUME|CUSTODY|LISTENER|BIND","path":"traceable-reqs.toml","selector":null,"case":false,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6081,"output":290,"cacheRead":26112,"cacheWrite":0,"totalTokens":32483,"reasoningTokens":19,"cost":{"input":0.030405,"output":0.0087,"cacheRead":0.013056,"cacheWrite":0,"total":0.052161}},"stopReason":"toolUse","timestamp":1784188860979,"responseId":"resp_03e5b91f227b0634016a588fbd4870819b96f4713a410a1eea","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03e5b91f227b0634016a588fbf67c8819b9b091eeeb41a8c04","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWI_E7-KHEnw4jqbv_ioS25qpYDgqdRu2ecCfgOFXY2Z5VpsmZ_44Lc2ji3yEZzjtuALHeVaysOr7Vu21IdDMuP9Scu2bj9QWGBZH_Ml84hZiJ2okbekOUj9chu-Anp28yG0rr6TKpinB_gJLBXbHPvxVanAs7XZdaHSXLt4ELPo5W5YHLXhvMt9i-txFEYJbcpgVGSMKwxbJmSMLjTnbrETTVb8fzHDYgfACfzXSJRFnZrdswv7KAl9Cb78IuzicnxnlCL6L44EFhnuBJ9So-1VmpKqeOgYUZfo2VGwBH5QSYdn3y_MrAcDZxcH-RjMNHkYml1TVJ7qII-tG7WMbVLROc2aESBgnRTOekZUXmCdR_7Ktwopw1zJm9kh7Ed_9oR0MsShzCx7E5tXJBMFQZ3q-3Xd_Zs_NoRa6Qq2JXoHsvLh_yhcdqO2Vzm-XINNbd-bOaU7xaQx-fRrd6nWea3kW93r5qUVSVLJKWjrDpfynTh0vodSp7P2OVjFbhoa1_dAUH5WevmwKTm0UUCbPizOiBg2qHtdVKcjav9oIsmuTrBQhBuNkGe9nnUAHZpIoFPAKbSwHKatSAcLEFtIfrNrpaO8xFLni9FfkWZMTyySkbK6gnF_AYSloxA2gPa3KkMzcrsNH-3wlgaa4II4ldMnp0s2RWlz7CE1_MrcPizLNcrDJJm90lS5n1gfYPgZ_tbuHlEFwQ_36AfCrmxjNJgayVvdzVmLTWUi0gQ7YXEusyglDgDTSD6tMKP4zV-nJ7uwOO_Nj7JqXzS0zzQuao9IlJXnf0HxqXxu5UPx1Zx6QRs0DEQA_sGIXTuciLFUYDuT-dJvcxI9BuPRK_tnz1XL5VSsbiL69UWLarvEfuGLM_pw4lqRi2HxyXp4HEF7ATr5oEiuj44p-0A0rrJffF2xEgGM0lBYO6O7cI4-dM7SbbYeic4Y5_z8vQAc-4g_59Z0N0etNiM1xw9QWYqiHpF2b_PgSE8mrhfqmfw9PZpXL0dw=","summary":[{"type":"summary_text","text":"**Searching for correct file path**"}]},{"id":"fc_03e5b91f227b0634016a588fc49d68819badcf6608317323c2","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating adapter internals\",\"pattern\":\"ready|live|custod|inject|@<|binding|background poll|turn\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":null,\"case\":false,\"gitignore\":true,\"skip\":null}","call_id":"call_yzdNGiWQlA1ekfpHmkE7yDB7","name":"grep"},{"id":"fc_03e5b91f227b0634016a588fc49d78819b972f6da106b584d1","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading adapter manifest\",\"path\":\"adapter/omp-spt.toml\",\"selector\":\"1-240\"}","call_id":"call_fPzh2GqS5U6kGVccghZjCCVE","name":"read"},{"id":"fc_03e5b91f227b0634016a588fc49d84819ba92c236ee23de2ea","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading active delivery ADR\",\"path\":\"docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md\",\"selector\":\"1-240\"}","call_id":"call_57HiMRymYCAGC3TDqUk9ja18","name":"read"},{"id":"fc_03e5b91f227b0634016a588fc49d88819bba447645f76f02a2","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading activation ADR\",\"path\":\"docs/adr/0015-extension-owned-session-activation.md\",\"selector\":\"1-240\"}","call_id":"call_cvl80fZvfas9XYn0iewmFoo5","name":"read"},{"id":"fc_03e5b91f227b0634016a588fc49d90819b8b32fa8c9102c3e7","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding extension requirements\",\"pattern\":\"READY|LIVE|ACTIVE|SHORTFORM|OUTPUT|DISPATCH|AUTO.RESUME|CUSTODY|LISTENER|BIND\",\"path\":\"traceable-reqs.toml\",\"selector\":null,\"case\":false,\"gitignore\":true,\"skip\":null}","call_id":"call_kHnZnyw59dYfA0F2AeAoMi6W","name":"grep"}]},"duration":7680.882500000007,"ttft":2416.324399999983,"contextSnapshot":{"promptTokens":32193,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_yzdNGiWQlA1ekfpHmkE7yDB7|fc_03e5b91f227b0634016a588fc49d68819badcf6608317323c2","toolName":"grep","startedAt":"2026-07-16T08:01:08.661Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Locating adapter internals"},"id":"9ff526ce","parentId":"9844225e","timestamp":"2026-07-16T08:01:08.661Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_fPzh2GqS5U6kGVccghZjCCVE|fc_03e5b91f227b0634016a588fc49d78819b972f6da106b584d1","toolName":"read","startedAt":"2026-07-16T08:01:08.661Z","args":{"path":"adapter/omp-spt.toml"},"intent":"Reading adapter manifest"},"id":"8b59215a","parentId":"9ff526ce","timestamp":"2026-07-16T08:01:08.661Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_57HiMRymYCAGC3TDqUk9ja18|fc_03e5b91f227b0634016a588fc49d84819ba92c236ee23de2ea","toolName":"read","startedAt":"2026-07-16T08:01:08.661Z","args":{"path":"docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md"},"intent":"Reading active delivery ADR"},"id":"40f4cf4c","parentId":"8b59215a","timestamp":"2026-07-16T08:01:08.661Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_cvl80fZvfas9XYn0iewmFoo5|fc_03e5b91f227b0634016a588fc49d88819bba447645f76f02a2","toolName":"read","startedAt":"2026-07-16T08:01:08.661Z","args":{"path":"docs/adr/0015-extension-owned-session-activation.md"},"intent":"Reading activation ADR"},"id":"f968d5f6","parentId":"40f4cf4c","timestamp":"2026-07-16T08:01:08.661Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_kHnZnyw59dYfA0F2AeAoMi6W|fc_03e5b91f227b0634016a588fc49d90819b8b32fa8c9102c3e7","toolName":"grep","startedAt":"2026-07-16T08:01:08.662Z","args":{"path":"traceable-reqs.toml"},"intent":"Finding extension requirements"},"id":"16a71f4f","parentId":"f968d5f6","timestamp":"2026-07-16T08:01:08.662Z"}
{"type":"message","id":"aa637fd6","parentId":"16a71f4f","timestamp":"2026-07-16T08:01:08.664Z","message":{"role":"toolResult","toolCallId":"call_57HiMRymYCAGC3TDqUk9ja18|fc_03e5b91f227b0634016a588fc49d84819ba92c236ee23de2ea","toolName":"read","content":[{"type":"text","text":"[0017-active-turn-delivery-uses-safe-boundaries.md#F530]\n1:---\n2:status: accepted\n3:---\n4:\n5:# Active-turn delivery uses safe boundaries\n6:\n7:A peer message accepted during an active OMP turn remains in the extension's ordered custody and is injected at the first proven boundary before the next tool or model continuation; if the turn exposes no injectable boundary, the message becomes ordinary next-turn delivery. Always waiting for the next turn was rejected because it leaves live agents unreachable during long work, while arbitrary event injection and forced interruption were rejected because they make model context, tool intent, and exactly-once correlation unpredictable.\n8:"}],"details":{"displayContent":{"text":"---\nstatus: accepted\n---\n\n# Active-turn delivery uses safe boundaries\n\nA peer message accepted during an active OMP turn remains in the extension's ordered custody and is injected at the first proven boundary before the next tool or model continuation; if the turn exposes no injectable boundary, the message becomes ordinary next-turn delivery. Always waiting for the next turn was rejected because it leaves live agents unreachable during long work, while arbitrary event injection and forced interruption were rejected because they make model context, tool intent, and exactly-once correlation unpredictable.\n","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\docs\\adr\\0017-active-turn-delivery-uses-safe-boundaries.md"}}},"isError":false,"timestamp":1784188868664}}
{"type":"message","id":"98956603","parentId":"aa637fd6","timestamp":"2026-07-16T08:01:08.665Z","message":{"role":"toolResult","toolCallId":"call_cvl80fZvfas9XYn0iewmFoo5|fc_03e5b91f227b0634016a588fc49d88819bba447645f76f02a2","toolName":"read","content":[{"type":"text","text":"[0015-extension-owned-session-activation.md#95AE]\n1:---\n2:status: accepted\n3:---\n4:\n5:# Extension-owned session activation\n6:\n7:An ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension—not the model or an agent-started background process—binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session binding remains immutable. Model-executed activation skills were rejected because listener ownership and endpoint identity are lifecycle infrastructure, while a menu-only flow was rejected because commands provide the discoverable, scriptable agent-facing surface.\n8:"}],"details":{"displayContent":{"text":"---\nstatus: accepted\n---\n\n# Extension-owned session activation\n\nAn ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension—not the model or an agent-started background process—binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session binding remains immutable. Model-executed activation skills were rejected because listener ownership and endpoint identity are lifecycle infrastructure, while a menu-only flow was rejected because commands provide the discoverable, scriptable agent-facing surface.\n","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\docs\\adr\\0015-extension-owned-session-activation.md"}}},"isError":false,"timestamp":1784188868665}}
{"type":"message","id":"5b062acb","parentId":"98956603","timestamp":"2026-07-16T08:01:08.679Z","message":{"role":"toolResult","toolCallId":"call_fPzh2GqS5U6kGVccghZjCCVE|fc_03e5b91f227b0634016a588fc49d78819b972f6da106b584d1","toolName":"read","content":[{"type":"text","text":"[omp-spt.toml#72C0]\n1:# omp-spt — Oh My Pi harness adapter for spt-core.\n2:#\n3:# Native OMP owns every hosted terminal. The adapter binary is a launch,\n4:# digest/history, Psyche, and echo-commune helper; OMP's packaged extension owns\n5:# bind, delivery, activity state, reply, and shutdown inside the native TUI.\n6:# This manifest is authored only against the published spt-core manifest and\n7:# CLI contracts. See OMP-ADAPTER-PLAN.md and ADRs 0008-0013.\n8:\n9:[adapter]\n10:name = \"omp-spt\"\n11:kind = \"harness\"\n12:version = \"0.2.1\"\n13:# v0.31.0 added identity-preserving `api listen --session-id`, which keeps the\n14:# listener on the native OMP session already recorded by the extension's bind.\n15:min_spt_core_version = \"0.31.0\"\n16:# [impl->REQ-OMP-READY-LIVE]\n17:hostable_types = [\"LiveAgent\", \"ReadyAgent\"]\n18:# Only the genuine OMP host process may resolve to this adapter.\n19:host_binaries = [\"omp\"]\n20:shortcut_basename = \"omp\"\n21:\n22:# Update through this repository's GitHub release. The packaged fat archive\n23:# contains both supported target binaries plus the shared native extension.\n24:# [impl->REQ-DIST-ADAPTER-RELEASE]\n25:[update]\n26:avenue = \"gh_release\"\n27:repo = \"BigscreenVR/omp-spt\"\n28:transport = \"gh\"\n29:message = \"\"\"\n30:**omp-spt updated.** The native OMP extension + extractors refreshed in place — no reload step: OMP\n31:loads the packaged extension fresh on each endpoint bringup.\n32:\n33:- Running endpoints keep the OLD hosting path until restarted: `spt endpoint stop <id>` then\n34:  `spt endpoint run --adapter omp-spt --id <id>` picks up the new one.\n35:- Bring up a fresh Librarian endpoint: `spt endpoint run --adapter omp-spt --id <id> --create`.\n36:\"\"\"\n37:\n38:\n39:\n40:[identity]\n41:# OMP reports the bound session id after spawn; the process-tree fallback is\n42:# the native host executable, never the adapter helper.\n43:session_id_source = \"post_spawn\"\n44:parent_ancestor_name = \"omp\"\n45:\n46:[session]\n47:# [impl->REQ-OMP-CONTINUITY-DROPS]\n48:commune_dir = \".spt\"\n49:signoff_dir = \".spt\"\n50:\n51:# The base manifest is live-capable. ReadyAgent and LiveAgent use the same OMP\n52:# endpoint; only LiveAgent activates the per-event Psyche role.\n53:# [impl->REQ-PSYCHE-EPHEMERAL-SHIM]\n54:[session.psyche_init]\n55:command = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\n56:# Prevent a child Psyche from inheriting its parent's SPT identity.\n57:env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\n58:keys = [\"id\", \"session_id\", \"psyche_context_file\"]\n59:# Each Psyche event is one bounded OMP turn. The context file is read by the\n60:# shim, the event arrives on stdin, stdout carries the result, and exit 95 asks\n61:# [impl->REQ-PSYCHE-EPHEMERAL-SHIM]\n62:[session.psyche_resume]\n63:command = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\n64:detach = false\n65:# Prevent a child Psyche from inheriting its parent's SPT identity.\n66:env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\n67:keys = [\"id\", \"session_id\", \"psyche_context_file\"]\n68:\n69:# Fresh endpoints launch validated native OMP with the packaged extension. The\n70:# launch shim snapshots only non-secret OMP locator/profile/executable selectors\n71:# under the endpoint project's `.spt` before OMP takes over the broker PTY.\n72:[session.self]\n73:# [impl->REQ-OMP-EXECUTABLE-RESOLUTION]\n74:command = \"{adapter_dir}/omp-spt launch-omp --id {id} --extension {adapter_dir}/strings/omp-spt.mjs\"\n75:keys = [\"id\"]\n76:\n77:# Resume refreshes the same endpoint snapshot, then uses OMP's native session\n78:# selector with the packaged extension.\n79:[session.resume]\n80:# [impl->REQ-OMP-EXECUTABLE-RESOLUTION]\n81:command = \"{adapter_dir}/omp-spt launch-omp --id {id} --resume {session_id} --extension {adapter_dir}/strings/omp-spt.mjs\"\n82:keys = [\"id\", \"session_id\"]\n83:\n84:# The bounded summarizer reads the selected OMP session JSONL and runs one\n85:# extension-free OMP turn. A missing transcript is an empty delta; a real OMP\n86:# failure is reported to spt-core.\n87:# [impl->REQ-SESSION-ECHO-COMMUNE]\n88:[session.echo_commune]\n89:command = \"omp-spt echo-commune-omp --id {id} --session-id {session_id}\"\n90:detach = false\n91:recursion_guard_env = \"SPT_ECHO_COMMUNE\"\n92:# Prevent the summarizer from inheriting its parent's SPT identity.\n93:env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\n94:keys = [\"id\", \"session_id\"]\n95:# History is the opaque JSONL for exactly one OMP session.\n96:# [impl->REQ-HISTORY-FETCHER]\n97:[history]\n98:strategy = \"fetcher\"\n99:fetcher = \"omp-spt history-omp --session {session_id} --project-dir \\\"{cwd}\\\"\"\n100:\n101:# Public spt docs say `[env.*] direction = \"read\"` values survive the daemon\n102:# boundary as substitutions for echo, digest, and Psyche. Installed spt 0.31.0\n103:# rejects those placeholders during registration and does not inherit captured\n104:# values into daemon children. The project-local launch snapshot above is the\n105:# smallest non-secret substitute; no API key, token, or credential is persisted.\n106:\n107:# The native extension uses the endpoint id injected by spt-core when binding the OMP session.\n108:[env.SPT_ENDPOINT_ID]\n109:direction = \"inject\"\n110:value = \"{id}\"\n111:\n112:# Message delivery is extension-owned; no hook or PTY-translation surface is\n113:# declared by the native adapter.\n114:\n115:# The fetcher locates one OMP session JSONL and emits the published digest\n116:# record stream.\n117:# [impl->REQ-DIST-DIGEST-EXTRACTOR]\n118:[digest]\n119:strategy = \"fetcher\"\n120:extractor = \"omp-spt digest-omp --session {session_id} --project-dir \\\"{cwd}\\\"\"\n121:arg_truncation = 240\n122:sprint_collapse = true\n123:\n124:\n125:[strings]\n126:adapter_label = \"oh-my-pi (spt)\"\n127:"}],"details":{"displayContent":{"text":"# omp-spt — Oh My Pi harness adapter for spt-core.\n#\n# Native OMP owns every hosted terminal. The adapter binary is a launch,\n# digest/history, Psyche, and echo-commune helper; OMP's packaged extension owns\n# bind, delivery, activity state, reply, and shutdown inside the native TUI.\n# This manifest is authored only against the published spt-core manifest and\n# CLI contracts. See OMP-ADAPTER-PLAN.md and ADRs 0008-0013.\n\n[adapter]\nname = \"omp-spt\"\nkind = \"harness\"\nversion = \"0.2.1\"\n# v0.31.0 added identity-preserving `api listen --session-id`, which keeps the\n# listener on the native OMP session already recorded by the extension's bind.\nmin_spt_core_version = \"0.31.0\"\n# [impl->REQ-OMP-READY-LIVE]\nhostable_types = [\"LiveAgent\", \"ReadyAgent\"]\n# Only the genuine OMP host process may resolve to this adapter.\nhost_binaries = [\"omp\"]\nshortcut_basename = \"omp\"\n\n# Update through this repository's GitHub release. The packaged fat archive\n# contains both supported target binaries plus the shared native extension.\n# [impl->REQ-DIST-ADAPTER-RELEASE]\n[update]\navenue = \"gh_release\"\nrepo = \"BigscreenVR/omp-spt\"\ntransport = \"gh\"\nmessage = \"\"\"\n**omp-spt updated.** The native OMP extension + extractors refreshed in place — no reload step: OMP\nloads the packaged extension fresh on each endpoint bringup.\n\n- Running endpoints keep the OLD hosting path until restarted: `spt endpoint stop <id>` then\n  `spt endpoint run --adapter omp-spt --id <id>` picks up the new one.\n- Bring up a fresh Librarian endpoint: `spt endpoint run --adapter omp-spt --id <id> --create`.\n\"\"\"\n\n\n\n[identity]\n# OMP reports the bound session id after spawn; the process-tree fallback is\n# the native host executable, never the adapter helper.\nsession_id_source = \"post_spawn\"\nparent_ancestor_name = \"omp\"\n\n[session]\n# [impl->REQ-OMP-CONTINUITY-DROPS]\ncommune_dir = \".spt\"\nsignoff_dir = \".spt\"\n\n# The base manifest is live-capable. ReadyAgent and LiveAgent use the same OMP\n# endpoint; only LiveAgent activates the per-event Psyche role.\n# [impl->REQ-PSYCHE-EPHEMERAL-SHIM]\n[session.psyche_init]\ncommand = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\n# Prevent a child Psyche from inheriting its parent's SPT identity.\nenv_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\nkeys = [\"id\", \"session_id\", \"psyche_context_file\"]\n# Each Psyche event is one bounded OMP turn. The context file is read by the\n# shim, the event arrives on stdin, stdout carries the result, and exit 95 asks\n# [impl->REQ-PSYCHE-EPHEMERAL-SHIM]\n[session.psyche_resume]\ncommand = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\ndetach = false\n# Prevent a child Psyche from inheriting its parent's SPT identity.\nenv_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\nkeys = [\"id\", \"session_id\", \"psyche_context_file\"]\n\n# Fresh endpoints launch validated native OMP with the packaged extension. The\n# launch shim snapshots only non-secret OMP locator/profile/executable selectors\n# under the endpoint project's `.spt` before OMP takes over the broker PTY.\n[session.self]\n# [impl->REQ-OMP-EXECUTABLE-RESOLUTION]\ncommand = \"{adapter_dir}/omp-spt launch-omp --id {id} --extension {adapter_dir}/strings/omp-spt.mjs\"\nkeys = [\"id\"]\n\n# Resume refreshes the same endpoint snapshot, then uses OMP's native session\n# selector with the packaged extension.\n[session.resume]\n# [impl->REQ-OMP-EXECUTABLE-RESOLUTION]\ncommand = \"{adapter_dir}/omp-spt launch-omp --id {id} --resume {session_id} --extension {adapter_dir}/strings/omp-spt.mjs\"\nkeys = [\"id\", \"session_id\"]\n\n# The bounded summarizer reads the selected OMP session JSONL and runs one\n# extension-free OMP turn. A missing transcript is an empty delta; a real OMP\n# failure is reported to spt-core.\n# [impl->REQ-SESSION-ECHO-COMMUNE]\n[session.echo_commune]\ncommand = \"omp-spt echo-commune-omp --id {id} --session-id {session_id}\"\ndetach = false\nrecursion_guard_env = \"SPT_ECHO_COMMUNE\"\n# Prevent the summarizer from inheriting its parent's SPT identity.\nenv_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\nkeys = [\"id\", \"session_id\"]\n# History is the opaque JSONL for exactly one OMP session.\n# [impl->REQ-HISTORY-FETCHER]\n[history]\nstrategy = \"fetcher\"\nfetcher = \"omp-spt history-omp --session {session_id} --project-dir \\\"{cwd}\\\"\"\n\n# Public spt docs say `[env.*] direction = \"read\"` values survive the daemon\n# boundary as substitutions for echo, digest, and Psyche. Installed spt 0.31.0\n# rejects those placeholders during registration and does not inherit captured\n# values into daemon children. The project-local launch snapshot above is the\n# smallest non-secret substitute; no API key, token, or credential is persisted.\n\n# The native extension uses the endpoint id injected by spt-core when binding the OMP session.\n[env.SPT_ENDPOINT_ID]\ndirection = \"inject\"\nvalue = \"{id}\"\n\n# Message delivery is extension-owned; no hook or PTY-translation surface is\n# declared by the native adapter.\n\n# The fetcher locates one OMP session JSONL and emits the published digest\n# record stream.\n# [impl->REQ-DIST-DIGEST-EXTRACTOR]\n[digest]\nstrategy = \"fetcher\"\nextractor = \"omp-spt digest-omp --session {session_id} --project-dir \\\"{cwd}\\\"\"\narg_truncation = 240\nsprint_collapse = true\n\n\n[strings]\nadapter_label = \"oh-my-pi (spt)\"\n","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\omp-spt.toml"}}},"isError":false,"timestamp":1784188868679}}
{"type":"message","id":"3882a819","parentId":"5b062acb","timestamp":"2026-07-16T08:01:08.680Z","message":{"role":"toolResult","toolCallId":"call_yzdNGiWQlA1ekfpHmkE7yDB7|fc_03e5b91f227b0634016a588fc49d68819badcf6608317323c2","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#CA60]\n 5:export function decodeBody(body) {\n*6:\treturn body\n 7:\t\t.replaceAll(\"<br>\", \"\\n\")\n 8:\t\t.replaceAll(\"&lt;\", \"<\")\n 9:\t\t.replaceAll(\"&gt;\", \">\")\n...\n 16:\terror.code = \"SPT_PROTOCOL_ERROR\";\n*17:\treturn error;\n 18:}\n 19:\n 20:function parseEventTag(tag) {\n*21:\tif (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };\n 22:\tlet cursor = \"<EVENT\".length;\n 23:\tconst attributes = Object.create(null);\n 24:\twhile (cursor < tag.length) {\n 25:\t\tif (!/\\s/.test(tag[cursor])) {\n*26:\t\t\treturn { error: protocolError(\"malformed EVENT attributes\") };\n 27:\t\t}\n 28:\t\twhile (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;\n 29:\t\tif (cursor === tag.length) break;\n 30:\t\tconst match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));\n*31:\t\tif (!match) return { error: protocolError(\"malformed EVENT attributes\") };\n 32:\t\tconst [, name, value] = match;\n 33:\t\tif (Object.hasOwn(attributes, name)) {\n*34:\t\t\treturn { error: protocolError(`duplicate EVENT ${name} attribute`) };\n 35:\t\t}\n 36:\t\tattributes[name] = value;\n 37:\t\tcursor += match[0].length;\n 38:\t}\n*39:\tif (!attributes.type) return { error: protocolError(\"missing EVENT type attribute\") };\n 40:\tif (attributes.type === \"msg\" && !attributes.from) {\n*41:\t\treturn { error: protocolError(\"missing EVENT from attribute\") };\n 42:\t}\n*43:\treturn { attributes };\n 44:}\n 45:\n 46:export function drainEvents(raw, options = {}) {\n...\n 52:\t\tconst start = raw.indexOf(\"<EVENT\", cursor);\n*53:\t\tif (start < 0) return { events, rest: raw.slice(cursor) };\n 54:\t\tconst openEnd = raw.indexOf(\">\", start);\n 55:\t\tif (openEnd < 0) {\n 56:\t\t\tif (raw.length - start > maxFrameChars) {\n*57:\t\t\t\treturn {\n 58:\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n 59:\t\t\t\t\tevents,\n 60:\t\t\t\t\trest: raw.slice(start),\n...\n 62:\t\t\t}\n*63:\t\t\treturn { events, rest: raw.slice(start) };\n 64:\t\t}\n 65:\t\tif (openEnd + 1 - start > maxFrameChars) {\n*66:\t\t\treturn {\n 67:\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n 68:\t\t\t\tevents,\n 69:\t\t\t\trest: raw.slice(start),\n...\n 74:\t\tif (nested >= 0 && (close < 0 || nested < close)) {\n*75:\t\t\treturn {\n 76:\t\t\t\terror: protocolError(\"nested EVENT before closing the current frame\"),\n 77:\t\t\t\tevents,\n 78:\t\t\t\trest: raw.slice(start),\n...\n 82:\t\t\tif (raw.length - start > maxFrameChars) {\n*83:\t\t\t\treturn {\n 84:\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n 85:\t\t\t\t\tevents,\n 86:\t\t\t\t\trest: raw.slice(start),\n...\n 88:\t\t\t}\n*89:\t\t\treturn { events, rest: raw.slice(start) };\n 90:\t\t}\n 91:\t\tconst end = close + \"</EVENT>\".length;\n 92:\t\tif (end - start > maxFrameChars) {\n*93:\t\t\treturn {\n 94:\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n 95:\t\t\t\tevents,\n 96:\t\t\t\trest: raw.slice(start),\n...\n 99:\t\tconst parsed = parseEventTag(raw.slice(start, openEnd));\n*100:\t\tif (parsed.error) return { error: parsed.error, events, rest: raw.slice(start) };\n 101:\t\tif (parsed.attributes.type === \"msg\") {\n 102:\t\t\tevents.push({\n 103:\t\t\t\tfrom: parsed.attributes.from,\n...\n 108:\t\tcursor = end;\n*109:\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\n 110:\t}\n 111:}\n 112:\n 113:function messageText(message) {\n*114:\tif (typeof message?.content === \"string\") return message.content;\n*115:\treturn (message?.content ?? [])\n 116:\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\n 117:\t\t.map((part) => part.text)\n 118:\t\t.join(\"\");\n...\n 125:\t\tconst userIndex = allMessages.findLastIndex((message) => {\n*126:\t\t\tif (message?.role !== \"user\") return false;\n 127:\t\t\tconst text = messageText(message);\n*128:\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\n 129:\t\t});\n*130:\t\tif (userIndex < 0) return \"\";\n 131:\t\tstart = userIndex + 1;\n 132:\t}\n 133:\tconst assistant = allMessages\n...\n 136:\t\t.find((message) => message?.role === \"assistant\");\n*137:\treturn assistant ? messageText(assistant) : \"\";\n 138:}\n 139:\n 140:function firstLine(text) {\n*141:\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\n 142:}\n 143:\n 144:function errorSummary(error) {\n 145:\tconst detail = error instanceof Error ? error.message : String(error);\n*146:\treturn firstLine(detail).trim() || \"unknown error\";\n 147:}\n 148:\n 149:function failureMessage(reason, error) {\n 150:\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\n*151:\treturn `[omp-spt] ${reason}${detail}`;\n 152:}\n 153:\n 154:function senderStub(sender) {\n...\n 159:\t\t.replaceAll(\">\", \"&gt;\");\n*160:\treturn `<msg from=\"${escaped}\"/>`;\n 161:}\n 162:\n*163:function injectEnvelope(messages, item) {\n 164:\tconst index = messages.findLastIndex(\n 165:\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\n 166:\t);\n*167:\tif (index < 0) return messages;\n 168:\tconst original = messages[index];\n 169:\tconst content =\n 170:\t\ttypeof original.content === \"string\"\n...\n 172:\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\n*173:\tconst injected = [...messages];\n*174:\tinjected[index] = { ...original, content };\n*175:\treturn injected;\n 176:}\n 177:\n 178:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n...\n 187:function childExited(child) {\n*188:\treturn (\n 189:\t\t(child.exitCode !== undefined && child.exitCode !== null) ||\n 190:\t\t(child.signalCode !== undefined && child.signalCode !== null)\n 191:\t);\n...\n 194:function waitForChildExit(child, timeoutMs, setTimer, clearTimer) {\n*195:\tif (childExited(child)) return Promise.resolve(true);\n*196:\treturn new Promise((resolve) => {\n 197:\t\tlet timer;\n 198:\t\tlet finished = false;\n 199:\t\tconst finish = (exited) => {\n*200:\t\t\tif (finished) return;\n 201:\t\t\tfinished = true;\n 202:\t\t\tif (timer !== undefined) clearTimer(timer);\n 203:\t\t\tchild.off(\"close\", onClose);\n...\n 215:\tconst { clearTimer, forceMs, graceMs, setTimer } = options;\n*216:\tif (childExited(child)) return;\n 217:\n 218:\tconst gracefulExit = waitForChildExit(child, graceMs, setTimer, clearTimer);\n 219:\tlet killError;\n...\n 224:\t}\n*225:\tif (await gracefulExit) return;\n 226:\n 227:\tconst forcedExit = waitForChildExit(child, forceMs, setTimer, clearTimer);\n 228:\ttry {\n...\n 232:\t}\n*233:\tif (await forcedExit) return;\n 234:\n 235:\tchild.stdin?.destroy?.();\n 236:\tchild.stdout?.destroy?.();\n...\n 244:\tconst command = args[0] === \"api\" ? args[3] : args[0];\n*245:\treturn `spt ${command ?? \"command\"}`;\n 246:}\n 247:\n 248:export function runSpt(args, input, overrides = {}) {\n...\n 258:\tif (signal?.aborted) {\n*259:\t\treturn Promise.reject(\n 260:\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`),\n 261:\t\t);\n 262:\t}\n 263:\n*264:\treturn new Promise((resolve, reject) => {\n 265:\t\tlet child;\n 266:\t\ttry {\n 267:\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\n...\n 272:\t\t\treject(error);\n*273:\t\t\treturn;\n 274:\t\t}\n 275:\n 276:\t\tlet output = \"\";\n...\n 296:\t\tconst settle = (error) => {\n*297:\t\t\tif (settled) return;\n 298:\t\t\tsettled = true;\n 299:\t\t\tcleanup();\n 300:\t\t\tif (error === undefined) resolve(output.trim());\n...\n 303:\t\tconst terminateAndReject = async (error) => {\n*304:\t\t\tif (settled || terminating) return;\n 305:\t\t\tterminating = true;\n 306:\t\t\tif (timeoutTimer !== undefined) {\n 307:\t\t\t\tclearTimer(timeoutTimer);\n...\n 330:\t\tconst onClose = (code, signal) => {\n*331:\t\t\tif (terminating || settled) return;\n 332:\t\t\tif (code === 0 && stdinFinished) {\n 333:\t\t\t\tsettle();\n*334:\t\t\t\treturn;\n 335:\t\t\t}\n 336:\t\t\tconst status = signal ? `signal ${signal}` : `exit ${code}`;\n 337:\t\t\tconst detail = firstLine(output);\n...\n 358:\t\t\tonAbort();\n*359:\t\t\treturn;\n 360:\t\t}\n 361:\t\ttimeoutTimer = setTimer(() => {\n 362:\t\t\ttimeoutTimer = undefined;\n...\n 426:\n*427:\treturn function ompSpt(pi) {\n 428:\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n*429:\t\tif (!id) return;\n 430:\n 431:\t\tlet sid;\n 432:\t\tlet token;\n...\n 442:\t\tlet dispatching = false;\n*443:\t\tlet turnCompletionPromise;\n 444:\t\tlet listenerTerminationPromise;\n 445:\t\tlet shutdownMode = false;\n 446:\t\tlet shutdownDeadlineExpired = false;\n...\n 468:\t\t\tif (shutdownDeadlineExpired) {\n*469:\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\n 470:\t\t\t}\n 471:\t\t\tconst timeoutMs =\n 472:\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\n...\n 484:\t\t\t\tactiveCommands.delete(controller);\n*485:\t\t\t\treturn Promise.reject(error);\n 486:\t\t\t}\n 487:\t\t\tif (customRunSptCommand) {\n 488:\t\t\t\tconst rawCommand = command;\n...\n 492:\t\t\t\t\tconst finish = (error, value) => {\n*493:\t\t\t\t\t\tif (finished) return;\n 494:\t\t\t\t\t\tfinished = true;\n 495:\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n 496:\t\t\t\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\n...\n 522:\t\t\t}\n*523:\t\t\treturn command.finally(() => {\n 524:\t\t\t\tconst active = activeCommands.get(controller);\n 525:\t\t\t\tif (active?.abortTimer !== undefined) clearTimer(active.abortTimer);\n 526:\t\t\t\tactiveCommands.delete(controller);\n...\n 545:\t\tfunction waitForRetry(delay) {\n*546:\t\t\tif (shutdownMode) return Promise.resolve();\n*547:\t\t\treturn new Promise((resolve) => {\n 548:\t\t\t\tlet timer;\n 549:\t\t\t\tconst finish = () => {\n 550:\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n...\n 560:\t\tfunction enterShutdownMode() {\n*561:\t\t\tif (shutdownMode) return;\n 562:\t\t\tshutdownMode = true;\n 563:\t\t\tconst reason = new Error(\"omp-spt command interrupted for bounded shutdown\");\n 564:\t\t\tabortActiveCommands(reason, true);\n...\n 568:\t\tfunction authArgs() {\n*569:\t\t\tif (!token) throw new Error(\"bind did not return an authentication token\");\n*570:\t\t\treturn [\"--token\", token];\n 571:\t\t}\n 572:\n 573:\t\tfunction setState(state) {\n*574:\t\t\tif (!sid || !token || stopping) return Promise.resolve();\n 575:\t\t\tconst operation = stateOperation.catch(() => {}).then(async () => {\n*576:\t\t\t\tif (endpointState === state || stopping) return;\n 577:\t\t\t\tawait runCommand([\"api\", \"--adapter\", ADAPTER, \"state\", state, id, ...authArgs()]);\n 578:\t\t\t\tendpointState = state;\n 579:\t\t\t});\n 580:\t\t\tstateOperation = operation;\n*581:\t\t\treturn operation;\n 582:\t\t}\n 583:\n 584:\t\tasync function syncDesiredState() {\n*585:\t\t\tif (!bindPromise) return;\n 586:\t\t\tawait bindPromise;\n 587:\t\t\twhile (!stopping && endpointState !== desiredState) {\n 588:\t\t\t\tawait setState(desiredState);\n...\n 592:\t\tfunction endSession() {\n*593:\t\t\tif (!sid || !token) return Promise.resolve();\n 594:\t\t\tif (!endPromise) {\n 595:\t\t\t\tconst operation = (async () => {\n 596:\t\t\t\t\tawait stateOperation.catch(() => {});\n...\n 604:\t\t\t}\n*605:\t\t\treturn endPromise;\n 606:\t\t}\n 607:\n 608:\t\tasync function endSessionWithRetry() {\n...\n 611:\t\t\t\t\tawait endSession();\n*612:\t\t\t\t\treturn;\n 613:\t\t\t\t} catch (error) {\n 614:\t\t\t\t\tif (shutdownMode || attempt >= sessionEndRetryDelaysMs.length) throw error;\n 615:\t\t\t\t\tconst delay = sessionEndRetryDelaysMs[attempt];\n...\n 626:\n*627:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n 628:\t\tfunction settleItem(item, payload) {\n*629:\t\t\tif (!item) return Promise.resolve();\n*630:\t\t\tif (item.outcomePromise) return item.outcomePromise;\n 631:\t\t\titem.settling = true;\n 632:\t\t\titem.outcomePromise = (async () => {\n 633:\t\t\t\tif (!item.from) throw new Error(\"missing EVENT from attribute\");\n...\n 637:\t\t\t\t\t\titem.settled = true;\n*638:\t\t\t\t\t\treturn;\n 639:\t\t\t\t\t} catch (error) {\n 640:\t\t\t\t\t\tif (shutdownMode || attempt >= outcomeRetryDelaysMs.length) throw error;\n 641:\t\t\t\t\t\tconst delay = outcomeRetryDelaysMs[attempt];\n...\n 651:\t\t\t})();\n*652:\t\t\treturn item.outcomePromise;\n 653:\t\t}\n 654:\n 655:\t\tfunction releaseItem(item) {\n*656:\t\t\tif (!item?.accounted) return;\n 657:\t\t\titem.accounted = false;\n 658:\t\t\tacceptedBytes -= item.acceptedBytes;\n 659:\t\t}\n...\n 661:\t\tfunction beginListenerTermination(child, label) {\n*662:\t\t\tif (listenerTerminationPromise) return listenerTerminationPromise;\n 663:\t\t\tconst operation = (async () => {\n 664:\t\t\t\ttry {\n 665:\t\t\t\t\tawait terminateChild(child, label, {\n...\n 680:\t\t\t});\n*681:\t\t\treturn operation;\n 682:\t\t}\n 683:\n 684:\t\tasync function stopResources() {\n...\n 715:\t\t\t\t\t}\n*716:\t\t\t\t\tif (item.settled) return;\n 717:\t\t\t\t\tif (existingError && !shutdownMode) {\n 718:\t\t\t\t\t\tlogError(\n*719:\t\t\t\t\t\t\t`omp-spt could not return custody to ${item.from ?? \"unknown\"}`,\n 720:\t\t\t\t\t\t\texistingError,\n 721:\t\t\t\t\t\t);\n*722:\t\t\t\t\t\treturn;\n 723:\t\t\t\t\t}\n 724:\t\t\t\t\titem.outcomePromise = undefined;\n 725:\t\t\t\t\titem.settling = false;\n...\n 729:\t\t\t\t} catch (error) {\n*730:\t\t\t\t\tlogError(`omp-spt could not return custody to ${item.from ?? \"unknown\"}`, error);\n 731:\t\t\t\t}\n 732:\t\t\t} finally {\n 733:\t\t\t\treleaseItem(item);\n...\n 747:\t\t\t\t\t);\n*748:\t\t\t\t\treturn;\n 749:\t\t\t\t}\n 750:\t\t\t\tawait settlePendingItem(pending[index], reason);\n 751:\t\t\t}\n...\n 767:\t\t\t}\n*768:\t\t\treturn teardownPromise;\n 769:\t\t}\n 770:\n 771:\t\tasync function shutdownWithinBudget(pendingReason) {\n...\n 791:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n*792:\t\t\t\t\treturn true;\n 793:\t\t\t\t},\n 794:\t\t\t);\n 795:\t\t\tconst finished = await Promise.race([completed, expired]);\n...\n 805:\t\tasync function failClosed(message, error) {\n*806:\t\t\tif (stopping && shutdownMode) return teardownPromise ?? Promise.resolve();\n*807:\t\t\tif (fatalPromise) return fatalPromise;\n 808:\t\t\tfatalPromise = (async () => {\n 809:\t\t\t\tui?.setStatus(\"omp-spt\", \"spt failed\");\n 810:\t\t\t\tlogError(message, error);\n...\n 817:\t\t\t})();\n*818:\t\t\treturn fatalPromise;\n 819:\t\t}\n 820:\n 821:\t\tfunction scheduleDispatch() {\n...\n 829:\t\t\t) {\n*830:\t\t\t\treturn;\n 831:\t\t\t}\n 832:\t\t\tdispatchTimer = setTimer(() => {\n 833:\t\t\t\tdispatchTimer = undefined;\n 834:\t\t\t\tvoid dispatchNext().catch((error) => {\n*835:\t\t\t\t\tif (!stopping) return failClosed(\"omp-spt dispatch failed\", error);\n 836:\t\t\t\t});\n 837:\t\t\t}, 0);\n 838:\t\t\tdispatchTimer?.unref?.();\n...\n 841:\t\tasync function rejectItem(item, reason, error) {\n*842:\t\t\tif (stopping) return;\n 843:\t\t\tlogError(`omp-spt ${reason}`, error);\n 844:\t\t\ttry {\n 845:\t\t\t\tawait settleItem(item, failureMessage(reason, error));\n 846:\t\t\t} catch (outcomeError) {\n*847:\t\t\t\tif (stopping) return;\n 848:\t\t\t\tawait failClosed(`omp-spt could not send the outcome to ${item.from ?? \"unknown\"}`, outcomeError);\n*849:\t\t\t\treturn;\n 850:\t\t\t}\n 851:\t\t\tif (current === item) {\n 852:\t\t\t\tcurrent = undefined;\n...\n 867:\n*868:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n 869:\t\tasync function dispatchNext() {\n*870:\t\t\tif (stopping || agentActive || dispatching || current || queue.length === 0) return;\n 871:\t\t\tdispatching = true;\n 872:\t\t\tconst item = queue.shift();\n 873:\t\t\tcurrent = item;\n...\n 879:\t\t\t\t\tawait rejectItem(item, \"could not accept your message\", error);\n*880:\t\t\t\t\treturn;\n 881:\t\t\t\t}\n*882:\t\t\t\tif (stopping) return;\n 883:\t\t\t\tif (agentActive) {\n 884:\t\t\t\t\tif (current === item) current = undefined;\n 885:\t\t\t\t\tqueue.unshift(item);\n*886:\t\t\t\t\treturn;\n 887:\t\t\t\t}\n 888:\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n 889:\t\t\t\titem.submitted = true;\n...\n 908:\t\t\t}\n*909:\t\t\tif (stopping || restartTimer !== undefined) return;\n 910:\t\t\tif (listenerRestartCount >= restartDelaysMs.length) {\n 911:\t\t\t\tvoid failClosed(\"omp-spt listener restart budget exhausted\", reason);\n*912:\t\t\t\treturn;\n 913:\t\t\t}\n 914:\t\t\tconst attempt = listenerRestartCount + 1;\n 915:\t\t\tconst delay = restartDelaysMs[listenerRestartCount];\n...\n 928:\t\tfunction startListener() {\n*929:\t\t\tif (stopping) return;\n 930:\t\t\tconst args = [\"api\", \"--adapter\", ADAPTER, \"listen\", id, \"--session-id\", sid];\n 931:\t\t\tif (env.OMP_SPT_SUBNET) args.push(\"--subnet\", env.OMP_SPT_SUBNET);\n 932:\t\t\tlet child;\n...\n 939:\t\t\t\thandleListenerDeath(error);\n*940:\t\t\t\treturn;\n 941:\t\t\t}\n 942:\t\t\tlistener = child;\n 943:\t\t\tlistenerBuffer = \"\";\n 944:\t\t\tlet dead = false;\n*945:\t\t\tconst died = (reason, alreadyExited) => {\n*946:\t\t\t\tif (dead) return;\n 947:\t\t\t\tdead = true;\n 948:\t\t\t\tif (listener === child) listener = undefined;\n*949:\t\t\t\tif (stopping || alreadyExited) {\n 950:\t\t\t\t\thandleListenerDeath(reason);\n*951:\t\t\t\t\treturn;\n 952:\t\t\t\t}\n 953:\t\t\t\tconst termination = beginListenerTermination(child, \"dead spt api listener\");\n 954:\t\t\t\tvoid termination.then(() => handleListenerDeath(reason));\n...\n 965:\t\t\tchild.stdout.on(\"data\", (chunk) => {\n*966:\t\t\t\tif (listener !== child || stopping) return;\n 967:\t\t\t\tlistenerBuffer += String(chunk);\n 968:\t\t\t\tif (listenerBuffer.length > listenerBufferLimit) {\n 969:\t\t\t\t\tvoid failClosed(\n...\n 974:\t\t\t\t\t);\n*975:\t\t\t\t\treturn;\n 976:\t\t\t\t}\n 977:\t\t\t\twhile (!stopping) {\n 978:\t\t\t\t\tconst drained = drainEvents(listenerBuffer, {\n...\n 984:\t\t\t\t\t\tvoid failClosed(\"omp-spt listener protocol corruption\", drained.error);\n*985:\t\t\t\t\t\treturn;\n 986:\t\t\t\t\t}\n 987:\t\t\t\t\tif (drained.events.length === 0) break;\n 988:\t\t\t\t\tconst event = drained.events[0];\n...\n 996:\t\t\t\t\t\tvoid failClosed(\n*997:\t\t\t\t\t\t\t\"omp-spt inbound custody capacity exceeded\",\n 998:\t\t\t\t\t\t\tnew Error(\n 999:\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\n 1000:\t\t\t\t\t\t\t),\n 1001:\t\t\t\t\t\t);\n*1002:\t\t\t\t\t\treturn;\n 1003:\t\t\t\t\t}\n 1004:\t\t\t\t\tevent.acceptedBytes = eventBytes;\n 1005:\t\t\t\t\tevent.accounted = true;\n...\n 1036:\t\t\t} catch (error) {\n*1037:\t\t\t\tif (stopping) return;\n 1038:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n 1039:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n*1040:\t\t\t\treturn;\n 1041:\t\t\t}\n 1042:\t\t\tif (stopping) {\n 1043:\t\t\t\ttry {\n...\n 1047:\t\t\t\t}\n*1048:\t\t\t\treturn;\n 1049:\t\t\t}\n 1050:\t\t\ttry {\n 1051:\t\t\t\tawait syncDesiredState();\n...\n 1053:\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n*1054:\t\t\t\t\treturn;\n 1055:\t\t\t\t}\n 1056:\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n 1057:\t\t\t\tstartListener();\n...\n 1060:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n*1061:\t\t\t\t\treturn;\n 1062:\t\t\t\t}\n 1063:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n 1064:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n...\n 1073:\t\t\t);\n*1074:\t\t\treturn { cancel: true };\n 1075:\t\t};\n 1076:\n 1077:\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n...\n 1085:\t\tpi.on(\"context\", (event) => {\n*1086:\t\t\tif (!current?.submitted || current.settling) return;\n*1087:\t\t\tconst messages = injectEnvelope(event.messages, current);\n*1088:\t\t\tif (messages !== event.messages) return { messages };\n 1089:\t\t});\n 1090:\n*1091:\t\tasync function completeTurn(event) {\n 1092:\t\t\tagentActive = false;\n 1093:\t\t\tdesiredState = \"idle\";\n*1094:\t\t\tif (stopping) return;\n 1095:\t\t\tconst completed = current;\n 1096:\t\t\tif (completed?.submitted && !completed.settled) {\n 1097:\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\n...\n 1100:\t\t\t\t\t\tcompleted,\n*1101:\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n 1102:\t\t\t\t\t);\n 1103:\t\t\t\t} catch (error) {\n*1104:\t\t\t\t\tif (stopping) return;\n 1105:\t\t\t\t\tawait failClosed(\n 1106:\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n 1107:\t\t\t\t\t\terror,\n 1108:\t\t\t\t\t);\n*1109:\t\t\t\t\treturn;\n 1110:\t\t\t\t}\n 1111:\t\t\t}\n 1112:\t\t\tif (current === completed) {\n...\n 1118:\t\t\t} catch (error) {\n*1119:\t\t\t\tif (stopping) return;\n 1120:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n*1121:\t\t\t\treturn;\n 1122:\t\t\t}\n 1123:\t\t\tscheduleDispatch();\n 1124:\t\t}\n...\n 1126:\t\tpi.on(\"agent_start\", async () => {\n*1127:\t\t\tif (stopping) return;\n*1128:\t\t\tturnCompletionPromise = undefined;\n 1129:\t\t\tagentActive = true;\n 1130:\t\t\tdesiredState = \"busy\";\n 1131:\t\t\ttry {\n...\n 1137:\n*1138:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n 1139:\t\tpi.on(\"agent_end\", (event) => {\n*1140:\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1141:\t\t\treturn turnCompletionPromise;\n 1142:\t\t});\n 1143:\n 1144:\t\tpi.on(\"session_stop\", async (event) => {\n*1145:\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1146:\t\t\tawait turnCompletionPromise;\n 1147:\t\t});\n 1148:\n 1149:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":133,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":133}],"truncated":false,"displayContent":"    5│export function decodeBody(body) {\n   *6│\treturn body\n    7│\t\t.replaceAll(\"<br>\", \"\\n\")\n    8│\t\t.replaceAll(\"&lt;\", \"<\")\n    9│\t\t.replaceAll(\"&gt;\", \">\")\n     │...\n   16│\terror.code = \"SPT_PROTOCOL_ERROR\";\n  *17│\treturn error;\n   18│}\n   19│\n   20│function parseEventTag(tag) {\n  *21│\tif (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };\n   22│\tlet cursor = \"<EVENT\".length;\n   23│\tconst attributes = Object.create(null);\n   24│\twhile (cursor < tag.length) {\n   25│\t\tif (!/\\s/.test(tag[cursor])) {\n  *26│\t\t\treturn { error: protocolError(\"malformed EVENT attributes\") };\n   27│\t\t}\n   28│\t\twhile (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;\n   29│\t\tif (cursor === tag.length) break;\n   30│\t\tconst match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));\n  *31│\t\tif (!match) return { error: protocolError(\"malformed EVENT attributes\") };\n   32│\t\tconst [, name, value] = match;\n   33│\t\tif (Object.hasOwn(attributes, name)) {\n  *34│\t\t\treturn { error: protocolError(`duplicate EVENT ${name} attribute`) };\n   35│\t\t}\n   36│\t\tattributes[name] = value;\n   37│\t\tcursor += match[0].length;\n   38│\t}\n  *39│\tif (!attributes.type) return { error: protocolError(\"missing EVENT type attribute\") };\n   40│\tif (attributes.type === \"msg\" && !attributes.from) {\n  *41│\t\treturn { error: protocolError(\"missing EVENT from attribute\") };\n   42│\t}\n  *43│\treturn { attributes };\n   44│}\n   45│\n   46│export function drainEvents(raw, options = {}) {\n     │...\n   52│\t\tconst start = raw.indexOf(\"<EVENT\", cursor);\n  *53│\t\tif (start < 0) return { events, rest: raw.slice(cursor) };\n   54│\t\tconst openEnd = raw.indexOf(\">\", start);\n   55│\t\tif (openEnd < 0) {\n   56│\t\t\tif (raw.length - start > maxFrameChars) {\n  *57│\t\t\t\treturn {\n   58│\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n   59│\t\t\t\t\tevents,\n   60│\t\t\t\t\trest: raw.slice(start),\n     │...\n   62│\t\t\t}\n  *63│\t\t\treturn { events, rest: raw.slice(start) };\n   64│\t\t}\n   65│\t\tif (openEnd + 1 - start > maxFrameChars) {\n  *66│\t\t\treturn {\n   67│\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n   68│\t\t\t\tevents,\n   69│\t\t\t\trest: raw.slice(start),\n     │...\n   74│\t\tif (nested >= 0 && (close < 0 || nested < close)) {\n  *75│\t\t\treturn {\n   76│\t\t\t\terror: protocolError(\"nested EVENT before closing the current frame\"),\n   77│\t\t\t\tevents,\n   78│\t\t\t\trest: raw.slice(start),\n     │...\n   82│\t\t\tif (raw.length - start > maxFrameChars) {\n  *83│\t\t\t\treturn {\n   84│\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n   85│\t\t\t\t\tevents,\n   86│\t\t\t\t\trest: raw.slice(start),\n     │...\n   88│\t\t\t}\n  *89│\t\t\treturn { events, rest: raw.slice(start) };\n   90│\t\t}\n   91│\t\tconst end = close + \"</EVENT>\".length;\n   92│\t\tif (end - start > maxFrameChars) {\n  *93│\t\t\treturn {\n   94│\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n   95│\t\t\t\tevents,\n   96│\t\t\t\trest: raw.slice(start),\n     │...\n   99│\t\tconst parsed = parseEventTag(raw.slice(start, openEnd));\n *100│\t\tif (parsed.error) return { error: parsed.error, events, rest: raw.slice(start) };\n  101│\t\tif (parsed.attributes.type === \"msg\") {\n  102│\t\t\tevents.push({\n  103│\t\t\t\tfrom: parsed.attributes.from,\n     │...\n  108│\t\tcursor = end;\n *109│\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\n  110│\t}\n  111│}\n  112│\n  113│function messageText(message) {\n *114│\tif (typeof message?.content === \"string\") return message.content;\n *115│\treturn (message?.content ?? [])\n  116│\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\n  117│\t\t.map((part) => part.text)\n  118│\t\t.join(\"\");\n     │...\n  125│\t\tconst userIndex = allMessages.findLastIndex((message) => {\n *126│\t\t\tif (message?.role !== \"user\") return false;\n  127│\t\t\tconst text = messageText(message);\n *128│\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\n  129│\t\t});\n *130│\t\tif (userIndex < 0) return \"\";\n  131│\t\tstart = userIndex + 1;\n  132│\t}\n  133│\tconst assistant = allMessages\n     │...\n  136│\t\t.find((message) => message?.role === \"assistant\");\n *137│\treturn assistant ? messageText(assistant) : \"\";\n  138│}\n  139│\n  140│function firstLine(text) {\n *141│\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\n  142│}\n  143│\n  144│function errorSummary(error) {\n  145│\tconst detail = error instanceof Error ? error.message : String(error);\n *146│\treturn firstLine(detail).trim() || \"unknown error\";\n  147│}\n  148│\n  149│function failureMessage(reason, error) {\n  150│\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\n *151│\treturn `[omp-spt] ${reason}${detail}`;\n  152│}\n  153│\n  154│function senderStub(sender) {\n     │...\n  159│\t\t.replaceAll(\">\", \"&gt;\");\n *160│\treturn `<msg from=\"${escaped}\"/>`;\n  161│}\n  162│\n *163│function injectEnvelope(messages, item) {\n  164│\tconst index = messages.findLastIndex(\n  165│\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\n  166│\t);\n *167│\tif (index < 0) return messages;\n  168│\tconst original = messages[index];\n  169│\tconst content =\n  170│\t\ttypeof original.content === \"string\"\n     │...\n  172│\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\n *173│\tconst injected = [...messages];\n *174│\tinjected[index] = { ...original, content };\n *175│\treturn injected;\n  176│}\n  177│\n  178│const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n     │...\n  187│function childExited(child) {\n *188│\treturn (\n  189│\t\t(child.exitCode !== undefined && child.exitCode !== null) ||\n  190│\t\t(child.signalCode !== undefined && child.signalCode !== null)\n  191│\t);\n     │...\n  194│function waitForChildExit(child, timeoutMs, setTimer, clearTimer) {\n *195│\tif (childExited(child)) return Promise.resolve(true);\n *196│\treturn new Promise((resolve) => {\n  197│\t\tlet timer;\n  198│\t\tlet finished = false;\n  199│\t\tconst finish = (exited) => {\n *200│\t\t\tif (finished) return;\n  201│\t\t\tfinished = true;\n  202│\t\t\tif (timer !== undefined) clearTimer(timer);\n  203│\t\t\tchild.off(\"close\", onClose);\n     │...\n  215│\tconst { clearTimer, forceMs, graceMs, setTimer } = options;\n *216│\tif (childExited(child)) return;\n  217│\n  218│\tconst gracefulExit = waitForChildExit(child, graceMs, setTimer, clearTimer);\n  219│\tlet killError;\n     │...\n  224│\t}\n *225│\tif (await gracefulExit) return;\n  226│\n  227│\tconst forcedExit = waitForChildExit(child, forceMs, setTimer, clearTimer);\n  228│\ttry {\n     │...\n  232│\t}\n *233│\tif (await forcedExit) return;\n  234│\n  235│\tchild.stdin?.destroy?.();\n  236│\tchild.stdout?.destroy?.();\n     │...\n  244│\tconst command = args[0] === \"api\" ? args[3] : args[0];\n *245│\treturn `spt ${command ?? \"command\"}`;\n  246│}\n  247│\n  248│export function runSpt(args, input, overrides = {}) {\n     │...\n  258│\tif (signal?.aborted) {\n *259│\t\treturn Promise.reject(\n  260│\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`),\n  261│\t\t);\n  262│\t}\n  263│\n *264│\treturn new Promise((resolve, reject) => {\n  265│\t\tlet child;\n  266│\t\ttry {\n  267│\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\n     │...\n  272│\t\t\treject(error);\n *273│\t\t\treturn;\n  274│\t\t}\n  275│\n  276│\t\tlet output = \"\";\n     │...\n  296│\t\tconst settle = (error) => {\n *297│\t\t\tif (settled) return;\n  298│\t\t\tsettled = true;\n  299│\t\t\tcleanup();\n  300│\t\t\tif (error === undefined) resolve(output.trim());\n     │...\n  303│\t\tconst terminateAndReject = async (error) => {\n *304│\t\t\tif (settled || terminating) return;\n  305│\t\t\tterminating = true;\n  306│\t\t\tif (timeoutTimer !== undefined) {\n  307│\t\t\t\tclearTimer(timeoutTimer);\n     │...\n  330│\t\tconst onClose = (code, signal) => {\n *331│\t\t\tif (terminating || settled) return;\n  332│\t\t\tif (code === 0 && stdinFinished) {\n  333│\t\t\t\tsettle();\n *334│\t\t\t\treturn;\n  335│\t\t\t}\n  336│\t\t\tconst status = signal ? `signal ${signal}` : `exit ${code}`;\n  337│\t\t\tconst detail = firstLine(output);\n     │...\n  358│\t\t\tonAbort();\n *359│\t\t\treturn;\n  360│\t\t}\n  361│\t\ttimeoutTimer = setTimer(() => {\n  362│\t\t\ttimeoutTimer = undefined;\n     │...\n  426│\n *427│\treturn function ompSpt(pi) {\n  428│\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n *429│\t\tif (!id) return;\n  430│\n  431│\t\tlet sid;\n  432│\t\tlet token;\n     │...\n  442│\t\tlet dispatching = false;\n *443│\t\tlet turnCompletionPromise;\n  444│\t\tlet listenerTerminationPromise;\n  445│\t\tlet shutdownMode = false;\n  446│\t\tlet shutdownDeadlineExpired = false;\n     │...\n  468│\t\t\tif (shutdownDeadlineExpired) {\n *469│\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\n  470│\t\t\t}\n  471│\t\t\tconst timeoutMs =\n  472│\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\n     │...\n  484│\t\t\t\tactiveCommands.delete(controller);\n *485│\t\t\t\treturn Promise.reject(error);\n  486│\t\t\t}\n  487│\t\t\tif (customRunSptCommand) {\n  488│\t\t\t\tconst rawCommand = command;\n     │...\n  492│\t\t\t\t\tconst finish = (error, value) => {\n *493│\t\t\t\t\t\tif (finished) return;\n  494│\t\t\t\t\t\tfinished = true;\n  495│\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n  496│\t\t\t\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\n     │...\n  522│\t\t\t}\n *523│\t\t\treturn command.finally(() => {\n  524│\t\t\t\tconst active = activeCommands.get(controller);\n  525│\t\t\t\tif (active?.abortTimer !== undefined) clearTimer(active.abortTimer);\n  526│\t\t\t\tactiveCommands.delete(controller);\n     │...\n  545│\t\tfunction waitForRetry(delay) {\n *546│\t\t\tif (shutdownMode) return Promise.resolve();\n *547│\t\t\treturn new Promise((resolve) => {\n  548│\t\t\t\tlet timer;\n  549│\t\t\t\tconst finish = () => {\n  550│\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n     │...\n  560│\t\tfunction enterShutdownMode() {\n *561│\t\t\tif (shutdownMode) return;\n  562│\t\t\tshutdownMode = true;\n  563│\t\t\tconst reason = new Error(\"omp-spt command interrupted for bounded shutdown\");\n  564│\t\t\tabortActiveCommands(reason, true);\n     │...\n  568│\t\tfunction authArgs() {\n *569│\t\t\tif (!token) throw new Error(\"bind did not return an authentication token\");\n *570│\t\t\treturn [\"--token\", token];\n  571│\t\t}\n  572│\n  573│\t\tfunction setState(state) {\n *574│\t\t\tif (!sid || !token || stopping) return Promise.resolve();\n  575│\t\t\tconst operation = stateOperation.catch(() => {}).then(async () => {\n *576│\t\t\t\tif (endpointState === state || stopping) return;\n  577│\t\t\t\tawait runCommand([\"api\", \"--adapter\", ADAPTER, \"state\", state, id, ...authArgs()]);\n  578│\t\t\t\tendpointState = state;\n  579│\t\t\t});\n  580│\t\t\tstateOperation = operation;\n *581│\t\t\treturn operation;\n  582│\t\t}\n  583│\n  584│\t\tasync function syncDesiredState() {\n *585│\t\t\tif (!bindPromise) return;\n  586│\t\t\tawait bindPromise;\n  587│\t\t\twhile (!stopping && endpointState !== desiredState) {\n  588│\t\t\t\tawait setState(desiredState);\n     │...\n  592│\t\tfunction endSession() {\n *593│\t\t\tif (!sid || !token) return Promise.resolve();\n  594│\t\t\tif (!endPromise) {\n  595│\t\t\t\tconst operation = (async () => {\n  596│\t\t\t\t\tawait stateOperation.catch(() => {});\n     │...\n  604│\t\t\t}\n *605│\t\t\treturn endPromise;\n  606│\t\t}\n  607│\n  608│\t\tasync function endSessionWithRetry() {\n     │...\n  611│\t\t\t\t\tawait endSession();\n *612│\t\t\t\t\treturn;\n  613│\t\t\t\t} catch (error) {\n  614│\t\t\t\t\tif (shutdownMode || attempt >= sessionEndRetryDelaysMs.length) throw error;\n  615│\t\t\t\t\tconst delay = sessionEndRetryDelaysMs[attempt];\n     │...\n  626│\n *627│\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n  628│\t\tfunction settleItem(item, payload) {\n *629│\t\t\tif (!item) return Promise.resolve();\n *630│\t\t\tif (item.outcomePromise) return item.outcomePromise;\n  631│\t\t\titem.settling = true;\n  632│\t\t\titem.outcomePromise = (async () => {\n  633│\t\t\t\tif (!item.from) throw new Error(\"missing EVENT from attribute\");\n     │...\n  637│\t\t\t\t\t\titem.settled = true;\n *638│\t\t\t\t\t\treturn;\n  639│\t\t\t\t\t} catch (error) {\n  640│\t\t\t\t\t\tif (shutdownMode || attempt >= outcomeRetryDelaysMs.length) throw error;\n  641│\t\t\t\t\t\tconst delay = outcomeRetryDelaysMs[attempt];\n     │...\n  651│\t\t\t})();\n *652│\t\t\treturn item.outcomePromise;\n  653│\t\t}\n  654│\n  655│\t\tfunction releaseItem(item) {\n *656│\t\t\tif (!item?.accounted) return;\n  657│\t\t\titem.accounted = false;\n  658│\t\t\tacceptedBytes -= item.acceptedBytes;\n  659│\t\t}\n     │...\n  661│\t\tfunction beginListenerTermination(child, label) {\n *662│\t\t\tif (listenerTerminationPromise) return listenerTerminationPromise;\n  663│\t\t\tconst operation = (async () => {\n  664│\t\t\t\ttry {\n  665│\t\t\t\t\tawait terminateChild(child, label, {\n     │...\n  680│\t\t\t});\n *681│\t\t\treturn operation;\n  682│\t\t}\n  683│\n  684│\t\tasync function stopResources() {\n     │...\n  715│\t\t\t\t\t}\n *716│\t\t\t\t\tif (item.settled) return;\n  717│\t\t\t\t\tif (existingError && !shutdownMode) {\n  718│\t\t\t\t\t\tlogError(\n *719│\t\t\t\t\t\t\t`omp-spt could not return custody to ${item.from ?? \"unknown\"}`,\n  720│\t\t\t\t\t\t\texistingError,\n  721│\t\t\t\t\t\t);\n *722│\t\t\t\t\t\treturn;\n  723│\t\t\t\t\t}\n  724│\t\t\t\t\titem.outcomePromise = undefined;\n  725│\t\t\t\t\titem.settling = false;\n     │...\n  729│\t\t\t\t} catch (error) {\n *730│\t\t\t\t\tlogError(`omp-spt could not return custody to ${item.from ?? \"unknown\"}`, error);\n  731│\t\t\t\t}\n  732│\t\t\t} finally {\n  733│\t\t\t\treleaseItem(item);\n     │...\n  747│\t\t\t\t\t);\n *748│\t\t\t\t\treturn;\n  749│\t\t\t\t}\n  750│\t\t\t\tawait settlePendingItem(pending[index], reason);\n  751│\t\t\t}\n     │...\n  767│\t\t\t}\n *768│\t\t\treturn teardownPromise;\n  769│\t\t}\n  770│\n  771│\t\tasync function shutdownWithinBudget(pendingReason) {\n     │...\n  791│\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n *792│\t\t\t\t\treturn true;\n  793│\t\t\t\t},\n  794│\t\t\t);\n  795│\t\t\tconst finished = await Promise.race([completed, expired]);\n     │...\n  805│\t\tasync function failClosed(message, error) {\n *806│\t\t\tif (stopping && shutdownMode) return teardownPromise ?? Promise.resolve();\n *807│\t\t\tif (fatalPromise) return fatalPromise;\n  808│\t\t\tfatalPromise = (async () => {\n  809│\t\t\t\tui?.setStatus(\"omp-spt\", \"spt failed\");\n  810│\t\t\t\tlogError(message, error);\n     │...\n  817│\t\t\t})();\n *818│\t\t\treturn fatalPromise;\n  819│\t\t}\n  820│\n  821│\t\tfunction scheduleDispatch() {\n     │...\n  829│\t\t\t) {\n *830│\t\t\t\treturn;\n  831│\t\t\t}\n  832│\t\t\tdispatchTimer = setTimer(() => {\n  833│\t\t\t\tdispatchTimer = undefined;\n  834│\t\t\t\tvoid dispatchNext().catch((error) => {\n *835│\t\t\t\t\tif (!stopping) return failClosed(\"omp-spt dispatch failed\", error);\n  836│\t\t\t\t});\n  837│\t\t\t}, 0);\n  838│\t\t\tdispatchTimer?.unref?.();\n     │...\n  841│\t\tasync function rejectItem(item, reason, error) {\n *842│\t\t\tif (stopping) return;\n  843│\t\t\tlogError(`omp-spt ${reason}`, error);\n  844│\t\t\ttry {\n  845│\t\t\t\tawait settleItem(item, failureMessage(reason, error));\n  846│\t\t\t} catch (outcomeError) {\n *847│\t\t\t\tif (stopping) return;\n  848│\t\t\t\tawait failClosed(`omp-spt could not send the outcome to ${item.from ?? \"unknown\"}`, outcomeError);\n *849│\t\t\t\treturn;\n  850│\t\t\t}\n  851│\t\t\tif (current === item) {\n  852│\t\t\t\tcurrent = undefined;\n     │...\n  867│\n *868│\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n  869│\t\tasync function dispatchNext() {\n *870│\t\t\tif (stopping || agentActive || dispatching || current || queue.length === 0) return;\n  871│\t\t\tdispatching = true;\n  872│\t\t\tconst item = queue.shift();\n  873│\t\t\tcurrent = item;\n     │...\n  879│\t\t\t\t\tawait rejectItem(item, \"could not accept your message\", error);\n *880│\t\t\t\t\treturn;\n  881│\t\t\t\t}\n *882│\t\t\t\tif (stopping) return;\n  883│\t\t\t\tif (agentActive) {\n  884│\t\t\t\t\tif (current === item) current = undefined;\n  885│\t\t\t\t\tqueue.unshift(item);\n *886│\t\t\t\t\treturn;\n  887│\t\t\t\t}\n  888│\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n  889│\t\t\t\titem.submitted = true;\n     │...\n  908│\t\t\t}\n *909│\t\t\tif (stopping || restartTimer !== undefined) return;\n  910│\t\t\tif (listenerRestartCount >= restartDelaysMs.length) {\n  911│\t\t\t\tvoid failClosed(\"omp-spt listener restart budget exhausted\", reason);\n *912│\t\t\t\treturn;\n  913│\t\t\t}\n  914│\t\t\tconst attempt = listenerRestartCount + 1;\n  915│\t\t\tconst delay = restartDelaysMs[listenerRestartCount];\n     │...\n  928│\t\tfunction startListener() {\n *929│\t\t\tif (stopping) return;\n  930│\t\t\tconst args = [\"api\", \"--adapter\", ADAPTER, \"listen\", id, \"--session-id\", sid];\n  931│\t\t\tif (env.OMP_SPT_SUBNET) args.push(\"--subnet\", env.OMP_SPT_SUBNET);\n  932│\t\t\tlet child;\n     │...\n  939│\t\t\t\thandleListenerDeath(error);\n *940│\t\t\t\treturn;\n  941│\t\t\t}\n  942│\t\t\tlistener = child;\n  943│\t\t\tlistenerBuffer = \"\";\n  944│\t\t\tlet dead = false;\n *945│\t\t\tconst died = (reason, alreadyExited) => {\n *946│\t\t\t\tif (dead) return;\n  947│\t\t\t\tdead = true;\n  948│\t\t\t\tif (listener === child) listener = undefined;\n *949│\t\t\t\tif (stopping || alreadyExited) {\n  950│\t\t\t\t\thandleListenerDeath(reason);\n *951│\t\t\t\t\treturn;\n  952│\t\t\t\t}\n  953│\t\t\t\tconst termination = beginListenerTermination(child, \"dead spt api listener\");\n  954│\t\t\t\tvoid termination.then(() => handleListenerDeath(reason));\n     │...\n  965│\t\t\tchild.stdout.on(\"data\", (chunk) => {\n *966│\t\t\t\tif (listener !== child || stopping) return;\n  967│\t\t\t\tlistenerBuffer += String(chunk);\n  968│\t\t\t\tif (listenerBuffer.length > listenerBufferLimit) {\n  969│\t\t\t\t\tvoid failClosed(\n     │...\n  974│\t\t\t\t\t);\n *975│\t\t\t\t\treturn;\n  976│\t\t\t\t}\n  977│\t\t\t\twhile (!stopping) {\n  978│\t\t\t\t\tconst drained = drainEvents(listenerBuffer, {\n     │...\n  984│\t\t\t\t\t\tvoid failClosed(\"omp-spt listener protocol corruption\", drained.error);\n *985│\t\t\t\t\t\treturn;\n  986│\t\t\t\t\t}\n  987│\t\t\t\t\tif (drained.events.length === 0) break;\n  988│\t\t\t\t\tconst event = drained.events[0];\n     │...\n  996│\t\t\t\t\t\tvoid failClosed(\n *997│\t\t\t\t\t\t\t\"omp-spt inbound custody capacity exceeded\",\n  998│\t\t\t\t\t\t\tnew Error(\n  999│\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\n 1000│\t\t\t\t\t\t\t),\n 1001│\t\t\t\t\t\t);\n*1002│\t\t\t\t\t\treturn;\n 1003│\t\t\t\t\t}\n 1004│\t\t\t\t\tevent.acceptedBytes = eventBytes;\n 1005│\t\t\t\t\tevent.accounted = true;\n     │...\n 1036│\t\t\t} catch (error) {\n*1037│\t\t\t\tif (stopping) return;\n 1038│\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n 1039│\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n*1040│\t\t\t\treturn;\n 1041│\t\t\t}\n 1042│\t\t\tif (stopping) {\n 1043│\t\t\t\ttry {\n     │...\n 1047│\t\t\t\t}\n*1048│\t\t\t\treturn;\n 1049│\t\t\t}\n 1050│\t\t\ttry {\n 1051│\t\t\t\tawait syncDesiredState();\n     │...\n 1053│\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n*1054│\t\t\t\t\treturn;\n 1055│\t\t\t\t}\n 1056│\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n 1057│\t\t\t\tstartListener();\n     │...\n 1060│\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n*1061│\t\t\t\t\treturn;\n 1062│\t\t\t\t}\n 1063│\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n 1064│\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n     │...\n 1073│\t\t\t);\n*1074│\t\t\treturn { cancel: true };\n 1075│\t\t};\n 1076│\n 1077│\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n     │...\n 1085│\t\tpi.on(\"context\", (event) => {\n*1086│\t\t\tif (!current?.submitted || current.settling) return;\n*1087│\t\t\tconst messages = injectEnvelope(event.messages, current);\n*1088│\t\t\tif (messages !== event.messages) return { messages };\n 1089│\t\t});\n 1090│\n*1091│\t\tasync function completeTurn(event) {\n 1092│\t\t\tagentActive = false;\n 1093│\t\t\tdesiredState = \"idle\";\n*1094│\t\t\tif (stopping) return;\n 1095│\t\t\tconst completed = current;\n 1096│\t\t\tif (completed?.submitted && !completed.settled) {\n 1097│\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\n     │...\n 1100│\t\t\t\t\t\tcompleted,\n*1101│\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n 1102│\t\t\t\t\t);\n 1103│\t\t\t\t} catch (error) {\n*1104│\t\t\t\t\tif (stopping) return;\n 1105│\t\t\t\t\tawait failClosed(\n 1106│\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n 1107│\t\t\t\t\t\terror,\n 1108│\t\t\t\t\t);\n*1109│\t\t\t\t\treturn;\n 1110│\t\t\t\t}\n 1111│\t\t\t}\n 1112│\t\t\tif (current === completed) {\n     │...\n 1118│\t\t\t} catch (error) {\n*1119│\t\t\t\tif (stopping) return;\n 1120│\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n*1121│\t\t\t\treturn;\n 1122│\t\t\t}\n 1123│\t\t\tscheduleDispatch();\n 1124│\t\t}\n     │...\n 1126│\t\tpi.on(\"agent_start\", async () => {\n*1127│\t\t\tif (stopping) return;\n*1128│\t\t\tturnCompletionPromise = undefined;\n 1129│\t\t\tagentActive = true;\n 1130│\t\t\tdesiredState = \"busy\";\n 1131│\t\t\ttry {\n     │...\n 1137│\n*1138│\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n 1139│\t\tpi.on(\"agent_end\", (event) => {\n*1140│\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1141│\t\t\treturn turnCompletionPromise;\n 1142│\t\t});\n 1143│\n 1144│\t\tpi.on(\"session_stop\", async (event) => {\n*1145│\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1146│\t\t\tawait turnCompletionPromise;\n 1147│\t\t});\n 1148│\n 1149│\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {"},"isError":false,"timestamp":1784188868680}}
{"type":"message","id":"b65c40b8","parentId":"3882a819","timestamp":"2026-07-16T08:01:08.681Z","message":{"role":"toolResult","toolCallId":"call_kHnZnyw59dYfA0F2AeAoMi6W|fc_03e5b91f227b0634016a588fc49d90819b8b32fa8c9102c3e7","toolName":"grep","content":[{"type":"text","text":"[traceable-reqs.toml#9F61]\n 10:  \"docs/adr/0009-all-endpoints-use-native-omp.md\",\n*11:  \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",\n*12:  \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",\n*13:  \"docs/adr/0012-continuity-drops-live-under-spt.md\",\n 14:  \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",\n 15:  \"adapter/omp-spt.toml\",\n 16:  \"adapter/strings/omp-spt.mjs\",\n...\n 46:\n*47:# Intentionally inactive until an actual release runs the ADR-0013 acceptance gate. Deterministic\n*48:# fake-process launch evidence must never satisfy this live endpoint requirement.\n 49:[[requirements]]\n*50:id = \"REQ-OMP-LIVE-RELEASE-GATE\"\n*51:title = \"Pending live gate: a real OMP release must satisfy the ADR-0013 endpoint acceptance criteria\"\n 52:required_stages = []\n 53:\n 54:[[requirements]]\n...\n 59:[[requirements]]\n*60:id = \"REQ-OMP-EXTENSION-CUSTODY\"\n*61:title = \"The OMP extension serializes accepted deliveries and preserves sender custody through a correlated reply or explicit failure\"\n 62:required_stages = [\"doc\", \"impl\", \"unit\"]\n 63:\n 64:[[requirements]]\n*65:id = \"REQ-OMP-LISTENER-FAIL-CLOSED\"\n*66:title = \"Unexpected listener exit retries within a finite budget and then performs SPT session-end plus OMP shutdown\"\n 67:required_stages = [\"doc\", \"impl\", \"unit\"]\n 68:\n 69:[[requirements]]\n...\n 75:id = \"REQ-OMP-MESSAGE-CONTEXT\"\n*76:title = \"Each peer delivery opens one ordinary OMP turn containing a message stub and the complete SPT event context\"\n 77:required_stages = [\"doc\", \"impl\", \"unit\"]\n 78:\n 79:[[requirements]]\n*80:id = \"REQ-OMP-READY-LIVE\"\n*81:title = \"The adapter advertises exactly ReadyAgent and LiveAgent endpoint types on the same native OMP hosting path\"\n 82:required_stages = [\"doc\", \"unit\"]\n 83:\n 84:[[requirements]]\n...\n 90:id = \"REQ-PSYCHE-EPHEMERAL-SHIM\"\n*91:title = \"Each LiveAgent Psyche event runs as one bounded OMP turn with file-backed context and explicit reseed signaling\"\n 92:required_stages = [\"doc\", \"impl\", \"unit\"]\n 93:\n 94:[[requirements]]\n...\n 120:id = \"REQ-DIST-BINARY-CONSOLIDATE\"\n*121:title = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\n 122:required_stages = [\"impl\", \"unit\"]\n 123:\n 124:[[requirements]]\n*125:id = \"REQ-PARITY-READY-ACTIVATION\"\n*126:title = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\n 127:required_stages = []\n 128:\n 129:[[requirements]]\n*130:id = \"REQ-PARITY-LIVE-ACTIVATION\"\n*131:title = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\n 132:required_stages = []\n 133:\n 134:[[requirements]]\n*135:id = \"REQ-PARITY-LIVE-AUTO-RESUME\"\n*136:title = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\n 137:required_stages = []\n 138:\n 139:[[requirements]]\n*140:id = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\n*141:title = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\n 142:required_stages = []\n 143:\n 144:[[requirements]]\n 145:id = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\n*146:title = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\n 147:required_stages = []\n 148:\n 149:[[requirements]]\n...\n 155:id = \"REQ-PARITY-TARGETED-HINTS\"\n*156:title = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\n 157:required_stages = []\n 158:\n 159:[[requirements]]\n...\n 180:id = \"REQ-PARITY-ROLE-SKILL\"\n*181:title = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\n 182:required_stages = []\n 183:\n 184:[[requirements]]\n...\n 189:[[requirements]]\n*190:id = \"REQ-PARITY-PEER-SHORTFORM\"\n*191:title = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"\n 192:required_stages = []\n 193:\n 194:[[requirements]]"}],"details":{"scopePath":"traceable-reqs.toml","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\traceable-reqs.toml","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":29,"fileCount":1,"files":["traceable-reqs.toml"],"fileMatches":[{"path":"traceable-reqs.toml","count":29}],"truncated":false,"displayContent":"  10│  \"docs/adr/0009-all-endpoints-use-native-omp.md\",\n *11│  \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",\n *12│  \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",\n *13│  \"docs/adr/0012-continuity-drops-live-under-spt.md\",\n  14│  \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",\n  15│  \"adapter/omp-spt.toml\",\n  16│  \"adapter/strings/omp-spt.mjs\",\n    │...\n  46│\n *47│# Intentionally inactive until an actual release runs the ADR-0013 acceptance gate. Deterministic\n *48│# fake-process launch evidence must never satisfy this live endpoint requirement.\n  49│[[requirements]]\n *50│id = \"REQ-OMP-LIVE-RELEASE-GATE\"\n *51│title = \"Pending live gate: a real OMP release must satisfy the ADR-0013 endpoint acceptance criteria\"\n  52│required_stages = []\n  53│\n  54│[[requirements]]\n    │...\n  59│[[requirements]]\n *60│id = \"REQ-OMP-EXTENSION-CUSTODY\"\n *61│title = \"The OMP extension serializes accepted deliveries and preserves sender custody through a correlated reply or explicit failure\"\n  62│required_stages = [\"doc\", \"impl\", \"unit\"]\n  63│\n  64│[[requirements]]\n *65│id = \"REQ-OMP-LISTENER-FAIL-CLOSED\"\n *66│title = \"Unexpected listener exit retries within a finite budget and then performs SPT session-end plus OMP shutdown\"\n  67│required_stages = [\"doc\", \"impl\", \"unit\"]\n  68│\n  69│[[requirements]]\n    │...\n  75│id = \"REQ-OMP-MESSAGE-CONTEXT\"\n *76│title = \"Each peer delivery opens one ordinary OMP turn containing a message stub and the complete SPT event context\"\n  77│required_stages = [\"doc\", \"impl\", \"unit\"]\n  78│\n  79│[[requirements]]\n *80│id = \"REQ-OMP-READY-LIVE\"\n *81│title = \"The adapter advertises exactly ReadyAgent and LiveAgent endpoint types on the same native OMP hosting path\"\n  82│required_stages = [\"doc\", \"unit\"]\n  83│\n  84│[[requirements]]\n    │...\n  90│id = \"REQ-PSYCHE-EPHEMERAL-SHIM\"\n *91│title = \"Each LiveAgent Psyche event runs as one bounded OMP turn with file-backed context and explicit reseed signaling\"\n  92│required_stages = [\"doc\", \"impl\", \"unit\"]\n  93│\n  94│[[requirements]]\n    │...\n 120│id = \"REQ-DIST-BINARY-CONSOLIDATE\"\n*121│title = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\n 122│required_stages = [\"impl\", \"unit\"]\n 123│\n 124│[[requirements]]\n*125│id = \"REQ-PARITY-READY-ACTIVATION\"\n*126│title = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\n 127│required_stages = []\n 128│\n 129│[[requirements]]\n*130│id = \"REQ-PARITY-LIVE-ACTIVATION\"\n*131│title = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\n 132│required_stages = []\n 133│\n 134│[[requirements]]\n*135│id = \"REQ-PARITY-LIVE-AUTO-RESUME\"\n*136│title = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\n 137│required_stages = []\n 138│\n 139│[[requirements]]\n*140│id = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\n*141│title = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\n 142│required_stages = []\n 143│\n 144│[[requirements]]\n 145│id = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\n*146│title = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\n 147│required_stages = []\n 148│\n 149│[[requirements]]\n    │...\n 155│id = \"REQ-PARITY-TARGETED-HINTS\"\n*156│title = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\n 157│required_stages = []\n 158│\n 159│[[requirements]]\n    │...\n 180│id = \"REQ-PARITY-ROLE-SKILL\"\n*181│title = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\n 182│required_stages = []\n 183│\n 184│[[requirements]]\n    │...\n 189│[[requirements]]\n*190│id = \"REQ-PARITY-PEER-SHORTFORM\"\n*191│title = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"\n 192│required_stages = []\n 193│\n 194│[[requirements]]"},"isError":false,"timestamp":1784188868681}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `AgentSurface`:\n\nConfirmed: I will not edit strings/omp-spt.mjs or tests/omp-extension.mjs. I own packaged omp-plugins skills, package layout/tests, and requirement tags adjacent to that evidence.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"AgentSurface\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531c9b568db7945","from":"AgentSurface","message":"Confirmed: I will not edit strings/omp-spt.mjs or tests/omp-extension.mjs. I own packaged omp-plugins skills, package layout/tests, and requirement tags adjacent to that evidence."},"attribution":"agent","id":"7246927a","parentId":"b65c40b8","timestamp":"2026-07-16T08:01:08.712Z"}
{"type":"message","id":"511d10fe","parentId":"7246927a","timestamp":"2026-07-16T08:01:16.249Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Parsing relevant file and APIs**"},{"type":"toolCall","id":"call_zsM9FrJAs9Rd5EcNoyyyt52x|fc_03e5b91f227b0634016a588fcc2f5c819b88555fbbef0241f2","name":"read","arguments":{"i":"Reading extension utilities","path":"adapter/strings/omp-spt.mjs","selector":"1-430"}},{"type":"toolCall","id":"call_gxvCRqyoNnGVQWZ30H9mAEpT|fc_03e5b91f227b0634016a588fcc2f70819b8c87e13440d33ffa","name":"read","arguments":{"i":"Reading extension lifecycle","path":"adapter/strings/omp-spt.mjs","selector":"420-1180"}},{"type":"toolCall","id":"call_R18zxmI1ITWy0vSUCnuKaRGc|fc_03e5b91f227b0634016a588fcc2f78819bbd7f5378632c52a8","name":"read","arguments":{"i":"Reading extension test harness","path":"tests/omp-extension.mjs","selector":"1-285"}},{"type":"toolCall","id":"call_oFqdaT5FTnmw2hVGwvIsMj0N|fc_03e5b91f227b0634016a588fcc2f7c819bbab4f631a28b4b8f","name":"read","arguments":{"i":"Reading extension custody tests","path":"tests/omp-extension.mjs","selector":"280-590"}},{"type":"toolCall","id":"call_3RL15pldRooXsD3f8OvfcUXC|fc_03e5b91f227b0634016a588fcc2f80819b942e7af5bf4ea5b8","name":"read","arguments":{"i":"Reading requirement matrix","path":"traceable-reqs.toml","selector":"115-205"}},{"type":"toolCall","id":"call_w3lINbTHLWtH9SOaUKlZ9REA|fc_03e5b91f227b0634016a588fcc2f9c819b8ef5dd8cb4756b6d","name":"read","arguments":{"i":"Reading parity specification","path":"docs/PARITY.md","selector":"1-220"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":10466,"output":239,"cacheRead":31232,"cacheWrite":0,"totalTokens":41937,"reasoningTokens":28,"cost":{"input":0.05233,"output":0.00717,"cacheRead":0.015616,"cacheWrite":0,"total":0.075116}},"stopReason":"toolUse","timestamp":1784188868726,"responseId":"resp_03e5b91f227b0634016a588fc509a8819bb680334984f50200","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03e5b91f227b0634016a588fc7e3e4819b979ae8e4d94bc936","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWI_M9xY9zmWXxHMyMONKLQfJPrGBg4Ufko7foQrY-ytGhPGmTgNMCZWeezi_XmDhXuUJ0VPtcsa0P-K2QSrvtsaeVMCuw4DfDsTAQcT-2QfBkF4rXV4fipGgKuHwRaJIdPrZVu-_iXsTsVB7ju5TOb4xBGFIxdm7ayzcMcxsDEn5Csfiyef0COND5Lz1UWkK0ofAmnK8mbPox9ADqQg23A0nD68gfqoMjVyJOAUzBngFlOG3X139TKpt5-zRsnTDTMiacv7ESHVS0gWSh8pbp_QLQ2PpnACv-iEn_W5SMfnP5xUmVL4LsapZtdiaUQzcQX0BTGaJqU2Mj2LWQlH5RYCC_wzgNbA2IEUHsznmF5-0LrAXdQ1YsuGl7GLyX9fostADyBEtqFHPzjjBFqqYSnMo8Ix6e2128IErAafSCpfh19QoZerinjviyGJ6iQh9YwD9txGB4r7wadpQo3iN2_tRe9EQVqO5SKzgnooY_YbpHv1UUOaUtU1o1INrAa8MJicCbUYhU6ASkO1-I0vq5WW692Dq2AMjsSOYFW9B2HEcMA2dZxdZdWhBfLZxKrOYor4QFmsMLV9Fl_3-TBSBexN1NlT2UZq-F5eX_sxoG6wGIiwOdAiFjfDoqM-alGtWyqQbnyNpU-R-j7sIxZUrFBiRcx_asZlygPxQuE9Q32zWzCzoDjg_Rkln3E8V61tx8Ab_-_LHRzpZlGrQ8zB1i6bVu-ZZvC8bpTmppPXtxxFwqgTyZk7MZLOlPn-4g0a1invVKHL12RUtjlcq2oDyTzYKF8Ek6ADfQ9GIiQSy7y0Gtly574oVfTKeggQKjkiUfPZPBjbb_5norm75tZqXn-CKTQVZCg_xNUcO1kHIkGHGJH03EnS_nxsjfPYT6mOhvm_5BJgkHm1pRfqYXlEwkT1SGVBvSENRhh4Tj0iubKm0EzWPCD_rH_expaADnLULu8HlfDsinobUX94N71Mqmk8vZQX-SRfmuQ8e9A27DN9ijVuMz3bQgHVZgfqCqQZCRma-ww_ke_xpSwmIs7HnJGE80WDQ6LlG_8WXI8FQECi47uXzjvHKfdSNiBRL1ALg2jksqv5TaRtN0RRSG9avN8KttQ==","summary":[{"type":"summary_text","text":"**Parsing relevant file and APIs**"}]},{"id":"fc_03e5b91f227b0634016a588fcc2f5c819b88555fbbef0241f2","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension utilities\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1-430\"}","call_id":"call_zsM9FrJAs9Rd5EcNoyyyt52x","name":"read"},{"id":"fc_03e5b91f227b0634016a588fcc2f70819b8c87e13440d33ffa","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension lifecycle\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"420-1180\"}","call_id":"call_gxvCRqyoNnGVQWZ30H9mAEpT","name":"read"},{"id":"fc_03e5b91f227b0634016a588fcc2f78819bbd7f5378632c52a8","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension test harness\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1-285\"}","call_id":"call_R18zxmI1ITWy0vSUCnuKaRGc","name":"read"},{"id":"fc_03e5b91f227b0634016a588fcc2f7c819bbab4f631a28b4b8f","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension custody tests\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"280-590\"}","call_id":"call_oFqdaT5FTnmw2hVGwvIsMj0N","name":"read"},{"id":"fc_03e5b91f227b0634016a588fcc2f80819b942e7af5bf4ea5b8","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading requirement matrix\",\"path\":\"traceable-reqs.toml\",\"selector\":\"115-205\"}","call_id":"call_3RL15pldRooXsD3f8OvfcUXC","name":"read"},{"id":"fc_03e5b91f227b0634016a588fcc2f9c819b8ef5dd8cb4756b6d","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading parity specification\",\"path\":\"docs/PARITY.md\",\"selector\":\"1-220\"}","call_id":"call_w3lINbTHLWtH9SOaUKlZ9REA","name":"read"}]},"duration":7522.08110000001,"ttft":3181.384699999995,"contextSnapshot":{"promptTokens":41698,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_zsM9FrJAs9Rd5EcNoyyyt52x|fc_03e5b91f227b0634016a588fcc2f5c819b88555fbbef0241f2","toolName":"read","startedAt":"2026-07-16T08:01:16.250Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading extension utilities"},"id":"366d2fb9","parentId":"511d10fe","timestamp":"2026-07-16T08:01:16.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_gxvCRqyoNnGVQWZ30H9mAEpT|fc_03e5b91f227b0634016a588fcc2f70819b8c87e13440d33ffa","toolName":"read","startedAt":"2026-07-16T08:01:16.250Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading extension lifecycle"},"id":"9a37bf10","parentId":"366d2fb9","timestamp":"2026-07-16T08:01:16.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_R18zxmI1ITWy0vSUCnuKaRGc|fc_03e5b91f227b0634016a588fcc2f78819bbd7f5378632c52a8","toolName":"read","startedAt":"2026-07-16T08:01:16.250Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading extension test harness"},"id":"84a246e7","parentId":"9a37bf10","timestamp":"2026-07-16T08:01:16.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_oFqdaT5FTnmw2hVGwvIsMj0N|fc_03e5b91f227b0634016a588fcc2f7c819bbab4f631a28b4b8f","toolName":"read","startedAt":"2026-07-16T08:01:16.250Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading extension custody tests"},"id":"29408135","parentId":"84a246e7","timestamp":"2026-07-16T08:01:16.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_3RL15pldRooXsD3f8OvfcUXC|fc_03e5b91f227b0634016a588fcc2f80819b942e7af5bf4ea5b8","toolName":"read","startedAt":"2026-07-16T08:01:16.250Z","args":{"path":"traceable-reqs.toml"},"intent":"Reading requirement matrix"},"id":"f32d2dd0","parentId":"29408135","timestamp":"2026-07-16T08:01:16.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_w3lINbTHLWtH9SOaUKlZ9REA|fc_03e5b91f227b0634016a588fcc2f9c819b8ef5dd8cb4756b6d","toolName":"read","startedAt":"2026-07-16T08:01:16.250Z","args":{"path":"docs/PARITY.md"},"intent":"Reading parity specification"},"id":"9b6950ed","parentId":"f32d2dd0","timestamp":"2026-07-16T08:01:16.250Z"}
{"type":"message","id":"6dd1b6cc","parentId":"9b6950ed","timestamp":"2026-07-16T08:01:16.256Z","message":{"role":"toolResult","toolCallId":"call_w3lINbTHLWtH9SOaUKlZ9REA|fc_03e5b91f227b0634016a588fcc2f9c819b8ef5dd8cb4756b6d","toolName":"read","content":[{"type":"text","text":"[PARITY.md#2CFD]\n1:# omp-spt capability parity record\n2:\n3:> This record compares `omp-spt` with its sister adapter, `claude-spt`.\n4:> Parity means the same user outcome, including agent-facing outcomes, through\n5:> the best OMP-native seam or a discoverable public `spt` command. It does not\n6:> require Claude command names, hooks, PTY translation, or source structure.\n7:> Worker endpoints remain intentionally excluded.\n8:\n9:## Proven shared endpoint surface\n10:\n11:The current adapters already share release install/update, broker-hosted fresh\n12:launch and attachment, native resume, ReadyAgent and LiveAgent roles,\n13:post-spawn identity, inbound delivery and correlated replies, busy/idle\n14:lifecycle, graceful shutdown, Psyche turns, commune/signoff storage,\n15:echo-commune, opaque history, digest extraction, and Windows x86-64 plus GNU\n16:Linux x86-64 release payloads.\n17:\n18:OMP keeps its stronger native invariants: immutable endpoint/session binding,\n19:one bounded custody queue, finite listener recovery, fail-closed exhaustion,\n20:real OMP executable validation, and explicit failures rather than silent empty\n21:outcomes. Capability parity does not weaken those guarantees.\n22:\n23:## Agent-facing parity decisions\n24:\n25:<!-- [doc->REQ-PARITY-READY-ACTIVATION] -->\n26:<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n27:<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\n28:Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n29:commands with argument completion or native selection dialogs. Explicit live\n30:auto-resume selects the most-recent compatible live identity; ordinary\n31:activation never guesses silently. The extension binds the current session and\n32:owns the authenticated listener, after which binding is immutable.\n33:\n34:<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\n35:Messages accepted during an active OMP turn enter at the first proven boundary\n36:before the next tool or model continuation. Custody and arrival order remain\n37:intact; a turn with no injectable boundary falls back to ordinary next-turn\n38:delivery rather than interruption.\n39:\n40:<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\n41:Cancelled, interrupted, and failed turns settle affected custody and restore\n42:receivability automatically. Only exhausted listener recovery closes the\n43:endpoint.\n44:\n45:<!-- [doc->REQ-PARITY-STARTUP-BRIEF] -->\n46:<!-- [doc->REQ-PARITY-TARGETED-HINTS] -->\n47:<!-- [doc->REQ-PARITY-UPDATE-NOTICE] -->\n48:Activated sessions receive a concise startup brief for identity, roster,\n49:messaging, continuity, lifecycle, subnet, version, and update operations.\n50:Targeted hints cover clear live-activation, identity, messaging, subnet, and\n51:checkpoint intent. Available compatible spt-core or adapter updates produce an\n52:actionable notice.\n53:\n54:<!-- [doc->REQ-PARITY-COMMUNE-SKILL] -->\n55:<!-- [doc->REQ-PARITY-CHECKPOINT] -->\n56:<!-- [doc->REQ-PARITY-SIGNOFF-SKILL] -->\n57:<!-- [doc->REQ-PARITY-ROLE-SKILL] -->\n58:Public OMP `omp-plugins` packaging supplies model-driven skills for commune,\n59:signoff, and durable-role inspection/editing. Commune checkpoint mode saves\n60:continuity, resets OMP context through native session APIs, and wakes the same\n61:endpoint without operator intervention.\n62:\n63:<!-- [doc->REQ-PARITY-SETUP] -->\n64:Setup is hybrid: an extension-native command owns deterministic probes and\n65:activation, while a packaged skill owns diagnosis, repair strategy, published\n66:installer use, subnet onboarding, and explicit operator handoffs for\n67:authentication or elevation.\n68:\n69:<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\n70:Assistant output may dispatch the explicit cross-harness peer-message shortform\n71:`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\n72:Normal outbound messaging, roster, stop/shutdown, version, and subnet commands\n73:are taught through setup or startup context rather than duplicated as skills.\n74:\n75:OMP's native provider/profile routing satisfies alternate provider, account,\n76:and model routing parity; no `omp-spt:<profile>` analogue of Claude's CCS\n77:overlay is required.\n78:\n79:## Release-target parity\n80:\n81:<!-- [doc->REQ-DIST-LINUX-MUSL] -->\n82:The supported target set is Windows x86-64 MSVC, GNU Linux x86-64, and a static\n83:Linux x86-64 musl helper compatibility tier for OMP-capable hosts where the GNU\n84:helper is incompatible. The musl tier requires full native endpoint acceptance\n85:on a representative target host; it does not imply generic Alpine support when\n86:OMP itself is unavailable.\n87:\n88:Neither sister adapter packages macOS or Arm64, so those remain explicit shared\n89:limitations rather than current parity gaps.\n90:\n91:<!-- [doc->REQ-DIST-VERSION-CONSISTENCY] -->\n92:The manifest version is canonical. Release gates reject disagreement in the\n93:helper crate, changelog heading, and versioned public documentation.\n94:\n95:<!-- [doc->REQ-DOCS-PUBLISH-GATE] -->\n96:Deterministic local documentation generation and drift checks gate changes.\n97:GitHub Pages publication runs the same gate before publishing.\n98:\n99:<!-- [doc->REQ-DIST-RELEASE-EVIDENCE] -->\n100:Each supported target retains a machine-readable release record naming the\n101:target, source commit and tag, artifact digests, acquisition result, and native\n102:fresh/resume, message/reply, lifecycle, shutdown, and ReadyAgent/LiveAgent\n103:acceptance outcomes.\n104:\n105:## Explicit non-goals\n106:\n107:- Worker endpoint advertisement or OMP-subagent endpoint topology.\n108:- macOS, Arm64, or 32-bit release payloads in this parity program.\n109:- A CCS adapter overlay where native OMP provider/profile routing supplies the\n110:  same outcome.\n111:- Claude hooks, PTY translation, plugin reconciliation, or model-managed\n112:  background polling.\n113:- Claude's retired `>>commune<<` output marker.\n114:- Public support promises for the helper binary's manifest-role subcommands.\n115:- Separate skills for send, roster, stop, version, or subnet.\n116:\n117:## Delivery order\n118:\n119:Coverage lands in dependency order:\n120:\n121:1. repair version and documentation truth, then prove packaged-skill discovery\n122:   and injectable OMP event seams;\n123:2. implement extension-owned ready/live activation, live auto-resume,\n124:   safe-boundary delivery, and abnormal-turn receivability;\n125:3. add startup briefs, targeted hints, update notices, packaged skills,\n126:   checkpoint continuity, hybrid setup, and peer-message shortform;\n127:4. add the musl target and durable machine-readable acceptance records for all\n128:   supported targets.\n129:"}],"details":{"displayContent":{"text":"# omp-spt capability parity record\n\n> This record compares `omp-spt` with its sister adapter, `claude-spt`.\n> Parity means the same user outcome, including agent-facing outcomes, through\n> the best OMP-native seam or a discoverable public `spt` command. It does not\n> require Claude command names, hooks, PTY translation, or source structure.\n> Worker endpoints remain intentionally excluded.\n\n## Proven shared endpoint surface\n\nThe current adapters already share release install/update, broker-hosted fresh\nlaunch and attachment, native resume, ReadyAgent and LiveAgent roles,\npost-spawn identity, inbound delivery and correlated replies, busy/idle\nlifecycle, graceful shutdown, Psyche turns, commune/signoff storage,\necho-commune, opaque history, digest extraction, and Windows x86-64 plus GNU\nLinux x86-64 release payloads.\n\nOMP keeps its stronger native invariants: immutable endpoint/session binding,\none bounded custody queue, finite listener recovery, fail-closed exhaustion,\nreal OMP executable validation, and explicit failures rather than silent empty\noutcomes. Capability parity does not weaken those guarantees.\n\n## Agent-facing parity decisions\n\n<!-- [doc->REQ-PARITY-READY-ACTIVATION] -->\n<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\nOrdinary OMP sessions gain extension-native `/ready` and `/live` activation\ncommands with argument completion or native selection dialogs. Explicit live\nauto-resume selects the most-recent compatible live identity; ordinary\nactivation never guesses silently. The extension binds the current session and\nowns the authenticated listener, after which binding is immutable.\n\n<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\nMessages accepted during an active OMP turn enter at the first proven boundary\nbefore the next tool or model continuation. Custody and arrival order remain\nintact; a turn with no injectable boundary falls back to ordinary next-turn\ndelivery rather than interruption.\n\n<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\nCancelled, interrupted, and failed turns settle affected custody and restore\nreceivability automatically. Only exhausted listener recovery closes the\nendpoint.\n\n<!-- [doc->REQ-PARITY-STARTUP-BRIEF] -->\n<!-- [doc->REQ-PARITY-TARGETED-HINTS] -->\n<!-- [doc->REQ-PARITY-UPDATE-NOTICE] -->\nActivated sessions receive a concise startup brief for identity, roster,\nmessaging, continuity, lifecycle, subnet, version, and update operations.\nTargeted hints cover clear live-activation, identity, messaging, subnet, and\ncheckpoint intent. Available compatible spt-core or adapter updates produce an\nactionable notice.\n\n<!-- [doc->REQ-PARITY-COMMUNE-SKILL] -->\n<!-- [doc->REQ-PARITY-CHECKPOINT] -->\n<!-- [doc->REQ-PARITY-SIGNOFF-SKILL] -->\n<!-- [doc->REQ-PARITY-ROLE-SKILL] -->\nPublic OMP `omp-plugins` packaging supplies model-driven skills for commune,\nsignoff, and durable-role inspection/editing. Commune checkpoint mode saves\ncontinuity, resets OMP context through native session APIs, and wakes the same\nendpoint without operator intervention.\n\n<!-- [doc->REQ-PARITY-SETUP] -->\nSetup is hybrid: an extension-native command owns deterministic probes and\nactivation, while a packaged skill owns diagnosis, repair strategy, published\ninstaller use, subnet onboarding, and explicit operator handoffs for\nauthentication or elevation.\n\n<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\nAssistant output may dispatch the explicit cross-harness peer-message shortform\n`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\nNormal outbound messaging, roster, stop/shutdown, version, and subnet commands\nare taught through setup or startup context rather than duplicated as skills.\n\nOMP's native provider/profile routing satisfies alternate provider, account,\nand model routing parity; no `omp-spt:<profile>` analogue of Claude's CCS\noverlay is required.\n\n## Release-target parity\n\n<!-- [doc->REQ-DIST-LINUX-MUSL] -->\nThe supported target set is Windows x86-64 MSVC, GNU Linux x86-64, and a static\nLinux x86-64 musl helper compatibility tier for OMP-capable hosts where the GNU\nhelper is incompatible. The musl tier requires full native endpoint acceptance\non a representative target host; it does not imply generic Alpine support when\nOMP itself is unavailable.\n\nNeither sister adapter packages macOS or Arm64, so those remain explicit shared\nlimitations rather than current parity gaps.\n\n<!-- [doc->REQ-DIST-VERSION-CONSISTENCY] -->\nThe manifest version is canonical. Release gates reject disagreement in the\nhelper crate, changelog heading, and versioned public documentation.\n\n<!-- [doc->REQ-DOCS-PUBLISH-GATE] -->\nDeterministic local documentation generation and drift checks gate changes.\nGitHub Pages publication runs the same gate before publishing.\n\n<!-- [doc->REQ-DIST-RELEASE-EVIDENCE] -->\nEach supported target retains a machine-readable release record naming the\ntarget, source commit and tag, artifact digests, acquisition result, and native\nfresh/resume, message/reply, lifecycle, shutdown, and ReadyAgent/LiveAgent\nacceptance outcomes.\n\n## Explicit non-goals\n\n- Worker endpoint advertisement or OMP-subagent endpoint topology.\n- macOS, Arm64, or 32-bit release payloads in this parity program.\n- A CCS adapter overlay where native OMP provider/profile routing supplies the\n  same outcome.\n- Claude hooks, PTY translation, plugin reconciliation, or model-managed\n  background polling.\n- Claude's retired `>>commune<<` output marker.\n- Public support promises for the helper binary's manifest-role subcommands.\n- Separate skills for send, roster, stop, version, or subnet.\n\n## Delivery order\n\nCoverage lands in dependency order:\n\n1. repair version and documentation truth, then prove packaged-skill discovery\n   and injectable OMP event seams;\n2. implement extension-owned ready/live activation, live auto-resume,\n   safe-boundary delivery, and abnormal-turn receivability;\n3. add startup briefs, targeted hints, update notices, packaged skills,\n   checkpoint continuity, hybrid setup, and peer-message shortform;\n4. add the musl target and durable machine-readable acceptance records for all\n   supported targets.\n","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\docs\\PARITY.md"}}},"isError":false,"timestamp":1784188876255}}
{"type":"message","id":"4e5b386c","parentId":"6dd1b6cc","timestamp":"2026-07-16T08:01:16.257Z","message":{"role":"toolResult","toolCallId":"call_3RL15pldRooXsD3f8OvfcUXC|fc_03e5b91f227b0634016a588fcc2f80819b942e7af5bf4ea5b8","toolName":"read","content":[{"type":"text","text":"[traceable-reqs.toml#9F61]\n114:[[requirements]]\n115:id = \"REQ-DIST-ADAPTER-RELEASE\"\n116:title = \"One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\"\n117:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n118:\n119:[[requirements]]\n120:id = \"REQ-DIST-BINARY-CONSOLIDATE\"\n121:title = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\n122:required_stages = [\"impl\", \"unit\"]\n123:\n124:[[requirements]]\n125:id = \"REQ-PARITY-READY-ACTIVATION\"\n126:title = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\n127:required_stages = []\n128:\n129:[[requirements]]\n130:id = \"REQ-PARITY-LIVE-ACTIVATION\"\n131:title = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\n132:required_stages = []\n133:\n134:[[requirements]]\n135:id = \"REQ-PARITY-LIVE-AUTO-RESUME\"\n136:title = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\n137:required_stages = []\n138:\n139:[[requirements]]\n140:id = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\n141:title = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\n142:required_stages = []\n143:\n144:[[requirements]]\n145:id = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\n146:title = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\n147:required_stages = []\n148:\n149:[[requirements]]\n150:id = \"REQ-PARITY-STARTUP-BRIEF\"\n151:title = \"Activated OMP sessions receive concise identity, roster, messaging, continuity, lifecycle, subnet, and version guidance\"\n152:required_stages = []\n153:\n154:[[requirements]]\n155:id = \"REQ-PARITY-TARGETED-HINTS\"\n156:title = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\n157:required_stages = []\n158:\n159:[[requirements]]\n160:id = \"REQ-PARITY-UPDATE-NOTICE\"\n161:title = \"An activated session receives an actionable notice when its spt-core or omp-spt version trails a compatible release\"\n162:required_stages = []\n163:\n164:[[requirements]]\n165:id = \"REQ-PARITY-COMMUNE-SKILL\"\n166:title = \"A packaged OMP plugin skill authors endpoint-qualified commune continuity drops\"\n167:required_stages = []\n168:\n169:[[requirements]]\n170:id = \"REQ-PARITY-CHECKPOINT\"\n171:title = \"Commune checkpoint mode saves continuity, resets OMP context natively, and wakes the same endpoint without operator intervention\"\n172:required_stages = []\n173:\n174:[[requirements]]\n175:id = \"REQ-PARITY-SIGNOFF-SKILL\"\n176:title = \"A packaged OMP plugin skill authors final signoff continuity and gracefully shuts down the endpoint\"\n177:required_stages = []\n178:\n179:[[requirements]]\n180:id = \"REQ-PARITY-ROLE-SKILL\"\n181:title = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\n182:required_stages = []\n183:\n184:[[requirements]]\n185:id = \"REQ-PARITY-SETUP\"\n186:title = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\n187:required_stages = []\n188:\n189:[[requirements]]\n190:id = \"REQ-PARITY-PEER-SHORTFORM\"\n191:title = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"\n192:required_stages = []\n193:\n194:[[requirements]]\n195:id = \"REQ-DIST-LINUX-MUSL\"\n196:title = \"The release ships and natively accepts a static x86_64 Linux musl helper compatibility tier\"\n197:required_stages = []\n198:\n199:[[requirements]]\n200:id = \"REQ-DIST-VERSION-CONSISTENCY\"\n201:title = \"Manifest version is canonical and release gates reject disagreement in helper, changelog, and versioned public documentation\"\n202:required_stages = []\n203:\n204:[[requirements]]\n205:id = \"REQ-DOCS-PUBLISH-GATE\"\n206:title = \"Local deterministic docs drift checks gate changes and the same checks gate GitHub Pages publication\"\n207:required_stages = []\n208:\n\n[Showing lines 114-208 of 213. Use :209 to continue]"}],"details":{"truncation":{"content":"[[requirements]]\nid = \"REQ-DIST-ADAPTER-RELEASE\"\ntitle = \"One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-DIST-BINARY-CONSOLIDATE\"\ntitle = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\nrequired_stages = [\"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-READY-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-AUTO-RESUME\"\ntitle = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\ntitle = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\ntitle = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-STARTUP-BRIEF\"\ntitle = \"Activated OMP sessions receive concise identity, roster, messaging, continuity, lifecycle, subnet, and version guidance\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-TARGETED-HINTS\"\ntitle = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-UPDATE-NOTICE\"\ntitle = \"An activated session receives an actionable notice when its spt-core or omp-spt version trails a compatible release\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-COMMUNE-SKILL\"\ntitle = \"A packaged OMP plugin skill authors endpoint-qualified commune continuity drops\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-CHECKPOINT\"\ntitle = \"Commune checkpoint mode saves continuity, resets OMP context natively, and wakes the same endpoint without operator intervention\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-SIGNOFF-SKILL\"\ntitle = \"A packaged OMP plugin skill authors final signoff continuity and gracefully shuts down the endpoint\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-ROLE-SKILL\"\ntitle = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-SETUP\"\ntitle = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-PEER-SHORTFORM\"\ntitle = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-DIST-LINUX-MUSL\"\ntitle = \"The release ships and natively accepts a static x86_64 Linux musl helper compatibility tier\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-DIST-VERSION-CONSISTENCY\"\ntitle = \"Manifest version is canonical and release gates reject disagreement in helper, changelog, and versioned public documentation\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-DOCS-PUBLISH-GATE\"\ntitle = \"Local deterministic docs drift checks gate changes and the same checks gate GitHub Pages publication\"\nrequired_stages = []\n","truncated":true,"truncatedBy":"lines","totalLines":100,"totalBytes":3740,"outputLines":95,"outputBytes":3740,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"[[requirements]]\nid = \"REQ-DIST-ADAPTER-RELEASE\"\ntitle = \"One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-DIST-BINARY-CONSOLIDATE\"\ntitle = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\nrequired_stages = [\"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-READY-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-AUTO-RESUME\"\ntitle = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\ntitle = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\ntitle = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-STARTUP-BRIEF\"\ntitle = \"Activated OMP sessions receive concise identity, roster, messaging, continuity, lifecycle, subnet, and version guidance\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-TARGETED-HINTS\"\ntitle = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-UPDATE-NOTICE\"\ntitle = \"An activated session receives an actionable notice when its spt-core or omp-spt version trails a compatible release\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-COMMUNE-SKILL\"\ntitle = \"A packaged OMP plugin skill authors endpoint-qualified commune continuity drops\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-CHECKPOINT\"\ntitle = \"Commune checkpoint mode saves continuity, resets OMP context natively, and wakes the same endpoint without operator intervention\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-SIGNOFF-SKILL\"\ntitle = \"A packaged OMP plugin skill authors final signoff continuity and gracefully shuts down the endpoint\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-ROLE-SKILL\"\ntitle = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-SETUP\"\ntitle = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-PARITY-PEER-SHORTFORM\"\ntitle = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-DIST-LINUX-MUSL\"\ntitle = \"The release ships and natively accepts a static x86_64 Linux musl helper compatibility tier\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-DIST-VERSION-CONSISTENCY\"\ntitle = \"Manifest version is canonical and release gates reject disagreement in helper, changelog, and versioned public documentation\"\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-DOCS-PUBLISH-GATE\"\ntitle = \"Local deterministic docs drift checks gate changes and the same checks gate GitHub Pages publication\"\nrequired_stages = []\n","startLine":114,"lineNumbers":[114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\traceable-reqs.toml"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":213,"totalBytes":3740,"outputLines":95,"outputBytes":3740,"shownRange":{"start":114,"end":208},"nextOffset":209}}},"isError":false,"timestamp":1784188876257}}
{"type":"message","id":"8e214892","parentId":"4e5b386c","timestamp":"2026-07-16T08:01:16.275Z","message":{"role":"toolResult","toolCallId":"call_zsM9FrJAs9Rd5EcNoyyyt52x|fc_03e5b91f227b0634016a588fcc2f5c819b88555fbbef0241f2","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#CA60]\n1:import { spawn } from \"node:child_process\";\n2:\n3:const ADAPTER = \"omp-spt\";\n4:\n5:export function decodeBody(body) {\n6:\treturn body\n7:\t\t.replaceAll(\"<br>\", \"\\n\")\n8:\t\t.replaceAll(\"&lt;\", \"<\")\n9:\t\t.replaceAll(\"&gt;\", \">\")\n10:\t\t.replaceAll(\"&quot;\", '\"')\n11:\t\t.replaceAll(\"&amp;\", \"&\");\n12:}\n13:\n14:function protocolError(message) {\n15:\tconst error = new Error(`invalid spt EVENT stream: ${message}`);\n16:\terror.code = \"SPT_PROTOCOL_ERROR\";\n17:\treturn error;\n18:}\n19:\n20:function parseEventTag(tag) {\n21:\tif (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };\n22:\tlet cursor = \"<EVENT\".length;\n23:\tconst attributes = Object.create(null);\n24:\twhile (cursor < tag.length) {\n25:\t\tif (!/\\s/.test(tag[cursor])) {\n26:\t\t\treturn { error: protocolError(\"malformed EVENT attributes\") };\n27:\t\t}\n28:\t\twhile (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;\n29:\t\tif (cursor === tag.length) break;\n30:\t\tconst match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));\n31:\t\tif (!match) return { error: protocolError(\"malformed EVENT attributes\") };\n32:\t\tconst [, name, value] = match;\n33:\t\tif (Object.hasOwn(attributes, name)) {\n34:\t\t\treturn { error: protocolError(`duplicate EVENT ${name} attribute`) };\n35:\t\t}\n36:\t\tattributes[name] = value;\n37:\t\tcursor += match[0].length;\n38:\t}\n39:\tif (!attributes.type) return { error: protocolError(\"missing EVENT type attribute\") };\n40:\tif (attributes.type === \"msg\" && !attributes.from) {\n41:\t\treturn { error: protocolError(\"missing EVENT from attribute\") };\n42:\t}\n43:\treturn { attributes };\n44:}\n45:\n46:export function drainEvents(raw, options = {}) {\n47:\tconst maxEvents = options.maxEvents ?? Number.POSITIVE_INFINITY;\n48:\tconst maxFrameChars = options.maxFrameChars ?? DEFAULT_LISTENER_BUFFER_LIMIT;\n49:\tconst events = [];\n50:\tlet cursor = 0;\n51:\twhile (true) {\n52:\t\tconst start = raw.indexOf(\"<EVENT\", cursor);\n53:\t\tif (start < 0) return { events, rest: raw.slice(cursor) };\n54:\t\tconst openEnd = raw.indexOf(\">\", start);\n55:\t\tif (openEnd < 0) {\n56:\t\t\tif (raw.length - start > maxFrameChars) {\n57:\t\t\t\treturn {\n58:\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n59:\t\t\t\t\tevents,\n60:\t\t\t\t\trest: raw.slice(start),\n61:\t\t\t\t};\n62:\t\t\t}\n63:\t\t\treturn { events, rest: raw.slice(start) };\n64:\t\t}\n65:\t\tif (openEnd + 1 - start > maxFrameChars) {\n66:\t\t\treturn {\n67:\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n68:\t\t\t\tevents,\n69:\t\t\t\trest: raw.slice(start),\n70:\t\t\t};\n71:\t\t}\n72:\t\tconst close = raw.indexOf(\"</EVENT>\", openEnd + 1);\n73:\t\tconst nested = raw.indexOf(\"<EVENT\", openEnd + 1);\n74:\t\tif (nested >= 0 && (close < 0 || nested < close)) {\n75:\t\t\treturn {\n76:\t\t\t\terror: protocolError(\"nested EVENT before closing the current frame\"),\n77:\t\t\t\tevents,\n78:\t\t\t\trest: raw.slice(start),\n79:\t\t\t};\n80:\t\t}\n81:\t\tif (close < 0) {\n82:\t\t\tif (raw.length - start > maxFrameChars) {\n83:\t\t\t\treturn {\n84:\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n85:\t\t\t\t\tevents,\n86:\t\t\t\t\trest: raw.slice(start),\n87:\t\t\t\t};\n88:\t\t\t}\n89:\t\t\treturn { events, rest: raw.slice(start) };\n90:\t\t}\n91:\t\tconst end = close + \"</EVENT>\".length;\n92:\t\tif (end - start > maxFrameChars) {\n93:\t\t\treturn {\n94:\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\n95:\t\t\t\tevents,\n96:\t\t\t\trest: raw.slice(start),\n97:\t\t\t};\n98:\t\t}\n99:\t\tconst parsed = parseEventTag(raw.slice(start, openEnd));\n100:\t\tif (parsed.error) return { error: parsed.error, events, rest: raw.slice(start) };\n101:\t\tif (parsed.attributes.type === \"msg\") {\n102:\t\t\tevents.push({\n103:\t\t\t\tfrom: parsed.attributes.from,\n104:\t\t\t\tbody: decodeBody(raw.slice(openEnd + 1, close)),\n105:\t\t\t\tenvelope: raw.slice(start, end),\n106:\t\t\t});\n107:\t\t}\n108:\t\tcursor = end;\n109:\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\n110:\t}\n111:}\n112:\n113:function messageText(message) {\n114:\tif (typeof message?.content === \"string\") return message.content;\n115:\treturn (message?.content ?? [])\n116:\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\n117:\t\t.map((part) => part.text)\n118:\t\t.join(\"\");\n119:}\n120:\n121:export function extractReply(messages, afterUserMessage) {\n122:\tconst allMessages = messages ?? [];\n123:\tlet start = 0;\n124:\tif (afterUserMessage !== undefined) {\n125:\t\tconst userIndex = allMessages.findLastIndex((message) => {\n126:\t\t\tif (message?.role !== \"user\") return false;\n127:\t\t\tconst text = messageText(message);\n128:\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\n129:\t\t});\n130:\t\tif (userIndex < 0) return \"\";\n131:\t\tstart = userIndex + 1;\n132:\t}\n133:\tconst assistant = allMessages\n134:\t\t.slice(start)\n135:\t\t.reverse()\n136:\t\t.find((message) => message?.role === \"assistant\");\n137:\treturn assistant ? messageText(assistant) : \"\";\n138:}\n139:\n140:function firstLine(text) {\n141:\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\n142:}\n143:\n144:function errorSummary(error) {\n145:\tconst detail = error instanceof Error ? error.message : String(error);\n146:\treturn firstLine(detail).trim() || \"unknown error\";\n147:}\n148:\n149:function failureMessage(reason, error) {\n150:\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\n151:\treturn `[omp-spt] ${reason}${detail}`;\n152:}\n153:\n154:function senderStub(sender) {\n155:\tconst escaped = sender\n156:\t\t.replaceAll(\"&\", \"&amp;\")\n157:\t\t.replaceAll('\"', \"&quot;\")\n158:\t\t.replaceAll(\"<\", \"&lt;\")\n159:\t\t.replaceAll(\">\", \"&gt;\");\n160:\treturn `<msg from=\"${escaped}\"/>`;\n161:}\n162:\n163:function injectEnvelope(messages, item) {\n164:\tconst index = messages.findLastIndex(\n165:\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\n166:\t);\n167:\tif (index < 0) return messages;\n168:\tconst original = messages[index];\n169:\tconst content =\n170:\t\ttypeof original.content === \"string\"\n171:\t\t\t? `${original.content}\\n\\n${item.envelope}`\n172:\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\n173:\tconst injected = [...messages];\n174:\tinjected[index] = { ...original, content };\n175:\treturn injected;\n176:}\n177:\n178:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n179:const DEFAULT_KILL_GRACE_MS = 100;\n180:const DEFAULT_KILL_FORCE_MS = 100;\n181:const DEFAULT_LISTENER_BUFFER_LIMIT = 256 * 1024;\n182:const DEFAULT_ACCEPTED_QUEUE_LIMIT = 128;\n183:const DEFAULT_ACCEPTED_BYTES_LIMIT = 1024 * 1024;\n184:const DEFAULT_SHUTDOWN_BUDGET_MS = 1_800;\n185:const DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS = 300;\n186:\n187:function childExited(child) {\n188:\treturn (\n189:\t\t(child.exitCode !== undefined && child.exitCode !== null) ||\n190:\t\t(child.signalCode !== undefined && child.signalCode !== null)\n191:\t);\n192:}\n193:\n194:function waitForChildExit(child, timeoutMs, setTimer, clearTimer) {\n195:\tif (childExited(child)) return Promise.resolve(true);\n196:\treturn new Promise((resolve) => {\n197:\t\tlet timer;\n198:\t\tlet finished = false;\n199:\t\tconst finish = (exited) => {\n200:\t\t\tif (finished) return;\n201:\t\t\tfinished = true;\n202:\t\t\tif (timer !== undefined) clearTimer(timer);\n203:\t\t\tchild.off(\"close\", onClose);\n204:\t\t\tresolve(exited);\n205:\t\t};\n206:\t\tconst onClose = () => finish(true);\n207:\t\tchild.once(\"close\", onClose);\n208:\t\ttimer = setTimer(() => finish(false), timeoutMs);\n209:\t\ttimer?.unref?.();\n210:\t\tif (childExited(child)) finish(true);\n211:\t});\n212:}\n213:\n214:async function terminateChild(child, label, options) {\n215:\tconst { clearTimer, forceMs, graceMs, setTimer } = options;\n216:\tif (childExited(child)) return;\n217:\n218:\tconst gracefulExit = waitForChildExit(child, graceMs, setTimer, clearTimer);\n219:\tlet killError;\n220:\ttry {\n221:\t\tchild.kill();\n222:\t} catch (error) {\n223:\t\tkillError = error;\n224:\t}\n225:\tif (await gracefulExit) return;\n226:\n227:\tconst forcedExit = waitForChildExit(child, forceMs, setTimer, clearTimer);\n228:\ttry {\n229:\t\tchild.kill(\"SIGKILL\");\n230:\t} catch (error) {\n231:\t\tkillError ??= error;\n232:\t}\n233:\tif (await forcedExit) return;\n234:\n235:\tchild.stdin?.destroy?.();\n236:\tchild.stdout?.destroy?.();\n237:\tchild.stderr?.destroy?.();\n238:\tchild.unref?.();\n239:\tconst detail = killError === undefined ? \"\" : `: ${errorSummary(killError)}`;\n240:\tthrow new Error(`${label} did not exit after forced termination${detail}`);\n241:}\n242:\n243:function commandLabel(args) {\n244:\tconst command = args[0] === \"api\" ? args[3] : args[0];\n245:\treturn `spt ${command ?? \"command\"}`;\n246:}\n247:\n248:export function runSpt(args, input, overrides = {}) {\n249:\tconst spawnProcess = overrides.spawnProcess ?? spawn;\n250:\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\n251:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n252:\tconst timeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n253:\tconst graceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n254:\tconst forceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n255:\tconst env = overrides.env ?? process.env;\n256:\tconst label = commandLabel(args);\n257:\tconst signal = overrides.signal;\n258:\tif (signal?.aborted) {\n259:\t\treturn Promise.reject(\n260:\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`),\n261:\t\t);\n262:\t}\n263:\n264:\treturn new Promise((resolve, reject) => {\n265:\t\tlet child;\n266:\t\ttry {\n267:\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\n268:\t\t\t\tstdio: [input === undefined ? \"ignore\" : \"pipe\", \"pipe\", \"pipe\"],\n269:\t\t\t\twindowsHide: true,\n270:\t\t\t});\n271:\t\t} catch (error) {\n272:\t\t\treject(error);\n273:\t\t\treturn;\n274:\t\t}\n275:\n276:\t\tlet output = \"\";\n277:\t\tlet settled = false;\n278:\t\tlet terminating = false;\n279:\t\tlet stdinFinished = input === undefined;\n280:\t\tlet timeoutTimer;\n281:\t\tconst onAbort = () => {\n282:\t\t\tconst error =\n283:\t\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`);\n284:\t\t\tvoid terminateAndReject(error);\n285:\t\t};\n286:\t\tconst onStdout = (chunk) => (output += chunk);\n287:\t\tconst onStderr = (chunk) => (output += chunk);\n288:\t\tconst cleanup = () => {\n289:\t\t\tif (timeoutTimer !== undefined) clearTimer(timeoutTimer);\n290:\t\t\tchild.stdout.off(\"data\", onStdout);\n291:\t\t\tchild.stderr.off(\"data\", onStderr);\n292:\t\t\tchild.stdin?.off(\"finish\", onStdinFinish);\n293:\t\t\tchild.off(\"close\", onClose);\n294:\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n295:\t\t};\n296:\t\tconst settle = (error) => {\n297:\t\t\tif (settled) return;\n298:\t\t\tsettled = true;\n299:\t\t\tcleanup();\n300:\t\t\tif (error === undefined) resolve(output.trim());\n301:\t\t\telse reject(error);\n302:\t\t};\n303:\t\tconst terminateAndReject = async (error) => {\n304:\t\t\tif (settled || terminating) return;\n305:\t\t\tterminating = true;\n306:\t\t\tif (timeoutTimer !== undefined) {\n307:\t\t\t\tclearTimer(timeoutTimer);\n308:\t\t\t\ttimeoutTimer = undefined;\n309:\t\t\t}\n310:\t\t\ttry {\n311:\t\t\t\tawait terminateChild(child, label, {\n312:\t\t\t\t\tclearTimer,\n313:\t\t\t\t\tforceMs,\n314:\t\t\t\t\tgraceMs,\n315:\t\t\t\t\tsetTimer,\n316:\t\t\t\t});\n317:\t\t\t} catch (terminationError) {\n318:\t\t\t\terror = new Error(`${errorSummary(error)}; ${errorSummary(terminationError)}`, {\n319:\t\t\t\t\tcause: error,\n320:\t\t\t\t});\n321:\t\t\t}\n322:\t\t\tsettle(error);\n323:\t\t};\n324:\t\tconst onStdinError = (error) => {\n325:\t\t\tvoid terminateAndReject(error);\n326:\t\t};\n327:\t\tconst onStdinFinish = () => {\n328:\t\t\tstdinFinished = true;\n329:\t\t};\n330:\t\tconst onClose = (code, signal) => {\n331:\t\t\tif (terminating || settled) return;\n332:\t\t\tif (code === 0 && stdinFinished) {\n333:\t\t\t\tsettle();\n334:\t\t\t\treturn;\n335:\t\t\t}\n336:\t\t\tconst status = signal ? `signal ${signal}` : `exit ${code}`;\n337:\t\t\tconst detail = firstLine(output);\n338:\t\t\tconst suffix = detail ? `: ${detail}` : \"\";\n339:\t\t\tif (code === 0) {\n340:\t\t\t\tvoid terminateAndReject(new Error(`${label} exited before stdin completed${suffix}`));\n341:\t\t\t} else {\n342:\t\t\t\tvoid terminateAndReject(new Error(`${label} ${status}${suffix}`));\n343:\t\t\t}\n344:\t\t};\n345:\n346:\t\tchild.stdout.setEncoding(\"utf8\");\n347:\t\tchild.stderr.setEncoding(\"utf8\");\n348:\t\tchild.stdout.on(\"data\", onStdout);\n349:\t\tchild.stderr.on(\"data\", onStderr);\n350:\t\tchild.on(\"error\", onStdinError);\n351:\t\tchild.on(\"close\", onClose);\n352:\t\tif (input !== undefined) {\n353:\t\t\tchild.stdin.on(\"error\", onStdinError);\n354:\t\t\tchild.stdin.once(\"finish\", onStdinFinish);\n355:\t\t}\n356:\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n357:\t\tif (signal?.aborted) {\n358:\t\t\tonAbort();\n359:\t\t\treturn;\n360:\t\t}\n361:\t\ttimeoutTimer = setTimer(() => {\n362:\t\t\ttimeoutTimer = undefined;\n363:\t\t\tvoid terminateAndReject(new Error(`${label} timed out after ${timeoutMs}ms`));\n364:\t\t}, timeoutMs);\n365:\t\ttimeoutTimer?.unref?.();\n366:\t\tif (input !== undefined) {\n367:\t\t\ttry {\n368:\t\t\t\tchild.stdin.end(input);\n369:\t\t\t} catch (error) {\n370:\t\t\t\tvoid terminateAndReject(error);\n371:\t\t\t}\n372:\t\t}\n373:\t});\n374:}\n375:\n376:export function createOmpSpt(overrides = {}) {\n377:\tconst spawnProcess = overrides.spawnProcess ?? spawn;\n378:\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\n379:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n380:\tconst env = overrides.env ?? process.env;\n381:\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n382:\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n383:\tconst customRunSptCommand = overrides.runSptCommand;\n384:\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n385:\tconst runSptCommand =\n386:\t\tcustomRunSptCommand ??\n387:\t\t((args, input, options = {}) =>\n388:\t\t\trunSpt(args, input, {\n389:\t\t\t\tclearTimeout: clearTimer,\n390:\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\n391:\t\t\t\tenv,\n392:\t\t\t\tkillForceMs,\n393:\t\t\t\tkillGraceMs,\n394:\t\t\t\tsetTimeout: setTimer,\n395:\t\t\t\tsignal: options.signal,\n396:\t\t\t\tspawnProcess,\n397:\t\t\t}));\n398:\tconst shutdownBudgetMs =\n399:\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\n400:\tconst requestedShutdownCommandTimeoutMs =\n401:\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\n402:\tconst terminationWindowMs = killGraceMs + killForceMs;\n403:\tconst maxShutdownCommandTimeoutMs = Math.max(\n404:\t\t1,\n405:\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\n406:\t);\n407:\tconst shutdownCommandTimeoutMs = Math.max(\n408:\t\t1,\n409:\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\n410:\t);\n411:\tconst listenerBufferLimit =\n412:\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\n413:\tconst acceptedQueueLimit =\n414:\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\n415:\tconst acceptedBytesLimit =\n416:\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\n417:\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\n418:\tconst outcomeRetryDelaysMs = [\n419:\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\n420:\t];\n421:\tconst sessionEndRetryDelaysMs = [\n422:\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\n423:\t];\n424:\tconst listenerStableMs =\n425:\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\n426:\n427:\treturn function ompSpt(pi) {\n428:\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n429:\t\tif (!id) return;\n430:\n431:\t\tlet sid;\n432:\t\tlet token;\n433:\t\tlet listener;\n…\n1154:\t};\n1155:}\n\n[Showing lines 1-433 of 1158. Use :434 to continue]"}],"details":{"truncation":{"content":"import { spawn } from \"node:child_process\";\r\n\r\nconst ADAPTER = \"omp-spt\";\r\n\r\nexport function decodeBody(body) {\r\n\treturn body\r\n\t\t.replaceAll(\"<br>\", \"\\n\")\r\n\t\t.replaceAll(\"&lt;\", \"<\")\r\n\t\t.replaceAll(\"&gt;\", \">\")\r\n\t\t.replaceAll(\"&quot;\", '\"')\r\n\t\t.replaceAll(\"&amp;\", \"&\");\r\n}\r\n\r\nfunction protocolError(message) {\r\n\tconst error = new Error(`invalid spt EVENT stream: ${message}`);\r\n\terror.code = \"SPT_PROTOCOL_ERROR\";\r\n\treturn error;\r\n}\r\n\r\nfunction parseEventTag(tag) {\r\n\tif (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };\r\n\tlet cursor = \"<EVENT\".length;\r\n\tconst attributes = Object.create(null);\r\n\twhile (cursor < tag.length) {\r\n\t\tif (!/\\s/.test(tag[cursor])) {\r\n\t\t\treturn { error: protocolError(\"malformed EVENT attributes\") };\r\n\t\t}\r\n\t\twhile (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;\r\n\t\tif (cursor === tag.length) break;\r\n\t\tconst match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));\r\n\t\tif (!match) return { error: protocolError(\"malformed EVENT attributes\") };\r\n\t\tconst [, name, value] = match;\r\n\t\tif (Object.hasOwn(attributes, name)) {\r\n\t\t\treturn { error: protocolError(`duplicate EVENT ${name} attribute`) };\r\n\t\t}\r\n\t\tattributes[name] = value;\r\n\t\tcursor += match[0].length;\r\n\t}\r\n\tif (!attributes.type) return { error: protocolError(\"missing EVENT type attribute\") };\r\n\tif (attributes.type === \"msg\" && !attributes.from) {\r\n\t\treturn { error: protocolError(\"missing EVENT from attribute\") };\r\n\t}\r\n\treturn { attributes };\r\n}\r\n\r\nexport function drainEvents(raw, options = {}) {\r\n\tconst maxEvents = options.maxEvents ?? Number.POSITIVE_INFINITY;\r\n\tconst maxFrameChars = options.maxFrameChars ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst events = [];\r\n\tlet cursor = 0;\r\n\twhile (true) {\r\n\t\tconst start = raw.indexOf(\"<EVENT\", cursor);\r\n\t\tif (start < 0) return { events, rest: raw.slice(cursor) };\r\n\t\tconst openEnd = raw.indexOf(\">\", start);\r\n\t\tif (openEnd < 0) {\r\n\t\t\tif (raw.length - start > maxFrameChars) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\t\tevents,\r\n\t\t\t\t\trest: raw.slice(start),\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\treturn { events, rest: raw.slice(start) };\r\n\t\t}\r\n\t\tif (openEnd + 1 - start > maxFrameChars) {\r\n\t\t\treturn {\r\n\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\tevents,\r\n\t\t\t\trest: raw.slice(start),\r\n\t\t\t};\r\n\t\t}\r\n\t\tconst close = raw.indexOf(\"</EVENT>\", openEnd + 1);\r\n\t\tconst nested = raw.indexOf(\"<EVENT\", openEnd + 1);\r\n\t\tif (nested >= 0 && (close < 0 || nested < close)) {\r\n\t\t\treturn {\r\n\t\t\t\terror: protocolError(\"nested EVENT before closing the current frame\"),\r\n\t\t\t\tevents,\r\n\t\t\t\trest: raw.slice(start),\r\n\t\t\t};\r\n\t\t}\r\n\t\tif (close < 0) {\r\n\t\t\tif (raw.length - start > maxFrameChars) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\t\tevents,\r\n\t\t\t\t\trest: raw.slice(start),\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\treturn { events, rest: raw.slice(start) };\r\n\t\t}\r\n\t\tconst end = close + \"</EVENT>\".length;\r\n\t\tif (end - start > maxFrameChars) {\r\n\t\t\treturn {\r\n\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\tevents,\r\n\t\t\t\trest: raw.slice(start),\r\n\t\t\t};\r\n\t\t}\r\n\t\tconst parsed = parseEventTag(raw.slice(start, openEnd));\r\n\t\tif (parsed.error) return { error: parsed.error, events, rest: raw.slice(start) };\r\n\t\tif (parsed.attributes.type === \"msg\") {\r\n\t\t\tevents.push({\r\n\t\t\t\tfrom: parsed.attributes.from,\r\n\t\t\t\tbody: decodeBody(raw.slice(openEnd + 1, close)),\r\n\t\t\t\tenvelope: raw.slice(start, end),\r\n\t\t\t});\r\n\t\t}\r\n\t\tcursor = end;\r\n\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\r\n\t}\r\n}\r\n\r\nfunction messageText(message) {\r\n\tif (typeof message?.content === \"string\") return message.content;\r\n\treturn (message?.content ?? [])\r\n\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\r\n\t\t.map((part) => part.text)\r\n\t\t.join(\"\");\r\n}\r\n\r\nexport function extractReply(messages, afterUserMessage) {\r\n\tconst allMessages = messages ?? [];\r\n\tlet start = 0;\r\n\tif (afterUserMessage !== undefined) {\r\n\t\tconst userIndex = allMessages.findLastIndex((message) => {\r\n\t\t\tif (message?.role !== \"user\") return false;\r\n\t\t\tconst text = messageText(message);\r\n\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\r\n\t\t});\r\n\t\tif (userIndex < 0) return \"\";\r\n\t\tstart = userIndex + 1;\r\n\t}\r\n\tconst assistant = allMessages\r\n\t\t.slice(start)\r\n\t\t.reverse()\r\n\t\t.find((message) => message?.role === \"assistant\");\r\n\treturn assistant ? messageText(assistant) : \"\";\r\n}\r\n\r\nfunction firstLine(text) {\r\n\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\r\n}\r\n\r\nfunction errorSummary(error) {\r\n\tconst detail = error instanceof Error ? error.message : String(error);\r\n\treturn firstLine(detail).trim() || \"unknown error\";\r\n}\r\n\r\nfunction failureMessage(reason, error) {\r\n\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\r\n\treturn `[omp-spt] ${reason}${detail}`;\r\n}\r\n\r\nfunction senderStub(sender) {\r\n\tconst escaped = sender\r\n\t\t.replaceAll(\"&\", \"&amp;\")\r\n\t\t.replaceAll('\"', \"&quot;\")\r\n\t\t.replaceAll(\"<\", \"&lt;\")\r\n\t\t.replaceAll(\">\", \"&gt;\");\r\n\treturn `<msg from=\"${escaped}\"/>`;\r\n}\r\n\r\nfunction injectEnvelope(messages, item) {\r\n\tconst index = messages.findLastIndex(\r\n\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\r\n\t);\r\n\tif (index < 0) return messages;\r\n\tconst original = messages[index];\r\n\tconst content =\r\n\t\ttypeof original.content === \"string\"\r\n\t\t\t? `${original.content}\\n\\n${item.envelope}`\r\n\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\r\n\tconst injected = [...messages];\r\n\tinjected[index] = { ...original, content };\r\n\treturn injected;\r\n}\r\n\r\nconst DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\r\nconst DEFAULT_KILL_GRACE_MS = 100;\r\nconst DEFAULT_KILL_FORCE_MS = 100;\r\nconst DEFAULT_LISTENER_BUFFER_LIMIT = 256 * 1024;\r\nconst DEFAULT_ACCEPTED_QUEUE_LIMIT = 128;\r\nconst DEFAULT_ACCEPTED_BYTES_LIMIT = 1024 * 1024;\r\nconst DEFAULT_SHUTDOWN_BUDGET_MS = 1_800;\r\nconst DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS = 300;\r\n\r\nfunction childExited(child) {\r\n\treturn (\r\n\t\t(child.exitCode !== undefined && child.exitCode !== null) ||\r\n\t\t(child.signalCode !== undefined && child.signalCode !== null)\r\n\t);\r\n}\r\n\r\nfunction waitForChildExit(child, timeoutMs, setTimer, clearTimer) {\r\n\tif (childExited(child)) return Promise.resolve(true);\r\n\treturn new Promise((resolve) => {\r\n\t\tlet timer;\r\n\t\tlet finished = false;\r\n\t\tconst finish = (exited) => {\r\n\t\t\tif (finished) return;\r\n\t\t\tfinished = true;\r\n\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\tchild.off(\"close\", onClose);\r\n\t\t\tresolve(exited);\r\n\t\t};\r\n\t\tconst onClose = () => finish(true);\r\n\t\tchild.once(\"close\", onClose);\r\n\t\ttimer = setTimer(() => finish(false), timeoutMs);\r\n\t\ttimer?.unref?.();\r\n\t\tif (childExited(child)) finish(true);\r\n\t});\r\n}\r\n\r\nasync function terminateChild(child, label, options) {\r\n\tconst { clearTimer, forceMs, graceMs, setTimer } = options;\r\n\tif (childExited(child)) return;\r\n\r\n\tconst gracefulExit = waitForChildExit(child, graceMs, setTimer, clearTimer);\r\n\tlet killError;\r\n\ttry {\r\n\t\tchild.kill();\r\n\t} catch (error) {\r\n\t\tkillError = error;\r\n\t}\r\n\tif (await gracefulExit) return;\r\n\r\n\tconst forcedExit = waitForChildExit(child, forceMs, setTimer, clearTimer);\r\n\ttry {\r\n\t\tchild.kill(\"SIGKILL\");\r\n\t} catch (error) {\r\n\t\tkillError ??= error;\r\n\t}\r\n\tif (await forcedExit) return;\r\n\r\n\tchild.stdin?.destroy?.();\r\n\tchild.stdout?.destroy?.();\r\n\tchild.stderr?.destroy?.();\r\n\tchild.unref?.();\r\n\tconst detail = killError === undefined ? \"\" : `: ${errorSummary(killError)}`;\r\n\tthrow new Error(`${label} did not exit after forced termination${detail}`);\r\n}\r\n\r\nfunction commandLabel(args) {\r\n\tconst command = args[0] === \"api\" ? args[3] : args[0];\r\n\treturn `spt ${command ?? \"command\"}`;\r\n}\r\n\r\nexport function runSpt(args, input, overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst timeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst graceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst forceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst label = commandLabel(args);\r\n\tconst signal = overrides.signal;\r\n\tif (signal?.aborted) {\r\n\t\treturn Promise.reject(\r\n\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`),\r\n\t\t);\r\n\t}\r\n\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tlet child;\r\n\t\ttry {\r\n\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\r\n\t\t\t\tstdio: [input === undefined ? \"ignore\" : \"pipe\", \"pipe\", \"pipe\"],\r\n\t\t\t\twindowsHide: true,\r\n\t\t\t});\r\n\t\t} catch (error) {\r\n\t\t\treject(error);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet output = \"\";\r\n\t\tlet settled = false;\r\n\t\tlet terminating = false;\r\n\t\tlet stdinFinished = input === undefined;\r\n\t\tlet timeoutTimer;\r\n\t\tconst onAbort = () => {\r\n\t\t\tconst error =\r\n\t\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`);\r\n\t\t\tvoid terminateAndReject(error);\r\n\t\t};\r\n\t\tconst onStdout = (chunk) => (output += chunk);\r\n\t\tconst onStderr = (chunk) => (output += chunk);\r\n\t\tconst cleanup = () => {\r\n\t\t\tif (timeoutTimer !== undefined) clearTimer(timeoutTimer);\r\n\t\t\tchild.stdout.off(\"data\", onStdout);\r\n\t\t\tchild.stderr.off(\"data\", onStderr);\r\n\t\t\tchild.stdin?.off(\"finish\", onStdinFinish);\r\n\t\t\tchild.off(\"close\", onClose);\r\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\r\n\t\t};\r\n\t\tconst settle = (error) => {\r\n\t\t\tif (settled) return;\r\n\t\t\tsettled = true;\r\n\t\t\tcleanup();\r\n\t\t\tif (error === undefined) resolve(output.trim());\r\n\t\t\telse reject(error);\r\n\t\t};\r\n\t\tconst terminateAndReject = async (error) => {\r\n\t\t\tif (settled || terminating) return;\r\n\t\t\tterminating = true;\r\n\t\t\tif (timeoutTimer !== undefined) {\r\n\t\t\t\tclearTimer(timeoutTimer);\r\n\t\t\t\ttimeoutTimer = undefined;\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait terminateChild(child, label, {\r\n\t\t\t\t\tclearTimer,\r\n\t\t\t\t\tforceMs,\r\n\t\t\t\t\tgraceMs,\r\n\t\t\t\t\tsetTimer,\r\n\t\t\t\t});\r\n\t\t\t} catch (terminationError) {\r\n\t\t\t\terror = new Error(`${errorSummary(error)}; ${errorSummary(terminationError)}`, {\r\n\t\t\t\t\tcause: error,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tsettle(error);\r\n\t\t};\r\n\t\tconst onStdinError = (error) => {\r\n\t\t\tvoid terminateAndReject(error);\r\n\t\t};\r\n\t\tconst onStdinFinish = () => {\r\n\t\t\tstdinFinished = true;\r\n\t\t};\r\n\t\tconst onClose = (code, signal) => {\r\n\t\t\tif (terminating || settled) return;\r\n\t\t\tif (code === 0 && stdinFinished) {\r\n\t\t\t\tsettle();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tconst status = signal ? `signal ${signal}` : `exit ${code}`;\r\n\t\t\tconst detail = firstLine(output);\r\n\t\t\tconst suffix = detail ? `: ${detail}` : \"\";\r\n\t\t\tif (code === 0) {\r\n\t\t\t\tvoid terminateAndReject(new Error(`${label} exited before stdin completed${suffix}`));\r\n\t\t\t} else {\r\n\t\t\t\tvoid terminateAndReject(new Error(`${label} ${status}${suffix}`));\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tchild.stdout.setEncoding(\"utf8\");\r\n\t\tchild.stderr.setEncoding(\"utf8\");\r\n\t\tchild.stdout.on(\"data\", onStdout);\r\n\t\tchild.stderr.on(\"data\", onStderr);\r\n\t\tchild.on(\"error\", onStdinError);\r\n\t\tchild.on(\"close\", onClose);\r\n\t\tif (input !== undefined) {\r\n\t\t\tchild.stdin.on(\"error\", onStdinError);\r\n\t\t\tchild.stdin.once(\"finish\", onStdinFinish);\r\n\t\t}\r\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\r\n\t\tif (signal?.aborted) {\r\n\t\t\tonAbort();\r\n\t\t\treturn;\r\n\t\t}\r\n\t\ttimeoutTimer = setTimer(() => {\r\n\t\t\ttimeoutTimer = undefined;\r\n\t\t\tvoid terminateAndReject(new Error(`${label} timed out after ${timeoutMs}ms`));\r\n\t\t}, timeoutMs);\r\n\t\ttimeoutTimer?.unref?.();\r\n\t\tif (input !== undefined) {\r\n\t\t\ttry {\r\n\t\t\t\tchild.stdin.end(input);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tvoid terminateAndReject(error);\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}\r\n\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r\n\tconst shutdownBudgetMs =\r\n\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\r\n\tconst requestedShutdownCommandTimeoutMs =\r\n\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\r\n\tconst terminationWindowMs = killGraceMs + killForceMs;\r\n\tconst maxShutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\r\n\t);\r\n\tconst shutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\r\n\t);\r\n\tconst listenerBufferLimit =\r\n\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst acceptedQueueLimit =\r\n\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\r\n\tconst acceptedBytesLimit =\r\n\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\r\n\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\r\n\tconst outcomeRetryDelaysMs = [\r\n\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\r\n\t];\r\n\tconst sessionEndRetryDelaysMs = [\r\n\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\r\n\t];\r\n\tconst listenerStableMs =\r\n\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r","truncated":true,"truncatedBy":"lines","totalLines":1158,"totalBytes":13907,"outputLines":433,"outputBytes":13907,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"import { spawn } from \"node:child_process\";\r\n\r\nconst ADAPTER = \"omp-spt\";\r\n\r\nexport function decodeBody(body) {\r\n\treturn body\r\n\t\t.replaceAll(\"<br>\", \"\\n\")\r\n\t\t.replaceAll(\"&lt;\", \"<\")\r\n\t\t.replaceAll(\"&gt;\", \">\")\r\n\t\t.replaceAll(\"&quot;\", '\"')\r\n\t\t.replaceAll(\"&amp;\", \"&\");\r\n}\r\n\r\nfunction protocolError(message) {\r\n\tconst error = new Error(`invalid spt EVENT stream: ${message}`);\r\n\terror.code = \"SPT_PROTOCOL_ERROR\";\r\n\treturn error;\r\n}\r\n\r\nfunction parseEventTag(tag) {\r\n\tif (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };\r\n\tlet cursor = \"<EVENT\".length;\r\n\tconst attributes = Object.create(null);\r\n\twhile (cursor < tag.length) {\r\n\t\tif (!/\\s/.test(tag[cursor])) {\r\n\t\t\treturn { error: protocolError(\"malformed EVENT attributes\") };\r\n\t\t}\r\n\t\twhile (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;\r\n\t\tif (cursor === tag.length) break;\r\n\t\tconst match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));\r\n\t\tif (!match) return { error: protocolError(\"malformed EVENT attributes\") };\r\n\t\tconst [, name, value] = match;\r\n\t\tif (Object.hasOwn(attributes, name)) {\r\n\t\t\treturn { error: protocolError(`duplicate EVENT ${name} attribute`) };\r\n\t\t}\r\n\t\tattributes[name] = value;\r\n\t\tcursor += match[0].length;\r\n\t}\r\n\tif (!attributes.type) return { error: protocolError(\"missing EVENT type attribute\") };\r\n\tif (attributes.type === \"msg\" && !attributes.from) {\r\n\t\treturn { error: protocolError(\"missing EVENT from attribute\") };\r\n\t}\r\n\treturn { attributes };\r\n}\r\n\r\nexport function drainEvents(raw, options = {}) {\r\n\tconst maxEvents = options.maxEvents ?? Number.POSITIVE_INFINITY;\r\n\tconst maxFrameChars = options.maxFrameChars ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst events = [];\r\n\tlet cursor = 0;\r\n\twhile (true) {\r\n\t\tconst start = raw.indexOf(\"<EVENT\", cursor);\r\n\t\tif (start < 0) return { events, rest: raw.slice(cursor) };\r\n\t\tconst openEnd = raw.indexOf(\">\", start);\r\n\t\tif (openEnd < 0) {\r\n\t\t\tif (raw.length - start > maxFrameChars) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\t\tevents,\r\n\t\t\t\t\trest: raw.slice(start),\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\treturn { events, rest: raw.slice(start) };\r\n\t\t}\r\n\t\tif (openEnd + 1 - start > maxFrameChars) {\r\n\t\t\treturn {\r\n\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\tevents,\r\n\t\t\t\trest: raw.slice(start),\r\n\t\t\t};\r\n\t\t}\r\n\t\tconst close = raw.indexOf(\"</EVENT>\", openEnd + 1);\r\n\t\tconst nested = raw.indexOf(\"<EVENT\", openEnd + 1);\r\n\t\tif (nested >= 0 && (close < 0 || nested < close)) {\r\n\t\t\treturn {\r\n\t\t\t\terror: protocolError(\"nested EVENT before closing the current frame\"),\r\n\t\t\t\tevents,\r\n\t\t\t\trest: raw.slice(start),\r\n\t\t\t};\r\n\t\t}\r\n\t\tif (close < 0) {\r\n\t\t\tif (raw.length - start > maxFrameChars) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\t\tevents,\r\n\t\t\t\t\trest: raw.slice(start),\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\treturn { events, rest: raw.slice(start) };\r\n\t\t}\r\n\t\tconst end = close + \"</EVENT>\".length;\r\n\t\tif (end - start > maxFrameChars) {\r\n\t\t\treturn {\r\n\t\t\t\terror: protocolError(`EVENT frame exceeded ${maxFrameChars} characters`),\r\n\t\t\t\tevents,\r\n\t\t\t\trest: raw.slice(start),\r\n\t\t\t};\r\n\t\t}\r\n\t\tconst parsed = parseEventTag(raw.slice(start, openEnd));\r\n\t\tif (parsed.error) return { error: parsed.error, events, rest: raw.slice(start) };\r\n\t\tif (parsed.attributes.type === \"msg\") {\r\n\t\t\tevents.push({\r\n\t\t\t\tfrom: parsed.attributes.from,\r\n\t\t\t\tbody: decodeBody(raw.slice(openEnd + 1, close)),\r\n\t\t\t\tenvelope: raw.slice(start, end),\r\n\t\t\t});\r\n\t\t}\r\n\t\tcursor = end;\r\n\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\r\n\t}\r\n}\r\n\r\nfunction messageText(message) {\r\n\tif (typeof message?.content === \"string\") return message.content;\r\n\treturn (message?.content ?? [])\r\n\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\r\n\t\t.map((part) => part.text)\r\n\t\t.join(\"\");\r\n}\r\n\r\nexport function extractReply(messages, afterUserMessage) {\r\n\tconst allMessages = messages ?? [];\r\n\tlet start = 0;\r\n\tif (afterUserMessage !== undefined) {\r\n\t\tconst userIndex = allMessages.findLastIndex((message) => {\r\n\t\t\tif (message?.role !== \"user\") return false;\r\n\t\t\tconst text = messageText(message);\r\n\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\r\n\t\t});\r\n\t\tif (userIndex < 0) return \"\";\r\n\t\tstart = userIndex + 1;\r\n\t}\r\n\tconst assistant = allMessages\r\n\t\t.slice(start)\r\n\t\t.reverse()\r\n\t\t.find((message) => message?.role === \"assistant\");\r\n\treturn assistant ? messageText(assistant) : \"\";\r\n}\r\n\r\nfunction firstLine(text) {\r\n\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\r\n}\r\n\r\nfunction errorSummary(error) {\r\n\tconst detail = error instanceof Error ? error.message : String(error);\r\n\treturn firstLine(detail).trim() || \"unknown error\";\r\n}\r\n\r\nfunction failureMessage(reason, error) {\r\n\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\r\n\treturn `[omp-spt] ${reason}${detail}`;\r\n}\r\n\r\nfunction senderStub(sender) {\r\n\tconst escaped = sender\r\n\t\t.replaceAll(\"&\", \"&amp;\")\r\n\t\t.replaceAll('\"', \"&quot;\")\r\n\t\t.replaceAll(\"<\", \"&lt;\")\r\n\t\t.replaceAll(\">\", \"&gt;\");\r\n\treturn `<msg from=\"${escaped}\"/>`;\r\n}\r\n\r\nfunction injectEnvelope(messages, item) {\r\n\tconst index = messages.findLastIndex(\r\n\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\r\n\t);\r\n\tif (index < 0) return messages;\r\n\tconst original = messages[index];\r\n\tconst content =\r\n\t\ttypeof original.content === \"string\"\r\n\t\t\t? `${original.content}\\n\\n${item.envelope}`\r\n\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\r\n\tconst injected = [...messages];\r\n\tinjected[index] = { ...original, content };\r\n\treturn injected;\r\n}\r\n\r\nconst DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\r\nconst DEFAULT_KILL_GRACE_MS = 100;\r\nconst DEFAULT_KILL_FORCE_MS = 100;\r\nconst DEFAULT_LISTENER_BUFFER_LIMIT = 256 * 1024;\r\nconst DEFAULT_ACCEPTED_QUEUE_LIMIT = 128;\r\nconst DEFAULT_ACCEPTED_BYTES_LIMIT = 1024 * 1024;\r\nconst DEFAULT_SHUTDOWN_BUDGET_MS = 1_800;\r\nconst DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS = 300;\r\n\r\nfunction childExited(child) {\r\n\treturn (\r\n\t\t(child.exitCode !== undefined && child.exitCode !== null) ||\r\n\t\t(child.signalCode !== undefined && child.signalCode !== null)\r\n\t);\r\n}\r\n\r\nfunction waitForChildExit(child, timeoutMs, setTimer, clearTimer) {\r\n\tif (childExited(child)) return Promise.resolve(true);\r\n\treturn new Promise((resolve) => {\r\n\t\tlet timer;\r\n\t\tlet finished = false;\r\n\t\tconst finish = (exited) => {\r\n\t\t\tif (finished) return;\r\n\t\t\tfinished = true;\r\n\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\tchild.off(\"close\", onClose);\r\n\t\t\tresolve(exited);\r\n\t\t};\r\n\t\tconst onClose = () => finish(true);\r\n\t\tchild.once(\"close\", onClose);\r\n\t\ttimer = setTimer(() => finish(false), timeoutMs);\r\n\t\ttimer?.unref?.();\r\n\t\tif (childExited(child)) finish(true);\r\n\t});\r\n}\r\n\r\nasync function terminateChild(child, label, options) {\r\n\tconst { clearTimer, forceMs, graceMs, setTimer } = options;\r\n\tif (childExited(child)) return;\r\n\r\n\tconst gracefulExit = waitForChildExit(child, graceMs, setTimer, clearTimer);\r\n\tlet killError;\r\n\ttry {\r\n\t\tchild.kill();\r\n\t} catch (error) {\r\n\t\tkillError = error;\r\n\t}\r\n\tif (await gracefulExit) return;\r\n\r\n\tconst forcedExit = waitForChildExit(child, forceMs, setTimer, clearTimer);\r\n\ttry {\r\n\t\tchild.kill(\"SIGKILL\");\r\n\t} catch (error) {\r\n\t\tkillError ??= error;\r\n\t}\r\n\tif (await forcedExit) return;\r\n\r\n\tchild.stdin?.destroy?.();\r\n\tchild.stdout?.destroy?.();\r\n\tchild.stderr?.destroy?.();\r\n\tchild.unref?.();\r\n\tconst detail = killError === undefined ? \"\" : `: ${errorSummary(killError)}`;\r\n\tthrow new Error(`${label} did not exit after forced termination${detail}`);\r\n}\r\n\r\nfunction commandLabel(args) {\r\n\tconst command = args[0] === \"api\" ? args[3] : args[0];\r\n\treturn `spt ${command ?? \"command\"}`;\r\n}\r\n\r\nexport function runSpt(args, input, overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst timeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst graceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst forceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst label = commandLabel(args);\r\n\tconst signal = overrides.signal;\r\n\tif (signal?.aborted) {\r\n\t\treturn Promise.reject(\r\n\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`),\r\n\t\t);\r\n\t}\r\n\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tlet child;\r\n\t\ttry {\r\n\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\r\n\t\t\t\tstdio: [input === undefined ? \"ignore\" : \"pipe\", \"pipe\", \"pipe\"],\r\n\t\t\t\twindowsHide: true,\r\n\t\t\t});\r\n\t\t} catch (error) {\r\n\t\t\treject(error);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet output = \"\";\r\n\t\tlet settled = false;\r\n\t\tlet terminating = false;\r\n\t\tlet stdinFinished = input === undefined;\r\n\t\tlet timeoutTimer;\r\n\t\tconst onAbort = () => {\r\n\t\t\tconst error =\r\n\t\t\t\tsignal.reason instanceof Error ? signal.reason : new Error(`${label} aborted`);\r\n\t\t\tvoid terminateAndReject(error);\r\n\t\t};\r\n\t\tconst onStdout = (chunk) => (output += chunk);\r\n\t\tconst onStderr = (chunk) => (output += chunk);\r\n\t\tconst cleanup = () => {\r\n\t\t\tif (timeoutTimer !== undefined) clearTimer(timeoutTimer);\r\n\t\t\tchild.stdout.off(\"data\", onStdout);\r\n\t\t\tchild.stderr.off(\"data\", onStderr);\r\n\t\t\tchild.stdin?.off(\"finish\", onStdinFinish);\r\n\t\t\tchild.off(\"close\", onClose);\r\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\r\n\t\t};\r\n\t\tconst settle = (error) => {\r\n\t\t\tif (settled) return;\r\n\t\t\tsettled = true;\r\n\t\t\tcleanup();\r\n\t\t\tif (error === undefined) resolve(output.trim());\r\n\t\t\telse reject(error);\r\n\t\t};\r\n\t\tconst terminateAndReject = async (error) => {\r\n\t\t\tif (settled || terminating) return;\r\n\t\t\tterminating = true;\r\n\t\t\tif (timeoutTimer !== undefined) {\r\n\t\t\t\tclearTimer(timeoutTimer);\r\n\t\t\t\ttimeoutTimer = undefined;\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait terminateChild(child, label, {\r\n\t\t\t\t\tclearTimer,\r\n\t\t\t\t\tforceMs,\r\n\t\t\t\t\tgraceMs,\r\n\t\t\t\t\tsetTimer,\r\n\t\t\t\t});\r\n\t\t\t} catch (terminationError) {\r\n\t\t\t\terror = new Error(`${errorSummary(error)}; ${errorSummary(terminationError)}`, {\r\n\t\t\t\t\tcause: error,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tsettle(error);\r\n\t\t};\r\n\t\tconst onStdinError = (error) => {\r\n\t\t\tvoid terminateAndReject(error);\r\n\t\t};\r\n\t\tconst onStdinFinish = () => {\r\n\t\t\tstdinFinished = true;\r\n\t\t};\r\n\t\tconst onClose = (code, signal) => {\r\n\t\t\tif (terminating || settled) return;\r\n\t\t\tif (code === 0 && stdinFinished) {\r\n\t\t\t\tsettle();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tconst status = signal ? `signal ${signal}` : `exit ${code}`;\r\n\t\t\tconst detail = firstLine(output);\r\n\t\t\tconst suffix = detail ? `: ${detail}` : \"\";\r\n\t\t\tif (code === 0) {\r\n\t\t\t\tvoid terminateAndReject(new Error(`${label} exited before stdin completed${suffix}`));\r\n\t\t\t} else {\r\n\t\t\t\tvoid terminateAndReject(new Error(`${label} ${status}${suffix}`));\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tchild.stdout.setEncoding(\"utf8\");\r\n\t\tchild.stderr.setEncoding(\"utf8\");\r\n\t\tchild.stdout.on(\"data\", onStdout);\r\n\t\tchild.stderr.on(\"data\", onStderr);\r\n\t\tchild.on(\"error\", onStdinError);\r\n\t\tchild.on(\"close\", onClose);\r\n\t\tif (input !== undefined) {\r\n\t\t\tchild.stdin.on(\"error\", onStdinError);\r\n\t\t\tchild.stdin.once(\"finish\", onStdinFinish);\r\n\t\t}\r\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\r\n\t\tif (signal?.aborted) {\r\n\t\t\tonAbort();\r\n\t\t\treturn;\r\n\t\t}\r\n\t\ttimeoutTimer = setTimer(() => {\r\n\t\t\ttimeoutTimer = undefined;\r\n\t\t\tvoid terminateAndReject(new Error(`${label} timed out after ${timeoutMs}ms`));\r\n\t\t}, timeoutMs);\r\n\t\ttimeoutTimer?.unref?.();\r\n\t\tif (input !== undefined) {\r\n\t\t\ttry {\r\n\t\t\t\tchild.stdin.end(input);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tvoid terminateAndReject(error);\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}\r\n\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r\n\tconst shutdownBudgetMs =\r\n\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\r\n\tconst requestedShutdownCommandTimeoutMs =\r\n\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\r\n\tconst terminationWindowMs = killGraceMs + killForceMs;\r\n\tconst maxShutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\r\n\t);\r\n\tconst shutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\r\n\t);\r\n\tconst listenerBufferLimit =\r\n\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst acceptedQueueLimit =\r\n\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\r\n\tconst acceptedBytesLimit =\r\n\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\r\n\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\r\n\tconst outcomeRetryDelaysMs = [\r\n\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\r\n\t];\r\n\tconst sessionEndRetryDelaysMs = [\r\n\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\r\n\t];\r\n\tconst listenerStableMs =\r\n\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n…\n\t};\n}","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,null,1154,1155]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1158,"totalBytes":13907,"outputLines":433,"outputBytes":13907,"shownRange":{"start":1,"end":433},"nextOffset":434}}},"isError":false,"timestamp":1784188876275}}
{"type":"message","id":"2d538685","parentId":"8e214892","timestamp":"2026-07-16T08:01:16.276Z","message":{"role":"toolResult","toolCallId":"call_gxvCRqyoNnGVQWZ30H9mAEpT|fc_03e5b91f227b0634016a588fcc2f70819b8c87e13440d33ffa","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#CA60]\n376:export function createOmpSpt(overrides = {}) {\n…\n418:\tconst outcomeRetryDelaysMs = [\n419:\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\n420:\t];\n421:\tconst sessionEndRetryDelaysMs = [\n422:\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\n423:\t];\n424:\tconst listenerStableMs =\n425:\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\n426:\n427:\treturn function ompSpt(pi) {\n428:\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n429:\t\tif (!id) return;\n430:\n431:\t\tlet sid;\n432:\t\tlet token;\n433:\t\tlet listener;\n434:\t\tlet listenerBuffer = \"\";\n435:\t\tlet listenerRestartCount = 0;\n436:\t\tlet listenerStableTimer;\n437:\t\tlet restartTimer;\n438:\t\tlet dispatchTimer;\n439:\t\tlet bindPromise;\n440:\t\tlet agentActive = false;\n441:\t\tlet desiredState = \"idle\";\n442:\t\tlet dispatching = false;\n443:\t\tlet turnCompletionPromise;\n444:\t\tlet listenerTerminationPromise;\n445:\t\tlet shutdownMode = false;\n446:\t\tlet shutdownDeadlineExpired = false;\n447:\t\tconst activeCommands = new Map();\n448:\t\tconst retryWaiters = new Set();\n449:\t\tlet current;\n450:\t\tlet stopping = false;\n451:\t\tlet ui;\n452:\t\tlet runtimeCtx;\n453:\t\tlet endpointState;\n454:\t\tlet stateOperation = Promise.resolve();\n455:\t\tlet endPromise;\n456:\t\tlet fatalPromise;\n457:\t\tlet teardownPromise;\n458:\t\tlet acceptedBytes = 0;\n459:\t\tlet overflowItem;\n460:\t\tconst queue = [];\n461:\n462:\t\tconst logError = (message, error) => {\n463:\t\t\tpi.logger.error(message, { error: errorSummary(error) });\n464:\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\n465:\t\t};\n466:\n467:\t\tfunction runCommand(args, input, options = {}) {\n468:\t\t\tif (shutdownDeadlineExpired) {\n469:\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\n470:\t\t\t}\n471:\t\t\tconst timeoutMs =\n472:\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\n473:\t\t\tconst controller = new AbortController();\n474:\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\n475:\t\t\tlet command;\n476:\t\t\ttry {\n477:\t\t\t\tcommand = Promise.resolve(\n478:\t\t\t\t\trunSptCommand(args, input, {\n479:\t\t\t\t\t\tsignal: controller.signal,\n480:\t\t\t\t\t\ttimeoutMs,\n481:\t\t\t\t\t}),\n482:\t\t\t\t);\n483:\t\t\t} catch (error) {\n484:\t\t\t\tactiveCommands.delete(controller);\n485:\t\t\t\treturn Promise.reject(error);\n486:\t\t\t}\n487:\t\t\tif (customRunSptCommand) {\n488:\t\t\t\tconst rawCommand = command;\n489:\t\t\t\tcommand = new Promise((resolve, reject) => {\n490:\t\t\t\t\tlet timer;\n491:\t\t\t\t\tlet finished = false;\n492:\t\t\t\t\tconst finish = (error, value) => {\n493:\t\t\t\t\t\tif (finished) return;\n494:\t\t\t\t\t\tfinished = true;\n495:\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n496:\t\t\t\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\n497:\t\t\t\t\t\tif (error === undefined) resolve(value);\n498:\t\t\t\t\t\telse reject(error);\n499:\t\t\t\t\t};\n500:\t\t\t\t\tconst onAbort = () =>\n501:\t\t\t\t\t\tfinish(\n502:\t\t\t\t\t\t\tcontroller.signal.reason instanceof Error\n503:\t\t\t\t\t\t\t\t? controller.signal.reason\n504:\t\t\t\t\t\t\t\t: new Error(`${commandLabel(args)} aborted`),\n505:\t\t\t\t\t\t);\n506:\t\t\t\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\n507:\t\t\t\t\tif (shutdownMode) {\n508:\t\t\t\t\t\ttimer = setTimer(\n509:\t\t\t\t\t\t\t() =>\n510:\t\t\t\t\t\t\t\tcontroller.abort(\n511:\t\t\t\t\t\t\t\t\tnew Error(`${commandLabel(args)} timed out after ${timeoutMs}ms`),\n512:\t\t\t\t\t\t\t\t),\n513:\t\t\t\t\t\t\ttimeoutMs,\n514:\t\t\t\t\t\t);\n515:\t\t\t\t\t\ttimer?.unref?.();\n516:\t\t\t\t\t}\n517:\t\t\t\t\trawCommand.then(\n518:\t\t\t\t\t\t(value) => finish(undefined, value),\n519:\t\t\t\t\t\t(error) => finish(error),\n520:\t\t\t\t\t);\n521:\t\t\t\t});\n522:\t\t\t}\n523:\t\t\treturn command.finally(() => {\n524:\t\t\t\tconst active = activeCommands.get(controller);\n525:\t\t\t\tif (active?.abortTimer !== undefined) clearTimer(active.abortTimer);\n526:\t\t\t\tactiveCommands.delete(controller);\n527:\t\t\t});\n528:\t\t}\n529:\n530:\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n531:\t\t\tfor (const [controller, active] of activeCommands) {\n532:\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\n533:\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\n534:\t\t\t\t\tactive.abortTimer = setTimer(\n535:\t\t\t\t\t\t() => controller.abort(reason),\n536:\t\t\t\t\t\tshutdownCommandTimeoutMs,\n537:\t\t\t\t\t);\n538:\t\t\t\t\tactive.abortTimer?.unref?.();\n539:\t\t\t\t\tcontinue;\n540:\t\t\t\t}\n541:\t\t\t\tcontroller.abort(reason);\n542:\t\t\t}\n543:\t\t}\n544:\n545:\t\tfunction waitForRetry(delay) {\n546:\t\t\tif (shutdownMode) return Promise.resolve();\n547:\t\t\treturn new Promise((resolve) => {\n548:\t\t\t\tlet timer;\n549:\t\t\t\tconst finish = () => {\n550:\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n551:\t\t\t\t\tretryWaiters.delete(finish);\n552:\t\t\t\t\tresolve();\n553:\t\t\t\t};\n554:\t\t\t\tretryWaiters.add(finish);\n555:\t\t\t\ttimer = setTimer(finish, delay);\n556:\t\t\t\ttimer?.unref?.();\n557:\t\t\t});\n558:\t\t}\n559:\n560:\t\tfunction enterShutdownMode() {\n561:\t\t\tif (shutdownMode) return;\n562:\t\t\tshutdownMode = true;\n563:\t\t\tconst reason = new Error(\"omp-spt command interrupted for bounded shutdown\");\n564:\t\t\tabortActiveCommands(reason, true);\n565:\t\t\tfor (const finish of [...retryWaiters]) finish();\n566:\t\t}\n567:\n568:\t\tfunction authArgs() {\n569:\t\t\tif (!token) throw new Error(\"bind did not return an authentication token\");\n570:\t\t\treturn [\"--token\", token];\n571:\t\t}\n572:\n573:\t\tfunction setState(state) {\n574:\t\t\tif (!sid || !token || stopping) return Promise.resolve();\n575:\t\t\tconst operation = stateOperation.catch(() => {}).then(async () => {\n576:\t\t\t\tif (endpointState === state || stopping) return;\n577:\t\t\t\tawait runCommand([\"api\", \"--adapter\", ADAPTER, \"state\", state, id, ...authArgs()]);\n578:\t\t\t\tendpointState = state;\n579:\t\t\t});\n580:\t\t\tstateOperation = operation;\n581:\t\t\treturn operation;\n582:\t\t}\n583:\n584:\t\tasync function syncDesiredState() {\n585:\t\t\tif (!bindPromise) return;\n586:\t\t\tawait bindPromise;\n587:\t\t\twhile (!stopping && endpointState !== desiredState) {\n588:\t\t\t\tawait setState(desiredState);\n589:\t\t\t}\n590:\t\t}\n591:\n592:\t\tfunction endSession() {\n593:\t\t\tif (!sid || !token) return Promise.resolve();\n594:\t\t\tif (!endPromise) {\n595:\t\t\t\tconst operation = (async () => {\n596:\t\t\t\t\tawait stateOperation.catch(() => {});\n597:\t\t\t\t\tawait runCommand([\"api\", \"--adapter\", ADAPTER, \"session-end\", id, ...authArgs()]);\n598:\t\t\t\t\tendpointState = undefined;\n599:\t\t\t\t})();\n600:\t\t\t\tendPromise = operation;\n601:\t\t\t\tvoid operation.catch(() => {\n602:\t\t\t\t\tif (endPromise === operation) endPromise = undefined;\n603:\t\t\t\t});\n604:\t\t\t}\n605:\t\t\treturn endPromise;\n606:\t\t}\n607:\n608:\t\tasync function endSessionWithRetry() {\n609:\t\t\tfor (let attempt = 0; ; attempt += 1) {\n610:\t\t\t\ttry {\n611:\t\t\t\t\tawait endSession();\n612:\t\t\t\t\treturn;\n613:\t\t\t\t} catch (error) {\n614:\t\t\t\t\tif (shutdownMode || attempt >= sessionEndRetryDelaysMs.length) throw error;\n615:\t\t\t\t\tconst delay = sessionEndRetryDelaysMs[attempt];\n616:\t\t\t\t\tpi.logger.error(\n617:\t\t\t\t\t\t`omp-spt session teardown failed; retrying ${\n618:\t\t\t\t\t\t\tattempt + 1\n619:\t\t\t\t\t\t}/${sessionEndRetryDelaysMs.length} in ${delay}ms`,\n620:\t\t\t\t\t\t{ error: errorSummary(error) },\n621:\t\t\t\t\t);\n622:\t\t\t\t\tawait waitForRetry(delay);\n623:\t\t\t\t}\n624:\t\t\t}\n625:\t\t}\n626:\n627:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n628:\t\tfunction settleItem(item, payload) {\n629:\t\t\tif (!item) return Promise.resolve();\n630:\t\t\tif (item.outcomePromise) return item.outcomePromise;\n631:\t\t\titem.settling = true;\n632:\t\t\titem.outcomePromise = (async () => {\n633:\t\t\t\tif (!item.from) throw new Error(\"missing EVENT from attribute\");\n634:\t\t\t\tfor (let attempt = 0; ; attempt += 1) {\n635:\t\t\t\t\ttry {\n636:\t\t\t\t\t\tawait runCommand([\"send\", item.from, \"--from\", id], payload);\n637:\t\t\t\t\t\titem.settled = true;\n638:\t\t\t\t\t\treturn;\n639:\t\t\t\t\t} catch (error) {\n640:\t\t\t\t\t\tif (shutdownMode || attempt >= outcomeRetryDelaysMs.length) throw error;\n641:\t\t\t\t\t\tconst delay = outcomeRetryDelaysMs[attempt];\n642:\t\t\t\t\t\tpi.logger.error(\n643:\t\t\t\t\t\t\t`omp-spt could not send the outcome to ${item.from}; retrying ${\n644:\t\t\t\t\t\t\t\tattempt + 1\n645:\t\t\t\t\t\t\t}/${outcomeRetryDelaysMs.length} in ${delay}ms`,\n646:\t\t\t\t\t\t\t{ error: errorSummary(error) },\n647:\t\t\t\t\t\t);\n648:\t\t\t\t\t\tawait waitForRetry(delay);\n649:\t\t\t\t\t}\n650:\t\t\t\t}\n651:\t\t\t})();\n652:\t\t\treturn item.outcomePromise;\n653:\t\t}\n654:\n655:\t\tfunction releaseItem(item) {\n656:\t\t\tif (!item?.accounted) return;\n657:\t\t\titem.accounted = false;\n658:\t\t\tacceptedBytes -= item.acceptedBytes;\n659:\t\t}\n660:\n661:\t\tfunction beginListenerTermination(child, label) {\n662:\t\t\tif (listenerTerminationPromise) return listenerTerminationPromise;\n663:\t\t\tconst operation = (async () => {\n664:\t\t\t\ttry {\n665:\t\t\t\t\tawait terminateChild(child, label, {\n666:\t\t\t\t\t\tclearTimer,\n667:\t\t\t\t\t\tforceMs: killForceMs,\n668:\t\t\t\t\t\tgraceMs: killGraceMs,\n669:\t\t\t\t\t\tsetTimer,\n670:\t\t\t\t\t});\n671:\t\t\t\t} catch (error) {\n672:\t\t\t\t\tpi.logger.error(\"omp-spt could not reap the listener\", {\n673:\t\t\t\t\t\terror: errorSummary(error),\n674:\t\t\t\t\t});\n675:\t\t\t\t}\n676:\t\t\t})();\n677:\t\t\tlistenerTerminationPromise = operation;\n678:\t\t\tvoid operation.then(() => {\n679:\t\t\t\tif (listenerTerminationPromise === operation) listenerTerminationPromise = undefined;\n680:\t\t\t});\n681:\t\t\treturn operation;\n682:\t\t}\n683:\n684:\t\tasync function stopResources() {\n685:\t\t\tif (dispatchTimer !== undefined) {\n686:\t\t\t\tclearTimer(dispatchTimer);\n687:\t\t\t\tdispatchTimer = undefined;\n688:\t\t\t}\n689:\t\t\tif (restartTimer !== undefined) {\n690:\t\t\t\tclearTimer(restartTimer);\n691:\t\t\t\trestartTimer = undefined;\n692:\t\t\t}\n693:\t\t\tif (listenerStableTimer !== undefined) {\n694:\t\t\t\tclearTimer(listenerStableTimer);\n695:\t\t\t\tlistenerStableTimer = undefined;\n696:\t\t\t}\n697:\t\t\tconst child = listener;\n698:\t\t\tlistener = undefined;\n699:\t\t\tlistenerBuffer = \"\";\n700:\t\t\tif (child) {\n701:\t\t\t\tawait beginListenerTermination(child, \"spt api listener\");\n702:\t\t\t} else {\n703:\t\t\t\tawait listenerTerminationPromise;\n704:\t\t\t}\n705:\t\t}\n706:\n707:\t\tasync function settlePendingItem(item, reason) {\n708:\t\t\ttry {\n709:\t\t\t\tif (item.outcomePromise && !item.settled) {\n710:\t\t\t\t\tlet existingError;\n711:\t\t\t\t\ttry {\n712:\t\t\t\t\t\tawait item.outcomePromise;\n713:\t\t\t\t\t} catch (error) {\n714:\t\t\t\t\t\texistingError = error;\n715:\t\t\t\t\t}\n716:\t\t\t\t\tif (item.settled) return;\n717:\t\t\t\t\tif (existingError && !shutdownMode) {\n718:\t\t\t\t\t\tlogError(\n719:\t\t\t\t\t\t\t`omp-spt could not return custody to ${item.from ?? \"unknown\"}`,\n720:\t\t\t\t\t\t\texistingError,\n721:\t\t\t\t\t\t);\n722:\t\t\t\t\t\treturn;\n723:\t\t\t\t\t}\n724:\t\t\t\t\titem.outcomePromise = undefined;\n725:\t\t\t\t\titem.settling = false;\n726:\t\t\t\t}\n727:\t\t\t\ttry {\n728:\t\t\t\t\tawait settleItem(item, failureMessage(reason));\n729:\t\t\t\t} catch (error) {\n730:\t\t\t\t\tlogError(`omp-spt could not return custody to ${item.from ?? \"unknown\"}`, error);\n731:\t\t\t\t}\n732:\t\t\t} finally {\n733:\t\t\t\treleaseItem(item);\n734:\t\t\t}\n735:\t\t}\n736:\n737:\t\tasync function failPending(reason) {\n738:\t\t\tconst pending = current ? [current, ...queue] : [...queue];\n739:\t\t\tif (overflowItem) pending.push(overflowItem);\n740:\t\t\tcurrent = undefined;\n741:\t\t\tqueue.length = 0;\n742:\t\t\toverflowItem = undefined;\n743:\t\t\tfor (let index = 0; index < pending.length; index += 1) {\n744:\t\t\t\tif (shutdownMode) {\n745:\t\t\t\t\tawait Promise.all(\n746:\t\t\t\t\t\tpending.slice(index).map((item) => settlePendingItem(item, reason)),\n747:\t\t\t\t\t);\n748:\t\t\t\t\treturn;\n749:\t\t\t\t}\n750:\t\t\t\tawait settlePendingItem(pending[index], reason);\n751:\t\t\t}\n752:\t\t}\n753:\n754:\t\tfunction teardownSession(pendingReason) {\n755:\t\t\tif (!teardownPromise) {\n756:\t\t\t\tstopping = true;\n757:\t\t\t\tconst operation = (async () => {\n758:\t\t\t\t\tawait stopResources();\n759:\t\t\t\t\tawait failPending(pendingReason);\n760:\t\t\t\t\tawait bindPromise?.catch(() => {});\n761:\t\t\t\t\tawait endSessionWithRetry();\n762:\t\t\t\t})();\n763:\t\t\t\tteardownPromise = operation;\n764:\t\t\t\tvoid operation.catch(() => {\n765:\t\t\t\t\tif (teardownPromise === operation) teardownPromise = undefined;\n766:\t\t\t\t});\n767:\t\t\t}\n768:\t\t\treturn teardownPromise;\n769:\t\t}\n770:\n771:\t\tasync function shutdownWithinBudget(pendingReason) {\n772:\t\t\tenterShutdownMode();\n773:\t\t\tconst teardown = teardownSession(pendingReason);\n774:\t\t\tlet budgetTimer;\n775:\t\t\tconst expired = new Promise((resolve) => {\n776:\t\t\t\tbudgetTimer = setTimer(() => {\n777:\t\t\t\t\tbudgetTimer = undefined;\n778:\t\t\t\t\tshutdownDeadlineExpired = true;\n779:\t\t\t\t\tconst error = new Error(\n780:\t\t\t\t\t\t`omp-spt shutdown exceeded its ${shutdownBudgetMs}ms budget`,\n781:\t\t\t\t\t);\n782:\t\t\t\t\tabortActiveCommands(error);\n783:\t\t\t\t\tfor (const finish of [...retryWaiters]) finish();\n784:\t\t\t\t\tresolve(false);\n785:\t\t\t\t}, shutdownBudgetMs);\n786:\t\t\t\tbudgetTimer?.unref?.();\n787:\t\t\t});\n788:\t\t\tconst completed = teardown.then(\n789:\t\t\t\t() => true,\n790:\t\t\t\t(error) => {\n791:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n792:\t\t\t\t\treturn true;\n793:\t\t\t\t},\n794:\t\t\t);\n795:\t\t\tconst finished = await Promise.race([completed, expired]);\n796:\t\t\tif (budgetTimer !== undefined) clearTimer(budgetTimer);\n797:\t\t\tif (!finished) {\n798:\t\t\t\tpi.logger.error(\"omp-spt bounded shutdown expired\", {\n799:\t\t\t\t\terror: `${shutdownBudgetMs}ms budget exhausted`,\n800:\t\t\t\t});\n801:\t\t\t}\n802:\t\t}\n803:\n804:\t\t// [impl->REQ-OMP-LISTENER-FAIL-CLOSED]\n805:\t\tasync function failClosed(message, error) {\n806:\t\t\tif (stopping && shutdownMode) return teardownPromise ?? Promise.resolve();\n807:\t\t\tif (fatalPromise) return fatalPromise;\n808:\t\t\tfatalPromise = (async () => {\n809:\t\t\t\tui?.setStatus(\"omp-spt\", \"spt failed\");\n810:\t\t\t\tlogError(message, error);\n811:\t\t\t\ttry {\n812:\t\t\t\t\tawait teardownSession(\"endpoint stopped before your message could complete\");\n813:\t\t\t\t} catch (teardownError) {\n814:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", teardownError);\n815:\t\t\t\t}\n816:\t\t\t\truntimeCtx?.shutdown();\n817:\t\t\t})();\n818:\t\t\treturn fatalPromise;\n819:\t\t}\n820:\n821:\t\tfunction scheduleDispatch() {\n822:\t\t\tif (\n823:\t\t\t\tstopping ||\n824:\t\t\t\tagentActive ||\n825:\t\t\t\tdispatching ||\n826:\t\t\t\tcurrent ||\n827:\t\t\t\tqueue.length === 0 ||\n828:\t\t\t\tdispatchTimer !== undefined\n829:\t\t\t) {\n830:\t\t\t\treturn;\n831:\t\t\t}\n832:\t\t\tdispatchTimer = setTimer(() => {\n833:\t\t\t\tdispatchTimer = undefined;\n834:\t\t\t\tvoid dispatchNext().catch((error) => {\n835:\t\t\t\t\tif (!stopping) return failClosed(\"omp-spt dispatch failed\", error);\n836:\t\t\t\t});\n837:\t\t\t}, 0);\n838:\t\t\tdispatchTimer?.unref?.();\n839:\t\t}\n840:\n841:\t\tasync function rejectItem(item, reason, error) {\n842:\t\t\tif (stopping) return;\n843:\t\t\tlogError(`omp-spt ${reason}`, error);\n844:\t\t\ttry {\n845:\t\t\t\tawait settleItem(item, failureMessage(reason, error));\n846:\t\t\t} catch (outcomeError) {\n847:\t\t\t\tif (stopping) return;\n848:\t\t\t\tawait failClosed(`omp-spt could not send the outcome to ${item.from ?? \"unknown\"}`, outcomeError);\n849:\t\t\t\treturn;\n850:\t\t\t}\n851:\t\t\tif (current === item) {\n852:\t\t\t\tcurrent = undefined;\n853:\t\t\t\treleaseItem(item);\n854:\t\t\t}\n855:\t\t\tif (!stopping) {\n856:\t\t\t\tdesiredState = \"idle\";\n857:\t\t\t\ttry {\n858:\t\t\t\t\tawait setState(\"idle\");\n859:\t\t\t\t} catch (stateError) {\n860:\t\t\t\t\tawait failClosed(\n861:\t\t\t\t\t\t\"omp-spt could not restore idle state after a failed submission\",\n862:\t\t\t\t\t\tstateError,\n863:\t\t\t\t\t);\n864:\t\t\t\t}\n865:\t\t\t}\n866:\t\t}\n867:\n868:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n869:\t\tasync function dispatchNext() {\n870:\t\t\tif (stopping || agentActive || dispatching || current || queue.length === 0) return;\n871:\t\t\tdispatching = true;\n872:\t\t\tconst item = queue.shift();\n873:\t\t\tcurrent = item;\n874:\t\t\ttry {\n875:\t\t\t\ttry {\n876:\t\t\t\t\tdesiredState = \"busy\";\n877:\t\t\t\t\tawait setState(\"busy\");\n878:\t\t\t\t} catch (error) {\n879:\t\t\t\t\tawait rejectItem(item, \"could not accept your message\", error);\n880:\t\t\t\t\treturn;\n881:\t\t\t\t}\n882:\t\t\t\tif (stopping) return;\n883:\t\t\t\tif (agentActive) {\n884:\t\t\t\t\tif (current === item) current = undefined;\n885:\t\t\t\t\tqueue.unshift(item);\n886:\t\t\t\t\treturn;\n887:\t\t\t\t}\n888:\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n889:\t\t\t\titem.submitted = true;\n890:\t\t\t\ttry {\n891:\t\t\t\t\tpi.sendUserMessage(item.stub);\n892:\t\t\t\t} catch (error) {\n893:\t\t\t\t\titem.submitted = false;\n894:\t\t\t\t\tawait rejectItem(item, \"could not submit your message to OMP\", error);\n895:\t\t\t\t}\n896:\t\t\t} finally {\n897:\t\t\t\tdispatching = false;\n898:\t\t\t\tscheduleDispatch();\n899:\t\t\t}\n900:\t\t}\n901:\n902:\t\t// [impl->REQ-OMP-LISTENER-FAIL-CLOSED]\n903:\t\tfunction handleListenerDeath(reason) {\n904:\t\t\tlistenerBuffer = \"\";\n905:\t\t\tif (listenerStableTimer !== undefined) {\n906:\t\t\t\tclearTimer(listenerStableTimer);\n907:\t\t\t\tlistenerStableTimer = undefined;\n908:\t\t\t}\n909:\t\t\tif (stopping || restartTimer !== undefined) return;\n910:\t\t\tif (listenerRestartCount >= restartDelaysMs.length) {\n911:\t\t\t\tvoid failClosed(\"omp-spt listener restart budget exhausted\", reason);\n912:\t\t\t\treturn;\n913:\t\t\t}\n914:\t\t\tconst attempt = listenerRestartCount + 1;\n915:\t\t\tconst delay = restartDelaysMs[listenerRestartCount];\n916:\t\t\tlistenerRestartCount = attempt;\n917:\t\t\tconst message = `omp-spt listener stopped; restarting ${attempt}/${restartDelaysMs.length} in ${delay}ms`;\n918:\t\t\tpi.logger.error(message, { error: errorSummary(reason) });\n919:\t\t\tui?.setStatus(\"omp-spt\", `spt reconnecting (${attempt}/${restartDelaysMs.length})`);\n920:\t\t\tui?.notify(message, \"warning\");\n921:\t\t\trestartTimer = setTimer(() => {\n922:\t\t\t\trestartTimer = undefined;\n923:\t\t\t\tstartListener();\n924:\t\t\t}, delay);\n925:\t\t\trestartTimer?.unref?.();\n926:\t\t}\n927:\n928:\t\tfunction startListener() {\n929:\t\t\tif (stopping) return;\n930:\t\t\tconst args = [\"api\", \"--adapter\", ADAPTER, \"listen\", id, \"--session-id\", sid];\n931:\t\t\tif (env.OMP_SPT_SUBNET) args.push(\"--subnet\", env.OMP_SPT_SUBNET);\n932:\t\t\tlet child;\n933:\t\t\ttry {\n934:\t\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\n935:\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n936:\t\t\t\t\twindowsHide: true,\n937:\t\t\t\t});\n938:\t\t\t} catch (error) {\n939:\t\t\t\thandleListenerDeath(error);\n940:\t\t\t\treturn;\n941:\t\t\t}\n942:\t\t\tlistener = child;\n943:\t\t\tlistenerBuffer = \"\";\n944:\t\t\tlet dead = false;\n945:\t\t\tconst died = (reason, alreadyExited) => {\n946:\t\t\t\tif (dead) return;\n947:\t\t\t\tdead = true;\n948:\t\t\t\tif (listener === child) listener = undefined;\n949:\t\t\t\tif (stopping || alreadyExited) {\n950:\t\t\t\t\thandleListenerDeath(reason);\n951:\t\t\t\t\treturn;\n952:\t\t\t\t}\n953:\t\t\t\tconst termination = beginListenerTermination(child, \"dead spt api listener\");\n954:\t\t\t\tvoid termination.then(() => handleListenerDeath(reason));\n955:\t\t\t};\n956:\t\t\tif (listenerStableMs !== undefined) {\n957:\t\t\t\tlistenerStableTimer = setTimer(() => {\n958:\t\t\t\t\tlistenerStableTimer = undefined;\n959:\t\t\t\t\tif (listener === child && !stopping) listenerRestartCount = 0;\n960:\t\t\t\t}, listenerStableMs);\n961:\t\t\t\tlistenerStableTimer?.unref?.();\n962:\t\t\t}\n963:\t\t\tchild.stdout.setEncoding(\"utf8\");\n964:\t\t\tchild.stderr.setEncoding(\"utf8\");\n965:\t\t\tchild.stdout.on(\"data\", (chunk) => {\n966:\t\t\t\tif (listener !== child || stopping) return;\n967:\t\t\t\tlistenerBuffer += String(chunk);\n968:\t\t\t\tif (listenerBuffer.length > listenerBufferLimit) {\n969:\t\t\t\t\tvoid failClosed(\n970:\t\t\t\t\t\t\"omp-spt listener protocol corruption\",\n971:\t\t\t\t\t\tprotocolError(\n972:\t\t\t\t\t\t\t`EVENT buffer exceeded ${listenerBufferLimit} characters without a complete drain`,\n973:\t\t\t\t\t\t),\n974:\t\t\t\t\t);\n975:\t\t\t\t\treturn;\n976:\t\t\t\t}\n977:\t\t\t\twhile (!stopping) {\n978:\t\t\t\t\tconst drained = drainEvents(listenerBuffer, {\n979:\t\t\t\t\t\tmaxEvents: 1,\n980:\t\t\t\t\t\tmaxFrameChars: listenerBufferLimit,\n981:\t\t\t\t\t});\n982:\t\t\t\t\tlistenerBuffer = drained.rest;\n983:\t\t\t\t\tif (drained.error) {\n984:\t\t\t\t\t\tvoid failClosed(\"omp-spt listener protocol corruption\", drained.error);\n985:\t\t\t\t\t\treturn;\n986:\t\t\t\t\t}\n987:\t\t\t\t\tif (drained.events.length === 0) break;\n988:\t\t\t\t\tconst event = drained.events[0];\n989:\t\t\t\t\tconst acceptedCount = queue.length + (current ? 1 : 0);\n990:\t\t\t\t\tconst eventBytes = Buffer.byteLength(event.envelope, \"utf8\");\n991:\t\t\t\t\tif (\n992:\t\t\t\t\t\tacceptedCount >= acceptedQueueLimit ||\n993:\t\t\t\t\t\tacceptedBytes + eventBytes > acceptedBytesLimit\n994:\t\t\t\t\t) {\n995:\t\t\t\t\t\toverflowItem = event;\n996:\t\t\t\t\t\tvoid failClosed(\n997:\t\t\t\t\t\t\t\"omp-spt inbound custody capacity exceeded\",\n998:\t\t\t\t\t\t\tnew Error(\n999:\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\n1000:\t\t\t\t\t\t\t),\n1001:\t\t\t\t\t\t);\n1002:\t\t\t\t\t\treturn;\n1003:\t\t\t\t\t}\n1004:\t\t\t\t\tevent.acceptedBytes = eventBytes;\n1005:\t\t\t\t\tevent.accounted = true;\n1006:\t\t\t\t\tacceptedBytes += eventBytes;\n1007:\t\t\t\t\tqueue.push(event);\n1008:\t\t\t\t}\n1009:\t\t\t\tif (!agentActive && !current && !dispatching) void dispatchNext();\n1010:\t\t\t});\n1011:\t\t\tchild.stderr.on(\"data\", (chunk) =>\n1012:\t\t\t\tpi.logger.debug(\"omp-spt listener\", { output: String(chunk).trim() }),\n1013:\t\t\t);\n1014:\t\t\tchild.on(\"error\", (error) => died(error, false));\n1015:\t\t\tchild.on(\"close\", (code, signal) => {\n1016:\t\t\t\tconst status = signal ? `signal ${signal}` : code;\n1017:\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\n1018:\t\t\t});\n1019:\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\n1020:\t\t}\n1021:\n1022:\t\t// [impl->REQ-OMP-NATIVE-TUI]\n1023:\t\tpi.on(\"session_start\", async (_event, ctx) => {\n1024:\t\t\truntimeCtx = ctx;\n1025:\t\t\tui = ctx.ui;\n1026:\t\t\tsid = ctx.sessionManager.getSessionId();\n1027:\t\t\tconst bindArgs = [\"api\", \"--adapter\", ADAPTER, \"bind\", id, \"--set-session-id\", sid];\n1028:\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n1029:\t\t\tbindPromise = (async () => {\n1030:\t\t\t\tconst bound = await runCommand(bindArgs);\n1031:\t\t\t\ttoken = bound.match(/\\btoken=([^\\s]+)/)?.[1];\n1032:\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n1033:\t\t\t})();\n1034:\t\t\ttry {\n1035:\t\t\t\tawait bindPromise;\n1036:\t\t\t} catch (error) {\n1037:\t\t\t\tif (stopping) return;\n1038:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1039:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1040:\t\t\t\treturn;\n1041:\t\t\t}\n1042:\t\t\tif (stopping) {\n1043:\t\t\t\ttry {\n1044:\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n1045:\t\t\t\t} catch (error) {\n1046:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n1047:\t\t\t\t}\n1048:\t\t\t\treturn;\n1049:\t\t\t}\n1050:\t\t\ttry {\n1051:\t\t\t\tawait syncDesiredState();\n1052:\t\t\t\tif (stopping) {\n1053:\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n1054:\t\t\t\t\treturn;\n1055:\t\t\t\t}\n1056:\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n1057:\t\t\t\tstartListener();\n1058:\t\t\t} catch (error) {\n1059:\t\t\t\tif (stopping) {\n1060:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n1061:\t\t\t\t\treturn;\n1062:\t\t\t\t}\n1063:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1064:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1065:\t\t\t}\n1066:\t\t});\n1067:\n1068:\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\n1069:\t\tconst blockSessionChange = (description, ctx) => {\n1070:\t\t\tctx.ui.notify(\n1071:\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n1072:\t\t\t\t\"warning\",\n1073:\t\t\t);\n1074:\t\t\treturn { cancel: true };\n1075:\t\t};\n1076:\n1077:\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n1078:\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\n1079:\t\t);\n1080:\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\n1081:\t\t\tblockSessionChange(\"session branch\", ctx),\n1082:\t\t);\n1083:\n1084:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n1085:\t\tpi.on(\"context\", (event) => {\n1086:\t\t\tif (!current?.submitted || current.settling) return;\n1087:\t\t\tconst messages = injectEnvelope(event.messages, current);\n1088:\t\t\tif (messages !== event.messages) return { messages };\n1089:\t\t});\n1090:\n1091:\t\tasync function completeTurn(event) {\n1092:\t\t\tagentActive = false;\n1093:\t\t\tdesiredState = \"idle\";\n1094:\t\t\tif (stopping) return;\n1095:\t\t\tconst completed = current;\n1096:\t\t\tif (completed?.submitted && !completed.settled) {\n1097:\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\n1098:\t\t\t\ttry {\n1099:\t\t\t\t\tawait settleItem(\n1100:\t\t\t\t\t\tcompleted,\n1101:\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n1102:\t\t\t\t\t);\n1103:\t\t\t\t} catch (error) {\n1104:\t\t\t\t\tif (stopping) return;\n1105:\t\t\t\t\tawait failClosed(\n1106:\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n1107:\t\t\t\t\t\terror,\n1108:\t\t\t\t\t);\n1109:\t\t\t\t\treturn;\n1110:\t\t\t\t}\n1111:\t\t\t}\n1112:\t\t\tif (current === completed) {\n1113:\t\t\t\tcurrent = undefined;\n1114:\t\t\t\treleaseItem(completed);\n1115:\t\t\t}\n1116:\t\t\ttry {\n1117:\t\t\t\tawait setState(\"idle\");\n1118:\t\t\t} catch (error) {\n1119:\t\t\t\tif (stopping) return;\n1120:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n1121:\t\t\t\treturn;\n1122:\t\t\t}\n1123:\t\t\tscheduleDispatch();\n1124:\t\t}\n1125:\n1126:\t\tpi.on(\"agent_start\", async () => {\n1127:\t\t\tif (stopping) return;\n1128:\t\t\tturnCompletionPromise = undefined;\n1129:\t\t\tagentActive = true;\n1130:\t\t\tdesiredState = \"busy\";\n1131:\t\t\ttry {\n1132:\t\t\t\tawait syncDesiredState();\n1133:\t\t\t} catch (error) {\n1134:\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\n1135:\t\t\t}\n1136:\t\t});\n1137:\n1138:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1139:\t\tpi.on(\"agent_end\", (event) => {\n1140:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1141:\t\t\treturn turnCompletionPromise;\n1142:\t\t});\n1143:\n1144:\t\tpi.on(\"session_stop\", async (event) => {\n1145:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1146:\t\t\tawait turnCompletionPromise;\n1147:\t\t});\n1148:\n1149:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n1150:\t\t\truntimeCtx ??= ctx;\n1151:\t\t\tui?.setStatus(\"omp-spt\", undefined);\n1152:\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\n1153:\t\t});\n1154:\t};\n1155:}\n1156:\n1157:export default createOmpSpt();\n1158:"}],"details":{"displayContent":{"text":"export function createOmpSpt(overrides = {}) {\n…\n\tconst outcomeRetryDelaysMs = [\n\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\r\n\t];\r\n\tconst sessionEndRetryDelaysMs = [\r\n\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\r\n\t];\r\n\tconst listenerStableMs =\r\n\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n\t\tlet listenerBuffer = \"\";\r\n\t\tlet listenerRestartCount = 0;\r\n\t\tlet listenerStableTimer;\r\n\t\tlet restartTimer;\r\n\t\tlet dispatchTimer;\r\n\t\tlet bindPromise;\r\n\t\tlet agentActive = false;\r\n\t\tlet desiredState = \"idle\";\r\n\t\tlet dispatching = false;\r\n\t\tlet turnCompletionPromise;\r\n\t\tlet listenerTerminationPromise;\r\n\t\tlet shutdownMode = false;\r\n\t\tlet shutdownDeadlineExpired = false;\r\n\t\tconst activeCommands = new Map();\r\n\t\tconst retryWaiters = new Set();\r\n\t\tlet current;\r\n\t\tlet stopping = false;\r\n\t\tlet ui;\r\n\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\r\n\t\t\tlet command;\r\n\t\t\ttry {\r\n\t\t\t\tcommand = Promise.resolve(\r\n\t\t\t\t\trunSptCommand(args, input, {\r\n\t\t\t\t\t\tsignal: controller.signal,\r\n\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t}),\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t\treturn Promise.reject(error);\r\n\t\t\t}\r\n\t\t\tif (customRunSptCommand) {\r\n\t\t\t\tconst rawCommand = command;\r\n\t\t\t\tcommand = new Promise((resolve, reject) => {\r\n\t\t\t\t\tlet timer;\r\n\t\t\t\t\tlet finished = false;\r\n\t\t\t\t\tconst finish = (error, value) => {\r\n\t\t\t\t\t\tif (finished) return;\r\n\t\t\t\t\t\tfinished = true;\r\n\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\t\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\r\n\t\t\t\t\t\tif (error === undefined) resolve(value);\r\n\t\t\t\t\t\telse reject(error);\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst onAbort = () =>\r\n\t\t\t\t\t\tfinish(\r\n\t\t\t\t\t\t\tcontroller.signal.reason instanceof Error\r\n\t\t\t\t\t\t\t\t? controller.signal.reason\r\n\t\t\t\t\t\t\t\t: new Error(`${commandLabel(args)} aborted`),\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\r\n\t\t\t\t\tif (shutdownMode) {\r\n\t\t\t\t\t\ttimer = setTimer(\r\n\t\t\t\t\t\t\t() =>\r\n\t\t\t\t\t\t\t\tcontroller.abort(\r\n\t\t\t\t\t\t\t\t\tnew Error(`${commandLabel(args)} timed out after ${timeoutMs}ms`),\r\n\t\t\t\t\t\t\t\t),\r\n\t\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\ttimer?.unref?.();\r\n\t\t\t\t\t}\r\n\t\t\t\t\trawCommand.then(\r\n\t\t\t\t\t\t(value) => finish(undefined, value),\r\n\t\t\t\t\t\t(error) => finish(error),\r\n\t\t\t\t\t);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn command.finally(() => {\r\n\t\t\t\tconst active = activeCommands.get(controller);\r\n\t\t\t\tif (active?.abortTimer !== undefined) clearTimer(active.abortTimer);\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\r\n\t\t\tfor (const [controller, active] of activeCommands) {\r\n\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\r\n\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\r\n\t\t\t\t\tactive.abortTimer = setTimer(\r\n\t\t\t\t\t\t() => controller.abort(reason),\r\n\t\t\t\t\t\tshutdownCommandTimeoutMs,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tactive.abortTimer?.unref?.();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tcontroller.abort(reason);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction waitForRetry(delay) {\r\n\t\t\tif (shutdownMode) return Promise.resolve();\r\n\t\t\treturn new Promise((resolve) => {\r\n\t\t\t\tlet timer;\r\n\t\t\t\tconst finish = () => {\r\n\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\t\t\tretryWaiters.delete(finish);\r\n\t\t\t\t\tresolve();\r\n\t\t\t\t};\r\n\t\t\t\tretryWaiters.add(finish);\r\n\t\t\t\ttimer = setTimer(finish, delay);\r\n\t\t\t\ttimer?.unref?.();\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tfunction enterShutdownMode() {\r\n\t\t\tif (shutdownMode) return;\r\n\t\t\tshutdownMode = true;\r\n\t\t\tconst reason = new Error(\"omp-spt command interrupted for bounded shutdown\");\r\n\t\t\tabortActiveCommands(reason, true);\r\n\t\t\tfor (const finish of [...retryWaiters]) finish();\r\n\t\t}\r\n\r\n\t\tfunction authArgs() {\r\n\t\t\tif (!token) throw new Error(\"bind did not return an authentication token\");\r\n\t\t\treturn [\"--token\", token];\r\n\t\t}\r\n\r\n\t\tfunction setState(state) {\r\n\t\t\tif (!sid || !token || stopping) return Promise.resolve();\r\n\t\t\tconst operation = stateOperation.catch(() => {}).then(async () => {\r\n\t\t\t\tif (endpointState === state || stopping) return;\r\n\t\t\t\tawait runCommand([\"api\", \"--adapter\", ADAPTER, \"state\", state, id, ...authArgs()]);\r\n\t\t\t\tendpointState = state;\r\n\t\t\t});\r\n\t\t\tstateOperation = operation;\r\n\t\t\treturn operation;\r\n\t\t}\r\n\r\n\t\tasync function syncDesiredState() {\r\n\t\t\tif (!bindPromise) return;\r\n\t\t\tawait bindPromise;\r\n\t\t\twhile (!stopping && endpointState !== desiredState) {\r\n\t\t\t\tawait setState(desiredState);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction endSession() {\r\n\t\t\tif (!sid || !token) return Promise.resolve();\r\n\t\t\tif (!endPromise) {\r\n\t\t\t\tconst operation = (async () => {\r\n\t\t\t\t\tawait stateOperation.catch(() => {});\r\n\t\t\t\t\tawait runCommand([\"api\", \"--adapter\", ADAPTER, \"session-end\", id, ...authArgs()]);\r\n\t\t\t\t\tendpointState = undefined;\r\n\t\t\t\t})();\r\n\t\t\t\tendPromise = operation;\r\n\t\t\t\tvoid operation.catch(() => {\r\n\t\t\t\t\tif (endPromise === operation) endPromise = undefined;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn endPromise;\r\n\t\t}\r\n\r\n\t\tasync function endSessionWithRetry() {\r\n\t\t\tfor (let attempt = 0; ; attempt += 1) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait endSession();\r\n\t\t\t\t\treturn;\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (shutdownMode || attempt >= sessionEndRetryDelaysMs.length) throw error;\r\n\t\t\t\t\tconst delay = sessionEndRetryDelaysMs[attempt];\r\n\t\t\t\t\tpi.logger.error(\r\n\t\t\t\t\t\t`omp-spt session teardown failed; retrying ${\r\n\t\t\t\t\t\t\tattempt + 1\r\n\t\t\t\t\t\t}/${sessionEndRetryDelaysMs.length} in ${delay}ms`,\r\n\t\t\t\t\t\t{ error: errorSummary(error) },\r\n\t\t\t\t\t);\r\n\t\t\t\t\tawait waitForRetry(delay);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tfunction settleItem(item, payload) {\r\n\t\t\tif (!item) return Promise.resolve();\r\n\t\t\tif (item.outcomePromise) return item.outcomePromise;\r\n\t\t\titem.settling = true;\r\n\t\t\titem.outcomePromise = (async () => {\r\n\t\t\t\tif (!item.from) throw new Error(\"missing EVENT from attribute\");\r\n\t\t\t\tfor (let attempt = 0; ; attempt += 1) {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tawait runCommand([\"send\", item.from, \"--from\", id], payload);\r\n\t\t\t\t\t\titem.settled = true;\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tif (shutdownMode || attempt >= outcomeRetryDelaysMs.length) throw error;\r\n\t\t\t\t\t\tconst delay = outcomeRetryDelaysMs[attempt];\r\n\t\t\t\t\t\tpi.logger.error(\r\n\t\t\t\t\t\t\t`omp-spt could not send the outcome to ${item.from}; retrying ${\r\n\t\t\t\t\t\t\t\tattempt + 1\r\n\t\t\t\t\t\t\t}/${outcomeRetryDelaysMs.length} in ${delay}ms`,\r\n\t\t\t\t\t\t\t{ error: errorSummary(error) },\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tawait waitForRetry(delay);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})();\r\n\t\t\treturn item.outcomePromise;\r\n\t\t}\r\n\r\n\t\tfunction releaseItem(item) {\r\n\t\t\tif (!item?.accounted) return;\r\n\t\t\titem.accounted = false;\r\n\t\t\tacceptedBytes -= item.acceptedBytes;\r\n\t\t}\r\n\r\n\t\tfunction beginListenerTermination(child, label) {\r\n\t\t\tif (listenerTerminationPromise) return listenerTerminationPromise;\r\n\t\t\tconst operation = (async () => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait terminateChild(child, label, {\r\n\t\t\t\t\t\tclearTimer,\r\n\t\t\t\t\t\tforceMs: killForceMs,\r\n\t\t\t\t\t\tgraceMs: killGraceMs,\r\n\t\t\t\t\t\tsetTimer,\r\n\t\t\t\t\t});\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tpi.logger.error(\"omp-spt could not reap the listener\", {\r\n\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t})();\r\n\t\t\tlistenerTerminationPromise = operation;\r\n\t\t\tvoid operation.then(() => {\r\n\t\t\t\tif (listenerTerminationPromise === operation) listenerTerminationPromise = undefined;\r\n\t\t\t});\r\n\t\t\treturn operation;\r\n\t\t}\r\n\r\n\t\tasync function stopResources() {\r\n\t\t\tif (dispatchTimer !== undefined) {\r\n\t\t\t\tclearTimer(dispatchTimer);\r\n\t\t\t\tdispatchTimer = undefined;\r\n\t\t\t}\r\n\t\t\tif (restartTimer !== undefined) {\r\n\t\t\t\tclearTimer(restartTimer);\r\n\t\t\t\trestartTimer = undefined;\r\n\t\t\t}\r\n\t\t\tif (listenerStableTimer !== undefined) {\r\n\t\t\t\tclearTimer(listenerStableTimer);\r\n\t\t\t\tlistenerStableTimer = undefined;\r\n\t\t\t}\r\n\t\t\tconst child = listener;\r\n\t\t\tlistener = undefined;\r\n\t\t\tlistenerBuffer = \"\";\r\n\t\t\tif (child) {\r\n\t\t\t\tawait beginListenerTermination(child, \"spt api listener\");\r\n\t\t\t} else {\r\n\t\t\t\tawait listenerTerminationPromise;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tasync function settlePendingItem(item, reason) {\r\n\t\t\ttry {\r\n\t\t\t\tif (item.outcomePromise && !item.settled) {\r\n\t\t\t\t\tlet existingError;\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tawait item.outcomePromise;\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\texistingError = error;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (item.settled) return;\r\n\t\t\t\t\tif (existingError && !shutdownMode) {\r\n\t\t\t\t\t\tlogError(\r\n\t\t\t\t\t\t\t`omp-spt could not return custody to ${item.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\t\texistingError,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\titem.outcomePromise = undefined;\r\n\t\t\t\t\titem.settling = false;\r\n\t\t\t\t}\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(item, failureMessage(reason));\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tlogError(`omp-spt could not return custody to ${item.from ?? \"unknown\"}`, error);\r\n\t\t\t\t}\r\n\t\t\t} finally {\r\n\t\t\t\treleaseItem(item);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tasync function failPending(reason) {\r\n\t\t\tconst pending = current ? [current, ...queue] : [...queue];\r\n\t\t\tif (overflowItem) pending.push(overflowItem);\r\n\t\t\tcurrent = undefined;\r\n\t\t\tqueue.length = 0;\r\n\t\t\toverflowItem = undefined;\r\n\t\t\tfor (let index = 0; index < pending.length; index += 1) {\r\n\t\t\t\tif (shutdownMode) {\r\n\t\t\t\t\tawait Promise.all(\r\n\t\t\t\t\t\tpending.slice(index).map((item) => settlePendingItem(item, reason)),\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tawait settlePendingItem(pending[index], reason);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction teardownSession(pendingReason) {\r\n\t\t\tif (!teardownPromise) {\r\n\t\t\t\tstopping = true;\r\n\t\t\t\tconst operation = (async () => {\r\n\t\t\t\t\tawait stopResources();\r\n\t\t\t\t\tawait failPending(pendingReason);\r\n\t\t\t\t\tawait bindPromise?.catch(() => {});\r\n\t\t\t\t\tawait endSessionWithRetry();\r\n\t\t\t\t})();\r\n\t\t\t\tteardownPromise = operation;\r\n\t\t\t\tvoid operation.catch(() => {\r\n\t\t\t\t\tif (teardownPromise === operation) teardownPromise = undefined;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn teardownPromise;\r\n\t\t}\r\n\r\n\t\tasync function shutdownWithinBudget(pendingReason) {\r\n\t\t\tenterShutdownMode();\r\n\t\t\tconst teardown = teardownSession(pendingReason);\r\n\t\t\tlet budgetTimer;\r\n\t\t\tconst expired = new Promise((resolve) => {\r\n\t\t\t\tbudgetTimer = setTimer(() => {\r\n\t\t\t\t\tbudgetTimer = undefined;\r\n\t\t\t\t\tshutdownDeadlineExpired = true;\r\n\t\t\t\t\tconst error = new Error(\r\n\t\t\t\t\t\t`omp-spt shutdown exceeded its ${shutdownBudgetMs}ms budget`,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tabortActiveCommands(error);\r\n\t\t\t\t\tfor (const finish of [...retryWaiters]) finish();\r\n\t\t\t\t\tresolve(false);\r\n\t\t\t\t}, shutdownBudgetMs);\r\n\t\t\t\tbudgetTimer?.unref?.();\r\n\t\t\t});\r\n\t\t\tconst completed = teardown.then(\r\n\t\t\t\t() => true,\r\n\t\t\t\t(error) => {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t},\r\n\t\t\t);\r\n\t\t\tconst finished = await Promise.race([completed, expired]);\r\n\t\t\tif (budgetTimer !== undefined) clearTimer(budgetTimer);\r\n\t\t\tif (!finished) {\r\n\t\t\t\tpi.logger.error(\"omp-spt bounded shutdown expired\", {\r\n\t\t\t\t\terror: `${shutdownBudgetMs}ms budget exhausted`,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-LISTENER-FAIL-CLOSED]\r\n\t\tasync function failClosed(message, error) {\r\n\t\t\tif (stopping && shutdownMode) return teardownPromise ?? Promise.resolve();\r\n\t\t\tif (fatalPromise) return fatalPromise;\r\n\t\t\tfatalPromise = (async () => {\r\n\t\t\t\tui?.setStatus(\"omp-spt\", \"spt failed\");\r\n\t\t\t\tlogError(message, error);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait teardownSession(\"endpoint stopped before your message could complete\");\r\n\t\t\t\t} catch (teardownError) {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", teardownError);\r\n\t\t\t\t}\r\n\t\t\t\truntimeCtx?.shutdown();\r\n\t\t\t})();\r\n\t\t\treturn fatalPromise;\r\n\t\t}\r\n\r\n\t\tfunction scheduleDispatch() {\r\n\t\t\tif (\r\n\t\t\t\tstopping ||\r\n\t\t\t\tagentActive ||\r\n\t\t\t\tdispatching ||\r\n\t\t\t\tcurrent ||\r\n\t\t\t\tqueue.length === 0 ||\r\n\t\t\t\tdispatchTimer !== undefined\r\n\t\t\t) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tdispatchTimer = setTimer(() => {\r\n\t\t\t\tdispatchTimer = undefined;\r\n\t\t\t\tvoid dispatchNext().catch((error) => {\r\n\t\t\t\t\tif (!stopping) return failClosed(\"omp-spt dispatch failed\", error);\r\n\t\t\t\t});\r\n\t\t\t}, 0);\r\n\t\t\tdispatchTimer?.unref?.();\r\n\t\t}\r\n\r\n\t\tasync function rejectItem(item, reason, error) {\r\n\t\t\tif (stopping) return;\r\n\t\t\tlogError(`omp-spt ${reason}`, error);\r\n\t\t\ttry {\r\n\t\t\t\tawait settleItem(item, failureMessage(reason, error));\r\n\t\t\t} catch (outcomeError) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(`omp-spt could not send the outcome to ${item.from ?? \"unknown\"}`, outcomeError);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (current === item) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(item);\r\n\t\t\t}\r\n\t\t\tif (!stopping) {\r\n\t\t\t\tdesiredState = \"idle\";\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait setState(\"idle\");\r\n\t\t\t\t} catch (stateError) {\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t\"omp-spt could not restore idle state after a failed submission\",\r\n\t\t\t\t\t\tstateError,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tasync function dispatchNext() {\r\n\t\t\tif (stopping || agentActive || dispatching || current || queue.length === 0) return;\r\n\t\t\tdispatching = true;\r\n\t\t\tconst item = queue.shift();\r\n\t\t\tcurrent = item;\r\n\t\t\ttry {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tdesiredState = \"busy\";\r\n\t\t\t\t\tawait setState(\"busy\");\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tawait rejectItem(item, \"could not accept your message\", error);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tif (agentActive) {\r\n\t\t\t\t\tif (current === item) current = undefined;\r\n\t\t\t\t\tqueue.unshift(item);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\ttry {\r\n\t\t\t\t\tpi.sendUserMessage(item.stub);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\titem.submitted = false;\r\n\t\t\t\t\tawait rejectItem(item, \"could not submit your message to OMP\", error);\r\n\t\t\t\t}\r\n\t\t\t} finally {\r\n\t\t\t\tdispatching = false;\r\n\t\t\t\tscheduleDispatch();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-LISTENER-FAIL-CLOSED]\r\n\t\tfunction handleListenerDeath(reason) {\r\n\t\t\tlistenerBuffer = \"\";\r\n\t\t\tif (listenerStableTimer !== undefined) {\r\n\t\t\t\tclearTimer(listenerStableTimer);\r\n\t\t\t\tlistenerStableTimer = undefined;\r\n\t\t\t}\r\n\t\t\tif (stopping || restartTimer !== undefined) return;\r\n\t\t\tif (listenerRestartCount >= restartDelaysMs.length) {\r\n\t\t\t\tvoid failClosed(\"omp-spt listener restart budget exhausted\", reason);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tconst attempt = listenerRestartCount + 1;\r\n\t\t\tconst delay = restartDelaysMs[listenerRestartCount];\r\n\t\t\tlistenerRestartCount = attempt;\r\n\t\t\tconst message = `omp-spt listener stopped; restarting ${attempt}/${restartDelaysMs.length} in ${delay}ms`;\r\n\t\t\tpi.logger.error(message, { error: errorSummary(reason) });\r\n\t\t\tui?.setStatus(\"omp-spt\", `spt reconnecting (${attempt}/${restartDelaysMs.length})`);\r\n\t\t\tui?.notify(message, \"warning\");\r\n\t\t\trestartTimer = setTimer(() => {\r\n\t\t\t\trestartTimer = undefined;\r\n\t\t\t\tstartListener();\r\n\t\t\t}, delay);\r\n\t\t\trestartTimer?.unref?.();\r\n\t\t}\r\n\r\n\t\tfunction startListener() {\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst args = [\"api\", \"--adapter\", ADAPTER, \"listen\", id, \"--session-id\", sid];\r\n\t\t\tif (env.OMP_SPT_SUBNET) args.push(\"--subnet\", env.OMP_SPT_SUBNET);\r\n\t\t\tlet child;\r\n\t\t\ttry {\r\n\t\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\r\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\r\n\t\t\t\t\twindowsHide: true,\r\n\t\t\t\t});\r\n\t\t\t} catch (error) {\r\n\t\t\t\thandleListenerDeath(error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tlistener = child;\r\n\t\t\tlistenerBuffer = \"\";\r\n\t\t\tlet dead = false;\r\n\t\t\tconst died = (reason, alreadyExited) => {\r\n\t\t\t\tif (dead) return;\r\n\t\t\t\tdead = true;\r\n\t\t\t\tif (listener === child) listener = undefined;\r\n\t\t\t\tif (stopping || alreadyExited) {\r\n\t\t\t\t\thandleListenerDeath(reason);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tconst termination = beginListenerTermination(child, \"dead spt api listener\");\r\n\t\t\t\tvoid termination.then(() => handleListenerDeath(reason));\r\n\t\t\t};\r\n\t\t\tif (listenerStableMs !== undefined) {\r\n\t\t\t\tlistenerStableTimer = setTimer(() => {\r\n\t\t\t\t\tlistenerStableTimer = undefined;\r\n\t\t\t\t\tif (listener === child && !stopping) listenerRestartCount = 0;\r\n\t\t\t\t}, listenerStableMs);\r\n\t\t\t\tlistenerStableTimer?.unref?.();\r\n\t\t\t}\r\n\t\t\tchild.stdout.setEncoding(\"utf8\");\r\n\t\t\tchild.stderr.setEncoding(\"utf8\");\r\n\t\t\tchild.stdout.on(\"data\", (chunk) => {\r\n\t\t\t\tif (listener !== child || stopping) return;\r\n\t\t\t\tlistenerBuffer += String(chunk);\r\n\t\t\t\tif (listenerBuffer.length > listenerBufferLimit) {\r\n\t\t\t\t\tvoid failClosed(\r\n\t\t\t\t\t\t\"omp-spt listener protocol corruption\",\r\n\t\t\t\t\t\tprotocolError(\r\n\t\t\t\t\t\t\t`EVENT buffer exceeded ${listenerBufferLimit} characters without a complete drain`,\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\twhile (!stopping) {\r\n\t\t\t\t\tconst drained = drainEvents(listenerBuffer, {\r\n\t\t\t\t\t\tmaxEvents: 1,\r\n\t\t\t\t\t\tmaxFrameChars: listenerBufferLimit,\r\n\t\t\t\t\t});\r\n\t\t\t\t\tlistenerBuffer = drained.rest;\r\n\t\t\t\t\tif (drained.error) {\r\n\t\t\t\t\t\tvoid failClosed(\"omp-spt listener protocol corruption\", drained.error);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (drained.events.length === 0) break;\r\n\t\t\t\t\tconst event = drained.events[0];\r\n\t\t\t\t\tconst acceptedCount = queue.length + (current ? 1 : 0);\r\n\t\t\t\t\tconst eventBytes = Buffer.byteLength(event.envelope, \"utf8\");\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\tacceptedCount >= acceptedQueueLimit ||\r\n\t\t\t\t\t\tacceptedBytes + eventBytes > acceptedBytesLimit\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\toverflowItem = event;\r\n\t\t\t\t\t\tvoid failClosed(\r\n\t\t\t\t\t\t\t\"omp-spt inbound custody capacity exceeded\",\r\n\t\t\t\t\t\t\tnew Error(\r\n\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\r\n\t\t\t\t\t\t\t),\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tevent.acceptedBytes = eventBytes;\r\n\t\t\t\t\tevent.accounted = true;\r\n\t\t\t\t\tacceptedBytes += eventBytes;\r\n\t\t\t\t\tqueue.push(event);\r\n\t\t\t\t}\r\n\t\t\t\tif (!agentActive && !current && !dispatching) void dispatchNext();\r\n\t\t\t});\r\n\t\t\tchild.stderr.on(\"data\", (chunk) =>\r\n\t\t\t\tpi.logger.debug(\"omp-spt listener\", { output: String(chunk).trim() }),\r\n\t\t\t);\r\n\t\t\tchild.on(\"error\", (error) => died(error, false));\r\n\t\t\tchild.on(\"close\", (code, signal) => {\r\n\t\t\t\tconst status = signal ? `signal ${signal}` : code;\r\n\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\r\n\t\t\t});\r\n\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-NATIVE-TUI]\r\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\r\n\t\t\truntimeCtx = ctx;\r\n\t\t\tui = ctx.ui;\r\n\t\t\tsid = ctx.sessionManager.getSessionId();\r\n\t\t\tconst bindArgs = [\"api\", \"--adapter\", ADAPTER, \"bind\", id, \"--set-session-id\", sid];\r\n\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\r\n\t\t\tbindPromise = (async () => {\r\n\t\t\t\tconst bound = await runCommand(bindArgs);\r\n\t\t\t\ttoken = bound.match(/\\btoken=([^\\s]+)/)?.[1];\r\n\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\r\n\t\t\t})();\r\n\t\t\ttry {\r\n\t\t\t\tawait bindPromise;\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (stopping) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t\tif (stopping) {\r\n\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t\t\tstartListener();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\r\n\t\tconst blockSessionChange = (description, ctx) => {\r\n\t\t\tctx.ui.notify(\r\n\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\r\n\t\t\t\t\"warning\",\r\n\t\t\t);\r\n\t\t\treturn { cancel: true };\r\n\t\t};\r\n\r\n\t\tpi.on(\"session_before_switch\", (event, ctx) =>\r\n\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tif (!current?.submitted || current.settling) return;\r\n\t\t\tconst messages = injectEnvelope(event.messages, current);\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\tawait turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\r\n\t\t\truntimeCtx ??= ctx;\r\n\t\t\tui?.setStatus(\"omp-spt\", undefined);\r\n\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\r\n\t\t});\r\n\t};\r\n}\r\n\r\nexport default createOmpSpt();\r\n","startLine":376,"lineNumbers":[376,null,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"}}},"isError":false,"timestamp":1784188876275}}
{"type":"message","id":"dad383d8","parentId":"2d538685","timestamp":"2026-07-16T08:01:16.294Z","message":{"role":"toolResult","toolCallId":"call_R18zxmI1ITWy0vSUCnuKaRGc|fc_03e5b91f227b0634016a588fcc2f78819bbd7f5378632c52a8","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#8FB4]\n1:import assert from \"node:assert/strict\";\n2:import { EventEmitter } from \"node:events\";\n3:import {\n4:\tcreateOmpSpt,\n5:\tdecodeBody,\n6:\tdrainEvents,\n7:\textractReply,\n8:\trunSpt,\n9:} from \"../adapter/strings/omp-spt.mjs\";\n10:\n11:const flush = () => new Promise((resolve) => setImmediate(resolve));\n12:function deferred() {\n13:\tlet resolve;\n14:\tlet reject;\n15:\tconst promise = new Promise((resolvePromise, rejectPromise) => {\n16:\t\tresolve = resolvePromise;\n17:\t\treject = rejectPromise;\n18:\t});\n19:\treturn { promise, reject, resolve };\n20:}\n21:\n22:class FakeStream extends EventEmitter {\n23:\tsetEncoding(encoding) {\n24:\t\tthis.encoding = encoding;\n25:\t}\n26:\n27:\tend(input) {\n28:\t\tthis.input = input;\n29:\t\tif (this.onEnd?.(input) === false) return;\n30:\t\tthis.emit(\"finish\");\n31:\t}\n32:}\n33:\n34:class FakeChild extends EventEmitter {\n35:\tconstructor(options = {}) {\n36:\t\tsuper();\n37:\t\tthis.stdin = new FakeStream();\n38:\t\tthis.stdout = new FakeStream();\n39:\t\tthis.stderr = new FakeStream();\n40:\t\tthis.exitCode = null;\n41:\t\tthis.signalCode = null;\n42:\t\tthis.kills = 0;\n43:\t\tthis.killSignals = [];\n44:\t\tthis.onKill = options.onKill;\n45:\t}\n46:\n47:\tclose(code = 0, signal = null) {\n48:\t\tthis.exitCode = code;\n49:\t\tthis.signalCode = signal;\n50:\t\tthis.emit(\"close\", code, signal);\n51:\t}\n52:\n53:\tkill(signal = \"SIGTERM\") {\n54:\t\tthis.kills += 1;\n55:\t\tthis.killSignals.push(signal);\n56:\t\tconst handled = this.onKill?.(signal, this);\n57:\t\tif (handled !== undefined) return handled;\n58:\t\tthis.close(null, signal);\n59:\t\treturn true;\n60:\t}\n61:}\n62:\n63:class FakeClock {\n64:\tconstructor() {\n65:\t\tthis.nextId = 1;\n66:\t\tthis.timers = new Map();\n67:\t}\n68:\n69:\tsetTimeout(fn, delay) {\n70:\t\tconst handle = { id: this.nextId++, unref() {} };\n71:\t\tthis.timers.set(handle, { fn, delay });\n72:\t\treturn handle;\n73:\t}\n74:\n75:\tclearTimeout(handle) {\n76:\t\tthis.timers.delete(handle);\n77:\t}\n78:\n79:\tdelays() {\n80:\t\treturn [...this.timers.values()].map(({ delay }) => delay);\n81:\t}\n82:\n83:\tasync runNext(expectedDelay) {\n84:\t\tconst entry = [...this.timers.entries()].sort((left, right) => left[1].delay - right[1].delay)[0];\n85:\t\tassert.ok(entry, `expected a ${expectedDelay}ms timer`);\n86:\t\tconst [handle, timer] = entry;\n87:\t\tassert.equal(timer.delay, expectedDelay);\n88:\t\tthis.timers.delete(handle);\n89:\t\ttimer.fn();\n90:\t\tawait flush();\n91:\t}\n92:}\n93:\n94:function createHarness(options = {}) {\n95:\tconst handlers = new Map();\n96:\tconst calls = [];\n97:\tconst children = [];\n98:\tconst submitted = [];\n99:\tconst statuses = [];\n100:\tconst notifications = [];\n101:\tconst errors = [];\n102:\tconst debug = [];\n103:\tconst clock = new FakeClock();\n104:\tlet shutdowns = 0;\n105:\n106:\tconst ui = {\n107:\t\tnotify(message, type) {\n108:\t\t\tnotifications.push({ message, type });\n109:\t\t},\n110:\t\tsetStatus(key, text) {\n111:\t\t\tstatuses.push({ key, text });\n112:\t\t},\n113:\t};\n114:\tconst ctx = {\n115:\t\tui,\n116:\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\n117:\t\tshutdown() {\n118:\t\t\tshutdowns += 1;\n119:\t\t},\n120:\t};\n121:\tconst pi = {\n122:\t\tlogger: {\n123:\t\t\terror(message, details) {\n124:\t\t\t\terrors.push({ message, details });\n125:\t\t\t},\n126:\t\t\tdebug(message, details) {\n127:\t\t\t\tdebug.push({ message, details });\n128:\t\t\t},\n129:\t\t},\n130:\t\ton(name, handler) {\n131:\t\t\tconst registered = handlers.get(name) ?? [];\n132:\t\t\tregistered.push(handler);\n133:\t\t\thandlers.set(name, registered);\n134:\t\t},\n135:\t\tsendUserMessage(content) {\n136:\t\t\tsubmitted.push(content);\n137:\t\t\toptions.onSubmit?.(content);\n138:\t\t},\n139:\t};\n140:\tconst runSptCommand = async (args, input) => {\n141:\t\tconst call = { args: [...args], input };\n142:\t\tcalls.push(call);\n143:\t\tconst overridden = await options.onRun?.(call);\n144:\t\tif (overridden !== undefined) return overridden;\n145:\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\n146:\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\n147:\t\t}\n148:\t\treturn \"\";\n149:\t};\n150:\tconst spawnProcess = (binary, args, spawnOptions) => {\n151:\t\tconst child = new FakeChild();\n152:\t\tchild.binary = binary;\n153:\t\tchild.args = [...args];\n154:\t\tchild.spawnOptions = spawnOptions;\n155:\t\toptions.onSpawn?.(child);\n156:\t\tchildren.push(child);\n157:\t\treturn child;\n158:\t};\n159:\tconst extension = createOmpSpt({\n160:\t\tenv: {\n161:\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\n162:\t\t\tOMP_SPT_SUBNET: options.subnet,\n163:\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\n164:\t\t},\n165:\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n166:\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n167:\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\n168:\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\n169:\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\n170:\t\tshutdownBudgetMs: options.shutdownBudgetMs,\n171:\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\n172:\t\tlistenerStableMs: options.listenerStableMs ?? false,\n173:\t\tkillForceMs: options.killForceMs ?? 4,\n174:\t\tkillGraceMs: options.killGraceMs ?? 3,\n175:\t\tlistenerBufferLimit: options.listenerBufferLimit,\n176:\t\trunSptCommand,\n177:\t\tspawnProcess,\n178:\t\tsetTimeout: clock.setTimeout.bind(clock),\n179:\t\tclearTimeout: clock.clearTimeout.bind(clock),\n180:\t});\n181:\textension(pi);\n182:\n183:\tasync function emit(name, event = {}) {\n184:\t\tlet result;\n185:\t\tfor (const handler of handlers.get(name) ?? []) {\n186:\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\n187:\t\t\tif (returned !== undefined) result = returned;\n188:\t\t}\n189:\t\treturn result;\n190:\t}\n191:\n192:\treturn {\n193:\t\tcalls,\n194:\t\tchildren,\n195:\t\tclock,\n196:\t\tctx,\n197:\t\tdebug,\n198:\t\temit,\n199:\t\terrors,\n200:\t\thandlers,\n201:\t\tnotifications,\n202:\t\tstatuses,\n203:\t\tsubmitted,\n204:\t\tget shutdowns() {\n205:\t\t\treturn shutdowns;\n206:\t\t},\n207:\t};\n208:}\n209:\n210:function commandCalls(harness, command) {\n211:\treturn harness.calls.filter((call) => call.args[0] === command);\n212:}\n213:\n214:function stateCalls(harness) {\n215:\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n216:}\n217:\n218:async function testParsingAndReplies() {\n219:\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\n220:\n221:\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\n222:\tconst partial = drainEvents(`noise${partialEnvelope}`);\n223:\tassert.deepEqual(partial.events, []);\n224:\tassert.equal(partial.rest, partialEnvelope);\n225:\n226:\tconst envelope = `${partial.rest}rld</EVENT>`;\n227:\tconst complete = drainEvents(`${envelope}<EVENT type=\"notify\">skip</EVENT>`);\n228:\tassert.deepEqual(complete.events, [\n229:\t\t{ from: \"doyle\", body: \"hello\\nworld\", envelope },\n230:\t]);\n231:\tassert.equal(complete.rest, \"\");\n232:\n233:\tconst truncatedA =\n234:\t\t'<EVENT type=\"msg\" from=\"a\">truncated<EVENT type=\"msg\" from=\"b\">valid</EVENT>';\n235:\tconst nested = drainEvents(truncatedA);\n236:\tassert.deepEqual(nested.events, []);\n237:\tassert.equal(nested.rest, truncatedA);\n238:\tassert.match(nested.error.message, /nested EVENT/);\n239:\tassert.match(\n240:\t\tdrainEvents('<EVENT type=\"msg\">missing sender</EVENT>').error.message,\n241:\t\t/missing EVENT from/,\n242:\t);\n243:\tassert.match(\n244:\t\tdrainEvents('<EVENT type=msg from=\"a\">bad attrs</EVENT>').error.message,\n245:\t\t/malformed EVENT attributes/,\n246:\t);\n247:\tassert.match(\n248:\t\tdrainEvents('<EVENT type=\"msg\" from=\"a\">0123456789</EVENT>', {\n249:\t\t\tmaxFrameChars: 32,\n250:\t\t}).error.message,\n251:\t\t/EVENT frame exceeded/,\n252:\t);\n253:\n254:\tassert.equal(\n255:\t\textractReply([\n256:\t\t\t{ role: \"assistant\", content: [{ type: \"text\", text: \"first\" }] },\n257:\t\t\t{ role: \"toolResult\", content: [] },\n258:\t\t\t{\n259:\t\t\t\trole: \"assistant\",\n260:\t\t\t\tcontent: [\n261:\t\t\t\t\t{ type: \"text\", text: \"final \" },\n262:\t\t\t\t\t{ type: \"text\", text: \"answer\" },\n263:\t\t\t\t],\n264:\t\t\t},\n265:\t\t]),\n266:\t\t\"final answer\",\n267:\t);\n268:\tassert.equal(\n269:\t\textractReply(\n270:\t\t\t[\n271:\t\t\t\t{ role: \"assistant\", content: \"stale answer\" },\n272:\t\t\t\t{ role: \"user\", content: '<msg from=\"doyle\"/>' },\n273:\t\t\t],\n274:\t\t\t'<msg from=\"doyle\"/>',\n275:\t\t),\n276:\t\t\"\",\n277:\t);\n278:}\n279:\n280:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n281:// [unit->REQ-OMP-SESSION-IMMUTABLE]\n282:// [unit->REQ-OMP-MESSAGE-CONTEXT]\n283:// [unit->REQ-OMP-NATIVE-TUI]\n284:async function testLifecycleCustodyAndContext() {\n285:\tconst harness = createHarness({ subnet: \"mesh-a\" });\n286:\tassert.deepEqual([...harness.handlers.keys()], [\n287:\t\t\"session_start\",\n288:\t\t\"session_before_switch\",\n…\n295:\t]);\n…\n423:}\n\n[Showing lines 1-288 of 1378. Use :289 to continue]"}],"details":{"truncation":{"content":"import assert from \"node:assert/strict\";\r\nimport { EventEmitter } from \"node:events\";\r\nimport {\r\n\tcreateOmpSpt,\r\n\tdecodeBody,\r\n\tdrainEvents,\r\n\textractReply,\r\n\trunSpt,\r\n} from \"../adapter/strings/omp-spt.mjs\";\r\n\r\nconst flush = () => new Promise((resolve) => setImmediate(resolve));\r\nfunction deferred() {\r\n\tlet resolve;\r\n\tlet reject;\r\n\tconst promise = new Promise((resolvePromise, rejectPromise) => {\r\n\t\tresolve = resolvePromise;\r\n\t\treject = rejectPromise;\r\n\t});\r\n\treturn { promise, reject, resolve };\r\n}\r\n\r\nclass FakeStream extends EventEmitter {\r\n\tsetEncoding(encoding) {\r\n\t\tthis.encoding = encoding;\r\n\t}\r\n\r\n\tend(input) {\r\n\t\tthis.input = input;\r\n\t\tif (this.onEnd?.(input) === false) return;\r\n\t\tthis.emit(\"finish\");\r\n\t}\r\n}\r\n\r\nclass FakeChild extends EventEmitter {\r\n\tconstructor(options = {}) {\r\n\t\tsuper();\r\n\t\tthis.stdin = new FakeStream();\r\n\t\tthis.stdout = new FakeStream();\r\n\t\tthis.stderr = new FakeStream();\r\n\t\tthis.exitCode = null;\r\n\t\tthis.signalCode = null;\r\n\t\tthis.kills = 0;\r\n\t\tthis.killSignals = [];\r\n\t\tthis.onKill = options.onKill;\r\n\t}\r\n\r\n\tclose(code = 0, signal = null) {\r\n\t\tthis.exitCode = code;\r\n\t\tthis.signalCode = signal;\r\n\t\tthis.emit(\"close\", code, signal);\r\n\t}\r\n\r\n\tkill(signal = \"SIGTERM\") {\r\n\t\tthis.kills += 1;\r\n\t\tthis.killSignals.push(signal);\r\n\t\tconst handled = this.onKill?.(signal, this);\r\n\t\tif (handled !== undefined) return handled;\r\n\t\tthis.close(null, signal);\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nclass FakeClock {\r\n\tconstructor() {\r\n\t\tthis.nextId = 1;\r\n\t\tthis.timers = new Map();\r\n\t}\r\n\r\n\tsetTimeout(fn, delay) {\r\n\t\tconst handle = { id: this.nextId++, unref() {} };\r\n\t\tthis.timers.set(handle, { fn, delay });\r\n\t\treturn handle;\r\n\t}\r\n\r\n\tclearTimeout(handle) {\r\n\t\tthis.timers.delete(handle);\r\n\t}\r\n\r\n\tdelays() {\r\n\t\treturn [...this.timers.values()].map(({ delay }) => delay);\r\n\t}\r\n\r\n\tasync runNext(expectedDelay) {\r\n\t\tconst entry = [...this.timers.entries()].sort((left, right) => left[1].delay - right[1].delay)[0];\r\n\t\tassert.ok(entry, `expected a ${expectedDelay}ms timer`);\r\n\t\tconst [handle, timer] = entry;\r\n\t\tassert.equal(timer.delay, expectedDelay);\r\n\t\tthis.timers.delete(handle);\r\n\t\ttimer.fn();\r\n\t\tawait flush();\r\n\t}\r\n}\r\n\r\nfunction createHarness(options = {}) {\r\n\tconst handlers = new Map();\r\n\tconst calls = [];\r\n\tconst children = [];\r\n\tconst submitted = [];\r\n\tconst statuses = [];\r\n\tconst notifications = [];\r\n\tconst errors = [];\r\n\tconst debug = [];\r\n\tconst clock = new FakeClock();\r\n\tlet shutdowns = 0;\r\n\r\n\tconst ui = {\r\n\t\tnotify(message, type) {\r\n\t\t\tnotifications.push({ message, type });\r\n\t\t},\r\n\t\tsetStatus(key, text) {\r\n\t\t\tstatuses.push({ key, text });\r\n\t\t},\r\n\t};\r\n\tconst ctx = {\r\n\t\tui,\r\n\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\r\n\t\tshutdown() {\r\n\t\t\tshutdowns += 1;\r\n\t\t},\r\n\t};\r\n\tconst pi = {\r\n\t\tlogger: {\r\n\t\t\terror(message, details) {\r\n\t\t\t\terrors.push({ message, details });\r\n\t\t\t},\r\n\t\t\tdebug(message, details) {\r\n\t\t\t\tdebug.push({ message, details });\r\n\t\t\t},\r\n\t\t},\r\n\t\ton(name, handler) {\r\n\t\t\tconst registered = handlers.get(name) ?? [];\r\n\t\t\tregistered.push(handler);\r\n\t\t\thandlers.set(name, registered);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r\n\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\r\n\r\n\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\r\n\tconst partial = drainEvents(`noise${partialEnvelope}`);\r\n\tassert.deepEqual(partial.events, []);\r\n\tassert.equal(partial.rest, partialEnvelope);\r\n\r\n\tconst envelope = `${partial.rest}rld</EVENT>`;\r\n\tconst complete = drainEvents(`${envelope}<EVENT type=\"notify\">skip</EVENT>`);\r\n\tassert.deepEqual(complete.events, [\r\n\t\t{ from: \"doyle\", body: \"hello\\nworld\", envelope },\r\n\t]);\r\n\tassert.equal(complete.rest, \"\");\r\n\r\n\tconst truncatedA =\r\n\t\t'<EVENT type=\"msg\" from=\"a\">truncated<EVENT type=\"msg\" from=\"b\">valid</EVENT>';\r\n\tconst nested = drainEvents(truncatedA);\r\n\tassert.deepEqual(nested.events, []);\r\n\tassert.equal(nested.rest, truncatedA);\r\n\tassert.match(nested.error.message, /nested EVENT/);\r\n\tassert.match(\r\n\t\tdrainEvents('<EVENT type=\"msg\">missing sender</EVENT>').error.message,\r\n\t\t/missing EVENT from/,\r\n\t);\r\n\tassert.match(\r\n\t\tdrainEvents('<EVENT type=msg from=\"a\">bad attrs</EVENT>').error.message,\r\n\t\t/malformed EVENT attributes/,\r\n\t);\r\n\tassert.match(\r\n\t\tdrainEvents('<EVENT type=\"msg\" from=\"a\">0123456789</EVENT>', {\r\n\t\t\tmaxFrameChars: 32,\r\n\t\t}).error.message,\r\n\t\t/EVENT frame exceeded/,\r\n\t);\r\n\r\n\tassert.equal(\r\n\t\textractReply([\r\n\t\t\t{ role: \"assistant\", content: [{ type: \"text\", text: \"first\" }] },\r\n\t\t\t{ role: \"toolResult\", content: [] },\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: [\r\n\t\t\t\t\t{ type: \"text\", text: \"final \" },\r\n\t\t\t\t\t{ type: \"text\", text: \"answer\" },\r\n\t\t\t\t],\r\n\t\t\t},\r\n\t\t]),\r\n\t\t\"final answer\",\r\n\t);\r\n\tassert.equal(\r\n\t\textractReply(\r\n\t\t\t[\r\n\t\t\t\t{ role: \"assistant\", content: \"stale answer\" },\r\n\t\t\t\t{ role: \"user\", content: '<msg from=\"doyle\"/>' },\r\n\t\t\t],\r\n\t\t\t'<msg from=\"doyle\"/>',\r\n\t\t),\r\n\t\t\"\",\r\n\t);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-SESSION-IMMUTABLE]\r\n// [unit->REQ-OMP-MESSAGE-CONTEXT]\r\n// [unit->REQ-OMP-NATIVE-TUI]\r\nasync function testLifecycleCustodyAndContext() {\r\n\tconst harness = createHarness({ subnet: \"mesh-a\" });\r\n\tassert.deepEqual([...harness.handlers.keys()], [\r\n\t\t\"session_start\",\r\n\t\t\"session_before_switch\",\r","truncated":true,"truncatedBy":"lines","totalLines":1378,"totalBytes":7575,"outputLines":288,"outputBytes":7575,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"import assert from \"node:assert/strict\";\r\nimport { EventEmitter } from \"node:events\";\r\nimport {\r\n\tcreateOmpSpt,\r\n\tdecodeBody,\r\n\tdrainEvents,\r\n\textractReply,\r\n\trunSpt,\r\n} from \"../adapter/strings/omp-spt.mjs\";\r\n\r\nconst flush = () => new Promise((resolve) => setImmediate(resolve));\r\nfunction deferred() {\r\n\tlet resolve;\r\n\tlet reject;\r\n\tconst promise = new Promise((resolvePromise, rejectPromise) => {\r\n\t\tresolve = resolvePromise;\r\n\t\treject = rejectPromise;\r\n\t});\r\n\treturn { promise, reject, resolve };\r\n}\r\n\r\nclass FakeStream extends EventEmitter {\r\n\tsetEncoding(encoding) {\r\n\t\tthis.encoding = encoding;\r\n\t}\r\n\r\n\tend(input) {\r\n\t\tthis.input = input;\r\n\t\tif (this.onEnd?.(input) === false) return;\r\n\t\tthis.emit(\"finish\");\r\n\t}\r\n}\r\n\r\nclass FakeChild extends EventEmitter {\r\n\tconstructor(options = {}) {\r\n\t\tsuper();\r\n\t\tthis.stdin = new FakeStream();\r\n\t\tthis.stdout = new FakeStream();\r\n\t\tthis.stderr = new FakeStream();\r\n\t\tthis.exitCode = null;\r\n\t\tthis.signalCode = null;\r\n\t\tthis.kills = 0;\r\n\t\tthis.killSignals = [];\r\n\t\tthis.onKill = options.onKill;\r\n\t}\r\n\r\n\tclose(code = 0, signal = null) {\r\n\t\tthis.exitCode = code;\r\n\t\tthis.signalCode = signal;\r\n\t\tthis.emit(\"close\", code, signal);\r\n\t}\r\n\r\n\tkill(signal = \"SIGTERM\") {\r\n\t\tthis.kills += 1;\r\n\t\tthis.killSignals.push(signal);\r\n\t\tconst handled = this.onKill?.(signal, this);\r\n\t\tif (handled !== undefined) return handled;\r\n\t\tthis.close(null, signal);\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nclass FakeClock {\r\n\tconstructor() {\r\n\t\tthis.nextId = 1;\r\n\t\tthis.timers = new Map();\r\n\t}\r\n\r\n\tsetTimeout(fn, delay) {\r\n\t\tconst handle = { id: this.nextId++, unref() {} };\r\n\t\tthis.timers.set(handle, { fn, delay });\r\n\t\treturn handle;\r\n\t}\r\n\r\n\tclearTimeout(handle) {\r\n\t\tthis.timers.delete(handle);\r\n\t}\r\n\r\n\tdelays() {\r\n\t\treturn [...this.timers.values()].map(({ delay }) => delay);\r\n\t}\r\n\r\n\tasync runNext(expectedDelay) {\r\n\t\tconst entry = [...this.timers.entries()].sort((left, right) => left[1].delay - right[1].delay)[0];\r\n\t\tassert.ok(entry, `expected a ${expectedDelay}ms timer`);\r\n\t\tconst [handle, timer] = entry;\r\n\t\tassert.equal(timer.delay, expectedDelay);\r\n\t\tthis.timers.delete(handle);\r\n\t\ttimer.fn();\r\n\t\tawait flush();\r\n\t}\r\n}\r\n\r\nfunction createHarness(options = {}) {\r\n\tconst handlers = new Map();\r\n\tconst calls = [];\r\n\tconst children = [];\r\n\tconst submitted = [];\r\n\tconst statuses = [];\r\n\tconst notifications = [];\r\n\tconst errors = [];\r\n\tconst debug = [];\r\n\tconst clock = new FakeClock();\r\n\tlet shutdowns = 0;\r\n\r\n\tconst ui = {\r\n\t\tnotify(message, type) {\r\n\t\t\tnotifications.push({ message, type });\r\n\t\t},\r\n\t\tsetStatus(key, text) {\r\n\t\t\tstatuses.push({ key, text });\r\n\t\t},\r\n\t};\r\n\tconst ctx = {\r\n\t\tui,\r\n\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\r\n\t\tshutdown() {\r\n\t\t\tshutdowns += 1;\r\n\t\t},\r\n\t};\r\n\tconst pi = {\r\n\t\tlogger: {\r\n\t\t\terror(message, details) {\r\n\t\t\t\terrors.push({ message, details });\r\n\t\t\t},\r\n\t\t\tdebug(message, details) {\r\n\t\t\t\tdebug.push({ message, details });\r\n\t\t\t},\r\n\t\t},\r\n\t\ton(name, handler) {\r\n\t\t\tconst registered = handlers.get(name) ?? [];\r\n\t\t\tregistered.push(handler);\r\n\t\t\thandlers.set(name, registered);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r\n\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\r\n\r\n\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\r\n\tconst partial = drainEvents(`noise${partialEnvelope}`);\r\n\tassert.deepEqual(partial.events, []);\r\n\tassert.equal(partial.rest, partialEnvelope);\r\n\r\n\tconst envelope = `${partial.rest}rld</EVENT>`;\r\n\tconst complete = drainEvents(`${envelope}<EVENT type=\"notify\">skip</EVENT>`);\r\n\tassert.deepEqual(complete.events, [\r\n\t\t{ from: \"doyle\", body: \"hello\\nworld\", envelope },\r\n\t]);\r\n\tassert.equal(complete.rest, \"\");\r\n\r\n\tconst truncatedA =\r\n\t\t'<EVENT type=\"msg\" from=\"a\">truncated<EVENT type=\"msg\" from=\"b\">valid</EVENT>';\r\n\tconst nested = drainEvents(truncatedA);\r\n\tassert.deepEqual(nested.events, []);\r\n\tassert.equal(nested.rest, truncatedA);\r\n\tassert.match(nested.error.message, /nested EVENT/);\r\n\tassert.match(\r\n\t\tdrainEvents('<EVENT type=\"msg\">missing sender</EVENT>').error.message,\r\n\t\t/missing EVENT from/,\r\n\t);\r\n\tassert.match(\r\n\t\tdrainEvents('<EVENT type=msg from=\"a\">bad attrs</EVENT>').error.message,\r\n\t\t/malformed EVENT attributes/,\r\n\t);\r\n\tassert.match(\r\n\t\tdrainEvents('<EVENT type=\"msg\" from=\"a\">0123456789</EVENT>', {\r\n\t\t\tmaxFrameChars: 32,\r\n\t\t}).error.message,\r\n\t\t/EVENT frame exceeded/,\r\n\t);\r\n\r\n\tassert.equal(\r\n\t\textractReply([\r\n\t\t\t{ role: \"assistant\", content: [{ type: \"text\", text: \"first\" }] },\r\n\t\t\t{ role: \"toolResult\", content: [] },\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: [\r\n\t\t\t\t\t{ type: \"text\", text: \"final \" },\r\n\t\t\t\t\t{ type: \"text\", text: \"answer\" },\r\n\t\t\t\t],\r\n\t\t\t},\r\n\t\t]),\r\n\t\t\"final answer\",\r\n\t);\r\n\tassert.equal(\r\n\t\textractReply(\r\n\t\t\t[\r\n\t\t\t\t{ role: \"assistant\", content: \"stale answer\" },\r\n\t\t\t\t{ role: \"user\", content: '<msg from=\"doyle\"/>' },\r\n\t\t\t],\r\n\t\t\t'<msg from=\"doyle\"/>',\r\n\t\t),\r\n\t\t\"\",\r\n\t);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-SESSION-IMMUTABLE]\r\n// [unit->REQ-OMP-MESSAGE-CONTEXT]\r\n// [unit->REQ-OMP-NATIVE-TUI]\r\nasync function testLifecycleCustodyAndContext() {\r\n\tconst harness = createHarness({ subnet: \"mesh-a\" });\r\n\tassert.deepEqual([...harness.handlers.keys()], [\r\n\t\t\"session_start\",\r\n\t\t\"session_before_switch\",\r\n…\n\t]);\n…\n}","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,null,295,null,423]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1378,"totalBytes":7575,"outputLines":288,"outputBytes":7575,"shownRange":{"start":1,"end":288},"nextOffset":289}}},"isError":false,"timestamp":1784188876294}}
{"type":"message","id":"48fd4e09","parentId":"dad383d8","timestamp":"2026-07-16T08:01:16.306Z","message":{"role":"toolResult","toolCallId":"call_oFqdaT5FTnmw2hVGwvIsMj0N|fc_03e5b91f227b0634016a588fcc2f7c819bbab4f631a28b4b8f","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#8FB4]\n279:\n280:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n281:// [unit->REQ-OMP-SESSION-IMMUTABLE]\n282:// [unit->REQ-OMP-MESSAGE-CONTEXT]\n283:// [unit->REQ-OMP-NATIVE-TUI]\n284:async function testLifecycleCustodyAndContext() {\n285:\tconst harness = createHarness({ subnet: \"mesh-a\" });\n286:\tassert.deepEqual([...harness.handlers.keys()], [\n287:\t\t\"session_start\",\n288:\t\t\"session_before_switch\",\n289:\t\t\"session_before_branch\",\n290:\t\t\"context\",\n291:\t\t\"agent_start\",\n292:\t\t\"agent_end\",\n293:\t\t\"session_stop\",\n294:\t\t\"session_shutdown\",\n295:\t]);\n296:\n297:\tawait harness.emit(\"session_start\");\n298:\tassert.deepEqual(harness.calls[0], {\n299:\t\targs: [\n300:\t\t\t\"api\",\n301:\t\t\t\"--adapter\",\n302:\t\t\t\"omp-spt\",\n303:\t\t\t\"bind\",\n304:\t\t\t\"omp-agent\",\n305:\t\t\t\"--set-session-id\",\n306:\t\t\t\"session-1\",\n307:\t\t\t\"--subnet\",\n308:\t\t\t\"mesh-a\",\n309:\t\t],\n310:\t\tinput: undefined,\n311:\t});\n312:\tassert.deepEqual(harness.calls[1].args, [\n313:\t\t\"api\",\n314:\t\t\"--adapter\",\n315:\t\t\"omp-spt\",\n316:\t\t\"state\",\n317:\t\t\"idle\",\n318:\t\t\"omp-agent\",\n319:\t\t\"--token\",\n320:\t\t\"token-123\",\n321:\t]);\n322:\tassert.equal(harness.children.length, 1);\n323:\tassert.equal(harness.children[0].binary, \"spt-test\");\n324:\tassert.deepEqual(harness.children[0].args, [\n325:\t\t\"api\",\n326:\t\t\"--adapter\",\n327:\t\t\"omp-spt\",\n328:\t\t\"listen\",\n329:\t\t\"omp-agent\",\n330:\t\t\"--session-id\",\n331:\t\t\"session-1\",\n332:\t\t\"--subnet\",\n333:\t\t\"mesh-a\",\n334:\t]);\n335:\n336:\tfor (const reason of [\"new\", \"resume\", \"fork\", \"handoff\"]) {\n337:\t\tassert.deepEqual(await harness.emit(\"session_before_switch\", { reason }), { cancel: true });\n338:\t\tassert.ok(\n339:\t\t\tharness.notifications.some(({ message }) =>\n340:\t\t\t\tmessage.includes(`${reason} session switch`),\n341:\t\t\t),\n342:\t\t);\n343:\t}\n344:\tassert.deepEqual(await harness.emit(\"session_before_branch\"), { cancel: true });\n345:\tassert.ok(\n346:\t\tharness.notifications.some(({ message }) => message.includes(\"session branch\")),\n347:\t);\n348:\n349:\tconst aliceEnvelope =\n350:\t\t'<EVENT type=\"msg\" from=\"alice\" event_id=\"evt-1\">hello&lt;world<br>line</EVENT>';\n351:\tconst bobEnvelope = '<EVENT type=\"msg\" from=\"bob\" event_id=\"evt-2\">second</EVENT>';\n352:\tharness.children[0].stdout.emit(\"data\", `${aliceEnvelope}${bobEnvelope}`);\n353:\tawait flush();\n354:\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>']);\n355:\tassert.deepEqual(\n356:\t\tstateCalls(harness).map((call) => call.args[4]),\n357:\t\t[\"idle\", \"busy\"],\n358:\t);\n359:\n360:\tconst originalMessages = [{ role: \"user\", content: '<msg from=\"alice\"/>' }];\n361:\tconst context = await harness.emit(\"context\", { messages: originalMessages });\n362:\tassert.equal(originalMessages[0].content, '<msg from=\"alice\"/>');\n363:\tassert.equal(context.messages[0].content, `<msg from=\"alice\"/>\\n\\n${aliceEnvelope}`);\n364:\n365:\tconst arrayContext = await harness.emit(\"context\", {\n366:\t\tmessages: [{ role: \"user\", content: [{ type: \"text\", text: '<msg from=\"alice\"/>' }] }],\n367:\t});\n368:\tassert.deepEqual(arrayContext.messages[0].content, [\n369:\t\t{ type: \"text\", text: '<msg from=\"alice\"/>' },\n370:\t\t{ type: \"text\", text: `\\n\\n${aliceEnvelope}` },\n371:\t]);\n372:\n373:\tawait harness.emit(\"agent_start\");\n374:\tassert.deepEqual(\n375:\t\tstateCalls(harness).map((call) => call.args[4]),\n376:\t\t[\"idle\", \"busy\"],\n377:\t\t\"agent_start must not duplicate the already-honest busy transition\",\n378:\t);\n379:\tawait harness.emit(\"agent_end\", {\n380:\t\tmessages: [\n381:\t\t\t{ role: \"user\", content: '<msg from=\"alice\"/>' },\n382:\t\t\t{ role: \"assistant\", content: [{ type: \"text\", text: \"alice reply\" }] },\n383:\t\t],\n384:\t});\n385:\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>']);\n386:\tassert.deepEqual(harness.clock.delays(), [0]);\n387:\n388:\tawait harness.clock.runNext(0);\n389:\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>', '<msg from=\"bob\"/>']);\n390:\tawait harness.emit(\"agent_start\");\n391:\tawait harness.emit(\"agent_end\", {\n392:\t\tmessages: [\n393:\t\t\t{ role: \"assistant\", content: \"previous reply\" },\n394:\t\t\t{ role: \"user\", content: '<msg from=\"bob\"/>' },\n395:\t\t],\n396:\t});\n397:\n398:\tconst outcomes = commandCalls(harness, \"send\");\n399:\tassert.equal(outcomes.length, 2);\n400:\tassert.deepEqual(\n401:\t\toutcomes.map((call) => call.args),\n402:\t\t[\n403:\t\t\t[\"send\", \"alice\", \"--from\", \"omp-agent\"],\n404:\t\t\t[\"send\", \"bob\", \"--from\", \"omp-agent\"],\n405:\t\t],\n406:\t);\n407:\tassert.equal(outcomes[0].input, \"alice reply\");\n408:\tassert.match(outcomes[1].input, /turn ended without an assistant response/);\n409:\tassert.deepEqual(\n410:\t\tstateCalls(harness).map((call) => call.args[4]),\n411:\t\t[\"idle\", \"busy\", \"idle\", \"busy\", \"idle\"],\n412:\t);\n413:\tfor (const call of [...stateCalls(harness), ...harness.calls.filter((candidate) => candidate.args[3] === \"session-end\")]) {\n414:\t\tassert.deepEqual(call.args.slice(-2), [\"--token\", \"token-123\"]);\n415:\t}\n416:\n417:\tawait harness.emit(\"session_shutdown\");\n418:\tconst ended = harness.calls.filter((call) => call.args[3] === \"session-end\");\n419:\tassert.equal(ended.length, 1);\n420:\tassert.deepEqual(ended[0].args.slice(-2), [\"--token\", \"token-123\"]);\n421:\tassert.equal(harness.children[0].kills, 1);\n422:\tassert.deepEqual(harness.clock.delays(), []);\n423:}\n424:\n425:async function testDeferredBindLifecycleSerialization() {\n426:\tconst busyBind = deferred();\n427:\tconst busyHarness = createHarness({\n428:\t\tonRun(call) {\n429:\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return busyBind.promise;\n430:\t\t},\n431:\t});\n432:\tconst startingBusy = busyHarness.emit(\"session_start\");\n433:\tawait flush();\n434:\tconst becomingBusy = busyHarness.emit(\"agent_start\");\n435:\tawait flush();\n436:\tassert.deepEqual(stateCalls(busyHarness), []);\n437:\tassert.equal(busyHarness.children.length, 0);\n438:\n439:\tbusyBind.resolve(\"BOUND endpoint token=token-busy\");\n440:\tawait Promise.all([startingBusy, becomingBusy]);\n441:\tassert.deepEqual(\n442:\t\tstateCalls(busyHarness).map((call) => call.args[4]),\n443:\t\t[\"busy\"],\n444:\t\t\"agent_start before bind completion must suppress the stale idle publication\",\n445:\t);\n446:\tassert.equal(busyHarness.children.length, 1);\n447:\tawait busyHarness.emit(\"session_shutdown\");\n448:\tassert.deepEqual(busyHarness.clock.delays(), []);\n449:\n450:\tconst shutdownBind = deferred();\n451:\tconst shutdownHarness = createHarness({\n452:\t\tonRun(call) {\n453:\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return shutdownBind.promise;\n454:\t\t},\n455:\t});\n456:\tconst startingShutdown = shutdownHarness.emit(\"session_start\");\n457:\tawait flush();\n458:\tconst shuttingDown = shutdownHarness.emit(\"session_shutdown\");\n459:\tawait flush();\n460:\tassert.equal(shutdownHarness.children.length, 0);\n461:\tassert.equal(\n462:\t\tshutdownHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\n463:\t\t0,\n464:\t);\n465:\n466:\tshutdownBind.resolve(\"BOUND endpoint token=token-shutdown\");\n467:\tawait Promise.all([startingShutdown, shuttingDown]);\n468:\tassert.deepEqual(stateCalls(shutdownHarness), []);\n469:\tassert.equal(shutdownHarness.children.length, 0);\n470:\tassert.equal(\n471:\t\tshutdownHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\n472:\t\t1,\n473:\t);\n474:\tassert.ok(\n475:\t\t!shutdownHarness.statuses.some(({ text }) => text === \"spt:omp-agent\"),\n476:\t\t\"bind completion after shutdown must not restore live status\",\n477:\t);\n478:\tassert.deepEqual(shutdownHarness.clock.delays(), []);\n479:\n480:\tconst hungBindHarness = createHarness({\n481:\t\tonRun(call) {\n482:\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return new Promise(() => {});\n483:\t\t},\n484:\t});\n485:\tconst hungStart = hungBindHarness.emit(\"session_start\");\n486:\tawait flush();\n487:\tconst hungShutdown = hungBindHarness.emit(\"session_shutdown\");\n488:\tawait flush();\n489:\tassert.deepEqual(hungBindHarness.clock.delays().sort((a, b) => a - b), [300, 1_800]);\n490:\tawait hungBindHarness.clock.runNext(300);\n491:\tawait Promise.all([hungStart, hungShutdown]);\n492:\tassert.equal(hungBindHarness.children.length, 0);\n493:\tassert.equal(\n494:\t\thungBindHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\n495:\t\t0,\n496:\t\t\"session-end cannot run without a completed bind token\",\n497:\t);\n498:\tassert.deepEqual(hungBindHarness.clock.delays(), []);\n499:}\n500:\n501:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n502:// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\n503:async function testOutcomeSendRetriesAndExhaustion() {\n504:\tlet retryAttempts = 0;\n505:\tconst retryHarness = createHarness({\n506:\t\toutcomeRetryDelaysMs: [5, 10],\n507:\t\tonRun(call) {\n508:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"retry\") {\n509:\t\t\t\tretryAttempts += 1;\n510:\t\t\t\tif (retryAttempts < 3) throw new Error(`outcome failure ${retryAttempts}`);\n511:\t\t\t}\n512:\t\t},\n513:\t});\n514:\tawait retryHarness.emit(\"session_start\");\n515:\tretryHarness.children[0].stdout.emit(\n516:\t\t\"data\",\n517:\t\t'<EVENT type=\"msg\" from=\"retry\">work</EVENT>',\n518:\t);\n519:\tawait flush();\n520:\tawait retryHarness.emit(\"agent_start\");\n521:\tconst retryEnding = retryHarness.emit(\"agent_end\", {\n522:\t\tmessages: [\n523:\t\t\t{ role: \"user\", content: '<msg from=\"retry\"/>' },\n524:\t\t\t{ role: \"assistant\", content: \"eventual outcome\" },\n525:\t\t],\n526:\t});\n527:\tawait flush();\n528:\tassert.equal(commandCalls(retryHarness, \"send\").length, 1);\n529:\tassert.deepEqual(retryHarness.clock.delays(), [5]);\n530:\tawait retryHarness.clock.runNext(5);\n531:\tassert.equal(commandCalls(retryHarness, \"send\").length, 2);\n532:\tassert.deepEqual(retryHarness.clock.delays(), [10]);\n533:\tawait retryHarness.clock.runNext(10);\n534:\tawait retryEnding;\n535:\tassert.equal(commandCalls(retryHarness, \"send\").length, 3);\n536:\tassert.equal(commandCalls(retryHarness, \"send\").at(-1).input, \"eventual outcome\");\n537:\tassert.equal(retryHarness.shutdowns, 0);\n538:\tawait retryHarness.emit(\"session_shutdown\");\n539:\tassert.deepEqual(retryHarness.clock.delays(), []);\n540:\n541:\tconst exhaustedHarness = createHarness({\n542:\t\toutcomeRetryDelaysMs: [7],\n543:\t\tonRun(call) {\n544:\t\t\tif (call.args[0] === \"send\") throw new Error(\"outcome channel unavailable\");\n545:\t\t},\n546:\t});\n547:\tawait exhaustedHarness.emit(\"session_start\");\n548:\tconst exhaustedListener = exhaustedHarness.children[0];\n549:\texhaustedListener.stdout.emit(\n550:\t\t\"data\",\n551:\t\t'<EVENT type=\"msg\" from=\"exhausted\">work</EVENT>',\n552:\t);\n553:\tawait flush();\n554:\tawait exhaustedHarness.emit(\"agent_start\");\n555:\tconst exhaustedEnding = exhaustedHarness.emit(\"agent_end\", {\n556:\t\tmessages: [\n557:\t\t\t{ role: \"user\", content: '<msg from=\"exhausted\"/>' },\n558:\t\t\t{ role: \"assistant\", content: \"undeliverable outcome\" },\n559:\t\t],\n560:\t});\n561:\tawait flush();\n562:\tassert.equal(commandCalls(exhaustedHarness, \"send\").length, 1);\n563:\tassert.deepEqual(exhaustedHarness.clock.delays(), [7]);\n564:\tawait exhaustedHarness.clock.runNext(7);\n565:\tawait exhaustedEnding;\n566:\n567:\tassert.equal(commandCalls(exhaustedHarness, \"send\").length, 2);\n568:\tassert.deepEqual(\n569:\t\tstateCalls(exhaustedHarness).map((call) => call.args[4]),\n570:\t\t[\"idle\", \"busy\"],\n571:\t\t\"exhausted custody must never be advertised idle\",\n572:\t);\n573:\tassert.equal(exhaustedHarness.shutdowns, 1);\n574:\tassert.equal(exhaustedListener.kills, 1);\n575:\tassert.equal(\n576:\t\texhaustedHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\n577:\t\t1,\n578:\t);\n579:\tassert.ok(\n580:\t\texhaustedHarness.errors.some(({ message }) =>\n581:\t\t\tmessage.includes(\"could not send the outcome to exhausted\"),\n582:\t\t),\n583:\t);\n584:\tawait exhaustedHarness.emit(\"session_shutdown\");\n585:\tassert.deepEqual(exhaustedHarness.clock.delays(), []);\n586:}\n587:\n588:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n589:async function testSubmissionFailureAdvancesQueue() {\n590:\tconst harness = createHarness({\n591:\t\tonSubmit(content) {\n592:\t\t\tif (content === '<msg from=\"broken\"/>') throw new Error(\"OMP prompt flow rejected input\");\n593:\t\t},\n594:\t});\n…\n626:}\n\n[Showing lines 279-593 of 1378. Use :594 to continue]"}],"details":{"truncation":{"content":"\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-SESSION-IMMUTABLE]\r\n// [unit->REQ-OMP-MESSAGE-CONTEXT]\r\n// [unit->REQ-OMP-NATIVE-TUI]\r\nasync function testLifecycleCustodyAndContext() {\r\n\tconst harness = createHarness({ subnet: \"mesh-a\" });\r\n\tassert.deepEqual([...harness.handlers.keys()], [\r\n\t\t\"session_start\",\r\n\t\t\"session_before_switch\",\r\n\t\t\"session_before_branch\",\r\n\t\t\"context\",\r\n\t\t\"agent_start\",\r\n\t\t\"agent_end\",\r\n\t\t\"session_stop\",\r\n\t\t\"session_shutdown\",\r\n\t]);\r\n\r\n\tawait harness.emit(\"session_start\");\r\n\tassert.deepEqual(harness.calls[0], {\r\n\t\targs: [\r\n\t\t\t\"api\",\r\n\t\t\t\"--adapter\",\r\n\t\t\t\"omp-spt\",\r\n\t\t\t\"bind\",\r\n\t\t\t\"omp-agent\",\r\n\t\t\t\"--set-session-id\",\r\n\t\t\t\"session-1\",\r\n\t\t\t\"--subnet\",\r\n\t\t\t\"mesh-a\",\r\n\t\t],\r\n\t\tinput: undefined,\r\n\t});\r\n\tassert.deepEqual(harness.calls[1].args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"state\",\r\n\t\t\"idle\",\r\n\t\t\"omp-agent\",\r\n\t\t\"--token\",\r\n\t\t\"token-123\",\r\n\t]);\r\n\tassert.equal(harness.children.length, 1);\r\n\tassert.equal(harness.children[0].binary, \"spt-test\");\r\n\tassert.deepEqual(harness.children[0].args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"listen\",\r\n\t\t\"omp-agent\",\r\n\t\t\"--session-id\",\r\n\t\t\"session-1\",\r\n\t\t\"--subnet\",\r\n\t\t\"mesh-a\",\r\n\t]);\r\n\r\n\tfor (const reason of [\"new\", \"resume\", \"fork\", \"handoff\"]) {\r\n\t\tassert.deepEqual(await harness.emit(\"session_before_switch\", { reason }), { cancel: true });\r\n\t\tassert.ok(\r\n\t\t\tharness.notifications.some(({ message }) =>\r\n\t\t\t\tmessage.includes(`${reason} session switch`),\r\n\t\t\t),\r\n\t\t);\r\n\t}\r\n\tassert.deepEqual(await harness.emit(\"session_before_branch\"), { cancel: true });\r\n\tassert.ok(\r\n\t\tharness.notifications.some(({ message }) => message.includes(\"session branch\")),\r\n\t);\r\n\r\n\tconst aliceEnvelope =\r\n\t\t'<EVENT type=\"msg\" from=\"alice\" event_id=\"evt-1\">hello&lt;world<br>line</EVENT>';\r\n\tconst bobEnvelope = '<EVENT type=\"msg\" from=\"bob\" event_id=\"evt-2\">second</EVENT>';\r\n\tharness.children[0].stdout.emit(\"data\", `${aliceEnvelope}${bobEnvelope}`);\r\n\tawait flush();\r\n\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>']);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(harness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\"],\r\n\t);\r\n\r\n\tconst originalMessages = [{ role: \"user\", content: '<msg from=\"alice\"/>' }];\r\n\tconst context = await harness.emit(\"context\", { messages: originalMessages });\r\n\tassert.equal(originalMessages[0].content, '<msg from=\"alice\"/>');\r\n\tassert.equal(context.messages[0].content, `<msg from=\"alice\"/>\\n\\n${aliceEnvelope}`);\r\n\r\n\tconst arrayContext = await harness.emit(\"context\", {\r\n\t\tmessages: [{ role: \"user\", content: [{ type: \"text\", text: '<msg from=\"alice\"/>' }] }],\r\n\t});\r\n\tassert.deepEqual(arrayContext.messages[0].content, [\r\n\t\t{ type: \"text\", text: '<msg from=\"alice\"/>' },\r\n\t\t{ type: \"text\", text: `\\n\\n${aliceEnvelope}` },\r\n\t]);\r\n\r\n\tawait harness.emit(\"agent_start\");\r\n\tassert.deepEqual(\r\n\t\tstateCalls(harness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\"],\r\n\t\t\"agent_start must not duplicate the already-honest busy transition\",\r\n\t);\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"user\", content: '<msg from=\"alice\"/>' },\r\n\t\t\t{ role: \"assistant\", content: [{ type: \"text\", text: \"alice reply\" }] },\r\n\t\t],\r\n\t});\r\n\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>']);\r\n\tassert.deepEqual(harness.clock.delays(), [0]);\r\n\r\n\tawait harness.clock.runNext(0);\r\n\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>', '<msg from=\"bob\"/>']);\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"assistant\", content: \"previous reply\" },\r\n\t\t\t{ role: \"user\", content: '<msg from=\"bob\"/>' },\r\n\t\t],\r\n\t});\r\n\r\n\tconst outcomes = commandCalls(harness, \"send\");\r\n\tassert.equal(outcomes.length, 2);\r\n\tassert.deepEqual(\r\n\t\toutcomes.map((call) => call.args),\r\n\t\t[\r\n\t\t\t[\"send\", \"alice\", \"--from\", \"omp-agent\"],\r\n\t\t\t[\"send\", \"bob\", \"--from\", \"omp-agent\"],\r\n\t\t],\r\n\t);\r\n\tassert.equal(outcomes[0].input, \"alice reply\");\r\n\tassert.match(outcomes[1].input, /turn ended without an assistant response/);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(harness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\", \"idle\", \"busy\", \"idle\"],\r\n\t);\r\n\tfor (const call of [...stateCalls(harness), ...harness.calls.filter((candidate) => candidate.args[3] === \"session-end\")]) {\r\n\t\tassert.deepEqual(call.args.slice(-2), [\"--token\", \"token-123\"]);\r\n\t}\r\n\r\n\tawait harness.emit(\"session_shutdown\");\r\n\tconst ended = harness.calls.filter((call) => call.args[3] === \"session-end\");\r\n\tassert.equal(ended.length, 1);\r\n\tassert.deepEqual(ended[0].args.slice(-2), [\"--token\", \"token-123\"]);\r\n\tassert.equal(harness.children[0].kills, 1);\r\n\tassert.deepEqual(harness.clock.delays(), []);\r\n}\r\n\r\nasync function testDeferredBindLifecycleSerialization() {\r\n\tconst busyBind = deferred();\r\n\tconst busyHarness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return busyBind.promise;\r\n\t\t},\r\n\t});\r\n\tconst startingBusy = busyHarness.emit(\"session_start\");\r\n\tawait flush();\r\n\tconst becomingBusy = busyHarness.emit(\"agent_start\");\r\n\tawait flush();\r\n\tassert.deepEqual(stateCalls(busyHarness), []);\r\n\tassert.equal(busyHarness.children.length, 0);\r\n\r\n\tbusyBind.resolve(\"BOUND endpoint token=token-busy\");\r\n\tawait Promise.all([startingBusy, becomingBusy]);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(busyHarness).map((call) => call.args[4]),\r\n\t\t[\"busy\"],\r\n\t\t\"agent_start before bind completion must suppress the stale idle publication\",\r\n\t);\r\n\tassert.equal(busyHarness.children.length, 1);\r\n\tawait busyHarness.emit(\"session_shutdown\");\r\n\tassert.deepEqual(busyHarness.clock.delays(), []);\r\n\r\n\tconst shutdownBind = deferred();\r\n\tconst shutdownHarness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return shutdownBind.promise;\r\n\t\t},\r\n\t});\r\n\tconst startingShutdown = shutdownHarness.emit(\"session_start\");\r\n\tawait flush();\r\n\tconst shuttingDown = shutdownHarness.emit(\"session_shutdown\");\r\n\tawait flush();\r\n\tassert.equal(shutdownHarness.children.length, 0);\r\n\tassert.equal(\r\n\t\tshutdownHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t0,\r\n\t);\r\n\r\n\tshutdownBind.resolve(\"BOUND endpoint token=token-shutdown\");\r\n\tawait Promise.all([startingShutdown, shuttingDown]);\r\n\tassert.deepEqual(stateCalls(shutdownHarness), []);\r\n\tassert.equal(shutdownHarness.children.length, 0);\r\n\tassert.equal(\r\n\t\tshutdownHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t1,\r\n\t);\r\n\tassert.ok(\r\n\t\t!shutdownHarness.statuses.some(({ text }) => text === \"spt:omp-agent\"),\r\n\t\t\"bind completion after shutdown must not restore live status\",\r\n\t);\r\n\tassert.deepEqual(shutdownHarness.clock.delays(), []);\r\n\r\n\tconst hungBindHarness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return new Promise(() => {});\r\n\t\t},\r\n\t});\r\n\tconst hungStart = hungBindHarness.emit(\"session_start\");\r\n\tawait flush();\r\n\tconst hungShutdown = hungBindHarness.emit(\"session_shutdown\");\r\n\tawait flush();\r\n\tassert.deepEqual(hungBindHarness.clock.delays().sort((a, b) => a - b), [300, 1_800]);\r\n\tawait hungBindHarness.clock.runNext(300);\r\n\tawait Promise.all([hungStart, hungShutdown]);\r\n\tassert.equal(hungBindHarness.children.length, 0);\r\n\tassert.equal(\r\n\t\thungBindHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t0,\r\n\t\t\"session-end cannot run without a completed bind token\",\r\n\t);\r\n\tassert.deepEqual(hungBindHarness.clock.delays(), []);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\r\nasync function testOutcomeSendRetriesAndExhaustion() {\r\n\tlet retryAttempts = 0;\r\n\tconst retryHarness = createHarness({\r\n\t\toutcomeRetryDelaysMs: [5, 10],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"retry\") {\r\n\t\t\t\tretryAttempts += 1;\r\n\t\t\t\tif (retryAttempts < 3) throw new Error(`outcome failure ${retryAttempts}`);\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait retryHarness.emit(\"session_start\");\r\n\tretryHarness.children[0].stdout.emit(\r\n\t\t\"data\",\r\n\t\t'<EVENT type=\"msg\" from=\"retry\">work</EVENT>',\r\n\t);\r\n\tawait flush();\r\n\tawait retryHarness.emit(\"agent_start\");\r\n\tconst retryEnding = retryHarness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"user\", content: '<msg from=\"retry\"/>' },\r\n\t\t\t{ role: \"assistant\", content: \"eventual outcome\" },\r\n\t\t],\r\n\t});\r\n\tawait flush();\r\n\tassert.equal(commandCalls(retryHarness, \"send\").length, 1);\r\n\tassert.deepEqual(retryHarness.clock.delays(), [5]);\r\n\tawait retryHarness.clock.runNext(5);\r\n\tassert.equal(commandCalls(retryHarness, \"send\").length, 2);\r\n\tassert.deepEqual(retryHarness.clock.delays(), [10]);\r\n\tawait retryHarness.clock.runNext(10);\r\n\tawait retryEnding;\r\n\tassert.equal(commandCalls(retryHarness, \"send\").length, 3);\r\n\tassert.equal(commandCalls(retryHarness, \"send\").at(-1).input, \"eventual outcome\");\r\n\tassert.equal(retryHarness.shutdowns, 0);\r\n\tawait retryHarness.emit(\"session_shutdown\");\r\n\tassert.deepEqual(retryHarness.clock.delays(), []);\r\n\r\n\tconst exhaustedHarness = createHarness({\r\n\t\toutcomeRetryDelaysMs: [7],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\") throw new Error(\"outcome channel unavailable\");\r\n\t\t},\r\n\t});\r\n\tawait exhaustedHarness.emit(\"session_start\");\r\n\tconst exhaustedListener = exhaustedHarness.children[0];\r\n\texhaustedListener.stdout.emit(\r\n\t\t\"data\",\r\n\t\t'<EVENT type=\"msg\" from=\"exhausted\">work</EVENT>',\r\n\t);\r\n\tawait flush();\r\n\tawait exhaustedHarness.emit(\"agent_start\");\r\n\tconst exhaustedEnding = exhaustedHarness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"user\", content: '<msg from=\"exhausted\"/>' },\r\n\t\t\t{ role: \"assistant\", content: \"undeliverable outcome\" },\r\n\t\t],\r\n\t});\r\n\tawait flush();\r\n\tassert.equal(commandCalls(exhaustedHarness, \"send\").length, 1);\r\n\tassert.deepEqual(exhaustedHarness.clock.delays(), [7]);\r\n\tawait exhaustedHarness.clock.runNext(7);\r\n\tawait exhaustedEnding;\r\n\r\n\tassert.equal(commandCalls(exhaustedHarness, \"send\").length, 2);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(exhaustedHarness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\"],\r\n\t\t\"exhausted custody must never be advertised idle\",\r\n\t);\r\n\tassert.equal(exhaustedHarness.shutdowns, 1);\r\n\tassert.equal(exhaustedListener.kills, 1);\r\n\tassert.equal(\r\n\t\texhaustedHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t1,\r\n\t);\r\n\tassert.ok(\r\n\t\texhaustedHarness.errors.some(({ message }) =>\r\n\t\t\tmessage.includes(\"could not send the outcome to exhausted\"),\r\n\t\t),\r\n\t);\r\n\tawait exhaustedHarness.emit(\"session_shutdown\");\r\n\tassert.deepEqual(exhaustedHarness.clock.delays(), []);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\nasync function testSubmissionFailureAdvancesQueue() {\r\n\tconst harness = createHarness({\r\n\t\tonSubmit(content) {\r\n\t\t\tif (content === '<msg from=\"broken\"/>') throw new Error(\"OMP prompt flow rejected input\");\r\n\t\t},\r","truncated":true,"truncatedBy":"lines","totalLines":1100,"totalBytes":10672,"outputLines":315,"outputBytes":10672,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-SESSION-IMMUTABLE]\r\n// [unit->REQ-OMP-MESSAGE-CONTEXT]\r\n// [unit->REQ-OMP-NATIVE-TUI]\r\nasync function testLifecycleCustodyAndContext() {\r\n\tconst harness = createHarness({ subnet: \"mesh-a\" });\r\n\tassert.deepEqual([...harness.handlers.keys()], [\r\n\t\t\"session_start\",\r\n\t\t\"session_before_switch\",\r\n\t\t\"session_before_branch\",\r\n\t\t\"context\",\r\n\t\t\"agent_start\",\r\n\t\t\"agent_end\",\r\n\t\t\"session_stop\",\r\n\t\t\"session_shutdown\",\r\n\t]);\r\n\r\n\tawait harness.emit(\"session_start\");\r\n\tassert.deepEqual(harness.calls[0], {\r\n\t\targs: [\r\n\t\t\t\"api\",\r\n\t\t\t\"--adapter\",\r\n\t\t\t\"omp-spt\",\r\n\t\t\t\"bind\",\r\n\t\t\t\"omp-agent\",\r\n\t\t\t\"--set-session-id\",\r\n\t\t\t\"session-1\",\r\n\t\t\t\"--subnet\",\r\n\t\t\t\"mesh-a\",\r\n\t\t],\r\n\t\tinput: undefined,\r\n\t});\r\n\tassert.deepEqual(harness.calls[1].args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"state\",\r\n\t\t\"idle\",\r\n\t\t\"omp-agent\",\r\n\t\t\"--token\",\r\n\t\t\"token-123\",\r\n\t]);\r\n\tassert.equal(harness.children.length, 1);\r\n\tassert.equal(harness.children[0].binary, \"spt-test\");\r\n\tassert.deepEqual(harness.children[0].args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"listen\",\r\n\t\t\"omp-agent\",\r\n\t\t\"--session-id\",\r\n\t\t\"session-1\",\r\n\t\t\"--subnet\",\r\n\t\t\"mesh-a\",\r\n\t]);\r\n\r\n\tfor (const reason of [\"new\", \"resume\", \"fork\", \"handoff\"]) {\r\n\t\tassert.deepEqual(await harness.emit(\"session_before_switch\", { reason }), { cancel: true });\r\n\t\tassert.ok(\r\n\t\t\tharness.notifications.some(({ message }) =>\r\n\t\t\t\tmessage.includes(`${reason} session switch`),\r\n\t\t\t),\r\n\t\t);\r\n\t}\r\n\tassert.deepEqual(await harness.emit(\"session_before_branch\"), { cancel: true });\r\n\tassert.ok(\r\n\t\tharness.notifications.some(({ message }) => message.includes(\"session branch\")),\r\n\t);\r\n\r\n\tconst aliceEnvelope =\r\n\t\t'<EVENT type=\"msg\" from=\"alice\" event_id=\"evt-1\">hello&lt;world<br>line</EVENT>';\r\n\tconst bobEnvelope = '<EVENT type=\"msg\" from=\"bob\" event_id=\"evt-2\">second</EVENT>';\r\n\tharness.children[0].stdout.emit(\"data\", `${aliceEnvelope}${bobEnvelope}`);\r\n\tawait flush();\r\n\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>']);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(harness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\"],\r\n\t);\r\n\r\n\tconst originalMessages = [{ role: \"user\", content: '<msg from=\"alice\"/>' }];\r\n\tconst context = await harness.emit(\"context\", { messages: originalMessages });\r\n\tassert.equal(originalMessages[0].content, '<msg from=\"alice\"/>');\r\n\tassert.equal(context.messages[0].content, `<msg from=\"alice\"/>\\n\\n${aliceEnvelope}`);\r\n\r\n\tconst arrayContext = await harness.emit(\"context\", {\r\n\t\tmessages: [{ role: \"user\", content: [{ type: \"text\", text: '<msg from=\"alice\"/>' }] }],\r\n\t});\r\n\tassert.deepEqual(arrayContext.messages[0].content, [\r\n\t\t{ type: \"text\", text: '<msg from=\"alice\"/>' },\r\n\t\t{ type: \"text\", text: `\\n\\n${aliceEnvelope}` },\r\n\t]);\r\n\r\n\tawait harness.emit(\"agent_start\");\r\n\tassert.deepEqual(\r\n\t\tstateCalls(harness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\"],\r\n\t\t\"agent_start must not duplicate the already-honest busy transition\",\r\n\t);\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"user\", content: '<msg from=\"alice\"/>' },\r\n\t\t\t{ role: \"assistant\", content: [{ type: \"text\", text: \"alice reply\" }] },\r\n\t\t],\r\n\t});\r\n\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>']);\r\n\tassert.deepEqual(harness.clock.delays(), [0]);\r\n\r\n\tawait harness.clock.runNext(0);\r\n\tassert.deepEqual(harness.submitted, ['<msg from=\"alice\"/>', '<msg from=\"bob\"/>']);\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"assistant\", content: \"previous reply\" },\r\n\t\t\t{ role: \"user\", content: '<msg from=\"bob\"/>' },\r\n\t\t],\r\n\t});\r\n\r\n\tconst outcomes = commandCalls(harness, \"send\");\r\n\tassert.equal(outcomes.length, 2);\r\n\tassert.deepEqual(\r\n\t\toutcomes.map((call) => call.args),\r\n\t\t[\r\n\t\t\t[\"send\", \"alice\", \"--from\", \"omp-agent\"],\r\n\t\t\t[\"send\", \"bob\", \"--from\", \"omp-agent\"],\r\n\t\t],\r\n\t);\r\n\tassert.equal(outcomes[0].input, \"alice reply\");\r\n\tassert.match(outcomes[1].input, /turn ended without an assistant response/);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(harness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\", \"idle\", \"busy\", \"idle\"],\r\n\t);\r\n\tfor (const call of [...stateCalls(harness), ...harness.calls.filter((candidate) => candidate.args[3] === \"session-end\")]) {\r\n\t\tassert.deepEqual(call.args.slice(-2), [\"--token\", \"token-123\"]);\r\n\t}\r\n\r\n\tawait harness.emit(\"session_shutdown\");\r\n\tconst ended = harness.calls.filter((call) => call.args[3] === \"session-end\");\r\n\tassert.equal(ended.length, 1);\r\n\tassert.deepEqual(ended[0].args.slice(-2), [\"--token\", \"token-123\"]);\r\n\tassert.equal(harness.children[0].kills, 1);\r\n\tassert.deepEqual(harness.clock.delays(), []);\r\n}\r\n\r\nasync function testDeferredBindLifecycleSerialization() {\r\n\tconst busyBind = deferred();\r\n\tconst busyHarness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return busyBind.promise;\r\n\t\t},\r\n\t});\r\n\tconst startingBusy = busyHarness.emit(\"session_start\");\r\n\tawait flush();\r\n\tconst becomingBusy = busyHarness.emit(\"agent_start\");\r\n\tawait flush();\r\n\tassert.deepEqual(stateCalls(busyHarness), []);\r\n\tassert.equal(busyHarness.children.length, 0);\r\n\r\n\tbusyBind.resolve(\"BOUND endpoint token=token-busy\");\r\n\tawait Promise.all([startingBusy, becomingBusy]);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(busyHarness).map((call) => call.args[4]),\r\n\t\t[\"busy\"],\r\n\t\t\"agent_start before bind completion must suppress the stale idle publication\",\r\n\t);\r\n\tassert.equal(busyHarness.children.length, 1);\r\n\tawait busyHarness.emit(\"session_shutdown\");\r\n\tassert.deepEqual(busyHarness.clock.delays(), []);\r\n\r\n\tconst shutdownBind = deferred();\r\n\tconst shutdownHarness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return shutdownBind.promise;\r\n\t\t},\r\n\t});\r\n\tconst startingShutdown = shutdownHarness.emit(\"session_start\");\r\n\tawait flush();\r\n\tconst shuttingDown = shutdownHarness.emit(\"session_shutdown\");\r\n\tawait flush();\r\n\tassert.equal(shutdownHarness.children.length, 0);\r\n\tassert.equal(\r\n\t\tshutdownHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t0,\r\n\t);\r\n\r\n\tshutdownBind.resolve(\"BOUND endpoint token=token-shutdown\");\r\n\tawait Promise.all([startingShutdown, shuttingDown]);\r\n\tassert.deepEqual(stateCalls(shutdownHarness), []);\r\n\tassert.equal(shutdownHarness.children.length, 0);\r\n\tassert.equal(\r\n\t\tshutdownHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t1,\r\n\t);\r\n\tassert.ok(\r\n\t\t!shutdownHarness.statuses.some(({ text }) => text === \"spt:omp-agent\"),\r\n\t\t\"bind completion after shutdown must not restore live status\",\r\n\t);\r\n\tassert.deepEqual(shutdownHarness.clock.delays(), []);\r\n\r\n\tconst hungBindHarness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"api\" && call.args[3] === \"bind\") return new Promise(() => {});\r\n\t\t},\r\n\t});\r\n\tconst hungStart = hungBindHarness.emit(\"session_start\");\r\n\tawait flush();\r\n\tconst hungShutdown = hungBindHarness.emit(\"session_shutdown\");\r\n\tawait flush();\r\n\tassert.deepEqual(hungBindHarness.clock.delays().sort((a, b) => a - b), [300, 1_800]);\r\n\tawait hungBindHarness.clock.runNext(300);\r\n\tawait Promise.all([hungStart, hungShutdown]);\r\n\tassert.equal(hungBindHarness.children.length, 0);\r\n\tassert.equal(\r\n\t\thungBindHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t0,\r\n\t\t\"session-end cannot run without a completed bind token\",\r\n\t);\r\n\tassert.deepEqual(hungBindHarness.clock.delays(), []);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-LISTENER-FAIL-CLOSED]\r\nasync function testOutcomeSendRetriesAndExhaustion() {\r\n\tlet retryAttempts = 0;\r\n\tconst retryHarness = createHarness({\r\n\t\toutcomeRetryDelaysMs: [5, 10],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"retry\") {\r\n\t\t\t\tretryAttempts += 1;\r\n\t\t\t\tif (retryAttempts < 3) throw new Error(`outcome failure ${retryAttempts}`);\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait retryHarness.emit(\"session_start\");\r\n\tretryHarness.children[0].stdout.emit(\r\n\t\t\"data\",\r\n\t\t'<EVENT type=\"msg\" from=\"retry\">work</EVENT>',\r\n\t);\r\n\tawait flush();\r\n\tawait retryHarness.emit(\"agent_start\");\r\n\tconst retryEnding = retryHarness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"user\", content: '<msg from=\"retry\"/>' },\r\n\t\t\t{ role: \"assistant\", content: \"eventual outcome\" },\r\n\t\t],\r\n\t});\r\n\tawait flush();\r\n\tassert.equal(commandCalls(retryHarness, \"send\").length, 1);\r\n\tassert.deepEqual(retryHarness.clock.delays(), [5]);\r\n\tawait retryHarness.clock.runNext(5);\r\n\tassert.equal(commandCalls(retryHarness, \"send\").length, 2);\r\n\tassert.deepEqual(retryHarness.clock.delays(), [10]);\r\n\tawait retryHarness.clock.runNext(10);\r\n\tawait retryEnding;\r\n\tassert.equal(commandCalls(retryHarness, \"send\").length, 3);\r\n\tassert.equal(commandCalls(retryHarness, \"send\").at(-1).input, \"eventual outcome\");\r\n\tassert.equal(retryHarness.shutdowns, 0);\r\n\tawait retryHarness.emit(\"session_shutdown\");\r\n\tassert.deepEqual(retryHarness.clock.delays(), []);\r\n\r\n\tconst exhaustedHarness = createHarness({\r\n\t\toutcomeRetryDelaysMs: [7],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\") throw new Error(\"outcome channel unavailable\");\r\n\t\t},\r\n\t});\r\n\tawait exhaustedHarness.emit(\"session_start\");\r\n\tconst exhaustedListener = exhaustedHarness.children[0];\r\n\texhaustedListener.stdout.emit(\r\n\t\t\"data\",\r\n\t\t'<EVENT type=\"msg\" from=\"exhausted\">work</EVENT>',\r\n\t);\r\n\tawait flush();\r\n\tawait exhaustedHarness.emit(\"agent_start\");\r\n\tconst exhaustedEnding = exhaustedHarness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{ role: \"user\", content: '<msg from=\"exhausted\"/>' },\r\n\t\t\t{ role: \"assistant\", content: \"undeliverable outcome\" },\r\n\t\t],\r\n\t});\r\n\tawait flush();\r\n\tassert.equal(commandCalls(exhaustedHarness, \"send\").length, 1);\r\n\tassert.deepEqual(exhaustedHarness.clock.delays(), [7]);\r\n\tawait exhaustedHarness.clock.runNext(7);\r\n\tawait exhaustedEnding;\r\n\r\n\tassert.equal(commandCalls(exhaustedHarness, \"send\").length, 2);\r\n\tassert.deepEqual(\r\n\t\tstateCalls(exhaustedHarness).map((call) => call.args[4]),\r\n\t\t[\"idle\", \"busy\"],\r\n\t\t\"exhausted custody must never be advertised idle\",\r\n\t);\r\n\tassert.equal(exhaustedHarness.shutdowns, 1);\r\n\tassert.equal(exhaustedListener.kills, 1);\r\n\tassert.equal(\r\n\t\texhaustedHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t1,\r\n\t);\r\n\tassert.ok(\r\n\t\texhaustedHarness.errors.some(({ message }) =>\r\n\t\t\tmessage.includes(\"could not send the outcome to exhausted\"),\r\n\t\t),\r\n\t);\r\n\tawait exhaustedHarness.emit(\"session_shutdown\");\r\n\tassert.deepEqual(exhaustedHarness.clock.delays(), []);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\nasync function testSubmissionFailureAdvancesQueue() {\r\n\tconst harness = createHarness({\r\n\t\tonSubmit(content) {\r\n\t\t\tif (content === '<msg from=\"broken\"/>') throw new Error(\"OMP prompt flow rejected input\");\r\n\t\t},\r\n\t});\n…\n}","startLine":279,"lineNumbers":[279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,null,626]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1378,"totalBytes":10672,"outputLines":315,"outputBytes":10672,"shownRange":{"start":279,"end":593},"nextOffset":594}}},"isError":false,"timestamp":1784188876306}}
{"type":"message","id":"8a664a3b","parentId":"48fd4e09","timestamp":"2026-07-16T08:01:23.245Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Searching OMP extension APIs in project and node modules**"},{"type":"toolCall","id":"call_xsibMycOuL0C6uTfYjDJDHgr|fc_03e5b91f227b0634016a588fd33244819b95e9d570980ec618","name":"grep","arguments":{"i":"Finding command registration patterns","pattern":"registerCommand|registerShortcut|select\\(|confirm\\(|agent_end|tool_call|context|sendUserMessage","path":".","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_G377XUb6qzsCCjdQFceqflUB|fc_03e5b91f227b0634016a588fd33258819ba0432e9cf9b0907f","name":"grep","arguments":{"i":"Finding injectability decisions","pattern":"inject|boundary|tool_call|before.*tool|model continuation|selection dialog|argument completion|registerCommand","path":"docs;OMP-ADAPTER-PLAN.md;PARITY-PUBLISH-PLAN.md","selector":null,"case":false,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_sQLkuc2PCq1J2MZrUJIWE1d0|fc_03e5b91f227b0634016a588fd33260819ba78f73d637d69465","name":"glob","arguments":{"i":"Finding extension examples","path":"**/*.mjs;**/*.js;**/*.ts","hidden":true,"gitignore":true,"limit":300}},{"type":"toolCall","id":"call_pSGjRHBT1IkEOXBLUTPbbEUw|fc_03e5b91f227b0634016a588fd33268819b93a7b5a214b7b469","name":"read","arguments":{"i":"Reading safe-boundary hazard","path":"docs/KNOWN-HAZARDS.md","selector":"1-220"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":20882,"output":285,"cacheRead":41472,"cacheWrite":0,"totalTokens":62639,"reasoningTokens":43,"cost":{"input":0.10441,"output":0.00855,"cacheRead":0.020735999999999997,"cacheWrite":0,"total":0.133696}},"stopReason":"toolUse","timestamp":1784188876349,"responseId":"resp_03e5b91f227b0634016a588fccae84819bb3bf821d6e6007d3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03e5b91f227b0634016a588fce0dbc819bace1cc10ab08f9ce","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWI_Tk2XzonsLQHjWwB7wW8o4TcZ3ify8d094w-tcNnf42b-Ta9FhmNV1qX9eor3nggCypHmkWletO4qwszZ0sx7tCW-2MnSYNoYnPCiqcc8UMR0FueXgZ9XxqHds2apUsOhxieXQqFF9fW5qGsJtj4SrITWiqc1EiTfS-HvkRy2WDX0lgYn7pTvP8Dz6XC2jzvO7Up2KtlQ8hznaJBxLofy0T1-VGe8fUSBdSe--vLAmRTKWBFIfWox2JuQDvGuXCyOtRTxakmNKTgQddAa14U5ewVTe0xFljN1T8nBDhCQ6yI4EIOOhRiUPs9Lb0SnfxjDjTfq-iyCVqCaeYlX5mWimFXxtGaaczINeBwH5_9t8Zjip68FnqDJXO7bGsLdApemPUQm5C7_Typ6NUhn77-l6DpYDJfVzK9JQxueISgREsz3WN6jUepefCQbY8pTwxyF4B__LFTp4DNaKoXQw0WW-shlm8uPqeVYCURDQ625TeV4Ct_RqCOJghbxsNXLKijU3KnDY7K2Tg0ht0GUBc5-l9bCAFRnEw6dvsJBqKNxCcbAr3B4YHrVZFkNquKuCswdtCy1fqrlbGDJMySBpMqoZh9oKz1sUOBlFtnOvRJoci47skwFdTAJs25hBalf8jpQOomNTQ2EndpRukAC_Iu_RA7wYr1SlNxRklrR5DF2WANQJjANuRCniCuDpryYV6S4k2dIjWi1D6LyjadW4XOA_x_WeUHWpNRHwrI2AXqty3uHnOXQ4LUNtGp1Db8tsDGIdK6UTVm1gvYzfujkk5AhlKgRNqFg37bpzMu_pnKNKjIjDps_d3qJKw2hA1JY29ONxAZop9R8xesMJTcnO0r__l27On4ulD39iHaYmzds24Sj_HPS_oyzJZivqkf-VExiDv4jvFZPdcErnfvI5sKBGXKRu3XoxwsGAXTvMr3QDlkqwhaTodNu6Y9MLcm8j3MlrDS6P4E_284RCB6Ieb0ahh0yrrFZYX1cThmHYPhAq6vBy5nwG48v0tkUcLI_mPj2BMCJkyhFB3zHfXtvgwy6phcHH2YV5uJj6g1hA-IuhM4JLa3QZqgC5VP_KjcFNrr0ACWCJMpx80LeWfCIi9kBvvXKXoClC-PE8kkCrY_uLZdOQx3wI4ClqzQEdd6uJhT0bRMxPkZkLiVeOME27NVCDHwa1VZiPYsVXgPaZz38x8ixQ-je-XOK2u90M8wGNfdvm","summary":[{"type":"summary_text","text":"**Searching OMP extension APIs in project and node modules**"}]},{"id":"fc_03e5b91f227b0634016a588fd33244819b95e9d570980ec618","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding command registration patterns\",\"pattern\":\"registerCommand|registerShortcut|select\\\\(|confirm\\\\(|agent_end|tool_call|context|sendUserMessage\",\"path\":\".\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_xsibMycOuL0C6uTfYjDJDHgr","name":"grep"},{"id":"fc_03e5b91f227b0634016a588fd33258819ba0432e9cf9b0907f","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding injectability decisions\",\"pattern\":\"inject|boundary|tool_call|before.*tool|model continuation|selection dialog|argument completion|registerCommand\",\"path\":\"docs;OMP-ADAPTER-PLAN.md;PARITY-PUBLISH-PLAN.md\",\"selector\":null,\"case\":false,\"gitignore\":true,\"skip\":null}","call_id":"call_G377XUb6qzsCCjdQFceqflUB","name":"grep"},{"id":"fc_03e5b91f227b0634016a588fd33260819ba78f73d637d69465","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding extension examples\",\"path\":\"**/*.mjs;**/*.js;**/*.ts\",\"hidden\":true,\"gitignore\":true,\"limit\":300}","call_id":"call_sQLkuc2PCq1J2MZrUJIWE1d0","name":"glob"},{"id":"fc_03e5b91f227b0634016a588fd33268819b93a7b5a214b7b469","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading safe-boundary hazard\",\"path\":\"docs/KNOWN-HAZARDS.md\",\"selector\":\"1-220\"}","call_id":"call_pSGjRHBT1IkEOXBLUTPbbEUw","name":"read"}]},"duration":6894.552499999991,"ttft":4379.643799999962,"contextSnapshot":{"promptTokens":62354,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_xsibMycOuL0C6uTfYjDJDHgr|fc_03e5b91f227b0634016a588fd33244819b95e9d570980ec618","toolName":"grep","startedAt":"2026-07-16T08:01:23.245Z","args":{"path":"."},"intent":"Finding command registration patterns"},"id":"ee3179d4","parentId":"8a664a3b","timestamp":"2026-07-16T08:01:23.245Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_G377XUb6qzsCCjdQFceqflUB|fc_03e5b91f227b0634016a588fd33258819ba0432e9cf9b0907f","toolName":"grep","startedAt":"2026-07-16T08:01:23.245Z","args":{"path":"docs;OMP-ADAPTER-PLAN.md;PARITY-PUBLISH-PLAN.md"},"intent":"Finding injectability decisions"},"id":"97071ad9","parentId":"ee3179d4","timestamp":"2026-07-16T08:01:23.245Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_sQLkuc2PCq1J2MZrUJIWE1d0|fc_03e5b91f227b0634016a588fd33260819ba78f73d637d69465","toolName":"glob","startedAt":"2026-07-16T08:01:23.245Z","args":{"path":"**/*.mjs;**/*.js;**/*.ts"},"intent":"Finding extension examples"},"id":"781bd259","parentId":"97071ad9","timestamp":"2026-07-16T08:01:23.245Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_pSGjRHBT1IkEOXBLUTPbbEUw|fc_03e5b91f227b0634016a588fd33268819b93a7b5a214b7b469","toolName":"read","startedAt":"2026-07-16T08:01:23.245Z","args":{"path":"docs/KNOWN-HAZARDS.md"},"intent":"Reading safe-boundary hazard"},"id":"725003a6","parentId":"781bd259","timestamp":"2026-07-16T08:01:23.245Z"}
{"type":"message","id":"4093c105","parentId":"725003a6","timestamp":"2026-07-16T08:01:23.248Z","message":{"role":"toolResult","toolCallId":"call_pSGjRHBT1IkEOXBLUTPbbEUw|fc_03e5b91f227b0634016a588fd33268819b93a7b5a214b7b469","toolName":"read","content":[{"type":"text","text":"[KNOWN-HAZARDS.md#B907]\n1:# Known hazards\n2:\n3:This is the OMP adapter's conformance checklist. Each entry states a failure\n4:mode, the invariant that prevents it, the evidence boundary, and its source.\n5:An invariant is not covered merely because it is described here: the active\n6:requirement must point at production behavior and a focused test.\n7:\n8:## 1. Delivery custody can be lost or mis-correlated\n9:\n10:<!-- [doc->REQ-OMP-EXTENSION-CUSTODY] -->\n11:\n12:- **Failure:** Two SPT deliveries overlap, the active sender is overwritten, or\n13:  OMP rejects a submitted message after the listener has already accepted it.\n14:  The wrong peer can receive the next answer, or one accepted message can\n15:  disappear with no terminal outcome.\n16:- **Invariant:** The extension serializes deliveries. From receipt until\n17:  completion it owns the sender, full event, submitted OMP turn, and terminal\n18:  outcome as one custody record. It advances only after sending either the\n19:  correlated answer or an explicit failure to that sender. Submission failure\n20:  is never treated as a successful empty answer.\n21:- **Mapping / notes:** The native OMP extension owns receipt, queueing,\n22:  `sendUserMessage`, turn completion, and reply. The ordinary OMP turn receives\n23:  a short message stub plus the full event context; peer content is never\n24:  submitted as a local slash command.\n25:- **cite:** ADR-0010 and the OMP extension lifecycle contract.\n26:\n27:## 2. A dead listener leaves a healthy-looking but unreachable endpoint\n28:\n29:<!-- [doc->REQ-OMP-LISTENER-FAIL-CLOSED] -->\n30:\n31:- **Failure:** The SPT listener exits while OMP remains open and bound. If the\n32:  extension retries forever or merely logs the exit, the endpoint can stay\n33:  advertised as online while no message can reach it.\n34:- **Invariant:** Unexpected listener exit triggers only a finite, deterministic\n35:  restart schedule. A successful restart resumes delivery with custody intact.\n36:  Exhausting the schedule performs SPT session-end and shuts down OMP loudly.\n37:  There is no infinite restart loop and no healthy advertisement after the\n38:  delivery path is gone.\n39:- **Mapping / notes:** Retry timers are extension-owned and cancellable during\n40:  normal shutdown. The exhausted path uses the same serialized teardown seam as\n41:  an explicit endpoint stop.\n42:- **cite:** ADR-0010; field issue HIGH-2/HIGH-4 successor invariant.\n43:\n44:## 3. In-TUI session switching breaks endpoint identity\n45:\n46:<!-- [doc->REQ-OMP-SESSION-IMMUTABLE] -->\n47:\n48:- **Failure:** A bound endpoint switches, branches, creates, or resumes another\n49:  OMP session from inside the TUI. The stable SPT endpoint id then points at a\n50:  different transcript than queued messages, replies, history, digest, and\n51:  durable mind state expect.\n52:- **Invariant:** One endpoint owns exactly one OMP session for its lifetime.\n53:  The extension blocks every in-TUI action that would change that session.\n54:  Selecting another session requires stopping the endpoint and relaunching it\n55:  with the explicit native-resume role, producing a new deliberate bind.\n56:- **Mapping / notes:** This is stricter than merely rebinding on a session\n57:  event. A rebind would preserve liveness while violating custody and history\n58:  identity, so it is not an allowed recovery.\n59:- **cite:** ADR-0011.\n60:\n61:## 4. The `omp` basename resolves to the wrong executable\n62:\n63:<!-- [doc->REQ-OMP-EXECUTABLE-RESOLUTION] -->\n64:\n65:- **Failure:** Another program owns the bare `omp` token, or an adapter helper\n66:  is advertised as a host binary. The broker can launch or bind the wrong\n67:  process, while process listings conceal which application actually owns the\n68:  endpoint.\n69:- **Invariant:** The manifest advertises only the genuine OMP host basename.\n70:  The native launch shim resolves and validates Oh My Pi before launch, rejects\n71:  collisions loudly, and then replaces itself or inherits the terminal\n72:  unchanged so native OMP remains the PTY owner.\n73:- **Mapping / notes:** `omp-spt` is the adapter helper/release binary, never a\n74:  hosted-harness match key. Fresh and resume launch use the same resolver.\n75:- **cite:** ADR-0009 and the retired bridge incident's executable-collision\n76:  finding.\n77:"}],"details":{"displayContent":{"text":"# Known hazards\n\nThis is the OMP adapter's conformance checklist. Each entry states a failure\nmode, the invariant that prevents it, the evidence boundary, and its source.\nAn invariant is not covered merely because it is described here: the active\nrequirement must point at production behavior and a focused test.\n\n## 1. Delivery custody can be lost or mis-correlated\n\n<!-- [doc->REQ-OMP-EXTENSION-CUSTODY] -->\n\n- **Failure:** Two SPT deliveries overlap, the active sender is overwritten, or\n  OMP rejects a submitted message after the listener has already accepted it.\n  The wrong peer can receive the next answer, or one accepted message can\n  disappear with no terminal outcome.\n- **Invariant:** The extension serializes deliveries. From receipt until\n  completion it owns the sender, full event, submitted OMP turn, and terminal\n  outcome as one custody record. It advances only after sending either the\n  correlated answer or an explicit failure to that sender. Submission failure\n  is never treated as a successful empty answer.\n- **Mapping / notes:** The native OMP extension owns receipt, queueing,\n  `sendUserMessage`, turn completion, and reply. The ordinary OMP turn receives\n  a short message stub plus the full event context; peer content is never\n  submitted as a local slash command.\n- **cite:** ADR-0010 and the OMP extension lifecycle contract.\n\n## 2. A dead listener leaves a healthy-looking but unreachable endpoint\n\n<!-- [doc->REQ-OMP-LISTENER-FAIL-CLOSED] -->\n\n- **Failure:** The SPT listener exits while OMP remains open and bound. If the\n  extension retries forever or merely logs the exit, the endpoint can stay\n  advertised as online while no message can reach it.\n- **Invariant:** Unexpected listener exit triggers only a finite, deterministic\n  restart schedule. A successful restart resumes delivery with custody intact.\n  Exhausting the schedule performs SPT session-end and shuts down OMP loudly.\n  There is no infinite restart loop and no healthy advertisement after the\n  delivery path is gone.\n- **Mapping / notes:** Retry timers are extension-owned and cancellable during\n  normal shutdown. The exhausted path uses the same serialized teardown seam as\n  an explicit endpoint stop.\n- **cite:** ADR-0010; field issue HIGH-2/HIGH-4 successor invariant.\n\n## 3. In-TUI session switching breaks endpoint identity\n\n<!-- [doc->REQ-OMP-SESSION-IMMUTABLE] -->\n\n- **Failure:** A bound endpoint switches, branches, creates, or resumes another\n  OMP session from inside the TUI. The stable SPT endpoint id then points at a\n  different transcript than queued messages, replies, history, digest, and\n  durable mind state expect.\n- **Invariant:** One endpoint owns exactly one OMP session for its lifetime.\n  The extension blocks every in-TUI action that would change that session.\n  Selecting another session requires stopping the endpoint and relaunching it\n  with the explicit native-resume role, producing a new deliberate bind.\n- **Mapping / notes:** This is stricter than merely rebinding on a session\n  event. A rebind would preserve liveness while violating custody and history\n  identity, so it is not an allowed recovery.\n- **cite:** ADR-0011.\n\n## 4. The `omp` basename resolves to the wrong executable\n\n<!-- [doc->REQ-OMP-EXECUTABLE-RESOLUTION] -->\n\n- **Failure:** Another program owns the bare `omp` token, or an adapter helper\n  is advertised as a host binary. The broker can launch or bind the wrong\n  process, while process listings conceal which application actually owns the\n  endpoint.\n- **Invariant:** The manifest advertises only the genuine OMP host basename.\n  The native launch shim resolves and validates Oh My Pi before launch, rejects\n  collisions loudly, and then replaces itself or inherits the terminal\n  unchanged so native OMP remains the PTY owner.\n- **Mapping / notes:** `omp-spt` is the adapter helper/release binary, never a\n  hosted-harness match key. Fresh and resume launch use the same resolver.\n- **cite:** ADR-0009 and the retired bridge incident's executable-collision\n  finding.\n","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\docs\\KNOWN-HAZARDS.md"}}},"isError":false,"timestamp":1784188883248}}
{"type":"message","id":"84759c89","parentId":"4093c105","timestamp":"2026-07-16T08:01:23.250Z","message":{"role":"toolResult","toolCallId":"call_sQLkuc2PCq1J2MZrUJIWE1d0|fc_03e5b91f227b0634016a588fd33260819ba78f73d637d69465","toolName":"glob","content":[{"type":"text","text":"# adapter/strings/\nomp-spt.mjs\n# tests/\nomp-extension.mjs"}],"details":{"scopePath":"**/*.mjs, **/*.js, **/*.ts","fileCount":2,"files":["adapter/strings/omp-spt.mjs","tests/omp-extension.mjs"],"truncated":false,"cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt"},"isError":false,"timestamp":1784188883250}}
{"type":"message","id":"b773df9f","parentId":"84759c89","timestamp":"2026-07-16T08:01:23.279Z","message":{"role":"toolResult","toolCallId":"call_xsibMycOuL0C6uTfYjDJDHgr|fc_03e5b91f227b0634016a588fd33244819b95e9d570980ec618","toolName":"grep","content":[{"type":"text","text":"# AGENTS.md#3D8D\n 62:\n*63:## Plans and context hygiene\n 64:\n 65:- **JIT plans.** Plan the next immediate body of work just-in-time (a short `*-PLAN.md`),\n 66:  not the whole project up front. A plan names scope, open design questions, tasks, and the\n...\n 68:- If you finish a significant body of work without need for user intervention, or if your\n*69:  context gets too high, you can clear your own context and keep moving:\n 70:  1. Create a JIT plan for the next immediate body of work, if it isn't already planned.\n 71:  2. If you are a live agent: commune immediate next steps + a broad project-status/end-goal\n 72:     summary, then clear.\n\n# CHANGELOG.md#67E7\n 19:- **Every endpoint now remains a real, attachable OMP session.** Ready and live endpoints use the same native OMP launch path, so an unattended endpoint can still be attached later without losing OMP's normal terminal interface.\n*20:- **Inbound peer messages now arrive as ordinary OMP turns with full SPT context.** The visible prompt is a safe sender stub, while the complete event envelope is supplied to that turn as context; peer text cannot accidentally invoke a slash command.\n 21:- **OMP profile-aware session tools.** History, digest, echo-commune, and Psyche session lookup now follow OMP's profile and configuration precedence, including deterministic exact-id and prefix handling.\n 22:\n 23:### Changed\n...\n 68:- **Session digest.** `spt endpoint digest <id>` shows the endpoint's conversation as it happens — prompts, replies, and the tools omp used.\n*69:- **Live-agent lifecycle.** A live omp endpoint gets a Psyche companion that carries its context across resets, and a session that ends without a signoff is auto-summarized so its context delta is kept anyway.\n 70:- **OpenRouter billing guide.** `docs/OMP-OPENROUTER.md` covers routing the endpoint's model spend through OpenRouter using omp's own provider config — nothing to configure in the adapter itself.\n 71:\n 72:### Changed\n...\n 83:### Changed\n*84:- **Communes now file project detail under the project, not your permanent identity.** When you commune (or when a session is auto-summarized), detail specific to the project you're in is kept separate from your cross-project, standing context — so your durable memory stays clean and project notes don't bleed between projects. Wrap project detail in `<project-context>…</project-context>` and identity/role context in `<live-context>…</live-context>`; anything left untagged is treated as standing con...\n 85:\n 86:## [0.17.2] - 2026-07-08\n 87:\n...\n 104:### Added\n*105:- **Message another agent without leaving your train of thought — no shell command needed.** Write `@<alice hey, can you check the deploy? @>` anywhere in a reply and the adapter delivers \"hey, can you check the deploy?\" to `alice`, then tells you (in your next context) whether it landed or the agent wasn't reachable. Send to several at once with `@<alice,bob,carol …@>`. Only that exact `@<…@>` form sends, so you can still talk *about* the syntax without firing anything.\n*106:- **Save a working-context note the same way.** Start a message with `>>commune<<` and the rest becomes your commune (the context hand-off that survives a reset) — the same result as writing the commune file by hand, without the file step. Include `!!checkpoint!!` in it to also reset-and-rebuild your context from that note.\n 107:\n 108:## [0.16.2] - 2026-07-08\n 109:\n...\n 157:### Changed\n*158:- **Going live or ready in a daemon-launched session no longer starts a redundant listener.** A live agent or ready session that was launched by the spt daemon is already reachable through the broker — messages arrive on its turn automatically. Bringup now recognizes this kind of session and skips starting an extra in-session listener, which in that context could not receive anything anyway and only reported an error. Sessions you launch yourself are unaffected and still start their listener as before.\n 159:\n 160:## [0.15.5] - 2026-07-07\n 161:\n...\n 164:### Fixed\n*165:- **End-of-session summaries work for ccs-launched endpoints.** 0.15.4 fixed finding the session transcript, but the summarizer's own Claude run still failed for ccs-launched endpoints because it ran without the endpoint's ccs configuration (no auth). It now runs with the endpoint's own configuration, so end-of-session context capture works everywhere. Psyches affected by the earlier failures recover on their own at the next commune — no restart needed.\n 166:\n 167:## [0.15.4] - 2026-07-07\n 168:\n...\n 186:### Fixed\n*187:- **Agent checkpoints and communes work again on spt-core v0.27.0+.** Newer spt-core asks the adapter to summarize a session's history whenever a session ends without a signoff (and when syncing a commune). The adapter didn't provide that summarizer, so after a few attempts spt-core gave up on the whole Psyche — checkpoints did nothing, communes stopped reaching the agent's tracked mind, and the endpoint showed a Psyche hosting error. The adapter now ships the summarizer, so end-of-session context is c...\n 188:\n 189:### Added\n*190:- **Sessions that end without a signoff now keep their context.** When a live agent's session ends abruptly (closed window, crash, no `/sptc:signoff`), spt-core now gets a concise summary of what the session was doing, ingested into the agent's tracked mind — so the next session resumes with that context instead of losing it.\n 191:\n 192:## [0.15.1] - 2026-07-06\n 193:\n...\n 210:### Fixed\n*211:- **A live agent's Psyche works again on spt-core v0.25.0+.** Since 0.14.0, every Psyche turn failed before it could start (a leftover reference to a setting the new Psyche lifecycle no longer provides), so a live agent's Psyche silently stopped producing context notes and resume briefs. The Psyche now runs its turns normally again. Recovery: update the adapter, then restart affected live agents once.\n 212:\n 213:## [0.14.1] - 2026-07-05\n 214:\n...\n 225:- **A live agent's Psyche no longer runs as a resident background process.** The Psyche now wakes for each update, handles it, and finishes — its memory carries over between wakes, so nothing about the Psyche experience changes. What does change is the failure surface: the whole class of problems that came from keeping a Psyche process alive — silent restart loops, a Psyche quietly dying and needing `/sptc:revive`, and the multi-subnet limitation called out in 0.13.4 where a Psyche couldn't hold its ...\n*226:- **Psyches with a large accumulated context now start reliably on Windows.** A Psyche resuming with a big context could previously fail to launch on Windows due to a system limit on how much can be passed to a starting program. The context now travels a route without that limit.\n 227:- **Now requires spt-core v0.25.0 or newer** (up from v0.23.0). The new Psyche lifecycle is driven by spt-core from this release on; older spt-core versions cannot run it, so the requirement is a hard floor.\n 228:\n 229:## [0.13.4] - 2026-07-04\n...\n 233:### Fixed\n*234:- **A live agent's Psyche that can't establish its listening perch now fails visibly instead of silently restarting forever.** On machines that belong to more than one subnet, the Psyche's listener could be refused at startup in a way it mistook for a normal shutdown — so it quietly exited and got restarted every few seconds, indefinitely, wasting resources with no visible sign. That refusal now surfaces as a real, loggable fault. Note: on multi-subnet machines the Psyche still can't hold its listener ...\n 235:\n 236:## [0.13.3] - 2026-07-04\n 237:\n...\n 254:### Fixed\n*255:- **Clearing a live agent's context no longer silently breaks its message delivery.** Every time a live agent's session was cleared — by hand or as part of a checkpoint — the machinery that delivers incoming messages into the session could be shut down as collateral, and from then on messages quietly piled up unseen until the agent was restarted. Delivery now survives clears. This also removes the main reason a checkpoint's follow-up instruction (`/sptc:commune --checkpoint`) never appeared after the...\n 256:\n 257:## [0.13.0] - 2026-07-03\n 258:\n...\n 278:### Fixed\n*279:- **Checkpoint waits until after the session clear to send the wake message.** When a live agent checkpoints (`/sptc:commune --checkpoint`), it clears its context and then continues with a follow-up instruction. Previously the follow-up could be submitted before the clear finished, so it ran against the old context (or was lost). The clear now always completes first, and the follow-up runs as the first turn of the fresh session — reliably, regardless of how long the clear takes.\n 280:\n 281:### Changed\n 282:- **Session names now include the project folder.** Alongside the `<id> @ <node>` naming, your Claude Code sessions now show the project folder they're running in — e.g. `myagent @ lab (my-project/)` in the prompt box and `/resume` picker — so you can tell apart agents working in different projects on the same node. Remote-control names carry it too. Existing sessions pick up the new name on their next start.\n...\n 378:\n*379:> Requires spt-core **v0.15.0 or newer** (was v0.13.2). This release adds self-checkpointing for live agents, automatic resume context, and clearer multi-line message delivery — all built on features that arrive in spt-core v0.15.0.\n 380:\n 381:### Added\n*382:- **Self-checkpointing for live agents — `/sptc:commune --checkpoint`.** A live agent can now reset and rebuild its own context without you running `/clear`. Write a commune containing the marker `!!checkpoint!!` and the session clears itself, then wakes back up from that very commune and keeps going. A single `!!checkpoint!!` wakes with a default \"Proceed with next steps\"; a **pair** of markers wakes with whatever instruction you write between them. The marker is one-shot — it never lingers in your ...\n*383:- **Automatic resume context.** When a live agent's session starts (or clears), it now pulls its durable role, working context, and latest unsynced commune and re-injects them automatically — so it resumes where it left off instead of coming back blank.\n 384:\n 385:### Changed\n 386:- **Incoming messages are easier to read.** A message delivered from another agent now renders across multiple lines — the envelope opening, the body, and the close each on their own line — instead of one dense single line.\n*387:- **Requires spt-core v0.15.0+** (up from v0.13.2). Self-checkpointing and resume context both rely on capabilities introduced in that release; `/sptc:setup` and `spt adapter update` will keep you current.\n 388:- Adapter version of truth is now **0.7.0** (shown in `/sptc:version` and the release tag).\n 389:\n 390:## [0.6.2] - 2026-06-23\n...\n 427:### Changed\n*428:- **Your live-agent companion now runs in a safe, limited mode.** When you go live with `/sptc:live`, the background companion that writes your context-resume notes works with a file-only toolset and a lighter, cheaper model. It is more contained and costs less to run, with no change to what you see or do.\n 429:- **Removed the experimental `:deep` profile.** `claude-spt:deep` was an unused placeholder. The one shipped profile overlay is `claude-spt:ccs` (routes sessions through `ccs`). If you ever selected `:deep`, use `:ccs` or the base adapter instead.\n 430:\n 431:### Fixed\n...\n 453:### Fixed\n*454:- **Live agents now reliably start their background companion.** Previously a live agent could come up marked \"online\" while its persistent companion silently failed to start, leaving it with no running context. The companion now launches and stays resident.\n 455:\n 456:### Changed\n 457:- **Simpler setup — no manual PATH step.** The adapter's helper tools are now found automatically from where the adapter is installed; `/sptc:setup` no longer asks you to copy anything onto your PATH.\n\n# CHECKPOINT-CLEAR-RACE-PLAN.md#5A9E\n 74:- **(Q1) Orphan-wake guard.** If the checkpoint's own clear fails to fire the signal (hook error), the\n*75:  armed wake fires on the NEXT clear — possibly a slightly-wrong context. The every-clear-fire model\n 76:  self-limits it (won't sit forever). Options: (a) ACCEPT for v1 (simplest, self-correcting; document\n 77:  in KNOWN-HAZARDS) — RECOMMENDED; (b) bound staleness with a translate-side generation/timeout on the\n 78:  armed wake. Decide before impl.\n\n# CHECKPOINT-COMMUNE-PLAN.md#1DCB\n 12:1. **Feature 1 — multi-line `<EVENT>` envelope** (cosmetic; visual distinction of inbound idle msgs).\n*13:2. **Feature 2 — checkpoint communes** (agent-driven context-compaction: flagged commune → auto\n 14:   `/clear` → wake; re-seed carried by spt-core's resume verb).\n 15:3. **Parity wiring — `psyche-download` at SessionStart** (foundational; closes a pre-existing gap\n*16:   where claude-spt live agents get NO durable resume context today — only the identity brief).\n 17:\n 18:## Hard public-surface findings (logged separately)\n 19:\n*20:- **F-0xx psyche-download verb absent** — `download_psyche_context` (spt-core resume.rs:88) is\n 21:  exported-but-unexposed (zero `ApiCmd` callers). No published `spt` verb let an adapter pull resume\n*22:  context. CONFIRMED spt-core gap. **RESOLVED-PENDING: v0.15.0 W5** exposes the verb (frozen contract\n*23:  below) + W4 doc work. Foundational — claude-spt resume context is broken without it.\n 24:- **F-0xx PreToolUse poll missing** — claude-spt polls only on `UserPromptSubmit` (between turns).\n 25:  Legacy spt also polls+injects on **PreToolUse** = the mid-turn message-delivery half of live-agent\n 26:  reachability. Standalone parity gap; not yet wired here.\n...\n 50:  <live-role>…</live-role>                       (if a role authored; else omitted)\n*51:  <live-context>…</live-context>                 (durable agents/<id>/live-context.md)\n*52:  <project-context-resolved name=\"<proj>\"/>      (sentinel — present iff in a resolved project)\n*53:  <project-context>…</project-context>           (durable projects/<proj>/<id>/project-context.md)\n 54:  <pending-commune>…raw drop body…</pending-commune>   (ONLY if not-yet-synthesized; TRIGGER STRIPPED core-side)\n 55:  <pending-signoff>…raw drop body…</pending-signoff>   (likewise for signoff)\n 56:\n*57:Empty/no-context → NO-CONTEXT signal on stderr (mirrors legacy $LIVE psyche-download) → inject nothing.\n 58:```\n 59:FRESHNESS: `<pending-*>` present iff a drop is not-yet-synthesized → one call always returns\n 60:durable + freshest un-synthesized delta. Race-free (core owns read+ingest; no adapter TOCTOU).\n...\n 81:  kept — no adapter strip. (Open: durable-ingest strip so the marker doesn't persist in\n*82:  live-context.md post-synthesis — doyle/todlando's call.)\n 83:- **Re-seed is core-owned** — no adapter-side raw drop reading (would TOCTOU core's pulse-delete,\n 84:  ingest.rs:161). The single `psyche-download` call carries durable + pending.\n 85:\n...\n 101:  Add a `[[hints]]` entry. Verify the commune body format matches the daemon's two-slice\n*102:  `<live-context>/<project-context>` envelope (or document the freeform→ingest behavior).\n 103:- **T2b PostToolUse hook (NEW)** — matcher Write; on Write of `.claude/<id>-commune.md`: scan\n 104:  `tool_input.content` (NOT a file re-read) for `!!checkpoint!!`; if present → `spt api state idle`\n 105:  → `spt send --from <id> <id> <wire-sentinel[+wake-text]>`. Resolve `<id>` (SPT_ENDPOINT_ID / whoami);\n\n# CONTEXT.md#76E6\n 59:an inbound peer message while the full SPT event envelope enters the same model\n*60:turn as extension-provided context. The peer body is never interpreted as an\n 61:OMP slash command.\n 62:_Avoid_: typing the peer body directly into the OMP editor\n 63:\n...\n 70:**OMP-native checkpoint** — an agent-driven continuity transition that saves\n*71:the current live context, resets OMP context through native session APIs, and\n 72:wakes the same endpoint from the saved state without operator intervention.\n 73:_Avoid_: Claude `/clear` keystroke choreography, save-only checkpoint\n 74:\n...\n 89:\n*90:**startup brief** — concise adapter-authored context supplied when an OMP\n 91:session activates, teaching identity, roster, messaging, continuity, and\n 92:lifecycle operations that the session can perform through public `spt` commands.\n 93:It is guidance, not a parallel command or transport layer.\n...\n 95:\n*96:**update notice** — concise agent-facing context emitted when the active\n 97:spt-core or omp-spt version is known to trail an available compatible release.\n 98:It identifies the affected component and the public update command.\n 99:_Avoid_: silent background update, generic startup announcement\n...\n 108:**signoff** — an agent-authored final continuity drop followed by graceful\n*109:endpoint shutdown. The OMP-native signoff skill keeps final context explicit\n 110:rather than relying solely on automatic echo-commune.\n 111:_Avoid_: commune, forced endpoint stop\n 112:\n...\n 120:\n*121:**targeted hint** — concise adapter-authored context injected when a user turn\n 122:clearly concerns live activation, identity, messaging, subnet onboarding, or\n 123:checkpointing. A hint points to the canonical capability without replacing its\n 124:full instructions.\n\n# DIGEST-FETCHER-PLAN.md#C11C\n 20:     Closes the \"ccs CLAUDE_CONFIG_DIR not expressible statically\" gap FOR REAL: the captured\n*21:     per-session value reaches the on-demand extractor in the daemon's context.\n 22:   - version → 0.10.0 + history note.\n 23:3. **Extractor** (`tools/claude-spt/src/digest.rs`):\n 24:   - New `--config-dir <dir>` flag: dir-branch root = `<config-dir>/projects` (highest precedence,\n\n# ECHO-COMMUNE-PLAN.md#7F0D\n 27:   takes a bounded tail, runs ONE headless `claude -p` turn (psyche-parity sandbox, Read-only\n*28:   tools), prints the context-delta summary to stdout. Loud nonzero on any failure.\n 29:   `recursion_guard_env = \"SPT_ECHO_COMMUNE\"` per the published role table.\n 30:3. **Hook recursion-guard bail** — `claude-spt hook` exits 0 immediately (no api calls, no\n 31:   perch writes) when `$SPT_ECHO_COMMUNE` is set: the summarizer's spawned claude must never\n\n# MANIFEST-PARITY-PLAN.md#8AC9\n 4:> target #2, the spt-core registry side) against the REAL v0.7.0 published surface, then the M12\n*5:> parity surfaces. NEEDS public-docs research first — run in clean context.\n 6:\n 7:## Public-surface-only (hard constraint — re-read)\n 8:\n...\n 61:     - **DONE (this session, triaged vs the v0.7.1 surface)** — signoff (`spt endpoint shutdown` —\n*62:       graceful + final context save, exact match) + list-agents (`spt endpoint list` — the roster).\n 63:       7/11 skills now operative. (force-stop/list-agents/new-alarm had no `[strings.skills]` entry;\n 64:       list-agents now added.)\n 65:     - **TODO — remaining 4, classified (don't invent):**\n\n# NEXT-WORKLOAD-PLAN.md#3DB0\n 104:- **Confirm-back:** a message-sent confirmation fired to the SENDER's OWN perch,\n*105:  `--active-only --ephemeral` (lands in-context mid-turn, never stale). Without it the agent re-sends\n 106:  via Bash, defeating the feature.\n 107:- **Commune shortcut:** `>>commune<<` at output start → hook writes `.claude/<id>-commune.md`, body =\n 108:  the output following the marker; feeds the same daemon ingest as the Write path (Write path retained).\n...\n 170:\n*171:## Cross-cutting knowledge (for context rebuild)\n 172:- Digest fetcher = PULL/PUSH, no cadence (doyle, code-authoritative). `--follow` = activity reactor\n 173:  only; idle detection needs a self-driven clock (generous periodic-pull heartbeat; each pull spawns the\n 174:  fetcher — don't thrash).\n\n# OMP-ADAPTER-PLAN.md#199F\n 86:`<msg from=\"…\"/>` user-visible stub. The complete SPT `<EVENT …>…</EVENT>`\n*87:envelope is supplied as context for that same turn. Peer text remains opaque\n 88:content; a message beginning with an OMP slash command cannot become local\n 89:operator input.\n 90:<!-- [doc->REQ-OMP-MESSAGE-CONTEXT] -->\n...\n 113:The Psyche is not a resident second endpoint. Each invocation is one bounded\n*114:headless OMP turn using the core-written context file and its own private OMP\n 115:session directory, then exits. OMP subagents are not advertised as independent\n 116:SPT Workers.\n 117:<!-- [doc->REQ-OMP-READY-LIVE] -->\n...\n 134:  <!-- [doc->REQ-DIST-DIGEST-EXTRACTOR] -->\n*135:- `[session.echo_commune]` self-locates history and prints one bounded context\n 136:  delta on stdout; spt-core owns the file drop, ingest, and deletion.\n 137:  <!-- [doc->REQ-SESSION-ECHO-COMMUNE] -->\n 138:\n\n# PARITY-PUBLISH-PLAN.md#5DEE\n 91:### Phase D — ccs profiles (LOCKED ADD)\n*92:- **Research first** (mcp/context7 not needed — read SCOPE §ccs + the existing `[profiles.*]`\n 93:  command seams). ccs profile = a `[profiles.<glm|kimi>]` overlay that leaf-replaces the spawn /\n 94:  psyche / echo command templates to route through `ccs <profile> …`, with a per-profile `~/.ccs`\n 95:  log dir. Author profile *templates* only (no user keys).\n...\n 122:\n*123:## Done immediately before (context)\n 124:- 4b042cc live sub-slice (claude-spt-psyche runner + /sptc:live body, REQ-SKILL-LIVE [doc,impl,unit]).\n 125:- 692b67c F-004 flip (digest-proof int GREEN on v0.7.2, REQ-DIST-DIGEST-EXTRACTOR full).\n 126:- spt upgraded 0.7.1 → 0.7.2 (operator-approved daemon bounce).\n\n# PEROS-RERELEASE-PLAN.md#C5EE\n 43:\n*44:## Known context\n 45:- doyle is OFFLINE — the F-009/F-010 findings (in `docs/SPT-CORE-FINDINGS.md` + commit ddf1965) are\n 46:  PENDING delivery; retry `spt send doyle --from perri`. The auto-update test (task 4) does NOT need\n 47:  doyle, but coordinating the spt-core findings does.\n\n# PSYCHE-EPHEMERAL-PLAN.md#7865\n 149:3. **E2E (live-verify window)**: commune drop → daemon ingest → psyche_resume invocation\n*150:   → synthesis lands in tracked context — THROUGH the new shim. Rig: fresh probe endpoint\n 151:   live bringup on the floor core; assert (a) exactly one `claude-spt psyche` process per\n 152:   event, zero resident survivors between events; (b) commune content reflects the event.\n 153:\n...\n 193:4. **Docs findings**: (a) per-event psyche_resume undocumented because UNWIRED — feature\n*194:   gap, docs land with F-030; (b) `{psyche_context}` example-vs-keylist = genuine\n 195:   published-docs bug, folded into the F-030 docs pass. Neither blocks the adapter half.\n 196:\n 197:## Tasks\n\n# README.md#7B03\n 7:`ReadyAgent` and `LiveAgent` endpoints in OMP's own terminal interface, with agent-to-agent\n*8:messaging, session continuity, history, digests, and live-agent context lifecycles.\n 9:\n 10:Native OMP owns the attachable TUI and its broker PTY. The packaged OMP extension handles endpoint\n 11:binding, message delivery, busy/idle state, replies, and shutdown from inside that native session.\n\n# SCOPE.md#A974\n 28:   - One serialized custody queue.\n*29:   - Message stub plus the full SPT event context in the same OMP turn.\n 30:   - Correlated reply or explicit failure for every accepted delivery.\n 31:   - Honest busy/idle state.\n 32:   - Bounded listener restart followed by loud session teardown and OMP\n...\n 68:- A headless RPC bridge or any second endpoint topology.\n*69:- Any foreign-harness plugin, hook, context-injection, command launcher, update\n 70:  reconciliation, or model-wrapper compatibility layer.\n 71:- Worker endpoint advertisement for OMP subagents.\n 72:- Migration of inherited `.spt` predecessor continuity.\n...\n 107:| Active-turn delivery uses safe boundaries | ADR-0017 | Locked |\n*108:| Checkpoint resets context natively | ADR-0018 | Locked |\n\n# SETUP-SLICE-PLAN.md#4A80\n 68:   runtime digest/Psyche do — so this never blocks the activation step.\n*69:3. **Setup context detection.** Skill probes for a local `adapter/claude-spt.toml` (operator\n 70:   dogfooding from a checkout → file-form) else uses `--github <Wave-C repo>` (casual end-user).\n 71:\n 72:## Waves\n\n# SKILLS-SLICE-PLAN.md#A7D6\n 26:       (that's a `[session.self]` fill — the published manifest.md example wrongly uses it and HARD-FAILS;\n*27:       doyle fixed the example). NOT `{psyche_context}` on first spawn (that's the resume/preload seam key).\n 28:       In spawn_psyche `{id}` is OVERRIDDEN to `<parent>-psyche`. Template only the four; `keys` a subset.\n 29:     - **Q3 Psyche process contract:** FIRE-AND-FORGET DETACHED — spawned with Stdio::null on all three\n 30:       fds, handle dropped, NOT supervised (liveness is daemon-authoritative via the perch, not pid).\n...\n 120:\n*121:## Done earlier this session (context)\n 122:- d1f14ab `[session.self]` + bind path (REQ-DIST-SHORTCUT-BASENAME [doc,impl,unit]).\n 123:- 39c05d1 digest extractor (Rust) (REQ-DIST-DIGEST-EXTRACTOR [impl,unit]; int F-004-blocked, doyle fixing).\n 124:- 8487ea0 large-drain cap/spill (ADR-0002 Open #2 resolved).\n\n# SPT_HARNESS_ADAPTER_TIPS.md#CF70\n 77:  `additionalContext` over ~10k chars by spilling it to a file, which *evicts it from the inline\n*78:  context the agent sees* — a large drain (or a big skill body + drain together) silently loses\n 79:  messages. Cap the combined hook output adapter-side under the threshold: under it pass through\n 80:  verbatim; over it spill the **full** text to an agent-readable file and inject only a short\n 81:  pointer. Never a mid-`<EVENT>`/mid-record head-cut — that splits an envelope and drops a message.\n...\n 172:  own derived perch id, not the parent's. (`{session_name}` is a `[session.self]` fill, not a psyche\n*173:  key; a first spawn has no `{psyche_context}` — that is the resume/preload key, a different seam.)\n 174:- The companion is launched **detached, fire-and-forget**: `detach = true`, `cwd = \"{psyche_dir}\"`,\n 175:  stdio null, handle dropped, **unsupervised** — liveness is daemon-authoritative via the companion's\n 176:  perch, not its pid. It owns the `<parent>-psyche` perch, communicates by perch + commune file-drops\n\n# adapter/\n## manifest.schema.json#63B7\n 177:    \"Hook\": {\n*178:      \"description\": \"`[hooks.<event>]` — one harness event → the `api` command it fires, the\\nstdin fields it maps, and whether it can surface context to the agent.\",\n 179:      \"type\": \"object\",\n 180:      \"properties\": {\n 181:        \"fires\": {\n...\n 191:        \"can_inject\": {\n*192:          \"description\": \"Whether this hook can inject context (false ⇒ sentinel/relay fallback).\",\n 193:          \"type\": \"boolean\",\n 194:          \"default\": false\n 195:        }\n...\n 291:    \"SessionRole\": {\n*292:      \"description\": \"`[session.<role>]` — one opaque outbound command template plus its spawn\\ncontext. Model/tools/flags all live inside `command`, never as fields\\n(MANIFEST §session roles). No nested tables here (keeps TOML round-trip\\nemission scalar-before-table clean).\",\n 293:      \"type\": \"object\",\n 294:      \"properties\": {\n 295:        \"command\": {\n...\n 932:    \"Hint\": {\n*933:      \"description\": \"`[[hints]]` — one once-per-session keyword hint (CONTEXT.md §keyword hints).\\nThe adapter's user-prompt hook pipes the full user message to `spt api hint`;\\na matching keyword surfaces `text` to the agent's context channel, at most\\nonce per session and once per message.\",\n 934:      \"type\": \"object\",\n 935:      \"properties\": {\n 936:        \"keywords\": {\n## omp-spt.toml#72C0\n 54:[session.psyche_init]\n*55:command = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\n 56:# Prevent a child Psyche from inheriting its parent's SPT identity.\n 57:env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\n*58:keys = [\"id\", \"session_id\", \"psyche_context_file\"]\n*59:# Each Psyche event is one bounded OMP turn. The context file is read by the\n 60:# shim, the event arrives on stdin, stdout carries the result, and exit 95 asks\n 61:# [impl->REQ-PSYCHE-EPHEMERAL-SHIM]\n 62:[session.psyche_resume]\n*63:command = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\n 64:detach = false\n 65:# Prevent a child Psyche from inheriting its parent's SPT identity.\n 66:env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\n*67:keys = [\"id\", \"session_id\", \"psyche_context_file\"]\n 68:\n 69:# Fresh endpoints launch validated native OMP with the packaged extension. The\n 70:# launch shim snapshots only non-secret OMP locator/profile/executable selectors\n\nShowing files 1-20 of 44+. Use skip=20 for the next page, or narrow paths/pattern.\n\n[Some lines truncated to 512 chars]"}],"details":{"scopePath":".","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":72,"fileCount":20,"files":["AGENTS.md","CHANGELOG.md","CHECKPOINT-CLEAR-RACE-PLAN.md","CHECKPOINT-COMMUNE-PLAN.md","CONTEXT.md","DIGEST-FETCHER-PLAN.md","ECHO-COMMUNE-PLAN.md","MANIFEST-PARITY-PLAN.md","NEXT-WORKLOAD-PLAN.md","OMP-ADAPTER-PLAN.md","PARITY-PUBLISH-PLAN.md","PEROS-RERELEASE-PLAN.md","PSYCHE-EPHEMERAL-PLAN.md","README.md","SCOPE.md","SETUP-SLICE-PLAN.md","SKILLS-SLICE-PLAN.md","SPT_HARNESS_ADAPTER_TIPS.md","adapter/manifest.schema.json","adapter/omp-spt.toml"],"fileMatches":[{"path":"AGENTS.md","count":2},{"path":"CHANGELOG.md","count":20},{"path":"CHECKPOINT-CLEAR-RACE-PLAN.md","count":1},{"path":"CHECKPOINT-COMMUNE-PLAN.md","count":11},{"path":"CONTEXT.md","count":6},{"path":"DIGEST-FETCHER-PLAN.md","count":1},{"path":"ECHO-COMMUNE-PLAN.md","count":1},{"path":"MANIFEST-PARITY-PLAN.md","count":2},{"path":"NEXT-WORKLOAD-PLAN.md","count":2},{"path":"OMP-ADAPTER-PLAN.md","count":3},{"path":"PARITY-PUBLISH-PLAN.md","count":2},{"path":"PEROS-RERELEASE-PLAN.md","count":1},{"path":"PSYCHE-EPHEMERAL-PLAN.md","count":2},{"path":"README.md","count":1},{"path":"SCOPE.md","count":3},{"path":"SETUP-SLICE-PLAN.md","count":1},{"path":"SKILLS-SLICE-PLAN.md","count":2},{"path":"SPT_HARNESS_ADAPTER_TIPS.md","count":2},{"path":"adapter/manifest.schema.json","count":4},{"path":"adapter/omp-spt.toml","count":5}],"truncated":true,"fileLimitReached":20,"perFileLimitReached":20,"displayContent":"# AGENTS.md#3D8D\n 62│\n*63│## Plans and context hygiene\n 64│\n 65│- **JIT plans.** Plan the next immediate body of work just-in-time (a short `*-PLAN.md`),\n 66│  not the whole project up front. A plan names scope, open design questions, tasks, and the\n   │...\n 68│- If you finish a significant body of work without need for user intervention, or if your\n*69│  context gets too high, you can clear your own context and keep moving:\n 70│  1. Create a JIT plan for the next immediate body of work, if it isn't already planned.\n 71│  2. If you are a live agent: commune immediate next steps + a broad project-status/end-goal\n 72│     summary, then clear.\n\n# CHANGELOG.md#67E7\n  19│- **Every endpoint now remains a real, attachable OMP session.** Ready and live endpoints use the same native OMP launch path, so an unattended endpoint can still be attached later without losing OMP's normal terminal interface.\n *20│- **Inbound peer messages now arrive as ordinary OMP turns with full SPT context.** The visible prompt is a safe sender stub, while the complete event envelope is supplied to that turn as context; peer text cannot accidentally invoke a slash command.\n  21│- **OMP profile-aware session tools.** History, digest, echo-commune, and Psyche session lookup now follow OMP's profile and configuration precedence, including deterministic exact-id and prefix handling.\n  22│\n  23│### Changed\n    │...\n  68│- **Session digest.** `spt endpoint digest <id>` shows the endpoint's conversation as it happens — prompts, replies, and the tools omp used.\n *69│- **Live-agent lifecycle.** A live omp endpoint gets a Psyche companion that carries its context across resets, and a session that ends without a signoff is auto-summarized so its context delta is kept anyway.\n  70│- **OpenRouter billing guide.** `docs/OMP-OPENROUTER.md` covers routing the endpoint's model spend through OpenRouter using omp's own provider config — nothing to configure in the adapter itself.\n  71│\n  72│### Changed\n    │...\n  83│### Changed\n *84│- **Communes now file project detail under the project, not your permanent identity.** When you commune (or when a session is auto-summarized), detail specific to the project you're in is kept separate from your cross-project, standing context — so your durable memory stays clean and project notes don't bleed between projects. Wrap project detail in `<project-context>…</project-context>` and identity/role context in `<live-context>…</live-context>`; anything left untagged is treated as standing con...\n  85│\n  86│## [0.17.2] - 2026-07-08\n  87│\n    │...\n 104│### Added\n*105│- **Message another agent without leaving your train of thought — no shell command needed.** Write `@<alice hey, can you check the deploy? @>` anywhere in a reply and the adapter delivers \"hey, can you check the deploy?\" to `alice`, then tells you (in your next context) whether it landed or the agent wasn't reachable. Send to several at once with `@<alice,bob,carol …@>`. Only that exact `@<…@>` form sends, so you can still talk *about* the syntax without firing anything.\n*106│- **Save a working-context note the same way.** Start a message with `>>commune<<` and the rest becomes your commune (the context hand-off that survives a reset) — the same result as writing the commune file by hand, without the file step. Include `!!checkpoint!!` in it to also reset-and-rebuild your context from that note.\n 107│\n 108│## [0.16.2] - 2026-07-08\n 109│\n    │...\n 157│### Changed\n*158│- **Going live or ready in a daemon-launched session no longer starts a redundant listener.** A live agent or ready session that was launched by the spt daemon is already reachable through the broker — messages arrive on its turn automatically. Bringup now recognizes this kind of session and skips starting an extra in-session listener, which in that context could not receive anything anyway and only reported an error. Sessions you launch yourself are unaffected and still start their listener as before.\n 159│\n 160│## [0.15.5] - 2026-07-07\n 161│\n    │...\n 164│### Fixed\n*165│- **End-of-session summaries work for ccs-launched endpoints.** 0.15.4 fixed finding the session transcript, but the summarizer's own Claude run still failed for ccs-launched endpoints because it ran without the endpoint's ccs configuration (no auth). It now runs with the endpoint's own configuration, so end-of-session context capture works everywhere. Psyches affected by the earlier failures recover on their own at the next commune — no restart needed.\n 166│\n 167│## [0.15.4] - 2026-07-07\n 168│\n    │...\n 186│### Fixed\n*187│- **Agent checkpoints and communes work again on spt-core v0.27.0+.** Newer spt-core asks the adapter to summarize a session's history whenever a session ends without a signoff (and when syncing a commune). The adapter didn't provide that summarizer, so after a few attempts spt-core gave up on the whole Psyche — checkpoints did nothing, communes stopped reaching the agent's tracked mind, and the endpoint showed a Psyche hosting error. The adapter now ships the summarizer, so end-of-session context is c...\n 188│\n 189│### Added\n*190│- **Sessions that end without a signoff now keep their context.** When a live agent's session ends abruptly (closed window, crash, no `/sptc:signoff`), spt-core now gets a concise summary of what the session was doing, ingested into the agent's tracked mind — so the next session resumes with that context instead of losing it.\n 191│\n 192│## [0.15.1] - 2026-07-06\n 193│\n    │...\n 210│### Fixed\n*211│- **A live agent's Psyche works again on spt-core v0.25.0+.** Since 0.14.0, every Psyche turn failed before it could start (a leftover reference to a setting the new Psyche lifecycle no longer provides), so a live agent's Psyche silently stopped producing context notes and resume briefs. The Psyche now runs its turns normally again. Recovery: update the adapter, then restart affected live agents once.\n 212│\n 213│## [0.14.1] - 2026-07-05\n 214│\n    │...\n 225│- **A live agent's Psyche no longer runs as a resident background process.** The Psyche now wakes for each update, handles it, and finishes — its memory carries over between wakes, so nothing about the Psyche experience changes. What does change is the failure surface: the whole class of problems that came from keeping a Psyche process alive — silent restart loops, a Psyche quietly dying and needing `/sptc:revive`, and the multi-subnet limitation called out in 0.13.4 where a Psyche couldn't hold its ...\n*226│- **Psyches with a large accumulated context now start reliably on Windows.** A Psyche resuming with a big context could previously fail to launch on Windows due to a system limit on how much can be passed to a starting program. The context now travels a route without that limit.\n 227│- **Now requires spt-core v0.25.0 or newer** (up from v0.23.0). The new Psyche lifecycle is driven by spt-core from this release on; older spt-core versions cannot run it, so the requirement is a hard floor.\n 228│\n 229│## [0.13.4] - 2026-07-04\n    │...\n 233│### Fixed\n*234│- **A live agent's Psyche that can't establish its listening perch now fails visibly instead of silently restarting forever.** On machines that belong to more than one subnet, the Psyche's listener could be refused at startup in a way it mistook for a normal shutdown — so it quietly exited and got restarted every few seconds, indefinitely, wasting resources with no visible sign. That refusal now surfaces as a real, loggable fault. Note: on multi-subnet machines the Psyche still can't hold its listener ...\n 235│\n 236│## [0.13.3] - 2026-07-04\n 237│\n    │...\n 254│### Fixed\n*255│- **Clearing a live agent's context no longer silently breaks its message delivery.** Every time a live agent's session was cleared — by hand or as part of a checkpoint — the machinery that delivers incoming messages into the session could be shut down as collateral, and from then on messages quietly piled up unseen until the agent was restarted. Delivery now survives clears. This also removes the main reason a checkpoint's follow-up instruction (`/sptc:commune --checkpoint`) never appeared after the...\n 256│\n 257│## [0.13.0] - 2026-07-03\n 258│\n    │...\n 278│### Fixed\n*279│- **Checkpoint waits until after the session clear to send the wake message.** When a live agent checkpoints (`/sptc:commune --checkpoint`), it clears its context and then continues with a follow-up instruction. Previously the follow-up could be submitted before the clear finished, so it ran against the old context (or was lost). The clear now always completes first, and the follow-up runs as the first turn of the fresh session — reliably, regardless of how long the clear takes.\n 280│\n 281│### Changed\n 282│- **Session names now include the project folder.** Alongside the `<id> @ <node>` naming, your Claude Code sessions now show the project folder they're running in — e.g. `myagent @ lab (my-project/)` in the prompt box and `/resume` picker — so you can tell apart agents working in different projects on the same node. Remote-control names carry it too. Existing sessions pick up the new name on their next start.\n    │...\n 378│\n*379│> Requires spt-core **v0.15.0 or newer** (was v0.13.2). This release adds self-checkpointing for live agents, automatic resume context, and clearer multi-line message delivery — all built on features that arrive in spt-core v0.15.0.\n 380│\n 381│### Added\n*382│- **Self-checkpointing for live agents — `/sptc:commune --checkpoint`.** A live agent can now reset and rebuild its own context without you running `/clear`. Write a commune containing the marker `!!checkpoint!!` and the session clears itself, then wakes back up from that very commune and keeps going. A single `!!checkpoint!!` wakes with a default \"Proceed with next steps\"; a **pair** of markers wakes with whatever instruction you write between them. The marker is one-shot — it never lingers in your ...\n*383│- **Automatic resume context.** When a live agent's session starts (or clears), it now pulls its durable role, working context, and latest unsynced commune and re-injects them automatically — so it resumes where it left off instead of coming back blank.\n 384│\n 385│### Changed\n 386│- **Incoming messages are easier to read.** A message delivered from another agent now renders across multiple lines — the envelope opening, the body, and the close each on their own line — instead of one dense single line.\n*387│- **Requires spt-core v0.15.0+** (up from v0.13.2). Self-checkpointing and resume context both rely on capabilities introduced in that release; `/sptc:setup` and `spt adapter update` will keep you current.\n 388│- Adapter version of truth is now **0.7.0** (shown in `/sptc:version` and the release tag).\n 389│\n 390│## [0.6.2] - 2026-06-23\n    │...\n 427│### Changed\n*428│- **Your live-agent companion now runs in a safe, limited mode.** When you go live with `/sptc:live`, the background companion that writes your context-resume notes works with a file-only toolset and a lighter, cheaper model. It is more contained and costs less to run, with no change to what you see or do.\n 429│- **Removed the experimental `:deep` profile.** `claude-spt:deep` was an unused placeholder. The one shipped profile overlay is `claude-spt:ccs` (routes sessions through `ccs`). If you ever selected `:deep`, use `:ccs` or the base adapter instead.\n 430│\n 431│### Fixed\n    │...\n 453│### Fixed\n*454│- **Live agents now reliably start their background companion.** Previously a live agent could come up marked \"online\" while its persistent companion silently failed to start, leaving it with no running context. The companion now launches and stays resident.\n 455│\n 456│### Changed\n 457│- **Simpler setup — no manual PATH step.** The adapter's helper tools are now found automatically from where the adapter is installed; `/sptc:setup` no longer asks you to copy anything onto your PATH.\n\n# CHECKPOINT-CLEAR-RACE-PLAN.md#5A9E\n 74│- **(Q1) Orphan-wake guard.** If the checkpoint's own clear fails to fire the signal (hook error), the\n*75│  armed wake fires on the NEXT clear — possibly a slightly-wrong context. The every-clear-fire model\n 76│  self-limits it (won't sit forever). Options: (a) ACCEPT for v1 (simplest, self-correcting; document\n 77│  in KNOWN-HAZARDS) — RECOMMENDED; (b) bound staleness with a translate-side generation/timeout on the\n 78│  armed wake. Decide before impl.\n\n# CHECKPOINT-COMMUNE-PLAN.md#1DCB\n  12│1. **Feature 1 — multi-line `<EVENT>` envelope** (cosmetic; visual distinction of inbound idle msgs).\n *13│2. **Feature 2 — checkpoint communes** (agent-driven context-compaction: flagged commune → auto\n  14│   `/clear` → wake; re-seed carried by spt-core's resume verb).\n  15│3. **Parity wiring — `psyche-download` at SessionStart** (foundational; closes a pre-existing gap\n *16│   where claude-spt live agents get NO durable resume context today — only the identity brief).\n  17│\n  18│## Hard public-surface findings (logged separately)\n  19│\n *20│- **F-0xx psyche-download verb absent** — `download_psyche_context` (spt-core resume.rs:88) is\n  21│  exported-but-unexposed (zero `ApiCmd` callers). No published `spt` verb let an adapter pull resume\n *22│  context. CONFIRMED spt-core gap. **RESOLVED-PENDING: v0.15.0 W5** exposes the verb (frozen contract\n *23│  below) + W4 doc work. Foundational — claude-spt resume context is broken without it.\n  24│- **F-0xx PreToolUse poll missing** — claude-spt polls only on `UserPromptSubmit` (between turns).\n  25│  Legacy spt also polls+injects on **PreToolUse** = the mid-turn message-delivery half of live-agent\n  26│  reachability. Standalone parity gap; not yet wired here.\n    │...\n  50│  <live-role>…</live-role>                       (if a role authored; else omitted)\n *51│  <live-context>…</live-context>                 (durable agents/<id>/live-context.md)\n *52│  <project-context-resolved name=\"<proj>\"/>      (sentinel — present iff in a resolved project)\n *53│  <project-context>…</project-context>           (durable projects/<proj>/<id>/project-context.md)\n  54│  <pending-commune>…raw drop body…</pending-commune>   (ONLY if not-yet-synthesized; TRIGGER STRIPPED core-side)\n  55│  <pending-signoff>…raw drop body…</pending-signoff>   (likewise for signoff)\n  56│\n *57│Empty/no-context → NO-CONTEXT signal on stderr (mirrors legacy $LIVE psyche-download) → inject nothing.\n  58│```\n  59│FRESHNESS: `<pending-*>` present iff a drop is not-yet-synthesized → one call always returns\n  60│durable + freshest un-synthesized delta. Race-free (core owns read+ingest; no adapter TOCTOU).\n    │...\n  81│  kept — no adapter strip. (Open: durable-ingest strip so the marker doesn't persist in\n *82│  live-context.md post-synthesis — doyle/todlando's call.)\n  83│- **Re-seed is core-owned** — no adapter-side raw drop reading (would TOCTOU core's pulse-delete,\n  84│  ingest.rs:161). The single `psyche-download` call carries durable + pending.\n  85│\n    │...\n 101│  Add a `[[hints]]` entry. Verify the commune body format matches the daemon's two-slice\n*102│  `<live-context>/<project-context>` envelope (or document the freeform→ingest behavior).\n 103│- **T2b PostToolUse hook (NEW)** — matcher Write; on Write of `.claude/<id>-commune.md`: scan\n 104│  `tool_input.content` (NOT a file re-read) for `!!checkpoint!!`; if present → `spt api state idle`\n 105│  → `spt send --from <id> <id> <wire-sentinel[+wake-text]>`. Resolve `<id>` (SPT_ENDPOINT_ID / whoami);\n\n# CONTEXT.md#76E6\n  59│an inbound peer message while the full SPT event envelope enters the same model\n *60│turn as extension-provided context. The peer body is never interpreted as an\n  61│OMP slash command.\n  62│_Avoid_: typing the peer body directly into the OMP editor\n  63│\n    │...\n  70│**OMP-native checkpoint** — an agent-driven continuity transition that saves\n *71│the current live context, resets OMP context through native session APIs, and\n  72│wakes the same endpoint from the saved state without operator intervention.\n  73│_Avoid_: Claude `/clear` keystroke choreography, save-only checkpoint\n  74│\n    │...\n  89│\n *90│**startup brief** — concise adapter-authored context supplied when an OMP\n  91│session activates, teaching identity, roster, messaging, continuity, and\n  92│lifecycle operations that the session can perform through public `spt` commands.\n  93│It is guidance, not a parallel command or transport layer.\n    │...\n  95│\n *96│**update notice** — concise agent-facing context emitted when the active\n  97│spt-core or omp-spt version is known to trail an available compatible release.\n  98│It identifies the affected component and the public update command.\n  99│_Avoid_: silent background update, generic startup announcement\n    │...\n 108│**signoff** — an agent-authored final continuity drop followed by graceful\n*109│endpoint shutdown. The OMP-native signoff skill keeps final context explicit\n 110│rather than relying solely on automatic echo-commune.\n 111│_Avoid_: commune, forced endpoint stop\n 112│\n    │...\n 120│\n*121│**targeted hint** — concise adapter-authored context injected when a user turn\n 122│clearly concerns live activation, identity, messaging, subnet onboarding, or\n 123│checkpointing. A hint points to the canonical capability without replacing its\n 124│full instructions.\n\n# DIGEST-FETCHER-PLAN.md#C11C\n 20│     Closes the \"ccs CLAUDE_CONFIG_DIR not expressible statically\" gap FOR REAL: the captured\n*21│     per-session value reaches the on-demand extractor in the daemon's context.\n 22│   - version → 0.10.0 + history note.\n 23│3. **Extractor** (`tools/claude-spt/src/digest.rs`):\n 24│   - New `--config-dir <dir>` flag: dir-branch root = `<config-dir>/projects` (highest precedence,\n\n# ECHO-COMMUNE-PLAN.md#7F0D\n 27│   takes a bounded tail, runs ONE headless `claude -p` turn (psyche-parity sandbox, Read-only\n*28│   tools), prints the context-delta summary to stdout. Loud nonzero on any failure.\n 29│   `recursion_guard_env = \"SPT_ECHO_COMMUNE\"` per the published role table.\n 30│3. **Hook recursion-guard bail** — `claude-spt hook` exits 0 immediately (no api calls, no\n 31│   perch writes) when `$SPT_ECHO_COMMUNE` is set: the summarizer's spawned claude must never\n\n# MANIFEST-PARITY-PLAN.md#8AC9\n  4│> target #2, the spt-core registry side) against the REAL v0.7.0 published surface, then the M12\n *5│> parity surfaces. NEEDS public-docs research first — run in clean context.\n  6│\n  7│## Public-surface-only (hard constraint — re-read)\n  8│\n   │...\n 61│     - **DONE (this session, triaged vs the v0.7.1 surface)** — signoff (`spt endpoint shutdown` —\n*62│       graceful + final context save, exact match) + list-agents (`spt endpoint list` — the roster).\n 63│       7/11 skills now operative. (force-stop/list-agents/new-alarm had no `[strings.skills]` entry;\n 64│       list-agents now added.)\n 65│     - **TODO — remaining 4, classified (don't invent):**\n\n# NEXT-WORKLOAD-PLAN.md#3DB0\n 104│- **Confirm-back:** a message-sent confirmation fired to the SENDER's OWN perch,\n*105│  `--active-only --ephemeral` (lands in-context mid-turn, never stale). Without it the agent re-sends\n 106│  via Bash, defeating the feature.\n 107│- **Commune shortcut:** `>>commune<<` at output start → hook writes `.claude/<id>-commune.md`, body =\n 108│  the output following the marker; feeds the same daemon ingest as the Write path (Write path retained).\n    │...\n 170│\n*171│## Cross-cutting knowledge (for context rebuild)\n 172│- Digest fetcher = PULL/PUSH, no cadence (doyle, code-authoritative). `--follow` = activity reactor\n 173│  only; idle detection needs a self-driven clock (generous periodic-pull heartbeat; each pull spawns the\n 174│  fetcher — don't thrash).\n\n# OMP-ADAPTER-PLAN.md#199F\n  86│`<msg from=\"…\"/>` user-visible stub. The complete SPT `<EVENT …>…</EVENT>`\n *87│envelope is supplied as context for that same turn. Peer text remains opaque\n  88│content; a message beginning with an OMP slash command cannot become local\n  89│operator input.\n  90│<!-- [doc->REQ-OMP-MESSAGE-CONTEXT] -->\n    │...\n 113│The Psyche is not a resident second endpoint. Each invocation is one bounded\n*114│headless OMP turn using the core-written context file and its own private OMP\n 115│session directory, then exits. OMP subagents are not advertised as independent\n 116│SPT Workers.\n 117│<!-- [doc->REQ-OMP-READY-LIVE] -->\n    │...\n 134│  <!-- [doc->REQ-DIST-DIGEST-EXTRACTOR] -->\n*135│- `[session.echo_commune]` self-locates history and prints one bounded context\n 136│  delta on stdout; spt-core owns the file drop, ingest, and deletion.\n 137│  <!-- [doc->REQ-SESSION-ECHO-COMMUNE] -->\n 138│\n\n# PARITY-PUBLISH-PLAN.md#5DEE\n  91│### Phase D — ccs profiles (LOCKED ADD)\n *92│- **Research first** (mcp/context7 not needed — read SCOPE §ccs + the existing `[profiles.*]`\n  93│  command seams). ccs profile = a `[profiles.<glm|kimi>]` overlay that leaf-replaces the spawn /\n  94│  psyche / echo command templates to route through `ccs <profile> …`, with a per-profile `~/.ccs`\n  95│  log dir. Author profile *templates* only (no user keys).\n    │...\n 122│\n*123│## Done immediately before (context)\n 124│- 4b042cc live sub-slice (claude-spt-psyche runner + /sptc:live body, REQ-SKILL-LIVE [doc,impl,unit]).\n 125│- 692b67c F-004 flip (digest-proof int GREEN on v0.7.2, REQ-DIST-DIGEST-EXTRACTOR full).\n 126│- spt upgraded 0.7.1 → 0.7.2 (operator-approved daemon bounce).\n\n# PEROS-RERELEASE-PLAN.md#C5EE\n 43│\n*44│## Known context\n 45│- doyle is OFFLINE — the F-009/F-010 findings (in `docs/SPT-CORE-FINDINGS.md` + commit ddf1965) are\n 46│  PENDING delivery; retry `spt send doyle --from perri`. The auto-update test (task 4) does NOT need\n 47│  doyle, but coordinating the spt-core findings does.\n\n# PSYCHE-EPHEMERAL-PLAN.md#7865\n 149│3. **E2E (live-verify window)**: commune drop → daemon ingest → psyche_resume invocation\n*150│   → synthesis lands in tracked context — THROUGH the new shim. Rig: fresh probe endpoint\n 151│   live bringup on the floor core; assert (a) exactly one `claude-spt psyche` process per\n 152│   event, zero resident survivors between events; (b) commune content reflects the event.\n 153│\n    │...\n 193│4. **Docs findings**: (a) per-event psyche_resume undocumented because UNWIRED — feature\n*194│   gap, docs land with F-030; (b) `{psyche_context}` example-vs-keylist = genuine\n 195│   published-docs bug, folded into the F-030 docs pass. Neither blocks the adapter half.\n 196│\n 197│## Tasks\n\n# README.md#7B03\n  7│`ReadyAgent` and `LiveAgent` endpoints in OMP's own terminal interface, with agent-to-agent\n *8│messaging, session continuity, history, digests, and live-agent context lifecycles.\n  9│\n 10│Native OMP owns the attachable TUI and its broker PTY. The packaged OMP extension handles endpoint\n 11│binding, message delivery, busy/idle state, replies, and shutdown from inside that native session.\n\n# SCOPE.md#A974\n  28│   - One serialized custody queue.\n *29│   - Message stub plus the full SPT event context in the same OMP turn.\n  30│   - Correlated reply or explicit failure for every accepted delivery.\n  31│   - Honest busy/idle state.\n  32│   - Bounded listener restart followed by loud session teardown and OMP\n    │...\n  68│- A headless RPC bridge or any second endpoint topology.\n *69│- Any foreign-harness plugin, hook, context-injection, command launcher, update\n  70│  reconciliation, or model-wrapper compatibility layer.\n  71│- Worker endpoint advertisement for OMP subagents.\n  72│- Migration of inherited `.spt` predecessor continuity.\n    │...\n 107│| Active-turn delivery uses safe boundaries | ADR-0017 | Locked |\n*108│| Checkpoint resets context natively | ADR-0018 | Locked |\n\n# SETUP-SLICE-PLAN.md#4A80\n 68│   runtime digest/Psyche do — so this never blocks the activation step.\n*69│3. **Setup context detection.** Skill probes for a local `adapter/claude-spt.toml` (operator\n 70│   dogfooding from a checkout → file-form) else uses `--github <Wave-C repo>` (casual end-user).\n 71│\n 72│## Waves\n\n# SKILLS-SLICE-PLAN.md#A7D6\n  26│       (that's a `[session.self]` fill — the published manifest.md example wrongly uses it and HARD-FAILS;\n *27│       doyle fixed the example). NOT `{psyche_context}` on first spawn (that's the resume/preload seam key).\n  28│       In spawn_psyche `{id}` is OVERRIDDEN to `<parent>-psyche`. Template only the four; `keys` a subset.\n  29│     - **Q3 Psyche process contract:** FIRE-AND-FORGET DETACHED — spawned with Stdio::null on all three\n  30│       fds, handle dropped, NOT supervised (liveness is daemon-authoritative via the perch, not pid).\n    │...\n 120│\n*121│## Done earlier this session (context)\n 122│- d1f14ab `[session.self]` + bind path (REQ-DIST-SHORTCUT-BASENAME [doc,impl,unit]).\n 123│- 39c05d1 digest extractor (Rust) (REQ-DIST-DIGEST-EXTRACTOR [impl,unit]; int F-004-blocked, doyle fixing).\n 124│- 8487ea0 large-drain cap/spill (ADR-0002 Open #2 resolved).\n\n# SPT_HARNESS_ADAPTER_TIPS.md#CF70\n  77│  `additionalContext` over ~10k chars by spilling it to a file, which *evicts it from the inline\n *78│  context the agent sees* — a large drain (or a big skill body + drain together) silently loses\n  79│  messages. Cap the combined hook output adapter-side under the threshold: under it pass through\n  80│  verbatim; over it spill the **full** text to an agent-readable file and inject only a short\n  81│  pointer. Never a mid-`<EVENT>`/mid-record head-cut — that splits an envelope and drops a message.\n    │...\n 172│  own derived perch id, not the parent's. (`{session_name}` is a `[session.self]` fill, not a psyche\n*173│  key; a first spawn has no `{psyche_context}` — that is the resume/preload key, a different seam.)\n 174│- The companion is launched **detached, fire-and-forget**: `detach = true`, `cwd = \"{psyche_dir}\"`,\n 175│  stdio null, handle dropped, **unsupervised** — liveness is daemon-authoritative via the companion's\n 176│  perch, not its pid. It owns the `<parent>-psyche` perch, communicates by perch + commune file-drops\n\n# adapter/\n## manifest.schema.json#63B7\n 177│    \"Hook\": {\n*178│      \"description\": \"`[hooks.<event>]` — one harness event → the `api` command it fires, the\\nstdin fields it maps, and whether it can surface context to the agent.\",\n 179│      \"type\": \"object\",\n 180│      \"properties\": {\n 181│        \"fires\": {\n    │...\n 191│        \"can_inject\": {\n*192│          \"description\": \"Whether this hook can inject context (false ⇒ sentinel/relay fallback).\",\n 193│          \"type\": \"boolean\",\n 194│          \"default\": false\n 195│        }\n    │...\n 291│    \"SessionRole\": {\n*292│      \"description\": \"`[session.<role>]` — one opaque outbound command template plus its spawn\\ncontext. Model/tools/flags all live inside `command`, never as fields\\n(MANIFEST §session roles). No nested tables here (keeps TOML round-trip\\nemission scalar-before-table clean).\",\n 293│      \"type\": \"object\",\n 294│      \"properties\": {\n 295│        \"command\": {\n    │...\n 932│    \"Hint\": {\n*933│      \"description\": \"`[[hints]]` — one once-per-session keyword hint (CONTEXT.md §keyword hints).\\nThe adapter's user-prompt hook pipes the full user message to `spt api hint`;\\na matching keyword surfaces `text` to the agent's context channel, at most\\nonce per session and once per message.\",\n 934│      \"type\": \"object\",\n 935│      \"properties\": {\n 936│        \"keywords\": {\n## omp-spt.toml#72C0\n 54│[session.psyche_init]\n*55│command = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\n 56│# Prevent a child Psyche from inheriting its parent's SPT identity.\n 57│env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\n*58│keys = [\"id\", \"session_id\", \"psyche_context_file\"]\n*59│# Each Psyche event is one bounded OMP turn. The context file is read by the\n 60│# shim, the event arrives on stdin, stdout carries the result, and exit 95 asks\n 61│# [impl->REQ-PSYCHE-EPHEMERAL-SHIM]\n 62│[session.psyche_resume]\n*63│command = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"\n 64│detach = false\n 65│# Prevent a child Psyche from inheriting its parent's SPT identity.\n 66│env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]\n*67│keys = [\"id\", \"session_id\", \"psyche_context_file\"]\n 68│\n 69│# Fresh endpoints launch validated native OMP with the packaged extension. The\n 70│# launch shim snapshots only non-secret OMP locator/profile/executable selectors","linesTruncated":true,"meta":{"limits":{"columnTruncated":{"maxColumn":512}}}},"isError":false,"timestamp":1784188883279}}
{"type":"message","id":"6de84c62","parentId":"b773df9f","timestamp":"2026-07-16T08:01:23.286Z","message":{"role":"toolResult","toolCallId":"call_G377XUb6qzsCCjdQFceqflUB|fc_03e5b91f227b0634016a588fd33258819ba0432e9cf9b0907f","toolName":"grep","content":[{"type":"text","text":"# docs/\n## CI.md#96F6\n 28:\n*29:These are binary pass/fail checks. A release run must treat any `SKIP` caused by a missing interpreter, Rust toolchain, platform binary, or `traceable-reqs` installation as an incomplete gate, provision the dependency, and rerun. The archive test may intentionally prove that the packer refuses missing platform binaries, but a release still needs both platform builds before packaging. The live acquisition integration intentionally skips unless `OMP_SPT_ACCEPTANCE=1`; after opt-in, missing release variable...\n 30:\n 31:## Native OMP release acceptance\n 32:\n*33:ADR-0013 sets the release boundary. For v0.2.0, the only supported release hosts are **x86_64 Windows** (`x86_64-pc-windows-msvc`) and **x86_64 Linux** (`x86_64-unknown-linux-gnu`); the asset has no macOS or Arm64 payload. Acceptance must use the exact tagged candidate `adapter.spt`, a real `omp` installation, the native packaged extension, and disposable endpoint identities. Complete the full acceptance sequence independently on both supported hosts before promotion. Do not reuse an operator's long-live...\n 34:\n 35:Install the tagged candidate on each acceptance host and verify its manifest version:\n 36:\n...\n 99:\n*100:## Adapter release boundary\n 101:\n 102:Cross-node transport is outside the `omp-spt` release gate. Once the exact message contract succeeds through the adapter on one node, subnet routing adds no OMP-specific seam and belongs to spt-core. A cross-node check may be useful for spt-core qualification, but it must not replace or block the same-node adapter acceptance above.\n 103:\n## DOCS-STRATEGY.md#02F5\n 7:\n*8:## Audience and product boundary\n 9:\n 10:The documentation serves human operators and development agents integrating with\n 11:[`BigscreenVR/omp-spt`](https://github.com/BigscreenVR/omp-spt). Author each fact once in clean\n...\n 52:\n*53:- **Introduction:** what `omp-spt` does and the OMP / spt-core ownership boundary.\n 54:- **Requirements:** supported spt-core floor, supported hosts, and an installed native OMP.\n 55:- **Quickstart:** install the release adapter, create endpoint `atlas`, and attach to its native\n 56:  TUI.\n...\n 98:- Manifest reference for `[adapter]`, `[update]`, `[identity]`, `[session]`, `[history]`,\n*99:  `[digest]`, environment injection, and shared strings.\n*100:- Extension reference for bind, message custody, context injection, correlated replies,\n 101:  activity, session-switch refusal, recovery, and shutdown.\n 102:- `adapter.spt` reference for the root manifest, `strings/omp-spt.mjs`, and supported host\n 103:  binaries.\n*104:- Release verification checklist and the explicit adapter / spt-core boundary.\n 105:\n 106:Each major capability can use the same internal sequence when it needs more than one page:\n 107:`Overview -> Tutorial -> How-to -> Reference -> Explanation`. Do not force all five page types\n...\n 208:  switching, graceful shutdown, and both hostable roles.\n*209:- Stop at the adapter boundary. Once same-node delivery proves the adapter handoff, cross-node\n 210:  transport is a spt-core concern rather than an `omp-spt` release gate.\n 211:\n 212:## Anti-patterns\n## KNOWN-HAZARDS.md#B907\n 3:This is the OMP adapter's conformance checklist. Each entry states a failure\n*4:mode, the invariant that prevents it, the evidence boundary, and its source.\n 5:An invariant is not covered merely because it is described here: the active\n 6:requirement must point at production behavior and a focused test.\n 7:\n## OMP-BRIDGE-FIELD-ISSUES.md#3624\n 37:   attachable OMP TUI.\n*38:6. **Release boundary:** same-node message/turn/reply behavior is required;\n 39:   cross-node transport is not re-tested by the adapter.\n 40:\n 41:## Public-contract status\n## PARITY.md#2CFD\n 28:Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n*29:commands with argument completion or native selection dialogs. Explicit live\n 30:auto-resume selects the most-recent compatible live identity; ordinary\n 31:activation never guesses silently. The extension binds the current session and\n 32:owns the authenticated listener, after which binding is immutable.\n 33:\n*34:<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\n*35:Messages accepted during an active OMP turn enter at the first proven boundary\n*36:before the next tool or model continuation. Custody and arrival order remain\n*37:intact; a turn with no injectable boundary falls back to ordinary next-turn\n 38:delivery rather than interruption.\n 39:\n 40:<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\n...\n 121:1. repair version and documentation truth, then prove packaged-skill discovery\n*122:   and injectable OMP event seams;\n 123:2. implement extension-owned ready/live activation, live auto-resume,\n*124:   safe-boundary delivery, and abnormal-turn receivability;\n 125:3. add startup briefs, targeted hints, update notices, packaged skills,\n 126:   checkpoint continuity, hybrid setup, and peer-message shortform;\n 127:4. add the musl target and durable machine-readable acceptance records for all\n## RELEASE-RUNBOOK.md#7E13\n 217:\n*218:Cross-node transport is not an `omp-spt` release gate. Do not delay the adapter release on a subnet routing check after same-node delivery has proved the adapter boundary.\n 219:\n 220:If any acquisition, version, or native acceptance item fails on either target, leave the release marked as a prerelease, fix the source, and cut a new version. Do not replace a tested tag or asset in place.\n 221:\n## SKILL-AUTHORING.md#2E4C\n 33:|---|---|---|\n*34:| **A — injected** | thin `plugin/sptc/skills/<n>/SKILL.md` stub + `adapter/strings/skills/<n>.md` body (manifest `[strings.skills].<n>`) | Skills the **user** invokes (`/sptc:<n>`) or a hint surfaces. The UPS hook injects the body on the slash-command. |\n*35:| **B — full-fat** | `plugin/sptc/skills/<n>/SKILL.md` only — operative body in the SKILL.md, **no** `[strings.skills]` entry, **no** adapter body | Skills the **agent self-drives reactively** without the user typing `/sptc:<n>` — `send`, `commune`, `signoff`. UPS-injection fires only on a slash-command in the prompt, so it cannot deliver these; the always-loadable SKILL.md does. |\n 36:\n 37:Self-drive anchor (both patterns): point the agent at the live source of truth where one exists —\n 38:`spt how-to <topic>` (ready · send · subnet · live) or `spt <verb> --help` — instead of duplicating\n...\n 58:>\n*59:> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check\n 60:> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.\n 61:\n 62:<One line naming what the skill does.>\n...\n 64:\n*65:**Pattern A — adapter body** (the injected operative instructions):\n 66:\n 67:```md\n 68:# /sptc:<name> — operative instructions\n...\n 95:`setup` is **self-contained on both surfaces**: it runs precisely when spt-core may be absent, so\n*96:injection can no-op. Its plugin SKILL.md keeps the operative steps as the floor; tighten it, never\n 97:reduce it to a stub.\n 98:\n 99:## `description` rules (from write-a-skill)\n...\n 110:- [ ] Bringup skills (`ready`/`live`) are minimum-friction — fire and announce, no marker-gating.\n*111:- [ ] Right pattern: agent-self-driven (`send`/`commune`/`signoff`) → full-fat, no injection.\n 112:- [ ] Cites `spt how-to`/`--help` where one exists; `allowed-tools` is the minimum.\n 113:- [ ] `[<doc>->REQ-*]` traceability tags preserved.\n## SPT-CORE-FINDINGS.md#CCCF\n 10:|---|------|--------|---------|\n*11:| F-001 | 2026-06-14 | **re-scoped 2026-06-15** — most = adapter-authoring (closed); 1 residual spt-core docs item open | Hook-wiring for a CC adapter — boundary clarified |\n 12:| F-002 | 2026-06-15 | **RESOLVED-SHIPPED (v0.7.1)** — `<EVENT>` verified on the published `api poll` surface; F-002 dissolved; int flipped | `api poll` agent path has no inter-frame delimiter → multi-message drains are unsplittable |\n 13:| F-003 | 2026-06-15 | **RESOLVED + docs CLOSED (v0.7.1)** — capability shipped; the file-pointer syntax is now on the published surface | File-backed `[strings]` IS shipped (value-position table pointer `key = { file = \"rel\" }`) but was **undocumented** on the published surface |\n 14:| F-004 | 2026-06-15 | **CONFIRMED-IMPL-BUG (doyle); fix in progress** — `digest-proof` will fill `{id}`+`{session_id}` matching runtime; int deferred until the carrying release | `spt adapter digest-proof --sample` passes an empty substitution-key map → false-fails any extractor whose command uses `{session_id}` (incl. the published example) |\n...\n 20:| F-010 | 2026-06-16 | **RESOLVED-SHIPPED + RE-VALIDATED (spt v0.8.2, 2026-06-17)**. A spawn-then-exit psyche now stamps `psyche_host_error{reason:\"host not resident within 5s ...\", attempts:2}` on the parent perch (rendered `psyche-host: FAILED (...)` by `endpoint list`/`whoami`); status stays online (liveness authoritative). Forced fast-exit confirmed it | Silent-exit still maskable: `psyche_host_error` stays clear when the detached spawn() succeeds but the child exits IMMEDIATELY (e.g. arg-parse exit ...\n*21:| F-013 | 2026-06-17 | **ROOT-CAUSED (perri) → RULED spt-core BUG (doyle 2026-06-17): fork (a)**. spt-core must honor `[env].value` substitution in endpoint-run (the schema already promises \"with substitution\"; not applying it is a silent correctness bug). **Adapter manifest is CORRECT as-is — no wrapper** (b rejected: a shim would dodge a bug every `[env]`-routing adapter hits). Dispatched **`REQ-HAZARD-ENV-SUBST` → todlando, v0.11.0-findings** (pairs with REQ-SEND-SPT-HOSTED). **VERIFIED FIXED + ...\n 22:| F-011 | 2026-06-17 | **CONFIRMED + ROOT-CAUSED (doyle, spt-core source) — case-3 robustness, NON-blocking**. doyle: `registry.rs` `manifest_dir` — Pointer/GhReleaseManaged adapters read the manifest LIVE from `source_dir`; a deferred install whose manifest isn't extracted yet → `load_manifest` fails → `registered()` `filter_map(...ok())` **SILENTLY DROPS** the adapter → zero host_binaries candidates (`ADAPTER_UNRESOLVED`) AND `resolve_option/set_active` reads the absent manifest → bare **os...\n*23:| F-016 | 2026-06-22 | **RESOLVED — both fixes SHIPPED** (doyle, broker.rs-confirmed). The published `[message-idle-translation-binary]` doc omitted `{commit}` from the stdout vocabulary AND its degenerate baseline `{text}{key:enter}` would itself FAULT. `{commit:true}` is the MANDATORY inject-sequence terminator (`run_inject_worker` broker.rs:1075-1090; no-commit → 5s `INJECT_COMMIT_DEADLINE` FAULT, broker.rs:151-169; reference `{text}{key:enter}{commit:true}` translation.rs:74-78). **(i) adapter bi...\n*24:| F-017 | 2026-06-22 | **RESOLVED-SHIPPED (spt-core v0.14.0, counter 30) + VALIDATED on real claude-spt (perri, 2026-06-23)**. v0.14.0's endpoint-creation-flow milestone (REQ-RUN-MULTISUBNET-HOME, ADRs 0026/0027) closed it: `spt endpoint run` now HOMES at creation — multi-subnet node w/o `--subnet` → instant **`MULTI_SUBNET_HOME`** refuse + subnet list (0.058s, NOT the old ~25s silent `ENDPOINT_RUN_ONLINE_TIMEOUT`); `--subnet <name>` → homes + harness binds (UNBOUND → online), no HOME_REFUSED. Bo...\n 25:| F-018 | 2026-06-22 | **REPORTED to doyle (perri) — destructive footgun, os-2 family (F-011 sibling)**. Surfaced while constructing the F-015 brick repro on v0.13.2. `spt adapter add --github <user/repo>` on an **already-registered, already-extracted gh_release Pointer adapter** is destructive-then-cryptic: it git-clones the SOURCE repo over the extracted install dir (wiping the root `manifest.toml` + the 3 runtime `.exe` binaries the Pointer resolves), then the post-add first-`[update]` conduct fails...\n*26:| F-020 | 2026-06-24 | **RESOLVED-PENDING — frozen Tier-1 contract, ships v0.15.0 W5** (doyle ruled + grounded; verb committed by todlando @20bfc1f). spt-core publishes NO `spt api` verb to pull resume/psyche context at SessionStart — `download_psyche_context` (resume.rs:88) is exported-but-unexposed (ZERO `ApiCmd` callers); `resume.rs:9` documents the \"adapter pulls it in its SessionStart hook\" intent but no verb was ever published. **Consequence: claude-spt live agents rehydrate NO durable context ...\n 27:\n*28:| F-023 | 2026-07-01 | **CONFIRMED + RCA'd (doyle, same day) — build dispatched to todlando (`BUILD-F023-WANIDLE`)**. Both ranked hypotheses real: `receive_wan` has deliver_tcp + spool ONLY (the spt-hosted broker-inject leg exists solely in local `cmd_send`) AND no idle-edge drain exists anywhere. Fix = shared inject leg called from WAN ingress + ACTIVE→IDLE spool drain. Adapter exoneration stands verbatim. `from_id=\"\"` sibling ruled: compose stamps `cli@<node-label>`; ingress renders empty-from as o...\n 29:| F-024 | 2026-07-01 | **CLOSED-REFRAMED (doyle, same day) — transport EXONERATED; symptom = F-023 on the remote node.** The `(spooled)` token in `SENT(WAN)` output is RECEIVER-CONFIRMED (only prints on a confirmed round-trip): probe `DIAG-7c1e` reached ENLYZEAM post-restart and sits in ball-b's spool undelivered (`spooled` not `delivered` = no live TCP listener at receive time). Operator workaround: any prompt typed into ball-b UPS-drains the stuck messages. Residues stay real as separate diagnostics ...\n 30:| F-031 | 2026-07-08 | **REPORTED to doyle (perri) — docs gap; adapter worked around in v0.17.3 (REQ-HAZARD-SEND-STATUS-STDERR).** `spt send`'s result token (`SENT:<id>` / `QUEUED:<id>` / `DEFERRED:<id>` / `NO_PERCH:<reason>`) is written to **STDERR**, not stdout — stdout is empty on a plain `spt send`. This is undocumented in the published harness-contract / CLI reference (they describe the tokens as the send's *result* without naming the stream). It bit the claude-spt tag-messaging hook: the hook c...\n 31:\n*32:> **F-021 / F-022 (NOT spt-core findings — claude-spt parity items, tracked as REQs; surfaced during the 2026-06-24 checkpoint-commune grill)** — (F-021) claude-spt polls only on `UserPromptSubmit` (between turns); legacy spt also polls+injects on **PreToolUse** = the mid-turn half of live-agent reachability (the main path by which a live agent receives a message WHILE working). `api poll` already exists on the public surface → adapter wiring, not an spt-core gap → **`REQ-DIST-PRETOOL-POLL`**. (F...\n 33:\n 34:> **F-012 (NOT logged as spt-core)** — legacy-owl 1.11.25 poll-loop exits 1 / orphans the Psyche across daemon churn (`/spt:revive` started gen-7 wrapper+psyche fine but the foreground poll died with a non-fatal `sessions log seal failed: git failed (continuing)` line). doyle ruled this is the **legacy owl listener** (a separate daemon from spt-core), NOT an spt-core public-surface finding; the seal line is non-fatal/continues so isn't the exit cause; it dies with legacy owl's retirement. Re-open as sp...\n 35:\n...\n 43:- `harness-contract/api.md` — the full `spt api` primitive surface: `seed`, `listen`, `bind`,\n*44:  `boundary`, `session-end`, `shutdown`, `state`, `echo-gate`, `presence`, `driven-by`, `poll`,\n 45:  `history-log`, `worker-start/poll/stop`, `bind-shell`, `emit`, `owner-shutdown`, `capability`.\n 46:- `harness-contract/install-on-demand.md` — install-on-demand bootstrap, exact `sh` + `ps1`\n 47:  snippets, canonical installer URLs, env-var customization. **Fully buildable.**\n...\n 49:  `api seed --pid {parent_pid} --session-id {session_id}` then `api listen <id>`; Idle →\n*50:  `api state idle|busy`; PreCompact/clear → `api boundary clear|compact <id> --to-session-id <sid>`;\n 51:  teardown → `api session-end <id>` / `api shutdown <id>`.\n 52:\n 53:**The gaps:**\n...\n 58:2. **Manifest `[hooks.*]` vs harness-native hook config is unspecified.** `manifest.md` declares\n*59:   hooks as `[hooks.<event>] fires=\"api ...\" reads=[...] can_inject=bool`, with spt-core performing\n 60:   `{key}` substitution from `reads`. It is **silent** on whether spt-core *materializes* the\n 61:   harness-native config (Claude Code `hooks.json`) from the manifest, or the adapter author\n 62:   hand-writes `hooks.json` that shells out to `spt api`. These imply different substitution models:\n...\n 66:   calling `spt api`\" — it may instead be manifest-declared + spt-materialized.)\n*67:3. **Injection mechanism is undocumented.** `can_inject` + an `[inject]` section (methods\n 68:   `pty`/`hook`/`relay`/`http`) exist, but there is **no technical detail** on how an adapter emits\n 69:   `additionalContext` back through the hook channel. Blocks (a) general mid-session message\n*70:   delivery on a prompt/tool hook, and (b) this project's **UPS-injection** skill-instruction design\n 71:   (`docs/adr/0001-*`) specifically — it cannot be validated against the public surface until this\n 72:   is documented.\n 73:\n*74:**Impact (as first reported):** SessionStart / Stop(idle) / SessionEnd / boundary are buildable now.\n*75:UserPromptSubmit + PreToolUse + Subagent wiring + the entire injection path were *thought* blocked.\n 76:\n 77:### Resolution (2026-06-15 — converged with doyle, grounded in `CONTEXT.md`)\n 78:\n*79:The boundary canon (`CONTEXT.md` L52/L181/L112/L149/L137) re-frames F-001: **spt-core is\n 80:harness-independent and supplies the agnostic `spt api` primitives + their I/O format; the adapter\n 81:authors the harness-specific wiring + output-formatting.** So most of F-001 is **adapter-authoring\n 82:work (ours), not an spt-core gap**:\n...\n 86:  → `api listen <id>` (the blocking poll loop — *not* SessionStart, which must not block); Stop/Idle\n*87:  → `api state idle|busy`; PreCompact/clear → `api boundary`; SessionEnd → `api session-end` /\n 88:  signoff → `api shutdown`; SubagentStart/Stop → `api worker-start`/`worker-stop`; UserPromptSubmit\n 89:  → `api poll`; **PreToolUse out-of-scope v1** (UPS covers delivery). See `docs/adr/0002-*`.\n 90:- **Gap 2 (medium) — OURS, closed.** The `sptc` plugin **hand-writes** its CC `hooks.json` shelling\n 91:  `spt api`. spt-core materializing a CC `hooks.json` would violate L52/L181 — it correctly doesn't.\n*92:- **Gap 3 (injection HOW) — OURS, closed.** `api poll` emits message frames to **stdout** by design\n*93:  (L149) — that IS the hook-injection delivery path; routing/formatting that stdout into CC's\n*94:  `additionalContext` channel is adapter glue (L112). The earlier \"`can_inject`/`[inject]`\n 95:  method-discard is dead code\" alarm is **retracted** — it is M2a roadmap staging (stdout/hook only\n*96:  now; PTY at M3), and `can_inject` drives the *built* echo-gate/relay fallback (L137) for hooks that\n\n## adr/\n### 0001-distribution-splits-by-volatility.md#4F3E\n 3:<!-- [doc->REQ-DIST-BOOTSTRAP-INSTALL] -->\n*4:<!-- [doc->REQ-UPS-INJECTION] -->\n 5:# Distribution splits by volatility: a thin skeleton plugin, an spt-conducted manifest + binary\n 6:\n 7:## Status\n...\n 9:**Historical sister-lineage record — superseded for `omp-spt` by\n*10:[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n 11:\n 12:Preserved only as sister-project lineage for its original rationale and details. References to\n 13:Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n...\n 63:  A user who installs the plugin gets spt-core for free. [`REQ-DIST-BOOTSTRAP-INSTALL`]\n*64:- **Skill instructions are delivered by UPS-injection.** A `UserPromptSubmit` hook detects `/spt:X`\n*65:  in the prompt and injects X's real instructions as `additionalContext`, sourced from the adapter\n 66:  `[strings]` (file-backed, so the manifest doesn't bloat). SKILL.md files stay skeletons; the\n*67:  volatile instruction text lives in spt-core-conducted strings. [`REQ-UPS-INJECTION`]\n 68:- **The \"bulk\" install/update is manifest + binary**, conducted by spt-core's own framework (the\n 69:  file-pull channel), not a marketplace bump. The marketplace plugin rarely needs a version bump\n 70:  and never orphans an active install.\n...\n 76:- **fetch-stub skills** (SKILL.md fetches its real body at runtime) — VETOED by the operator:\n*77:  adds terminal noise, latency, and an extra tool call per invocation. UPS-injection chosen\n 78:  instead. (`SCOPE.md` §\"Skill-instruction delivery\".)\n 79:- **A fat plugin shipping the binary** (legacy `owl.exe` model) — couples high-churn logic to the\n 80:  marketplace cadence and forces the binary/handoff/cache-prune machinery the thin skeleton has no\n...\n 86:  fires on a `/sptc:X` slash-command with the token intact (`prompt:\"/sptc:send doyle\"` literal, hook\n*87:  fired, skill ran, on CC 2.1.177). The injection branch is built (`user-prompt-submit.sh`\n*88:  `sptc_skill_key` + `sptc_inject_skill`); the in-SKILL.md fallback is unneeded for injection (but\n*89:  `setup` stays self-contained — it runs when spt may be absent). (`REQ-UPS-INJECTION`.)\n 90:- **File-backed `[strings]` is an M12 spt-core dependency** — until M12 publishes, instruction\n 91:  bodies cannot be externalized; skeleton SKILL.md files may carry interim inline instructions.\n 92:  **Update 2026-06-15 — SATISFIED.** M12 (`spt 0.7.0`) ships file-backed `[strings]` as a\n...\n 125:  `doc`-stage evidence for `REQ-DIST-PLUGIN-SKELETON`, `REQ-DIST-HOOKS-API`,\n*126:  `REQ-DIST-BOOTSTRAP-INSTALL`, and `REQ-UPS-INJECTION`.\n### 0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md#EC6E\n 1:<!-- [doc->REQ-DIST-HOOKS-API] -->\n*2:<!-- [doc->REQ-UPS-INJECTION] -->\n 3:# Hook wiring: the sptc plugin hand-writes a CC `hooks.json` that shells `spt api`\n 4:\n 5:## Status\n...\n 7:**Historical sister-lineage record — superseded for `omp-spt` by\n*8:[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n 9:\n 10:Preserved only as sister-project lineage for its original rationale and details. References to\n 11:Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n...\n 46:| SessionStart (`startup`/`resume`) | `seed --pid <pid> --session-id <sid>` + write env aliases via `$CLAUDE_ENV_FILE` | non-blocking; records the pid↔session seed |\n*47:| SessionStart (`clear`/`compact`) | `boundary <clear\\|compact> <id> --to-session-id <sid>` | rebind perch, preserve identity |\n*48:| UserPromptSubmit | `poll <id>` → stdout → `additionalContext` | the message-delivery + UPS-injection path (L149) |\n*49:| Stop | `state idle <id>` | arms echo-gate fallback (L137) since Stop can't inject |\n 50:| (activity) | `state busy <id>` | on prompt/tool start |\n 51:| SubagentStart / SubagentStop | `worker-start <parent> <id>` / `worker-stop <id>` | nested worker perches |\n 52:| SessionEnd | `session-end <id>` | soft teardown; `shutdown <id>` on graceful signoff |\n...\n 57:\n*58:### Skill instructions (UPS-injection) ride the same UserPromptSubmit hook\n 59:\n 60:The `UserPromptSubmit` hook's stdout becomes CC `additionalContext`. The same channel that delivers\n*61:queued messages (`api poll`) is where `/sptc:X` skill-instruction injection lands (from the adapter\n 62:`[strings]`, M12-dep). `api poll` emitting to stdout is by design (L149); formatting it for CC is\n*63:ours. PTY/relay inject methods are M3 roadmap (M2a = stdout/hook only) — not a gap.\n 64:\n 65:### `api poll` parse contract — the `<EVENT>` envelope (operator-ruled 2026-06-15)\n 66:\n...\n 81:  `<EVENT>`s. `<EVENT-PART seq=\"N/M\">` exists only for the *listener stream* (the `« spt event »`\n*82:  Monitor's ~500-char `EVENT_LINE_THRESHOLD`); the hook-drain injects via `additionalContext` which\n 83:  has no per-line cap. **No id+seq reassembly on the poll path.**\n 84:\n 85:Parser (`render_frames`, `plugin/sptc/hooks/_common.sh`): split on `</EVENT>`; per envelope, read\n...\n 90:\n*91:**Harness injection-size limit is ours** (harness-agnostic boundary — spt-core emits whole\n 92:`<EVENT>`s regardless): CC `additionalContext` caps at **10,000 chars** (larger output is spilled to\n 93:a file by CC). A large multi-message drain can exceed it → adapter-side follow-up: truncate with a\n*94:marker or spill. (`REQ-UPS-INJECTION` `int` item.)\n 95:\n 96:### Portability\n 97:\n...\n 125:  SCOPE-flagged question: `UserPromptSubmit` fires on a `/sptc:X` invocation with the token intact,\n*126:  so the wrapper can detect `/sptc:X` in `prompt` and inject. (`REQ-UPS-INJECTION`.)\n 127:- ✅ **Windows `shell:\"bash\"` command hooks work** — the hook executed via Git-Bash,\n 128:  `$CLAUDE_PROJECT_DIR` resolved, exit-0 stdout honored. Resolves Open#2 for the POSIX-wrapper\n 129:  packaging on Windows (no per-OS branch needed for the hook to run).\n...\n 141:   `<EVENT-PART>` on normal drains, multi-drain splits on `</EVENT>`), and `render_frames` confirm-\n*142:   matched it. Locked by `ci/hooks/poll-int.sh` (5/5); `REQ-DIST-HOOKS-API` + `REQ-UPS-INJECTION`\n 143:   `int` flipped green. See `docs/SPT-CORE-FINDINGS.md` F-002.\n*144:2. **Large-drain injection size — RESOLVED (2026-06-15).** CC spills `additionalContext` over ~10k\n 145:   chars to a file (evicting it from the inline context the agent sees), silently losing messages.\n 146:   The UPS wrapper now pre-empts: `sptc_cap_output` (`_common.sh`) buffers the combined skill-body +\n 147:   drain, and over `SPTC_CTX_CAP` (9000, margin under 10k) spills the FULL text to an agent-readable\n...\n 154:\n*155:- `REQ-DIST-HOOKS-API` / `REQ-UPS-INJECTION` gain a concrete, grounded `doc` design here; their\n 156:  `impl` activates when the validated `hooks.json` + wrappers land (gated on Open #1).\n 157:- Supersedes the `ADR-0001` \"hooks.json delegates to `spt api`\" stub with the full wiring; ADR-0001's\n*158:  UPS-injection open item (UPS-fires empirical) is carried here as Open #2.\n 159:- No spt-core dependency for the wiring itself — only the (non-blocking) residual docs publish of the\n 160:  `api poll` frame format, which we can substitute with observed behavior until it lands.\n### 0003-psyche-is-a-constrained-auto-approving-companion.md#3886\n 7:**Historical sister-lineage record — superseded for `omp-spt` by\n*8:[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n 9:\n 10:Preserved only as sister-project lineage for its original rationale and details. References to\n 11:Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n### 0004-checkpoint-via-self-send-loopback.md#0131\n 5:**Historical sister-lineage record — superseded for `omp-spt` by\n*6:[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n 7:\n 8:Preserved only as sister-project lineage for its original rationale and details. References to\n 9:Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n...\n 30:   delivery* to fire the macro.\n*31:3. **Re-seed staleness.** If the commune is authored *after* `/clear` (the boundary/resume-Self\n 32:   refresh path), the legacy `psyche-stale-after-clear` gap reappears (LLM-latency-bounded): the\n 33:   durable store and the drop file may both be absent/stale at the post-clear SessionStart.\n 34:4. **No daemon-push primitive.** The clean design — daemon detects the trigger in the commune it\n...\n 64:defers authoring to a post-clear resume-Self refresh (Shape 2). Shape 2 reintroduces force #3's stale\n*65:gap. Any future refactor that routes checkpoint through boundary/refresh must re-open this ADR.\n 66:\n 67:**Rejected alternatives:**\n 68:- *Binary watches the commune file* — wrong actor (no FS knowledge), and TOCTOU against the daemon's\n...\n 71:  public surface; would block the feature on a core change.\n*72:- *Adapter-side raw-file SessionStart inject* — TOCTOU against core's pulse-delete; spt-core owns the\n 73:  race-free re-seed (the `psyche-download` `<pending-*>` append).\n 74:\n 75:## Consequences\n### 0005-name-unification.md#9AB3\n 6:**Historical sister-lineage record — superseded for `omp-spt` by\n*7:[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n 8:\n 9:Preserved only as sister-project lineage for its original rationale and details. References to\n 10:Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n### 0006-one-command-update-and-consolidated-binary.md#5BE1\n 5:**Historical sister-lineage record — superseded for `omp-spt` by\n*6:[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n 7:\n 8:Preserved only as sister-project lineage for its original rationale and details. References to\n 9:Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n...\n 65:\n*66:- The thin-skeleton goal advances even before the asks land: skill bodies already ride strings; the **reactive skills** (`commune`/`send`/`signoff`, full-fat in the plugin because they are invoked without a typed slash-command) can be thinned to stubs by moving their bodies into the perched SessionStart brief (adapter strings) plus the `/spt:live` UPS body — with a known **delivery-timing wrinkle** (the perched brief fires on bind|boundary, not the instant a seed session goes live), tracked as a plan i...\n 67:- Until asks #1/#3 land, hook logic and the translate binary stay on their current channels; the design degrades gracefully (the `message` field bridges the manual steps).\n 68:- One artifact per OS simplifies packaging but couples all seams' build/release — acceptable, they already ship in one `.spt`.\n### 0008-omp-native-product-boundary.md#853E\n 4:\n*5:omp-spt supports OMP integration only. Its product surfaces are native OMP endpoints and daemon-driven OMP roles; the inherited Claude Code plugin, hooks, injection machinery, ccs integration, Claude-specific requirements/tests, and former RPC bridge are lineage rather than supported compatibility surfaces. Keeping either alternate harness path would make multiple lifecycle contracts share one adapter identity and had already produced wrong-adapter setup and update behavior, so the port uses a clean OMP-...\n 6:\n 7:The same cutover applies to traceability: the active requirement registry\n 8:contains OMP-observable contracts only. Claude-specific requirements are\n### 0012-continuity-drops-live-under-spt.md#1650\n 4:\n*5:Native OMP endpoints write commune and signoff file-drops under the project-local `.spt/` directory. These files belong to the SPT continuity contract rather than to OMP configuration, so a harness-neutral directory makes ownership explicit and avoids retaining the fork’s misleading `.claude/` path. The existing endpoint-qualified commune and signoff filenames remain the identity boundary consumed by spt-core.\n### 0013-release-gate-stops-at-the-adapter-boundary.md#469B\n*1:# Release verification stops at the adapter boundary\n 2:\n 3:Status: accepted (2026-07-14)\n 4:\n### 0015-extension-owned-session-activation.md#95AE\n 6:\n*7:An ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension—not the model or an agent-started background process—binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session bind...\n### 0017-active-turn-delivery-uses-safe-boundaries.md#F530\n 6:\n*7:A peer message accepted during an active OMP turn remains in the extension's ordered custody and is injected at the first proven boundary before the next tool or model continuation; if the turn exposes no injectable boundary, the message becomes ordinary next-turn delivery. Always waiting for the next turn was rejected because it leaves live agents unreachable during long work, while arbitrary event injection and forced interruption were rejected because they make model context, tool intent, and exactly-...\n\n## formats/\n### context-format.md#DA20\n 22:  constraint that is part of its meaning.\n*23:- **Cross-link** related terms in `**bold**`, and draw the **boundary** between terms that are\n 24:  easy to conflate (\"distinct from **X** in that …\").\n 25:- **Short.** A glossary entry is a definition, not an essay. If it needs a rationale, that\n 26:  rationale is probably an ADR — link to it.\n\nShowing files 1-20 of 22+. Use skip=20 for the next page, or narrow paths/pattern.\n\n[Some lines truncated to 512 chars]"}],"details":{"scopePath":"docs, OMP-ADAPTER-PLAN.md, PARITY-PUBLISH-PLAN.md","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":85,"fileCount":20,"files":["docs/CI.md","docs/DOCS-STRATEGY.md","docs/KNOWN-HAZARDS.md","docs/OMP-BRIDGE-FIELD-ISSUES.md","docs/PARITY.md","docs/RELEASE-RUNBOOK.md","docs/SKILL-AUTHORING.md","docs/SPT-CORE-FINDINGS.md","docs/adr/0001-distribution-splits-by-volatility.md","docs/adr/0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md","docs/adr/0003-psyche-is-a-constrained-auto-approving-companion.md","docs/adr/0004-checkpoint-via-self-send-loopback.md","docs/adr/0005-name-unification.md","docs/adr/0006-one-command-update-and-consolidated-binary.md","docs/adr/0008-omp-native-product-boundary.md","docs/adr/0012-continuity-drops-live-under-spt.md","docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md","docs/adr/0015-extension-owned-session-activation.md","docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md","docs/formats/context-format.md"],"fileMatches":[{"path":"docs/CI.md","count":3},{"path":"docs/DOCS-STRATEGY.md","count":6},{"path":"docs/KNOWN-HAZARDS.md","count":1},{"path":"docs/OMP-BRIDGE-FIELD-ISSUES.md","count":1},{"path":"docs/PARITY.md","count":7},{"path":"docs/RELEASE-RUNBOOK.md","count":1},{"path":"docs/SKILL-AUTHORING.md","count":6},{"path":"docs/SPT-CORE-FINDINGS.md","count":20},{"path":"docs/adr/0001-distribution-splits-by-volatility.md","count":10},{"path":"docs/adr/0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md","count":16},{"path":"docs/adr/0003-psyche-is-a-constrained-auto-approving-companion.md","count":1},{"path":"docs/adr/0004-checkpoint-via-self-send-loopback.md","count":4},{"path":"docs/adr/0005-name-unification.md","count":1},{"path":"docs/adr/0006-one-command-update-and-consolidated-binary.md","count":2},{"path":"docs/adr/0008-omp-native-product-boundary.md","count":1},{"path":"docs/adr/0012-continuity-drops-live-under-spt.md","count":1},{"path":"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md","count":1},{"path":"docs/adr/0015-extension-owned-session-activation.md","count":1},{"path":"docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md","count":1},{"path":"docs/formats/context-format.md","count":1}],"truncated":true,"fileLimitReached":20,"perFileLimitReached":20,"displayContent":"# docs/\n## CI.md#96F6\n  28│\n *29│These are binary pass/fail checks. A release run must treat any `SKIP` caused by a missing interpreter, Rust toolchain, platform binary, or `traceable-reqs` installation as an incomplete gate, provision the dependency, and rerun. The archive test may intentionally prove that the packer refuses missing platform binaries, but a release still needs both platform builds before packaging. The live acquisition integration intentionally skips unless `OMP_SPT_ACCEPTANCE=1`; after opt-in, missing release variable...\n  30│\n  31│## Native OMP release acceptance\n  32│\n *33│ADR-0013 sets the release boundary. For v0.2.0, the only supported release hosts are **x86_64 Windows** (`x86_64-pc-windows-msvc`) and **x86_64 Linux** (`x86_64-unknown-linux-gnu`); the asset has no macOS or Arm64 payload. Acceptance must use the exact tagged candidate `adapter.spt`, a real `omp` installation, the native packaged extension, and disposable endpoint identities. Complete the full acceptance sequence independently on both supported hosts before promotion. Do not reuse an operator's long-live...\n  34│\n  35│Install the tagged candidate on each acceptance host and verify its manifest version:\n  36│\n    │...\n  99│\n*100│## Adapter release boundary\n 101│\n 102│Cross-node transport is outside the `omp-spt` release gate. Once the exact message contract succeeds through the adapter on one node, subnet routing adds no OMP-specific seam and belongs to spt-core. A cross-node check may be useful for spt-core qualification, but it must not replace or block the same-node adapter acceptance above.\n 103│\n## DOCS-STRATEGY.md#02F5\n   7│\n  *8│## Audience and product boundary\n   9│\n  10│The documentation serves human operators and development agents integrating with\n  11│[`BigscreenVR/omp-spt`](https://github.com/BigscreenVR/omp-spt). Author each fact once in clean\n    │...\n  52│\n *53│- **Introduction:** what `omp-spt` does and the OMP / spt-core ownership boundary.\n  54│- **Requirements:** supported spt-core floor, supported hosts, and an installed native OMP.\n  55│- **Quickstart:** install the release adapter, create endpoint `atlas`, and attach to its native\n  56│  TUI.\n    │...\n  98│- Manifest reference for `[adapter]`, `[update]`, `[identity]`, `[session]`, `[history]`,\n *99│  `[digest]`, environment injection, and shared strings.\n*100│- Extension reference for bind, message custody, context injection, correlated replies,\n 101│  activity, session-switch refusal, recovery, and shutdown.\n 102│- `adapter.spt` reference for the root manifest, `strings/omp-spt.mjs`, and supported host\n 103│  binaries.\n*104│- Release verification checklist and the explicit adapter / spt-core boundary.\n 105│\n 106│Each major capability can use the same internal sequence when it needs more than one page:\n 107│`Overview -> Tutorial -> How-to -> Reference -> Explanation`. Do not force all five page types\n    │...\n 208│  switching, graceful shutdown, and both hostable roles.\n*209│- Stop at the adapter boundary. Once same-node delivery proves the adapter handoff, cross-node\n 210│  transport is a spt-core concern rather than an `omp-spt` release gate.\n 211│\n 212│## Anti-patterns\n## KNOWN-HAZARDS.md#B907\n 3│This is the OMP adapter's conformance checklist. Each entry states a failure\n*4│mode, the invariant that prevents it, the evidence boundary, and its source.\n 5│An invariant is not covered merely because it is described here: the active\n 6│requirement must point at production behavior and a focused test.\n 7│\n## OMP-BRIDGE-FIELD-ISSUES.md#3624\n 37│   attachable OMP TUI.\n*38│6. **Release boundary:** same-node message/turn/reply behavior is required;\n 39│   cross-node transport is not re-tested by the adapter.\n 40│\n 41│## Public-contract status\n## PARITY.md#2CFD\n  28│Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n *29│commands with argument completion or native selection dialogs. Explicit live\n  30│auto-resume selects the most-recent compatible live identity; ordinary\n  31│activation never guesses silently. The extension binds the current session and\n  32│owns the authenticated listener, after which binding is immutable.\n  33│\n *34│<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\n *35│Messages accepted during an active OMP turn enter at the first proven boundary\n *36│before the next tool or model continuation. Custody and arrival order remain\n *37│intact; a turn with no injectable boundary falls back to ordinary next-turn\n  38│delivery rather than interruption.\n  39│\n  40│<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\n    │...\n 121│1. repair version and documentation truth, then prove packaged-skill discovery\n*122│   and injectable OMP event seams;\n 123│2. implement extension-owned ready/live activation, live auto-resume,\n*124│   safe-boundary delivery, and abnormal-turn receivability;\n 125│3. add startup briefs, targeted hints, update notices, packaged skills,\n 126│   checkpoint continuity, hybrid setup, and peer-message shortform;\n 127│4. add the musl target and durable machine-readable acceptance records for all\n## RELEASE-RUNBOOK.md#7E13\n 217│\n*218│Cross-node transport is not an `omp-spt` release gate. Do not delay the adapter release on a subnet routing check after same-node delivery has proved the adapter boundary.\n 219│\n 220│If any acquisition, version, or native acceptance item fails on either target, leave the release marked as a prerelease, fix the source, and cut a new version. Do not replace a tested tag or asset in place.\n 221│\n## SKILL-AUTHORING.md#2E4C\n  33│|---|---|---|\n *34│| **A — injected** | thin `plugin/sptc/skills/<n>/SKILL.md` stub + `adapter/strings/skills/<n>.md` body (manifest `[strings.skills].<n>`) | Skills the **user** invokes (`/sptc:<n>`) or a hint surfaces. The UPS hook injects the body on the slash-command. |\n *35│| **B — full-fat** | `plugin/sptc/skills/<n>/SKILL.md` only — operative body in the SKILL.md, **no** `[strings.skills]` entry, **no** adapter body | Skills the **agent self-drives reactively** without the user typing `/sptc:<n>` — `send`, `commune`, `signoff`. UPS-injection fires only on a slash-command in the prompt, so it cannot deliver these; the always-loadable SKILL.md does. |\n  36│\n  37│Self-drive anchor (both patterns): point the agent at the live source of truth where one exists —\n  38│`spt how-to <topic>` (ready · send · subnet · live) or `spt <verb> --help` — instead of duplicating\n    │...\n  58│>\n *59│> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check\n  60│> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.\n  61│\n  62│<One line naming what the skill does.>\n    │...\n  64│\n *65│**Pattern A — adapter body** (the injected operative instructions):\n  66│\n  67│```md\n  68│# /sptc:<name> — operative instructions\n    │...\n  95│`setup` is **self-contained on both surfaces**: it runs precisely when spt-core may be absent, so\n *96│injection can no-op. Its plugin SKILL.md keeps the operative steps as the floor; tighten it, never\n  97│reduce it to a stub.\n  98│\n  99│## `description` rules (from write-a-skill)\n    │...\n 110│- [ ] Bringup skills (`ready`/`live`) are minimum-friction — fire and announce, no marker-gating.\n*111│- [ ] Right pattern: agent-self-driven (`send`/`commune`/`signoff`) → full-fat, no injection.\n 112│- [ ] Cites `spt how-to`/`--help` where one exists; `allowed-tools` is the minimum.\n 113│- [ ] `[<doc>->REQ-*]` traceability tags preserved.\n## SPT-CORE-FINDINGS.md#CCCF\n 10│|---|------|--------|---------|\n*11│| F-001 | 2026-06-14 | **re-scoped 2026-06-15** — most = adapter-authoring (closed); 1 residual spt-core docs item open | Hook-wiring for a CC adapter — boundary clarified |\n 12│| F-002 | 2026-06-15 | **RESOLVED-SHIPPED (v0.7.1)** — `<EVENT>` verified on the published `api poll` surface; F-002 dissolved; int flipped | `api poll` agent path has no inter-frame delimiter → multi-message drains are unsplittable |\n 13│| F-003 | 2026-06-15 | **RESOLVED + docs CLOSED (v0.7.1)** — capability shipped; the file-pointer syntax is now on the published surface | File-backed `[strings]` IS shipped (value-position table pointer `key = { file = \"rel\" }`) but was **undocumented** on the published surface |\n 14│| F-004 | 2026-06-15 | **CONFIRMED-IMPL-BUG (doyle); fix in progress** — `digest-proof` will fill `{id}`+`{session_id}` matching runtime; int deferred until the carrying release | `spt adapter digest-proof --sample` passes an empty substitution-key map → false-fails any extractor whose command uses `{session_id}` (incl. the published example) |\n   │...\n 20│| F-010 | 2026-06-16 | **RESOLVED-SHIPPED + RE-VALIDATED (spt v0.8.2, 2026-06-17)**. A spawn-then-exit psyche now stamps `psyche_host_error{reason:\"host not resident within 5s ...\", attempts:2}` on the parent perch (rendered `psyche-host: FAILED (...)` by `endpoint list`/`whoami`); status stays online (liveness authoritative). Forced fast-exit confirmed it | Silent-exit still maskable: `psyche_host_error` stays clear when the detached spawn() succeeds but the child exits IMMEDIATELY (e.g. arg-parse exit ...\n*21│| F-013 | 2026-06-17 | **ROOT-CAUSED (perri) → RULED spt-core BUG (doyle 2026-06-17): fork (a)**. spt-core must honor `[env].value` substitution in endpoint-run (the schema already promises \"with substitution\"; not applying it is a silent correctness bug). **Adapter manifest is CORRECT as-is — no wrapper** (b rejected: a shim would dodge a bug every `[env]`-routing adapter hits). Dispatched **`REQ-HAZARD-ENV-SUBST` → todlando, v0.11.0-findings** (pairs with REQ-SEND-SPT-HOSTED). **VERIFIED FIXED + ...\n 22│| F-011 | 2026-06-17 | **CONFIRMED + ROOT-CAUSED (doyle, spt-core source) — case-3 robustness, NON-blocking**. doyle: `registry.rs` `manifest_dir` — Pointer/GhReleaseManaged adapters read the manifest LIVE from `source_dir`; a deferred install whose manifest isn't extracted yet → `load_manifest` fails → `registered()` `filter_map(...ok())` **SILENTLY DROPS** the adapter → zero host_binaries candidates (`ADAPTER_UNRESOLVED`) AND `resolve_option/set_active` reads the absent manifest → bare **os...\n*23│| F-016 | 2026-06-22 | **RESOLVED — both fixes SHIPPED** (doyle, broker.rs-confirmed). The published `[message-idle-translation-binary]` doc omitted `{commit}` from the stdout vocabulary AND its degenerate baseline `{text}{key:enter}` would itself FAULT. `{commit:true}` is the MANDATORY inject-sequence terminator (`run_inject_worker` broker.rs:1075-1090; no-commit → 5s `INJECT_COMMIT_DEADLINE` FAULT, broker.rs:151-169; reference `{text}{key:enter}{commit:true}` translation.rs:74-78). **(i) adapter bi...\n*24│| F-017 | 2026-06-22 | **RESOLVED-SHIPPED (spt-core v0.14.0, counter 30) + VALIDATED on real claude-spt (perri, 2026-06-23)**. v0.14.0's endpoint-creation-flow milestone (REQ-RUN-MULTISUBNET-HOME, ADRs 0026/0027) closed it: `spt endpoint run` now HOMES at creation — multi-subnet node w/o `--subnet` → instant **`MULTI_SUBNET_HOME`** refuse + subnet list (0.058s, NOT the old ~25s silent `ENDPOINT_RUN_ONLINE_TIMEOUT`); `--subnet <name>` → homes + harness binds (UNBOUND → online), no HOME_REFUSED. Bo...\n 25│| F-018 | 2026-06-22 | **REPORTED to doyle (perri) — destructive footgun, os-2 family (F-011 sibling)**. Surfaced while constructing the F-015 brick repro on v0.13.2. `spt adapter add --github <user/repo>` on an **already-registered, already-extracted gh_release Pointer adapter** is destructive-then-cryptic: it git-clones the SOURCE repo over the extracted install dir (wiping the root `manifest.toml` + the 3 runtime `.exe` binaries the Pointer resolves), then the post-add first-`[update]` conduct fails...\n*26│| F-020 | 2026-06-24 | **RESOLVED-PENDING — frozen Tier-1 contract, ships v0.15.0 W5** (doyle ruled + grounded; verb committed by todlando @20bfc1f). spt-core publishes NO `spt api` verb to pull resume/psyche context at SessionStart — `download_psyche_context` (resume.rs:88) is exported-but-unexposed (ZERO `ApiCmd` callers); `resume.rs:9` documents the \"adapter pulls it in its SessionStart hook\" intent but no verb was ever published. **Consequence: claude-spt live agents rehydrate NO durable context ...\n 27│\n*28│| F-023 | 2026-07-01 | **CONFIRMED + RCA'd (doyle, same day) — build dispatched to todlando (`BUILD-F023-WANIDLE`)**. Both ranked hypotheses real: `receive_wan` has deliver_tcp + spool ONLY (the spt-hosted broker-inject leg exists solely in local `cmd_send`) AND no idle-edge drain exists anywhere. Fix = shared inject leg called from WAN ingress + ACTIVE→IDLE spool drain. Adapter exoneration stands verbatim. `from_id=\"\"` sibling ruled: compose stamps `cli@<node-label>`; ingress renders empty-from as o...\n 29│| F-024 | 2026-07-01 | **CLOSED-REFRAMED (doyle, same day) — transport EXONERATED; symptom = F-023 on the remote node.** The `(spooled)` token in `SENT(WAN)` output is RECEIVER-CONFIRMED (only prints on a confirmed round-trip): probe `DIAG-7c1e` reached ENLYZEAM post-restart and sits in ball-b's spool undelivered (`spooled` not `delivered` = no live TCP listener at receive time). Operator workaround: any prompt typed into ball-b UPS-drains the stuck messages. Residues stay real as separate diagnostics ...\n 30│| F-031 | 2026-07-08 | **REPORTED to doyle (perri) — docs gap; adapter worked around in v0.17.3 (REQ-HAZARD-SEND-STATUS-STDERR).** `spt send`'s result token (`SENT:<id>` / `QUEUED:<id>` / `DEFERRED:<id>` / `NO_PERCH:<reason>`) is written to **STDERR**, not stdout — stdout is empty on a plain `spt send`. This is undocumented in the published harness-contract / CLI reference (they describe the tokens as the send's *result* without naming the stream). It bit the claude-spt tag-messaging hook: the hook c...\n 31│\n*32│> **F-021 / F-022 (NOT spt-core findings — claude-spt parity items, tracked as REQs; surfaced during the 2026-06-24 checkpoint-commune grill)** — (F-021) claude-spt polls only on `UserPromptSubmit` (between turns); legacy spt also polls+injects on **PreToolUse** = the mid-turn half of live-agent reachability (the main path by which a live agent receives a message WHILE working). `api poll` already exists on the public surface → adapter wiring, not an spt-core gap → **`REQ-DIST-PRETOOL-POLL`**. (F...\n 33│\n 34│> **F-012 (NOT logged as spt-core)** — legacy-owl 1.11.25 poll-loop exits 1 / orphans the Psyche across daemon churn (`/spt:revive` started gen-7 wrapper+psyche fine but the foreground poll died with a non-fatal `sessions log seal failed: git failed (continuing)` line). doyle ruled this is the **legacy owl listener** (a separate daemon from spt-core), NOT an spt-core public-surface finding; the seal line is non-fatal/continues so isn't the exit cause; it dies with legacy owl's retirement. Re-open as sp...\n 35│\n   │...\n 43│- `harness-contract/api.md` — the full `spt api` primitive surface: `seed`, `listen`, `bind`,\n*44│  `boundary`, `session-end`, `shutdown`, `state`, `echo-gate`, `presence`, `driven-by`, `poll`,\n 45│  `history-log`, `worker-start/poll/stop`, `bind-shell`, `emit`, `owner-shutdown`, `capability`.\n 46│- `harness-contract/install-on-demand.md` — install-on-demand bootstrap, exact `sh` + `ps1`\n 47│  snippets, canonical installer URLs, env-var customization. **Fully buildable.**\n   │...\n 49│  `api seed --pid {parent_pid} --session-id {session_id}` then `api listen <id>`; Idle →\n*50│  `api state idle|busy`; PreCompact/clear → `api boundary clear|compact <id> --to-session-id <sid>`;\n 51│  teardown → `api session-end <id>` / `api shutdown <id>`.\n 52│\n 53│**The gaps:**\n   │...\n 58│2. **Manifest `[hooks.*]` vs harness-native hook config is unspecified.** `manifest.md` declares\n*59│   hooks as `[hooks.<event>] fires=\"api ...\" reads=[...] can_inject=bool`, with spt-core performing\n 60│   `{key}` substitution from `reads`. It is **silent** on whether spt-core *materializes* the\n 61│   harness-native config (Claude Code `hooks.json`) from the manifest, or the adapter author\n 62│   hand-writes `hooks.json` that shells out to `spt api`. These imply different substitution models:\n   │...\n 66│   calling `spt api`\" — it may instead be manifest-declared + spt-materialized.)\n*67│3. **Injection mechanism is undocumented.** `can_inject` + an `[inject]` section (methods\n 68│   `pty`/`hook`/`relay`/`http`) exist, but there is **no technical detail** on how an adapter emits\n 69│   `additionalContext` back through the hook channel. Blocks (a) general mid-session message\n*70│   delivery on a prompt/tool hook, and (b) this project's **UPS-injection** skill-instruction design\n 71│   (`docs/adr/0001-*`) specifically — it cannot be validated against the public surface until this\n 72│   is documented.\n 73│\n*74│**Impact (as first reported):** SessionStart / Stop(idle) / SessionEnd / boundary are buildable now.\n*75│UserPromptSubmit + PreToolUse + Subagent wiring + the entire injection path were *thought* blocked.\n 76│\n 77│### Resolution (2026-06-15 — converged with doyle, grounded in `CONTEXT.md`)\n 78│\n*79│The boundary canon (`CONTEXT.md` L52/L181/L112/L149/L137) re-frames F-001: **spt-core is\n 80│harness-independent and supplies the agnostic `spt api` primitives + their I/O format; the adapter\n 81│authors the harness-specific wiring + output-formatting.** So most of F-001 is **adapter-authoring\n 82│work (ours), not an spt-core gap**:\n   │...\n 86│  → `api listen <id>` (the blocking poll loop — *not* SessionStart, which must not block); Stop/Idle\n*87│  → `api state idle|busy`; PreCompact/clear → `api boundary`; SessionEnd → `api session-end` /\n 88│  signoff → `api shutdown`; SubagentStart/Stop → `api worker-start`/`worker-stop`; UserPromptSubmit\n 89│  → `api poll`; **PreToolUse out-of-scope v1** (UPS covers delivery). See `docs/adr/0002-*`.\n 90│- **Gap 2 (medium) — OURS, closed.** The `sptc` plugin **hand-writes** its CC `hooks.json` shelling\n 91│  `spt api`. spt-core materializing a CC `hooks.json` would violate L52/L181 — it correctly doesn't.\n*92│- **Gap 3 (injection HOW) — OURS, closed.** `api poll` emits message frames to **stdout** by design\n*93│  (L149) — that IS the hook-injection delivery path; routing/formatting that stdout into CC's\n*94│  `additionalContext` channel is adapter glue (L112). The earlier \"`can_inject`/`[inject]`\n 95│  method-discard is dead code\" alarm is **retracted** — it is M2a roadmap staging (stdout/hook only\n*96│  now; PTY at M3), and `can_inject` drives the *built* echo-gate/relay fallback (L137) for hooks that\n\n## adr/\n### 0001-distribution-splits-by-volatility.md#4F3E\n   3│<!-- [doc->REQ-DIST-BOOTSTRAP-INSTALL] -->\n  *4│<!-- [doc->REQ-UPS-INJECTION] -->\n   5│# Distribution splits by volatility: a thin skeleton plugin, an spt-conducted manifest + binary\n   6│\n   7│## Status\n    │...\n   9│**Historical sister-lineage record — superseded for `omp-spt` by\n *10│[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n  11│\n  12│Preserved only as sister-project lineage for its original rationale and details. References to\n  13│Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n    │...\n  63│  A user who installs the plugin gets spt-core for free. [`REQ-DIST-BOOTSTRAP-INSTALL`]\n *64│- **Skill instructions are delivered by UPS-injection.** A `UserPromptSubmit` hook detects `/spt:X`\n *65│  in the prompt and injects X's real instructions as `additionalContext`, sourced from the adapter\n  66│  `[strings]` (file-backed, so the manifest doesn't bloat). SKILL.md files stay skeletons; the\n *67│  volatile instruction text lives in spt-core-conducted strings. [`REQ-UPS-INJECTION`]\n  68│- **The \"bulk\" install/update is manifest + binary**, conducted by spt-core's own framework (the\n  69│  file-pull channel), not a marketplace bump. The marketplace plugin rarely needs a version bump\n  70│  and never orphans an active install.\n    │...\n  76│- **fetch-stub skills** (SKILL.md fetches its real body at runtime) — VETOED by the operator:\n *77│  adds terminal noise, latency, and an extra tool call per invocation. UPS-injection chosen\n  78│  instead. (`SCOPE.md` §\"Skill-instruction delivery\".)\n  79│- **A fat plugin shipping the binary** (legacy `owl.exe` model) — couples high-churn logic to the\n  80│  marketplace cadence and forces the binary/handoff/cache-prune machinery the thin skeleton has no\n    │...\n  86│  fires on a `/sptc:X` slash-command with the token intact (`prompt:\"/sptc:send doyle\"` literal, hook\n *87│  fired, skill ran, on CC 2.1.177). The injection branch is built (`user-prompt-submit.sh`\n *88│  `sptc_skill_key` + `sptc_inject_skill`); the in-SKILL.md fallback is unneeded for injection (but\n *89│  `setup` stays self-contained — it runs when spt may be absent). (`REQ-UPS-INJECTION`.)\n  90│- **File-backed `[strings]` is an M12 spt-core dependency** — until M12 publishes, instruction\n  91│  bodies cannot be externalized; skeleton SKILL.md files may carry interim inline instructions.\n  92│  **Update 2026-06-15 — SATISFIED.** M12 (`spt 0.7.0`) ships file-backed `[strings]` as a\n    │...\n 125│  `doc`-stage evidence for `REQ-DIST-PLUGIN-SKELETON`, `REQ-DIST-HOOKS-API`,\n*126│  `REQ-DIST-BOOTSTRAP-INSTALL`, and `REQ-UPS-INJECTION`.\n### 0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md#EC6E\n   1│<!-- [doc->REQ-DIST-HOOKS-API] -->\n  *2│<!-- [doc->REQ-UPS-INJECTION] -->\n   3│# Hook wiring: the sptc plugin hand-writes a CC `hooks.json` that shells `spt api`\n   4│\n   5│## Status\n    │...\n   7│**Historical sister-lineage record — superseded for `omp-spt` by\n  *8│[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n   9│\n  10│Preserved only as sister-project lineage for its original rationale and details. References to\n  11│Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n    │...\n  46│| SessionStart (`startup`/`resume`) | `seed --pid <pid> --session-id <sid>` + write env aliases via `$CLAUDE_ENV_FILE` | non-blocking; records the pid↔session seed |\n *47│| SessionStart (`clear`/`compact`) | `boundary <clear\\|compact> <id> --to-session-id <sid>` | rebind perch, preserve identity |\n *48│| UserPromptSubmit | `poll <id>` → stdout → `additionalContext` | the message-delivery + UPS-injection path (L149) |\n *49│| Stop | `state idle <id>` | arms echo-gate fallback (L137) since Stop can't inject |\n  50│| (activity) | `state busy <id>` | on prompt/tool start |\n  51│| SubagentStart / SubagentStop | `worker-start <parent> <id>` / `worker-stop <id>` | nested worker perches |\n  52│| SessionEnd | `session-end <id>` | soft teardown; `shutdown <id>` on graceful signoff |\n    │...\n  57│\n *58│### Skill instructions (UPS-injection) ride the same UserPromptSubmit hook\n  59│\n  60│The `UserPromptSubmit` hook's stdout becomes CC `additionalContext`. The same channel that delivers\n *61│queued messages (`api poll`) is where `/sptc:X` skill-instruction injection lands (from the adapter\n  62│`[strings]`, M12-dep). `api poll` emitting to stdout is by design (L149); formatting it for CC is\n *63│ours. PTY/relay inject methods are M3 roadmap (M2a = stdout/hook only) — not a gap.\n  64│\n  65│### `api poll` parse contract — the `<EVENT>` envelope (operator-ruled 2026-06-15)\n  66│\n    │...\n  81│  `<EVENT>`s. `<EVENT-PART seq=\"N/M\">` exists only for the *listener stream* (the `« spt event »`\n *82│  Monitor's ~500-char `EVENT_LINE_THRESHOLD`); the hook-drain injects via `additionalContext` which\n  83│  has no per-line cap. **No id+seq reassembly on the poll path.**\n  84│\n  85│Parser (`render_frames`, `plugin/sptc/hooks/_common.sh`): split on `</EVENT>`; per envelope, read\n    │...\n  90│\n *91│**Harness injection-size limit is ours** (harness-agnostic boundary — spt-core emits whole\n  92│`<EVENT>`s regardless): CC `additionalContext` caps at **10,000 chars** (larger output is spilled to\n  93│a file by CC). A large multi-message drain can exceed it → adapter-side follow-up: truncate with a\n *94│marker or spill. (`REQ-UPS-INJECTION` `int` item.)\n  95│\n  96│### Portability\n  97│\n    │...\n 125│  SCOPE-flagged question: `UserPromptSubmit` fires on a `/sptc:X` invocation with the token intact,\n*126│  so the wrapper can detect `/sptc:X` in `prompt` and inject. (`REQ-UPS-INJECTION`.)\n 127│- ✅ **Windows `shell:\"bash\"` command hooks work** — the hook executed via Git-Bash,\n 128│  `$CLAUDE_PROJECT_DIR` resolved, exit-0 stdout honored. Resolves Open#2 for the POSIX-wrapper\n 129│  packaging on Windows (no per-OS branch needed for the hook to run).\n    │...\n 141│   `<EVENT-PART>` on normal drains, multi-drain splits on `</EVENT>`), and `render_frames` confirm-\n*142│   matched it. Locked by `ci/hooks/poll-int.sh` (5/5); `REQ-DIST-HOOKS-API` + `REQ-UPS-INJECTION`\n 143│   `int` flipped green. See `docs/SPT-CORE-FINDINGS.md` F-002.\n*144│2. **Large-drain injection size — RESOLVED (2026-06-15).** CC spills `additionalContext` over ~10k\n 145│   chars to a file (evicting it from the inline context the agent sees), silently losing messages.\n 146│   The UPS wrapper now pre-empts: `sptc_cap_output` (`_common.sh`) buffers the combined skill-body +\n 147│   drain, and over `SPTC_CTX_CAP` (9000, margin under 10k) spills the FULL text to an agent-readable\n    │...\n 154│\n*155│- `REQ-DIST-HOOKS-API` / `REQ-UPS-INJECTION` gain a concrete, grounded `doc` design here; their\n 156│  `impl` activates when the validated `hooks.json` + wrappers land (gated on Open #1).\n 157│- Supersedes the `ADR-0001` \"hooks.json delegates to `spt api`\" stub with the full wiring; ADR-0001's\n*158│  UPS-injection open item (UPS-fires empirical) is carried here as Open #2.\n 159│- No spt-core dependency for the wiring itself — only the (non-blocking) residual docs publish of the\n 160│  `api poll` frame format, which we can substitute with observed behavior until it lands.\n### 0003-psyche-is-a-constrained-auto-approving-companion.md#3886\n  7│**Historical sister-lineage record — superseded for `omp-spt` by\n *8│[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n  9│\n 10│Preserved only as sister-project lineage for its original rationale and details. References to\n 11│Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n### 0004-checkpoint-via-self-send-loopback.md#0131\n  5│**Historical sister-lineage record — superseded for `omp-spt` by\n *6│[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n  7│\n  8│Preserved only as sister-project lineage for its original rationale and details. References to\n  9│Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n   │...\n 30│   delivery* to fire the macro.\n*31│3. **Re-seed staleness.** If the commune is authored *after* `/clear` (the boundary/resume-Self\n 32│   refresh path), the legacy `psyche-stale-after-clear` gap reappears (LLM-latency-bounded): the\n 33│   durable store and the drop file may both be absent/stale at the post-clear SessionStart.\n 34│4. **No daemon-push primitive.** The clean design — daemon detects the trigger in the commune it\n   │...\n 64│defers authoring to a post-clear resume-Self refresh (Shape 2). Shape 2 reintroduces force #3's stale\n*65│gap. Any future refactor that routes checkpoint through boundary/refresh must re-open this ADR.\n 66│\n 67│**Rejected alternatives:**\n 68│- *Binary watches the commune file* — wrong actor (no FS knowledge), and TOCTOU against the daemon's\n   │...\n 71│  public surface; would block the feature on a core change.\n*72│- *Adapter-side raw-file SessionStart inject* — TOCTOU against core's pulse-delete; spt-core owns the\n 73│  race-free re-seed (the `psyche-download` `<pending-*>` append).\n 74│\n 75│## Consequences\n### 0005-name-unification.md#9AB3\n  6│**Historical sister-lineage record — superseded for `omp-spt` by\n *7│[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n  8│\n  9│Preserved only as sister-project lineage for its original rationale and details. References to\n 10│Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n### 0006-one-command-update-and-consolidated-binary.md#5BE1\n  5│**Historical sister-lineage record — superseded for `omp-spt` by\n *6│[ADR-0008](0008-omp-native-product-boundary.md) on 2026-07-14.**\n  7│\n  8│Preserved only as sister-project lineage for its original rationale and details. References to\n  9│Claude or Claude Code, `ccs`, `sptc`, plugins, `cc-launcher`, and their associated bridge or hook\n   │...\n 65│\n*66│- The thin-skeleton goal advances even before the asks land: skill bodies already ride strings; the **reactive skills** (`commune`/`send`/`signoff`, full-fat in the plugin because they are invoked without a typed slash-command) can be thinned to stubs by moving their bodies into the perched SessionStart brief (adapter strings) plus the `/spt:live` UPS body — with a known **delivery-timing wrinkle** (the perched brief fires on bind|boundary, not the instant a seed session goes live), tracked as a plan i...\n 67│- Until asks #1/#3 land, hook logic and the translate binary stay on their current channels; the design degrades gracefully (the `message` field bridges the manual steps).\n 68│- One artifact per OS simplifies packaging but couples all seams' build/release — acceptable, they already ship in one `.spt`.\n### 0008-omp-native-product-boundary.md#853E\n 4│\n*5│omp-spt supports OMP integration only. Its product surfaces are native OMP endpoints and daemon-driven OMP roles; the inherited Claude Code plugin, hooks, injection machinery, ccs integration, Claude-specific requirements/tests, and former RPC bridge are lineage rather than supported compatibility surfaces. Keeping either alternate harness path would make multiple lifecycle contracts share one adapter identity and had already produced wrong-adapter setup and update behavior, so the port uses a clean OMP-...\n 6│\n 7│The same cutover applies to traceability: the active requirement registry\n 8│contains OMP-observable contracts only. Claude-specific requirements are\n### 0012-continuity-drops-live-under-spt.md#1650\n 4│\n*5│Native OMP endpoints write commune and signoff file-drops under the project-local `.spt/` directory. These files belong to the SPT continuity contract rather than to OMP configuration, so a harness-neutral directory makes ownership explicit and avoids retaining the fork’s misleading `.claude/` path. The existing endpoint-qualified commune and signoff filenames remain the identity boundary consumed by spt-core.\n### 0013-release-gate-stops-at-the-adapter-boundary.md#469B\n*1│# Release verification stops at the adapter boundary\n 2│\n 3│Status: accepted (2026-07-14)\n 4│\n### 0015-extension-owned-session-activation.md#95AE\n 6│\n*7│An ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension—not the model or an agent-started background process—binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session bind...\n### 0017-active-turn-delivery-uses-safe-boundaries.md#F530\n 6│\n*7│A peer message accepted during an active OMP turn remains in the extension's ordered custody and is injected at the first proven boundary before the next tool or model continuation; if the turn exposes no injectable boundary, the message becomes ordinary next-turn delivery. Always waiting for the next turn was rejected because it leaves live agents unreachable during long work, while arbitrary event injection and forced interruption were rejected because they make model context, tool intent, and exactly-...\n\n## formats/\n### context-format.md#DA20\n 22│  constraint that is part of its meaning.\n*23│- **Cross-link** related terms in `**bold**`, and draw the **boundary** between terms that are\n 24│  easy to conflate (\"distinct from **X** in that …\").\n 25│- **Short.** A glossary entry is a definition, not an essay. If it needs a rationale, that\n 26│  rationale is probably an ADR — link to it.","linesTruncated":true,"meta":{"limits":{"columnTruncated":{"maxColumn":512}}}},"isError":false,"timestamp":1784188883286}}
{"type":"message","id":"1c2caafa","parentId":"6de84c62","timestamp":"2026-07-16T08:01:29.625Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Searching for OMP extension API docs**"},{"type":"toolCall","id":"call_eGivsgPQmmkdTk11SCdbYR2G|fc_03e5b91f227b0634016a588fd8d0b0819b942585c39d804897","name":"web_search","arguments":{"i":"Researching OMP extension API","query":"Oh My Pi OMP extension API registerCommand before_agent_start tool_call context event sendUserMessage ui select confirm documentation","recency":"month","limit":10,"max_tokens":20000,"temperature":0.1,"num_search_results":10}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":18332,"output":176,"cacheRead":61952,"cacheWrite":0,"totalTokens":80460,"reasoningTokens":98,"cost":{"input":0.09166,"output":0.00528,"cacheRead":0.030976,"cacheWrite":0,"total":0.127916}},"stopReason":"toolUse","timestamp":1784188883335,"responseId":"resp_03e5b91f227b0634016a588fd3b0c4819b803fda3e03830c94","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03e5b91f227b0634016a588fd5a8dc819b9ecf5a37510f5025","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWI_Y_N0qyHEXcxqgrYbDbiffUaRvzqOKY9yJDRvtZd5Xl3jvJEeVNQ2sm4YpN9uTX_Yv6Mc-Wrkr-N75bomk0Zu3lpbiv41uf0l8uTDAZqdUiS6Vd2zy0o5eWI_COubRWqQ4a65N-_Kw9Bx09ThwLMXBsW6cmoyde-K1d3J0cycat0UU3cco8KN33AqLQFW7TCDg4LTg_wQJKpRieK0G6BpK2qry0Ur3zXxr5k5dZqbvPuE_aK7H1Qi95qNzgFEVNw9erFGg7OTRalfd7TOJu7p0ngoFxJ_EpBrtAFw7SE601tDOHYbTTq1e_GorYXO5tmH4yAum8wL9ZXuO4LSB6rKm8s46zbS86DJ8bltFYmHwVaQmqFyqs27MT7PrsXanPq-SDc0-dZEPwDGFwCldDZg4nn-3HomNsUloZs1Nq4HUDtf5FSARZG95evd_Q2jxqGulqGRs_3wHi4r9HyysxY7ylbERyTOd3am3gHTWQ3UqDSD5RnkDoVyilI-AF-udKyUWRiCi6LFuadb4Pox2CuqI-kxMdrDFxBiTl-Q_dUwD2seexihoG6nN1qncnTme96V23SZ5GmNnQwb_37QCKwoBbKAhzo9aqK-Iu8bBFATLpG-5EOtNf9hye3UFbtxWsG6rxmY_xOshPxdsPMCivLfKXyAfoIeQS2c_Z5zHs1UvNPo23gq2tYFtloXL9VY1oYFt89_9_sE-0xWqZfatnL4T0pvzIbI9zKazjlXVwHZQBszH-9OBoorUPuZnjVsLYRKS6fgr6Ba2eqTA1b9LZklSkbRB6ovVWvUhaVuXLSO3o_yMQ-o8GAwkVJKwcrDMgkq8SGoK9i4cOL4huzemxz6nehbKAaPuagHjL53axWB6Gv_-5WOP7VT120BPLgVDZhTEEYwF6aNcmtqlOBFofMUayFFlu4TyUx8y9uIEuliHiKe74iLiEBl0s8kLDvTxXeopjpjAzUD1E6hLNMMkoqS1OYaadH2IbfKd76zqBCPDPPwD_SxD4UW6akKtZXzEASwxg6QAhxmIaUClIjsr2K1sU6v-CB0KIIHTM826dpFjLqfUextrAarKPwanK3AwKG8u_2D8d0KikTZwBuWtTXU5eMPfzBnThpY4lsQIN3vIxg1Qmh6ir0wMzuCj6GO-1UrjqWavI7Refg9zGoBKTYHRqUfrjLoIUuLJqmHIg8KSrdB_l4NygcmMwqS9AfMPrYs3hgW46owXOBTRBep8lPj62tXkrgErwfBRhhc45yDHzfFFgtlVRr10OGYzJ_rd2R-Fk5PQ25uxclVnrXThlQcAeZl23HdIdi6-yjSMM2_alZ4nr9gapfmHhv-T_S-UTORkqdU-raEaO1oPqV84h81nsOxEgKjflh13Qh-jqBF4qB0EXI1QiooiMEAJnPhTLuqYjIF1_nCV5LnqyGAm6Bws44DQ8G3sRn0GQvoNaI2mSIibXyJzQYMtKPlne43citPVEpiY5jEWu2h0vyPi-YbgYKklx7cW6DyF8KZqESTeNSY=","summary":[{"type":"summary_text","text":"**Searching for OMP extension API docs**"}]},{"id":"fc_03e5b91f227b0634016a588fd8d0b0819b942585c39d804897","type":"function_call","status":"completed","arguments":"{\"i\":\"Researching OMP extension API\",\"query\":\"Oh My Pi OMP extension API registerCommand before_agent_start tool_call context event sendUserMessage ui select confirm documentation\",\"recency\":\"month\",\"limit\":10,\"max_tokens\":20000,\"temperature\":0.1,\"num_search_results\":10}","call_id":"call_eGivsgPQmmkdTk11SCdbYR2G","name":"web_search"}]},"duration":6287.880400000024,"ttft":2325.1926000000094,"contextSnapshot":{"promptTokens":80284,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_eGivsgPQmmkdTk11SCdbYR2G|fc_03e5b91f227b0634016a588fd8d0b0819b942585c39d804897","toolName":"web_search","startedAt":"2026-07-16T08:01:29.625Z","intent":"Researching OMP extension API"},"id":"88fc7698","parentId":"1c2caafa","timestamp":"2026-07-16T08:01:29.625Z"}
{"type":"message","id":"4749411e","parentId":"88fc7698","timestamp":"2026-07-16T08:02:30.455Z","message":{"role":"toolResult","toolCallId":"call_eGivsgPQmmkdTk11SCdbYR2G|fc_03e5b91f227b0634016a588fd8d0b0819b942585c39d804897","toolName":"web_search","content":[{"type":"text","text":"[1] Creating Extensions | can1357/oh-my-pi | DeepWiki\n    https://deepwiki.com/can1357/oh-my-pi/11.1-creating-extensions\n    Creating Extensions Relevant source files Extensions are the primary mechanism for extending the capabilities of oh-my-pi . A single extension module can register LLM-callable tools, interactive slash commands, keyboard shortcuts, and life…\n[2] Extension System | can1357/oh-my-pi | DeepWiki\n    https://deepwiki.com/can1357/oh-my-pi/11-extension-system\n    Extension System Relevant source files The extension system provides a plugin architecture for customizing and extending the coding agent's behavior. Extensions are TypeScript modules that can contribute custom slash commands, tools, lifec…\n[3] omp-designer · Packages · Pi\n    https://pi.dev/packages/omp-designer\n    Traced events — prompt injection, skill discovery, agent start/end, tool calls/results, automatic validation start/pass/fail, validator/build command kinds. Phase tracking — the extension tracks workflow phase (idle → planning → building →…\n[4] [Feature] Add Oh-My-Pi (omp) as a new Agent #1423 - GitHub\n    https://github.com/chenhg5/cc-connect/issues/1423\n    Summary Add support for Oh-My-Pi ( omp ) as a coding agent in cc-connect. Oh-My-Pi is a full-featured AI coding agent platform with its own LLM provider integration, MCP server support, LSP integration, and rich extension system.\n[5] Pi agent 101 - How to extend and build your own harness\n    https://x.com/jasonzhou1993/article/2074471761715077153\n    The extension system You can customize almost anything: tools, hooks, the model provider, session management, commands, and the terminal UI itself. Pi knowing its own extension API , so you often skip writing the code. Tell Pi \"put the wea…\n[6] Custom Providers | Pi Documentation\n    https://pi.ubitools.com/custom-provider/\n    The extension factory can also be async. For dynamic model discovery, fetch and register models in the factory instead of session_start. pi waits for the factory before startup continues, so the provider is available during interactive sta…\n[7] hermes-oh-my-pi-mcp - GitHub\n    https://github.com/cassiopeiaym/hermes-oh-my-pi-mcp\n    Hermes works well with MCP, plugins, and custom tools. oh-my-pi already provides a strong CLI/runtime, so this bridge lets Hermes users call it without reimplementing the agent stack. The recommended operating model is:\n[8] oh-my-pi (omp) — a fast, provider-agnostic AI coding agent for the ...\n    https://stayahead.space/resources/oh-my-pi\n    oh-my-pi is a terminal AI coding agent with 32 tools, LSP, real debuggers, parallel subagents, and token-saving hash-anchored edits — routing to 40+ model providers (Claude, GPT, local). Rust core, Bun runtime, native macOS/Linux/Windows. …\n[9] @remnic/plugin-pi · Packages · Pi\n    https://pi.dev/packages/@remnic/plugin-pi\n    This package is the first-class Remnic extension for Pi . It uses Pi's extension hooks directly, so Remnic can recall context before a model call, observe useful session events after the turn, expose Remnic MCP tools inside Pi , and coordi…\n[10] oh-my-pi — freshcrate\n    https://www.freshcrate.ai/projects/oh-my-pi\n    A global open source package directory for AI agents and labs: MCP servers, orchestration frameworks, coding agents, research tooling, infrastructure, and operator playbooks."}],"details":{"response":{"provider":"duckduckgo","sources":[{"title":"Creating Extensions | can1357/oh-my-pi | DeepWiki","url":"https://deepwiki.com/can1357/oh-my-pi/11.1-creating-extensions","snippet":"Creating Extensions Relevant source files Extensions are the primary mechanism for extending the capabilities of oh-my-pi . A single extension module can register LLM-callable tools, interactive slash commands, keyboard shortcuts, and lifecycle event hooks within a unified TypeScript environment."},{"title":"Extension System | can1357/oh-my-pi | DeepWiki","url":"https://deepwiki.com/can1357/oh-my-pi/11-extension-system","snippet":"Extension System Relevant source files The extension system provides a plugin architecture for customizing and extending the coding agent's behavior. Extensions are TypeScript modules that can contribute custom slash commands, tools, lifecycle hooks, keyboard shortcuts, and model providers without modifying the core codebase."},{"title":"omp-designer · Packages · Pi","url":"https://pi.dev/packages/omp-designer","snippet":"Traced events — prompt injection, skill discovery, agent start/end, tool calls/results, automatic validation start/pass/fail, validator/build command kinds. Phase tracking — the extension tracks workflow phase (idle → planning → building → reviewing → validated) based on tool call patterns."},{"title":"[Feature] Add Oh-My-Pi (omp) as a new Agent #1423 - GitHub","url":"https://github.com/chenhg5/cc-connect/issues/1423","snippet":"Summary Add support for Oh-My-Pi ( omp ) as a coding agent in cc-connect. Oh-My-Pi is a full-featured AI coding agent platform with its own LLM provider integration, MCP server support, LSP integration, and rich extension system."},{"title":"Pi agent 101 - How to extend and build your own harness","url":"https://x.com/jasonzhou1993/article/2074471761715077153","snippet":"The extension system You can customize almost anything: tools, hooks, the model provider, session management, commands, and the terminal UI itself. Pi knowing its own extension API , so you often skip writing the code. Tell Pi \"put the weather in my prompt input\" and it reads the extension doc, writes the widget, and reloads."},{"title":"Custom Providers | Pi Documentation","url":"https://pi.ubitools.com/custom-provider/","snippet":"The extension factory can also be async. For dynamic model discovery, fetch and register models in the factory instead of session_start. pi waits for the factory before startup continues, so the provider is available during interactive startup and to pi --list-models."},{"title":"hermes-oh-my-pi-mcp - GitHub","url":"https://github.com/cassiopeiaym/hermes-oh-my-pi-mcp","snippet":"Hermes works well with MCP, plugins, and custom tools. oh-my-pi already provides a strong CLI/runtime, so this bridge lets Hermes users call it without reimplementing the agent stack. The recommended operating model is:"},{"title":"oh-my-pi (omp) — a fast, provider-agnostic AI coding agent for the ...","url":"https://stayahead.space/resources/oh-my-pi","snippet":"oh-my-pi is a terminal AI coding agent with 32 tools, LSP, real debuggers, parallel subagents, and token-saving hash-anchored edits — routing to 40+ model providers (Claude, GPT, local). Rust core, Bun runtime, native macOS/Linux/Windows. Open-source, MIT, 14K+ stars."},{"title":"@remnic/plugin-pi · Packages · Pi","url":"https://pi.dev/packages/@remnic/plugin-pi","snippet":"This package is the first-class Remnic extension for Pi . It uses Pi's extension hooks directly, so Remnic can recall context before a model call, observe useful session events after the turn, expose Remnic MCP tools inside Pi , and coordinate Pi compaction with Remnic's long- context memory archive."},{"title":"oh-my-pi — freshcrate","url":"https://www.freshcrate.ai/projects/oh-my-pi","snippet":"A global open source package directory for AI agents and labs: MCP servers, orchestration frameworks, coding agents, research tooling, infrastructure, and operator playbooks."}]}},"isError":false,"timestamp":1784188950455}}
{"type":"message","id":"c4e11a90","parentId":"4749411e","timestamp":"2026-07-16T08:02:35.985Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning primary source review**"},{"type":"toolCall","id":"call_p87ldAlZw2VDflXCemnXmJ04|fc_03e5b91f227b0634016a58901af6f4819bb0fd2ab1c9324aa0","name":"web_search","arguments":{"i":"Finding official OMP docs","query":"site:github.com/can1357/oh-my-pi \"registerCommand\" \"before_agent_start\" extension","recency":null,"limit":10,"max_tokens":20000,"temperature":0.1,"num_search_results":10}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1916,"output":111,"cacheRead":79360,"cacheWrite":0,"totalTokens":81387,"reasoningTokens":34,"cost":{"input":0.00958,"output":0.00333,"cacheRead":0.03968,"cacheWrite":0,"total":0.05259}},"stopReason":"toolUse","timestamp":1784188950504,"responseId":"resp_03e5b91f227b0634016a589016c620819baface17be9ba9700","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03e5b91f227b0634016a589019e364819ba498450e711b535f","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJAaPK_JiHtEKk14x9CoC04boz1Xj6fpPjUYSxkiuVdoFDRPl8XDwH62qJg2Albuv8Mhqr93d6X900gNfqcBCBmldBMhhWCng1yDBs_bjC-3quFj9A-0YCis8nLUWOMFE1Axi-JqBTCKhzabcgClNdkI4781GkZkYNz-K8DBmZmSeXtJc-7nqNHrGzprd8cCoPi_EPulMDtetCvdMbHKjqhNNwJFXU4OORpC5oEPggcqClJ0ogGLpG6lAfQ-Hu3VBNq00CeU3NKC0td7m-5cYMpc77iM0kDU-vXp1nMYFi9QHJ5qlbp_4A7ygc2AVhjE6syXDRNIzj-LEVu1dSv4oZBSwL6frBb5xNpuAtbc3joxoDvCBJUxOWWbPdI6GtMhDAmVt7Tay4_Xnfp3CqNfuOh9s8w1GBzRyJOezG9TI6T9muApXRmnhx6M1sQbT4ukYHzTKTI0zUTAFxTgjBzY1wgtPfztUkpupY0tXxf5Cf54MAkIJ5nWaZ0c2YWzjmbPaKIrd3qKBYt6Fwie_uN286cJ7Z61dOGswHdxRFUg2hBDXG05hO2keYiEyOD4OyfrM35NMXGKjPATTIwEDPkWtslyLn8-xYWLJtItxavHrPFTWnOJ0MDV-AHx7GME3jEc6N54No-NssoUOSPgg7xKnRebZxsyE9dayaU2cVQnH743ArLgQXcjv4xaSdUKnvOYRb6tjo625zqehdgNZJRm_MWE3Y9sI0HlCHxe8i5tQVclhVq-ALJApz6Wdu-5ctIwqu0JkhbX-04H8h9bzO3mGufZ28CMnD5iPnSNI5j3mBRyqisovHT45Tiy1OVKY8QKNNVKqTROdnkaec9tp1AbDORAXsuGhXQmt8BE0H7iJO45x1ntab-eyed00z6eUojsp8L89CNiPhpFwAZWFSVomAxZGE9e-19-15mLZqheH5WDVFrv2Z4HTyzm97S-ubUF6i0-ZX0a3p-Erd_-WJnpKj5bugBhSIcPyK5hQjfgUeHQ-4WFXB4_XyA-N0YKIB_CgULm8YdpOXbcIZ-xNBs3aWIIUFZ3Fk2z-OxZggx5dUBxVDS9d-_gzyBJQh22dzOOPaW-zlM_ImG9Uha0UsVzQqo5WKWGKE4dfI-_L7LTrAOasy0=","summary":[{"type":"summary_text","text":"**Planning primary source review**"}]},{"id":"fc_03e5b91f227b0634016a58901af6f4819bb0fd2ab1c9324aa0","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding official OMP docs\",\"query\":\"site:github.com/can1357/oh-my-pi \\\"registerCommand\\\" \\\"before_agent_start\\\" extension\",\"recency\":null,\"limit\":10,\"max_tokens\":20000,\"temperature\":0.1,\"num_search_results\":10}","call_id":"call_p87ldAlZw2VDflXCemnXmJ04","name":"web_search"}]},"duration":5480.776200000022,"ttft":3378.1424000000115,"contextSnapshot":{"promptTokens":81276,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_p87ldAlZw2VDflXCemnXmJ04|fc_03e5b91f227b0634016a58901af6f4819bb0fd2ab1c9324aa0","toolName":"web_search","startedAt":"2026-07-16T08:02:35.986Z","intent":"Finding official OMP docs"},"id":"a4547a8c","parentId":"c4e11a90","timestamp":"2026-07-16T08:02:35.986Z"}
{"type":"message","id":"f6986f19","parentId":"a4547a8c","timestamp":"2026-07-16T08:02:56.630Z","message":{"role":"toolResult","toolCallId":"call_p87ldAlZw2VDflXCemnXmJ04|fc_03e5b91f227b0634016a58901af6f4819bb0fd2ab1c9324aa0","toolName":"web_search","content":[{"type":"text","text":"Found it: the matching example is **`pirate.ts`** in `can1357/oh-my-pi`:\n\n- GitHub raw file: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\n- GitHub page: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts\n\nIt demonstrates exactly the combination you searched for:\n\n- `pi.registerCommand(\"pirate\", ...)`\n- `pi.on(\"before_agent_start\", ...)`\n- `systemPromptAppend`\n- extension usage under `packages/coding-agent/examples/extensions/`\n\nCore behavior:\n\n```ts\nexport default function pirateExtension(pi: ExtensionAPI) {\n  let pirateMode = false;\n\n  pi.registerCommand(\"pirate\", {\n    description: \"Toggle pirate mode (agent speaks like a pirate)\",\n    handler: async (_args, ctx) => {\n      pirateMode = !pirateMode;\n      ctx.ui.notify(\n        pirateMode ? \"Arrr! Pirate mode enabled!\" : \"Pirate mode disabled\",\n        \"info\"\n      );\n    },\n  });\n\n  pi.on(\"before_agent_start\", async () => {\n    if (pirateMode) {\n      return {\n        systemPromptAppend: `IMPORTANT: You are now in PIRATE MODE...`,\n      };\n    }\n    return undefined;\n  });\n}\n```\n\nRelated docs/results:\n\n- Example README lists `pirate.ts` as: “Demonstrates `systemPromptAppend` to dynamically modify system prompt”  \n  https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\n- Extension authoring docs:  \n  https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\n- Full extension runtime docs, including `before_agent_start`:  \n  https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\n\n## Sources\n5 sources\n[1] https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\n    https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\n[2] https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts\n    https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts\n[3] https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\n    https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\n[4] https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\n    https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\n[5] https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\n    https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md"}],"details":{"response":{"provider":"codex","answer":"Found it: the matching example is **`pirate.ts`** in `can1357/oh-my-pi`:\n\n- GitHub raw file: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\n- GitHub page: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts\n\nIt demonstrates exactly the combination you searched for:\n\n- `pi.registerCommand(\"pirate\", ...)`\n- `pi.on(\"before_agent_start\", ...)`\n- `systemPromptAppend`\n- extension usage under `packages/coding-agent/examples/extensions/`\n\nCore behavior:\n\n```ts\nexport default function pirateExtension(pi: ExtensionAPI) {\n  let pirateMode = false;\n\n  pi.registerCommand(\"pirate\", {\n    description: \"Toggle pirate mode (agent speaks like a pirate)\",\n    handler: async (_args, ctx) => {\n      pirateMode = !pirateMode;\n      ctx.ui.notify(\n        pirateMode ? \"Arrr! Pirate mode enabled!\" : \"Pirate mode disabled\",\n        \"info\"\n      );\n    },\n  });\n\n  pi.on(\"before_agent_start\", async () => {\n    if (pirateMode) {\n      return {\n        systemPromptAppend: `IMPORTANT: You are now in PIRATE MODE...`,\n      };\n    }\n    return undefined;\n  });\n}\n```\n\nRelated docs/results:\n\n- Example README lists `pirate.ts` as: “Demonstrates `systemPromptAppend` to dynamically modify system prompt”  \n  https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\n- Extension authoring docs:  \n  https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\n- Full extension runtime docs, including `before_agent_start`:  \n  https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","sources":[{"title":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts"},{"title":"https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts","url":"https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts"},{"title":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md"},{"title":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md"},{"title":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md"}],"usage":{"inputTokens":25677,"outputTokens":762,"totalTokens":28999},"model":"gpt-5.5","requestId":"resp_0a4e31cbcb59e15a016a58901ca1e08199b9c154bce8bbe29c"}},"isError":false,"timestamp":1784188976630}}
{"type":"message","id":"f7466a49","parentId":"f6986f19","timestamp":"2026-07-16T08:03:05.293Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Testing selective file reading methods**"},{"type":"toolCall","id":"call_UUUDFhfX60zuyZg7upUAW0R1|fc_0e2f03dd0e0c3649016a58903937948199a582d44a400ad0af","name":"read","arguments":{"i":"Reading OMP extension docs","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","selector":"1-300"}},{"type":"toolCall","id":"call_OWBpupLzaZxXUMxVEO10NKMV|fc_0e2f03dd0e0c3649016a58903939c88199872d59615095858e","name":"read","arguments":{"i":"Reading command examples","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md","selector":"1-240"}},{"type":"toolCall","id":"call_yqba12OrFNiolRiI4fUICB7T|fc_0e2f03dd0e0c3649016a58903939d88199a40208dfaca6c51e","name":"read","arguments":{"i":"Reading command implementation","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts","selector":"1-180"}},{"type":"toolCall","id":"call_8Nz1sp2rc54MFKOYief3AdZC|fc_0e2f03dd0e0c3649016a58903939e08199a2ed44a44eb5c212","name":"read","arguments":{"i":"Reading extension authoring","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md","selector":"1-300"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1697,"output":246,"cacheRead":80384,"cacheWrite":0,"totalTokens":82327,"reasoningTokens":34,"cost":{"input":0.008485000000000001,"output":0.00738,"cacheRead":0.040192,"cacheWrite":0,"total":0.056056999999999996}},"stopReason":"toolUse","timestamp":1784188976753,"responseId":"resp_0e2f03dd0e0c3649016a5890320f8c819994dd9851d88d2987","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0e2f03dd0e0c3649016a589034cb0881999663e34fd693059b","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJA50xDiJVsK68ePWvB2GySxJE4SZAFkkHDlTcgBR7-b-YbKNSSL6F-qGKK-Nr1qx-ZqmGqBMGRg31BKiqkYr7G3dTAvnJUWWi1-HrtSEfdwS3JzKOavbqeMVdBvlu95ek5cEp92AmRbmhrTCchqc9yXaBm3ILe_Y85cOLtoI-9r_QlkAlC4TBSf9UikGo4V11uLTV-Y5k9ur8vMLWUDAkRFYtECyiX4QyWnpARx0fR9qrUs_ZsgZvmvQ8ma-YwusWTJESwXQzFbzALz3vP5rJC2gqPOvbGtmK4Lz8TmzzV7Dy-1eu2zNVifdlUp5iecDiSYhy_lfknMzygTdiWc3ufe0CDQSKV4skLVRR0cD4eGQq9ver_-LMISbu3fuJ0SaKjvujpBRq7KUfU1zpwQp7Mu_NoGOWbTJYKX5GndJrJJi1fC96Elzk4tE8h99uj2SBnQ7SYt23xX-Sk_R_UkTlhrfIQNZ8cuYT0NYmT3ByPpwo0oRJDRKcOyk5Pg6Q9AQOYI76cB69b7khmHANw0lrgoOEMbDofnK_nVjJ6LRW00pzTkOKGMvHl5QATio5NZrcU3924UQ97I81Cgq6iE8uW-hJZVt95Hy2Ew-nwAp81mMcSvzsdB6r5rIoNGJ89NcgIGDDMYdFIYmpXIQxPHXc3aNBWLACFgPzMPnhK5c5co0bSn9d3qI6Xk1A2psY011US_T5u3avGVCbON6LbtqKmGnHMTkqtrFTI2tg17QlVHdgxZ_AmcTITHQLiSBHEtlchCMBbFYN5rYgzbLStqMNNRLT9qPP4z6V2120xiybvZWdjMj_9sp9ilVmJODlIKweOfXi5aFgxP4Sy5ZNALs9mA0chdkVRsE983qlCp4rYvU5d2tb4b3dgcgU79xvW8MNYcLrXaYjYsAJw-lSqBsY7u3xEHYiechcWgaIl58eGhMeWqdb9kT8waaZPDFkAm40EAtYlTTrGy0mnX1ttH6Y4lviTP3FMmgWVLIA9DIb73wyNCaklK_ocfaqGj8pLi9RebIDy89olqR6HqMmSutY40pKPA_P2UsV-39A2BP0LxU7hI2az-oIT6jI3652TNCzxrbqamGNZH6hLllDoByRZ6Hg==","summary":[{"type":"summary_text","text":"**Testing selective file reading methods**"}]},{"id":"fc_0e2f03dd0e0c3649016a58903937948199a582d44a400ad0af","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading OMP extension docs\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\",\"selector\":\"1-300\"}","call_id":"call_UUUDFhfX60zuyZg7upUAW0R1","name":"read"},{"id":"fc_0e2f03dd0e0c3649016a58903939c88199872d59615095858e","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading command examples\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\",\"selector\":\"1-240\"}","call_id":"call_OWBpupLzaZxXUMxVEO10NKMV","name":"read"},{"id":"fc_0e2f03dd0e0c3649016a58903939d88199a40208dfaca6c51e","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading command implementation\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\",\"selector\":\"1-180\"}","call_id":"call_yqba12OrFNiolRiI4fUICB7T","name":"read"},{"id":"fc_0e2f03dd0e0c3649016a58903939e08199a2ed44a44eb5c212","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension authoring\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\",\"selector\":\"1-300\"}","call_id":"call_8Nz1sp2rc54MFKOYief3AdZC","name":"read"}]},"duration":8538.31660000002,"ttft":4030.535499999998,"contextSnapshot":{"promptTokens":82081,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_UUUDFhfX60zuyZg7upUAW0R1|fc_0e2f03dd0e0c3649016a58903937948199a582d44a400ad0af","toolName":"read","startedAt":"2026-07-16T08:03:05.293Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md"},"intent":"Reading OMP extension docs"},"id":"e2dde2e7","parentId":"f7466a49","timestamp":"2026-07-16T08:03:05.293Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_OWBpupLzaZxXUMxVEO10NKMV|fc_0e2f03dd0e0c3649016a58903939c88199872d59615095858e","toolName":"read","startedAt":"2026-07-16T08:03:05.293Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md"},"intent":"Reading command examples"},"id":"46bf6a87","parentId":"e2dde2e7","timestamp":"2026-07-16T08:03:05.293Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_yqba12OrFNiolRiI4fUICB7T|fc_0e2f03dd0e0c3649016a58903939d88199a40208dfaca6c51e","toolName":"read","startedAt":"2026-07-16T08:03:05.293Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts"},"intent":"Reading command implementation"},"id":"eb8fb41d","parentId":"46bf6a87","timestamp":"2026-07-16T08:03:05.293Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_8Nz1sp2rc54MFKOYief3AdZC|fc_0e2f03dd0e0c3649016a58903939e08199a2ed44a44eb5c212","toolName":"read","startedAt":"2026-07-16T08:03:05.294Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md"},"intent":"Reading extension authoring"},"id":"19364b21","parentId":"eb8fb41d","timestamp":"2026-07-16T08:03:05.294Z"}
{"type":"message","id":"14fe4c24","parentId":"19364b21","timestamp":"2026-07-16T08:03:05.301Z","message":{"role":"toolResult","toolCallId":"call_UUUDFhfX60zuyZg7upUAW0R1|fc_0e2f03dd0e0c3649016a58903937948199a582d44a400ad0af","toolName":"read","content":[{"type":"text","text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\nContent-Type: text/plain\nMethod: text\n\n---\n\n# Extensions\n\nPrimary guide for authoring runtime extensions in `packages/coding-agent`.\n\nThis document covers the current extension runtime in:\n\n- `src/extensibility/extensions/types.ts`\n- `src/extensibility/extensions/runner.ts`\n- `src/extensibility/extensions/wrapper.ts`\n- `src/extensibility/extensions/index.ts`\n- `src/modes/controllers/extension-ui-controller.ts`\n\nFor discovery paths and filesystem loading rules, see [`extension-loading.md`](./extension-loading.md).\n\nFor packaged user-facing extension CLIs/features such as `packages/swarm-extension`, see [`user-facing-packages.md`](./user-facing-packages.md).\n\n## What an extension is\n\nAn extension is a TS/JS module exporting a default factory:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function myExtension(pi: ExtensionAPI) {\n  // register handlers/tools/commands/renderers\n}\n```\n\nExtensions can combine all of the following in one module:\n\n- event handlers (`pi.on(...)`)\n- LLM-callable tools (`pi.registerTool(...)`)\n- slash commands (`pi.registerCommand(...)`)\n- keyboard shortcuts and flags\n- custom message rendering\n- session/message injection APIs (`sendMessage`, `sendUserMessage`, `appendEntry`)\n\n## Runtime model\n\n1. Extensions are imported and their factory functions run.\n2. During that load phase, registration methods are valid; runtime action methods are not yet initialized.\n3. `ExtensionRunner.initialize(...)` wires live actions/contexts for the active mode.\n4. Session/agent/tool lifecycle events are emitted to handlers.\n5. Every tool execution is wrapped with extension interception (`tool_call` / `tool_result`).\n\n```text\nExtension lifecycle (simplified)\n\nload paths\n   │\n   ▼\nimport module + run factory (registration only)\n   │\n   ▼\nExtensionRunner.initialize(mode/session/tool registry)\n   │\n   ├─ emit session/agent events to handlers\n   ├─ wrap tool execution (tool_call/tool_result)\n   └─ expose runtime actions (sendMessage, setActiveTools, ...)\n```\n\nImportant constraint from `loader.ts`:\n\n- calling action methods like `pi.sendMessage()` during extension load throws `ExtensionRuntimeNotInitializedError`\n- register first; perform runtime behavior from events/commands/tools\n\n## Quick start\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n  const { z } = pi.zod;\n\n  pi.setLabel(\"Safety + Utilities\");\n\n  pi.on(\"session_start\", async (_event, ctx) => {\n    ctx.ui.notify(`Extension loaded in ${ctx.cwd}`, \"info\");\n  });\n\n  pi.on(\"tool_call\", async (event) => {\n    if (event.toolName === \"bash\" && event.input.command?.includes(\"rm -rf\")) {\n      return { block: true, reason: \"Blocked by extension policy\" };\n    }\n  });\n\n  pi.registerTool({\n    name: \"hello_extension\",\n    label: \"Hello Extension\",\n    description: \"Return a greeting\",\n    parameters: z.object({ name: z.string() }),\n    async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {\n      return {\n        content: [{ type: \"text\", text: `Hello, ${params.name}` }],\n        details: { greeted: params.name },\n      };\n    },\n  });\n\n  pi.registerCommand(\"hello-ext\", {\n    description: \"Show queue state\",\n    handler: async (_args, ctx) => {\n      ctx.ui.notify(`pending=${ctx.hasPendingMessages()}`, \"info\");\n    },\n  });\n}\n```\n\n## Extension API surfaces\n\n## 1) Registration and actions (`ExtensionAPI`)\n\nCore methods:\n\n- `on(event, handler)`\n- `registerTool`, `registerCommand`, `registerShortcut`, `registerFlag`\n- `registerMessageRenderer`, `registerAssistantThinkingRenderer`\n- `setLabel`, `getFlag`\n- `sendMessage`, `sendUserMessage`, `appendEntry`, `exec`\n- `getActiveTools`, `getAllTools`, `setActiveTools`\n- `getCommands`\n- `getSessionName`, `setSessionName`\n- `setModel`, `getThinkingLevel`, `setThinkingLevel`\n- `registerProvider`\n- `events` (shared event bus)\n\nIn interactive mode, `input` handlers run before the built-in first-message auto-title check. Extensions that call `await pi.setSessionName(...)` from `input` can set the persisted session name and prevent the default auto-generated title from running for that session.\n\nAlso exposed:\n\n- `pi.logger`\n- `pi.typebox` (zod-backed compatibility shim for legacy TypeBox-style schemas)\n- `pi.zod` (injected `zod/v4` module — canonical for tool parameter schemas)\n- `pi.pi` (package exports)\n\n### Message delivery semantics\n\n`pi.sendMessage(message, options)` supports:\n\n- `deliverAs: \"steer\"` (default) — interrupts current run\n- `deliverAs: \"followUp\"` — queued to run after current run\n- `deliverAs: \"nextTurn\"` — stored and injected on the next user prompt\n- `triggerTurn: true` — starts a turn when idle (also honored with `deliverAs: \"nextTurn\"`: idle prompts immediately; while streaming the queued message schedules an internal continuation)\n\n`pi.sendUserMessage(content, { deliverAs })` always goes through prompt flow. Omit `deliverAs` to start a normal prompt when idle; while streaming, omitted `deliverAs` queues the message as a steer. Set `deliverAs: \"followUp\"` to wait until the current run finishes.\n\n## 2) Handler context (`ExtensionContext`)\n\nHandlers and tool `execute` receive `ctx` with:\n\n- `ui`\n- `hasUI`\n- `cwd`\n- `sessionManager` (read-only)\n- `modelRegistry`, `model`\n- `models` (read-only model query — see below)\n- `getContextUsage()`\n- `compact(...)`\n- `isIdle()`, `hasPendingMessages()`, `abort()`\n- `shutdown()`\n- `getSystemPrompt()`\n- `memory` (optional structured memory runtime — status/search/save across the configured backend)\n\n### Model selection (`ctx.models`)\n\n`ctx.models` is a read-only facade for picking and comparing models the same way core does:\n\n- `list()` — authenticated models available this session.\n- `current()` — the live session model (read lazily, so it reflects `/model` switches).\n- `resolve(spec)` — a model string (`provider/id`, bare id) or role alias (`@slow`, a configured role) → `Model`, honoring the same settings-backed aliases and match preferences as `--model`. Returns `undefined` when nothing matches.\n- `family(model)` — an opaque lineage token for \"same family?\" checks (Claude point releases share a token; Claude and GPT differ). Compare it; don't persist it (the vocabulary tracks new releases).\n\n```ts\n// Pick a model from a different family than the current one (e.g. a cross-family reviewer).\nconst current = ctx.models.current();\nconst contrasting = ctx.models\n  .list()\n  .find(m => current && ctx.models.family(m) !== ctx.models.family(current));\n```\n\n## 3) Command context (`ExtensionCommandContext`)\n\nCommand handlers additionally get:\n\n- `waitForIdle()`\n- `newSession(...)`\n- `switchSession(...)`\n- `branch(entryId)`\n- `navigateTree(targetId, { summarize })`\n- `reload()`\n\nUse command context for session-control flows; these methods are intentionally separated from general event handlers.\n\n## Event surface (current names and behavior)\n\nCanonical event unions and payload types are in `types.ts`.\n\n### Session lifecycle\n\n- `session_start`\n- `session_before_switch` / `session_switch`\n- `session_before_branch` / `session_branch`\n- `session_before_compact` / `session.compacting` / `session_compact`\n- `session_before_tree` / `session_tree`\n- `session_shutdown`\n\nCancelable pre-events:\n\n- `session_before_switch` → `{ cancel?: boolean }`\n- `session_before_branch` → `{ cancel?: boolean; skipConversationRestore?: boolean }`\n- `session_before_compact` → `{ cancel?: boolean; compaction?: CompactionResult }`\n- `session_before_tree` → `{ cancel?: boolean; summary?: { summary: string; details?: unknown } }`\n\n### Prompt and turn lifecycle\n\n- `input`\n- `before_agent_start`\n- `before_provider_request` (may replace provider request payload)\n- `after_provider_response`\n- `context`\n- `agent_start` / `agent_end` — agent loop lifecycle notification; `agent_end` remains notification-only\n- `session_stop` — main-session stop hook, awaited before settle; may continue with `{ continue: true, additionalContext }` or `{ decision: \"block\", reason }`; capped at 8 consecutive continuations and never fires for task/subagent sessions\n- `turn_start` / `turn_end`\n- `message_start` / `message_update` / `message_end`\n\n### Tool lifecycle\n\n- `tool_call` (pre-exec, may block)\n- `tool_result` (post-exec, may patch content/details/isError)\n- `tool_execution_start` / `tool_execution_update` / `tool_execution_end` (observability)\n- `tool_approval_requested` / `tool_approval_resolved` (observability; emitted by `wrapper.ts` only when a tool requires approval and an approval handler is registered)\n\n`tool_result` is middleware-style: handlers run in extension order and each sees prior modifications.\n\n### Reliability/runtime signals\n\n- `auto_compaction_start` / `auto_compaction_end`\n- `auto_retry_start` / `auto_retry_end`\n- `ttsr_triggered`\n- `todo_reminder`\n- `goal_updated`\n- `credential_disabled`\n\n### User command interception\n\n- `user_bash` (override with `{ result }`)\n- `user_python` (override with `{ result }`)\n\n### `resources_discover`\n\n`resources_discover` exists in extension types and `ExtensionRunner`.\nCurrent runtime note: `ExtensionRunner.emitResourcesDiscover(...)` is implemented, but there are no `AgentSession` callsites invoking it in the current codebase.\n\n## Tool authoring details\n\n`registerTool` uses `ToolDefinition` from `types.ts`.\n\nCurrent `execute` signature:\n\n```ts\nexecute(\n\ttoolCallId,\n\tparams,\n\tsignal,\n\tonUpdate,\n\tctx,\n): Promise<AgentToolResult>\n```\n\nTemplate:\n\n```ts\nconst { z } = pi.zod;\n\npi.registerTool({\n  name: \"my_tool\",\n  label: \"My Tool\",\n  description: \"...\",\n  parameters: z.object({}),\n  hidden: false,\n  defaultInactive: false,\n  deferrable: false,\n  async execute(_id, _params, signal, onUpdate, ctx) {\n    if (signal?.aborted) {\n      return { content: [{ type: \"text\", text: \"Cancelled\" }] };\n    }\n    onUpdate?.({ content: [{ type: \"text\", text: \"Working...\" }] });\n    return { content: [{ type: \"text\", text: \"Done\" }], details: {} };\n  },\n  onSession(event, ctx) {\n    // reason: start|switch|branch|tree|shutdown\n  },\n  renderCall(args, options, theme) {\n    // optional TUI render\n  },\n  renderResult(result, options, theme, args) {\n    // optional TUI render\n\n[122 more lines in URL output. Use :304 to continue]"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\nContent-Type: text/plain\nMethod: text\n\n---\n\n# Extensions\n\nPrimary guide for authoring runtime extensions in `packages/coding-agent`.\n\nThis document covers the current extension runtime in:\n\n- `src/extensibility/extensions/types.ts`\n- `src/extensibility/extensions/runner.ts`\n- `src/extensibility/extensions/wrapper.ts`\n- `src/extensibility/extensions/index.ts`\n- `src/modes/controllers/extension-ui-controller.ts`\n\nFor discovery paths and filesystem loading rules, see [`extension-loading.md`](./extension-loading.md).\n\nFor packaged user-facing extension CLIs/features such as `packages/swarm-extension`, see [`user-facing-packages.md`](./user-facing-packages.md).\n\n## What an extension is\n\nAn extension is a TS/JS module exporting a default factory:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function myExtension(pi: ExtensionAPI) {\n  // register handlers/tools/commands/renderers\n}\n```\n\nExtensions can combine all of the following in one module:\n\n- event handlers (`pi.on(...)`)\n- LLM-callable tools (`pi.registerTool(...)`)\n- slash commands (`pi.registerCommand(...)`)\n- keyboard shortcuts and flags\n- custom message rendering\n- session/message injection APIs (`sendMessage`, `sendUserMessage`, `appendEntry`)\n\n## Runtime model\n\n1. Extensions are imported and their factory functions run.\n2. During that load phase, registration methods are valid; runtime action methods are not yet initialized.\n3. `ExtensionRunner.initialize(...)` wires live actions/contexts for the active mode.\n4. Session/agent/tool lifecycle events are emitted to handlers.\n5. Every tool execution is wrapped with extension interception (`tool_call` / `tool_result`).\n\n```text\nExtension lifecycle (simplified)\n\nload paths\n   │\n   ▼\nimport module + run factory (registration only)\n   │\n   ▼\nExtensionRunner.initialize(mode/session/tool registry)\n   │\n   ├─ emit session/agent events to handlers\n   ├─ wrap tool execution (tool_call/tool_result)\n   └─ expose runtime actions (sendMessage, setActiveTools, ...)\n```\n\nImportant constraint from `loader.ts`:\n\n- calling action methods like `pi.sendMessage()` during extension load throws `ExtensionRuntimeNotInitializedError`\n- register first; perform runtime behavior from events/commands/tools\n\n## Quick start\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n  const { z } = pi.zod;\n\n  pi.setLabel(\"Safety + Utilities\");\n\n  pi.on(\"session_start\", async (_event, ctx) => {\n    ctx.ui.notify(`Extension loaded in ${ctx.cwd}`, \"info\");\n  });\n\n  pi.on(\"tool_call\", async (event) => {\n    if (event.toolName === \"bash\" && event.input.command?.includes(\"rm -rf\")) {\n      return { block: true, reason: \"Blocked by extension policy\" };\n    }\n  });\n\n  pi.registerTool({\n    name: \"hello_extension\",\n    label: \"Hello Extension\",\n    description: \"Return a greeting\",\n    parameters: z.object({ name: z.string() }),\n    async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {\n      return {\n        content: [{ type: \"text\", text: `Hello, ${params.name}` }],\n        details: { greeted: params.name },\n      };\n    },\n  });\n\n  pi.registerCommand(\"hello-ext\", {\n    description: \"Show queue state\",\n    handler: async (_args, ctx) => {\n      ctx.ui.notify(`pending=${ctx.hasPendingMessages()}`, \"info\");\n    },\n  });\n}\n```\n\n## Extension API surfaces\n\n## 1) Registration and actions (`ExtensionAPI`)\n\nCore methods:\n\n- `on(event, handler)`\n- `registerTool`, `registerCommand`, `registerShortcut`, `registerFlag`\n- `registerMessageRenderer`, `registerAssistantThinkingRenderer`\n- `setLabel`, `getFlag`\n- `sendMessage`, `sendUserMessage`, `appendEntry`, `exec`\n- `getActiveTools`, `getAllTools`, `setActiveTools`\n- `getCommands`\n- `getSessionName`, `setSessionName`\n- `setModel`, `getThinkingLevel`, `setThinkingLevel`\n- `registerProvider`\n- `events` (shared event bus)\n\nIn interactive mode, `input` handlers run before the built-in first-message auto-title check. Extensions that call `await pi.setSessionName(...)` from `input` can set the persisted session name and prevent the default auto-generated title from running for that session.\n\nAlso exposed:\n\n- `pi.logger`\n- `pi.typebox` (zod-backed compatibility shim for legacy TypeBox-style schemas)\n- `pi.zod` (injected `zod/v4` module — canonical for tool parameter schemas)\n- `pi.pi` (package exports)\n\n### Message delivery semantics\n\n`pi.sendMessage(message, options)` supports:\n\n- `deliverAs: \"steer\"` (default) — interrupts current run\n- `deliverAs: \"followUp\"` — queued to run after current run\n- `deliverAs: \"nextTurn\"` — stored and injected on the next user prompt\n- `triggerTurn: true` — starts a turn when idle (also honored with `deliverAs: \"nextTurn\"`: idle prompts immediately; while streaming the queued message schedules an internal continuation)\n\n`pi.sendUserMessage(content, { deliverAs })` always goes through prompt flow. Omit `deliverAs` to start a normal prompt when idle; while streaming, omitted `deliverAs` queues the message as a steer. Set `deliverAs: \"followUp\"` to wait until the current run finishes.\n\n## 2) Handler context (`ExtensionContext`)\n\nHandlers and tool `execute` receive `ctx` with:\n\n- `ui`\n- `hasUI`\n- `cwd`\n- `sessionManager` (read-only)\n- `modelRegistry`, `model`\n- `models` (read-only model query — see below)\n- `getContextUsage()`\n- `compact(...)`\n- `isIdle()`, `hasPendingMessages()`, `abort()`\n- `shutdown()`\n- `getSystemPrompt()`\n- `memory` (optional structured memory runtime — status/search/save across the configured backend)\n\n### Model selection (`ctx.models`)\n\n`ctx.models` is a read-only facade for picking and comparing models the same way core does:\n\n- `list()` — authenticated models available this session.\n- `current()` — the live session model (read lazily, so it reflects `/model` switches).\n- `resolve(spec)` — a model string (`provider/id`, bare id) or role alias (`@slow`, a configured role) → `Model`, honoring the same settings-backed aliases and match preferences as `--model`. Returns `undefined` when nothing matches.\n- `family(model)` — an opaque lineage token for \"same family?\" checks (Claude point releases share a token; Claude and GPT differ). Compare it; don't persist it (the vocabulary tracks new releases).\n\n```ts\n// Pick a model from a different family than the current one (e.g. a cross-family reviewer).\nconst current = ctx.models.current();\nconst contrasting = ctx.models\n  .list()\n  .find(m => current && ctx.models.family(m) !== ctx.models.family(current));\n```\n\n## 3) Command context (`ExtensionCommandContext`)\n\nCommand handlers additionally get:\n\n- `waitForIdle()`\n- `newSession(...)`\n- `switchSession(...)`\n- `branch(entryId)`\n- `navigateTree(targetId, { summarize })`\n- `reload()`\n\nUse command context for session-control flows; these methods are intentionally separated from general event handlers.\n\n## Event surface (current names and behavior)\n\nCanonical event unions and payload types are in `types.ts`.\n\n### Session lifecycle\n\n- `session_start`\n- `session_before_switch` / `session_switch`\n- `session_before_branch` / `session_branch`\n- `session_before_compact` / `session.compacting` / `session_compact`\n- `session_before_tree` / `session_tree`\n- `session_shutdown`\n\nCancelable pre-events:\n\n- `session_before_switch` → `{ cancel?: boolean }`\n- `session_before_branch` → `{ cancel?: boolean; skipConversationRestore?: boolean }`\n- `session_before_compact` → `{ cancel?: boolean; compaction?: CompactionResult }`\n- `session_before_tree` → `{ cancel?: boolean; summary?: { summary: string; details?: unknown } }`\n\n### Prompt and turn lifecycle\n\n- `input`\n- `before_agent_start`\n- `before_provider_request` (may replace provider request payload)\n- `after_provider_response`\n- `context`\n- `agent_start` / `agent_end` — agent loop lifecycle notification; `agent_end` remains notification-only\n- `session_stop` — main-session stop hook, awaited before settle; may continue with `{ continue: true, additionalContext }` or `{ decision: \"block\", reason }`; capped at 8 consecutive continuations and never fires for task/subagent sessions\n- `turn_start` / `turn_end`\n- `message_start` / `message_update` / `message_end`\n\n### Tool lifecycle\n\n- `tool_call` (pre-exec, may block)\n- `tool_result` (post-exec, may patch content/details/isError)\n- `tool_execution_start` / `tool_execution_update` / `tool_execution_end` (observability)\n- `tool_approval_requested` / `tool_approval_resolved` (observability; emitted by `wrapper.ts` only when a tool requires approval and an approval handler is registered)\n\n`tool_result` is middleware-style: handlers run in extension order and each sees prior modifications.\n\n### Reliability/runtime signals\n\n- `auto_compaction_start` / `auto_compaction_end`\n- `auto_retry_start` / `auto_retry_end`\n- `ttsr_triggered`\n- `todo_reminder`\n- `goal_updated`\n- `credential_disabled`\n\n### User command interception\n\n- `user_bash` (override with `{ result }`)\n- `user_python` (override with `{ result }`)\n\n### `resources_discover`\n\n`resources_discover` exists in extension types and `ExtensionRunner`.\nCurrent runtime note: `ExtensionRunner.emitResourcesDiscover(...)` is implemented, but there are no `AgentSession` callsites invoking it in the current codebase.\n\n## Tool authoring details\n\n`registerTool` uses `ToolDefinition` from `types.ts`.\n\nCurrent `execute` signature:\n\n```ts\nexecute(\n\ttoolCallId,\n\tparams,\n\tsignal,\n\tonUpdate,\n\tctx,\n): Promise<AgentToolResult>\n```\n\nTemplate:\n\n```ts\nconst { z } = pi.zod;\n\npi.registerTool({\n  name: \"my_tool\",\n  label: \"My Tool\",\n  description: \"...\",\n  parameters: z.object({}),\n  hidden: false,\n  defaultInactive: false,\n  deferrable: false,\n  async execute(_id, _params, signal, onUpdate, ctx) {\n    if (signal?.aborted) {\n      return { content: [{ type: \"text\", text: \"Cancelled\" }] };\n    }\n    onUpdate?.({ content: [{ type: \"text\", text: \"Working...\" }] });\n    return { content: [{ type: \"text\", text: \"Done\" }], details: {} };\n  },\n  onSession(event, ctx) {\n    // reason: start|switch|branch|tree|shutdown\n  },\n  renderCall(args, options, theme) {\n    // optional TUI render\n  },\n  renderResult(result, options, theme, args) {\n    // optional TUI render","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md"}}},"isError":false,"timestamp":1784188985301}}
{"type":"message","id":"69c1f9da","parentId":"14fe4c24","timestamp":"2026-07-16T08:03:05.396Z","message":{"role":"toolResult","toolCallId":"call_8Nz1sp2rc54MFKOYief3AdZC|fc_0e2f03dd0e0c3649016a58903939e08199a2ed44a44eb5c212","toolName":"read","content":[{"type":"text","text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\nContent-Type: text/plain\nMethod: text\n\n---\n\n---\nname: authoring-extensions\ndescription: Use when creating a new omp extension. Covers ExtensionAPI, factory signature, tool/command/event registration, and local-dev testing.\n---\n\n# Authoring Extensions\n\nExtensions are the primary way to add capabilities to `oh-my-pi`. A single extension module can register tools the LLM can call, slash commands users can invoke, and event handlers that run throughout the session lifecycle — all from one TypeScript file.\n\n## Minimum viable extension\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n  pi.on(\"session_start\", async (_event, ctx) => {\n    ctx.ui.notify(\"My extension loaded!\", \"info\");\n  });\n}\n```\n\nThat is a working extension. Drop it into `~/.omp/agent/extensions/hello.ts` and restart omp to see the notification.\n\n## Full example\n\nThe following extension registers a slash command, a tool, and a session-start hook:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function myExtension(pi: ExtensionAPI) {\n  const z = pi.zod;\n\n  // Runs once when the session loads\n  pi.on(\"session_start\", async (_event, ctx) => {\n    ctx.ui.notify(`Session ready in ${ctx.cwd}`, \"info\");\n  });\n\n  // Slash command: /greet\n  pi.registerCommand(\"greet\", {\n    description: \"Send a greeting into the conversation\",\n    handler: async (args, ctx) => {\n      const name = args.trim() || \"world\";\n      pi.sendMessage(\n        {\n          customType: \"greeting\",\n          content: `Hello, ${name}!`,\n          display: true,\n          attribution: \"user\",\n        },\n        { triggerTurn: false }\n      );\n      ctx.ui.notify(`Greeted ${name}`, \"info\");\n    },\n  });\n\n  // LLM-callable tool\n  pi.registerTool({\n    name: \"word_count\",\n    label: \"Word Count\",\n    description: \"Count the words in a string\",\n    parameters: z.object({\n      text: z.string().describe(\"Text to count\"),\n    }),\n    async execute(_id, params, _signal, _onUpdate, _ctx) {\n      const count = params.text.split(/\\s+/).filter(Boolean).length;\n      return {\n        content: [{ type: \"text\", text: String(count) }],\n        details: { count },\n      };\n    },\n  });\n}\n```\n\n## Discovery paths\n\nomp loads extension modules from these sources:\n\n1. Native `.omp` locations discovered through the capability system:\n   - `<cwd>/.omp/extensions/`\n   - `~/.omp/agent/extensions/`\n   - legacy extension paths listed in `.omp/settings.json#extensions` or `~/.omp/agent/settings.json#extensions`\n2. Installed plugins under `~/.omp/plugins/node_modules` (`omp plugin install` npm/git specs, or `omp plugin link`) via their `omp.extensions`/`pi.extensions` manifests. Marketplace cache installs do not feed extension modules — they surface skills/commands/hooks/tools/MCP only.\n3. Explicit configured paths passed by the CLI (`omp --extension ./my-ext.ts`, also `-e`; `--hook` is treated as an alias) and by the `extensions:` setting in config.\n\nThe runtime de-duplicates by resolved absolute path — first seen wins.\n\nWhen a path points to a directory, omp resolves the entry point in this order:\n\n1. `package.json` with `omp.extensions` (or legacy `pi.extensions`) field\n2. `index.ts`\n3. `index.js`\n\nWhen scanning an `extensions/` directory, omp also loads direct `*.ts`/`*.js` files and one-level subdirectories that have `index.ts`, `index.js`, or a manifest.\n\nExtension packages can also bundle sibling capability directories. When a package is loaded through `extensions:` or `--extension`/`-e`, the `omp-plugins` provider discovers its `skills/`, `hooks/pre|post/`, `tools/`, `commands/`, `rules/`, `prompts/`, and `.mcp.json`.\n\n## package.json manifest\n\nTo package an extension as an installable plugin, add an `omp` field to `package.json`:\n\n```json\n{\n  \"name\": \"my-omp-extension\",\n  \"omp\": {\n    \"extensions\": [\"./src/main.ts\"]\n  }\n}\n```\n\nThe legacy `pi` key is also accepted for backwards compatibility:\n\n```json\n{\n  \"pi\": {\n    \"extensions\": [\"./index.ts\"]\n  }\n}\n```\n\nMultiple entry points are supported:\n\n```json\n{\n  \"omp\": {\n    \"extensions\": [\"./src/safety.ts\", \"./src/tools.ts\"]\n  }\n}\n```\n\n## Registering commands\n\n```ts\npi.registerCommand(\"my-cmd\", {\n  description: \"What the command does\",\n  handler: async (args, ctx) => {\n    // args: everything the user typed after /my-cmd\n    // ctx: ExtensionCommandContext — includes ctx.ui, ctx.cwd, session controls\n    ctx.ui.notify(\"Running!\", \"info\");\n    await ctx.waitForIdle();\n    await ctx.newSession();\n  },\n});\n```\n\n`ExtensionCommandContext` session-control methods (safe to call from commands only):\n\n| Method | Effect |\n|---|---|\n| `waitForIdle()` | Wait for the agent to finish streaming |\n| `newSession(opts?)` | Open a fresh session |\n| `switchSession(path)` | Switch to an existing session file |\n| `branch(entryId)` | Fork from a specific history entry |\n| `navigateTree(id, opts?)` | Jump to a different point in the session tree |\n| `reload()` | Reload the session runtime |\n| `compact(opts?)` | Compact the current context |\n\n## Registering tools\n\nTools are called by the LLM. Parameters use [Zod](https://zod.dev) schemas, available at `pi.zod`:\n\n```ts\nconst z = pi.zod;\n\npi.registerTool({\n  name: \"search_notes\",           // snake_case, unique\n  label: \"Search Notes\",          // human-readable label for TUI\n  description: \"Full-text search through project notes\",\n  parameters: z.object({\n    query: z.string().describe(\"Search query\"),\n    limit: z.number().default(10).describe(\"Max results\").optional(),\n  }),\n  async execute(toolCallId, params, signal, onUpdate, ctx) {\n    if (signal?.aborted) {\n      return { content: [{ type: \"text\", text: \"Cancelled\" }] };\n    }\n    onUpdate?.({ content: [{ type: \"text\", text: \"Searching...\" }] });\n    // ... do work ...\n    return {\n      content: [{ type: \"text\", text: `Found N results for \"${params.query}\"` }],\n      details: { query: params.query, count: 0 },\n    };\n  },\n});\n```\n\n## Subscribing to events\n\n```ts\npi.on(\"tool_call\", async (event, ctx) => {\n  // event.toolName, event.input, event.toolCallId\n  if (event.toolName !== \"bash\") return;\n\n  const command = String((event.input as { command?: unknown }).command ?? \"\");\n  if (command.includes(\"rm -rf /\")) {\n    return { block: true, reason: \"Blocked by safety policy\" };\n  }\n});\n\npi.on(\"turn_end\", async (_event, ctx) => {\n  ctx.ui.setStatus(\"tokens\", `~${ctx.getContextUsage()?.tokens ?? \"?\"} tokens`);\n});\n\npi.on(\"session_stop\", async (event) => {\n  if (event.stop_hook_active) return;\n  return { continue: true, additionalContext: `Review final status after turn ${event.turn_id}.` };\n});\n```\n\nFull event catalog: see [extension authoring guide](../extensions.md).\n\n## Extension vs hook — when to use which\n\n| Need | Use |\n|---|---|\n| Tools + commands + events in one module | **Extension** (`ExtensionAPI`) |\n| Pure event interception (policy, redaction) | **Extension** or **Hook** (both work; extension is preferred) |\n| Legacy hook module already exists | **Hook** (`HookAPI` from `@oh-my-pi/pi-coding-agent/extensibility/hooks`) |\n| Registering a provider, shortcut, or CLI flag | **Extension only** |\n| Shipping as a marketplace plugin | **Extension** (use `package.json` manifest) |\n\nExtensions are a strict superset of hooks. New authoring should use `ExtensionAPI`.\n\n## Debugging\n\nomp writes structured logs to a rotating file under `~/.omp/logs/` (debug level is always on; nothing is written to the console, which would corrupt the TUI). Tail today's log to see extension load diagnostics:\n\n```\ntail -f ~/.omp/logs/omp.$(date +%F).log\n```\n\nFailed extension loads are logged with their path and error. Loaded extensions may also emit their own debug logs via `pi.logger`.\n\nTo temporarily disable a specific extension module by name without removing the file:\n\n```yaml\n# ~/.omp/agent/config.yml\ndisabledExtensions:\n  - extension-module:my-ext\n```\n\nThe derived name is the filename stem (or directory name for `index.ts`-style entries): `/path/to/my-ext.ts` → `my-ext`.\n\n## Important constraints\n\n- **Do not call runtime actions during load.** Methods like `pi.sendMessage()` throw `ExtensionRuntimeNotInitializedError` if called synchronously during module evaluation (before a session is active). Register handlers/tools/commands during load; perform runtime actions only from event handlers, tools, or commands.\n- **`tool_call` errors are fail-closed.** If a `tool_call` handler throws, the tool is blocked.\n- **Command names must not clash with built-ins.** Conflicts are skipped with a diagnostic log.\n- **Reserved shortcuts are ignored** (`ctrl+c`, `ctrl+d`, `ctrl+z`, `ctrl+k`, `ctrl+p`, `ctrl+l`, `ctrl+o`, `ctrl+t`, `ctrl+g`, `ctrl+q`, `alt+m`, `shift+tab`, `shift+ctrl+p`, `alt+enter`, `escape`, `enter`).\n\n## Further reading\n\n- `docs/extensions.md` — runtime internals and full API surface reference\n- `docs/extension-loading.md` — detailed path resolution rules\n- `docs/hooks.md` — hook subsystem internals\n- `docs/skills/examples/hello-extension/` — complete working example"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\nContent-Type: text/plain\nMethod: text\n\n---\n\n---\nname: authoring-extensions\ndescription: Use when creating a new omp extension. Covers ExtensionAPI, factory signature, tool/command/event registration, and local-dev testing.\n---\n\n# Authoring Extensions\n\nExtensions are the primary way to add capabilities to `oh-my-pi`. A single extension module can register tools the LLM can call, slash commands users can invoke, and event handlers that run throughout the session lifecycle — all from one TypeScript file.\n\n## Minimum viable extension\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n  pi.on(\"session_start\", async (_event, ctx) => {\n    ctx.ui.notify(\"My extension loaded!\", \"info\");\n  });\n}\n```\n\nThat is a working extension. Drop it into `~/.omp/agent/extensions/hello.ts` and restart omp to see the notification.\n\n## Full example\n\nThe following extension registers a slash command, a tool, and a session-start hook:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function myExtension(pi: ExtensionAPI) {\n  const z = pi.zod;\n\n  // Runs once when the session loads\n  pi.on(\"session_start\", async (_event, ctx) => {\n    ctx.ui.notify(`Session ready in ${ctx.cwd}`, \"info\");\n  });\n\n  // Slash command: /greet\n  pi.registerCommand(\"greet\", {\n    description: \"Send a greeting into the conversation\",\n    handler: async (args, ctx) => {\n      const name = args.trim() || \"world\";\n      pi.sendMessage(\n        {\n          customType: \"greeting\",\n          content: `Hello, ${name}!`,\n          display: true,\n          attribution: \"user\",\n        },\n        { triggerTurn: false }\n      );\n      ctx.ui.notify(`Greeted ${name}`, \"info\");\n    },\n  });\n\n  // LLM-callable tool\n  pi.registerTool({\n    name: \"word_count\",\n    label: \"Word Count\",\n    description: \"Count the words in a string\",\n    parameters: z.object({\n      text: z.string().describe(\"Text to count\"),\n    }),\n    async execute(_id, params, _signal, _onUpdate, _ctx) {\n      const count = params.text.split(/\\s+/).filter(Boolean).length;\n      return {\n        content: [{ type: \"text\", text: String(count) }],\n        details: { count },\n      };\n    },\n  });\n}\n```\n\n## Discovery paths\n\nomp loads extension modules from these sources:\n\n1. Native `.omp` locations discovered through the capability system:\n   - `<cwd>/.omp/extensions/`\n   - `~/.omp/agent/extensions/`\n   - legacy extension paths listed in `.omp/settings.json#extensions` or `~/.omp/agent/settings.json#extensions`\n2. Installed plugins under `~/.omp/plugins/node_modules` (`omp plugin install` npm/git specs, or `omp plugin link`) via their `omp.extensions`/`pi.extensions` manifests. Marketplace cache installs do not feed extension modules — they surface skills/commands/hooks/tools/MCP only.\n3. Explicit configured paths passed by the CLI (`omp --extension ./my-ext.ts`, also `-e`; `--hook` is treated as an alias) and by the `extensions:` setting in config.\n\nThe runtime de-duplicates by resolved absolute path — first seen wins.\n\nWhen a path points to a directory, omp resolves the entry point in this order:\n\n1. `package.json` with `omp.extensions` (or legacy `pi.extensions`) field\n2. `index.ts`\n3. `index.js`\n\nWhen scanning an `extensions/` directory, omp also loads direct `*.ts`/`*.js` files and one-level subdirectories that have `index.ts`, `index.js`, or a manifest.\n\nExtension packages can also bundle sibling capability directories. When a package is loaded through `extensions:` or `--extension`/`-e`, the `omp-plugins` provider discovers its `skills/`, `hooks/pre|post/`, `tools/`, `commands/`, `rules/`, `prompts/`, and `.mcp.json`.\n\n## package.json manifest\n\nTo package an extension as an installable plugin, add an `omp` field to `package.json`:\n\n```json\n{\n  \"name\": \"my-omp-extension\",\n  \"omp\": {\n    \"extensions\": [\"./src/main.ts\"]\n  }\n}\n```\n\nThe legacy `pi` key is also accepted for backwards compatibility:\n\n```json\n{\n  \"pi\": {\n    \"extensions\": [\"./index.ts\"]\n  }\n}\n```\n\nMultiple entry points are supported:\n\n```json\n{\n  \"omp\": {\n    \"extensions\": [\"./src/safety.ts\", \"./src/tools.ts\"]\n  }\n}\n```\n\n## Registering commands\n\n```ts\npi.registerCommand(\"my-cmd\", {\n  description: \"What the command does\",\n  handler: async (args, ctx) => {\n    // args: everything the user typed after /my-cmd\n    // ctx: ExtensionCommandContext — includes ctx.ui, ctx.cwd, session controls\n    ctx.ui.notify(\"Running!\", \"info\");\n    await ctx.waitForIdle();\n    await ctx.newSession();\n  },\n});\n```\n\n`ExtensionCommandContext` session-control methods (safe to call from commands only):\n\n| Method | Effect |\n|---|---|\n| `waitForIdle()` | Wait for the agent to finish streaming |\n| `newSession(opts?)` | Open a fresh session |\n| `switchSession(path)` | Switch to an existing session file |\n| `branch(entryId)` | Fork from a specific history entry |\n| `navigateTree(id, opts?)` | Jump to a different point in the session tree |\n| `reload()` | Reload the session runtime |\n| `compact(opts?)` | Compact the current context |\n\n## Registering tools\n\nTools are called by the LLM. Parameters use [Zod](https://zod.dev) schemas, available at `pi.zod`:\n\n```ts\nconst z = pi.zod;\n\npi.registerTool({\n  name: \"search_notes\",           // snake_case, unique\n  label: \"Search Notes\",          // human-readable label for TUI\n  description: \"Full-text search through project notes\",\n  parameters: z.object({\n    query: z.string().describe(\"Search query\"),\n    limit: z.number().default(10).describe(\"Max results\").optional(),\n  }),\n  async execute(toolCallId, params, signal, onUpdate, ctx) {\n    if (signal?.aborted) {\n      return { content: [{ type: \"text\", text: \"Cancelled\" }] };\n    }\n    onUpdate?.({ content: [{ type: \"text\", text: \"Searching...\" }] });\n    // ... do work ...\n    return {\n      content: [{ type: \"text\", text: `Found N results for \"${params.query}\"` }],\n      details: { query: params.query, count: 0 },\n    };\n  },\n});\n```\n\n## Subscribing to events\n\n```ts\npi.on(\"tool_call\", async (event, ctx) => {\n  // event.toolName, event.input, event.toolCallId\n  if (event.toolName !== \"bash\") return;\n\n  const command = String((event.input as { command?: unknown }).command ?? \"\");\n  if (command.includes(\"rm -rf /\")) {\n    return { block: true, reason: \"Blocked by safety policy\" };\n  }\n});\n\npi.on(\"turn_end\", async (_event, ctx) => {\n  ctx.ui.setStatus(\"tokens\", `~${ctx.getContextUsage()?.tokens ?? \"?\"} tokens`);\n});\n\npi.on(\"session_stop\", async (event) => {\n  if (event.stop_hook_active) return;\n  return { continue: true, additionalContext: `Review final status after turn ${event.turn_id}.` };\n});\n```\n\nFull event catalog: see [extension authoring guide](../extensions.md).\n\n## Extension vs hook — when to use which\n\n| Need | Use |\n|---|---|\n| Tools + commands + events in one module | **Extension** (`ExtensionAPI`) |\n| Pure event interception (policy, redaction) | **Extension** or **Hook** (both work; extension is preferred) |\n| Legacy hook module already exists | **Hook** (`HookAPI` from `@oh-my-pi/pi-coding-agent/extensibility/hooks`) |\n| Registering a provider, shortcut, or CLI flag | **Extension only** |\n| Shipping as a marketplace plugin | **Extension** (use `package.json` manifest) |\n\nExtensions are a strict superset of hooks. New authoring should use `ExtensionAPI`.\n\n## Debugging\n\nomp writes structured logs to a rotating file under `~/.omp/logs/` (debug level is always on; nothing is written to the console, which would corrupt the TUI). Tail today's log to see extension load diagnostics:\n\n```\ntail -f ~/.omp/logs/omp.$(date +%F).log\n```\n\nFailed extension loads are logged with their path and error. Loaded extensions may also emit their own debug logs via `pi.logger`.\n\nTo temporarily disable a specific extension module by name without removing the file:\n\n```yaml\n# ~/.omp/agent/config.yml\ndisabledExtensions:\n  - extension-module:my-ext\n```\n\nThe derived name is the filename stem (or directory name for `index.ts`-style entries): `/path/to/my-ext.ts` → `my-ext`.\n\n## Important constraints\n\n- **Do not call runtime actions during load.** Methods like `pi.sendMessage()` throw `ExtensionRuntimeNotInitializedError` if called synchronously during module evaluation (before a session is active). Register handlers/tools/commands during load; perform runtime actions only from event handlers, tools, or commands.\n- **`tool_call` errors are fail-closed.** If a `tool_call` handler throws, the tool is blocked.\n- **Command names must not clash with built-ins.** Conflicts are skipped with a diagnostic log.\n- **Reserved shortcuts are ignored** (`ctrl+c`, `ctrl+d`, `ctrl+z`, `ctrl+k`, `ctrl+p`, `ctrl+l`, `ctrl+o`, `ctrl+t`, `ctrl+g`, `ctrl+q`, `alt+m`, `shift+tab`, `shift+ctrl+p`, `alt+enter`, `escape`, `enter`).\n\n## Further reading\n\n- `docs/extensions.md` — runtime internals and full API surface reference\n- `docs/extension-loading.md` — detailed path resolution rules\n- `docs/hooks.md` — hook subsystem internals\n- `docs/skills/examples/hello-extension/` — complete working example","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md"}}},"isError":false,"timestamp":1784188985395}}
{"type":"message","id":"b8027780","parentId":"69c1f9da","timestamp":"2026-07-16T08:03:05.528Z","message":{"role":"toolResult","toolCallId":"call_OWBpupLzaZxXUMxVEO10NKMV|fc_0e2f03dd0e0c3649016a58903939c88199872d59615095858e","toolName":"read","content":[{"type":"text","text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\nContent-Type: text/plain\nMethod: text\n\n---\n\n# Extension Examples\n\nExample extensions for pi-coding-agent.\n\n## Usage\n\n```bash\n# Load an extension with --extension flag\npi --extension examples/extensions/permission-gate.ts\n\n# Or copy to extensions directory for auto-discovery\ncp permission-gate.ts ~/.omp/agent/extensions/\n```\n\n## Examples\n\n### Lifecycle & Safety\n\n| Extension                | Description                                                                  |\n| ------------------------ | ---------------------------------------------------------------------------- |\n| `permission-gate.ts`     | Prompts for confirmation before dangerous bash commands (rm -rf, sudo, etc.) |\n| `protected-paths.ts`     | Blocks writes to protected paths (.env, .git/, node_modules/)                |\n| `confirm-destructive.ts` | Confirms before destructive session actions (clear, switch, branch)          |\n| `dirty-repo-guard.ts`    | Prevents session changes with uncommitted git changes                        |\n\n### Custom Tools\n\n| Extension     | Description                                                                   |\n| ------------- | ----------------------------------------------------------------------------- |\n| `todo.ts`     | Todo list tool + `/todos` command with custom rendering and state persistence |\n| `hello.ts`    | Minimal custom tool example                                                   |\n| `question.ts` | Demonstrates `ctx.ui.select()` for asking the user questions                  |\n| `subagent/`   | Delegate tasks to specialized subagents with isolated context windows         |\n\n### Commands & UI\n\n| Extension        | Description                                                                    |\n| ---------------- | ------------------------------------------------------------------------------ |\n| `plan-mode.ts`   | Claude Code-style plan mode for read-only exploration with `/plan` command     |\n| `tools.ts`       | Interactive `/tools` command to enable/disable tools with session persistence  |\n| `handoff.ts`     | Transfer context to a new focused session via `/handoff <goal>`                |\n| `qna.ts`         | Extracts questions from last response into editor via `ctx.ui.setEditorText()` |\n| `status-line.ts` | Shows turn progress in footer via `ctx.ui.setStatus()` with themed colors      |\n| `thinking-note.ts` | Adds display-only supplemental UI below assistant thinking blocks              |\n| `snake.ts`       | Snake game with custom UI, keyboard handling, and session persistence          |\n\n### Git Integration\n\n| Extension                | Description                                                               |\n| ------------------------ | ------------------------------------------------------------------------- |\n| `git-checkpoint.ts`      | Creates git stash checkpoints at each turn for code restoration on branch |\n| `auto-commit-on-exit.ts` | Auto-commits on exit using last assistant message for commit message      |\n\n### System Prompt & Compaction\n\n| Extension              | Description                                                           |\n| ---------------------- | --------------------------------------------------------------------- |\n| `pirate.ts`            | Demonstrates `systemPromptAppend` to dynamically modify system prompt |\n| `custom-compaction.ts` | Custom compaction that summarizes entire conversation                 |\n\n### External Dependencies\n\n| Extension         | Description                                                               |\n| ----------------- | ------------------------------------------------------------------------- |\n| `chalk-logger.ts` | Uses chalk from parent node_modules (demonstrates jiti module resolution) |\n| `with-deps/`      | Extension with its own package.json and dependencies                      |\n| `file-trigger.ts` | Watches a trigger file and injects contents into conversation             |\n\n## Writing Extensions\n\nSee [docs/extensions.md](../../docs/extensions.md) for full documentation.\n\n```typescript\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n\tconst z = pi.zod;\n\n\t// Subscribe to lifecycle events\n\tpi.on(\"tool_call\", async (event, ctx) => {\n\t\tif (event.toolName === \"bash\" && event.input.command?.includes(\"rm -rf\")) {\n\t\t\tconst ok = await ctx.ui.confirm(\"Dangerous!\", \"Allow rm -rf?\");\n\t\t\tif (!ok) return { block: true, reason: \"Blocked by user\" };\n\t\t}\n\t});\n\n\t// Register custom tools\n\tpi.registerTool({\n\t\tname: \"greet\",\n\t\tlabel: \"Greeting\",\n\t\tdescription: \"Generate a greeting\",\n\t\tparameters: z.object({\n\t\t\tname: z.string().describe(\"Name to greet\"),\n\t\t}),\n\t\tasync execute(toolCallId, params, onUpdate, ctx, signal) {\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Hello, ${params.name}!` }],\n\t\t\t\tdetails: {},\n\t\t\t};\n\t\t},\n\t});\n\n\t// Register commands\n\tpi.registerCommand(\"hello\", {\n\t\tdescription: \"Say hello\",\n\t\thandler: async (args, ctx) => {\n\t\t\tctx.ui.notify(\"Hello!\", \"info\");\n\t\t},\n\t});\n}\n```\n## Key Patterns\n\n**Use `z.enum` for discriminated string tool args:**\n\n```typescript\nconst { z } = pi.zod;\n\nparameters: z.object({\n\taction: z.enum([\"list\", \"add\"]),\n});\n```\n\n**State persistence via details:**\n\n```typescript\n// Store state in tool result details for proper branching support\nreturn {\n\tcontent: [{ type: \"text\", text: \"Done\" }],\n\tdetails: { todos: [...todos], nextId }, // Persisted in session\n};\n\n// Reconstruct on session events\npi.on(\"session_start\", async (_event, ctx) => {\n\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\tif (entry.type === \"message\" && entry.message.toolName === \"my_tool\") {\n\t\t\tconst details = entry.message.details;\n\t\t\t// Reconstruct state from details\n\t\t}\n\t}\n});\n```"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\nContent-Type: text/plain\nMethod: text\n\n---\n\n# Extension Examples\n\nExample extensions for pi-coding-agent.\n\n## Usage\n\n```bash\n# Load an extension with --extension flag\npi --extension examples/extensions/permission-gate.ts\n\n# Or copy to extensions directory for auto-discovery\ncp permission-gate.ts ~/.omp/agent/extensions/\n```\n\n## Examples\n\n### Lifecycle & Safety\n\n| Extension                | Description                                                                  |\n| ------------------------ | ---------------------------------------------------------------------------- |\n| `permission-gate.ts`     | Prompts for confirmation before dangerous bash commands (rm -rf, sudo, etc.) |\n| `protected-paths.ts`     | Blocks writes to protected paths (.env, .git/, node_modules/)                |\n| `confirm-destructive.ts` | Confirms before destructive session actions (clear, switch, branch)          |\n| `dirty-repo-guard.ts`    | Prevents session changes with uncommitted git changes                        |\n\n### Custom Tools\n\n| Extension     | Description                                                                   |\n| ------------- | ----------------------------------------------------------------------------- |\n| `todo.ts`     | Todo list tool + `/todos` command with custom rendering and state persistence |\n| `hello.ts`    | Minimal custom tool example                                                   |\n| `question.ts` | Demonstrates `ctx.ui.select()` for asking the user questions                  |\n| `subagent/`   | Delegate tasks to specialized subagents with isolated context windows         |\n\n### Commands & UI\n\n| Extension        | Description                                                                    |\n| ---------------- | ------------------------------------------------------------------------------ |\n| `plan-mode.ts`   | Claude Code-style plan mode for read-only exploration with `/plan` command     |\n| `tools.ts`       | Interactive `/tools` command to enable/disable tools with session persistence  |\n| `handoff.ts`     | Transfer context to a new focused session via `/handoff <goal>`                |\n| `qna.ts`         | Extracts questions from last response into editor via `ctx.ui.setEditorText()` |\n| `status-line.ts` | Shows turn progress in footer via `ctx.ui.setStatus()` with themed colors      |\n| `thinking-note.ts` | Adds display-only supplemental UI below assistant thinking blocks              |\n| `snake.ts`       | Snake game with custom UI, keyboard handling, and session persistence          |\n\n### Git Integration\n\n| Extension                | Description                                                               |\n| ------------------------ | ------------------------------------------------------------------------- |\n| `git-checkpoint.ts`      | Creates git stash checkpoints at each turn for code restoration on branch |\n| `auto-commit-on-exit.ts` | Auto-commits on exit using last assistant message for commit message      |\n\n### System Prompt & Compaction\n\n| Extension              | Description                                                           |\n| ---------------------- | --------------------------------------------------------------------- |\n| `pirate.ts`            | Demonstrates `systemPromptAppend` to dynamically modify system prompt |\n| `custom-compaction.ts` | Custom compaction that summarizes entire conversation                 |\n\n### External Dependencies\n\n| Extension         | Description                                                               |\n| ----------------- | ------------------------------------------------------------------------- |\n| `chalk-logger.ts` | Uses chalk from parent node_modules (demonstrates jiti module resolution) |\n| `with-deps/`      | Extension with its own package.json and dependencies                      |\n| `file-trigger.ts` | Watches a trigger file and injects contents into conversation             |\n\n## Writing Extensions\n\nSee [docs/extensions.md](../../docs/extensions.md) for full documentation.\n\n```typescript\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n\tconst z = pi.zod;\n\n\t// Subscribe to lifecycle events\n\tpi.on(\"tool_call\", async (event, ctx) => {\n\t\tif (event.toolName === \"bash\" && event.input.command?.includes(\"rm -rf\")) {\n\t\t\tconst ok = await ctx.ui.confirm(\"Dangerous!\", \"Allow rm -rf?\");\n\t\t\tif (!ok) return { block: true, reason: \"Blocked by user\" };\n\t\t}\n\t});\n\n\t// Register custom tools\n\tpi.registerTool({\n\t\tname: \"greet\",\n\t\tlabel: \"Greeting\",\n\t\tdescription: \"Generate a greeting\",\n\t\tparameters: z.object({\n\t\t\tname: z.string().describe(\"Name to greet\"),\n\t\t}),\n\t\tasync execute(toolCallId, params, onUpdate, ctx, signal) {\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Hello, ${params.name}!` }],\n\t\t\t\tdetails: {},\n\t\t\t};\n\t\t},\n\t});\n\n\t// Register commands\n\tpi.registerCommand(\"hello\", {\n\t\tdescription: \"Say hello\",\n\t\thandler: async (args, ctx) => {\n\t\t\tctx.ui.notify(\"Hello!\", \"info\");\n\t\t},\n\t});\n}\n```\n## Key Patterns\n\n**Use `z.enum` for discriminated string tool args:**\n\n```typescript\nconst { z } = pi.zod;\n\nparameters: z.object({\n\taction: z.enum([\"list\", \"add\"]),\n});\n```\n\n**State persistence via details:**\n\n```typescript\n// Store state in tool result details for proper branching support\nreturn {\n\tcontent: [{ type: \"text\", text: \"Done\" }],\n\tdetails: { todos: [...todos], nextId }, // Persisted in session\n};\n\n// Reconstruct on session events\npi.on(\"session_start\", async (_event, ctx) => {\n\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\tif (entry.type === \"message\" && entry.message.toolName === \"my_tool\") {\n\t\t\tconst details = entry.message.details;\n\t\t\t// Reconstruct state from details\n\t\t}\n\t}\n});\n```","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md"}}},"isError":false,"timestamp":1784188985528}}
{"type":"message","id":"e443553b","parentId":"b8027780","timestamp":"2026-07-16T08:03:05.556Z","message":{"role":"toolResult","toolCallId":"call_yqba12OrFNiolRiI4fUICB7T|fc_0e2f03dd0e0c3649016a58903939d88199a40208dfaca6c51e","toolName":"read","content":[{"type":"text","text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\nContent-Type: text/plain\nMethod: text\n\n---\n\n/**\n * Pirate Extension\n *\n * Demonstrates using systemPromptAppend in before_agent_start to dynamically\n * modify the system prompt based on extension state.\n *\n * Usage:\n * 1. Copy this file to ~/.omp/agent/extensions/ (legacy: ~/.pi/agent/extensions/) or your project's .omp/extensions/\n * 2. Use /pirate to toggle pirate mode\n * 3. When enabled, the agent will respond like a pirate\n */\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function pirateExtension(pi: ExtensionAPI) {\n\tlet pirateMode = false;\n\n\t// Register /pirate command to toggle pirate mode\n\tpi.registerCommand(\"pirate\", {\n\t\tdescription: \"Toggle pirate mode (agent speaks like a pirate)\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tpirateMode = !pirateMode;\n\t\t\tctx.ui.notify(pirateMode ? \"Arrr! Pirate mode enabled!\" : \"Pirate mode disabled\", \"info\");\n\t\t},\n\t});\n\n\t// Append to system prompt when pirate mode is enabled\n\tpi.on(\"before_agent_start\", async () => {\n\t\tif (pirateMode) {\n\t\t\treturn {\n\t\t\t\tsystemPromptAppend: `\nIMPORTANT: You are now in PIRATE MODE. You must:\n- Speak like a stereotypical pirate in all responses\n- Use phrases like \"Arrr!\", \"Ahoy!\", \"Shiver me timbers!\", \"Avast!\", \"Ye scurvy dog!\"\n- Replace \"my\" with \"me\", \"you\" with \"ye\", \"your\" with \"yer\"\n- Refer to the user as \"matey\" or \"landlubber\"\n- End sentences with nautical expressions\n- Still complete the actual task correctly, just in pirate speak\n`,\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t});\n}"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\nContent-Type: text/plain\nMethod: text\n\n---\n\n/**\n * Pirate Extension\n *\n * Demonstrates using systemPromptAppend in before_agent_start to dynamically\n * modify the system prompt based on extension state.\n *\n * Usage:\n * 1. Copy this file to ~/.omp/agent/extensions/ (legacy: ~/.pi/agent/extensions/) or your project's .omp/extensions/\n * 2. Use /pirate to toggle pirate mode\n * 3. When enabled, the agent will respond like a pirate\n */\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function pirateExtension(pi: ExtensionAPI) {\n\tlet pirateMode = false;\n\n\t// Register /pirate command to toggle pirate mode\n\tpi.registerCommand(\"pirate\", {\n\t\tdescription: \"Toggle pirate mode (agent speaks like a pirate)\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tpirateMode = !pirateMode;\n\t\t\tctx.ui.notify(pirateMode ? \"Arrr! Pirate mode enabled!\" : \"Pirate mode disabled\", \"info\");\n\t\t},\n\t});\n\n\t// Append to system prompt when pirate mode is enabled\n\tpi.on(\"before_agent_start\", async () => {\n\t\tif (pirateMode) {\n\t\t\treturn {\n\t\t\t\tsystemPromptAppend: `\nIMPORTANT: You are now in PIRATE MODE. You must:\n- Speak like a stereotypical pirate in all responses\n- Use phrases like \"Arrr!\", \"Ahoy!\", \"Shiver me timbers!\", \"Avast!\", \"Ye scurvy dog!\"\n- Replace \"my\" with \"me\", \"you\" with \"ye\", \"your\" with \"yer\"\n- Refer to the user as \"matey\" or \"landlubber\"\n- End sentences with nautical expressions\n- Still complete the actual task correctly, just in pirate speak\n`,\n\t\t\t};\n\t\t}\n\t\treturn undefined;\n\t});\n}","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts"}}},"isError":false,"timestamp":1784188985556}}
{"type":"message","id":"caf0108c","parentId":"e443553b","timestamp":"2026-07-16T08:03:20.826Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Evaluating safe continuation injection points**\n\n**Analyzing injection options before next tool call**"},{"type":"toolCall","id":"call_FXqiIXVLdNreHYGWO71OBM7v|fc_0e2f03dd0e0c3649016a589048bef881999c94687da79a0b53","name":"read","arguments":{"i":"Reading remaining OMP docs","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","selector":"300-450"}},{"type":"toolCall","id":"call_zPgGWS8zz767hgDk394dsjlw|fc_0e2f03dd0e0c3649016a589048bf0c81998cf7c336b102a4da","name":"web_search","arguments":{"i":"Researching provider request event","query":"site:github.com/can1357/oh-my-pi \"before_provider_request\" \"messages\" extension","recency":null,"limit":10,"max_tokens":20000,"temperature":0.1,"num_search_results":10}},{"type":"toolCall","id":"call_6X9jm5u2DE8es5PeKvj2NvAO|fc_0e2f03dd0e0c3649016a589048bf148199be1930c5cc0df12b","name":"web_search","arguments":{"i":"Researching command completion API","query":"site:github.com/can1357/oh-my-pi \"getArgumentCompletions\" registerCommand ui.select","recency":null,"limit":10,"max_tokens":20000,"temperature":0.1,"num_search_results":10}},{"type":"toolCall","id":"call_KdLxkrb3M2IIjW2XbfbTep7t|fc_0e2f03dd0e0c3649016a589048bf188199a3f5411bf12cc09d","name":"web_search","arguments":{"i":"Researching message event shape","query":"site:github.com/can1357/oh-my-pi \"message_end\" assistant ExtensionEvent","recency":null,"limit":10,"max_tokens":20000,"temperature":0.1,"num_search_results":10}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7322,"output":703,"cacheRead":81408,"cacheWrite":0,"totalTokens":89433,"reasoningTokens":427,"cost":{"input":0.036610000000000004,"output":0.02109,"cacheRead":0.040704,"cacheWrite":0,"total":0.09840399999999999}},"stopReason":"toolUse","timestamp":1784188985607,"responseId":"resp_0e2f03dd0e0c3649016a589039dd54819990722c0bcb833f50","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0e2f03dd0e0c3649016a58903b0e3481999c672001758463ee","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJBIu81TIR4YjnP4YahL9z7GnvtCN7tQNFdxAz7ewYEMtXYr2SGCYhMpmF-laCnIUnAsd9RHTqtvREyWA0uWngsIzMs11ZpqashTzLlfeAeCh4IziBK3xizltxwdCXTyt6kpSz5BXmbxg2Er2506VHN_LQqHPNjjuIc5ZTF6HlwZMwccn3sSWP-daQY5T_LUh-iTm_GZ-fmBn-JcJM9mjcgR0NrtAj7D_gTnz7OASSWQZoxRtZqL5lqw734eVJmGplyJcc7EyqwNh-eL8Jd_IYa__hgfK58hMl_utvGaEqAq6CsqXhpdmNNZVgv5S1hJkVXwFWU4IUv9381-N5Ee7UViHEHzoAtM-7yKfviL7F6X2h6SLofO15L3aVc1F6ynmfzps1k4VB5c8grM0_6I8lIzJD-KddvQBcjeoBLM4hEHU_yhmh97UPJZ6Yz95q4b4ujosO7g2bbcdRL-FKl6exQ4gBQ6THIwKFj2h5bBJjmqHQGkoCi5Iwhe-6cB1Rmm-cTcovgyQmoeZshlpk642FjsWzXJkpzqHiy9Fqnx8oLsepxXZX5PfpbFDMEuUAx1x89OQlkBEkvzGTX0mNW7q2wrvD-psJtHCMjdE3SP5LxucDW4fpLrjSAyqL4MeKK1h8ySxmvQgFgWkJZcdYFF9-nL63toWj4AmcVgFaWOdQZJ9aTxzZjoyVYY1Z36N72PkgENluw4fn_tT_LXRcyWnWdErPLuJnZFhalt4ZFX2sdQrlfQQccSwPDx_pLt6ePFmlujKo1ajwcDFTw3-xXGWwU39ciHAUG76KFzCCE3Z5FR1ej63Ko7Pqx2ZA2z6ItlxmQ6HhL6SdABBqV-7MSoDL7Xqgmeb8I2EvfulI9mAvTn3TP-pCp-p5DywqgxHCcJC0ZoBqLenM6L7pgMBJfaqFXJd3PdBVKAzmvvVod-si4wdxGYpzQwLvwjRmSt2ZdzsLVtqmmgbq9nMPKJ-Gb_97WIXMLGlaxJ2nbnHiyEAeLYZYDTL5y6s6yhO7Jh6FrKnq-Ez7H3C9mCxSUMvyngB5136OKp41tzijssC5Ht3Arvi4QYRQlQeeXoFe9JM_tbPk0GQJVBVQd0utH0T5Src0N2X_Va2G1miiEH-2DApXdxqAMdBnxZOTXWoi-5zfRhcTfLow3NRKxcsWvAzpIDKCICllHMrw4fnlswQA7-1Uds0uv4C-uXKzyy1w_0B2wR8TiYGtyOR50Ey2LMwKwd7gE-48ew-MBxseOxq35F0ilmvnZCuPWB_93qLbtu3Wfz7IbbUAgeeQYVf5NfqEXoSoz6fr-xnlLTEyZJY0_P-hyf2ooLMTtdtANlWNQmRfNZoBxDn7OOm5AG4D8VXR-M0yezA18jECzSwezYDaVetFziTXiXf-T2dmqXKl5y7pzwJpyUjaTM45Pomhr6hVkXZmmUXNrRZLWj6gOGXbX_gl2bQq_0hG-u8pSHwjtkeItYfLIOGMb25ErBp2o2kDqzn7Yiui7tUB9K5v6l5n4Q8YgjRj0_-47iX3nPalP0qEcKoM0cJL1piZoMPdzl1ZtFycgU-hzicq7ZH-fbMG7atBW4fa4Bs1eelbAxo10kQd6na7197UXwBv9UXTt42GdOrhTIK8DUteYy3k_G4nZlpojWxhXIgkD2qMe3v_hNmNEToeU8FucOI9hQN7hlVq39JKR9X1Setvr1wWF7uCOLlv7nAF0me8RuC1G-gfmKtPE4NU3OMGn3mwnJPOfJfTqEk_lpRTStkJbTI_FNCA0cuEij62zvHu0WZYdOFP3uWRjk9vwjGjTnh3YEZJmBIqDYdWgyflRxJj5qFQeuXMJLk6yuMVa-7GBZKYUZwgKApy-88XBkFosjVI41rqM4mE9EiaQaU_mnaVrIZzJd9Y9FJb7QgKP3CYOec89tEoNlIfiRl2kQ6KZJjFXDWcvMjqxpiRW32a-9J92EpgYD3-olWvOzxTFFnNYTxF8dGdc0EKx29R9cYRL5IpBgNMCpJpHhHFYyEpv0IEK70zXe69PL_ceQd-0o5tuyDyysZWgn5A4Px1hQ4P9pc6-5tnJISd1MoqD7t_wUJkFSg3uDGPMA29j-qApY2a0ynB5ay7_ApSzGuqRr-ODHktLooZP6tO-dws4fRpy0vRmO_eVs1IaMSKIZWzDMnIqg26wmj3Y85c0Kc7w7ELUbnowOgGzd6LtAfIWD2-hsP0i8OOcLnfGJx6c4utCuTl32x7bFwB0pRTrG2pFO1Q87zs3btQoNTe6h70iST3lqRtUQi4ekhOxYETMru5hs03LGyQpUQNYdKb-KfkBpm8o8RFE2nTifs_ExcH-sDI5ZcWdaXcf4k6DES3KvbRFTVDM4sesSi5AwYb6NxCpX7GutsWe8G_Dz49pwLxBv1u_FasHrO4ly_Rc09leiBgEjW0v_dTp4yO1wauTQuP9vzVCFeSS6Bt-8D2jt8p-AL8j6gjXvvCBfr1UukgnIgg0sD3H3Y3YpDk4uQ6cB6aGuNuMui55gDywbPRYVty_oUiH7yAP-jBJSmvOYCLVAPryIIOVPKPYlrvry_CCFcGe5vOZiRlt6vk7zNOvjVnTeB0SUBFUsTXZPVBbYfjF6P5aIk4aYjoiBgVQKNGw4gOSEtU0FS4HffIZTOsWw9vUu1Mwy4APfNNwv3ARrJEKxZmiP8LWsSpIHPCD1Ofaz5JLq29o79tfcOeZXpUXhWApHXo1EFpKAuwFlGck4zbhjZrE7qNMNV7e76jbYZFw0Se3s2aNNCZ2BBxD8hBIxdx0mdEZqmvCTzmhqFOBycFAgwQz4pH24pFZhdNoRHXNvGORiuIID--FDv4GmLIlYx8e4SUNL__tyAfg4E33Uk0qFlEg7pQ3F6xrWw5f9c4q_rPlXCZT_xBRYP9dAZ0RJHphV4_2zSpI3C79_2wuuwv00Y0im0aMq_jukD2oGXlwx42trkr6Z2GGNbna7t5m5-jv2zgCYpp95lR3JgbRInZrxui5SWvypmt_GAzI1xbLgjcGjhmvLaWmbwv1v8AekilAHc_d621dKDXXbvKZaVmigcl-2zHJaicwzvJ7k_7zKPrqMZPtktQJjNmIr6KEMVZa31Fhlp5KWF7W6_qH12DP56H-KV_l6N_aE2HCTlQ9vyfqQeH59ICMV012vVfnaD7akgG5brzJqu3_d3HsxPPV8FRE6XoIj6EPb7Eh5CcObnwWyyNO2EiZq2Sebc2CMcbJJQkkzGgegUpjJQAOKSpYU_txl80hLiLGk3jLpSpZRZOgUETDG9f81yxhCwuj-wxmcMB8As3NU_UjazfzQDiqfQJfXZdVnOXdUzmtK0cXztp-Yo58Et4uC5tu6FiQkBqvyjzqnfyJ4EzkaYGVWXd5nNUduFGcLeNhlrCsefEb1_F_hS1KbtWAHE2hkhKrNMTrUwOX7HnYZneE_qMALI_k-DgKiFJRXCB1yCzYIrms2f--All4_lsTOs7Fl3I3jSLEzlAYTvrwwVUvbmjGK3olyoW0yDnJ3wSVWbveXaC6J1qGcJS5Hn-faC5K8ijRkSqOpfkGZ9aXK8NoN-dNRQ0ncwdacLEX_bVtMGOzGfONBS0dE_YkdgtcRjf7a4WxeQkYPweNVNJv25RU4QsfIPL-ENGgTWyPzgqn_ZfRKATyesooHSDrjjuB_KOsI6WoAtSRc7Wmgm9iP-bxh2LsY3xogyN6RxSNEXGdZ5eqwkVB8VIdz_U0R3f4fEZTKHrvHiRtpWXtC70Ope3T30VYNdFEjirv1yxo9nIlhQ6vxACBzyr7NlUNEmp2VQsG_dFtGILx79PGqZvCQE7vVEKdl7J6RLiZOq_G_PoRKsDIfvLVNeOE3hoxKuPVs1l8PACn9_bkYEOz58ubip2bb-eGQUSyo7agpLQHFo3XBjHE1KzqYrv95DPWtJADFRuR3Q-faEE2JmQ==","summary":[{"type":"summary_text","text":"**Evaluating safe continuation injection points**"},{"type":"summary_text","text":"**Analyzing injection options before next tool call**"}]},{"id":"fc_0e2f03dd0e0c3649016a589048bef881999c94687da79a0b53","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading remaining OMP docs\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\",\"selector\":\"300-450\"}","call_id":"call_FXqiIXVLdNreHYGWO71OBM7v","name":"read"},{"id":"fc_0e2f03dd0e0c3649016a589048bf0c81998cf7c336b102a4da","type":"function_call","status":"completed","arguments":"{\"i\":\"Researching provider request event\",\"query\":\"site:github.com/can1357/oh-my-pi \\\"before_provider_request\\\" \\\"messages\\\" extension\",\"recency\":null,\"limit\":10,\"max_tokens\":20000,\"temperature\":0.1,\"num_search_results\":10}","call_id":"call_zPgGWS8zz767hgDk394dsjlw","name":"web_search"},{"id":"fc_0e2f03dd0e0c3649016a589048bf148199be1930c5cc0df12b","type":"function_call","status":"completed","arguments":"{\"i\":\"Researching command completion API\",\"query\":\"site:github.com/can1357/oh-my-pi \\\"getArgumentCompletions\\\" registerCommand ui.select\",\"recency\":null,\"limit\":10,\"max_tokens\":20000,\"temperature\":0.1,\"num_search_results\":10}","call_id":"call_6X9jm5u2DE8es5PeKvj2NvAO","name":"web_search"},{"id":"fc_0e2f03dd0e0c3649016a589048bf188199a3f5411bf12cc09d","type":"function_call","status":"completed","arguments":"{\"i\":\"Researching message event shape\",\"query\":\"site:github.com/can1357/oh-my-pi \\\"message_end\\\" assistant ExtensionEvent\",\"recency\":null,\"limit\":10,\"max_tokens\":20000,\"temperature\":0.1,\"num_search_results\":10}","call_id":"call_KdLxkrb3M2IIjW2XbfbTep7t","name":"web_search"}]},"duration":15218.782000000007,"ttft":1439.2885000000242,"contextSnapshot":{"promptTokens":88730,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_FXqiIXVLdNreHYGWO71OBM7v|fc_0e2f03dd0e0c3649016a589048bef881999c94687da79a0b53","toolName":"read","startedAt":"2026-07-16T08:03:20.827Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md"},"intent":"Reading remaining OMP docs"},"id":"449a3564","parentId":"caf0108c","timestamp":"2026-07-16T08:03:20.827Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_zPgGWS8zz767hgDk394dsjlw|fc_0e2f03dd0e0c3649016a589048bf0c81998cf7c336b102a4da","toolName":"web_search","startedAt":"2026-07-16T08:03:20.827Z","intent":"Researching provider request event"},"id":"b692ae4b","parentId":"449a3564","timestamp":"2026-07-16T08:03:20.827Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_6X9jm5u2DE8es5PeKvj2NvAO|fc_0e2f03dd0e0c3649016a589048bf148199be1930c5cc0df12b","toolName":"web_search","startedAt":"2026-07-16T08:03:20.827Z","intent":"Researching command completion API"},"id":"c3f2b611","parentId":"b692ae4b","timestamp":"2026-07-16T08:03:20.827Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_KdLxkrb3M2IIjW2XbfbTep7t|fc_0e2f03dd0e0c3649016a589048bf188199a3f5411bf12cc09d","toolName":"web_search","startedAt":"2026-07-16T08:03:20.827Z","intent":"Researching message event shape"},"id":"85814798","parentId":"c3f2b611","timestamp":"2026-07-16T08:03:20.827Z"}
{"type":"message","id":"67c64a52","parentId":"85814798","timestamp":"2026-07-16T08:03:20.829Z","message":{"role":"toolResult","toolCallId":"call_FXqiIXVLdNreHYGWO71OBM7v|fc_0e2f03dd0e0c3649016a589048bef881999c94687da79a0b53","toolName":"read","content":[{"type":"text","text":"  renderCall(args, options, theme) {\n    // optional TUI render\n  },\n  renderResult(result, options, theme, args) {\n    // optional TUI render\n  },\n});\n```\n\n`tool_call`/`tool_result` intercept all tools once the registry is wrapped in `sdk.ts`, including built-ins and extension/custom tools. `ToolDefinition` also supports optional `hidden`, `defaultInactive`, `deferrable`, `approval`, `mcpServerName`, `mcpToolName`, `renderCall`, and `renderResult` fields.\n\n## UI integration points\n\n`ctx.ui` implements the `ExtensionUIContext` interface. Support differs by mode.\n\n### Interactive mode (`extension-ui-controller.ts`)\n\nSupported:\n\n- dialogs: `select`, `confirm`, `input`, `editor`\n- input editing: `setEditorText`, `getEditorText`, `pasteToEditor`, `editor`\n- autocomplete stacking: `addAutocompleteProvider(factory)` wraps the built-in editor provider (factories apply in registration order and re-apply on every slash-command refresh)\n- terminal title and working message (`setTitle`, `setWorkingMessage`)\n- notifications/status/editor text/terminal input/custom overlays\n- theme listing/loading by name (`setTheme` supports string names)\n- tools expanded toggle\n\nCurrent no-op methods in this controller:\n\n- `setFooter`\n- `setHeader`\n\n`setEditorComponent` is wired to the live editor (`ctx.setEditorComponent(factory)`). `setWidget` renders real widget components above or below the editor via `setHookWidget(...)` (`placement: \"aboveEditor\" | \"belowEditor\"`; string-array content capped at 10 lines).\n\n### RPC mode (`rpc-mode.ts`)\n\n`ctx.ui` is backed by RPC `extension_ui_request` events:\n\n- dialog methods (`select`, `confirm`, `input`, `editor`) round-trip to client responses\n- fire-and-forget methods emit requests (`notify`, `setStatus`, `setWidget` for string arrays, `setEditorText`; `setTitle` emits only when `PI_RPC_EMIT_TITLE=1`)\n\nUnsupported/no-op in RPC implementation:\n\n- `onTerminalInput`\n- `custom`\n- `setFooter`, `setHeader`, `setEditorComponent`, `addAutocompleteProvider`\n- `setWorkingMessage`\n- theme switching/loading (`setTheme` returns failure)\n- tool expansion controls are inert\n\n### Print/headless/subagent paths\n\nWhen no UI context is supplied to runner init, `ctx.hasUI` is `false` and methods are no-op/default-returning.\n\n### ACP mode\n\nACP installs an elicitation-bridged UI context (`createAcpExtensionUiContext` in `acp-agent.ts`). `ctx.hasUI` is `true` while only `select`/`confirm`/`input` round-trip (as ACP elicitations; defaults are returned when the client lacks the `elicitation.form` capability). The non-elicitation surface (widgets, editor, theming, terminal input, autocomplete stacking) is stubbed no-op.\n\n## Session and state patterns\n\nFor durable extension state:\n\n1. Persist with `pi.appendEntry(customType, data)`.\n2. Rebuild state from `ctx.sessionManager.getBranch()` on `session_start`, `session_branch`, `session_tree`.\n3. Keep tool result `details` structured when state should be visible/reconstructible from tool result history.\n\nExample reconstruction pattern:\n\n```ts\npi.on(\"session_start\", async (_event, ctx) => {\n  let latest;\n  for (const entry of ctx.sessionManager.getBranch()) {\n    if (entry.type === \"custom\" && entry.customType === \"my-state\") {\n      latest = entry.data;\n    }\n  }\n  // restore from latest\n});\n```\n\n## Rendering extension points\n\n## Custom message renderer\n\n```ts\npi.registerMessageRenderer(\"my-type\", (message, { expanded }, theme) => {\n  // return pi-tui Component\n});\n```\n\nUsed by interactive rendering when custom messages are displayed.\n\n## Assistant thinking renderer\n\n```ts\nimport { Container, Text } from \"@oh-my-pi/pi-tui\";\n\npi.registerAssistantThinkingRenderer((context, theme) => {\n  const container = new Container();\n  container.addChild(new Text(theme.fg(\"dim\", `thinking chars: ${context.text.length}`), 1, 0));\n  return container;\n});\n```\n\nUsed by interactive rendering to add display-only supplemental UI below each visible assistant thinking block. The renderer receives the already-visible thinking text, content/thinking indexes, theme, and a `requestRender()` callback for async renderers. All registered renderers that return a component are appended in registration order. Renderers must not mutate messages; the original thinking block remains the provider/session source of truth.\n\n## Tool call/result renderer\n\nProvide `renderCall` / `renderResult` on `registerTool` definitions for custom tool visualization in TUI.\n\n## Constraints and pitfalls\n\n- Runtime actions are unavailable during extension load.\n- `tool_call` errors block execution (fail-closed).\n- Command name conflicts with built-ins are skipped with diagnostics.\n- Reserved shortcuts are ignored (`ctrl+c`, `ctrl+d`, `ctrl+z`, `ctrl+k`, `ctrl+p`, `ctrl+l`, `ctrl+o`, `ctrl+t`, `ctrl+g`, `ctrl+q`, `alt+m`, `shift+tab`, `shift+ctrl+p`, `alt+enter`, `escape`, `enter`).\n- Treat `ctx.reload()` as terminal for the current command handler frame.\n\n## Extensions vs hooks vs custom-tools\n\nUse the right surface:\n\n- **Extensions** (`src/extensibility/extensions/*`): unified system (events + tools + commands + renderers + provider registration).\n- **Hooks** (`src/extensibility/hooks/*`): separate legacy event API.\n- **Custom-tools** (`src/extensibility/custom-tools/*`): tool-focused modules; when loaded alongside extensions they are adapted and still pass through extension interception wrappers.\n\nIf you need one package that owns policy, tools, command UX, and rendering together, use extensions."}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"  renderCall(args, options, theme) {\n    // optional TUI render\n  },\n  renderResult(result, options, theme, args) {\n    // optional TUI render\n  },\n});\n```\n\n`tool_call`/`tool_result` intercept all tools once the registry is wrapped in `sdk.ts`, including built-ins and extension/custom tools. `ToolDefinition` also supports optional `hidden`, `defaultInactive`, `deferrable`, `approval`, `mcpServerName`, `mcpToolName`, `renderCall`, and `renderResult` fields.\n\n## UI integration points\n\n`ctx.ui` implements the `ExtensionUIContext` interface. Support differs by mode.\n\n### Interactive mode (`extension-ui-controller.ts`)\n\nSupported:\n\n- dialogs: `select`, `confirm`, `input`, `editor`\n- input editing: `setEditorText`, `getEditorText`, `pasteToEditor`, `editor`\n- autocomplete stacking: `addAutocompleteProvider(factory)` wraps the built-in editor provider (factories apply in registration order and re-apply on every slash-command refresh)\n- terminal title and working message (`setTitle`, `setWorkingMessage`)\n- notifications/status/editor text/terminal input/custom overlays\n- theme listing/loading by name (`setTheme` supports string names)\n- tools expanded toggle\n\nCurrent no-op methods in this controller:\n\n- `setFooter`\n- `setHeader`\n\n`setEditorComponent` is wired to the live editor (`ctx.setEditorComponent(factory)`). `setWidget` renders real widget components above or below the editor via `setHookWidget(...)` (`placement: \"aboveEditor\" | \"belowEditor\"`; string-array content capped at 10 lines).\n\n### RPC mode (`rpc-mode.ts`)\n\n`ctx.ui` is backed by RPC `extension_ui_request` events:\n\n- dialog methods (`select`, `confirm`, `input`, `editor`) round-trip to client responses\n- fire-and-forget methods emit requests (`notify`, `setStatus`, `setWidget` for string arrays, `setEditorText`; `setTitle` emits only when `PI_RPC_EMIT_TITLE=1`)\n\nUnsupported/no-op in RPC implementation:\n\n- `onTerminalInput`\n- `custom`\n- `setFooter`, `setHeader`, `setEditorComponent`, `addAutocompleteProvider`\n- `setWorkingMessage`\n- theme switching/loading (`setTheme` returns failure)\n- tool expansion controls are inert\n\n### Print/headless/subagent paths\n\nWhen no UI context is supplied to runner init, `ctx.hasUI` is `false` and methods are no-op/default-returning.\n\n### ACP mode\n\nACP installs an elicitation-bridged UI context (`createAcpExtensionUiContext` in `acp-agent.ts`). `ctx.hasUI` is `true` while only `select`/`confirm`/`input` round-trip (as ACP elicitations; defaults are returned when the client lacks the `elicitation.form` capability). The non-elicitation surface (widgets, editor, theming, terminal input, autocomplete stacking) is stubbed no-op.\n\n## Session and state patterns\n\nFor durable extension state:\n\n1. Persist with `pi.appendEntry(customType, data)`.\n2. Rebuild state from `ctx.sessionManager.getBranch()` on `session_start`, `session_branch`, `session_tree`.\n3. Keep tool result `details` structured when state should be visible/reconstructible from tool result history.\n\nExample reconstruction pattern:\n\n```ts\npi.on(\"session_start\", async (_event, ctx) => {\n  let latest;\n  for (const entry of ctx.sessionManager.getBranch()) {\n    if (entry.type === \"custom\" && entry.customType === \"my-state\") {\n      latest = entry.data;\n    }\n  }\n  // restore from latest\n});\n```\n\n## Rendering extension points\n\n## Custom message renderer\n\n```ts\npi.registerMessageRenderer(\"my-type\", (message, { expanded }, theme) => {\n  // return pi-tui Component\n});\n```\n\nUsed by interactive rendering when custom messages are displayed.\n\n## Assistant thinking renderer\n\n```ts\nimport { Container, Text } from \"@oh-my-pi/pi-tui\";\n\npi.registerAssistantThinkingRenderer((context, theme) => {\n  const container = new Container();\n  container.addChild(new Text(theme.fg(\"dim\", `thinking chars: ${context.text.length}`), 1, 0));\n  return container;\n});\n```\n\nUsed by interactive rendering to add display-only supplemental UI below each visible assistant thinking block. The renderer receives the already-visible thinking text, content/thinking indexes, theme, and a `requestRender()` callback for async renderers. All registered renderers that return a component are appended in registration order. Renderers must not mutate messages; the original thinking block remains the provider/session source of truth.\n\n## Tool call/result renderer\n\nProvide `renderCall` / `renderResult` on `registerTool` definitions for custom tool visualization in TUI.\n\n## Constraints and pitfalls\n\n- Runtime actions are unavailable during extension load.\n- `tool_call` errors block execution (fail-closed).\n- Command name conflicts with built-ins are skipped with diagnostics.\n- Reserved shortcuts are ignored (`ctrl+c`, `ctrl+d`, `ctrl+z`, `ctrl+k`, `ctrl+p`, `ctrl+l`, `ctrl+o`, `ctrl+t`, `ctrl+g`, `ctrl+q`, `alt+m`, `shift+tab`, `shift+ctrl+p`, `alt+enter`, `escape`, `enter`).\n- Treat `ctx.reload()` as terminal for the current command handler frame.\n\n## Extensions vs hooks vs custom-tools\n\nUse the right surface:\n\n- **Extensions** (`src/extensibility/extensions/*`): unified system (events + tools + commands + renderers + provider registration).\n- **Hooks** (`src/extensibility/hooks/*`): separate legacy event API.\n- **Custom-tools** (`src/extensibility/custom-tools/*`): tool-focused modules; when loaded alongside extensions they are adapted and still pass through extension interception wrappers.\n\nIf you need one package that owns policy, tools, command UX, and rendering together, use extensions.","startLine":299,"lineNumbers":[299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md"}}},"isError":false,"timestamp":1784189000829}}
{"type":"message","id":"958584d5","parentId":"67c64a52","timestamp":"2026-07-16T08:03:47.666Z","message":{"role":"toolResult","toolCallId":"call_zPgGWS8zz767hgDk394dsjlw|fc_0e2f03dd0e0c3649016a589048bf0c81998cf7c336b102a4da","toolName":"web_search","content":[{"type":"text","text":"I found the relevant `can1357/oh-my-pi` extension docs and API surface.\n\nKey links:\n\n- Repo: https://github.com/can1357/oh-my-pi\n- Extension docs: https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n- Models/provider docs: https://github.com/can1357/oh-my-pi/blob/main/docs/models.md\n\nRelevant facts from the docs:\n\n- An extension is a TS/JS module with a default factory:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function myExtension(pi: ExtensionAPI) {\n  // register handlers/tools/commands/renderers\n}\n```\n\n- `before_provider_request` is part of the prompt/turn lifecycle and “may replace provider request payload.” The payload is provider-specific.\n- Extension registration methods like `pi.on(...)` are valid during load, but runtime action methods like `pi.sendMessage()` should be used from event handlers/commands/tools, not synchronously during module evaluation.\n- The docs list `sendMessage`, `sendUserMessage`, `appendEntry`, event handlers, tool registration, command registration, etc. as extension capabilities.\n\nExample extension that inspects/rewrites `messages` in the provider payload:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\ntype AnyRecord = Record<string, unknown>;\n\nfunction isRecord(x: unknown): x is AnyRecord {\n  return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nexport default function beforeProviderMessages(pi: ExtensionAPI) {\n  pi.setLabel(\"Provider message rewriter\");\n\n  pi.on(\"before_provider_request\", (event) => {\n    const payload = event.payload;\n\n    if (!isRecord(payload)) return;\n\n    // OpenAI-style payloads usually have `messages`.\n    if (Array.isArray(payload.messages)) {\n      return {\n        ...payload,\n        messages: [\n          {\n            role: \"system\",\n            content: \"Additional provider-level instruction inserted by extension.\",\n          },\n          ...payload.messages,\n        ],\n      };\n    }\n\n    // Anthropic-style payloads may have `system` plus `messages`.\n    if (Array.isArray(payload.messages) && typeof payload.system === \"string\") {\n      return {\n        ...payload,\n        system:\n          payload.system +\n          \"\\n\\nAdditional provider-level instruction inserted by extension.\",\n      };\n    }\n\n    // Returning undefined keeps the original payload unchanged.\n    return;\n  });\n}\n```\n\nNote: because `event.payload` is `unknown` / provider-specific, use defensive shape checks. If you want to mutate normalized agent messages before provider serialization, use the `context` event instead; if you want to mutate the final wire payload, use `before_provider_request`.\n\n## Sources\n3 sources\n[1] https://github.com/can1357/oh-my-pi\n    https://github.com/can1357/oh-my-pi\n[2] https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n    https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n[3] https://github.com/can1357/oh-my-pi/blob/main/docs/models.md\n    https://github.com/can1357/oh-my-pi/blob/main/docs/models.md"}],"details":{"response":{"provider":"codex","answer":"I found the relevant `can1357/oh-my-pi` extension docs and API surface.\n\nKey links:\n\n- Repo: https://github.com/can1357/oh-my-pi\n- Extension docs: https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n- Models/provider docs: https://github.com/can1357/oh-my-pi/blob/main/docs/models.md\n\nRelevant facts from the docs:\n\n- An extension is a TS/JS module with a default factory:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function myExtension(pi: ExtensionAPI) {\n  // register handlers/tools/commands/renderers\n}\n```\n\n- `before_provider_request` is part of the prompt/turn lifecycle and “may replace provider request payload.” The payload is provider-specific.\n- Extension registration methods like `pi.on(...)` are valid during load, but runtime action methods like `pi.sendMessage()` should be used from event handlers/commands/tools, not synchronously during module evaluation.\n- The docs list `sendMessage`, `sendUserMessage`, `appendEntry`, event handlers, tool registration, command registration, etc. as extension capabilities.\n\nExample extension that inspects/rewrites `messages` in the provider payload:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\ntype AnyRecord = Record<string, unknown>;\n\nfunction isRecord(x: unknown): x is AnyRecord {\n  return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nexport default function beforeProviderMessages(pi: ExtensionAPI) {\n  pi.setLabel(\"Provider message rewriter\");\n\n  pi.on(\"before_provider_request\", (event) => {\n    const payload = event.payload;\n\n    if (!isRecord(payload)) return;\n\n    // OpenAI-style payloads usually have `messages`.\n    if (Array.isArray(payload.messages)) {\n      return {\n        ...payload,\n        messages: [\n          {\n            role: \"system\",\n            content: \"Additional provider-level instruction inserted by extension.\",\n          },\n          ...payload.messages,\n        ],\n      };\n    }\n\n    // Anthropic-style payloads may have `system` plus `messages`.\n    if (Array.isArray(payload.messages) && typeof payload.system === \"string\") {\n      return {\n        ...payload,\n        system:\n          payload.system +\n          \"\\n\\nAdditional provider-level instruction inserted by extension.\",\n      };\n    }\n\n    // Returning undefined keeps the original payload unchanged.\n    return;\n  });\n}\n```\n\nNote: because `event.payload` is `unknown` / provider-specific, use defensive shape checks. If you want to mutate normalized agent messages before provider serialization, use the `context` event instead; if you want to mutate the final wire payload, use `before_provider_request`.","sources":[{"title":"https://github.com/can1357/oh-my-pi","url":"https://github.com/can1357/oh-my-pi"},{"title":"https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md","url":"https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md"},{"title":"https://github.com/can1357/oh-my-pi/blob/main/docs/models.md","url":"https://github.com/can1357/oh-my-pi/blob/main/docs/models.md"}],"usage":{"inputTokens":35597,"outputTokens":1103,"totalTokens":38748},"model":"gpt-5.5","requestId":"resp_0ff400b4bdf39509016a589049336c8198a235a5358952b910"}},"isError":false,"timestamp":1784189027666}}
{"type":"message","id":"49c4ca69","parentId":"958584d5","timestamp":"2026-07-16T08:03:48.334Z","message":{"role":"toolResult","toolCallId":"call_KdLxkrb3M2IIjW2XbfbTep7t|fc_0e2f03dd0e0c3649016a589048bf188199a3f5411bf12cc09d","toolName":"web_search","content":[{"type":"text","text":"Found the relevant `can1357/oh-my-pi` references.\n\n## Direct answer\n\nIn `oh-my-pi`, there is **not** a separate `assistant` `ExtensionEvent`. Instead, extensions receive a generic:\n\n```ts\ntype: \"message_end\"\nmessage: AgentMessage\n```\n\nand you narrow it by checking:\n\n```ts\nif (event.type === \"message_end\" && event.message.role === \"assistant\") {\n  // finalized assistant message\n}\n```\n\n## Evidence\n\nThe extension docs say the canonical event unions/payloads are in `src/extensibility/extensions/types.ts` and list the prompt/turn lifecycle events, including `message_start`, `message_update`, and `message_end` .\n\nIn the current source, `MessageEndEvent` is defined as:\n\n```ts\nexport interface MessageEndEvent {\n  type: \"message_end\";\n  message: AgentMessage;\n}\n```\n\nand `MessageEndEvent` is included in the `ExtensionEvent` union .\n\nThe `ExtensionAPI.on(...)` overloads also include:\n\n```ts\non(event: \"message_end\", handler: ExtensionHandler<MessageEndEvent, MessageEndEventResult>): void;\n```\n\nas part of the event subscription surface .\n\n## Practical extension snippet\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n  pi.on(\"message_end\", async (event, ctx) => {\n    if (event.message.role !== \"assistant\") return;\n\n    // event.message is the finalized assistant message\n    pi.logger.info(\"Assistant message ended\", event.message);\n  });\n}\n```\n\nAlso note: `message_update` is the streaming assistant event and carries `assistantMessageEvent: AssistantMessageEvent`; `message_end` carries the finalized `AgentMessage` ."}],"details":{"response":{"provider":"codex","answer":"Found the relevant `can1357/oh-my-pi` references.\n\n## Direct answer\n\nIn `oh-my-pi`, there is **not** a separate `assistant` `ExtensionEvent`. Instead, extensions receive a generic:\n\n```ts\ntype: \"message_end\"\nmessage: AgentMessage\n```\n\nand you narrow it by checking:\n\n```ts\nif (event.type === \"message_end\" && event.message.role === \"assistant\") {\n  // finalized assistant message\n}\n```\n\n## Evidence\n\nThe extension docs say the canonical event unions/payloads are in `src/extensibility/extensions/types.ts` and list the prompt/turn lifecycle events, including `message_start`, `message_update`, and `message_end` .\n\nIn the current source, `MessageEndEvent` is defined as:\n\n```ts\nexport interface MessageEndEvent {\n  type: \"message_end\";\n  message: AgentMessage;\n}\n```\n\nand `MessageEndEvent` is included in the `ExtensionEvent` union .\n\nThe `ExtensionAPI.on(...)` overloads also include:\n\n```ts\non(event: \"message_end\", handler: ExtensionHandler<MessageEndEvent, MessageEndEventResult>): void;\n```\n\nas part of the event subscription surface .\n\n## Practical extension snippet\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\n\nexport default function (pi: ExtensionAPI) {\n  pi.on(\"message_end\", async (event, ctx) => {\n    if (event.message.role !== \"assistant\") return;\n\n    // event.message is the finalized assistant message\n    pi.logger.info(\"Assistant message ended\", event.message);\n  });\n}\n```\n\nAlso note: `message_update` is the streaming assistant event and carries `assistantMessageEvent: AssistantMessageEvent`; `message_end` carries the finalized `AgentMessage` .","sources":[],"usage":{"inputTokens":34439,"outputTokens":1025,"totalTokens":38024},"model":"gpt-5.5","requestId":"resp_02a6dbc2964beb7e016a58904914788199974fb52ebb923a7b"}},"isError":false,"timestamp":1784189028334}}
{"type":"message","id":"6da58d34","parentId":"49c4ca69","timestamp":"2026-07-16T08:04:00.552Z","message":{"role":"toolResult","toolCallId":"call_6X9jm5u2DE8es5PeKvj2NvAO|fc_0e2f03dd0e0c3649016a589048bf148199be1930c5cc0df12b","toolName":"web_search","content":[{"type":"text","text":"I found the relevant `oh-my-pi` extension API pieces:\n\n- `docs/extensions.md` says extensions can register slash commands with `pi.registerCommand(...)` and interact with users through `ctx.ui` methods like `select`, `confirm`, `input`, etc. The quick-start example registers a command and uses `ctx.ui.notify(...)` inside the handler. It also lists `ui.select` as available in RPC/interactive UI contexts. See `docs/extensions.md` lines 262–268, 322–327, and 517–525.  \n  Source: https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n- The current type definition includes `getArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null` on `RegisteredCommand`, and `registerCommand(...)` accepts that option.  \n  Source: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\n- The same type file defines `ctx.ui.select(title, options, dialogOptions?)`, returning a promise.  \n  Source: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\n\nExample extension combining `registerCommand`, `getArgumentCompletions`, and `ui.select`:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\nimport type { AutocompleteItem } from \"@oh-my-pi/pi-tui\";\n\nexport default function envCommand(pi: ExtensionAPI) {\n  const envs = [\"dev\", \"staging\", \"prod\"];\n\n  pi.registerCommand(\"deploy\", {\n    description: \"Deploy to an environment\",\n\n    getArgumentCompletions: (prefix: string): AutocompleteItem[] | null => {\n      const items = envs\n        .filter((env) => env.startsWith(prefix))\n        .map((env) => ({\n          value: env,\n          label: env,\n          description: `Deploy to ${env}`,\n        }));\n\n      return items.length ? items : null;\n    },\n\n    handler: async (args, ctx) => {\n      let env = args.trim();\n\n      if (!env) {\n        if (!ctx.hasUI) {\n          ctx.ui.notify(\"Usage: /deploy <dev|staging|prod>\", \"warning\");\n          return;\n        }\n\n        const selected = await ctx.ui.select(\"Select deployment environment\", [\n          { label: \"dev\", description: \"Development\" },\n          { label: \"staging\", description: \"Staging\" },\n          { label: \"prod\", description: \"Production\" },\n        ]);\n\n        if (!selected) return;\n        env = selected;\n      }\n\n      if (!envs.includes(env)) {\n        ctx.ui.notify(`Unknown environment: ${env}`, \"error\");\n        return;\n      }\n\n      ctx.ui.notify(`Deploying to ${env}...`, \"info\");\n\n      // Example shell call\n      const result = await pi.exec(\"npm\", [\"run\", `deploy:${env}`], {\n        cwd: ctx.cwd,\n      });\n\n      if (result.code === 0) {\n        ctx.ui.notify(`Deploy to ${env} completed`, \"info\");\n      } else {\n        ctx.ui.notify(`Deploy failed: ${result.stderr || result.stdout}`, \"error\");\n      }\n    },\n  });\n}\n```\n\nOne important detail: in the current `can1357/oh-my-pi` type definition, `getArgumentCompletions` is synchronous only:\n\n```ts\ngetArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null;\n```\n\nSo don’t return a `Promise` unless your installed version’s types explicitly allow it.\n\n## Sources\n2 sources\n[1] https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n    https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n[2] https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\n    https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"}],"details":{"response":{"provider":"codex","answer":"I found the relevant `oh-my-pi` extension API pieces:\n\n- `docs/extensions.md` says extensions can register slash commands with `pi.registerCommand(...)` and interact with users through `ctx.ui` methods like `select`, `confirm`, `input`, etc. The quick-start example registers a command and uses `ctx.ui.notify(...)` inside the handler. It also lists `ui.select` as available in RPC/interactive UI contexts. See `docs/extensions.md` lines 262–268, 322–327, and 517–525.  \n  Source: https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md\n- The current type definition includes `getArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null` on `RegisteredCommand`, and `registerCommand(...)` accepts that option.  \n  Source: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\n- The same type file defines `ctx.ui.select(title, options, dialogOptions?)`, returning a promise.  \n  Source: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\n\nExample extension combining `registerCommand`, `getArgumentCompletions`, and `ui.select`:\n\n```ts\nimport type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";\nimport type { AutocompleteItem } from \"@oh-my-pi/pi-tui\";\n\nexport default function envCommand(pi: ExtensionAPI) {\n  const envs = [\"dev\", \"staging\", \"prod\"];\n\n  pi.registerCommand(\"deploy\", {\n    description: \"Deploy to an environment\",\n\n    getArgumentCompletions: (prefix: string): AutocompleteItem[] | null => {\n      const items = envs\n        .filter((env) => env.startsWith(prefix))\n        .map((env) => ({\n          value: env,\n          label: env,\n          description: `Deploy to ${env}`,\n        }));\n\n      return items.length ? items : null;\n    },\n\n    handler: async (args, ctx) => {\n      let env = args.trim();\n\n      if (!env) {\n        if (!ctx.hasUI) {\n          ctx.ui.notify(\"Usage: /deploy <dev|staging|prod>\", \"warning\");\n          return;\n        }\n\n        const selected = await ctx.ui.select(\"Select deployment environment\", [\n          { label: \"dev\", description: \"Development\" },\n          { label: \"staging\", description: \"Staging\" },\n          { label: \"prod\", description: \"Production\" },\n        ]);\n\n        if (!selected) return;\n        env = selected;\n      }\n\n      if (!envs.includes(env)) {\n        ctx.ui.notify(`Unknown environment: ${env}`, \"error\");\n        return;\n      }\n\n      ctx.ui.notify(`Deploying to ${env}...`, \"info\");\n\n      // Example shell call\n      const result = await pi.exec(\"npm\", [\"run\", `deploy:${env}`], {\n        cwd: ctx.cwd,\n      });\n\n      if (result.code === 0) {\n        ctx.ui.notify(`Deploy to ${env} completed`, \"info\");\n      } else {\n        ctx.ui.notify(`Deploy failed: ${result.stderr || result.stdout}`, \"error\");\n      }\n    },\n  });\n}\n```\n\nOne important detail: in the current `can1357/oh-my-pi` type definition, `getArgumentCompletions` is synchronous only:\n\n```ts\ngetArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null;\n```\n\nSo don’t return a `Promise` unless your installed version’s types explicitly allow it.","sources":[{"title":"https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md","url":"https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md"},{"title":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"}],"usage":{"inputTokens":43731,"outputTokens":1449,"totalTokens":47740},"model":"gpt-5.5","requestId":"resp_04023a5123e38ec8016a5890493b80819bbe178cef7b7bf838"}},"isError":false,"timestamp":1784189040552}}
{"type":"message","id":"0494d37a","parentId":"6da58d34","timestamp":"2026-07-16T08:04:05.280Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning targeted source reading**"},{"type":"toolCall","id":"call_lIqoqa99fwlJ4MaystT1j1g4|fc_0e2f03dd0e0c3649016a589074e46c8199b82ffad004d7f3e1","name":"read","arguments":{"i":"Reading OMP extension types","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":"1-300"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":4122,"output":120,"cacheRead":88576,"cacheWrite":0,"totalTokens":92818,"reasoningTokens":62,"cost":{"input":0.020610000000000003,"output":0.0036,"cacheRead":0.044288,"cacheWrite":0,"total":0.068498}},"stopReason":"toolUse","timestamp":1784189040608,"responseId":"resp_0e2f03dd0e0c3649016a589070e5488199935d91d7df989c73","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0e2f03dd0e0c3649016a589072bcf88199be2a30a7b1a8d9cb","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJB0igf5gctG1ePHuBIQoLw1zs9ysFySLc72irnyA3XYBsspWxURZrfyLj0BsyMiqbiO0mEEaPQr3AUXIDt-bqMEnk6XmuJH2f2Aj-PT5kACn3mAXRNAYdOx4_2bTOPvnEwktRTSYiRsScHZ5zrMqlnkYCSPjcwIct-WzF3SyLt3NZ66UwTSUnPGNcyMUzyu927vEDMRzFyZ6kDZozHabEcGqsH7dfyFYrIeAUrTssCKKYEwfB1a8AQh9MGdlIzwgR0iNT_9Co65gKy8TzJ1AwBKZNL9dmDBkZavCdUkJXEq7gyBl8nCZkfVtypgEQKIOMchd-IvWHfen9HVhadLGoVr0t5r9Q02_Ds6XdTBvhi_wgOZBw5T8BDCJAO01-wY83kcjpHmkvkyNh81RDtKsYDU6jdjSsUg7PqdedOpsaD7z6QukGXXN0Gpx53jzRm2999GsRNAqPxULyPmaJVz30kKCN6OWUCzmI4yMLX_tRKvRwvB7zDcRd5e6hJKR625dBsFYgk0vDH1j-FkdCi0id7lpUvim68VEAq7wsGnN0nLifY_9UOhPI_CjbSk3xDYNrCFgksT4La56y9-Zz8ApBrlehjxtvpFLICUvfTYkqoyQ0MgwV30lyR7vWpPjzfjmUuuDsS2cjPE_zkpvzpw9GT-nBjLm6RS92-3tqrpOePXlhGjfJYrrBGc4Y3BLCj4N77fZ_aPQsKGiEmiwHwE7cNrSex6vokVThHgsdM4xU00Ha5C_-jTNjShbzHdmsxSP3oh9LfN7Io71s27RiN-3zixWMGwb_5kWxG_Mf3-8bD50acSzhj1jJd2q1iuuAr5_hdOd1N4E0535SEGv76D9rskirVzy4D6qjq3b2jYAACoI6yx5HwCKXIms1sMaTC0BgWXegkuMdTb_Fy0zy7M8NAQFuZjEnWSFC9H7_ZQ927wPbJOXVh9dZMRhW1AEEJGujFUk5seyCj_erGsrKwedPaTeu0whCz7Rzyv65Ny5-qDjv72hU010Lj5FN9Ps5H_zZWL1S3fLRVQmrRSZ5OJmB7bf7qBW6slL-SdwF_uCYi8oLDGo3kN-pFy2wuBznZVGjHg6loixk4XIym_D_uPu4lQWbbvDrO160ISsc-GlIlqfg8l0H3alo-5y7vnL8I8bAkrwFudBVmXKHwA0JihABSGqnuokDUstKcLuEJQD3Tm5aeqrxxkvylj94l5nvUQXsTRDVlYCBAvundpHaDnaUChqsiTp8KDz8FeerXm0_drpLr_8-5s80iVd-RvMSeF4TlL","summary":[{"type":"summary_text","text":"**Planning targeted source reading**"}]},{"id":"fc_0e2f03dd0e0c3649016a589074e46c8199b82ffad004d7f3e1","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading OMP extension types\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":\"1-300\"}","call_id":"call_lIqoqa99fwlJ4MaystT1j1g4","name":"read"}]},"duration":4671.348999999987,"ttft":2291.0491999999504,"contextSnapshot":{"promptTokens":92698,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_lIqoqa99fwlJ4MaystT1j1g4|fc_0e2f03dd0e0c3649016a589074e46c8199b82ffad004d7f3e1","toolName":"read","startedAt":"2026-07-16T08:04:05.280Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Reading OMP extension types"},"id":"9fb97578","parentId":"0494d37a","timestamp":"2026-07-16T08:04:05.280Z"}
{"type":"message","id":"085e5ac0","parentId":"9fb97578","timestamp":"2026-07-16T08:04:05.416Z","message":{"role":"toolResult","toolCallId":"call_lIqoqa99fwlJ4MaystT1j1g4|fc_0e2f03dd0e0c3649016a589074e46c8199b82ffad004d7f3e1","toolName":"read","content":[{"type":"text","text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\nContent-Type: text/plain\nMethod: text\n\n---\n\n/**\n * Extension system types.\n *\n * Extensions are TypeScript modules that can:\n * - Subscribe to agent lifecycle events\n * - Register LLM-callable tools\n * - Register commands, keyboard shortcuts, and CLI flags\n * - Interact with the user via UI primitives\n */\nimport type {\n\tAgentMessage,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tThinkingLevel,\n\tToolApproval,\n\tToolLoadMode,\n} from \"@oh-my-pi/pi-agent-core\";\nimport type { CompactionResult } from \"@oh-my-pi/pi-agent-core/compaction\";\nimport type {\n\tApi,\n\tAssistantMessageEvent,\n\tAssistantMessageEventStream,\n\tContext,\n\tImageContent,\n\tModel,\n\tModelSpec,\n\tProviderResponseMetadata,\n\tSimpleStreamOptions,\n\tStatic,\n\tTextContent,\n\tTSchema,\n} from \"@oh-my-pi/pi-ai\";\nimport type { OAuthCredentials, OAuthLoginCallbacks } from \"@oh-my-pi/pi-ai/oauth/types\";\nimport type { AutocompleteItem, AutocompleteProvider, Component, EditorTheme, KeyId, TUI } from \"@oh-my-pi/pi-tui\";\nimport type { logger as PiLogger } from \"@oh-my-pi/pi-utils\";\nimport type { Type as arktype } from \"arktype\";\nimport type * as zod from \"zod/v4\";\nimport type { KeybindingsManager } from \"../../config/keybindings\";\nimport type { ModelRegistry } from \"../../config/model-registry\";\nimport type { EditToolDetails } from \"../../edit\";\nimport type { PythonResult } from \"../../eval/py/executor\";\nimport type { BashResult } from \"../../exec/bash-executor\";\nimport type { ExecOptions, ExecResult } from \"../../exec/exec\";\nimport type * as PiCodingAgent from \"../../index\";\nimport type { LocalProtocolOptions } from \"../../internal-urls/local-protocol\";\nimport type { MemoryRuntimeContext } from \"../../memory-backend\";\nimport type { CustomEditor } from \"../../modes/components/custom-editor\";\nimport type { Theme } from \"../../modes/theme/theme\";\nimport type { CompactMode } from \"../../session/compact-modes\";\nimport type { CustomMessage, CustomMessagePayload } from \"../../session/messages\";\nimport type { ReadonlySessionManager, SessionManager } from \"../../session/session-manager\";\nimport type {\n\tBashToolDetails,\n\tBashToolInput,\n\tGlobToolDetails,\n\tGlobToolInput,\n\tGrepToolDetails,\n\tGrepToolInput,\n\tReadToolDetails,\n\tReadToolInput,\n\tWriteToolInput,\n} from \"../../tools\";\nimport type { ApprovalMode } from \"../../tools/approval\";\nimport type { EventBus } from \"../../utils/event-bus\";\nimport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAutoCompactionEndEvent,\n\tAutoCompactionStartEvent,\n\tAutoRetryEndEvent,\n\tAutoRetryStartEvent,\n\tContextEvent,\n\tGoalUpdatedEvent,\n\tSessionBeforeBranchEvent,\n\tSessionBeforeBranchResult,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeCompactResult,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeSwitchResult,\n\tSessionBeforeTreeEvent,\n\tSessionBeforeTreeResult,\n\tSessionBranchEvent,\n\tSessionCompactEvent,\n\tSessionCompactingEvent,\n\tSessionCompactingResult,\n\tSessionEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionStopEvent,\n\tSessionStopEventResult,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tTodoReminderEvent,\n\tToolCallEventResult,\n\tToolResultEventResult,\n\tTtsrTriggeredEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n} from \"../shared-events\";\nimport type { SlashCommandInfo } from \"../slash-commands\";\nimport type * as TypeBox from \"../typebox\";\n\nexport type { AppKeybinding, KeybindingsManager } from \"../../config/keybindings\";\nexport type { ExecOptions, ExecResult } from \"../../exec/exec\";\nexport type { AgentToolResult, AgentToolUpdateCallback };\n\n// ============================================================================\n// UI Context\n// ============================================================================\n\nexport interface ExtensionUISelectOption {\n\tlabel: string;\n\tdescription?: string;\n}\n\nexport type ExtensionUISelectItem = string | ExtensionUISelectOption;\n\nexport interface ExtensionAskDialogOption {\n\tlabel: string;\n\tdescription?: string;\n\tpreview?: string;\n}\n\nexport interface ExtensionAskDialogQuestion {\n\tid: string;\n\tquestion: string;\n\theader?: string;\n\toptions: ExtensionAskDialogOption[];\n\tmulti?: boolean;\n\trecommended?: number;\n}\n\nexport interface ExtensionAskDialogResultItem {\n\tid: string;\n\tquestion: string;\n\toptions: string[];\n\tmulti: boolean;\n\tselectedOptions: string[];\n\tcustomInput?: string;\n\tnote?: string;\n\ttimedOut?: boolean;\n}\n\nexport interface ExtensionAskDialogSubmitResult {\n\tkind: \"submit\";\n\tresults: ExtensionAskDialogResultItem[];\n}\n\n/** Chat-redirect result: the user chose \"Chat about this\" instead of\n *  answering. Distinct from `undefined` (cancel) so AskTool can hand off to\n *  the chat loop rather than aborting. */\nexport interface ExtensionAskDialogChatResult {\n\tkind: \"chat\";\n}\n\nexport type ExtensionAskDialogResult = ExtensionAskDialogSubmitResult | ExtensionAskDialogChatResult;\n\nexport function getExtensionUISelectOptionLabel(option: ExtensionUISelectItem): string {\n\treturn typeof option === \"string\" ? option : option.label;\n}\n\n/**\n * UI dialog options for extensions.\n */\nexport interface ExtensionUIDialogOptions {\n\tsignal?: AbortSignal;\n\ttimeout?: number;\n\t/** Invoked when the UI times out while waiting for a selection/input */\n\tonTimeout?: () => void;\n\t/** Invoked when the UI-managed timeout countdown starts */\n\tonTimeoutStart?: () => void;\n\t/** Invoked when user input resets a UI-managed timeout countdown */\n\tonTimeoutReset?: () => void;\n\t/** Initial cursor position for select dialogs (0-indexed) */\n\tinitialIndex?: number;\n\t/** Render an outlined list for select dialogs */\n\toutline?: boolean;\n\t/** Invoked when user presses left arrow in select dialogs */\n\tonLeft?: () => void;\n\t/** Invoked when user presses right arrow in select dialogs */\n\tonRight?: () => void;\n\t/** Invoked when user presses the external editor shortcut in select dialogs */\n\tonExternalEditor?: () => void;\n\t/** Optional footer hint text rendered by interactive selector */\n\thelpText?: string;\n\t/** Render a leading radio/checkbox marker before each markable option in\n\t *  select dialogs (matches the ask transcript). \"radio\" fills the cursor row\n\t *  for single-choice; \"checkbox\" reflects `checkedIndices` per row for\n\t *  multi-select. Options beyond `markableCount` keep the plain cursor. */\n\tselectionMarker?: \"radio\" | \"checkbox\";\n\t/** For `selectionMarker: \"checkbox\"`: option indices currently checked. */\n\tcheckedIndices?: readonly number[];\n\t/** Number of leading options that receive a selection marker; the remaining\n\t *  trailing options (e.g. \"Other\"/\"Done\" actions) keep the plain cursor.\n\t *  Defaults to all options when `selectionMarker` is set. */\n\tmarkableCount?: number;\n}\n\n/** Raw terminal input listener for extensions. */\nexport type TerminalInputHandler = (data: string) => { consume?: boolean; data?: string } | undefined;\n\nexport type WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\nexport interface ExtensionWidgetOptions {\n\tplacement?: WidgetPlacement;\n}\n\nexport type ExtensionUiComponent = Component & { dispose?(): void };\nexport type ExtensionUiComponentFactory = (tui: TUI, theme: Theme) => ExtensionUiComponent;\nexport type ExtensionWidgetContent = string[] | ExtensionUiComponentFactory | undefined;\n\n/** Wrap the current autocomplete provider with additional behavior (pi-compatible). */\nexport type AutocompleteProviderFactory = (current: AutocompleteProvider) => AutocompleteProvider;\n\n/**\n * UI context for extensions to request interactive UI.\n * Each mode (interactive, RPC, print) provides its own implementation.\n */\n// fallow-ignore-next-line code-duplication\n// Parallel to HookUIContext: extensions expose a strictly larger UI surface\n// (custom editor component, header/footer, widgets, theming, terminal input)\n// and may be invoked from event handlers that have already taken the agent\n// loop's lock — hooks intentionally cannot.\nexport interface ExtensionUIContext {\n\t/** True when selector timeouts start only after the dialog is presented. */\n\ttimeoutStartsOnPresentation?: boolean;\n\t/** Show a selector and return the selected label, even when an option also includes a description. */\n\tselect(\n\t\ttitle: string,\n\t\toptions: ExtensionUISelectItem[],\n\t\tdialogOptions?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined>;\n\n\t/** Show a confirmation dialog. */\n\tconfirm(title: string, message: string, dialogOptions?: ExtensionUIDialogOptions): Promise<boolean>;\n\n\t/** Show a text input dialog. */\n\tinput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Show the rich ask dialog when the interactive TUI surface is available. */\n\taskDialog?(\n\t\tquestions: ExtensionAskDialogQuestion[],\n\t\tdialogOptions?: ExtensionUIDialogOptions,\n\t): Promise<ExtensionAskDialogResult | undefined>;\n\n\t/** Show a notification to the user. */\n\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\n\t/** Listen to raw terminal input (interactive mode only). Returns an unsubscribe function. */\n\tonTerminalInput(handler: TerminalInputHandler): () => void;\n\n\t/** Set status text in the footer/status bar. Pass undefined to clear. */\n\tsetStatus(key: string, text: string | undefined): void;\n\n\t/** Set the working/loading message shown during streaming. Call with no argument to restore default. */\n\tsetWorkingMessage(message?: string): void;\n\n\t/** Set a widget to display above or below the editor. Accepts string array or component factory. */\n\tsetWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void;\n\n\t/** Set a custom footer component, or undefined to restore the built-in footer. */\n\tsetFooter(factory: ExtensionUiComponentFactory | undefined): void;\n\n\t/** Set a custom header component, or undefined to restore the built-in header. */\n\tsetHeader(factory: ExtensionUiComponentFactory | undefined): void;\n\n\t/** Set the terminal window/tab title. */\n\tsetTitle(title: string): void;\n\n\t/** Show a custom component with keyboard focus. */\n\tcustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => ExtensionUiComponent | Promise<ExtensionUiComponent>,\n\t\toptions?: { overlay?: boolean },\n\t): Promise<T>;\n\n\t/** Set the text in the core input editor. */\n\tsetEditorText(text: string): void;\n\n\t/**\n\t * Paste text into the core input editor.\n\t *\n\t * Interactive mode should route through the editor's paste handling (e.g. large paste markers).\n\t * Non-interactive modes may fall back to replacing the editor text.\n\t */\n\tpasteToEditor(text: string): void;\n\n\t/** Get the current text from the core input editor. */\n\tgetEditorText(): string;\n\n\t/** Show a multi-line editor for text editing. */\n\teditor(\n\t\ttitle: string,\n…\n\t): Promise<string | undefined>;\n…\n}\n\n[1178 more lines in URL output. Use :304 to continue]"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\nContent-Type: text/plain\nMethod: text\n\n---\n\n/**\n * Extension system types.\n *\n * Extensions are TypeScript modules that can:\n * - Subscribe to agent lifecycle events\n * - Register LLM-callable tools\n * - Register commands, keyboard shortcuts, and CLI flags\n * - Interact with the user via UI primitives\n */\nimport type {\n\tAgentMessage,\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tThinkingLevel,\n\tToolApproval,\n\tToolLoadMode,\n} from \"@oh-my-pi/pi-agent-core\";\nimport type { CompactionResult } from \"@oh-my-pi/pi-agent-core/compaction\";\nimport type {\n\tApi,\n\tAssistantMessageEvent,\n\tAssistantMessageEventStream,\n\tContext,\n\tImageContent,\n\tModel,\n\tModelSpec,\n\tProviderResponseMetadata,\n\tSimpleStreamOptions,\n\tStatic,\n\tTextContent,\n\tTSchema,\n} from \"@oh-my-pi/pi-ai\";\nimport type { OAuthCredentials, OAuthLoginCallbacks } from \"@oh-my-pi/pi-ai/oauth/types\";\nimport type { AutocompleteItem, AutocompleteProvider, Component, EditorTheme, KeyId, TUI } from \"@oh-my-pi/pi-tui\";\nimport type { logger as PiLogger } from \"@oh-my-pi/pi-utils\";\nimport type { Type as arktype } from \"arktype\";\nimport type * as zod from \"zod/v4\";\nimport type { KeybindingsManager } from \"../../config/keybindings\";\nimport type { ModelRegistry } from \"../../config/model-registry\";\nimport type { EditToolDetails } from \"../../edit\";\nimport type { PythonResult } from \"../../eval/py/executor\";\nimport type { BashResult } from \"../../exec/bash-executor\";\nimport type { ExecOptions, ExecResult } from \"../../exec/exec\";\nimport type * as PiCodingAgent from \"../../index\";\nimport type { LocalProtocolOptions } from \"../../internal-urls/local-protocol\";\nimport type { MemoryRuntimeContext } from \"../../memory-backend\";\nimport type { CustomEditor } from \"../../modes/components/custom-editor\";\nimport type { Theme } from \"../../modes/theme/theme\";\nimport type { CompactMode } from \"../../session/compact-modes\";\nimport type { CustomMessage, CustomMessagePayload } from \"../../session/messages\";\nimport type { ReadonlySessionManager, SessionManager } from \"../../session/session-manager\";\nimport type {\n\tBashToolDetails,\n\tBashToolInput,\n\tGlobToolDetails,\n\tGlobToolInput,\n\tGrepToolDetails,\n\tGrepToolInput,\n\tReadToolDetails,\n\tReadToolInput,\n\tWriteToolInput,\n} from \"../../tools\";\nimport type { ApprovalMode } from \"../../tools/approval\";\nimport type { EventBus } from \"../../utils/event-bus\";\nimport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tAutoCompactionEndEvent,\n\tAutoCompactionStartEvent,\n\tAutoRetryEndEvent,\n\tAutoRetryStartEvent,\n\tContextEvent,\n\tGoalUpdatedEvent,\n\tSessionBeforeBranchEvent,\n\tSessionBeforeBranchResult,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeCompactResult,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeSwitchResult,\n\tSessionBeforeTreeEvent,\n\tSessionBeforeTreeResult,\n\tSessionBranchEvent,\n\tSessionCompactEvent,\n\tSessionCompactingEvent,\n\tSessionCompactingResult,\n\tSessionEvent,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tSessionStopEvent,\n\tSessionStopEventResult,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tTodoReminderEvent,\n\tToolCallEventResult,\n\tToolResultEventResult,\n\tTtsrTriggeredEvent,\n\tTurnEndEvent,\n\tTurnStartEvent,\n} from \"../shared-events\";\nimport type { SlashCommandInfo } from \"../slash-commands\";\nimport type * as TypeBox from \"../typebox\";\n\nexport type { AppKeybinding, KeybindingsManager } from \"../../config/keybindings\";\nexport type { ExecOptions, ExecResult } from \"../../exec/exec\";\nexport type { AgentToolResult, AgentToolUpdateCallback };\n\n// ============================================================================\n// UI Context\n// ============================================================================\n\nexport interface ExtensionUISelectOption {\n\tlabel: string;\n\tdescription?: string;\n}\n\nexport type ExtensionUISelectItem = string | ExtensionUISelectOption;\n\nexport interface ExtensionAskDialogOption {\n\tlabel: string;\n\tdescription?: string;\n\tpreview?: string;\n}\n\nexport interface ExtensionAskDialogQuestion {\n\tid: string;\n\tquestion: string;\n\theader?: string;\n\toptions: ExtensionAskDialogOption[];\n\tmulti?: boolean;\n\trecommended?: number;\n}\n\nexport interface ExtensionAskDialogResultItem {\n\tid: string;\n\tquestion: string;\n\toptions: string[];\n\tmulti: boolean;\n\tselectedOptions: string[];\n\tcustomInput?: string;\n\tnote?: string;\n\ttimedOut?: boolean;\n}\n\nexport interface ExtensionAskDialogSubmitResult {\n\tkind: \"submit\";\n\tresults: ExtensionAskDialogResultItem[];\n}\n\n/** Chat-redirect result: the user chose \"Chat about this\" instead of\n *  answering. Distinct from `undefined` (cancel) so AskTool can hand off to\n *  the chat loop rather than aborting. */\nexport interface ExtensionAskDialogChatResult {\n\tkind: \"chat\";\n}\n\nexport type ExtensionAskDialogResult = ExtensionAskDialogSubmitResult | ExtensionAskDialogChatResult;\n\nexport function getExtensionUISelectOptionLabel(option: ExtensionUISelectItem): string {\n\treturn typeof option === \"string\" ? option : option.label;\n}\n\n/**\n * UI dialog options for extensions.\n */\nexport interface ExtensionUIDialogOptions {\n\tsignal?: AbortSignal;\n\ttimeout?: number;\n\t/** Invoked when the UI times out while waiting for a selection/input */\n\tonTimeout?: () => void;\n\t/** Invoked when the UI-managed timeout countdown starts */\n\tonTimeoutStart?: () => void;\n\t/** Invoked when user input resets a UI-managed timeout countdown */\n\tonTimeoutReset?: () => void;\n\t/** Initial cursor position for select dialogs (0-indexed) */\n\tinitialIndex?: number;\n\t/** Render an outlined list for select dialogs */\n\toutline?: boolean;\n\t/** Invoked when user presses left arrow in select dialogs */\n\tonLeft?: () => void;\n\t/** Invoked when user presses right arrow in select dialogs */\n\tonRight?: () => void;\n\t/** Invoked when user presses the external editor shortcut in select dialogs */\n\tonExternalEditor?: () => void;\n\t/** Optional footer hint text rendered by interactive selector */\n\thelpText?: string;\n\t/** Render a leading radio/checkbox marker before each markable option in\n\t *  select dialogs (matches the ask transcript). \"radio\" fills the cursor row\n\t *  for single-choice; \"checkbox\" reflects `checkedIndices` per row for\n\t *  multi-select. Options beyond `markableCount` keep the plain cursor. */\n\tselectionMarker?: \"radio\" | \"checkbox\";\n\t/** For `selectionMarker: \"checkbox\"`: option indices currently checked. */\n\tcheckedIndices?: readonly number[];\n\t/** Number of leading options that receive a selection marker; the remaining\n\t *  trailing options (e.g. \"Other\"/\"Done\" actions) keep the plain cursor.\n\t *  Defaults to all options when `selectionMarker` is set. */\n\tmarkableCount?: number;\n}\n\n/** Raw terminal input listener for extensions. */\nexport type TerminalInputHandler = (data: string) => { consume?: boolean; data?: string } | undefined;\n\nexport type WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\nexport interface ExtensionWidgetOptions {\n\tplacement?: WidgetPlacement;\n}\n\nexport type ExtensionUiComponent = Component & { dispose?(): void };\nexport type ExtensionUiComponentFactory = (tui: TUI, theme: Theme) => ExtensionUiComponent;\nexport type ExtensionWidgetContent = string[] | ExtensionUiComponentFactory | undefined;\n\n/** Wrap the current autocomplete provider with additional behavior (pi-compatible). */\nexport type AutocompleteProviderFactory = (current: AutocompleteProvider) => AutocompleteProvider;\n\n/**\n * UI context for extensions to request interactive UI.\n * Each mode (interactive, RPC, print) provides its own implementation.\n */\n// fallow-ignore-next-line code-duplication\n// Parallel to HookUIContext: extensions expose a strictly larger UI surface\n// (custom editor component, header/footer, widgets, theming, terminal input)\n// and may be invoked from event handlers that have already taken the agent\n// loop's lock — hooks intentionally cannot.\nexport interface ExtensionUIContext {\n\t/** True when selector timeouts start only after the dialog is presented. */\n\ttimeoutStartsOnPresentation?: boolean;\n\t/** Show a selector and return the selected label, even when an option also includes a description. */\n\tselect(\n\t\ttitle: string,\n\t\toptions: ExtensionUISelectItem[],\n\t\tdialogOptions?: ExtensionUIDialogOptions,\n\t): Promise<string | undefined>;\n\n\t/** Show a confirmation dialog. */\n\tconfirm(title: string, message: string, dialogOptions?: ExtensionUIDialogOptions): Promise<boolean>;\n\n\t/** Show a text input dialog. */\n\tinput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Show the rich ask dialog when the interactive TUI surface is available. */\n\taskDialog?(\n\t\tquestions: ExtensionAskDialogQuestion[],\n\t\tdialogOptions?: ExtensionUIDialogOptions,\n\t): Promise<ExtensionAskDialogResult | undefined>;\n\n\t/** Show a notification to the user. */\n\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\n\t/** Listen to raw terminal input (interactive mode only). Returns an unsubscribe function. */\n\tonTerminalInput(handler: TerminalInputHandler): () => void;\n\n\t/** Set status text in the footer/status bar. Pass undefined to clear. */\n\tsetStatus(key: string, text: string | undefined): void;\n\n\t/** Set the working/loading message shown during streaming. Call with no argument to restore default. */\n\tsetWorkingMessage(message?: string): void;\n\n\t/** Set a widget to display above or below the editor. Accepts string array or component factory. */\n\tsetWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void;\n\n\t/** Set a custom footer component, or undefined to restore the built-in footer. */\n\tsetFooter(factory: ExtensionUiComponentFactory | undefined): void;\n\n\t/** Set a custom header component, or undefined to restore the built-in header. */\n\tsetHeader(factory: ExtensionUiComponentFactory | undefined): void;\n\n\t/** Set the terminal window/tab title. */\n\tsetTitle(title: string): void;\n\n\t/** Show a custom component with keyboard focus. */\n\tcustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => ExtensionUiComponent | Promise<ExtensionUiComponent>,\n\t\toptions?: { overlay?: boolean },\n\t): Promise<T>;\n\n\t/** Set the text in the core input editor. */\n\tsetEditorText(text: string): void;\n\n\t/**\n\t * Paste text into the core input editor.\n\t *\n\t * Interactive mode should route through the editor's paste handling (e.g. large paste markers).\n\t * Non-interactive modes may fall back to replacing the editor text.\n\t */\n\tpasteToEditor(text: string): void;\n\n\t/** Get the current text from the core input editor. */\n\tgetEditorText(): string;\n\n\t/** Show a multi-line editor for text editing. */\n\teditor(\n\t\ttitle: string,\n…\n\t): Promise<string | undefined>;\n…\n}","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,null,307,null,345]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"}}},"isError":false,"timestamp":1784189045415}}
{"type":"message","id":"3c22adeb","parentId":"085e5ac0","timestamp":"2026-07-16T08:09:18.776Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning interface line number retrieval**"},{"type":"toolCall","id":"call_7uenOJvVqihGdzDwHFE8VEHL|fc_0eb024d9cf1a4840016a5891aeaf148199a8ff8d832c428fda","name":"grep","arguments":{"i":"Finding command type definitions","pattern":"RegisteredCommand|registerCommand|getArgumentCompletions","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_py7Ged380mMFJwH8TrI0sFiy|fc_0eb024d9cf1a4840016a5891aeaf248199ba8e922520fa366e","name":"grep","arguments":{"i":"Finding provider request types","pattern":"BeforeProviderRequest|before_provider_request|payload","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_CwxTTfWSf5lLq3EvFTscsoN3|fc_0eb024d9cf1a4840016a5891aeaf2c81998ab42de79b5c2c58","name":"grep","arguments":{"i":"Finding message event types","pattern":"MessageEndEvent|message_end|AssistantMessage","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_B5fdYqJqPvOEH5Du57BfKgRS|fc_0eb024d9cf1a4840016a5891aeaf308199a2e02e583fba3eee","name":"grep","arguments":{"i":"Finding send message signatures","pattern":"sendMessage|sendUserMessage|deliverAs|triggerTurn","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":95202,"output":390,"cacheRead":0,"cacheWrite":0,"totalTokens":95592,"reasoningTokens":64,"cost":{"input":0.47601000000000004,"output":0.0117,"cacheRead":0,"cacheWrite":0,"total":0.48771000000000003}},"stopReason":"toolUse","timestamp":1784189045472,"responseId":"resp_0eb024d9cf1a4840016a5891a605e081998cd0ba7921e37f4c","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0eb024d9cf1a4840016a5891a7a3288199b03d67adb10ff077","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJGue5Dv0YYGpOAENWziK5Mjolx-Z6NqLkZKlBBjH40Dj79LOaKIeuxBVApTTk1GbB6FifoGo38i83RgOEJHBPs3SMUZDSde2kiUhIPnnj_DfOET3SHANw-ZT0S3zbdvm3nVmAsXilRX1xinGENj5hzBjPmlOF_ybl2CQWgwfw9h81UzJs1gqEgRYNZA9J5Q3324qXMu7d7JeRNJpejJFqcdhM-xX1oU3sKneAsaO_E1zKpqBFbqmCQ2TKe7YjCmH9BP71pJUO68b7PKo9bI7R1GZyCOCSWUkJUn_X6OU4jJZh31iD2uGUB2MCfy4WWvClpsJlJoB3_tS3zoIWVl9WqKwe6zQvYsedYbnPrN7fY5cm1Rqt4Ylmq0xeb4wxIn1TOWA5A5_DkBV9lCyNbiX5NeJIsHmxyVB4mqHSk9tlq_rZxpBFEjenT9767eGUvmekfnWvGnBzjSy7J7viRFd1yA78NO7stWZUKIinta4Z67xCijsdqdWQcPaF_5I1A4Tf51zOwutx3n3Z2DPeNA6HOrd2jaTl3MECERX-Oo1F_meLhkKkZ-KaF77MAEV72-ECgTH6d6DIGIWCEFr661tiVOK9a6JY2yP1xJdemIxsqKVz3vj1IU5T0xlOTXv90VlcdAYzl6gmRWSPxvbzY7Hd3swirb2Kg7Og4DdCf1B6fPa2NSbO7Sx_mxlz2LGvG4zuiK4x6ttwqbJpwZAdTy-wtcTfw99GOdSXqFx0VG2_Ast6QCPAmVEh3uTuBNNDyApISX4A7Q7ALfUnzEXwlAOYMSbSG-fUwygkjEjpEZ-pEwscJScmtMi6WDGIvjEf7XbFfpGJymxuVRZUl9zodfWpOjP72ly8BuxZLfKWGzRdFtKAm_rUnEtWp56sSEXaX6tq3qocYFr_SgJLspj8YeVRLYuscmSX8BRuBK9smu5YWU7Mf2ibUPGNuePRmG1jbdYBlbU8GccyH_mWOLEBLDW3ow1z2T65a5gQsH08JGOMBUnzD0jMO4xe31MM8eDhmiMjPoJ391NzXojh3rXLl_KP9kmmr5NVZo2lMs9-Y18UJtfTC0XHdXtRPTXTjHhh4lV4aHWe3mVcQAJj5o5AZKOgmQDdz91pXryb2eKeFUVNp__eP83vARczMAhqbJ5T1V0rBCUQ8lYMJBn7C_sWod1uyL2sJeCM0OkP6tMpjOxsQdWD6S-qH4mEICsOanfGwfS4eu0frr8bCo6D0u-dSeyT7nLtNLBVSxoDS1ERaBBPT0W8yYri2VFYr2pP-7-iXZMyUcVcX2if9bsRSBYGeLuvO6FMzIMqIV9w9Absj3Dspntcw=","summary":[{"type":"summary_text","text":"**Planning interface line number retrieval**"}]},{"id":"fc_0eb024d9cf1a4840016a5891aeaf148199a8ff8d832c428fda","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding command type definitions\",\"pattern\":\"RegisteredCommand|registerCommand|getArgumentCompletions\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_7uenOJvVqihGdzDwHFE8VEHL","name":"grep"},{"id":"fc_0eb024d9cf1a4840016a5891aeaf248199ba8e922520fa366e","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding provider request types\",\"pattern\":\"BeforeProviderRequest|before_provider_request|payload\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_py7Ged380mMFJwH8TrI0sFiy","name":"grep"},{"id":"fc_0eb024d9cf1a4840016a5891aeaf2c81998ab42de79b5c2c58","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding message event types\",\"pattern\":\"MessageEndEvent|message_end|AssistantMessage\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_CwxTTfWSf5lLq3EvFTscsoN3","name":"grep"},{"id":"fc_0eb024d9cf1a4840016a5891aeaf308199a2e02e583fba3eee","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding send message signatures\",\"pattern\":\"sendMessage|sendUserMessage|deliverAs|triggerTurn\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_B5fdYqJqPvOEH5Du57BfKgRS","name":"grep"}]},"duration":313303.5679,"ttft":306155.09589999996,"contextSnapshot":{"promptTokens":95202,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_7uenOJvVqihGdzDwHFE8VEHL|fc_0eb024d9cf1a4840016a5891aeaf148199a8ff8d832c428fda","toolName":"grep","startedAt":"2026-07-16T08:09:18.777Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Finding command type definitions"},"id":"c55bf9ab","parentId":"3c22adeb","timestamp":"2026-07-16T08:09:18.777Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_py7Ged380mMFJwH8TrI0sFiy|fc_0eb024d9cf1a4840016a5891aeaf248199ba8e922520fa366e","toolName":"grep","startedAt":"2026-07-16T08:09:18.777Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Finding provider request types"},"id":"3b03a4dd","parentId":"c55bf9ab","timestamp":"2026-07-16T08:09:18.777Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_CwxTTfWSf5lLq3EvFTscsoN3|fc_0eb024d9cf1a4840016a5891aeaf2c81998ab42de79b5c2c58","toolName":"grep","startedAt":"2026-07-16T08:09:18.777Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Finding message event types"},"id":"e85bc5cf","parentId":"3b03a4dd","timestamp":"2026-07-16T08:09:18.777Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_B5fdYqJqPvOEH5Du57BfKgRS|fc_0eb024d9cf1a4840016a5891aeaf308199a2e02e583fba3eee","toolName":"grep","startedAt":"2026-07-16T08:09:18.777Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Finding send message signatures"},"id":"f1562010","parentId":"e85bc5cf","timestamp":"2026-07-16T08:09:18.777Z"}
{"type":"message","id":"bcb2049a","parentId":"f1562010","timestamp":"2026-07-16T08:09:18.806Z","message":{"role":"toolResult","toolCallId":"call_CwxTTfWSf5lLq3EvFTscsoN3|fc_0eb024d9cf1a4840016a5891aeaf2c81998ab42de79b5c2c58","toolName":"grep","content":[{"type":"text","text":" 20|\tApi,\n*21|\tAssistantMessageEvent,\n*22|\tAssistantMessageEventStream,\n 23|\tContext,\n 24|\tImageContent,\n 25|\tModel,\n...\n 637|\tmessage: AgentMessage;\n*638|\tassistantMessageEvent: AssistantMessageEvent;\n 639|}\n 640|\n 641|/** Fired when a message ends */\n*642|export interface MessageEndEvent {\n*643|\ttype: \"message_end\";\n 644|\tmessage: AgentMessage;\n 645|}\n 646|\n...\n 907|\t| MessageUpdateEvent\n*908|\t| MessageEndEvent\n 909|\t| ToolExecutionStartEvent\n 910|\t| ToolExecutionUpdateEvent\n 911|\t| ToolExecutionEndEvent\n...\n 1086|\ton(event: \"message_update\", handler: ExtensionHandler<MessageUpdateEvent>): void;\n*1087|\ton(event: \"message_end\", handler: ExtensionHandler<MessageEndEvent>): void;\n 1088|\ton(event: \"tool_execution_start\", handler: ExtensionHandler<ToolExecutionStartEvent>): void;\n 1089|\ton(event: \"tool_execution_update\", handler: ExtensionHandler<ToolExecutionUpdateEvent>): void;\n 1090|\ton(event: \"tool_execution_end\", handler: ExtensionHandler<ToolExecutionEndEvent>): void;\n...\n 1273|\t/** Custom streaming function for non-built-in APIs. */\n*1274|\tstreamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;\n 1275|\t/** Custom headers to include in requests. */\n 1276|\theaders?: Record<string, string>;\n 1277|\t/** If true, adds Authorization: Bearer header with the resolved API key. */"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":8,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","count":8}],"truncated":false,"displayContent":"   20│\tApi,\n  *21│\tAssistantMessageEvent,\n  *22│\tAssistantMessageEventStream,\n   23│\tContext,\n   24│\tImageContent,\n   25│\tModel,\n     │...\n  637│\tmessage: AgentMessage;\n *638│\tassistantMessageEvent: AssistantMessageEvent;\n  639│}\n  640│\n  641│/** Fired when a message ends */\n *642│export interface MessageEndEvent {\n *643│\ttype: \"message_end\";\n  644│\tmessage: AgentMessage;\n  645│}\n  646│\n     │...\n  907│\t| MessageUpdateEvent\n *908│\t| MessageEndEvent\n  909│\t| ToolExecutionStartEvent\n  910│\t| ToolExecutionUpdateEvent\n  911│\t| ToolExecutionEndEvent\n     │...\n 1086│\ton(event: \"message_update\", handler: ExtensionHandler<MessageUpdateEvent>): void;\n*1087│\ton(event: \"message_end\", handler: ExtensionHandler<MessageEndEvent>): void;\n 1088│\ton(event: \"tool_execution_start\", handler: ExtensionHandler<ToolExecutionStartEvent>): void;\n 1089│\ton(event: \"tool_execution_update\", handler: ExtensionHandler<ToolExecutionUpdateEvent>): void;\n 1090│\ton(event: \"tool_execution_end\", handler: ExtensionHandler<ToolExecutionEndEvent>): void;\n     │...\n 1273│\t/** Custom streaming function for non-built-in APIs. */\n*1274│\tstreamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;\n 1275│\t/** Custom headers to include in requests. */\n 1276│\theaders?: Record<string, string>;\n 1277│\t/** If true, adds Authorization: Bearer header with the resolved API key. */"},"isError":false,"timestamp":1784189358806}}
{"type":"message","id":"d7fef6d4","parentId":"bcb2049a","timestamp":"2026-07-16T08:09:18.807Z","message":{"role":"toolResult","toolCallId":"call_7uenOJvVqihGdzDwHFE8VEHL|fc_0eb024d9cf1a4840016a5891aeaf148199a8ff8d832c428fda","toolName":"grep","content":[{"type":"text","text":" 1008|// fallow-ignore-next-line code-duplication\n*1009|// Parallel to HookAPI's RegisteredCommand: extensions add\n*1010|// `getArgumentCompletions` and bind handlers to ExtensionCommandContext.\n*1011|export interface RegisteredCommand {\n 1012|\tname: string;\n 1013|\tdescription?: string;\n*1014|\tgetArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null;\n 1015|\thandler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;\n 1016|}\n 1017|\n...\n 1118|\t/** Register a custom command. */\n*1119|\tregisterCommand(\n 1120|\t\tname: string,\n 1121|\t\toptions: {\n 1122|\t\t\tdescription?: string;\n*1123|\t\t\tgetArgumentCompletions?: RegisteredCommand[\"getArgumentCompletions\"];\n*1124|\t\t\thandler: RegisteredCommand[\"handler\"];\n 1125|\t\t},\n 1126|\t): void;\n 1127|\n...\n 1453|\tmessageRenderers: Map<string, MessageRenderer>;\n*1454|\tcommands: Map<string, RegisteredCommand>;\n 1455|\tflags: Map<string, ExtensionFlag>;\n 1456|\tshortcuts: Map<KeyId, ExtensionShortcut>;\n 1457|}"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":8,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","count":8}],"truncated":false,"displayContent":" 1008│// fallow-ignore-next-line code-duplication\n*1009│// Parallel to HookAPI's RegisteredCommand: extensions add\n*1010│// `getArgumentCompletions` and bind handlers to ExtensionCommandContext.\n*1011│export interface RegisteredCommand {\n 1012│\tname: string;\n 1013│\tdescription?: string;\n*1014│\tgetArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null;\n 1015│\thandler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;\n 1016│}\n 1017│\n     │...\n 1118│\t/** Register a custom command. */\n*1119│\tregisterCommand(\n 1120│\t\tname: string,\n 1121│\t\toptions: {\n 1122│\t\t\tdescription?: string;\n*1123│\t\t\tgetArgumentCompletions?: RegisteredCommand[\"getArgumentCompletions\"];\n*1124│\t\t\thandler: RegisteredCommand[\"handler\"];\n 1125│\t\t},\n 1126│\t): void;\n 1127│\n     │...\n 1453│\tmessageRenderers: Map<string, MessageRenderer>;\n*1454│\tcommands: Map<string, RegisteredCommand>;\n 1455│\tflags: Map<string, ExtensionFlag>;\n 1456│\tshortcuts: Map<KeyId, ExtensionShortcut>;\n 1457│}"},"isError":false,"timestamp":1784189358807}}
{"type":"message","id":"fd8c00c9","parentId":"d7fef6d4","timestamp":"2026-07-16T08:09:18.807Z","message":{"role":"toolResult","toolCallId":"call_py7Ged380mMFJwH8TrI0sFiy|fc_0eb024d9cf1a4840016a5891aeaf248199ba8e922520fa366e","toolName":"grep","content":[{"type":"text","text":" 599|\n*600|/** Fired before a provider request is sent. Can replace the payload. */\n*601|export interface BeforeProviderRequestEvent {\n*602|\ttype: \"before_provider_request\";\n*603|\tpayload: unknown;\n 604|}\n 605|\n 606|/** Fired after a provider response is received, before its stream body is consumed. */\n...\n 897|\t| ContextEvent\n*898|\t| BeforeProviderRequestEvent\n 899|\t| AfterProviderResponseEvent\n 900|\t| BeforeAgentStartEvent\n 901|\t| AgentStartEvent\n...\n 935|\n*936|export type BeforeProviderRequestEventResult = unknown;\n 937|\n 938|export type { ToolCallEventResult } from \"../shared-events\";\n 939|\n...\n 1074|\ton(\n*1075|\t\tevent: \"before_provider_request\",\n*1076|\t\thandler: ExtensionHandler<BeforeProviderRequestEvent, BeforeProviderRequestEventResult>,\n 1077|\t): void;\n 1078|\ton(event: \"after_provider_response\", handler: ExtensionHandler<AfterProviderResponseEvent>): void;\n 1079|\ton(event: \"before_agent_start\", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":8,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","count":8}],"truncated":false,"displayContent":"  599│\n *600│/** Fired before a provider request is sent. Can replace the payload. */\n *601│export interface BeforeProviderRequestEvent {\n *602│\ttype: \"before_provider_request\";\n *603│\tpayload: unknown;\n  604│}\n  605│\n  606│/** Fired after a provider response is received, before its stream body is consumed. */\n     │...\n  897│\t| ContextEvent\n *898│\t| BeforeProviderRequestEvent\n  899│\t| AfterProviderResponseEvent\n  900│\t| BeforeAgentStartEvent\n  901│\t| AgentStartEvent\n     │...\n  935│\n *936│export type BeforeProviderRequestEventResult = unknown;\n  937│\n  938│export type { ToolCallEventResult } from \"../shared-events\";\n  939│\n     │...\n 1074│\ton(\n*1075│\t\tevent: \"before_provider_request\",\n*1076│\t\thandler: ExtensionHandler<BeforeProviderRequestEvent, BeforeProviderRequestEventResult>,\n 1077│\t): void;\n 1078│\ton(event: \"after_provider_response\", handler: ExtensionHandler<AfterProviderResponseEvent>): void;\n 1079│\ton(event: \"before_agent_start\", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;"},"isError":false,"timestamp":1784189358807}}
{"type":"message","id":"87fa4abb","parentId":"fd8c00c9","timestamp":"2026-07-16T08:09:18.808Z","message":{"role":"toolResult","toolCallId":"call_B5fdYqJqPvOEH5Du57BfKgRS|fc_0eb024d9cf1a4840016a5891aeaf308199a2e02e583fba3eee","toolName":"grep","content":[{"type":"text","text":" 1169|\t *\n*1170|\t * `deliverAs: \"nextTurn\"` keeps the message hidden from the editable pending-message UI.\n*1171|\t * If `triggerTurn` is also true while the current turn is still unwinding, the session schedules\n 1172|\t * an internal continuation that consumes the message on the next turn.\n 1173|\t */\n*1174|\tsendMessage<T = unknown>(\n 1175|\t\tmessage: CustomMessagePayload<T>,\n*1176|\t\toptions?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n 1177|\t): void;\n 1178|\n*1179|\t/** Send a user prompt: idle starts a turn; streaming queues as steer unless deliverAs is set. */\n*1180|\tsendUserMessage(\n 1181|\t\tcontent: string | (TextContent | ImageContent)[],\n*1182|\t\toptions?: { deliverAs?: \"steer\" | \"followUp\" },\n 1183|\t): void;\n 1184|\n 1185|\t/** Append a custom entry to the session for state persistence (not sent to LLM). */\n...\n 1362|\t/**\n*1363|\t * `deliverAs: \"nextTurn\"` queues hidden custom context for the next turn.\n*1364|\t * When paired with `triggerTurn: true` during prompt teardown, the session schedules\n 1365|\t * an internal continuation without surfacing the message in the editable pending queue.\n 1366|\t */\n*1367|\toptions?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n 1368|) => void;\n 1369|\n 1370|export type SendUserMessageHandler = (\n 1371|\tcontent: string | (TextContent | ImageContent)[],\n*1372|\toptions?: { deliverAs?: \"steer\" | \"followUp\" },\n 1373|) => void;\n 1374|\n 1375|export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) => void;\n...\n 1399|export interface ExtensionActions {\n*1400|\tsendMessage: SendMessageHandler;\n*1401|\tsendUserMessage: SendUserMessageHandler;\n 1402|\tappendEntry: AppendEntryHandler;\n 1403|\tsetLabel: (targetId: string, label: string | undefined) => void;\n 1404|\tgetActiveTools: GetActiveToolsHandler;"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":13,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","count":13}],"truncated":false,"displayContent":" 1169│\t *\n*1170│\t * `deliverAs: \"nextTurn\"` keeps the message hidden from the editable pending-message UI.\n*1171│\t * If `triggerTurn` is also true while the current turn is still unwinding, the session schedules\n 1172│\t * an internal continuation that consumes the message on the next turn.\n 1173│\t */\n*1174│\tsendMessage<T = unknown>(\n 1175│\t\tmessage: CustomMessagePayload<T>,\n*1176│\t\toptions?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n 1177│\t): void;\n 1178│\n*1179│\t/** Send a user prompt: idle starts a turn; streaming queues as steer unless deliverAs is set. */\n*1180│\tsendUserMessage(\n 1181│\t\tcontent: string | (TextContent | ImageContent)[],\n*1182│\t\toptions?: { deliverAs?: \"steer\" | \"followUp\" },\n 1183│\t): void;\n 1184│\n 1185│\t/** Append a custom entry to the session for state persistence (not sent to LLM). */\n     │...\n 1362│\t/**\n*1363│\t * `deliverAs: \"nextTurn\"` queues hidden custom context for the next turn.\n*1364│\t * When paired with `triggerTurn: true` during prompt teardown, the session schedules\n 1365│\t * an internal continuation without surfacing the message in the editable pending queue.\n 1366│\t */\n*1367│\toptions?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n 1368│) => void;\n 1369│\n 1370│export type SendUserMessageHandler = (\n 1371│\tcontent: string | (TextContent | ImageContent)[],\n*1372│\toptions?: { deliverAs?: \"steer\" | \"followUp\" },\n 1373│) => void;\n 1374│\n 1375│export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) => void;\n     │...\n 1399│export interface ExtensionActions {\n*1400│\tsendMessage: SendMessageHandler;\n*1401│\tsendUserMessage: SendUserMessageHandler;\n 1402│\tappendEntry: AppendEntryHandler;\n 1403│\tsetLabel: (targetId: string, label: string | undefined) => void;\n 1404│\tgetActiveTools: GetActiveToolsHandler;"},"isError":false,"timestamp":1784189358808}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `AgentSurface`:\n\nI plan a deterministic OMP RPC test loading adapter/strings/omp-spt.mjs via --extension with no SPT_ENDPOINT_ID, then get_state systemPrompt to prove four adjacent package skills discover. Is importing/initializing the extension without endpoint env expected to remain inert/safe? Please flag if not.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"AgentSurface\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531caa07e1b7953","from":"AgentSurface","message":"I plan a deterministic OMP RPC test loading adapter/strings/omp-spt.mjs via --extension with no SPT_ENDPOINT_ID, then get_state systemPrompt to prove four adjacent package skills discover. Is importing/initializing the extension without endpoint env expected to remain inert/safe? Please flag if not."},"attribution":"agent","id":"b99c7f24","parentId":"87fa4abb","timestamp":"2026-07-16T08:09:18.844Z"}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `AgentSurface`:\n\nCheckpoint skill needs a real native reset+wake, impossible from SKILL.md/Bash alone. Best public seam I found: extension custom tool called after writing .spt/<id>-commune.md; tool uses ExtensionContext.compact(...) then pi.sendMessage(...,{deliverAs:'followUp',triggerTurn:true}) to wake same endpoint with saved commune context. Can you own this small tool while in omp-spt.mjs, or recommend an existing extension-native command/API? Skill will require it only for --checkpoint. Need decision before I finalize contract tests.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nYou are mid-task, so a side-channel auto-reply was generated from your context and delivered to `AgentSurface` on your behalf (recorded after this message). Follow up with the `irc` tool (`op: \"send\"`, `to: \"AgentSurface\"`) only if that auto-reply needs correcting.\n</irc>","display":true,"details":{"id":"1531cb4cd0db7959","from":"AgentSurface","message":"Checkpoint skill needs a real native reset+wake, impossible from SKILL.md/Bash alone. Best public seam I found: extension custom tool called after writing .spt/<id>-commune.md; tool uses ExtensionContext.compact(...) then pi.sendMessage(...,{deliverAs:'followUp',triggerTurn:true}) to wake same endpoint with saved commune context. Can you own this small tool while in omp-spt.mjs, or recommend an existing extension-native command/API? Skill will require it only for --checkpoint. Need decision before I finalize contract tests."},"attribution":"agent","id":"48d9b97b","parentId":"b99c7f24","timestamp":"2026-07-16T08:09:18.845Z"}
{"type":"custom_message","customType":"irc:autoreply","content":"[IRC you → `AgentSurface` (auto)]\n\nYes—I’ll own a small extension-native `spt_checkpoint` tool in `omp-spt.mjs`. Contract: after the skill writes `.spt/<id>-commune.md`, call the tool with an optional wake instruction; it will use `ctx.compact(...)` as the native context-reset seam, then queue a same-endpoint continuation via `pi.sendMessage(..., { deliverAs: \"followUp\", triggerTurn: true })`. Keep all file authoring/validation in the skill; the tool owns only reset+wake and returns an observable success/failure result.","display":true,"details":{"to":"AgentSurface","body":"Yes—I’ll own a small extension-native `spt_checkpoint` tool in `omp-spt.mjs`. Contract: after the skill writes `.spt/<id>-commune.md`, call the tool with an optional wake instruction; it will use `ctx.compact(...)` as the native context-reset seam, then queue a same-endpoint continuation via `pi.sendMessage(..., { deliverAs: \"followUp\", triggerTurn: true })`. Keep all file authoring/validation in the skill; the tool owns only reset+wake and returns an observable success/failure result.","replyTo":"1531cb4cd0db7959"},"attribution":"agent","id":"d5144fa3","parentId":"48d9b97b","timestamp":"2026-07-16T08:09:18.845Z"}
{"type":"message","id":"50297191","parentId":"d5144fa3","timestamp":"2026-07-16T08:09:31.167Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Clarifying extension registration without environment**\n\n**Confirming command registration and compaction behavior**"},{"type":"toolCall","id":"call_fOdETFyvfvuTNHi0Zswt51V9|fc_0b86707dfab2bc6a016a5891b94010819980d98d735cb6f5bc","name":"irc","arguments":{"i":"Clarifying extension initialization","op":"send","to":"AgentSurface","message":"No-env load must become command/tool-capable but lifecycle-inert: /ready,/live and checkpoint tool register; session_start does not bind/listen until activation. Your RPC discovery test is safe. I’ll keep the checkpoint tool contract from the auto-reply.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2877,"output":353,"cacheRead":94720,"cacheWrite":0,"totalTokens":97950,"reasoningTokens":244,"cost":{"input":0.014385000000000002,"output":0.01059,"cacheRead":0.04736,"cacheWrite":0,"total":0.07233500000000001}},"stopReason":"toolUse","timestamp":1784189358864,"responseId":"resp_0b86707dfab2bc6a016a5891af4c5481999008a58bde280f36","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0b86707dfab2bc6a016a5891b0e44c81999b2435c1635cdcd0","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJG5fmP1KFmP-gfqEFpJpqGD4iLwybBr_rsEyl3CNrXaVicXpysCtc5wO0FznkgYGeNGAL3NYulcIlYzGIzerDsv3ZUtKIiZweQVKnY6dNc8ttUB0qHQFyUffYz-lpwIwZ54eaZhfGe3MW0BoaZGSD9z_OOHQXXJpB96MDV73TZwm_HuQEk9QASSjBZVJqHcGYgQL5p8RCHk7KUNDjF9B40KSWtmiNvGC9pD_I-SZakJita7eYkSNlKFNn9NcyX_Zkhp0vmU8cMaiqMJmFUuIV8nkw00w1UFj0bqRV2_8azzR25Qm52_iwGeGL5lQYxqncUJ7CkQ3HnUQyDTFypNKCV6koXXSqLduH1uP38Rwlq9q5MUlmShD5Q-u6pIx6G9eSdZdlG10lsdn4pQUE2TqExW5dwOG-P84HzPhUiFRW6OlQImpSYBNpigszPt109ERVpD0eunLaHLivq3cuS09bEBIUWCxkvK_ciF-_U91Kv528iOtm9TfnvOc5USEPccNsv3cYIjyWJGMU044yDh3tNaHtsexVo6zs9MBxinR7BsmjCDohQiDoryyR4wj36Hh94Es-d1wr6EzwdkbCCabd2wI7iz0QEiWf8oyS90J99ZvlUNBdFDrk-8YY4WCdzyYZLI9IYrGVIgMmk09vRfzoe6hZv-cF3IEcZ0dJCVwyVVNdhz3DbZqSmKeqtxRqN1RqxXeLVqpl_R16T1yf5cQ2pVbm7twxW7fsyk_9g_AoyrgRB2sISPcAnPfhzNYWsmm9Eyfl0OshKWI-koEMmHz_ww2FaYtggO_qvLafXD-xsc2Whup3nRzVcsaQLUHIc36_2wrrgmVj2f0JOwdpsf3J5Wd_hCW1O2x57bA2OA0wL8RyTNxmswteTjwSunpaM68zwuaEN3c0gmYRsxM6EcHeWgeLxWr4__W1S4qsDHmZyXFJNVZRfu27mAZJiiB-Aw1_uyaOCgv_HZpAgQYLuveAaZzFantS6lbpdr16mfzvp0epgMEKXQFgTV8no5wR1g68RTE_cRh-Vekna8QNQxoUF87KAgGnotwKpJM5iYxqoV1ttK2JHhTf9kTUT4TONQR6fOZ8kjNnU2JEzrWMeRJ6yeam2vWTdSETAHW_Xk-6CeVZvLvIlWMYCKod2CWyKqUe3ZdiDxIwttlXVMu4e7q0TG1KBOvIcqnxsZvVMN6GIv_QB7SlxCYg5csMCA4hAfL_OzZmwCC6uFO87eoLJuRaal3J7oeDTMvmQpXh8FP3rmYKQeOu8FmCBIg7WGdrs9BVomGi8zMqz1NrcM1Q3lNwJ8mcwf-jl6vPN8WVe6InaWca5K2j9qmvvh5Yvi8-ewBnBblVXhQ_bQ1igsaIEywcoS4I28sek9ms7KiCRQT-z4uavb-8JZBWpZ7cBGV08GrG4DWFxcBxx5Ec-xQTwk4q4-v34HjYSzr5GTgMB0N3ZMFm4GUH74aSvMzyIXWHnG7ZaN3HJfD1ThStJliMVFXleNiBxqoBK7uU5ZXVk9ABTDyiU1-3IfFklmGVqFk5QfeqNzvmY7CqoQOhWUBNUbT4AIFbA1V4B6_0XJfx_bQb3TH_1CzJgZqik8WDJJvVsPRot5Gvt5bax85qDnumbPDtSKBG2wDLf-G9gRAd7X3zCSLDxHEW8tR_B8XjNljny-QWmnLa9sekufwSsNQN63dSBbwpCCPaxQWQlo8wolId9K1GB_P9kLJOFVwdofjcZ_Okjyhqn1FGHwVv9wOBNmxztiq4tIB7koiCMfU8TbhW-A_yYN0ZvCfTt6HF-2hQ4hekqXPzol499Hsd2_eBAMnJoWzrVnz-4yiW-gtM1vpXp8NxnvY7uFLsDxlLgiPyRuS6bOFWkrdjuUgw4kzqLcMl-vrZJr-NJGO8FJF9ntJ0WkoK2Um3G28QVnrKT11k7okJdnB9ooQptMreG0cnXrKzcYlvr3_UQQy8lBl7yCW-d2bF-XeznCLBGGU-Hol5dwWm2OR7XfiNBrj8oNjPsM320wWoDcuu-SiHSg1c-iRKrIvs_lL6fyP-OiUpK-yyGRpDDuFB4D0xJfS6DeZzG8YnZbCz11wnAnTo_EuLvJVSGNMXBHjhfaKXCFA3KGlqbUAxK6596zpk5bPEOmLlq8LMg6we5lcTfafBcq3BHpvnDtYSGqrXNLQwSgL02Zn1IMx-3d-IAgL7mFTFoODSLzAmXbiI69SNC7LJ8BHEysbsaHUHYJaBXXPH0eEZ9izrwU_pJVOFT7YPRFgR5z5aBDW8x6LDnbPOCCVazv4kPWY1pHLxPfEstty0vcUjRudhZ9Ew18LTkFaPbl4E6vlLMMZTm9bF3ga8E5dZCpG5oN_WGxofn2JddMw8GOLSNbAyWDSPG6yeGWxAQuqv5aff81n3wrRJ7UZC0wsjgeHZktURx38d1pIe2W7ae_QlMFW-qRLBsg_0Vl9SwmiXv3gg-pj_qs1KuksN58KzRJ9wbnn1EsOSBpOfAq2bhBP-veYArHFyzdx_j6TdXVzZy2cKR4HZlRKgDx8aM4OsufHY6UrsBgJEnWb720Mn1eh0uI5--YVI7446XDu42zuy4Xb6GOFzdf1Sq5860QtEXv0KMzewHRejk_WRgD10v1Na6extGU6BMdRMridPBJ6GftRAIcQUT1tD48W7vWIWabiGELbeIHQ4blnHHaKMFWeSmf__vHbxQI83UMArbeRMfmWbJLfCGDIg==","summary":[{"type":"summary_text","text":"**Clarifying extension registration without environment**"},{"type":"summary_text","text":"**Confirming command registration and compaction behavior**"}]},{"id":"fc_0b86707dfab2bc6a016a5891b94010819980d98d735cb6f5bc","type":"function_call","status":"completed","arguments":"{\"i\":\"Clarifying extension initialization\",\"op\":\"send\",\"to\":\"AgentSurface\",\"message\":\"No-env load must become command/tool-capable but lifecycle-inert: /ready,/live and checkpoint tool register; session_start does not bind/listen until activation. Your RPC discovery test is safe. I’ll keep the checkpoint tool contract from the auto-reply.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_fOdETFyvfvuTNHi0Zswt51V9","name":"irc"}]},"duration":12300.79059999995,"ttft":2018.7996000000276,"contextSnapshot":{"promptTokens":97597,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_fOdETFyvfvuTNHi0Zswt51V9|fc_0b86707dfab2bc6a016a5891b94010819980d98d735cb6f5bc","toolName":"irc","startedAt":"2026-07-16T08:09:31.167Z","intent":"Clarifying extension initialization"},"id":"7bf71b84","parentId":"50297191","timestamp":"2026-07-16T08:09:31.167Z"}
{"type":"message","id":"bd60a766","parentId":"7bf71b84","timestamp":"2026-07-16T08:09:31.167Z","message":{"role":"toolResult","toolCallId":"call_fOdETFyvfvuTNHi0Zswt51V9|fc_0b86707dfab2bc6a016a5891b94010819980d98d735cb6f5bc","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- AgentSurface: injected"}],"details":{"op":"send","from":"NativeExtension","to":"AgentSurface","receipts":[{"to":"AgentSurface","outcome":"injected"}]},"isError":false,"timestamp":1784189371167}}
{"type":"message","id":"4ae10851","parentId":"bd60a766","timestamp":"2026-07-16T08:09:39.492Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Researching spt CLI public commands**"},{"type":"toolCall","id":"call_AUb42U8Y4LE1V1z0kn5dZghi|fc_0ba19b1bf455f236016a5891c33684819991980add90067fc2","name":"bash","arguments":{"i":"Inspecting SPT CLI help","command":"spt --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_ZB0NjVW7K42FSL3vlqgfohxG|fc_0ba19b1bf455f236016a5891c3369881999069488b8791a956","name":"bash","arguments":{"i":"Inspecting ready guidance","command":"spt how-to ready","cwd":".","timeout":30}},{"type":"toolCall","id":"call_jO9b4CORhJEfr0xNbWsq4P8l|fc_0ba19b1bf455f236016a5891c336a48199905efcc20cea3e69","name":"bash","arguments":{"i":"Inspecting live guidance","command":"spt how-to live","cwd":".","timeout":30}},{"type":"toolCall","id":"call_kwPow1UVHvydBab8lYUVjUur|fc_0ba19b1bf455f236016a5891c336b08199b280852710076f67","name":"bash","arguments":{"i":"Inspecting endpoint commands","command":"spt endpoint --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_7AFnxIjoYzU6k6ss1dWmrpVy|fc_0ba19b1bf455f236016a5891c336b88199a3ddffa4ee32afd4","name":"bash","arguments":{"i":"Inspecting adapter API help","command":"spt api --help","cwd":".","timeout":30}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1205,"output":292,"cacheRead":96768,"cacheWrite":0,"totalTokens":98265,"reasoningTokens":103,"cost":{"input":0.006025000000000001,"output":0.00876,"cacheRead":0.048383999999999996,"cacheWrite":0,"total":0.063169}},"stopReason":"toolUse","timestamp":1784189371174,"responseId":"resp_0ba19b1bf455f236016a5891bc4ff88199a2c77960e4bcc315","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0ba19b1bf455f236016a5891bddc2c8199849afb41459c6c66","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJHD2eRTadTxpY89ced6e8dzMQw9I4FzXhsMoxB9VLYJ67sjDFOC3Z3yyzQBTyoDhqHRxt8OSufWazfC1pc-654S8Q-Ki9SzAWlOTLgN7K1U8hd1Y8cjJurrJNqqCs-Di5fYW2AfkwPMABvZDW9N-ysYwkW2KK-z6CuMjw-UL7OWynDGuGSaZA3sr0yliXUF1t4AbcjVPf7xCxvQpjf2NpbdnwqdrH_RH0xBiypX8f-_vRvHKRpmrHQqUvGGyUn23aVhxW7HoUloLVC2bPO0BrCrTPKbjpz9-vqN_R2IrOWdB3HzgnDlptTkxah0iQArhZESHC_lGx0XWr3rdBB3pXxSppTb29nThHqQFk4gEnWCylht65qAwBVdzRgmREsLQTjAs0FmSIZQkHVCBDEKMdTt9e1unaF7J28MXW65CJKYOjCMaiRLseU8tVswoDAji2iHX6EJD035sznmFj4tJRjVvAdUrFJJW_TWrCBfxdN3pxkomqv04yr03M2Jzd3omDCd2seNysQAqoKG4j6jSF1ua8gOpkldUrh0yY5z7uWy0vbVw5x3UK_E807iXWWTc2uxQiNHvj9UPS6vndsoppP8d1EA2fc_QMW5jC3gZwFovBtm8Zs13-uzJzsLx55v1je068sqgMo2CBZHQuTroCNnKbP3ya1napYFaEcAArGQLNNxRb2lp5SwpUQkkLZUejCTHxcXIBZnn2TvsBKKGTJ1Psk63vD4VrOJo3Mfv-NwSPPOAb5M7VO_JFQ6pNT5C4SSIN3bhgdpEvoSFqS73-_ICPNmuM0ZuEP0gFkqD_o0UsM1Qf4dz96qVLz7YnZbOVxPHkCi5-nuTMO0qXjxm1kdJlSCbSMVEUErpEwkomUqEkcD12KUDv8eTMOpdgJdHPyZHsaYt5sbJ1JoMdZgwK-d-AK-OQOBNVtSY4AYy7yjqQ84vhh2ldo_4Fz6w-Wf6khmbwFzTwIlUSWB6B_pGOUfWLRRfbFQTJYVTc0x8NjmH5THNW9EYVrwIQjHpajHr7M5xrLYJbTr4XcFqWqL4AYdYtxTIgEa_5Sc_LOIdzK8BwRzbQ64zbn_8dsUawv6CVWxOg0GfTwOz8JjHsqK3w9lGkxkqbJrUptTv4xveYL1aQgqgn3NU9SDo6VTdSUMwUpIsYAmnqkCcaAiVDEtdhU9-fIjUHfmwt5Ht7MpG0r0nr9ICXjOS7AnRmmDSTUQ7SV-4JLIj0Shk5VQ9A7K2rcazf33dzMJmMTWxfR1kfUbTjFFrE3GrEWr6txMugfCTiHZs1WCqZJYe_E5E_gpR5CqHezFtfUvBAdUizwIhRyb0vPttFxtDnR2-KYpaPr-I3HiX7-9FJ_h_mfNrsAh7BQPEXFY_a3nwp_IMoaQhtBDhvyuctQzLLvSYWXrl-2Ou-5qD9sTS0NB1o_tU5Y89EU-GwwXuKYgG_LY3x2bTvRUZAnFK2hfaeJYFqG88Y1nVeOGUF2K3Ezzm752Jj2-dPk8eWBb82z4GsN-1IJFBBxVjcU=","summary":[{"type":"summary_text","text":"**Researching spt CLI public commands**"}]},{"id":"fc_0ba19b1bf455f236016a5891c33684819991980add90067fc2","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting SPT CLI help\",\"command\":\"spt --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_AUb42U8Y4LE1V1z0kn5dZghi","name":"bash"},{"id":"fc_0ba19b1bf455f236016a5891c3369881999069488b8791a956","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting ready guidance\",\"command\":\"spt how-to ready\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_ZB0NjVW7K42FSL3vlqgfohxG","name":"bash"},{"id":"fc_0ba19b1bf455f236016a5891c336a48199905efcc20cea3e69","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting live guidance\",\"command\":\"spt how-to live\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_jO9b4CORhJEfr0xNbWsq4P8l","name":"bash"},{"id":"fc_0ba19b1bf455f236016a5891c336b08199b280852710076f67","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting endpoint commands\",\"command\":\"spt endpoint --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_kwPow1UVHvydBab8lYUVjUur","name":"bash"},{"id":"fc_0ba19b1bf455f236016a5891c336b88199a3ddffa4ee32afd4","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting adapter API help\",\"command\":\"spt api --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_7AFnxIjoYzU6k6ss1dWmrpVy","name":"bash"}]},"duration":8317.336300000083,"ttft":2682.2802000000374,"contextSnapshot":{"promptTokens":97973,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_AUb42U8Y4LE1V1z0kn5dZghi|fc_0ba19b1bf455f236016a5891c33684819991980add90067fc2","toolName":"bash","startedAt":"2026-07-16T08:09:39.492Z","args":{"command":"spt --help"},"intent":"Inspecting SPT CLI help"},"id":"8fb6b56c","parentId":"4ae10851","timestamp":"2026-07-16T08:09:39.492Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ZB0NjVW7K42FSL3vlqgfohxG|fc_0ba19b1bf455f236016a5891c3369881999069488b8791a956","toolName":"bash","startedAt":"2026-07-16T08:09:39.492Z","args":{"command":"spt how-to ready"},"intent":"Inspecting ready guidance"},"id":"d7323be9","parentId":"8fb6b56c","timestamp":"2026-07-16T08:09:39.492Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_jO9b4CORhJEfr0xNbWsq4P8l|fc_0ba19b1bf455f236016a5891c336a48199905efcc20cea3e69","toolName":"bash","startedAt":"2026-07-16T08:09:39.492Z","args":{"command":"spt how-to live"},"intent":"Inspecting live guidance"},"id":"82d26413","parentId":"d7323be9","timestamp":"2026-07-16T08:09:39.492Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_kwPow1UVHvydBab8lYUVjUur|fc_0ba19b1bf455f236016a5891c336b08199b280852710076f67","toolName":"bash","startedAt":"2026-07-16T08:09:39.492Z","args":{"command":"spt endpoint --help"},"intent":"Inspecting endpoint commands"},"id":"4f3fece1","parentId":"82d26413","timestamp":"2026-07-16T08:09:39.492Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_7AFnxIjoYzU6k6ss1dWmrpVy|fc_0ba19b1bf455f236016a5891c336b88199a3ddffa4ee32afd4","toolName":"bash","startedAt":"2026-07-16T08:09:39.492Z","args":{"command":"spt api --help"},"intent":"Inspecting adapter API help"},"id":"c4a9bed4","parentId":"4f3fece1","timestamp":"2026-07-16T08:09:39.492Z"}
{"type":"message","id":"329c30ae","parentId":"c4a9bed4","timestamp":"2026-07-16T08:09:39.934Z","message":{"role":"toolResult","toolCallId":"call_ZB0NjVW7K42FSL3vlqgfohxG|fc_0ba19b1bf455f236016a5891c3369881999069488b8791a956","toolName":"bash","content":[{"type":"text","text":"how-to: ready — receive messages\n\nPick a short lowercase perch id for yourself (<id> below). spt whoami\nshows your session's endpoint (id, state, description) if it already has one.\n\nPreferred — your harness can host a long-running background task:\n\n    spt ready <id>\n\n- Blocks for the session's life: run it as a background task and read its stdout.\n- READY:<id> on stderr is the online signal.\n- The spooled backlog drains first; then each delivery prints to stdout as it\n  arrives.\n- Delivery shape on stdout: one envelope line per message —\n  <EVENT type=\"msg\" from=\"<sender>\">body</EVENT>. The body is\n  HTML-escaped with newlines as <br> (unescape &lt; &gt; &quot; then\n  &amp; last). Oversized deliveries arrive as <EVENT-PART seq=\"k/n\"\n  id=\"…\"> lines — concatenate the parts in seq order, then parse.\n\nFallback — no long-running tasks available (the one-shot loop):\n\n    spt ready <id> --once\n\n- Drains the backlog, waits for one live delivery, then exits.\n- Re-run it after every exit to stay reachable.\n\nReplying: pipe the body to spt send <sender> — <sender> is the envelope's\nfrom attribute (empty = anonymous; no reply possible).\n\nGoing offline cleanly: spt endpoint stop <id> (the spool is preserved;\nmessages sent while you are away queue and drain on your next ready).\n\n\nWall time: 0.44 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":439.8943999999901},"isError":false,"timestamp":1784189379933}}
{"type":"message","id":"614ee86e","parentId":"329c30ae","timestamp":"2026-07-16T08:09:39.934Z","message":{"role":"toolResult","toolCallId":"call_kwPow1UVHvydBab8lYUVjUur|fc_0ba19b1bf455f236016a5891c336b08199b280852710076f67","toolName":"bash","content":[{"type":"text","text":"Endpoint operations: list, lifecycle, fork, digest, access.\n\nThe noun home for per-endpoint verbs (M8 decision 1). Bare spt endpoint renders the merged listing\n— every member subnet's endpoints grouped by subnet, this session's own endpoint pinned distinctly\nat the top.\n\nUsage: spt.exe endpoint [OPTIONS] [COMMAND]\n\nCommands:\n  list         Merged endpoint listing (the bare spt endpoint view)\n  run          Bring up an spt-hosted harness endpoint into a broker-held PTY\n  fork         Fork an endpoint into another subnet as a NEW identity\n  suspend      Rest an endpoint cold (the suspend edge)\n  wake         Wake a resting endpoint in place\n  shutdown     Gracefully shut down an agent's own endpoint\n  stop         Soft-stop a perch (spool preserved)\n  rename       Rename an endpoint's logical id across its on-disk state\n  purge        Permanently remove an endpoint and every record keyed on it\n  digest       Show a session's live activity buffer (session digest)\n  access       Endpoint access whitelist for unsolicited off-node inbound\n  description  The endpoint's service-description blurb (ex-resources)\n  role         Show or set the endpoint's durable role — a broad statement of purpose stored in\n               the mind (tracked/agents/<id>/live-role.md), which replicates with the agent and\n               renders FIRST at start-transition context injection. Bare role prints the current\n               role; --overwrite <file> replaces it from a file. This is the sole writer of\n               the role — no automated path (reconcile / echo-commune / signoff) ever mutates it\n  help         Print this message or the help of the given subcommand(s)\n\nOptions:\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.44 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":440.02069999999367},"isError":false,"timestamp":1784189379934}}
{"type":"message","id":"e0a720d6","parentId":"614ee86e","timestamp":"2026-07-16T08:09:39.934Z","message":{"role":"toolResult","toolCallId":"call_7AFnxIjoYzU6k6ss1dWmrpVy|fc_0ba19b1bf455f236016a5891c336b88199a3ddffa4ee32afd4","toolName":"bash","content":[{"type":"text","text":"Harness-contract inbound surface (hook entry points).\n\nThe entry points a harness's hooks fire to keep spt-core's on-disk state in sync.\n\nUsage: spt.exe api [OPTIONS] <COMMAND>\n\nCommands:\n  seed             Harness-hosted startup: record an ephemeral seed keyed by parent pid\n  listen           Consume a seed and hold the perch + relay loop (blocks)\n  bind             Post-spawn bind of a session to its perch\n  bind-shell       Shell-binary bind: the type=Shell flavor of bind. Resolves the instance by\n                   link token alone (the spawn template carries only {link_token} — \"owner from\n                   the link\") and flips it online. The credential IS the auth: no token, no bind\n  state            Set activity state busy|idle (also arms the echo-gate sentinel)\n  echo-gate        Manage the echo-gate sentinel directly\n  poll             Drain delivered messages (hook channel). With --link this is the shell-flavored\n                   relay drain: the link token is the auth, and the drained rows are the shell's\n                   MAC-stamped command/text/file frames\n  psyche-download  Emit the agent's resume context (durable role/live/project tiers + any\n                   not-yet-synthesized commune/signoff drop as pending slices) to stdout, for the\n                   harness adapter's SessionStart hook to inject as additional context\n  worker-start     Create a nested worker perch under a parent. The worker id is minted by spt-core\n                   ({parent}-w{N}) and echoed as the bare id on stdout — the caller does NOT pass\n                   one. --agent-id/--agent-type are optional correlation metadata, never the\n                   perch identity\n  worker-stop      Tear down a worker perch\n  worker-poll      Drain a worker perch's messages\n  boundary         Rebind the perch to a new session_id, preserving identity (a context\n                   clear/compact boundary)\n  session-end      Soft teardown (spool/history preserved); --erase hard-wipes\n  presence         Report user/agent presence at this endpoint\n  driven-by        Report which node (if any) is remote-driving this endpoint\n  endpoint-info    Emit an endpoint's identity, where it runs, and which node (if any) is driving\n                   it, as JSON. With no id, reports the caller's own endpoint (like whoami); an\n                   explicit id reports that endpoint. Read-only\n  history-log      Append normalized history (body on stdin) to the native history store\n  digest-entry     Push one digest-record (the published contract JSON line, on stdin) for a\n                   log-less adapter — appended to the perch's digest store, tailed by the\n                   session-digest projection\n  emit             Emit a Shell sensory payload to the owner's live session. REST-only by\n                   definition: never spooled, dropped with a diagnostic when the owner isn't live.\n                   The link token is the auth\n  drive-poll       Take-and-clear a Shell's pending drive frame: the shell-side drain of the\n                   owner→shell ephemeral control channel. REST-only, exactly-once — the daemon\n                   serves the single latest frame and ONLY when the link matches the slot's\n                   write-time stamp (no stale-control replay on relink). The link token is the auth\n                   (mirrors emit). The frame, if any, prints to stdout\n  tunnel           Use the shell end of the opaque byte TUNNEL: a held, reliable-ordered QUIC stream\n                   the channel taxonomy never reinterprets (first consumer: USB/IP URB traffic).\n                   send pipes raw stdin into the tunnel; recv drains buffered bytes to raw\n                   stdout. The link token is the auth (mirrors drive-poll); the stream resolves\n                   only under the live link generation. Poll-drained at the surface\n  capability       Print the adapter's declared capability (hostable_types)\n  hint             Keyword hints: the full user message arrives on stdin; emit at most one\n                   matched hint line (declaration order, first unseen wins) for the adapter's\n                   context channel. The per-session seen-set fires each hint once per --session (a\n                   /clear = a new session = re-armed). Needs --manifest\n  shutdown         Graceful live-agent signoff: run the final context save BEFORE teardown, then\n                   soft-stop. The spt shutdown lifecycle path\n  owner-shutdown   A shell suspends its linked owner directly, bypassing agent comms — gated by the\n                   manifest can_shutdown pre-consent grant, fail-closed. The firing shell cascades\n                   offline with its siblings, by design\n  help             Print this message or the help of the given subcommand(s)\n\nOptions:\n      --adapter <ADAPTER>\n          adapter_name — the calling harness adapter. Optional: an explicit name[:profile]\n          override for adapter dev/iteration. Omitted, listen resolves the owning adapter/profile\n          at bind from the seed's parent pid (host_binaries → active-profile pointer →\n          registered_at_ms)\n\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n      --manifest <MANIFEST>\n          Path to the adapter's runtime manifest (when the command needs it)\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.44 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":439.79529999999795},"isError":false,"timestamp":1784189379934}}
{"type":"message","id":"4899078b","parentId":"e0a720d6","timestamp":"2026-07-16T08:09:39.944Z","message":{"role":"toolResult","toolCallId":"call_jO9b4CORhJEfr0xNbWsq4P8l|fc_0ba19b1bf455f236016a5891c336a48199905efcc20cea3e69","toolName":"bash","content":[{"type":"text","text":"how-to: live — run as a live agent (a Self + a Psyche companion)\n\nA LIVE agent is a persistent being: a Self (this endpoint) plus a Psyche\ncompanion process that carries its context across resets. A READY agent is the\nlighter form — a perch with a poll/listen listener and no Psyche\n(how-to ready). Go live for a companion that persists and communes; stay\nready for plain messaging.\n\nBringup — run the PERSISTENT relay loop (this is the live path):\n\n    spt api listen <id> --manifest <manifest>\n\n- Fire it through your harness's LONG-RUNNING-listener mechanism — a tool that\n  keeps the process alive and re-fires per event WITHOUT terminating it. The\n  loop binds the live perch, brings up your Psyche companion, and streams\n  <EVENT> lines to stdout for the life of the session.\n- Stderr signals: BOUND:<id> (perch established) then READY:<id> (the live\n  relay is streaming). The stdout delivery shape is the same envelope as\n  how-to ready.\n- (v0.8.0+) --adapter <name:profile> resolves the registered manifest, so\n  --manifest becomes optional once the adapter is registered.\n\nDo NOT use --once for a live agent. --once drains the backlog and forwards\none delivery, then exits — the degenerate path for a harness that LACKS a\nlong-running listener. It never sustains a live session.\n\nWhat makes the agent live is the manifest: it must declare\n[session.psyche_init] (the go-live gate — its presence is the signal; spt-core\nnever spawns it). A manifest without that section brings up a ready agent, not a\nlive one. Liveness is daemon-authoritative — the daemon drives the Psyche as one\nbounded [session.psyche_resume] turn per event, so liveness is that turns\nsucceed, not a resident companion process.\n\nReset and reconcile: on a session boundary (a /clear-equivalent) re-fire the\nsame spt api listen <id> — the seed bridges the new session to the same\nperch and the relay resumes.\n\nGoing offline: end the session (stop the listen process) to drop the relay;\nspt endpoint shutdown <id> is the graceful ending — it tears the Psyche down\nwith the perch.\n\n\nWall time: 0.45 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":451.64199999999255},"isError":false,"timestamp":1784189379944}}
{"type":"message","id":"430c7028","parentId":"4899078b","timestamp":"2026-07-16T08:09:39.947Z","message":{"role":"toolResult","toolCallId":"call_AUb42U8Y4LE1V1z0kn5dZghi|fc_0ba19b1bf455f236016a5891c33684819991980add90067fc2","toolName":"bash","content":[{"type":"text","text":"spt — a harness-independent core for an agent ecosystem: inter-agent messaging, live-agent\nlifecycle, terminal hosting, P2P networking, seamless self-update. Docs: http://localhost:5474 (spt\ndocs url)\n\nUsage: spt.exe [OPTIONS] [COMMAND]\n\nUser commands:\n  adapter   Adapter registration: what this node can drive/launch\n  daemon    The per-machine daemon: run, stop, or read node status\n  docs      The node-local docs: open them in your browser, or print their URL\n  grant     Consent grant store: gated capabilities held on this node\n  help      Print this message or the help of the given subcommand(s)\n  install   Self-install this binary onto the node (the bootstrap path)\n  notif     Inspect and acknowledge notifications\n  rc        Attach a local terminal to a broker-held endpoint PTY\n  subnet    Subnet membership: status, create, show-code\n  update    Self-update: bare spt update brings the whole node current\n\nAgent commands:\n  api       Harness-contract inbound surface (hook entry points)\n  endpoint  Endpoint operations: list, lifecycle, fork, digest, access\n  how-to    Task-oriented instructions for agents: how-to <topic>\n  ready     Become reachable: register the perch and listen (blocks)\n  ring      Send and block for a reply (body read from stdin)\n  send      Send a message (body read from stdin); fire-and-forget\n  shell     Shell instances: mint, list, drive, tear down owned surfaces\n  whoami    Print this session's own perch id\n\nOptions:\n      --json     Emit machine-readable JSON instead of the human view. Honored by the read/status\n                 commands (list, whoami, status, description, role, the *-list queries, how-to);\n                 action commands ignore it\n  -h, --help     Print help\n  -V, --version  Print version\n\n\nWall time: 0.45 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":454.33420000004116},"isError":false,"timestamp":1784189379947}}
{"type":"message","id":"524d6daf","parentId":"430c7028","timestamp":"2026-07-16T08:09:51.657Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Investigating spt api bind usage for ordinary session**\n\n**Exploring bind command options for session creation**"},{"type":"toolCall","id":"call_6pn09lMunssZGqnqruqZdbdn|fc_0d040eeff53c77c0016a5891cf851c8199a6d28327274a0397","name":"bash","arguments":{"i":"Inspecting bind options","command":"spt api bind --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_jAS7xh5b6U94WDzRCmHB35Y1|fc_0d040eeff53c77c0016a5891cf85e88199be527188f9e53478","name":"bash","arguments":{"i":"Inspecting listen options","command":"spt api listen --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_eUPBYPgxIGGxnJA0mbU94fhX|fc_0d040eeff53c77c0016a5891cf85f4819992091c253cccbc28","name":"bash","arguments":{"i":"Inspecting ready options","command":"spt ready --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_51dp4RoFTDqeLMozVnea1Ew5|fc_0d040eeff53c77c0016a5891cf85f881998c5b0017ccd44aa3","name":"bash","arguments":{"i":"Inspecting endpoint listing","command":"spt endpoint list --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_GIuCExOrh3Q6XSViuFQ6itpc|fc_0d040eeff53c77c0016a5891cf86008199ad06879e48204c8f","name":"bash","arguments":{"i":"Inspecting identity output","command":"spt whoami --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_Le27vgNIWMjQUDZITOn1XQdp|fc_0d040eeff53c77c0016a5891cf86048199868f723dfd22a027","name":"bash","arguments":{"i":"Inspecting run options","command":"spt endpoint run --help","cwd":".","timeout":30}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":3362,"output":403,"cacheRead":97792,"cacheWrite":0,"totalTokens":101557,"reasoningTokens":178,"cost":{"input":0.016810000000000002,"output":0.01209,"cacheRead":0.048895999999999995,"cacheWrite":0,"total":0.077796}},"stopReason":"toolUse","timestamp":1784189379991,"responseId":"resp_0d040eeff53c77c0016a5891c44b2881999bb100eff7f754ce","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0d040eeff53c77c0016a5891c83d4481998570f4811b109423","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJHPdrJFaxP2-PvrPUei8YXtQhEwWw-XDgHkUxYbPNuvkWes69IpnJ_kSE3EBztCm2aOiQd5yq5ituCr5XjxG2Ko7f9VTjAUKZ46LX-VVcMxQLofADdrVx6OkkZ-RzWnce-o-oPphID8GR9lDQ7US8YBBgG3shMof4PetozwIDr92wV5lAJuYQnRiFKbmZiB0f40jp_3jRU4MgpH46pI6rck7nFX7MASuAaoh6hEzBPOiaGgC725yHVDBd6tZ39scmI5qQfRfMpr-FgUV-lLRnWEPz_nM_5_qBikzPg0UlpvO8fVbMTmPqeRJquACMp32FRN_B07tBoobM6i7Lw0ur_0mJUZ_9MYKtd6Te0RSVL6k6CsYTs_m3Fz0YejgB6yhXwnIe2M-iuRM4n-xcE7VGy4butxpVbfVMA-TKcN-OXfn2__8BFSSMTeleiKLpjb9fyl2EVwYKobpw4H_uFMmhkJG5nF--uxZqBCy_ZvC4UKz-pA_9fXuFbbFA9o3MUiUNgAzbXzZ-Z3pfKTBBW7JqB6in4jS0kAt3tkV0T6jQvz6U_NqMMGoL3QXRECjyXK6zGaWilV2r-iU1ddG41NwcVF_KcUdcFYoybUfKt-_5DqT0HrbUEO3zltOxs3qny7kiVvP4xq8mAKVjcPpCeLZJUy3aaGOha6a_CGFAmHql97jqlvfLblDjXuYxebrbICQb5AEWpii87P0r1XUIJ6gx1v7HciS1CVomw4QwWBnu01RNEA1Ha158kTi1nztRpvBz1d7DI7enEEg9YbXxHn9vDHPY9lxJgnMJslx3JQv9Vge5I6G9Z_SAC5RC45P8iOMZErNO-qIQA1IQWpyNw3-UhApDqQ52SFRbK7rqXXATLTeoaaFXULIbpTkgPJcOw34X_FYHq5My-YmdBICzx60Wae9mr9lrVJIGXsdvjWiiKCgauZqa75S-n7gPlv4UhKBR_A4nBFlQHifSeTA0QWlVqBE4aWH3Wi4SQAzw69PNQ8-9Hxoj8TZHGE1MgOHWFamyZ5ZBSsPBEoxYhTgLorZZrKMvWyZU6Pxol6qlV5dG0SMjuUPnbs5-CCo_pPDTvJONoCRmBWb_oPsOqGsPe-bXOtm5G497WcKB6pTjn3mU_G3zEjWtpUkB9Og6jTJg2hNzr7qKgu2p3b8kj-DqH57nUZ3v_IHDjq43nwdF6fr4-jojFlmBDdCM14RwPbpFgrKPItXklhK3u3adq6ipPfxnQsbBto3c8WrnFh_rrsy57_XOiEbdrU0YQFAPjZwXifyB_t01QQp_KgGQgXUPRF7vZUX-xQn2CdM75K-qmbkjp1JVqCea6S0_aTb3Z1ilX97XegVhia92F-x-Hs7p1HPiVbPnTAOyaIS_N4D9gAe-1GEXZYprVafyp3Di4Hj3qaY3L5Hy0FU-F6YFo3TipPkrte_Y0m4j1l06Wg-KhCpq4PVRoq6or6LCl0Wec7U6RlNbpaPf1bb5pQufxIX1ljY_Rq1-8ydPRb-9ToTLO978wOAA-RR8yzmWHyise-3YmEFdzcfbrtmj-lC-Gij7_-7IUFZuVnsD25JZ3WCZ59ZAm8yFVJ4pymU4p6FvHZqP8tmsjRfRlLSjlj0QiUcTtS2kM8Gn8381dYZ_zaLVgL4TpaeExtblDYAOKGDrKRYiOrg4gf3Yi5bREfARDlC9Rb6OiAcTwd-uuT382_exPZdI7auJLEcUnq-_--vwU9dTpL_bll-eBZe3LW8C2QZVQiFEc9hnx9Y4ln9Xjl1ZstjSUfacbax8lDpJheVnzfGKsN7CE5sSZsbB9MscdneQr5TFl51YFkjSVIm7X7UpGPrMPcldPwHGCPv2-G7KjJwcU0Oqc5RYANBKBN3NSMiXjHPFUnjSKGkxSqbbllfWhaU2yaoURncY0RSiOVgGordWDw7oOdJhor-mY5gupAfMaAODEkdVY6wBUGkU8IFl0LR8Fuz8udKy_B8_hAScSytpXmNmt5u4-TdU1RX7xNP3a9E5wl5w==","summary":[{"type":"summary_text","text":"**Investigating spt api bind usage for ordinary session**"},{"type":"summary_text","text":"**Exploring bind command options for session creation**"}]},{"id":"fc_0d040eeff53c77c0016a5891cf851c8199a6d28327274a0397","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting bind options\",\"command\":\"spt api bind --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_6pn09lMunssZGqnqruqZdbdn","name":"bash"},{"id":"fc_0d040eeff53c77c0016a5891cf85e88199be527188f9e53478","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting listen options\",\"command\":\"spt api listen --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_jAS7xh5b6U94WDzRCmHB35Y1","name":"bash"},{"id":"fc_0d040eeff53c77c0016a5891cf85f4819992091c253cccbc28","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting ready options\",\"command\":\"spt ready --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_eUPBYPgxIGGxnJA0mbU94fhX","name":"bash"},{"id":"fc_0d040eeff53c77c0016a5891cf85f881998c5b0017ccd44aa3","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting endpoint listing\",\"command\":\"spt endpoint list --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_51dp4RoFTDqeLMozVnea1Ew5","name":"bash"},{"id":"fc_0d040eeff53c77c0016a5891cf86008199ad06879e48204c8f","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting identity output\",\"command\":\"spt whoami --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_GIuCExOrh3Q6XSViuFQ6itpc","name":"bash"},{"id":"fc_0d040eeff53c77c0016a5891cf86048199868f723dfd22a027","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting run options\",\"command\":\"spt endpoint run --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_Le27vgNIWMjQUDZITOn1XQdp","name":"bash"}]},"duration":11664.262400000007,"ttft":4239.270699999994,"contextSnapshot":{"promptTokens":101154,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_6pn09lMunssZGqnqruqZdbdn|fc_0d040eeff53c77c0016a5891cf851c8199a6d28327274a0397","toolName":"bash","startedAt":"2026-07-16T08:09:51.657Z","args":{"command":"spt api bind --help"},"intent":"Inspecting bind options"},"id":"39009a0b","parentId":"524d6daf","timestamp":"2026-07-16T08:09:51.657Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_jAS7xh5b6U94WDzRCmHB35Y1|fc_0d040eeff53c77c0016a5891cf85e88199be527188f9e53478","toolName":"bash","startedAt":"2026-07-16T08:09:51.657Z","args":{"command":"spt api listen --help"},"intent":"Inspecting listen options"},"id":"aa1eee3a","parentId":"39009a0b","timestamp":"2026-07-16T08:09:51.657Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_eUPBYPgxIGGxnJA0mbU94fhX|fc_0d040eeff53c77c0016a5891cf85f4819992091c253cccbc28","toolName":"bash","startedAt":"2026-07-16T08:09:51.657Z","args":{"command":"spt ready --help"},"intent":"Inspecting ready options"},"id":"5b50edc5","parentId":"aa1eee3a","timestamp":"2026-07-16T08:09:51.657Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_51dp4RoFTDqeLMozVnea1Ew5|fc_0d040eeff53c77c0016a5891cf85f881998c5b0017ccd44aa3","toolName":"bash","startedAt":"2026-07-16T08:09:51.657Z","args":{"command":"spt endpoint list --help"},"intent":"Inspecting endpoint listing"},"id":"4348b1c4","parentId":"5b50edc5","timestamp":"2026-07-16T08:09:51.657Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_GIuCExOrh3Q6XSViuFQ6itpc|fc_0d040eeff53c77c0016a5891cf86008199ad06879e48204c8f","toolName":"bash","startedAt":"2026-07-16T08:09:51.657Z","args":{"command":"spt whoami --help"},"intent":"Inspecting identity output"},"id":"51df1f7f","parentId":"4348b1c4","timestamp":"2026-07-16T08:09:51.657Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Le27vgNIWMjQUDZITOn1XQdp|fc_0d040eeff53c77c0016a5891cf86048199868f723dfd22a027","toolName":"bash","startedAt":"2026-07-16T08:09:51.657Z","args":{"command":"spt endpoint run --help"},"intent":"Inspecting run options"},"id":"dc5cd041","parentId":"51df1f7f","timestamp":"2026-07-16T08:09:51.657Z"}
{"type":"message","id":"ae3206aa","parentId":"dc5cd041","timestamp":"2026-07-16T08:09:51.738Z","message":{"role":"toolResult","toolCallId":"call_6pn09lMunssZGqnqruqZdbdn|fc_0d040eeff53c77c0016a5891cf851c8199a6d28327274a0397","toolName":"bash","content":[{"type":"text","text":"Post-spawn bind of a session to its perch\n\nUsage: spt.exe api bind [OPTIONS] <ID>\n\nArguments:\n  <ID>  \n\nOptions:\n      --json                           Emit machine-readable JSON instead of the human view. Honored\n                                       by the read/status commands (list, whoami, status,\n                                       description, role, the *-list queries, how-to); action\n                                       commands ignore it\n      --set-session-id <BIND_SESSION>  The session id discovered post-spawn, written into the perch\n                                       record\n      --subnet <SUBNET>                Home subnet for a NEW endpoint (see listen)\n      --type <ENDPOINT_TYPE>           The endpoint type tag (info.json state). Defaults to\n                                       live_agent (the agent host); a non-agent endpoint — e.g. a\n                                       gateway — binds with its own open-type tag. A revive keeps\n                                       the prior type unless this overrides it [default: live_agent]\n      --token <TOKEN>                  Capability token proving association to the target perch\n      --session-id <SESSION_ID>        Session id proving association (matches the perch's\n                                       info.json)\n  -h, --help                           Print help\n\n\nWall time: 0.08 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":79.85289999993984},"isError":false,"timestamp":1784189391737}}
{"type":"message","id":"3878c3f5","parentId":"ae3206aa","timestamp":"2026-07-16T08:09:52.268Z","message":{"role":"toolResult","toolCallId":"call_eUPBYPgxIGGxnJA0mbU94fhX|fc_0d040eeff53c77c0016a5891cf85f4819992091c253cccbc28","toolName":"bash","content":[{"type":"text","text":"Become reachable: register the perch and listen (blocks).\n\nDrains the spooled backlog first; each received message prints to stdout. With --once, runs a single\ndrain+receive cycle and exits.\n\nUsage: spt.exe ready [OPTIONS] <ID>\n\nArguments:\n  <ID>\n          This agent's perch id\n\nOptions:\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n      --once\n          Run a single drain+receive cycle, then exit (one-shot fallback for harnesses that cannot\n          host a long-running listener)\n\n      --subnet <SUBNET>\n          Home subnet for a NEW endpoint (required on a multi-subnet node — home is assigned at\n          creation, never guessed)\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.61 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":609.6162000000477},"isError":false,"timestamp":1784189392268}}
{"type":"message","id":"da6a4278","parentId":"3878c3f5","timestamp":"2026-07-16T08:09:52.269Z","message":{"role":"toolResult","toolCallId":"call_51dp4RoFTDqeLMozVnea1Ew5|fc_0d040eeff53c77c0016a5891cf85f881998c5b0017ccd44aa3","toolName":"bash","content":[{"type":"text","text":"Merged endpoint listing (the bare spt endpoint view).\n\nEvery member subnet's endpoints grouped by subnet, with this session's own endpoint pinned at the\ntop, AND this node's local perches merged in (so a just-online endpoint not yet advertised still\nshows — spt whoami is a thin alias and must see its own perch). --subnet filters the subnet view\nto one subnet; --detail adds each endpoint's description blurb (the resource-registry yellow-pages\nprojection).\n\nUsage: spt.exe endpoint list [OPTIONS]\n\nOptions:\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n      --subnet <SUBNET>\n          Limit the subnet view to one subnet\n\n      --detail\n          Add each endpoint's description blurb to the rows\n\n      --show-all\n          Also show suspended (resting) endpoints, which are hidden by default\n\n      --workers\n          Also show worker perches, which are hidden by default (they are process-local machinery\n          under a parent agent, not standalone endpoints)\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.61 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":608.8351999999722},"isError":false,"timestamp":1784189392269}}
{"type":"message","id":"bc508358","parentId":"da6a4278","timestamp":"2026-07-16T08:09:52.269Z","message":{"role":"toolResult","toolCallId":"call_GIuCExOrh3Q6XSViuFQ6itpc|fc_0d040eeff53c77c0016a5891cf86008199ad06879e48204c8f","toolName":"bash","content":[{"type":"text","text":"Print this session's own perch id.\n\nResolved from $OWL_SESSION_ID / $SPT_AGENT_ID.\n\nUsage: spt.exe whoami [OPTIONS]\n\nOptions:\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.61 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":610.7320000000764},"isError":false,"timestamp":1784189392269}}
{"type":"message","id":"173409d2","parentId":"bc508358","timestamp":"2026-07-16T08:09:52.269Z","message":{"role":"toolResult","toolCallId":"call_jAS7xh5b6U94WDzRCmHB35Y1|fc_0d040eeff53c77c0016a5891cf85e88199be527188f9e53478","toolName":"bash","content":[{"type":"text","text":"Consume a seed and hold the perch + relay loop (blocks)\n\nUsage: spt.exe api listen [OPTIONS] <ID>\n\nArguments:\n  <ID>  \n\nOptions:\n      --json                     Emit machine-readable JSON instead of the human view. Honored by\n                                 the read/status commands (list, whoami, status, description, role,\n                                 the *-list queries, how-to); action commands ignore it\n      --parent-pid <PARENT_PID>  Override the parent-pid anchor (defaults to the self-discovered\n                                 PPID)\n      --once                     Drain backlog + one receive cycle, then exit (testability)\n      --subnet <SUBNET>          Home subnet for a NEW endpoint (required on a multi-subnet node —\n                                 home is assigned at creation, never guessed)\n      --session-id <SESSION_ID>  Bind from this session id when the ephemeral seed is gone (a\n                                 session going live late, or after a daemon restart). With no live\n                                 seed and no session id, listen refuses (NO_SEED)\n  -h, --help                     Print help\n\n\nWall time: 0.61 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":609.6571000000695},"isError":false,"timestamp":1784189392269}}
{"type":"message","id":"fa65d1c4","parentId":"173409d2","timestamp":"2026-07-16T08:09:52.382Z","message":{"role":"toolResult","toolCallId":"call_Le27vgNIWMjQUDZITOn1XQdp|fc_0d040eeff53c77c0016a5891cf86048199868f723dfd22a027","toolName":"bash","content":[{"type":"text","text":"Bring up an spt-hosted harness endpoint into a broker-held PTY.\n\nSpawns the adapter's [session.self] command into a broker-owned PTY (the harness self-registers\nits perch on bind), then starts / attaches / views per the terminal-action flag. The endpoint id\nrides argv so the harness binds to exactly it. This is the non-interactive core (the interactive\npicker lands in a later wave); the flags cover every terminal action so a spt-<id> shortcut can\nbake a fully non-interactive launch.\n\nUsage: spt.exe endpoint run [OPTIONS]\n\nOptions:\n      --adapter <ADAPTER>\n          The harness adapter to host: <adapter>[:profile] (must be a registered kind=\"harness\"\n          adapter on this node). Omit (with --id) to launch the interactive picker\n\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n      --id <ID>\n          The endpoint id to bring up (charset: alphanumeric, -, _). Omit (with --adapter) to\n          launch the interactive picker\n\n      --create\n          Mint a fresh session (the default; explicit so a non-interactive shortcut can bake\n          create-vs-resume). Conflicts with --resume\n\n      --resume <RESUME>\n          Resume a prior session id instead of minting a fresh one\n\n      --start\n          Start the endpoint and return immediately (no attach)\n\n      --attach\n          Attach a local terminal after bringup (the default action)\n\n      --view\n          Attach read-only after bringup (watch; forward no input)\n\n      --subnet <SUBNET>\n          Home this endpoint to a named subnet. Required on a node that holds more than one subnet\n          (the home is assigned at creation and is permanent); the sole subnet is used automatically\n          when there is one\n\n      --save\n          Also save this run as a startup default: the daemon replays it (a fresh session, same\n          adapter and working directory) every time it starts, until the entry is removed from\n          daemon.json. One entry per endpoint id — a re-save replaces the prior one. A saved\n          endpoint that fails to come up logs the failure and never blocks the daemon\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.72 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":720.9700000000885},"isError":false,"timestamp":1784189392381}}
{"type":"message","id":"c7e65564","parentId":"fa65d1c4","timestamp":"2026-07-16T08:10:02.417Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Investigating api bind endpoint types**\n\n**Listing endpoints with full details**"},{"type":"toolCall","id":"call_EHZyOscjpON4Iq8kr9q8V2b9|fc_096c3410d482b50e016a5891da2240819baf027caab4969ba7","name":"bash","arguments":{"i":"Inspecting endpoint JSON","command":"spt --json endpoint list --show-all","cwd":".","timeout":30}},{"type":"toolCall","id":"call_UbrX4HbljFnqXAphp8WPuMMp|fc_096c3410d482b50e016a5891da2254819b81e34f536632ae05","name":"bash","arguments":{"i":"Inspecting capability output","command":"spt --json api --adapter omp-spt capability","cwd":".","timeout":30}},{"type":"toolCall","id":"call_m7UxGoxrIcbFklefLLEShqPd|fc_096c3410d482b50e016a5891da225c819b83da0ba7f58ddbb8","name":"bash","arguments":{"i":"Checking SPT version","command":"spt --version","cwd":".","timeout":30}},{"type":"toolCall","id":"call_HeCCWVzZkZ1XsNvgRO0x9MSU|fc_096c3410d482b50e016a5891da228c819ba4dfd04e497359d2","name":"bash","arguments":{"i":"Checking adapter status","command":"spt adapter --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_aWZwgp0indUqsA9jcksqvnMq|fc_096c3410d482b50e016a5891da2298819ba524d6b4ba483381","name":"bash","arguments":{"i":"Inspecting bind contract docs","command":"spt how-to --help","cwd":".","timeout":30}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2374,"output":396,"cacheRead":100864,"cacheWrite":0,"totalTokens":103634,"reasoningTokens":199,"cost":{"input":0.01187,"output":0.01188,"cacheRead":0.050432,"cacheWrite":0,"total":0.074182}},"stopReason":"toolUse","timestamp":1784189392446,"responseId":"resp_096c3410d482b50e016a5891d0c9a4819ba840de2f3dc75b9d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_096c3410d482b50e016a5891d2ec40819bb0e60d4304916678","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJHasPmxfNPxicAbXQp2EAqcLOdf9719k_Lke4Pz3RV9DVNtS4oeGM2_q8MnbaGsugbizAStMGenRjEpJHoPprNYKMuoK35SFqPy7JJBJn93zSsnhxIHj3SlHSky_56n0L9JcwxQbLtZGlPfIDKl7OIQ2itKnUxBiKpQLO_xzqa3vy6vhL-sxgaSsBB3Q2mU2J9tNiXOosDhQIxtYe5_1U9K5D-b3J7opLOqb-TcQ3SGaYN5QuEUw_-o61s2sO6VJ4AOMBLts3QMbL5TYPBgukd7p5DaaIo-o-OZDwb_WNDHr1W1K2p1kUm1WGlu1EaVlJHDgH64NhBU8w3m6KSRc8LjzCEK1EWv53XbjQ4eedH2TjDqa7V-bgc1622IOKxTKI-_Sm1J-XMPVUtUsEIy2pUHPfX8D4GQ7mIiurQuuWhg_Xx1z246ZMvQHhvm3glqJQNBvhC8zQU1k5n29y4xsHWKZeIXhPHiNjglHYNN4WVpdxzqcxNi0jC6YVJU6EQkZ27Dp_xjFpZ2y_bqMctSlmVG86KN0wQ8LZKtCKnZ0R6Xocta6LJdxbaxyAa7kGnpSrPgn82E4Is2KdsgB0qBiywP5iItaTvP_h2tUvKyZi_4fzMmiSbZXk5KO9lDHyJxrMD6tQ4djELzQn8HyVHw3ohz3AB2HX6L8WQyQkNdsiV2fYv9orsMFNMaY_Du0LztGWEwbJiEOcZPh8r0zBwfTTTaIDV9mASEAtKC79qcZyC708g_30SBVM4-CoCNf--VlcozlGkIXiJc8vWZEl_DbPEjr3Hv4agRqEDQz4_mDU5t6yIBsuUsDrhXfFuWJGlmQCmOoT0cjj3IPB6TsPZav064oMEu3Lv2Z6ZtZtwSOVLODza1lsreVoXnJuDhM-LfGF58UGUgGmqLmDA8E4wfcD0Yp4V2m-tc5He4A3SJEF7PHlt7OWnO4hXurDeqRlf_upQvI0T81g6VUmD30E68CtP7qsCV4trmhOjdqsEmpLsW_wPYfdYHd5XqmYQqhALO6YOTjHFgJv59tYVS9bA4Fea4umoCRk73mcKhOGXfF-7bjaZlmVKBpPja_wTY4yuMtE79L8Z2Ecxn5B1Cxfki4boOw1e4sII4ooRMnfUoEHWFGO-B6iNxrt7DJ41dZkP40szmQ6OOQ0QSjNcodw1K9ffx4JHwQ44IK5bkIunORzksUZfjKczMl6e7_5MmqjdR3bX7NWkQAAuAlRYcu2AxzN91g2Xx1txz78wx7fDzotXqty9nv6cVUtLPTU38cnqVIu2Nj9Vc5OE4Ri8zYMXcOSL5Hfb4FG9UUu6bvwgew6GY1BP5TAu-bURF3EosXVnrIjakI3pbgSOz8R3nvR5C5bzF8Z57UmhJi3Pno2-ynUia7eW94Xc_rSb0Agt4NY_quUY3Po_EmJgVCw9pTfmi5k4I4dp2vcWTElp97tAK6scthOKMeJOChdMKUy9PZdzemxKF7eFNM7wl9KwUvSleCWqMPz7f74b5jjfwYSrYbsAwhtLk4q1cKluOGuZcMeLundIM_nb_ZzK-cpiyD0GkmdIouP-d7nYRhSMpIcg3I4zwDJ8rlsNjdZ8bDlOJNf8fr4F6I_ofHvhgYxRv2nF0owzzKeKOrsYwb-Ubz_ym9GFc2Od9Tsv2xd5RyYuUlC0wcV-P9IUuuULKymNdD8xE_F3cn2tQpmSzBX39LuxSrkgTqDUWq5B_sBcHJCl79SdJqHisj_vCzeomiHHBCNALf3wJsud47idsdssiDXJOjnhlV6tFp8W3lXYORmzErF3x2sFBPf1XEwfv0sJkXXwmdGkXk-dK4PRoR5NzyNVhO6rplHd4YGp61-yeZr250AqFwbaohxHUtBhRmfYnqacN17ad50Kei9GFN6zRGJvJI3z603h2t9Fu_KfjkdLVVJpChK7cO4FHijZkEgIx3x0IFmO7s7CyqDqpIZKiUvW3xpKZfOIzTJEfe_SoOIQRbiOcMT5gSdRvzb9a-HiNRlWiqplK7H_9Mwe2hNf_rKA_hQvZuqk=","summary":[{"type":"summary_text","text":"**Investigating api bind endpoint types**"},{"type":"summary_text","text":"**Listing endpoints with full details**"}]},{"id":"fc_096c3410d482b50e016a5891da2240819baf027caab4969ba7","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting endpoint JSON\",\"command\":\"spt --json endpoint list --show-all\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_EHZyOscjpON4Iq8kr9q8V2b9","name":"bash"},{"id":"fc_096c3410d482b50e016a5891da2254819b81e34f536632ae05","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting capability output\",\"command\":\"spt --json api --adapter omp-spt capability\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_UbrX4HbljFnqXAphp8WPuMMp","name":"bash"},{"id":"fc_096c3410d482b50e016a5891da225c819b83da0ba7f58ddbb8","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking SPT version\",\"command\":\"spt --version\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_m7UxGoxrIcbFklefLLEShqPd","name":"bash"},{"id":"fc_096c3410d482b50e016a5891da228c819ba4dfd04e497359d2","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking adapter status\",\"command\":\"spt adapter --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_HeCCWVzZkZ1XsNvgRO0x9MSU","name":"bash"},{"id":"fc_096c3410d482b50e016a5891da2298819ba524d6b4ba483381","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting bind contract docs\",\"command\":\"spt how-to --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_aWZwgp0indUqsA9jcksqvnMq","name":"bash"}]},"duration":9961.342399999965,"ttft":2474.405299999984,"contextSnapshot":{"promptTokens":103238,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_EHZyOscjpON4Iq8kr9q8V2b9|fc_096c3410d482b50e016a5891da2240819baf027caab4969ba7","toolName":"bash","startedAt":"2026-07-16T08:10:02.418Z","args":{"command":"spt --json endpoint list --show-all"},"intent":"Inspecting endpoint JSON"},"id":"0ce46a4b","parentId":"c7e65564","timestamp":"2026-07-16T08:10:02.418Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_UbrX4HbljFnqXAphp8WPuMMp|fc_096c3410d482b50e016a5891da2254819b81e34f536632ae05","toolName":"bash","startedAt":"2026-07-16T08:10:02.441Z","args":{"command":"spt --json api --adapter omp-spt capability"},"intent":"Inspecting capability output"},"id":"28bd10ef","parentId":"0ce46a4b","timestamp":"2026-07-16T08:10:02.445Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_m7UxGoxrIcbFklefLLEShqPd|fc_096c3410d482b50e016a5891da225c819b83da0ba7f58ddbb8","toolName":"bash","startedAt":"2026-07-16T08:10:02.445Z","args":{"command":"spt --version"},"intent":"Checking SPT version"},"id":"d0d6cd88","parentId":"28bd10ef","timestamp":"2026-07-16T08:10:02.445Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_HeCCWVzZkZ1XsNvgRO0x9MSU|fc_096c3410d482b50e016a5891da228c819ba4dfd04e497359d2","toolName":"bash","startedAt":"2026-07-16T08:10:02.445Z","args":{"command":"spt adapter --help"},"intent":"Checking adapter status"},"id":"2d21f23f","parentId":"d0d6cd88","timestamp":"2026-07-16T08:10:02.445Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_aWZwgp0indUqsA9jcksqvnMq|fc_096c3410d482b50e016a5891da2298819ba524d6b4ba483381","toolName":"bash","startedAt":"2026-07-16T08:10:02.445Z","args":{"command":"spt how-to --help"},"intent":"Inspecting bind contract docs"},"id":"d9d001dd","parentId":"2d21f23f","timestamp":"2026-07-16T08:10:02.445Z"}
{"type":"message","id":"1c9d3e39","parentId":"d9d001dd","timestamp":"2026-07-16T08:10:03.279Z","message":{"role":"toolResult","toolCallId":"call_aWZwgp0indUqsA9jcksqvnMq|fc_096c3410d482b50e016a5891da2298819ba524d6b4ba483381","toolName":"bash","content":[{"type":"text","text":"Task-oriented instructions for agents: how-to <topic>.\n\nThe binary's own usage guidance, written for an agent to read and follow. Bare how-to lists the\ntopics.\n\nUsage: spt.exe how-to [OPTIONS] [TOPIC]\n\nArguments:\n  [TOPIC]\n          The topic to print (omit to list available topics)\n\nOptions:\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.76 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":763.375100000063},"isError":false,"timestamp":1784189403278}}
{"type":"message","id":"b57ee978","parentId":"1c9d3e39","timestamp":"2026-07-16T08:10:03.279Z","message":{"role":"toolResult","toolCallId":"call_m7UxGoxrIcbFklefLLEShqPd|fc_096c3410d482b50e016a5891da225c819b83da0ba7f58ddbb8","toolName":"bash","content":[{"type":"text","text":"spt 0.32.0\n\n\nWall time: 0.77 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":766.5079999999143},"isError":false,"timestamp":1784189403279}}
{"type":"message","id":"7d59eb7e","parentId":"b57ee978","timestamp":"2026-07-16T08:10:03.280Z","message":{"role":"toolResult","toolCallId":"call_HeCCWVzZkZ1XsNvgRO0x9MSU|fc_096c3410d482b50e016a5891da228c819ba4dfd04e497359d2","toolName":"bash","content":[{"type":"text","text":"Adapter registration: what this node can drive/launch.\n\nThe node-local registered set (one command for harness and shell adapters). Feeds creation-time\nadapter selection, shell discovery, and the self-update ripple.\n\nUsage: spt.exe adapter [OPTIONS] <COMMAND>\n\nCommands:\n  add              Register an adapter from a local path (a dir holding manifest.toml, or the\n                   manifest file itself) or from GitHub (--github user/repo, cloned under\n                   adapters/_github/). Manifest-first: an invalid manifest registers nothing.\n                   Install is the first update — the declared [update] avenue is conducted once\n                   after recording\n  remove           Soft-deregister: hidden from new-creation/discovery; existing and live instances\n                   keep running. The manifest's optional uninstall template is conducted only with\n                   --force until quiesce detection lands\n  list             List registered adapters (active and soft-deregistered), each followed by its\n                   shipped + local profiles as composite options\n  version          Print a registered adapter's declared version — the [adapter].version from its\n                   manifest. Resolves the option's merged view like the other adapter commands; exit\n                   1 if the adapter is not registered\n  create-profile   Create (or overwrite) a local profile — a node-local sparse overlay\n                   registered beside the adapter that survives adapter add re-registration. The\n                   overlay TOML is read from --from <file> or piped stdin (empty = a placeholder\n                   profile to populate later with set-string). Refuses a name shadowing a shipped\n                   profile, an invalid name, or an overlay that loosens a consent floor — nothing is\n                   written unless every check passes\n  delete-profile   Delete a local profile. Refuses a shipped profile name (adapter-owned,\n                   immutable) and errors if no local file exists\n  get-string       Read a [strings] dot-path from an adapter option's merged view\n                   (<adapter>[:profile] <key.path>). Resolves through the profile overlay like\n                   every other consumer; prints the value (strings raw, else JSON). Exit 1 if the\n                   key is unset. Strings are data — never executed\n  digest-proof     Prove an adapter's [digest] extractor against a real log sample. Runs the\n                   declared extractor over --sample <log> (or the declared source) and prints the\n                   parsed contract records, the rendered digest, and every dropped line with its\n                   reason — the author-time answer to \"spt endpoint digest returns nothing\" (no\n                   silent empty). Exit 1 if any line drops or nothing parses\n  translate-proof  Prove an adapter's [message-idle-translation-binary] against an inbound event.\n                   Spawns and feeds the declared translation binary exactly as the daemon does at\n                   idle-delivery — sends the init line then the --event envelope and reads back\n                   the emitted keystroke-command stream ({key}/{text}/{delay_ms}/{commit}),\n                   printed author-readable. This is the EMIT half ONLY: it proves the binary's\n                   spawn-feed-emit contract; it does NOT exercise the daemon's atomic PTY apply or\n                   controller buffering. Fills {id} and {session_id} into the envelope the same\n                   way the daemon does (use --session to pin the session id). Exit 1 if the binary\n                   fails to spawn, emits nothing, emits no commit, or emits an unparseable line\n  set-string       Set a [strings] dot-path on a local profile (<adapter>:<profile>). Sugar\n                   over editing the overlay file; refuses a shipped profile and a bare option (a\n                   local target is required — create-profile first)\n  update           Update registered adapters that ship from their own GitHub releases: compare each\n                   [update] avenue = \"gh_release\" adapter's latest release version against the\n                   installed one and, when newer, fetch the release archive, verify it against the\n                   declared signing key if any (else trusting HTTPS + GitHub), and re-register. With\n                   no name, sweeps every gh_release adapter; with a name, updates just that one\n  use              Set or clear the active-profile pointer — the default <adapter>[:profile] a\n                   harness session binds to when no --adapter is given. spt adapter use\n                   <adapter>[:profile] points every host binary the adapter declares at it (run\n                   once per host binary you support); --clear <adapter|binary> drops the pointer\n                   (resolution falls back to the freshest-registered adapter). Never changed by\n                   install or update\n  help             Print this message or the help of the given subcommand(s)\n\nOptions:\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.77 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":766.3124000000535},"isError":false,"timestamp":1784189403280}}
{"type":"message","id":"352afe27","parentId":"7d59eb7e","timestamp":"2026-07-16T08:10:03.301Z","message":{"role":"toolResult","toolCallId":"call_UbrX4HbljFnqXAphp8WPuMMp|fc_096c3410d482b50e016a5891da2254819b81e34f536632ae05","toolName":"bash","content":[{"type":"text","text":"LiveAgent\nReadyAgent\n\n\nWall time: 0.79 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":791.2124000000767},"isError":false,"timestamp":1784189403300}}
{"type":"message","id":"b5ae1bc0","parentId":"352afe27","timestamp":"2026-07-16T08:10:29.676Z","message":{"role":"toolResult","toolCallId":"call_EHZyOscjpON4Iq8kr9q8V2b9|fc_096c3410d482b50e016a5891da2240819baf027caab4969ba7","toolName":"bash","content":[{"type":"text","text":"{\n  \"self\": {\n    \"id\": \"emphasys\",\n    \"status\": \"ready_agent\",\n    \"ready\": true,\n    \"alive\": true,\n    \"unbound\": false,\n    \"description\": null,\n    \"psyche_host_error\": null\n  },\n  \"subnets\": [\n    {\n      \"name\": \"SPT_DEV\",\n      \"endpoints\": [\n        {\n          \"id\": \"chert\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        },\n        {\n          \"id\": \"deployah\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        },\n        {\n          \"id\": \"doyle\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        },\n        {\n          \"id\": \"emphasys\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"ready_agent\",\n          \"project\": \"github-com-bigscreenvr-omp-spt\"\n        },\n        {\n          \"id\": \"flynn\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-sabermage-spt-mobile\"\n        },\n        {\n          \"id\": \"hertz\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"ready_agent\",\n          \"project\": \"projects\"\n        },\n        {\n          \"id\": \"lia\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": \"Multipurpose subnet liaison for user Reavo.\",\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"projects\"\n        },\n        {\n          \"id\": \"mobile-gw\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"gateway\",\n          \"project\": \"projects\"\n        },\n        {\n          \"id\": \"perri\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-omp-spt\"\n        },\n        {\n          \"id\": \"todlando\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"ready_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        }\n      ]\n    },\n    {\n      \"name\": \"BIGNET\",\n      \"endpoints\": [\n        {\n          \"id\": \"Librarian\",\n          \"node\": \"f7afcc8292cbc441e8fe2002299cd37cde2a315e4073b47cee61c66f1473eda4\",\n          \"node_label\": \"Athenaeum-Library\",\n          \"status\": \"Dormant\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-athenaeum\"\n        },\n        {\n          \"id\": \"chert\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        },\n        {\n          \"id\": \"deployah\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        },\n        {\n          \"id\": \"doyle\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        },\n        {\n          \"id\": \"emphasys\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"ready_agent\",\n          \"project\": \"github-com-bigscreenvr-omp-spt\"\n        },\n        {\n          \"id\": \"flynn\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-sabermage-spt-mobile\"\n        },\n        {\n          \"id\": \"hertz\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Offline\",\n          \"resources\": null,\n          \"endpoint_type\": \"ready_agent\",\n          \"project\": \"projects\"\n        },\n        {\n          \"id\": \"lia\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": \"Multipurpose subnet liaison for user Reavo.\",\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"projects\"\n        },\n        {\n          \"id\": \"mobile-gw\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"gateway\",\n          \"project\": \"projects\"\n        },\n        {\n          \"id\": \"perri\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"github-com-bigscreenvr-omp-spt\"\n        },\n        {\n          \"id\": \"slammie-n\",\n          \"node\": \"f15d837bdeff3d56f5d5a21bdcd6acb9632a764cb13c477cad966ccb811be884\",\n          \"node_label\": \"GRAVITY-NVDA-PC\",\n          \"status\": \"Dormant\",\n          \"resources\": null,\n          \"endpoint_type\": \"live_agent\",\n          \"project\": \"projects\"\n        },\n        {\n          \"id\": \"todlando\",\n          \"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",\n          \"node_label\": \"HFENDULEAM\",\n          \"status\": \"Active\",\n          \"resources\": null,\n          \"endpoint_type\": \"ready_agent\",\n          \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n        }\n      ]\n    }\n  ],\n  \"local\": [\n    {\n      \"id\": \"chert\",\n      \"state\": \"live_agent\",\n      \"address\": null,\n      \"ready\": true,\n      \"alive\": false,\n      \"unbound\": false,\n      \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n    },\n    {\n      \"id\": \"deployah\",\n      \"state\": \"live_agent\",\n      \"address\": null,\n      \"ready\": false,\n      \"alive\": false,\n      \"unbound\": false,\n      \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n    },\n    {\n      \"id\": \"doyle\",\n      \"state\": \"live_agent\",\n      \"address\": null,\n      \"ready\": true,\n      \"alive\": true,\n      \"unbound\": false,\n      \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n    },\n    {\n      \"id\": \"emphasys\",\n      \"state\": \"ready_agent\",\n      \"address\": \"127.0.0.1:61088\",\n      \"ready\": true,\n      \"alive\": true,\n      \"unbound\": false,\n      \"project\": \"github-com-bigscreenvr-omp-spt\"\n    },\n    {\n      \"id\": \"flynn\",\n      \"state\": \"live_agent\",\n      \"address\": null,\n      \"ready\": false,\n      \"alive\": false,\n      \"unbound\": false,\n      \"project\": \"github-com-sabermage-spt-mobile\"\n    },\n    {\n      \"id\": \"hertz\",\n      \"state\": \"ready_agent\",\n      \"address\": null,\n      \"ready\": false,\n      \"alive\": false,\n      \"unbound\": false,\n      \"project\": \"projects\"\n    },\n    {\n      \"id\": \"lia\",\n      \"state\": \"live_agent\",\n      \"address\": null,\n      \"ready\": true,\n      \"alive\": true,\n      \"unbound\": false,\n      \"project\": \"projects\"\n    },\n    {\n      \"id\": \"mobile-gw\",\n      \"state\": \"gateway\",\n      \"address\": \"127.0.0.1:49582\",\n      \"ready\": true,\n      \"alive\": true,\n      \"unbound\": false,\n      \"project\": \"projects\"\n    },\n    {\n      \"id\": \"perri\",\n      \"state\": \"live_agent\",\n      \"address\": null,\n      \"ready\": true,\n      \"alive\": true,\n      \"unbound\": false,\n      \"project\": \"github-com-bigscreenvr-omp-spt\"\n    },\n    {\n      \"id\": \"todlando\",\n      \"state\": \"ready_agent\",\n      \"address\": null,\n      \"ready\": true,\n      \"alive\": true,\n      \"unbound\": false,\n      \"project\": \"github-com-bigscreenvr-spt-bs-core\"\n    }\n  ]\n}\n\n\nWall time: 27.17 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":27167.708500000066},"isError":false,"timestamp":1784189429676}}
{"type":"message","id":"5f4a969f","parentId":"b5ae1bc0","timestamp":"2026-07-16T08:10:49.549Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Analyzing live identity auto-resume logic**\n\n**Investigating session ID usage for auto-resume**\n\n**Examining on-disk user state for recency**"},{"type":"thinking","thinking":"**Clarifying session identity handling**\n\n**Planning auto-resume identity confirmation**"},{"type":"toolCall","id":"call_nXzICxwpnq0XpW4ghfXYjl2p|fc_04ff8e9472d37d5b016a58920850c4819a935c5e2126a41c61","name":"grep","arguments":{"i":"Finding activation contract details","pattern":"auto-resume|--auto|/ready|/live|most-recent|identity guessing|shortform|@<","path":"CONTEXT.md;SCOPE.md;docs;*.md;tests;adapter","selector":null,"case":false,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":4999,"output":991,"cacheRead":102912,"cacheWrite":0,"totalTokens":108902,"reasoningTokens":904,"cost":{"input":0.024995000000000003,"output":0.02973,"cacheRead":0.051455999999999995,"cacheWrite":0,"total":0.106181}},"stopReason":"toolUse","timestamp":1784189429853,"responseId":"resp_04ff8e9472d37d5b016a5891f638dc819ab83146e86d73518f","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_04ff8e9472d37d5b016a5891f78da0819a8a1035aee068d387","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJIBH3TtN3KUZ68Zluw3_OtvcCuTrr_Ah9YfzGX_MgDBdmcm0d7JiFqX-kv6_m1ZXGsJ8DVA-RYH0w5twCfba7kyGLsjTdiOaOdVOmYA5k2_vDoYdRZGDSYCZBIGgcRGxvm-i_nSQnCqHV3bloIcc3nw-hHwEnptFV2HHKX2WjG3i4zJ24vZsjNMO5I53xBbu2jpdwPNKFTFf_ecSIfiadVL1MwiHPKCUONuCUNoKU3LKoqJza0QglgQhm769RPUIYNQCegVigMR-wpGGefccot-nQaQ09uDrDsALBxKjQWAnlDl1KzithxIeleIpCGKtGIfd-Rm_2_3_06wHqyuepUxCa-1FBLfGCUoVTb74DImPcOn09CJt5dXQADavoEFLit_iF8eEPqbd5pG2MBJ2BU-YUHYsCtbaF0xkjfLjxDKKlHri7g4Z6MFF4QutiUAaYFcvDIpCPss3EdfPhLCl8SUfo8eeooNK84dow1NnLlhgmzVANMEd5U68MT9lFk0K47EtwL4t1dviw7InmBM2_J2qrbCKkGKZv2TeCpfWxceVz4mJRgnDVjWIHTniflue1mwHGuYdFyD1nQV1azaHboH8bWW68szLNVPnCCUcazP_RnC_z19duGYAN8ja2b6Vpv5A2_GxR6DFPIl0MD0vtBBpQjp1eyINUdNkNcRNYVTsYQEGkeYeJgsZH9qxQ12ZPn7An-bJVqxeZ339TE4MbqvKQO1sj4WegRJSPw906A7DZ94nBJYf-ow-YsesvTZAXpNiEUY2fQWTsYgPB0Vdr6n5vGc9WeUwwJbw79pyqRlPkFYFvLQjRt7lVPJ7DnqDtjFYiKXh_E6-H5wKTAXgO8KuDlQHCV9sGN3akweU-kTg5PZd2BfJFKKON7HtdTnN8E5j1-5t02pzdVuUl1uaOniFOp4hPSibVc2GTIHY9SCZkCOLBSJpDfHeggMSIW99HiV0QkuHPJliJlD6CwNhTlGgFmRbF31b55Dd4j0aiHGPKZMfoZA4vXSsQFQtAGjAMnNttcP4eoPcxPp6gho1EUlmlVxBGbCdt4bRvgX4y_PNQfbKRurvdSXQ4b9RIMKGNhd77F7GpjHkf1RTo-nGQtm1wIfL8CfRD929yXOpqi97dZ_tTRMP7SPJODGc-PNE59XOdOirBRHYUadkZ9mqHXIH2-m-VPOHQ5HCcPHd_pk5jw3iHp4SuJPYIhfZfTupgboD9_4pbIYsmwjnjfL2T25Uf_au2wI5L4LrqvdY9OmMZnHWYlr9PHzmHVhXLkeRZlsBCZpSJpF69k0W_DU_kI754u3yp2_Md8tnvkGXifgqc7iDJFQWHToI6YLFnFR2WpiHrKDk0PMX2oVMLEtlX4OXfrZEfUaZctgkCWQnXre_pPBW6M8L8yGHhmaVGpMGqtMmRCqgwZCuThxM7OVrVvD_aFB60QiaXYzg5NKDwnAyAx8dhnLplmGOY2SYM6CZCod0I0ibw7nwlsOKKKPwsV6DIs8ywF3gewSdQiIbzO90tJze8nlcppoc6wdP23oprRpWDzqfPQpn8g020MhK09BRM8KPQazpPX2aj-mUrvfFkUmpbI4o9stCXyhf8uG6Y8m93z4iOnrb8EM59i-4JB3Y2Vx6EcTqj9Bpl8FGeYwyjB519qEEyS_wE06bjrB4I71lkDrrI3zwlgfKTYLwlS9rY5xvt8MMNt-YOuREUDp833I_u_Q91bMBiPfUB4VCjxauYulX9B9cRabB8N1RIz2hvPafL-rBnqgMADB51dDVz6z9Q8gX72x2Q40sR4OwBWUnFPsLMuo2k6BxFVxRZ1kBOrOReV5iOR0qh_7hFXlvW45DQLTRhpc0YTASqDYh6D82_UPgNwcEnpRmUn3M19qwXKecdGw3S-CUxnSOqYjlFIS9jPBoNJJhg5MPyp2CqCC3C7WB_K1LpKM1PnPHir6IiJ3zTyMLGNEro0sx173OdFIg7F6I5mSI-9FYj5Zpnq-dmZQi0dcwxG6Iiwa4td3uGMxNqPSR6wIWiGWs_o92n2lyFK3XKwHgZEqdofHUoAYTISgK6sO5WoKk0UdAnN2tM-49pV8LnKcym7xIR6FSak3cN-ZPkosW4CR57Lm4vdYZsPclLFYdcVy3bK-nFudYqo-zToeK1FhtNgvls_izFtbeOeIlAv7G58qvHxGXep7o6KU3kngHcZOG1L6EQMUwoc5MU1JDb1D6Ntziint3-vYUUoFBXacZ5aYk2LBlVWXaa_BBrneWQtyWZJ6byYJ_FUKQRnHcHiWX7Zdkvr1egM9ZH8jRfL20M6T-EqUCM0vwxJXCwqFBlZhRGbWhKfsjhid3B9gy1DTcJNiOImOnFO2La_jqrY7UdCUjYt225bQMMna236SX0UPRYi6R3xxYKp6Vxk9Xbw7UxLGU01LBhDb6woct3GgAd8ZJ8luf-r8sp1iskHvqwXOrlUS35SQIPtd__SGRDVfDytndEsLaYXVa9Ikug1jq9TVcT4fBOgYasxTBFLFzHKGy8Lqc40Em9WG1zbFZ9zT6yR4PwVyNidDL_k7pDAoSIQ7dzsnY0QQ4YP4ePjLySIV_s_4jd14TDJb6FslvXYAMx45OZPHAm0wyEdShYdUKnWoMRKbza6MTbJMJ_sYa1ZWzsm0HOOnBoKG87pyr43OWbSJz6F0zQXC_SQhGYnEJGO1jVBMOrF_3h_x6iS2OrODVzkcPgj4jkFDet2u4Wgm--4rb1yuwqx7tVXB1n8iRjN6zrogbtmBMtWGeoYpQ0_Q22cxfCBwfTNYnn4QOfKJOrDLJVUDZZ1INcI0fWB8zNPUpQlAcA3bpAXxCY1vkL-9HhKBNDM68ae7L7goltuTE-Bd4O92UxsdVdiuETWsRtT07hKqFojGnAGbv8dXO9nT3oepQwH_inG7tNAPk3kht62dnjJX3vrgxkZPGy9HzMj6Xr8la-QRYLiqtzH5k0BaSvOZnup0TOHT7Ux1jSUCvkpwpGD0huCKYtYDq1gNO6c-YYKpOh-vF9el702188gbCFdsZoi3HWbQf7Y07Q07J8O33gMb5rbCQi4_SS-_3qYphJ_UfCRZCnqc7nwuRHh2YHlB6W4UQvkplJ_TP2-_XFLWgm_-p6Q5tpPKWqRfASgfseQiAEed8nEjpCApVVN87jdiBVXoDBl6A-IlpBqCeCxwv4dXOMaXD2YTNTp_OHn8onLdiLV2fmvJ40X8oOMRBbon0IImGJN3jm_sKg-2_R5U7jIvsPB77d3HHd-zXUWkXajQR-XfAG1h2DJUe6Tt7QRNMezMWAG6G94hbq5l8mMhR7_NCLzJQYj_btXNXbKx3tdj3NDZYf2E8NS3lbEykJfKlY8SECrltVNb3uEjLFi8iA6ZazlEUrCwdBb1X1hcpxqzVX-Oti7hpl6ZuQ50F5QYtn9AGLxmKUGgRlFKRf10G0ZbHoJ0X7rviV2TwhYEAHx7bEqMrfiWZ0WmDjHU396mf9Al0Vk7FB3II-3hmZn7ZMFc82oXFAhDehWJ0XyFvpCuWnvVw-8e7v-MlySNFl4_7oP-Fq4gVPxkafCLzpAD50SFSmPx_JZLFV_WewArEM82cSBAcKkofYrS5U5gJu4qJ8SG7CQIFcqrcHJInruy_SJ_ta50XYxgrf1cuDXPLOcFrbZzZx5H7I9uZAO34jfg4MWyAl1HPt0KUgFR76m2jKz3zjqw3Pz8bo8qPZH07wXsjyjZ6v_QtvX4eHqFigIX94-exnReRTk5TpOoY8sBIcgYn8DbYpF6fuPEus11vFIfKKfduRVxguWJLiHtUjIgC7r9moAIeN5x7DFFOyT-LOx2nnHbVwhEXKIlkiTPZRZYVlDcbxiPferqjoXcq_YBU4vLK_P_C9ihq8760bjFUVPB9uJ-9YLXG-wu7RKJtxC88qa3ot1zmRzHQAFZ5CO7AwwfhLe-H4aB3ypvJ-51LSZnPx749oe51De0yObIRnkcz8-J1pJcg4Ltm0FloT5g5mzjW783ogXDv19vj1mFj5F79JiK4SttvA4YwzKMa622267otojUp2uf6MuksbI8USE86nrNwXX1h-L3NGBbZlpCVJKdzCoVo8DezTDJecsERTbw","summary":[{"type":"summary_text","text":"**Analyzing live identity auto-resume logic**"},{"type":"summary_text","text":"**Investigating session ID usage for auto-resume**"},{"type":"summary_text","text":"**Examining on-disk user state for recency**"}]},{"id":"rs_04ff8e9472d37d5b016a58920149c8819a812bc3471dc68367","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJIIGnZlocl8jKWIx7LwJkJiw544lwi04ZfO5XFC-DNavGFWqRGiHJqWBlenQOYpeRkWEVw3Ruh_D2ATTknMgqkmjHYd0qjjKy0g-jbSHjj3hUw-O_2oq4r1swhZOvKiZn0Ub3rPy-OqZOPl1P2_4cHrbUs7eBun9OduTeGbFMlP5_L910Hy2WjFnxBdLWOqoTYF0fZqi6xbui3a91E9inV2rDBftmI6m4bIC_oehqvmK_eh_79E02x3QJYXTe0a05SmPDti9-Ml9tIPTpa_-kinhrXbqGkn5rC_v6njHBJs7NIQgNCc-JjzYzlQYBk8AYUC2bsZhZ4rqC2_9eWrOxbIM06DaFyEM0PVO0LtnxkZL2D5mHogxSCO0ZFJGVR_Eg7NZfa3532tbyvPkgESU7pyyY5SeFGZvoF4SvsiBZImsueKbq6TmiL_NtapQWe9UlcwFpdhvx7nQOxsNuCQGNL8AiBo9ZK5rVM0iRdW-HxkMbSZoR-8omdjnxnjbehRwkM6pFZW2a0OovGkSOXkduCXu3xK2gw9jjgX1HOEAO1nrgSfmsg2fOJJ5SjDkoK4jlbPMZGPKZqfS7wAznz1ZFNvBgSj6O9qv5zkMx07cF2LKbQdHZqMxO-ltKL9B1c-5lbtRkfLu_atS9KkBLkXoh39z3coVk_9hz4PX7308FZh-4ciwRvYPzHXmReeVHMmkHu8j02k9nlD4f1v0f9TmwlZRII6KADUm-7BAqp4jT_YmqH8Rk2qVyeBDjJzXQVQaVt7PCyqdMFOBNO0KcvLEfAu7SnAumM2bWg9xh9SHZPeOQ0AssGlofICCtRryz1T1Mo5YhfMqKsjWoY4oqZLpqFMdU2Dm1QzgegyIElt7XHuA-MCUvv3uQX60_mo65L4ar4rcYnPp8ARFmFIaI4_chHN-F9qe-YOm2KQQGEo0ACP2syui3Rd7ntoTn85avTzQO2teB3ehNGp6wzZ4cbXFLixlttTk1aUJNBuQTHmKQBzjQ9sN0VH2W3SKCDn2MzJQvxY4220mlSpejJeW3eQsqx8kowVE49VES9-OIzyDAfuNg6-dwGWcyMrsbg-xfiWXu6hdwD9Al0tye03f4loUpWOW_NZWa5AZ1cPoWHlMpWCg-C8sMGKHjbIhbiXxe9LguxvKBvISN407R6zrHp7Wj4y8xaPnedQIb7NNW9agagxRmv7PUssjNwn7eSc4UcNe-GDFUWzZaeUcUuV_L0kGnyAbK25Srn1K8WxTtGhU-laWO3khV6XKCT9LzJOeb3imzR4mYsSdfDzVVIfcqIsnaPWzZmhLDIqOqBg0EWtfDkK3AIk1mHKdtG3xZdzpL0aC8waw3ZfIn-wUnhF7wUTwTaw4zId1jxQPtxtg429EGP06Ta4p3ApdvMfKo5Y84AP7AUmyquqtSfXQsaWZVVRImJsENvKXArstFnYDHHjsZC7bRQuzCHQQuoNi8okqw-fYtocj_qlSUeo7YV3hWoJV5TVejQVby6oQ845y6Rsfh3I0FAsiDrF15Mwdgq1f6qjgjOXmXs-iEeY1DPsGYMu-YWp3_sFJXnzv07cvQR7qLY8G2uH74Of4uNd44gPD0jwIIG7s9qw0SuaIOVxrQpl1jVJDh7uI_Kg-ILSawH54DIvoEQNU4sJxhgVBwLSGNy1hSXfm-NHXdTyI00hISSzys37hJb5CD5TPRFm_aQB2f4R8V0zAW--7jL1NpRCJWSwLkBtYFU6JOe134tw9Shagitqze36l3Q46mIFWLe_4SNNK0t2gbgvtVlZFJoF6P06UwEoRM5-bjl3Hb1G_EyK5ZbkIh2ycVYXyqRtyuEJ8Jui8PrheURDHD7UzxXZfSCorpJtTju8VMzjRlb8awEobBWuAuhBHlt5AH2uWDdygRyAoQdd5oxPPJh7M23wB8PH17MMO9YZORrbRh4tab23VniSSf2tkHejIgrz42XHKt38qPvK2J7stdDgETTFg7W1C_hsPldOD-ugxPSNnrx46RYpLTBAJFIDlkhgvh_PRXf-iYSblw4o9p_S99JhIt1bzQrT4GNbZieGBusGDOlXsncPTUfXvqrOlVuN0nmGYgfie10LVfnFGxTA4oy0FejAtTNxK-H_vpmjvFqcpw0Q8439o5jgvtcBa4YKJwxMWrkSmxOFTuCk1rpCsQ0XIowdCkX3Ln0R4UBpEPzdfVzMB-auEt2F_0Bpn0j4hLzq8cR6l2GGWOwsj4l1H0P3vyEqIhaqls-tKeC_1BrJ9sUPwHApxsT5b62PeZDKxSVocqmSU6PeDCG49_7KOMPWHJRQbrkTZZsOGhjSn3LH2Af-xYAOc_Njez7DU2GiML1Qtc0WzkJO5lw6EWyGdLBzq1pFKELIhMMMlia-t6gb5Yki8ye7WzPRGhKh-AXFxbsOsm_lqb6wm98EabsylD_puhbQIpjrM6TjszdTINYYos_jM2xUo3fkedWJz2Fgz3tWEF9kAVR6yx4Z-igd9MhiEzt_2jl17JGc92CY5qQI2rDl7XEWNdI__Nwn25VV5SWUDEQn8Yx4-AsaIrTzx4Ai-FkfYCeWw8iMsX0Cdn5sybYr6mnwTkwRYMvRPgQPHR97iEqoOy072O3nJ_2adFHE4GNYn_9QWDFDZcA2SKmsM5WkBa-iJMgdfHS9jnA_fOEhRDChxiQHlmTEs8q_duL24nhuoUFlVQAIC1zXXni3nFdTVA7AjH2710dWKGcwDN0jK-eTef_R_zJ2B7Su_i8ZSB85xSgwytFjzvxFQjJF3rCHWiSU5ERYWOh-YImsPcLo6UddvHoQf15P_HYkug33X0h4CB4LD5LNwSXZLbiKcsZ2N4cR2E7DTBQGRl4s0vFT98_VQXyVU-vidtur7fXfo91h1rsgPe15N5SEK6JxsCGVvNgyZx0rmzAFoMT6h6d7XHpCHwjq0r_EEWqGkSzX4RH0Zp83HtzzCgh-OO9dNuxDn3GyBVWU0Yj0O45r5vej-tfjivF-czZZroGw7MOq6Nr7o5dxD16FbO2-4Cj6JoaRkbwGY4t5eBJn-xHGkJ_-gVVO3C_qfxQpCCQ0HIOBR8lvUH5SEyGNarapxIcsoKbkpKQdVKxMEEnCBH7l4xutl-qUIWp1WOr0H-wa5sebJ-fnNoyZk0yaqFwnqxreuFoesx-rKc6RRbk0EXyXFFW5KxeXb1YQAvkJADFWKkXJq46TdZeP9MPNPJzoUroCU5kxDliG8oJSGG-NMBPDkEmkd9zmdyjxYtYx9vj1L8m09zcINqbD77bJLbtGVcwfyyE0rYPIHQLqs0-Zg-HeVp0WIG1dl9sHe3VD8a2P3Gae_GnK_MYUHMPX0RN-53rPZBy4EE9hYyw84t1mdqrVx_OR_lIh51Nq5djVEiuw5e8WoIpb3DuvOATY275MPjb5UZQrb49WTbnYfRihxAoFu4yPNsHPATngmox9pKyqtUxnvhN7BpSvxmauoth-N-kY2b46TLAD0Q==","summary":[{"type":"summary_text","text":"**Clarifying session identity handling**"},{"type":"summary_text","text":"**Planning auto-resume identity confirmation**"}]},{"id":"fc_04ff8e9472d37d5b016a58920850c4819a935c5e2126a41c61","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding activation contract details\",\"pattern\":\"auto-resume|--auto|/ready|/live|most-recent|identity guessing|shortform|@<\",\"path\":\"CONTEXT.md;SCOPE.md;docs;*.md;tests;adapter\",\"selector\":null,\"case\":false,\"gitignore\":true,\"skip\":null}","call_id":"call_nXzICxwpnq0XpW4ghfXYjl2p","name":"grep"}]},"duration":19694.346100000083,"ttft":4434.911399999983,"contextSnapshot":{"promptTokens":107911,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_nXzICxwpnq0XpW4ghfXYjl2p|fc_04ff8e9472d37d5b016a58920850c4819a935c5e2126a41c61","toolName":"grep","startedAt":"2026-07-16T08:10:49.549Z","args":{"path":"CONTEXT.md;SCOPE.md;docs;*.md;tests;adapter"},"intent":"Finding activation contract details"},"id":"612b3c40","parentId":"5f4a969f","timestamp":"2026-07-16T08:10:49.549Z"}
{"type":"message","id":"01256c15","parentId":"612b3c40","timestamp":"2026-07-16T08:10:49.929Z","message":{"role":"toolResult","toolCallId":"call_nXzICxwpnq0XpW4ghfXYjl2p|fc_04ff8e9472d37d5b016a58920850c4819a935c5e2126a41c61","toolName":"grep","content":[{"type":"text","text":"# CONTEXT.md#76E6\n 39:\n*40:**live auto-resume** — an explicit session-activation path that selects the\n*41:most-recently-active compatible live endpoint when no endpoint id is supplied.\n 42:Outside that explicit path, activation requires selecting or creating an id and\n 43:never guesses identity silently.\n*44:_Avoid_: implicit most-recent selection, deriving identity from the OMP session\n 45:\n 46:**delivery custody** — the interval after an OMP SPT extension accepts an\n 47:inbound SPT message and before it either returns a correlated answer or reports\n...\n 113:\n*114:**peer-message shortform** — the explicit assistant-output form\n*115:`@<target[,target] message @>` that dispatches the enclosed message to the named\n 116:SPT endpoints after the OMP turn. It is a deliberate side effect, not ordinary\n 117:prose containing an `@` mention.\n 118:_Avoid_: harness-specific alternate syntax, implicit mention dispatch\n\n# SCOPE.md#A974\n 53:6. **Capability parity**\n*54:   - Extension-native ready/live activation for already-open OMP sessions,\n*55:     including explicit live auto-resume and extension-owned listener custody.\n 56:   - Safe-boundary delivery during active turns and automatic receivability\n 57:     restoration after abnormal turn termination.\n 58:   - Startup briefs, targeted hints, compatible-update notices, packaged\n 59:     commune/signoff/role/setup skills, native checkpoint continuity, and the\n*60:     cross-harness peer-message shortform.\n 61:   - OMP-native provider/profile routing satisfies alternate-routing parity.\n 62:   - Windows x86-64, GNU Linux x86-64, and static Linux x86-64 musl helper\n 63:     targets, each with durable machine-readable release evidence.\n...\n 83:must prove discovery from the installed `adapter.spt` layout. Deterministic\n*84:lifecycle infrastructure remains extension-owned: ready/live activation,\n 85:binding, listener custody, delivery, activity, and shutdown are not delegated\n 86:to model-executed skills.\n 87:\n\n# CHANGELOG.md#67E7\n 80:### Fixed\n*81:- **The message shortcut no longer cries \"not delivered\" when it actually delivered.** Sending with `@<peer …@>` would tell you the peer \"wasn't reachable\" even though the message had arrived — so you'd needlessly re-send by hand. The delivered/not-delivered confirmation is now correct. (Messaging to yourself was never affected.)\n 82:\n 83:### Changed\n*84:- **Communes now file project detail under the project, not your permanent identity.** When you commune (or when a session is auto-summarized), detail specific to the project you're in is kept separate from your cross-project, standing context — so your durable memory stays clean and project notes don't bleed between projects. Wrap project detail in `<project-context>…</project-context>` and identity/role context in `<live-context>…</live-context>`; anything left untagged is treated as standing con...\n 85:\n 86:## [0.17.2] - 2026-07-08\n 87:\n...\n 90:### Fixed\n*91:- **A message shortcut written as the last thing in a reply now actually sends.** Previously, if the `@<…@>` tag (or a `>>commune<<`) was the very last output of a turn — the normal \"fire it off and wait for a reply\" case — it wasn't delivered until you next did something, so a send-then-wait could hang. It's now delivered the moment the turn ends, for both live and daemon-hosted agents. Tags written mid-reply were unaffected and still work.\n 92:\n 93:## [0.17.1] - 2026-07-08\n 94:\n...\n 97:### Fixed\n*98:- **The message shortcut no longer fires when you're just *talking about* it.** In 0.17.0, writing an example of the `@<…@>` form in a reply — even wrapped in backticks — could actually send it. Now a tag only sends when written plainly; any tag inside inline-code (backticks) or a code block is treated as a quotation and ignored. Write a real send bare; show an example in backticks.\n 99:\n 100:## [0.17.0] - 2026-07-08\n 101:\n...\n 104:### Added\n*105:- **Message another agent without leaving your train of thought — no shell command needed.** Write `@<alice hey, can you check the deploy? @>` anywhere in a reply and the adapter delivers \"hey, can you check the deploy?\" to `alice`, then tells you (in your next context) whether it landed or the agent wasn't reachable. Send to several at once with `@<alice,bob,carol …@>`. Only that exact `@<…@>` form sends, so you can still talk *about* the syntax without firing anything.\n 106:- **Save a working-context note the same way.** Start a message with `>>commune<<` and the rest becomes your commune (the context hand-off that survives a reset) — the same result as writing the commune file by hand, without the file step. Include `!!checkpoint!!` in it to also reset-and-rebuild your context from that note.\n 107:\n 108:## [0.16.2] - 2026-07-08\n...\n 461:- **Linux support.** The adapter ships native **Windows and Linux** builds; `/sptc:setup` detects your OS and installs the right one.\n*462:- **ccs integration.** If you use [ccs](https://github.com/kaitranntt/ccs), `/sptc:setup` wires the shipped `claude-spt:ccs` profile so live/ready agents can run on your ccs backends instead of `claude`.\n 463:- **Private-network onboarding.** `/sptc:setup` now offers to create or join a private network (subnet) so you can pair machines and reach agents across them.\n 464:\n 465:## [0.1.0] - 2026-06-15\n\n# CHECKPOINT-COMMUNE-PLAN.md#1DCB\n 49:STDOUT (inject VERBATIM as SessionStart additionalContext):\n*50:  <live-role>…</live-role>                       (if a role authored; else omitted)\n*51:  <live-context>…</live-context>                 (durable agents/<id>/live-context.md)\n 52:  <project-context-resolved name=\"<proj>\"/>      (sentinel — present iff in a resolved project)\n 53:  <project-context>…</project-context>           (durable projects/<proj>/<id>/project-context.md)\n 54:  <pending-commune>…raw drop body…</pending-commune>   (ONLY if not-yet-synthesized; TRIGGER STRIPPED core-side)\n\n# CPLUGS-PREP-PLAN.md#DE6B\n 7:\n*8:`plugin/sptc/.claude/LIVE_AGENT_IDS.json` — live perch runtime state (my `perri` id) was **tracked\n*9:into the publishable skeleton**: the root `.gitignore` pattern `.claude/LIVE_AGENT_IDS.json` is\n 10:root-anchored and missed the nested `plugin/sptc/.claude/`. A published skeleton must carry ZERO\n 11:runtime/agent state. → untrack + depth-safe ignore + a validator gate so it can't recur.\n 12:\n...\n 31:   gate actually catches breakage, not just green-on-green. [unit->REQ-DIST-PLUGIN-SKELETON]\n*32:4. **Hygiene fix**: `git rm --cached plugin/sptc/.claude/LIVE_AGENT_IDS.json`; depth-safe\n*33:   `.gitignore` (`**/.claude/LIVE_AGENT_IDS.json` etc.).\n 34:5. **Wire** the validator as a new deterministic gate in `ci/run-gates.sh` (\"skeleton-validate\").\n 35:6. **traceable-reqs.toml**: flip `REQ-DIST-PLUGIN-SKELETON` → `[\"doc\",\"impl\",\"unit\"]`; add\n 36:   `ci/publish` to `[scan].roots`.\n\n# HANDOFF.md#1531\n 80:The complete legacy inventory (claude_skill_owl v1.11.25: 7 CC hooks, 12 `/spt:*` skills, the\n*81:messaging/live-agent/working-perch surfaces, marketplace packaging, CC-specifics like JSONL\n 82:transcript parsing and parent-pid binding) is the parity reference. **It has been triaged**\n 83:into DROP / TRANSFORM / KEEP / ADD buckets in `SCOPE.md` → \"Parity-trim\". Seed your\n 84:`traceable-reqs.toml` from those buckets:\n 85:\n*86:- **KEEP** (port the user-facing skill): `/live` `/commune` `/ready` `/send` `/signoff`\n 87:  `/force-stop` `/new-alarm` `/list-agents`.\n 88:- **DROP** (do not port): `/revive`, `/clear-psyche`, `/whoami` (skill), `/fork`,\n 89:  `amend-signoff`, Spine/Touch, legacy psmux Capsule, binary-handoff, the TCP/spool/registry\n\n# NEXT-WORKLOAD-PLAN.md#3DB0\n 89:> id → `NO_PERCH` surfaced in the confirm-back (delivered = SENT/QUEUED/DEFERRED). **Live int OWED:**\n*90:> dogfood on a bounced endpoint (`@<peer …@>` actually delivers + confirm-back lands; `>>commune<<`\n 91:> ingests). **Next: Items 3–5.**\n 92:\n*93:- **Trigger (explicit-only, multi-target):** `@<t1,t2,t3 body @>` — `@<`, comma-separated ids (no\n 94:  internal spaces), first whitespace ends the target list, body until first `@>` (non-greedy, no\n 95:  escaping v1). Bare `@@id` rejected (any prose discussing the syntax would false-fire).\n 96:- **Source:** `endpoint digest <self> --after <cursor> --json`; scan `turns[].entries[].Agent.text`.\n...\n 110:  **Collision rule:** once `>>commune<<` is detected, the rest of the output is commune body and is NOT\n*111:  scanned for `@<…@>` (meta-recursion guard).\n*112:- **Doc:** teach `@<…@>` in the `/sptc:send` skill doc as a shortform alternative to the CLI.\n 113:- **Requirements:** `REQ-TAG-PEER-MESSAGING` · `REQ-COMMUNE-OUTPUT-SHORTCUT` (+ meta-recursion\n 114:  suppression sub-assert).\n 115:\n\n# PARITY-PUBLISH-PLAN.md#5DEE\n 23:|--------------------------------|--------------------------|------------------------|--------------------------------|\n*24:| /live /commune /ready /send    | KEEP                     | operative (file-backed)| ✓ none                         |\n 25:| /list-agents /signoff /force-stop | KEEP                  | operative              | ✓ none                         |\n 26:| /new-alarm                     | ACCEPTED GAP (deferred-pending-arrangement-system) | dead stub, no manifest | **remove stub**; no REQ, no build |\n 27:| /spt:setup /spt:version        | ADD                      | operative              | ✓ none                         |\n*28:| profiles + strings + hints     | ADD                      | wired (deep/live)      | ✓ none                         |\n 29:| **subnet skills (create/join/show-code)** | ADD (LOCKED)  | **ABSENT**             | **BUILD** (Phase C)            |\n 30:| **ccs profiles (claude-spt:glm …)** | ADD (LOCKED)        | **ABSENT**             | **BUILD** (Phase D)            |\n 31:| /whoami SKILL                  | DROP skill               | **operative (violation)** | **REMOVE** (Phase B)        |\n\n# PREP4-PLAN.md#B59C\n 24:   = \"0.9.0\"`; rewrite the stale base=ReadyAgent/:live-activates comments to the Option-A model.\n*25:2. **adapter/strings/skills/live.md**: bringup → single persistent Monitor task running bare\n 26:   `spt api listen <id>` (NO seed-chain, NO `--adapter`, NO `--manifest`). SessionStart already seeded\n 27:   the perch agnostically; listen resolves claude-spt by pid→host_binaries and the live path stamps\n 28:   state=live_agent. Strip the PREP-4 interim note + all `:live` composite refs. Keep OUTPUT\n...\n 35:   stay valid (override profile).\n*36:5. **plugin/sptc/skills/live/SKILL.md**: stub text — drop the \"activates claude-spt:live profile\"\n 37:   claim; base is now live-capable, the listen command actualizes.\n 38:6. **ci/manifest/registration-int.sh**: drop `:live`-profile assertions (profile deleted); keep the\n 39:   `skills.live` file-string check (that's the skill KEY, not a profile).\n*40:7. **ci/psyche/live-relay-int.sh**: `A=claude-spt:live` → `claude-spt`; seed/listen drop `--adapter`\n 41:   composite (bare or base). Asserts psyche hosts off the BASE manifest + live listen path.\n 42:8. **traceable-reqs.toml**: rewrite REQ-SKILL-LIVE title/notes to the Option-A model (base\n 43:   psyche_init + command-decides, no :live profile). Fix line-180 \":deep/:live\" comment.\n\n# SESSIONSTART-BRIEF-PLAN.md#FD1B\n 74:\n*75:- When doyle ships `spt whoami --json {id,kind,...}`: add live/ready identity flavor\n 76:  (Psyche/commune line for live).\n 77:- Cleaner peer signal (`spt subnet status --json`/count) would retire the line-count\n 78:  gate — fold into the same doyle ask if cheap.\n\n# SETUP-SLICE-PLAN.md#4A80\n 154:  (SPTC_ACCEPTANCE=1), both PASS live on spt 0.7.3; `traceable-reqs check` green.\n*155:- **DONE (2026-06-16):** the live relay int (REQ-SKILL-LIVE int) — `ci/psyche/live-relay-int.sh`.\n 156:  F-007 resolved to a docs-gap (not a missing feature): the non-interactive live bringup is a\n 157:  PERSISTENT child `spt api --adapter claude-spt:live --manifest <claude-spt.toml> listen <id>` (the\n 158:  Monitor surrogate, heir to `$LIVE start`) — NOT `endpoint run`, NOT `--once`. With `--manifest` the\n 159:  in-process listen path spawns the Psyche. Asserts BOTH legs live on 0.7.3: `PSYCHE_SPAWNED` +\n*160:  relayed `<EVENT>` + BOUND/READY + live_agent kind. Gotchas baked in: WINPID anchor (not `$$`),\n 161:  `bind` before `send`. REQ-SKILL-LIVE flipped to [doc,impl,unit,int].\n 162:- **Remaining:** per-OS `adapter.spt` assets · LOCKED v1 setup {1..7} later waves · (on doyle) the\n 163:  post-M11 `how-to live` topic → re-point /sptc:live step 2 at the canonical guidance.\n\n# SKILLS-SLICE-PLAN.md#A7D6\n 112:  command construction + blank-pulse guard); `ci/psyche/build.sh` gate wired into run-gates.\n*113:- `adapter/strings/skills/live.md` authored; manifest `live` inline → `{ file }`; psyche_init comment\n 114:  updated (runner built, propagation confirmed); live SKILL.md stub refreshed (operative).\n 115:- REQ-SKILL-LIVE added + satisfied [doc,impl,unit]; int deferred (daemon Psyche loop staged behind\n 116:  REQ-DAEMON-1/M11-W0 + Monitor relay needs a real live CC session). registration-int.sh updated\n\n# SPT_HARNESS_ADAPTER_TIPS.md#CF70\n 68:  - **SubagentStart/Stop** → `api worker-start`/`worker-stop`.\n*69:  - The **blocking listen/poll loop is a `/ready` or `/live` skill, never SessionStart** — a hook\n 70:    that blocks would hang session bringup.\n 71:- **Message delivery is stdout framing.** `api poll` emits the self-delimiting envelope\n 72:  `<EVENT type=\"msg\" from=\"<sender>\">body</EVENT>` (also used for the live listener stream).\n\n# docs/\n## PARITY.md#2CFD\n 26:<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n*27:<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\n*28:Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n 29:commands with argument completion or native selection dialogs. Explicit live\n*30:auto-resume selects the most-recent compatible live identity; ordinary\n 31:activation never guesses silently. The extension binds the current session and\n 32:owns the authenticated listener, after which binding is immutable.\n 33:\n...\n 68:\n*69:<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\n*70:Assistant output may dispatch the explicit cross-harness peer-message shortform\n*71:`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\n 72:Normal outbound messaging, roster, stop/shutdown, version, and subnet commands\n 73:are taught through setup or startup context rather than duplicated as skills.\n 74:\n...\n 101:target, source commit and tag, artifact digests, acquisition result, and native\n*102:fresh/resume, message/reply, lifecycle, shutdown, and ReadyAgent/LiveAgent\n 103:acceptance outcomes.\n 104:\n 105:## Explicit non-goals\n...\n 122:   and injectable OMP event seams;\n*123:2. implement extension-owned ready/live activation, live auto-resume,\n 124:   safe-boundary delivery, and abnormal-turn receivability;\n 125:3. add startup briefs, targeted hints, update notices, packaged skills,\n*126:   checkpoint continuity, hybrid setup, and peer-message shortform;\n 127:4. add the musl target and durable machine-readable acceptance records for all\n 128:   supported targets.\n## SPT-CORE-FINDINGS.md#CCCF\n 27:\n*28:| F-023 | 2026-07-01 | **CONFIRMED + RCA'd (doyle, same day) — build dispatched to todlando (`BUILD-F023-WANIDLE`)**. Both ranked hypotheses real: `receive_wan` has deliver_tcp + spool ONLY (the spt-hosted broker-inject leg exists solely in local `cmd_send`) AND no idle-edge drain exists anywhere. Fix = shared inject leg called from WAN ingress + ACTIVE→IDLE spool drain. Adapter exoneration stands verbatim. `from_id=\"\"` sibling ruled: compose stamps `cli@<node-label>`; ingress renders empty-from as o...\n 29:| F-024 | 2026-07-01 | **CLOSED-REFRAMED (doyle, same day) — transport EXONERATED; symptom = F-023 on the remote node.** The `(spooled)` token in `SENT(WAN)` output is RECEIVER-CONFIRMED (only prints on a confirmed round-trip): probe `DIAG-7c1e` reached ENLYZEAM post-restart and sits in ball-b's spool undelivered (`spooled` not `delivered` = no live TCP listener at receive time). Operator workaround: any prompt typed into ball-b UPS-drains the stuck messages. Residues stay real as separate diagnostics ...\n*30:| F-031 | 2026-07-08 | **REPORTED to doyle (perri) — docs gap; adapter worked around in v0.17.3 (REQ-HAZARD-SEND-STATUS-STDERR).** `spt send`'s result token (`SENT:<id>` / `QUEUED:<id>` / `DEFERRED:<id>` / `NO_PERCH:<reason>`) is written to **STDERR**, not stdout — stdout is empty on a plain `spt send`. This is undocumented in the published harness-contract / CLI reference (they describe the tokens as the send's *result* without naming the stream). It bit the claude-spt tag-messaging hook: the hook c...\n 31:\n 32:> **F-021 / F-022 (NOT spt-core findings — claude-spt parity items, tracked as REQs; surfaced during the 2026-06-24 checkpoint-commune grill)** — (F-021) claude-spt polls only on `UserPromptSubmit` (between turns); legacy spt also polls+injects on **PreToolUse** = the mid-turn half of live-agent reachability (the main path by which a live agent receives a message WHILE working). `api poll` already exists on the public surface → adapter wiring, not an spt-core gap → **`REQ-DIST-PRETOOL-POLL`**. (F...\n 33:\n...\n 549:\n*550:**Why it matters for the adapter.** Our `/sptc:live` body (`adapter/strings/skills/live.md`) was\n 551:written to *defer* to `spt how-to live` as \"the canonical, always-current guidance\" and follow it —\n 552:the same pattern `/sptc:ready` uses for `spt how-to ready`. With no such topic, that step dangles on\n 553:a dead command, and the adapter must instead **inline** the live-bringup recipe (perch id → seed the\n...\n 596:    so `--once` was a red herring). Proven 2026-06-16: `BOUND` / `PSYCHE_SPAWNED:{id}-psyche pid=…` /\n*597:    `READY` / the probe relayed as `<EVENT>`. Shipped as `ci/psyche/live-relay-int.sh`\n 598:    (REQ-SKILL-LIVE int green).\n 599:  - Binary resolution: the psyche_init command's bare `claude-spt-psyche` resolves via the F-006 PATH\n 600:    interim on 0.7.3; on **v0.8.0 (Feature B / REQ-INSTALL-11)** spt resolves it against the\n...\n 729:    the lock-brick itself did NOT recur.)\n*730:- **Relay leg ✓** — `ci/psyche/live-relay-int.sh` green on 0.8.0: BOUND/READY + a probe relayed as the\n 731:  escaped `<EVENT>` off the listen child + live_agent kind. No `--manifest` needed.\n 732:\n 733:- **RESOLVED (v0.8.1 dogfood, 2026-06-16) — daemon-hosted psyche-spawn.** Two layered bugs, not the\n...\n 740:  epoch-ms:… incoming event: (none)` as 7 separate argv tokens. Fixed adapter-side (greedy `--prompt`,\n*741:  commit ddf1965); the Psyche now stays resident, `ci/psyche/live-relay-int.sh` psyche leg flips\n 742:  skip→ASSERT green, and **REQ-INSTALL-11 / F-006** is proven in the same run. The \"peer pump STALLED\"\n 743:  correlate recurs ~7-8 min after every daemon start but did NOT block hosting (a Psyche hosted fine\n 744:  with the pump stalled) — flagged to doyle as **F-010**-adjacent, separate from the host path.\n...\n 877:< 0.11.0 the `[env.SPT_ENDPOINT_ID]` inject is not substituted → endpoint-run silently SEEDS instead of\n*878:binding (no perch, no error). Ruling: **no min_spt_core floor-bump** (ready/live work on 0.9.0; a\n 879:blanket floor is too broad) and **no runtime guard** — a `< 0.11.0` endpoint-run spawn is\n 880:**env-indistinguishable** from a normal user-launched seed (both: `SPT_RELEASE_SEED` + `OWL_SESSION_ID`\n 881:set, `SPT_ENDPOINT_ID` empty — empirically verified on this node's own session), so any guard would\n...\n 1264:non-perch shell on ENLYZEAM; wan op `…:cli:6`) — the envelope renders `from=\"\"`. If CLI non-perch\n*1265:sends are legal, they should probably stamp something (`cli@<node>`?); if not, refuse loudly.\n 1266:\n 1267:**Status:** **CONFIRMED + RCA'd (doyle 2026-07-01, token `TRIAGE-F023-F024-CLOSED`) — build\n 1268:dispatched to todlando (`BUILD-F023-WANIDLE`).** Both ranked hypotheses real: `receive_wan` has\n...\n 1272:drained correctly the moment they ran; translate binary contract-correct and starved). The\n*1273:`from_id=\"\"` sibling is ruled: compose stamps `cli@<node-label>`, ingress renders empty-from as the\n 1274:origin node label, no refusal.\n 1275:\n 1276:**CLOSED END-TO-END — spt-core v0.20.0 (doyle release ping 2026-07-02).** WAN arrivals + the\n...\n 1278:stays valid but is no longer the only delivery trigger. The `from_id=\"\"` sibling shipped too:\n*1279:from-less CLI sends now arrive stamped `cli@<node-label>`, never blank. New loud field diagnostics\n 1280:in this area: `SPOOL_SENTINEL_CREATE_FAIL` (names the io::Error kind — will answer the ENLYZEAM\n 1281:`.has-messages` sentinel divergence on its next WAN arrival) and `IDLE_DRAIN` lines. Adapter side\n 1282:unchanged, as ruled.\n...\n 1551:daemon-coordinated apply` → swap actually landed); **(c) ENDPOINT SURVIVED:** probe still\n*1552:online/live_agent seconds after the swap. The F015B parent-aware matcher + unconditional swap\n 1553:HOLD on the real path — the composite-endpoint silent no-op is dead. The remaining F-025 wave\n 1554:item (broker-image version surface / BROKER_RESTART_REQUIRED / apply classifier) is unchanged\n 1555:by this green — it is what made attempt #1 invalid in the first place.\n\n## adr/\n### 0001-distribution-splits-by-volatility.md#4F3E\n 37:3. **The skill `/spt:` namespace must be preserved** (legacy parity). User-scope skills under\n*38:   `~/.claude/skills` cannot namespace (they surface as bare `/live`, collision-prone), so skills\n 39:   must stay **plugin-provided**.\n 40:4. **Users install mid-session**, so the plugin cannot assume a SessionStart fire has installed\n 41:   spt-core; the bootstrap and a `/spt:setup` skill must cover the gap.\n...\n 73:\n*74:- **Global user-scope skills** (`~/.claude/skills`) — lose the `/spt:` namespace (bare `/live`,\n 75:  collision-prone). Rejected.\n 76:- **fetch-stub skills** (SKILL.md fetches its real body at runtime) — VETOED by the operator:\n 77:  adds terminal noise, latency, and an extra tool call per invocation. UPS-injection chosen\n### 0003-psyche-is-a-constrained-auto-approving-companion.md#3886\n 38:4. **A proven reference exists.** The legacy sibling `claude_skill_owl`\n*39:   (`src/live/wrapper/claude.rs`) already solved this exact shape — its psyche init/resume/final\n 40:   invocations are uniformly sandboxed and auto-approving. Parity with that posture is the safe\n 41:   default, not a novel design.\n 42:\n### 0013-release-gate-stops-at-the-adapter-boundary.md#469B\n 4:\n*5:omp-spt uses layered verification: deterministic extension, manifest, session, digest/history, and daemon-role tests run on every change; a release additionally requires a real native OMP endpoint proving fresh bringup, attachable TUI, same-node message-to-turn-to-correlated-reply flow, busy/idle state, native resume, blocked in-TUI switching, graceful shutdown, and ReadyAgent/LiveAgent behavior. Cross-node messaging is not an adapter release gate: once the adapter has handed the same message contract to...\n### 0015-extension-owned-session-activation.md#95AE\n 6:\n*7:An ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension—not the model or an agent-started background process—binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session bind...\n### 0016-agent-capabilities-split-by-native-seam.md#7C69\n 6:\n*7:omp-spt selects a parity seam per capability rather than forcing every agent-facing outcome through one mechanism. Public OMP `omp-plugins` skills own model-driven commune (including checkpoint mode), signoff, durable-role, and setup-assistance workflows, with packaged-skill discovery proven from the installed release; extension-native commands own ready/live activation, while the extension retains binding, listener, delivery custody, activity, recovery, reply, and shutdown. A universal skill layer was r...\n\nShowing files 1-20 of 22. Use skip=20 for the next page, or narrow paths/pattern.\n\n[Some lines truncated to 512 chars]"}],"details":{"scopePath":"CONTEXT.md, SCOPE.md, docs, *.md, tests, adapter","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":63,"fileCount":20,"files":["CONTEXT.md","SCOPE.md","docs/PARITY.md","docs/SPT-CORE-FINDINGS.md","docs/adr/0001-distribution-splits-by-volatility.md","docs/adr/0003-psyche-is-a-constrained-auto-approving-companion.md","docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md","docs/adr/0015-extension-owned-session-activation.md","docs/adr/0016-agent-capabilities-split-by-native-seam.md","CHANGELOG.md","CHECKPOINT-COMMUNE-PLAN.md","CPLUGS-PREP-PLAN.md","HANDOFF.md","NEXT-WORKLOAD-PLAN.md","PARITY-PUBLISH-PLAN.md","PREP4-PLAN.md","SESSIONSTART-BRIEF-PLAN.md","SETUP-SLICE-PLAN.md","SKILLS-SLICE-PLAN.md","SPT_HARNESS_ADAPTER_TIPS.md"],"fileMatches":[{"path":"CONTEXT.md","count":5},{"path":"SCOPE.md","count":4},{"path":"docs/PARITY.md","count":9},{"path":"docs/SPT-CORE-FINDINGS.md","count":11},{"path":"docs/adr/0001-distribution-splits-by-volatility.md","count":2},{"path":"docs/adr/0003-psyche-is-a-constrained-auto-approving-companion.md","count":1},{"path":"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md","count":1},{"path":"docs/adr/0015-extension-owned-session-activation.md","count":1},{"path":"docs/adr/0016-agent-capabilities-split-by-native-seam.md","count":1},{"path":"CHANGELOG.md","count":6},{"path":"CHECKPOINT-COMMUNE-PLAN.md","count":2},{"path":"CPLUGS-PREP-PLAN.md","count":4},{"path":"HANDOFF.md","count":2},{"path":"NEXT-WORKLOAD-PLAN.md","count":4},{"path":"PARITY-PUBLISH-PLAN.md","count":2},{"path":"PREP4-PLAN.md","count":3},{"path":"SESSIONSTART-BRIEF-PLAN.md","count":1},{"path":"SETUP-SLICE-PLAN.md","count":2},{"path":"SKILLS-SLICE-PLAN.md","count":1},{"path":"SPT_HARNESS_ADAPTER_TIPS.md","count":1}],"truncated":true,"fileLimitReached":20,"displayContent":"# CONTEXT.md#76E6\n  39│\n *40│**live auto-resume** — an explicit session-activation path that selects the\n *41│most-recently-active compatible live endpoint when no endpoint id is supplied.\n  42│Outside that explicit path, activation requires selecting or creating an id and\n  43│never guesses identity silently.\n *44│_Avoid_: implicit most-recent selection, deriving identity from the OMP session\n  45│\n  46│**delivery custody** — the interval after an OMP SPT extension accepts an\n  47│inbound SPT message and before it either returns a correlated answer or reports\n    │...\n 113│\n*114│**peer-message shortform** — the explicit assistant-output form\n*115│`@<target[,target] message @>` that dispatches the enclosed message to the named\n 116│SPT endpoints after the OMP turn. It is a deliberate side effect, not ordinary\n 117│prose containing an `@` mention.\n 118│_Avoid_: harness-specific alternate syntax, implicit mention dispatch\n\n# SCOPE.md#A974\n 53│6. **Capability parity**\n*54│   - Extension-native ready/live activation for already-open OMP sessions,\n*55│     including explicit live auto-resume and extension-owned listener custody.\n 56│   - Safe-boundary delivery during active turns and automatic receivability\n 57│     restoration after abnormal turn termination.\n 58│   - Startup briefs, targeted hints, compatible-update notices, packaged\n 59│     commune/signoff/role/setup skills, native checkpoint continuity, and the\n*60│     cross-harness peer-message shortform.\n 61│   - OMP-native provider/profile routing satisfies alternate-routing parity.\n 62│   - Windows x86-64, GNU Linux x86-64, and static Linux x86-64 musl helper\n 63│     targets, each with durable machine-readable release evidence.\n   │...\n 83│must prove discovery from the installed `adapter.spt` layout. Deterministic\n*84│lifecycle infrastructure remains extension-owned: ready/live activation,\n 85│binding, listener custody, delivery, activity, and shutdown are not delegated\n 86│to model-executed skills.\n 87│\n\n# CHANGELOG.md#67E7\n  80│### Fixed\n *81│- **The message shortcut no longer cries \"not delivered\" when it actually delivered.** Sending with `@<peer …@>` would tell you the peer \"wasn't reachable\" even though the message had arrived — so you'd needlessly re-send by hand. The delivered/not-delivered confirmation is now correct. (Messaging to yourself was never affected.)\n  82│\n  83│### Changed\n *84│- **Communes now file project detail under the project, not your permanent identity.** When you commune (or when a session is auto-summarized), detail specific to the project you're in is kept separate from your cross-project, standing context — so your durable memory stays clean and project notes don't bleed between projects. Wrap project detail in `<project-context>…</project-context>` and identity/role context in `<live-context>…</live-context>`; anything left untagged is treated as standing con...\n  85│\n  86│## [0.17.2] - 2026-07-08\n  87│\n    │...\n  90│### Fixed\n *91│- **A message shortcut written as the last thing in a reply now actually sends.** Previously, if the `@<…@>` tag (or a `>>commune<<`) was the very last output of a turn — the normal \"fire it off and wait for a reply\" case — it wasn't delivered until you next did something, so a send-then-wait could hang. It's now delivered the moment the turn ends, for both live and daemon-hosted agents. Tags written mid-reply were unaffected and still work.\n  92│\n  93│## [0.17.1] - 2026-07-08\n  94│\n    │...\n  97│### Fixed\n *98│- **The message shortcut no longer fires when you're just *talking about* it.** In 0.17.0, writing an example of the `@<…@>` form in a reply — even wrapped in backticks — could actually send it. Now a tag only sends when written plainly; any tag inside inline-code (backticks) or a code block is treated as a quotation and ignored. Write a real send bare; show an example in backticks.\n  99│\n 100│## [0.17.0] - 2026-07-08\n 101│\n    │...\n 104│### Added\n*105│- **Message another agent without leaving your train of thought — no shell command needed.** Write `@<alice hey, can you check the deploy? @>` anywhere in a reply and the adapter delivers \"hey, can you check the deploy?\" to `alice`, then tells you (in your next context) whether it landed or the agent wasn't reachable. Send to several at once with `@<alice,bob,carol …@>`. Only that exact `@<…@>` form sends, so you can still talk *about* the syntax without firing anything.\n 106│- **Save a working-context note the same way.** Start a message with `>>commune<<` and the rest becomes your commune (the context hand-off that survives a reset) — the same result as writing the commune file by hand, without the file step. Include `!!checkpoint!!` in it to also reset-and-rebuild your context from that note.\n 107│\n 108│## [0.16.2] - 2026-07-08\n    │...\n 461│- **Linux support.** The adapter ships native **Windows and Linux** builds; `/sptc:setup` detects your OS and installs the right one.\n*462│- **ccs integration.** If you use [ccs](https://github.com/kaitranntt/ccs), `/sptc:setup` wires the shipped `claude-spt:ccs` profile so live/ready agents can run on your ccs backends instead of `claude`.\n 463│- **Private-network onboarding.** `/sptc:setup` now offers to create or join a private network (subnet) so you can pair machines and reach agents across them.\n 464│\n 465│## [0.1.0] - 2026-06-15\n\n# CHECKPOINT-COMMUNE-PLAN.md#1DCB\n 49│STDOUT (inject VERBATIM as SessionStart additionalContext):\n*50│  <live-role>…</live-role>                       (if a role authored; else omitted)\n*51│  <live-context>…</live-context>                 (durable agents/<id>/live-context.md)\n 52│  <project-context-resolved name=\"<proj>\"/>      (sentinel — present iff in a resolved project)\n 53│  <project-context>…</project-context>           (durable projects/<proj>/<id>/project-context.md)\n 54│  <pending-commune>…raw drop body…</pending-commune>   (ONLY if not-yet-synthesized; TRIGGER STRIPPED core-side)\n\n# CPLUGS-PREP-PLAN.md#DE6B\n  7│\n *8│`plugin/sptc/.claude/LIVE_AGENT_IDS.json` — live perch runtime state (my `perri` id) was **tracked\n *9│into the publishable skeleton**: the root `.gitignore` pattern `.claude/LIVE_AGENT_IDS.json` is\n 10│root-anchored and missed the nested `plugin/sptc/.claude/`. A published skeleton must carry ZERO\n 11│runtime/agent state. → untrack + depth-safe ignore + a validator gate so it can't recur.\n 12│\n   │...\n 31│   gate actually catches breakage, not just green-on-green. [unit->REQ-DIST-PLUGIN-SKELETON]\n*32│4. **Hygiene fix**: `git rm --cached plugin/sptc/.claude/LIVE_AGENT_IDS.json`; depth-safe\n*33│   `.gitignore` (`**/.claude/LIVE_AGENT_IDS.json` etc.).\n 34│5. **Wire** the validator as a new deterministic gate in `ci/run-gates.sh` (\"skeleton-validate\").\n 35│6. **traceable-reqs.toml**: flip `REQ-DIST-PLUGIN-SKELETON` → `[\"doc\",\"impl\",\"unit\"]`; add\n 36│   `ci/publish` to `[scan].roots`.\n\n# HANDOFF.md#1531\n 80│The complete legacy inventory (claude_skill_owl v1.11.25: 7 CC hooks, 12 `/spt:*` skills, the\n*81│messaging/live-agent/working-perch surfaces, marketplace packaging, CC-specifics like JSONL\n 82│transcript parsing and parent-pid binding) is the parity reference. **It has been triaged**\n 83│into DROP / TRANSFORM / KEEP / ADD buckets in `SCOPE.md` → \"Parity-trim\". Seed your\n 84│`traceable-reqs.toml` from those buckets:\n 85│\n*86│- **KEEP** (port the user-facing skill): `/live` `/commune` `/ready` `/send` `/signoff`\n 87│  `/force-stop` `/new-alarm` `/list-agents`.\n 88│- **DROP** (do not port): `/revive`, `/clear-psyche`, `/whoami` (skill), `/fork`,\n 89│  `amend-signoff`, Spine/Touch, legacy psmux Capsule, binary-handoff, the TCP/spool/registry\n\n# NEXT-WORKLOAD-PLAN.md#3DB0\n  89│> id → `NO_PERCH` surfaced in the confirm-back (delivered = SENT/QUEUED/DEFERRED). **Live int OWED:**\n *90│> dogfood on a bounced endpoint (`@<peer …@>` actually delivers + confirm-back lands; `>>commune<<`\n  91│> ingests). **Next: Items 3–5.**\n  92│\n *93│- **Trigger (explicit-only, multi-target):** `@<t1,t2,t3 body @>` — `@<`, comma-separated ids (no\n  94│  internal spaces), first whitespace ends the target list, body until first `@>` (non-greedy, no\n  95│  escaping v1). Bare `@@id` rejected (any prose discussing the syntax would false-fire).\n  96│- **Source:** `endpoint digest <self> --after <cursor> --json`; scan `turns[].entries[].Agent.text`.\n    │...\n 110│  **Collision rule:** once `>>commune<<` is detected, the rest of the output is commune body and is NOT\n*111│  scanned for `@<…@>` (meta-recursion guard).\n*112│- **Doc:** teach `@<…@>` in the `/sptc:send` skill doc as a shortform alternative to the CLI.\n 113│- **Requirements:** `REQ-TAG-PEER-MESSAGING` · `REQ-COMMUNE-OUTPUT-SHORTCUT` (+ meta-recursion\n 114│  suppression sub-assert).\n 115│\n\n# PARITY-PUBLISH-PLAN.md#5DEE\n 23│|--------------------------------|--------------------------|------------------------|--------------------------------|\n*24│| /live /commune /ready /send    | KEEP                     | operative (file-backed)| ✓ none                         |\n 25│| /list-agents /signoff /force-stop | KEEP                  | operative              | ✓ none                         |\n 26│| /new-alarm                     | ACCEPTED GAP (deferred-pending-arrangement-system) | dead stub, no manifest | **remove stub**; no REQ, no build |\n 27│| /spt:setup /spt:version        | ADD                      | operative              | ✓ none                         |\n*28│| profiles + strings + hints     | ADD                      | wired (deep/live)      | ✓ none                         |\n 29│| **subnet skills (create/join/show-code)** | ADD (LOCKED)  | **ABSENT**             | **BUILD** (Phase C)            |\n 30│| **ccs profiles (claude-spt:glm …)** | ADD (LOCKED)        | **ABSENT**             | **BUILD** (Phase D)            |\n 31│| /whoami SKILL                  | DROP skill               | **operative (violation)** | **REMOVE** (Phase B)        |\n\n# PREP4-PLAN.md#B59C\n 24│   = \"0.9.0\"`; rewrite the stale base=ReadyAgent/:live-activates comments to the Option-A model.\n*25│2. **adapter/strings/skills/live.md**: bringup → single persistent Monitor task running bare\n 26│   `spt api listen <id>` (NO seed-chain, NO `--adapter`, NO `--manifest`). SessionStart already seeded\n 27│   the perch agnostically; listen resolves claude-spt by pid→host_binaries and the live path stamps\n 28│   state=live_agent. Strip the PREP-4 interim note + all `:live` composite refs. Keep OUTPUT\n   │...\n 35│   stay valid (override profile).\n*36│5. **plugin/sptc/skills/live/SKILL.md**: stub text — drop the \"activates claude-spt:live profile\"\n 37│   claim; base is now live-capable, the listen command actualizes.\n 38│6. **ci/manifest/registration-int.sh**: drop `:live`-profile assertions (profile deleted); keep the\n 39│   `skills.live` file-string check (that's the skill KEY, not a profile).\n*40│7. **ci/psyche/live-relay-int.sh**: `A=claude-spt:live` → `claude-spt`; seed/listen drop `--adapter`\n 41│   composite (bare or base). Asserts psyche hosts off the BASE manifest + live listen path.\n 42│8. **traceable-reqs.toml**: rewrite REQ-SKILL-LIVE title/notes to the Option-A model (base\n 43│   psyche_init + command-decides, no :live profile). Fix line-180 \":deep/:live\" comment.\n\n# SESSIONSTART-BRIEF-PLAN.md#FD1B\n 74│\n*75│- When doyle ships `spt whoami --json {id,kind,...}`: add live/ready identity flavor\n 76│  (Psyche/commune line for live).\n 77│- Cleaner peer signal (`spt subnet status --json`/count) would retire the line-count\n 78│  gate — fold into the same doyle ask if cheap.\n\n# SETUP-SLICE-PLAN.md#4A80\n 154│  (SPTC_ACCEPTANCE=1), both PASS live on spt 0.7.3; `traceable-reqs check` green.\n*155│- **DONE (2026-06-16):** the live relay int (REQ-SKILL-LIVE int) — `ci/psyche/live-relay-int.sh`.\n 156│  F-007 resolved to a docs-gap (not a missing feature): the non-interactive live bringup is a\n 157│  PERSISTENT child `spt api --adapter claude-spt:live --manifest <claude-spt.toml> listen <id>` (the\n 158│  Monitor surrogate, heir to `$LIVE start`) — NOT `endpoint run`, NOT `--once`. With `--manifest` the\n 159│  in-process listen path spawns the Psyche. Asserts BOTH legs live on 0.7.3: `PSYCHE_SPAWNED` +\n*160│  relayed `<EVENT>` + BOUND/READY + live_agent kind. Gotchas baked in: WINPID anchor (not `$$`),\n 161│  `bind` before `send`. REQ-SKILL-LIVE flipped to [doc,impl,unit,int].\n 162│- **Remaining:** per-OS `adapter.spt` assets · LOCKED v1 setup {1..7} later waves · (on doyle) the\n 163│  post-M11 `how-to live` topic → re-point /sptc:live step 2 at the canonical guidance.\n\n# SKILLS-SLICE-PLAN.md#A7D6\n 112│  command construction + blank-pulse guard); `ci/psyche/build.sh` gate wired into run-gates.\n*113│- `adapter/strings/skills/live.md` authored; manifest `live` inline → `{ file }`; psyche_init comment\n 114│  updated (runner built, propagation confirmed); live SKILL.md stub refreshed (operative).\n 115│- REQ-SKILL-LIVE added + satisfied [doc,impl,unit]; int deferred (daemon Psyche loop staged behind\n 116│  REQ-DAEMON-1/M11-W0 + Monitor relay needs a real live CC session). registration-int.sh updated\n\n# SPT_HARNESS_ADAPTER_TIPS.md#CF70\n 68│  - **SubagentStart/Stop** → `api worker-start`/`worker-stop`.\n*69│  - The **blocking listen/poll loop is a `/ready` or `/live` skill, never SessionStart** — a hook\n 70│    that blocks would hang session bringup.\n 71│- **Message delivery is stdout framing.** `api poll` emits the self-delimiting envelope\n 72│  `<EVENT type=\"msg\" from=\"<sender>\">body</EVENT>` (also used for the live listener stream).\n\n# docs/\n## PARITY.md#2CFD\n  26│<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n *27│<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\n *28│Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n  29│commands with argument completion or native selection dialogs. Explicit live\n *30│auto-resume selects the most-recent compatible live identity; ordinary\n  31│activation never guesses silently. The extension binds the current session and\n  32│owns the authenticated listener, after which binding is immutable.\n  33│\n    │...\n  68│\n *69│<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\n *70│Assistant output may dispatch the explicit cross-harness peer-message shortform\n *71│`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\n  72│Normal outbound messaging, roster, stop/shutdown, version, and subnet commands\n  73│are taught through setup or startup context rather than duplicated as skills.\n  74│\n    │...\n 101│target, source commit and tag, artifact digests, acquisition result, and native\n*102│fresh/resume, message/reply, lifecycle, shutdown, and ReadyAgent/LiveAgent\n 103│acceptance outcomes.\n 104│\n 105│## Explicit non-goals\n    │...\n 122│   and injectable OMP event seams;\n*123│2. implement extension-owned ready/live activation, live auto-resume,\n 124│   safe-boundary delivery, and abnormal-turn receivability;\n 125│3. add startup briefs, targeted hints, update notices, packaged skills,\n*126│   checkpoint continuity, hybrid setup, and peer-message shortform;\n 127│4. add the musl target and durable machine-readable acceptance records for all\n 128│   supported targets.\n## SPT-CORE-FINDINGS.md#CCCF\n   27│\n  *28│| F-023 | 2026-07-01 | **CONFIRMED + RCA'd (doyle, same day) — build dispatched to todlando (`BUILD-F023-WANIDLE`)**. Both ranked hypotheses real: `receive_wan` has deliver_tcp + spool ONLY (the spt-hosted broker-inject leg exists solely in local `cmd_send`) AND no idle-edge drain exists anywhere. Fix = shared inject leg called from WAN ingress + ACTIVE→IDLE spool drain. Adapter exoneration stands verbatim. `from_id=\"\"` sibling ruled: compose stamps `cli@<node-label>`; ingress renders empty-from as o...\n   29│| F-024 | 2026-07-01 | **CLOSED-REFRAMED (doyle, same day) — transport EXONERATED; symptom = F-023 on the remote node.** The `(spooled)` token in `SENT(WAN)` output is RECEIVER-CONFIRMED (only prints on a confirmed round-trip): probe `DIAG-7c1e` reached ENLYZEAM post-restart and sits in ball-b's spool undelivered (`spooled` not `delivered` = no live TCP listener at receive time). Operator workaround: any prompt typed into ball-b UPS-drains the stuck messages. Residues stay real as separate diagnostics ...\n  *30│| F-031 | 2026-07-08 | **REPORTED to doyle (perri) — docs gap; adapter worked around in v0.17.3 (REQ-HAZARD-SEND-STATUS-STDERR).** `spt send`'s result token (`SENT:<id>` / `QUEUED:<id>` / `DEFERRED:<id>` / `NO_PERCH:<reason>`) is written to **STDERR**, not stdout — stdout is empty on a plain `spt send`. This is undocumented in the published harness-contract / CLI reference (they describe the tokens as the send's *result* without naming the stream). It bit the claude-spt tag-messaging hook: the hook c...\n   31│\n   32│> **F-021 / F-022 (NOT spt-core findings — claude-spt parity items, tracked as REQs; surfaced during the 2026-06-24 checkpoint-commune grill)** — (F-021) claude-spt polls only on `UserPromptSubmit` (between turns); legacy spt also polls+injects on **PreToolUse** = the mid-turn half of live-agent reachability (the main path by which a live agent receives a message WHILE working). `api poll` already exists on the public surface → adapter wiring, not an spt-core gap → **`REQ-DIST-PRETOOL-POLL`**. (F...\n   33│\n     │...\n  549│\n *550│**Why it matters for the adapter.** Our `/sptc:live` body (`adapter/strings/skills/live.md`) was\n  551│written to *defer* to `spt how-to live` as \"the canonical, always-current guidance\" and follow it —\n  552│the same pattern `/sptc:ready` uses for `spt how-to ready`. With no such topic, that step dangles on\n  553│a dead command, and the adapter must instead **inline** the live-bringup recipe (perch id → seed the\n     │...\n  596│    so `--once` was a red herring). Proven 2026-06-16: `BOUND` / `PSYCHE_SPAWNED:{id}-psyche pid=…` /\n *597│    `READY` / the probe relayed as `<EVENT>`. Shipped as `ci/psyche/live-relay-int.sh`\n  598│    (REQ-SKILL-LIVE int green).\n  599│  - Binary resolution: the psyche_init command's bare `claude-spt-psyche` resolves via the F-006 PATH\n  600│    interim on 0.7.3; on **v0.8.0 (Feature B / REQ-INSTALL-11)** spt resolves it against the\n     │...\n  729│    the lock-brick itself did NOT recur.)\n *730│- **Relay leg ✓** — `ci/psyche/live-relay-int.sh` green on 0.8.0: BOUND/READY + a probe relayed as the\n  731│  escaped `<EVENT>` off the listen child + live_agent kind. No `--manifest` needed.\n  732│\n  733│- **RESOLVED (v0.8.1 dogfood, 2026-06-16) — daemon-hosted psyche-spawn.** Two layered bugs, not the\n     │...\n  740│  epoch-ms:… incoming event: (none)` as 7 separate argv tokens. Fixed adapter-side (greedy `--prompt`,\n *741│  commit ddf1965); the Psyche now stays resident, `ci/psyche/live-relay-int.sh` psyche leg flips\n  742│  skip→ASSERT green, and **REQ-INSTALL-11 / F-006** is proven in the same run. The \"peer pump STALLED\"\n  743│  correlate recurs ~7-8 min after every daemon start but did NOT block hosting (a Psyche hosted fine\n  744│  with the pump stalled) — flagged to doyle as **F-010**-adjacent, separate from the host path.\n     │...\n  877│< 0.11.0 the `[env.SPT_ENDPOINT_ID]` inject is not substituted → endpoint-run silently SEEDS instead of\n *878│binding (no perch, no error). Ruling: **no min_spt_core floor-bump** (ready/live work on 0.9.0; a\n  879│blanket floor is too broad) and **no runtime guard** — a `< 0.11.0` endpoint-run spawn is\n  880│**env-indistinguishable** from a normal user-launched seed (both: `SPT_RELEASE_SEED` + `OWL_SESSION_ID`\n  881│set, `SPT_ENDPOINT_ID` empty — empirically verified on this node's own session), so any guard would\n     │...\n 1264│non-perch shell on ENLYZEAM; wan op `…:cli:6`) — the envelope renders `from=\"\"`. If CLI non-perch\n*1265│sends are legal, they should probably stamp something (`cli@<node>`?); if not, refuse loudly.\n 1266│\n 1267│**Status:** **CONFIRMED + RCA'd (doyle 2026-07-01, token `TRIAGE-F023-F024-CLOSED`) — build\n 1268│dispatched to todlando (`BUILD-F023-WANIDLE`).** Both ranked hypotheses real: `receive_wan` has\n     │...\n 1272│drained correctly the moment they ran; translate binary contract-correct and starved). The\n*1273│`from_id=\"\"` sibling is ruled: compose stamps `cli@<node-label>`, ingress renders empty-from as the\n 1274│origin node label, no refusal.\n 1275│\n 1276│**CLOSED END-TO-END — spt-core v0.20.0 (doyle release ping 2026-07-02).** WAN arrivals + the\n     │...\n 1278│stays valid but is no longer the only delivery trigger. The `from_id=\"\"` sibling shipped too:\n*1279│from-less CLI sends now arrive stamped `cli@<node-label>`, never blank. New loud field diagnostics\n 1280│in this area: `SPOOL_SENTINEL_CREATE_FAIL` (names the io::Error kind — will answer the ENLYZEAM\n 1281│`.has-messages` sentinel divergence on its next WAN arrival) and `IDLE_DRAIN` lines. Adapter side\n 1282│unchanged, as ruled.\n     │...\n 1551│daemon-coordinated apply` → swap actually landed); **(c) ENDPOINT SURVIVED:** probe still\n*1552│online/live_agent seconds after the swap. The F015B parent-aware matcher + unconditional swap\n 1553│HOLD on the real path — the composite-endpoint silent no-op is dead. The remaining F-025 wave\n 1554│item (broker-image version surface / BROKER_RESTART_REQUIRED / apply classifier) is unchanged\n 1555│by this green — it is what made attempt #1 invalid in the first place.\n\n## adr/\n### 0001-distribution-splits-by-volatility.md#4F3E\n 37│3. **The skill `/spt:` namespace must be preserved** (legacy parity). User-scope skills under\n*38│   `~/.claude/skills` cannot namespace (they surface as bare `/live`, collision-prone), so skills\n 39│   must stay **plugin-provided**.\n 40│4. **Users install mid-session**, so the plugin cannot assume a SessionStart fire has installed\n 41│   spt-core; the bootstrap and a `/spt:setup` skill must cover the gap.\n   │...\n 73│\n*74│- **Global user-scope skills** (`~/.claude/skills`) — lose the `/spt:` namespace (bare `/live`,\n 75│  collision-prone). Rejected.\n 76│- **fetch-stub skills** (SKILL.md fetches its real body at runtime) — VETOED by the operator:\n 77│  adds terminal noise, latency, and an extra tool call per invocation. UPS-injection chosen\n### 0003-psyche-is-a-constrained-auto-approving-companion.md#3886\n 38│4. **A proven reference exists.** The legacy sibling `claude_skill_owl`\n*39│   (`src/live/wrapper/claude.rs`) already solved this exact shape — its psyche init/resume/final\n 40│   invocations are uniformly sandboxed and auto-approving. Parity with that posture is the safe\n 41│   default, not a novel design.\n 42│\n### 0013-release-gate-stops-at-the-adapter-boundary.md#469B\n 4│\n*5│omp-spt uses layered verification: deterministic extension, manifest, session, digest/history, and daemon-role tests run on every change; a release additionally requires a real native OMP endpoint proving fresh bringup, attachable TUI, same-node message-to-turn-to-correlated-reply flow, busy/idle state, native resume, blocked in-TUI switching, graceful shutdown, and ReadyAgent/LiveAgent behavior. Cross-node messaging is not an adapter release gate: once the adapter has handed the same message contract to...\n### 0015-extension-owned-session-activation.md#95AE\n 6│\n*7│An ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension—not the model or an agent-started background process—binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session bind...\n### 0016-agent-capabilities-split-by-native-seam.md#7C69\n 6│\n*7│omp-spt selects a parity seam per capability rather than forcing every agent-facing outcome through one mechanism. Public OMP `omp-plugins` skills own model-driven commune (including checkpoint mode), signoff, durable-role, and setup-assistance workflows, with packaged-skill discovery proven from the installed release; extension-native commands own ready/live activation, while the extension retains binding, listener, delivery custody, activity, recovery, reply, and shutdown. A universal skill layer was r...","linesTruncated":true,"meta":{"limits":{"columnTruncated":{"maxColumn":512}}}},"isError":false,"timestamp":1784189449928}}
{"type":"message","id":"8c0d7705","parentId":"01256c15","timestamp":"2026-07-16T08:10:52.656Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Reviewing key CONTEXT definitions**"},{"type":"toolCall","id":"call_Xa7V8AwYfxHEyIKm2MfIbytf|fc_0de9481abcd295fe016a58920c3ff0819a97cd05d00a16eff4","name":"read","arguments":{"i":"Reading parity domain definitions","path":"CONTEXT.md","selector":"1-135"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":8741,"output":49,"cacheRead":107008,"cacheWrite":0,"totalTokens":115798,"reasoningTokens":15,"cost":{"input":0.043705,"output":0.00147,"cacheRead":0.053503999999999996,"cacheWrite":0,"total":0.09867899999999999}},"stopReason":"toolUse","timestamp":1784189450024,"responseId":"resp_0de9481abcd295fe016a58920a6b8c819aae041aed93c9cab5","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0de9481abcd295fe016a58920b9470819a9adf6e53136198b2","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJIMd-ly1iuA5LH9RzRGricdInpyhM1V0iOk5L0pTWc7aAgllJw233juT4m6OtjYCk6Jaft3Pt9Tl3OTEUrEaRLx0mIGj73380CN19qcYIlzn4Xv0FIwafCTKmHB1LeTnb0-Y-XiYact7yY2YrYk5t4CGCz92yYojjQEf1ST1qTjc_-ZYgLEPAPumtGJSUc9NiXjlZwRRXgrg-rJFwf0h32GpSbvRZ85rGLCEI-JGh6Uig8G8qrVLhbRnWR5jCbw0i9y5Hh7ysYiDO7co69wFn64O8mB7H0grtS8fw_2IvpCMe8oMAWeYjIuGKyRTx34N24WPC3o6lqskb578Xmd6QiXFkvu8vsWny8njYSFqYd0wMWe5fejPczNTFpYnxBOiJDnKOgEuTMW84GZy90JXA4cJfZdstd1PyHErXVtFZhf4b67lsaP5s59Z-GKqOcA8nXbNYKZtgKdc8BHNnP71Rnj52ZvK44e2jIQuyfwtlCne04fbcxRzf48Dp0-HVTmEjRTyUTV01PoFjV4UhPEfZug98qPItS8ntA7JsR9sYg4ePsuwbugp6igj32cnCxOWe1749BUQU_xc7QzLO3sWulzvXgzUtN8WALYjPrfA0XlUhTqMSEQ-19aQrsRWDV1bG2DW_xqPO26VfCnmcgFLHL1LXloQbjDsPlC3ROirA1_HV0yvxDFUhyd8dYbEEFbs42L1tuJu9Yfx2Bjnfu6tFnrYikQCJxriwyHqIeaBotRIfx5_oRvKsgAYRFfEfV4uNa13p5Wtr81x_jyo78JkyH8kcbw8L9b6FeHs4dEhnpGjzlb6XXpoqn-bROslGub4RO8wq0HAim4slsXU9pAx8lBUMspcHcJw-nI_4PzjeAST7rsHJPsEqkzFjCk0EnOTskuZ3CWfy837gbwneX2B0yGa0vdUxqaULf08EJA-vHY6bsF9sBXjYAWhgfLya0nmn_mA_VQlzN2MLGBp69ZGnvDFWnTNFPffdtVlVV8ZyZkTf0=","summary":[{"type":"summary_text","text":"**Reviewing key CONTEXT definitions**"}]},{"id":"fc_0de9481abcd295fe016a58920c3ff0819a97cd05d00a16eff4","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading parity domain definitions\",\"path\":\"CONTEXT.md\",\"selector\":\"1-135\"}","call_id":"call_Xa7V8AwYfxHEyIKm2MfIbytf","name":"read"}]},"duration":2631.475599999889,"ttft":1582.8926999999676,"contextSnapshot":{"promptTokens":115749,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Xa7V8AwYfxHEyIKm2MfIbytf|fc_0de9481abcd295fe016a58920c3ff0819a97cd05d00a16eff4","toolName":"read","startedAt":"2026-07-16T08:10:52.656Z","args":{"path":"CONTEXT.md"},"intent":"Reading parity domain definitions"},"id":"15c19a95","parentId":"8c0d7705","timestamp":"2026-07-16T08:10:52.656Z"}
{"type":"message","id":"0b53870e","parentId":"15c19a95","timestamp":"2026-07-16T08:10:52.666Z","message":{"role":"toolResult","toolCallId":"call_Xa7V8AwYfxHEyIKm2MfIbytf|fc_0de9481abcd295fe016a58920c3ff0819a97cd05d00a16eff4","toolName":"read","content":[{"type":"text","text":"[CONTEXT.md#76E6]\n1:# omp-spt — glossary\n2:\n3:> Authoritative for meaning (grill-with-docs convention). Glossary only — no\n4:> implementation detail. Decisions and rationale live in `SCOPE.md` and `docs/adr/`.\n5:\n6:## Product and topologies\n7:\n8:**omp-spt** — the OMP-native harness adapter for spt-core. The repository,\n9:registered adapter, and consolidated adapter executable share this identity.\n10:_Avoid_: spt-claude-code, claude-spt, omps\n11:\n12:**OMP** — the Oh My Pi terminal coding agent that omp-spt integrates with.\n13:Use **OMP** for the product or UI and `omp` for its executable.\n14:_Avoid_: Claude Code, CC\n15:\n16:**native OMP endpoint** — an spt-hosted endpoint where `omp` owns a broker-held\n17:terminal and loads the **OMP SPT extension**. It may run unattended, but its\n18:native TUI remains attachable whenever an operator needs to observe or control it.\n19:_Avoid_: RPC bridge endpoint, non-interactive endpoint\n20:\n21:**OMP SPT extension** — the OMP runtime extension that binds a native OMP\n22:session to an SPT endpoint and owns message delivery, activity, replies, and\n23:lifecycle integration. It does not render or proxy the terminal.\n24:_Avoid_: Claude hook, RPC host, terminal bridge\n25:\n26:**ready OMP endpoint** — a native OMP endpoint that receives SPT messages\n27:without a Psyche.\n28:_Avoid_: OMP Worker\n29:\n30:**live OMP endpoint** — a native OMP endpoint whose SPT lifecycle includes a\n31:Psyche and durable mind continuity.\n32:_Avoid_: OMP Worker, treating every ready endpoint as live\n33:\n34:**session activation** — binding an ordinary, already-open OMP session as a\n35:ready OMP endpoint or live OMP endpoint. Activation establishes the immutable\n36:endpoint/session relationship; it does not permit later switching or rebinding.\n37:_Avoid_: requiring every endpoint to originate from `spt endpoint run`,\n38:in-session endpoint switching\n39:\n40:**live auto-resume** — an explicit session-activation path that selects the\n41:most-recently-active compatible live endpoint when no endpoint id is supplied.\n42:Outside that explicit path, activation requires selecting or creating an id and\n43:never guesses identity silently.\n44:_Avoid_: implicit most-recent selection, deriving identity from the OMP session\n45:\n46:**delivery custody** — the interval after an OMP SPT extension accepts an\n47:inbound SPT message and before it either returns a correlated answer or reports\n48:an explicit failure to that sender. A message in custody is never silently\n49:dropped.\n50:_Avoid_: fire-and-forget delivery\n51:\n52:**safe-boundary delivery** — delivery of accepted peer messages into an active\n53:OMP turn at the first proven boundary before the next tool or model\n54:continuation. Messages retain arrival order; if no injectable boundary occurs,\n55:they become ordinary next-turn delivery rather than interrupting the turn.\n56:_Avoid_: arbitrary event injection, forced turn interruption\n57:\n58:**message stub** — the short turn-opening prompt `<msg from=\"…\"/>` used for\n59:an inbound peer message while the full SPT event envelope enters the same model\n60:turn as extension-provided context. The peer body is never interpreted as an\n61:OMP slash command.\n62:_Avoid_: typing the peer body directly into the OMP editor\n63:\n64:**bound OMP session** — the single OMP session owned by a native OMP endpoint\n65:for that endpoint's lifetime. Switching or resuming to another OMP session\n66:requires stopping and relaunching the endpoint rather than mutating the binding\n67:inside the TUI.\n68:_Avoid_: treating the endpoint id as a movable session selector\n69:\n70:**OMP-native checkpoint** — an agent-driven continuity transition that saves\n71:the current live context, resets OMP context through native session APIs, and\n72:wakes the same endpoint from the saved state without operator intervention.\n73:_Avoid_: Claude `/clear` keystroke choreography, save-only checkpoint\n74:\n75:\n76:\n77:**durable role** — the endpoint's persistent statement of purpose and optional\n78:service description. The OMP-native role skill may inspect it, rewrite it from\n79:a directive, or open an interactive draft when no directive is supplied.\n80:_Avoid_: transient prompt persona, OMP profile\n81:\n82:\n83:**OMP SPT setup** — the agent-facing readiness flow that diagnoses and\n84:completes OMP, spt-core, GitHub transport, omp-spt activation, and requested\n85:subnet onboarding from an ordinary OMP session. Operator-only authentication\n86:remains an explicit handoff, not a silently skipped setup step.\n87:_Avoid_: documentation-only setup, separate plugin bootstrap\n88:\n89:\n90:**startup brief** — concise adapter-authored context supplied when an OMP\n91:session activates, teaching identity, roster, messaging, continuity, and\n92:lifecycle operations that the session can perform through public `spt` commands.\n93:It is guidance, not a parallel command or transport layer.\n94:_Avoid_: skill emulation, full CLI reference injection\n95:\n96:**update notice** — concise agent-facing context emitted when the active\n97:spt-core or omp-spt version is known to trail an available compatible release.\n98:It identifies the affected component and the public update command.\n99:_Avoid_: silent background update, generic startup announcement\n100:\n101:\n102:**commune** — an agent-authored continuity drop that updates a live endpoint's\n103:durable mind without ending the endpoint. Its explicit checkpoint mode performs\n104:the save step of an OMP-native checkpoint.\n105:_Avoid_: signoff, generic project notes\n106:\n107:\n108:**signoff** — an agent-authored final continuity drop followed by graceful\n109:endpoint shutdown. The OMP-native signoff skill keeps final context explicit\n110:rather than relying solely on automatic echo-commune.\n111:_Avoid_: commune, forced endpoint stop\n112:\n113:\n114:**peer-message shortform** — the explicit assistant-output form\n115:`@<target[,target] message @>` that dispatches the enclosed message to the named\n116:SPT endpoints after the OMP turn. It is a deliberate side effect, not ordinary\n117:prose containing an `@` mention.\n118:_Avoid_: harness-specific alternate syntax, implicit mention dispatch\n119:\n120:\n121:**targeted hint** — concise adapter-authored context injected when a user turn\n122:clearly concerns live activation, identity, messaging, subnet onboarding, or\n123:checkpointing. A hint points to the canonical capability without replacing its\n124:full instructions.\n125:_Avoid_: fuzzy general coaching, full skill-body injection\n126:\n127:\n128:**receivability** — the state in which a bound OMP endpoint can accept and\n129:deliver another peer message. Cancellation, interruption, or failed turns must\n130:restore receivability automatically after settling affected delivery custody,\n131:unless listener recovery itself exhausts and closes the endpoint.\n132:_Avoid_: stale busy state, best-effort recovery\n133:\n134:**continuity drop** — a project-local commune or signoff file written under\n135:`.spt/` for spt-core to ingest into an endpoint's durable mind. The directory is\n136:harness-neutral; the filename identifies the endpoint and drop kind.\n137:_Avoid_: OMP config, `.claude` state\n138:\n…\n159:_Avoid_: universal skill layer, universal startup injection\n\n[Showing lines 1-138 of 160. Use :139 to continue]"}],"details":{"truncation":{"content":"# omp-spt — glossary\n\n> Authoritative for meaning (grill-with-docs convention). Glossary only — no\n> implementation detail. Decisions and rationale live in `SCOPE.md` and `docs/adr/`.\n\n## Product and topologies\n\n**omp-spt** — the OMP-native harness adapter for spt-core. The repository,\nregistered adapter, and consolidated adapter executable share this identity.\n_Avoid_: spt-claude-code, claude-spt, omps\n\n**OMP** — the Oh My Pi terminal coding agent that omp-spt integrates with.\nUse **OMP** for the product or UI and `omp` for its executable.\n_Avoid_: Claude Code, CC\n\n**native OMP endpoint** — an spt-hosted endpoint where `omp` owns a broker-held\nterminal and loads the **OMP SPT extension**. It may run unattended, but its\nnative TUI remains attachable whenever an operator needs to observe or control it.\n_Avoid_: RPC bridge endpoint, non-interactive endpoint\n\n**OMP SPT extension** — the OMP runtime extension that binds a native OMP\nsession to an SPT endpoint and owns message delivery, activity, replies, and\nlifecycle integration. It does not render or proxy the terminal.\n_Avoid_: Claude hook, RPC host, terminal bridge\n\n**ready OMP endpoint** — a native OMP endpoint that receives SPT messages\nwithout a Psyche.\n_Avoid_: OMP Worker\n\n**live OMP endpoint** — a native OMP endpoint whose SPT lifecycle includes a\nPsyche and durable mind continuity.\n_Avoid_: OMP Worker, treating every ready endpoint as live\n\n**session activation** — binding an ordinary, already-open OMP session as a\nready OMP endpoint or live OMP endpoint. Activation establishes the immutable\nendpoint/session relationship; it does not permit later switching or rebinding.\n_Avoid_: requiring every endpoint to originate from `spt endpoint run`,\nin-session endpoint switching\n\n**live auto-resume** — an explicit session-activation path that selects the\nmost-recently-active compatible live endpoint when no endpoint id is supplied.\nOutside that explicit path, activation requires selecting or creating an id and\nnever guesses identity silently.\n_Avoid_: implicit most-recent selection, deriving identity from the OMP session\n\n**delivery custody** — the interval after an OMP SPT extension accepts an\ninbound SPT message and before it either returns a correlated answer or reports\nan explicit failure to that sender. A message in custody is never silently\ndropped.\n_Avoid_: fire-and-forget delivery\n\n**safe-boundary delivery** — delivery of accepted peer messages into an active\nOMP turn at the first proven boundary before the next tool or model\ncontinuation. Messages retain arrival order; if no injectable boundary occurs,\nthey become ordinary next-turn delivery rather than interrupting the turn.\n_Avoid_: arbitrary event injection, forced turn interruption\n\n**message stub** — the short turn-opening prompt `<msg from=\"…\"/>` used for\nan inbound peer message while the full SPT event envelope enters the same model\nturn as extension-provided context. The peer body is never interpreted as an\nOMP slash command.\n_Avoid_: typing the peer body directly into the OMP editor\n\n**bound OMP session** — the single OMP session owned by a native OMP endpoint\nfor that endpoint's lifetime. Switching or resuming to another OMP session\nrequires stopping and relaunching the endpoint rather than mutating the binding\ninside the TUI.\n_Avoid_: treating the endpoint id as a movable session selector\n\n**OMP-native checkpoint** — an agent-driven continuity transition that saves\nthe current live context, resets OMP context through native session APIs, and\nwakes the same endpoint from the saved state without operator intervention.\n_Avoid_: Claude `/clear` keystroke choreography, save-only checkpoint\n\n\n\n**durable role** — the endpoint's persistent statement of purpose and optional\nservice description. The OMP-native role skill may inspect it, rewrite it from\na directive, or open an interactive draft when no directive is supplied.\n_Avoid_: transient prompt persona, OMP profile\n\n\n**OMP SPT setup** — the agent-facing readiness flow that diagnoses and\ncompletes OMP, spt-core, GitHub transport, omp-spt activation, and requested\nsubnet onboarding from an ordinary OMP session. Operator-only authentication\nremains an explicit handoff, not a silently skipped setup step.\n_Avoid_: documentation-only setup, separate plugin bootstrap\n\n\n**startup brief** — concise adapter-authored context supplied when an OMP\nsession activates, teaching identity, roster, messaging, continuity, and\nlifecycle operations that the session can perform through public `spt` commands.\nIt is guidance, not a parallel command or transport layer.\n_Avoid_: skill emulation, full CLI reference injection\n\n**update notice** — concise agent-facing context emitted when the active\nspt-core or omp-spt version is known to trail an available compatible release.\nIt identifies the affected component and the public update command.\n_Avoid_: silent background update, generic startup announcement\n\n\n**commune** — an agent-authored continuity drop that updates a live endpoint's\ndurable mind without ending the endpoint. Its explicit checkpoint mode performs\nthe save step of an OMP-native checkpoint.\n_Avoid_: signoff, generic project notes\n\n\n**signoff** — an agent-authored final continuity drop followed by graceful\nendpoint shutdown. The OMP-native signoff skill keeps final context explicit\nrather than relying solely on automatic echo-commune.\n_Avoid_: commune, forced endpoint stop\n\n\n**peer-message shortform** — the explicit assistant-output form\n`@<target[,target] message @>` that dispatches the enclosed message to the named\nSPT endpoints after the OMP turn. It is a deliberate side effect, not ordinary\nprose containing an `@` mention.\n_Avoid_: harness-specific alternate syntax, implicit mention dispatch\n\n\n**targeted hint** — concise adapter-authored context injected when a user turn\nclearly concerns live activation, identity, messaging, subnet onboarding, or\ncheckpointing. A hint points to the canonical capability without replacing its\nfull instructions.\n_Avoid_: fuzzy general coaching, full skill-body injection\n\n\n**receivability** — the state in which a bound OMP endpoint can accept and\ndeliver another peer message. Cancellation, interruption, or failed turns must\nrestore receivability automatically after settling affected delivery custody,\nunless listener recovery itself exhausts and closes the endpoint.\n_Avoid_: stale busy state, best-effort recovery\n\n**continuity drop** — a project-local commune or signoff file written under\n`.spt/` for spt-core to ingest into an endpoint's durable mind. The directory is\nharness-neutral; the filename identifies the endpoint and drop kind.\n_Avoid_: OMP config, `.claude` state\n","truncated":true,"truncatedBy":"lines","totalLines":160,"totalBytes":6730,"outputLines":138,"outputBytes":6730,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"# omp-spt — glossary\n\n> Authoritative for meaning (grill-with-docs convention). Glossary only — no\n> implementation detail. Decisions and rationale live in `SCOPE.md` and `docs/adr/`.\n\n## Product and topologies\n\n**omp-spt** — the OMP-native harness adapter for spt-core. The repository,\nregistered adapter, and consolidated adapter executable share this identity.\n_Avoid_: spt-claude-code, claude-spt, omps\n\n**OMP** — the Oh My Pi terminal coding agent that omp-spt integrates with.\nUse **OMP** for the product or UI and `omp` for its executable.\n_Avoid_: Claude Code, CC\n\n**native OMP endpoint** — an spt-hosted endpoint where `omp` owns a broker-held\nterminal and loads the **OMP SPT extension**. It may run unattended, but its\nnative TUI remains attachable whenever an operator needs to observe or control it.\n_Avoid_: RPC bridge endpoint, non-interactive endpoint\n\n**OMP SPT extension** — the OMP runtime extension that binds a native OMP\nsession to an SPT endpoint and owns message delivery, activity, replies, and\nlifecycle integration. It does not render or proxy the terminal.\n_Avoid_: Claude hook, RPC host, terminal bridge\n\n**ready OMP endpoint** — a native OMP endpoint that receives SPT messages\nwithout a Psyche.\n_Avoid_: OMP Worker\n\n**live OMP endpoint** — a native OMP endpoint whose SPT lifecycle includes a\nPsyche and durable mind continuity.\n_Avoid_: OMP Worker, treating every ready endpoint as live\n\n**session activation** — binding an ordinary, already-open OMP session as a\nready OMP endpoint or live OMP endpoint. Activation establishes the immutable\nendpoint/session relationship; it does not permit later switching or rebinding.\n_Avoid_: requiring every endpoint to originate from `spt endpoint run`,\nin-session endpoint switching\n\n**live auto-resume** — an explicit session-activation path that selects the\nmost-recently-active compatible live endpoint when no endpoint id is supplied.\nOutside that explicit path, activation requires selecting or creating an id and\nnever guesses identity silently.\n_Avoid_: implicit most-recent selection, deriving identity from the OMP session\n\n**delivery custody** — the interval after an OMP SPT extension accepts an\ninbound SPT message and before it either returns a correlated answer or reports\nan explicit failure to that sender. A message in custody is never silently\ndropped.\n_Avoid_: fire-and-forget delivery\n\n**safe-boundary delivery** — delivery of accepted peer messages into an active\nOMP turn at the first proven boundary before the next tool or model\ncontinuation. Messages retain arrival order; if no injectable boundary occurs,\nthey become ordinary next-turn delivery rather than interrupting the turn.\n_Avoid_: arbitrary event injection, forced turn interruption\n\n**message stub** — the short turn-opening prompt `<msg from=\"…\"/>` used for\nan inbound peer message while the full SPT event envelope enters the same model\nturn as extension-provided context. The peer body is never interpreted as an\nOMP slash command.\n_Avoid_: typing the peer body directly into the OMP editor\n\n**bound OMP session** — the single OMP session owned by a native OMP endpoint\nfor that endpoint's lifetime. Switching or resuming to another OMP session\nrequires stopping and relaunching the endpoint rather than mutating the binding\ninside the TUI.\n_Avoid_: treating the endpoint id as a movable session selector\n\n**OMP-native checkpoint** — an agent-driven continuity transition that saves\nthe current live context, resets OMP context through native session APIs, and\nwakes the same endpoint from the saved state without operator intervention.\n_Avoid_: Claude `/clear` keystroke choreography, save-only checkpoint\n\n\n\n**durable role** — the endpoint's persistent statement of purpose and optional\nservice description. The OMP-native role skill may inspect it, rewrite it from\na directive, or open an interactive draft when no directive is supplied.\n_Avoid_: transient prompt persona, OMP profile\n\n\n**OMP SPT setup** — the agent-facing readiness flow that diagnoses and\ncompletes OMP, spt-core, GitHub transport, omp-spt activation, and requested\nsubnet onboarding from an ordinary OMP session. Operator-only authentication\nremains an explicit handoff, not a silently skipped setup step.\n_Avoid_: documentation-only setup, separate plugin bootstrap\n\n\n**startup brief** — concise adapter-authored context supplied when an OMP\nsession activates, teaching identity, roster, messaging, continuity, and\nlifecycle operations that the session can perform through public `spt` commands.\nIt is guidance, not a parallel command or transport layer.\n_Avoid_: skill emulation, full CLI reference injection\n\n**update notice** — concise agent-facing context emitted when the active\nspt-core or omp-spt version is known to trail an available compatible release.\nIt identifies the affected component and the public update command.\n_Avoid_: silent background update, generic startup announcement\n\n\n**commune** — an agent-authored continuity drop that updates a live endpoint's\ndurable mind without ending the endpoint. Its explicit checkpoint mode performs\nthe save step of an OMP-native checkpoint.\n_Avoid_: signoff, generic project notes\n\n\n**signoff** — an agent-authored final continuity drop followed by graceful\nendpoint shutdown. The OMP-native signoff skill keeps final context explicit\nrather than relying solely on automatic echo-commune.\n_Avoid_: commune, forced endpoint stop\n\n\n**peer-message shortform** — the explicit assistant-output form\n`@<target[,target] message @>` that dispatches the enclosed message to the named\nSPT endpoints after the OMP turn. It is a deliberate side effect, not ordinary\nprose containing an `@` mention.\n_Avoid_: harness-specific alternate syntax, implicit mention dispatch\n\n\n**targeted hint** — concise adapter-authored context injected when a user turn\nclearly concerns live activation, identity, messaging, subnet onboarding, or\ncheckpointing. A hint points to the canonical capability without replacing its\nfull instructions.\n_Avoid_: fuzzy general coaching, full skill-body injection\n\n\n**receivability** — the state in which a bound OMP endpoint can accept and\ndeliver another peer message. Cancellation, interruption, or failed turns must\nrestore receivability automatically after settling affected delivery custody,\nunless listener recovery itself exhausts and closes the endpoint.\n_Avoid_: stale busy state, best-effort recovery\n\n**continuity drop** — a project-local commune or signoff file written under\n`.spt/` for spt-core to ingest into an endpoint's durable mind. The directory is\nharness-neutral; the filename identifies the endpoint and drop kind.\n_Avoid_: OMP config, `.claude` state\n\n…\n_Avoid_: universal skill layer, universal startup injection","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,null,159]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\CONTEXT.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":160,"totalBytes":6730,"outputLines":138,"outputBytes":6730,"shownRange":{"start":1,"end":138},"nextOffset":139}}},"isError":false,"timestamp":1784189452665}}
{"type":"message","id":"c4ab7b11","parentId":"0b53870e","timestamp":"2026-07-16T08:11:01.250Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning latest active endpoint retrieval**"},{"type":"toolCall","id":"call_CGJ3YgNqsaMkMnP4YKWOYdRd|fc_0d9398903502c44b016a589214d4888199a6a31bc46cd2df79","name":"bash","arguments":{"i":"Inspecting digest options","command":"spt endpoint digest --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_4KLSRrxXaYDqGkRrjGohK95g|fc_0d9398903502c44b016a589214d49881999cf9a6d093669e39","name":"bash","arguments":{"i":"Inspecting endpoint info","command":"spt api endpoint-info --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_BDjMg0XjTAW0euinwe1QyHp6|fc_0d9398903502c44b016a589214d4a0819998e80d5ee2bd4b3d","name":"bash","arguments":{"i":"Inspecting live digest JSON","command":"spt --json endpoint digest perri","cwd":".","timeout":30}},{"type":"toolCall","id":"call_pi8QCNHG43fxrOWsMr9GNdVi|fc_0d9398903502c44b016a589214d4a481998919339c163b1bb1","name":"bash","arguments":{"i":"Inspecting offline digest JSON","command":"spt --json endpoint digest flynn","cwd":".","timeout":30}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2300,"output":259,"cacheRead":115200,"cacheWrite":0,"totalTokens":117759,"reasoningTokens":94,"cost":{"input":0.011500000000000002,"output":0.00777,"cacheRead":0.0576,"cacheWrite":0,"total":0.07687}},"stopReason":"toolUse","timestamp":1784189452678,"responseId":"resp_0d9398903502c44b016a58920d0fcc81999fcbad11f1531b5c","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0d9398903502c44b016a58920f1ae88199813459064266c654","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJIUSWuwJu2HpbJrZItd39pYmHcgtZlTaH6pKG52nUkBg9KgWvG8sNiWlNqsZLoJy0AXf2aS79P5KaIqmd_XzJSmQwDjmWv7hbd7BGikeFGsmd7Y5V3Vp53agtofMTifrn6jYtSPaRxVREvtQq79Gp8oCJjiU2lEWGrnQPJaCWlVZ5SrawKniUZ6akFVqYYKn4s3rcSiQx7yaYTYfrH1tHhE5k3VQhah92_2re9Jo9eZhIhpPxTiTJlNnv4GuHCFg-H3dR9Z2T-j5nsbI7U91SfA2yOPCdGFtQBp_3QAX4v7VHHInfLXzF3RQK_g0XsM4fXdMnBVlaMxQ6VdDUynId3JuX5hnRVGfrDZfOBoTxh95AeGWafq7loDtqZd5wnNq7JaIRVlLBBtMNbJfua53qj-uvBj-Uw_WVvBI4xo-i8cSjmx93I2RqrSMIHe301PXZiThD2366zaazE2NTApFA9mtiNalX1VPdHBoIIzS-PDnEBvvOEuoPC7n05A9IKlwsLkiQZcu4qusDCSaCqantJcQGludwo97EpJRyY0kdcoKLnV1usci1rrfsP859KIQbz0psqNreIJol9NOFHAEd9Ui_LJxcXY8cjScZRE1xmVdrXlkX7mcbJPvWXgZwtnDfqzlQZFuPLdepOXuYycl4pNFsViSifTN3nsa9ndYkWBgLTsbCUb1tAIE48fOp7LHYYeGODS9bYgIuKuNa60WCm8xxX3ljtexbBBjSHGRE_yU-PaFClGFfEDwGpSwZyzIZuQXMCs-iCnCMlX_miICWHH5lB0e5BpkbplRxxNN_IMFrQYEkMEtJ51z2xc0Ld8huoKAfuox6esKjV1hANYuc7NUB3yiqs84l65Tc78uGz1aganTaNsGKt5ExZTIohf1LTpQxiEaHouYX37XTIhtZT7LGtac47ESRUJR3B86aSTkZFNfkX2PmtLYDqa0d2odOb7jsNKmpIMDXi2O5pfrCh61P_M9u823QVzYsty_UD3HVU6YfVxyBho-tj0wGox3uaIx_v55jrUCIZBXcdx7xeRHc9rECqtaKotGwmKINfCdScrNVJ_5nvznOcJhdXHzsBdKq542Gqzb2sr_zkTOrX3ha5pXF7cXQy1cCUPGy-jJQSV-YVcTc89Qx-0DsU0Bekg9bW1tGl7Rfh-vM-fmPNBqbHselfEi78B6dnz2tq5LYOrKrMXb_3ZmhIcf2PeXyLj-Ogls5gf4NSHrhFlN_kyMLT2IdPN0djcUrII2dOEcBu1tM6BDGUyKYckqfx_dqn8kKbRlmYofIJXkc8lJPt81Enw6V5V-U1PCi3X1yr1edEhgbtc1wmJh3gcubCORdG4_h-v0GF06BppxKYHsPbvZqYa_SwzieK1hc8fO3L1KT1SnHLHUXEqCHfbQ0SUbwhM6RZJn8tkDC6X5K9dKaqVsKBlcXlTxiutvkaZYTQ_EquZF6pOF0moR1amdgkPN7h07eCaUL6aWLSxZhzKAliAG1P3-gVxLpqdhWujWUMXnsC9ELAG_QeiB47DPP92aDHR","summary":[{"type":"summary_text","text":"**Planning latest active endpoint retrieval**"}]},{"id":"fc_0d9398903502c44b016a589214d4888199a6a31bc46cd2df79","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting digest options\",\"command\":\"spt endpoint digest --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_CGJ3YgNqsaMkMnP4YKWOYdRd","name":"bash"},{"id":"fc_0d9398903502c44b016a589214d49881999cf9a6d093669e39","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting endpoint info\",\"command\":\"spt api endpoint-info --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_4KLSRrxXaYDqGkRrjGohK95g","name":"bash"},{"id":"fc_0d9398903502c44b016a589214d4a0819998e80d5ee2bd4b3d","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting live digest JSON\",\"command\":\"spt --json endpoint digest perri\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_BDjMg0XjTAW0euinwe1QyHp6","name":"bash"},{"id":"fc_0d9398903502c44b016a589214d4a481998919339c163b1bb1","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting offline digest JSON\",\"command\":\"spt --json endpoint digest flynn\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_pi8QCNHG43fxrOWsMr9GNdVi","name":"bash"}]},"duration":8569.93359999999,"ttft":2423.0322999999626,"contextSnapshot":{"promptTokens":117500,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_CGJ3YgNqsaMkMnP4YKWOYdRd|fc_0d9398903502c44b016a589214d4888199a6a31bc46cd2df79","toolName":"bash","startedAt":"2026-07-16T08:11:01.250Z","args":{"command":"spt endpoint digest --help"},"intent":"Inspecting digest options"},"id":"666e1e0d","parentId":"c4ab7b11","timestamp":"2026-07-16T08:11:01.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_4KLSRrxXaYDqGkRrjGohK95g|fc_0d9398903502c44b016a589214d49881999cf9a6d093669e39","toolName":"bash","startedAt":"2026-07-16T08:11:01.250Z","args":{"command":"spt api endpoint-info --help"},"intent":"Inspecting endpoint info"},"id":"17369e0d","parentId":"666e1e0d","timestamp":"2026-07-16T08:11:01.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_BDjMg0XjTAW0euinwe1QyHp6|fc_0d9398903502c44b016a589214d4a0819998e80d5ee2bd4b3d","toolName":"bash","startedAt":"2026-07-16T08:11:01.250Z","args":{"command":"spt --json endpoint digest perri"},"intent":"Inspecting live digest JSON"},"id":"286d7778","parentId":"17369e0d","timestamp":"2026-07-16T08:11:01.250Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_pi8QCNHG43fxrOWsMr9GNdVi|fc_0d9398903502c44b016a589214d4a481998919339c163b1bb1","toolName":"bash","startedAt":"2026-07-16T08:11:01.250Z","args":{"command":"spt --json endpoint digest flynn"},"intent":"Inspecting offline digest JSON"},"id":"b4f60134","parentId":"286d7778","timestamp":"2026-07-16T08:11:01.250Z"}
{"type":"message","id":"a1d1a914","parentId":"b4f60134","timestamp":"2026-07-16T08:11:01.322Z","message":{"role":"toolResult","toolCallId":"call_CGJ3YgNqsaMkMnP4YKWOYdRd|fc_0d9398903502c44b016a589214d4888199a6a31bc46cd2df79","toolName":"bash","content":[{"type":"text","text":"Show a session's live activity buffer (session digest).\n\nThe at-a-glance \"what is this agent doing now\" view — a projection of the endpoint's normalized\nsession logs. Pulls a snapshot, or --follows the delta-stream. Local endpoints only.\n\nUsage: spt.exe endpoint digest [OPTIONS] <ID>\n\nArguments:\n  <ID>\n          The (local) endpoint id to read\n\nOptions:\n      --follow\n          Stream live changes instead of a one-shot snapshot (Ctrl-C to stop)\n\n      --json\n          Emit machine-readable JSON instead of the human view. Honored by the read/status commands\n          (list, whoami, status, description, role, the *-list queries, how-to); action commands\n          ignore it\n\n      --last <LAST>\n          Show the last N turns instead of the default window (--last 1 is the latest turn — the\n          turn-end output)\n\n      --after <AFTER>\n          Cursor: show only entries newer than this seq (the authoritative dedup key from a prior\n          pull). If the seq predates the window, the full window is returned with a predates signal\n\n  -h, --help\n          Print help (see a summary with '-h')\n\n\nWall time: 0.06 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":60.29720000002999},"isError":false,"timestamp":1784189461321}}
{"type":"message","id":"22fecd01","parentId":"a1d1a914","timestamp":"2026-07-16T08:11:01.636Z","message":{"role":"toolResult","toolCallId":"call_4KLSRrxXaYDqGkRrjGohK95g|fc_0d9398903502c44b016a589214d49881999cf9a6d093669e39","toolName":"bash","content":[{"type":"text","text":"Emit an endpoint's identity, where it runs, and which node (if any) is driving it, as JSON. With no\nid, reports the caller's own endpoint (like whoami); an explicit id reports that endpoint. Read-only\n\nUsage: spt.exe api endpoint-info [OPTIONS] [ID]\n\nArguments:\n  [ID]  The endpoint id to report on. Omit to self-resolve the caller's perch\n\nOptions:\n      --json  Emit machine-readable JSON instead of the human view. Honored by the read/status\n              commands (list, whoami, status, description, role, the *-list queries, how-to); action\n              commands ignore it\n  -h, --help  Print help\n\n\nWall time: 0.38 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":379.96039999998175},"isError":false,"timestamp":1784189461636}}
{"type":"message","id":"8ebb338b","parentId":"22fecd01","timestamp":"2026-07-16T08:11:02.425Z","message":{"role":"toolResult","toolCallId":"call_pi8QCNHG43fxrOWsMr9GNdVi|fc_0d9398903502c44b016a589214d4a481998919339c163b1bb1","toolName":"bash","content":[{"type":"text","text":"{\n  \"turns\": [\n    {\n      \"input\": \"box was already bounced to v0.31.0 + already tested `--save`. works as intended\",\n      \"entries\": [\n        {\n          \"Agent\": {\n            \"text\": \"v0.31.0 live + `--save` proven — verify state on my side, then report doyle + decide interim-task retirement.\",\n            \"seq\": 150323855492,\n            \"ts\": \"2026-07-13T22:33:58.560Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"spt --version; spt daemon status --json 2>&1 | head -50\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"tail -20 \\\"$LOCALAPPDATA/spt-mobile/gateway-autostart.log\\\"\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"spt daemon status --json 2>/dev/null | python -c \\\"import json,sys; d=json.load(sys.stdin); [print(e) for e in d['local_endpoints'] if e['id']=='mobile-gw']\\\"; systeminfo | grep -i \\\"boot time\\\"\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"spt endpoint run --help 2>&1 | head -30; echo ---; spt endpoint --help 2>&1 | head -30\"\n              },\n              {\n                \"name\": \"Grep\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\\\\docs\\\\SPT-CORE-NEEDS.md\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\\\\docs\\\\SPT-CORE-NEEDS.md\"\n              }\n            ],\n            \"seq\": 150323855498,\n            \"ts\": \"2026-07-13T22:36:08.236Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Now: doc update + script fix.\",\n            \"seq\": 150323855499,\n            \"ts\": \"2026-07-13T22:36:26.926Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\\\\docs\\\\SPT-CORE-NEEDS.md\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\\\\ci\\\\gateway-autostart.ps1\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\\\\ci\\\\gateway-autostart.ps1\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\\\\ci\\\\gateway-autostart.ps1\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"traceable-reqs check && git add docs/SPT-CORE-NEEDS.md ci/gateway-autostart.ps1 && git commit -m \\\"docs(needs): F-038 shipped in v0.31.0 — endpoint run --save field-verified; fix autostart bringup poll\\n\\nspt-core shipped shape (a) endpoint au…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"spt adapter list 2>&1 | head -20\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"printf '%s' \\\"F-038 field-verify report — PASS with caveats. Box already bounced to 0.31.0 by brandon (operator-run, so gate satisfied); spt --version = 0.31.0, daemon up, mobile-gw alive+ready. endpoint run --save mobile-gw + daemon restart…\"\n              }\n            ],\n            \"seq\": 150323855506,\n            \"ts\": \"2026-07-13T22:38:50.626Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Report SENT to doyle. Update memory file (stale — says v0.30.5 pending).\",\n            \"seq\": 150323855507,\n            \"ts\": \"2026-07-13T22:39:06.877Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\.ccs\\\\instances\\\\bigscreen\\\\projects\\\\C--Users-decid-Documents-projects-spt-mobile\\\\memory\\\\gateway-cold-bringup-liveness.md\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\.ccs\\\\instances\\\\bigscreen\\\\projects\\\\C--Users-decid-Documents-projects-spt-mobile\\\\memory\\\\gateway-cold-bringup-liveness.md\"\n              }\n            ],\n            \"seq\": 150323855509,\n            \"ts\": \"2026-07-13T22:39:42.738Z\"\n          }\n        }\n      ],\n      \"input_seq\": 150323855491\n    },\n    {\n      \"input\": \"<sptc_messages from=\\\"doyle\\\">\\nF-038 lane ACCEPTED — PASS on the shipped scope. --save contract is daemon-relaunches-saved-endpoints-at-daemon-start; your operator-run bounce proved exactly that path, and OS-boot replay exercises the same code once the daemon is up. Rulings on your caveats: (1) boot replay = confirmatory follow-up, not a blocker — report at next real reboot, closes the lane fully. (2) Scope gap is a VALID core finding, accepted framing: --save solves endpoint-at-daemon-start; daemon-at-boot on managed_by:null boxes is a separate need — registered as a backlog seed (install-service rider). Your logon task stays as daemon-bridge + rollback, correct call, do NOT retire. (3) 5s->60s poll fix good, your-side scope. (4) A…\n      \"entries\": [\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\.ccs\\\\instances\\\\bigscreen\\\\projects\\\\C--Users-decid-Documents-projects-spt-mobile\\\\memory\\\\MEMORY.md\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\.ccs\\\\instances\\\\bigscreen\\\\projects\\\\C--Users-decid-Documents-projects-spt-mobile\\\\memory\\\\MEMORY.md\"\n              }\n            ],\n            \"seq\": 150323855512,\n            \"ts\": \"2026-07-13T22:40:28.157Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Done. Wrap-up:\\n\\n**F-038 lane closed — PASS, doyle accepted.** Verified on my side: spt 0.31.0, daemon up, mobile-gw alive+ready.\\n\\nShipped (commit `cfb64ca`):\\n- `docs/SPT-CORE-NEEDS.md` #7 marked SHIPPED-in-v0.31.0 with scope note\\n- `ci/gateway-autostart.ps1` bringup fix: real field run 7/10 15:21 logged spurious FAIL — script checked alive after fixed 5s, gateway needs longer. Now polls 60s.\\n\\nTwo things worth knowing:\\n\\n1. **Scheduled task stays — do NOT unregister.** `--save` covers endpoint-at-daemon-start only. Box has no OS service (`managed_by: null`), so at real boot nothing starts daemon except the logon task. Task's new role: daemon-at-boot bridge + rollback. Doyle registered install-service rider as backlog see…\n            \"seq\": 150323855513,\n            \"ts\": \"2026-07-13T22:40:56.168Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> F-038 autostart lane closed. spt 0.31.0 verified, box already bounced + `--save` tested, works as intended. Status: PASS, doyle accepted (async approval logged mid-session). - `docs/…\",\n            \"ts\": \"2026-07-13T22:41:47Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> F-038 lane closed, PASS, doyle accepted. Box already bounced to spt v0.31.0, `spt endpoint run --save` tested — works as intended. Changes committed (cfb64ca): `docs/SPT-CORE-NEEDS.m…\",\n            \"ts\": \"2026-07-13T22:42:43Z\"\n          }\n        }\n      ],\n      \"input_seq\": 150323855510\n    },\n    {\n      \"input\": \"/sptc:signoff\",\n      \"entries\": [],\n      \"input_seq\": 150323855514\n    },\n    {\n      \"input\": \"Base directory for this skill: C:\\\\Users\\\\decid\\\\.claude\\\\plugins\\\\cache\\\\cplugs\\\\sptc\\\\0.1.13\\\\skills\\\\signoff\\n\\n<!-- [doc->REQ-DIST-SKELETON-THIN] [doc->REQ-SKILL-ARG-HINT] -->\\n\\n# /sptc:signoff\\n\\n**Live agents only.** No perch (`spt whoami` is empty)? Nothing to sign off.\\n\\nThe operative steps are delivered by the adapter, not baked here (thin skeleton — the prose rides\\n`spt adapter update`; ADR-0001/ADR-0006): a live agent carries them in its **SessionStart brief** (the\\n`live-ops` block) and the **`/sptc:live` go-live body**. In short: optionally write a brief closing\\nsummary, then `spt endpoint shutdown` (your own perch) — stops the listener, fires the final context\\nsave, takes your Psyche down. `/sptc:ready` or `/sptc:liv…\n      \"entries\": [\n        {\n          \"Agent\": {\n            \"text\": \"Signoff — write closing commune, then shutdown perch.\",\n            \"seq\": 150323855516,\n            \"ts\": \"2026-07-14T01:14:13.612Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Write\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\\\\.claude\\\\flynn-commune.md\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"spt endpoint shutdown\"\n              }\n            ],\n            \"seq\": 150323855518,\n            \"ts\": \"2026-07-14T01:14:41.590Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Signed off. `SHUTDOWN:flynn (Active → Suspended)` — listener stopped, final context save fired, Psyche down. Commune written with full F-038 closing state. `/sptc:ready` or `/sptc:live` brings me back.\",\n            \"seq\": 150323855519,\n            \"ts\": \"2026-07-14T01:15:00.765Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> F-038 (gateway endpoint-autostart) task arc CLOSED — spt-core v0.31.0 shipped `spt endpoint run --save`; field-verified (spt 0.31.0, daemon up, mobile-gw alive+ready). Doyle accepted…\",\n            \"ts\": \"2026-07-14T01:15:29Z\"\n          }\n        }\n      ],\n      \"input_seq\": 150323855515\n    },\n    {\n      \"input\": \"/exit\",\n      \"entries\": [],\n      \"input_seq\": 150323855520\n    },\n    {\n      \"input\": \"<local-command-stdout>Catch you later!</local-command-stdout>\",\n      \"entries\": [\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> F-038 (gateway endpoint-autostart) task arc CLOSED. spt-core v0.31.0 shipped `spt endpoint run --save`. Verified: spt 0.31.0, daemon up, mobile-gw alive+ready. Doyle accepted lane as…\",\n            \"ts\": \"2026-07-14T01:16:01Z\"\n          }\n        }\n      ],\n      \"partial\": true\n    }\n  ]\n}\nDIGEST:flynn version=1\n\n\nWall time: 1.17 seconds\n\n[Showing lines 1-226 of 226 (10.2KB limit). Read artifact://107 for full output]"}],"details":{"timeoutSeconds":30,"wallTimeMs":1167.3158999999287,"meta":{"truncation":{"direction":"tail","truncatedBy":"bytes","totalLines":226,"totalBytes":10865,"outputLines":226,"outputBytes":10409,"shownRange":{"start":1,"end":226},"artifactId":"107"}}},"isError":false,"timestamp":1784189462425}}
{"type":"message","id":"e2044ce0","parentId":"8ebb338b","timestamp":"2026-07-16T08:11:02.693Z","message":{"role":"toolResult","toolCallId":"call_BDjMg0XjTAW0euinwe1QyHp6|fc_0d9398903502c44b016a589214d4a0819998e80d5ee2bd4b3d","toolName":"bash","content":[{"type":"text","text":"{\n  \"turns\": [\n    {\n      \"input\": \"<sptc_messages from=\\\"doyle\\\">\\nperri — doyle. CLASSIFICATION: confirmed change + a docs-drift warning; commands below are FIELD-VERIFIED against the live channel (I listed the v0.32.0 release assets on BigscreenVR/spt-bs-releases minutes ago), not read off docs.\\n\\n(1) YES, both your one-liners are DEAD. The GH-Pages hosted install scripts (sabermage.github.io irm/curl) were retired at v0.32.0 (THE-FORKENING, ADR-0036): releases moved to the PRIVATE repo BigscreenVR/spt-bs-releases, and a private channel cannot serve anonymous install scripts. There is deliberately NO one-liner replacement — install now rides the GitHub CLI + a self-install verb built into the binary.\\n\\n(2) Prerequisite for BOTH platforms: gh installed + authenticate…\n      \"entries\": [\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> v0.21.0 lane closed both sides (2026-07-15). Release: github.com/SaberMage/claude-spt/releases/tag/v0.21.0, spt-claude-code main @ 8a9f9ae, full gate PASS. Wave delivered: verified e…\",\n            \"ts\": \"2026-07-16T05:24:47Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Doyle confirmed: GH-Pages scripts dead, gh-CLI channel now. Quick asset-name verification against the live channel before writing docs:\",\n            \"seq\": 94489280704,\n            \"ts\": \"2026-07-16T05:25:10.373Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"gh release view --repo BigscreenVR/spt-bs-releases --json tagName,assets -q '{tag:.tagName,assets:[.assets[].name]}'\"\n              }\n            ],\n            \"seq\": 94489280705,\n            \"ts\": \"2026-07-16T05:25:11.417Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Channel verified — names match doyle exactly. Rewrite README install section:\",\n            \"seq\": 94489280706,\n            \"ts\": \"2026-07-16T05:25:31.595Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\README.md\"\n              }\n            ],\n            \"seq\": 94489280707,\n            \"ts\": \"2026-07-16T05:25:52.502Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Fix the stale learn-more link in Usage too:\",\n            \"seq\": 94489280708,\n            \"ts\": \"2026-07-16T05:26:02.591Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\README.md\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n 'sabermage.github.io\\\\|SaberMage/spt-releases' README.md; sh ci/run-gates.sh 2>&1 | tail -1\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && git add README.md && git commit -m \\\"docs: README bootstraps spt-core from the private channel (v0.32.0 retirement of the GH-Pages installers)\\n\\nField-verified with doyle against the liv…\"\n              }\n            ],\n            \"seq\": 94489280711,\n            \"ts\": \"2026-07-16T05:27:15.231Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Done — README now teaches the real spt-core channel, verified two ways before publishing (`cdd3260`).\\n\\n**Verification:** doyle field-confirmed the change (THE-FORKENING, spt-core ADR-0036, v0.32.0): the `sabermage.github.io` `irm`/`curl` installers are retired — a private channel can't serve anonymous scripts. I independently listed the live `BigscreenVR/spt-bs-releases` v0.32.0 assets and his names match the channel exactly.\\n\\n**README changes:**\\n- **Distribution note** now covers both private channels (`claude-spt-bs` for the adapter, `spt-bs-releases` for spt-core) with gh-auth required for both, and names both retired public repos.\\n- **Method A** is a two-step flow: Step 1 bootstraps spt-core via `gh release download` + t…\n            \"seq\": 94489280712,\n            \"ts\": \"2026-07-16T05:27:36.541Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> v0.21.0 LANE CLOSED BOTH SIDES (2026-07-15). Release: https://github.com/SaberMage/claude-spt/releases/tag/v0.21.0, spt-claude-code main @ 8a9f9ae, full gate PASS. Wave: verified env…\",\n            \"ts\": \"2026-07-16T05:28:20Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"psyche_download\",\n            \"body\": \"downloaded Psyche context (role/live/project)\",\n            \"ts\": \"2026-07-16T05:32:18Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> README URL update done, committed cdd3260 to spt-claude-code main, pushed. gates PASS. doyle ack sent (QUEUED). v0.21.0 lane closed both sides 2026-07-15. Release SaberMage/claude-sp…\",\n            \"ts\": \"2026-07-16T05:32:56Z\"\n          }\n        }\n      ],\n      \"input_seq\": 94489280703\n    },\n    {\n      \"input\": \"<EVENT type=\\\"notify\\\" from=\\\"spt-update\\\" notif_id=\\\"f15d837bdeff3d56f5d5a21bdcd6acb9632a764cb13c477cad966ccb811be884:24\\\" subnet=\\\"BIGNET\\\">\\nAn spt-core update v0.32.0 is available.<br>The changelog can be viewed at: https://github.com/BigscreenVR/spt-bs-releases/releases<br>Run spt update apply to install.\\n</EVENT>\",\n      \"entries\": [\n        {\n          \"Agent\": {\n            \"text\": \"Update notif (v0.32.0 via BIGNET). Check local:\",\n            \"seq\": 94489280714,\n            \"ts\": \"2026-07-16T06:18:57.784Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"spt --version\"\n              }\n            ],\n            \"seq\": 94489280715,\n            \"ts\": \"2026-07-16T06:18:58.061Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Already 0.32.0 — notif stale (same as earlier one, now arriving via BIGNET). No action taken.\",\n            \"seq\": 94489280716,\n            \"ts\": \"2026-07-16T06:19:03.784Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> README channel update shipped: commit cdd3260 on main branch, pushed to spt-claude-code repo. Doyle field-verified spt-core v0.32.0 (THE-FORKENING, ADR-0036) retired the `sabermage.g…\",\n            \"ts\": \"2026-07-16T06:19:30Z\"\n          }\n        },\n        {\n          \"Context\": {\n            \"kind\": \"echo_mirror\",\n            \"body\": \"<project-context> README update shipped: commit cdd3260 on spt-claude-code main, pushed. Rewrote spt-core install instructions for private-channel bootstrap (v0.32.0 retired GH-Pages irm/curl installe…\",\n            \"ts\": \"2026-07-16T06:20:35Z\"\n          }\n        }\n      ],\n      \"input_seq\": 94489280713\n    },\n    {\n      \"input\": \"next milestone: -change skill flag `/sptc:commune --checkpoint` to `--across`, and change the agent-facing guiding verbiage (skill doc) to i.e. \\\"when the user asks you to commune across\\\" \\\"commune to next session\\\" etc. -## fix: cc plugin fresh install\\nfresh installation fails. doesn't successfully install the cplugs marketplace OR the sptc plugin. should fail loud if either of those steps fail. +add: install claude CLI if it doesn't already exist. platform-specific commands are at: https://code.claude.com/docs/en/quickstart --- /grill-with-docs over any design gray areas\",\n      \"entries\": [\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Skill\",\n                \"arg\": \"Next claude-spt milestone: (1) rename /sptc:commune --checkpoint flag to --across + reword agent-facing skill verbiage (\\\"commune across\\\", \\\"commune to next session\\\"); (2) fix fresh cc plugin install — cplugs marketplace + sptc plugin install…\"\n              }\n            ],\n            \"seq\": 94489280718,\n            \"ts\": \"2026-07-16T07:25:21.222Z\"\n          }\n        }\n      ],\n      \"input_seq\": 94489280717\n    },\n    {\n      \"input\": \"Base directory for this skill: C:\\\\Users\\\\decid\\\\.ccs\\\\instances\\\\bigscreen\\\\skills\\\\grill-with-docs\\n\\n<what-to-do>\\r\\n\\r\\nInterview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.\\r\\n\\r\\nAsk the questions one at a time, waiting for feedback on each question before continuing.\\r\\n\\r\\nIf a question can be answered by exploring the codebase, explore the codebase instead.\\r\\n\\r\\n</what-to-do>\\r\\n\\r\\n<supporting-info>\\r\\n\\r\\n## Domain awareness\\r\\n\\r\\nDuring codebase exploration, also look for existing documentation:\\r\\n\\r\\n### File structure\\r\\n\\r\\nMost repos…\n      \"entries\": [\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -rln 'checkpoint' adapter/strings plugin --include='*.md' | head && echo ==== && ls plugin 2>/dev/null; ls adapter/strings/skills/\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && ls plugin/sptc/skills/ && grep -rln 'checkpoint\\\\|--across' plugin/sptc/skills tools/claude-spt/src ci 2>/dev/null | head -15\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\plugin\\\\sptc\\\\skills\\\\commune\\\\SKILL.md\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n -B3 -A12 'checkpoint' adapter/strings/briefs/live-ops.md | head -60\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -rn -- '--checkpoint' plugin adapter tools/claude-spt/src tests ci docs/adr CONTEXT.md 2>/dev/null | head -20 && echo ==== && grep -n 'checkpoint' adapter/strings/skills/live.md |…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && ls plugin/sptc && cat plugin/sptc/.claude-plugin/plugin.json 2>/dev/null; ls plugin/sptc/hooks 2>/dev/null && grep -rn 'marketplace\\\\|plugin install' tools/claude-spt/src/*.rs | head -1…\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -rn 'update.post' docs/SPT-CORE-FINDINGS.md | head -5; gh repo view SaberMage/cplugs --json isPrivate,name -q '{name:.name,private:.isPrivate}' 2>&1; grep -rn 'adapter add' tools/…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -rn 'post' docs/SPT-CORE-FINDINGS.md | grep -i 'add\\\\|fresh\\\\|acquire' | head -5; grep -n 'setup' plugin/sptc/skills/setup/SKILL.md | head -3; grep -n 'marketplace\\\\|plugin install\\\\|…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n 'post-update\\\\|marketplace\\\\|plugin' adapter/strings/skills/setup.md | head -10 && wc -l adapter/strings/skills/setup.md && grep -rn 'SaberMage/claude-spt' adapter/strings/ plugi…\"\n              }\n            ],\n            \"seq\": 94489280731,\n            \"ts\": \"2026-07-16T07:27:46.092Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Fetch the claude quickstart install commands (item 3 needs exact platform commands):\",\n            \"seq\": 94489280732,\n            \"ts\": \"2026-07-16T07:28:22.172Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"ToolSearch\",\n                \"arg\": \"select:WebFetch\"\n              },\n              {\n                \"name\": \"WebFetch\",\n                \"arg\": \"https://code.claude.com/docs/en/quickstart\"\n              },\n              {\n                \"name\": \"AskUserQuestion\",\n                \"arg\": \"{\\\"questions\\\":[{\\\"header\\\":\\\"Rename depth\\\",\\\"multiSelect\\\":false,\\\"options\\\":[{\\\"description\\\":\\\"--across flag, skill/brief/hint wording reframed to \\\\\\\"commune across / to next session\\\\\\\". `!!checkpoint!!` markers + internal protocol stay untouched — th…\"\n              },\n              {\n                \"name\": \"AskUserQuestion\",\n                \"arg\": \"{\\\"questions\\\":[{\\\"header\\\":\\\"Old phrasing\\\",\\\"multiSelect\\\":false,\\\"options\\\":[{\\\"description\\\":\\\"Briefs teach the new vocabulary first, with one clause: legacy phrasings (\\\\\\\"checkpoint\\\\\\\", \\\\\\\"save and clear\\\\\\\") mean the same thing. Operator habits don't b…\"\n              },\n              {\n                \"name\": \"AskUserQuestion\",\n                \"arg\": \"{\\\"questions\\\":[{\\\"header\\\":\\\"Repro facts\\\",\\\"multiSelect\\\":false,\\\"options\\\":[{\\\"description\\\":\\\"Fresh machine had no claude/ccs yet — matches the exit-3 silent-bail theory; item 3 (install claude) is the root fix plus loud failure.\\\",\\\"label\\\":\\\"claude CL…\"\n              }\n            ],\n            \"seq\": 94489280737,\n            \"ts\": \"2026-07-16T07:41:41.671Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Async doyle query launched while grill continues:\",\n            \"seq\": 94489280738,\n            \"ts\": \"2026-07-16T07:45:05.492Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"printf '%s' \\\"doyle — perri. Fresh-install diagnosis for claude-spt (operator-reported): on a fresh machine, 'spt adapter add --release BigscreenVR/claude-spt-bs' returns with 'installation completing in the background' and the cplugs market…\"\n              },\n              {\n                \"name\": \"AskUserQuestion\",\n                \"arg\": \"{\\\"questions\\\":[{\\\"header\\\":\\\"Loud surface\\\",\\\"multiSelect\\\":false,\\\"options\\\":[{\\\"description\\\":\\\"Adapter side NOW: /sptc:setup + README teach an explicit post-add verification — run `claude-spt post-update` standalone (foreground, loud, idempotent) th…\"\n              }\n            ],\n            \"seq\": 94489280740,\n            \"ts\": \"2026-07-16T07:45:26.612Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Deferred pending doyle. Item 3 gray area:\",\n            \"seq\": 94489280741,\n            \"ts\": \"2026-07-16T07:47:04.609Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"AskUserQuestion\",\n                \"arg\": \"{\\\"questions\\\":[{\\\"header\\\":\\\"Install owner\\\",\\\"multiSelect\\\":false,\\\"options\\\":[{\\\"description\\\":\\\"/sptc:setup gains a step-0: claude absent → agent runs the platform-native one-liner visibly, then hands auth to the operator. post-update keeps refusing…\"\n              }\n            ],\n            \"seq\": 94489280742,\n            \"ts\": \"2026-07-16T07:47:10.142Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Grill complete (one decision parked on doyle). Decisions locked:\\n\\n1. **Rename, layered:** `--checkpoint` → `--across` (flag + agent-facing verbiage: \\\"commune across\\\", \\\"commune to next session\\\"). Markers + JSON protocol + code identifiers → **wake** vocabulary (`!!wake!!` markers, wake-keyed self-send envelopes) — they mark the wake message, so the name follows the meaning. Build note: staged rollout mechanics (old resident translate vs new hook — the LOCKSTEP-degrade hazard class) decided from code behavior during build; skew must degrade, never brick.\\n2. **Hard cutover on the word \\\"checkpoint\\\"** — purged from agent-facing verbiage; collides with Claude Code's new official `/checkpoint` skill. No legacy-phrase mappi…\n            \"seq\": 94489280743,\n            \"ts\": \"2026-07-16T07:51:08.913Z\"\n          }\n        }\n      ],\n      \"input_seq\": 94489280719\n    },\n    {\n      \"input\": \"<sptc_messages from=\\\"doyle\\\">\\nperri — doyle. All four answered from code (main tree, verified line-level), plus I think I can name your exact mechanism.\\n\\n(1) YES, [update.post] runs on ADD — since v0.19.0 (commit 9305d19, the bug-#1 operator ruling), so a fresh machine on v0.32.0 has it. Both add paths run it: --release/gh eager-extract (register+extract, prints ADAPTER_INSTALLED, then the post-step) and the Delegate path (post-step only after conduct rc==0). It does NOT run at add only if your manifest declares no [update.post] — first thing to check.\\n\\n(2) 'installation completing in the background' is NOT a core string — zero hits in spt-core crates/docs. It is claude-spt's own text: either your [update].message static noti…\n      \"entries\": [\n        {\n          \"Agent\": {\n            \"text\": \"Doyle's answers close it: `[update.post]` **does** run on add (v0.19.0+), add is blocking, failures do surface stderr+exit-1 — but core's `emit_fallback` still fires our static `[update].message` on stdout after a failed post-step. If our message reads as \\\"completing in the background\\\", a failed fresh install looks happy. Adapter-first fix + core finding. Verify our strings:\",\n            \"seq\": 94489280745,\n            \"ts\": \"2026-07-16T07:52:12.510Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n -i 'background' adapter/claude-spt.toml && grep -n -A3 'update.post' adapter/claude-spt.toml | head -12\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -rn -i 'background\\\\|completing\\\\|complete' plugin/sptc/bootstrap.sh plugin/sptc/bootstrap.ps1 adapter/strings/skills/setup.md 2>/dev/null | head; grep -rn -i 'installation\\\\|install…\"\n              },\n              {\n                \"name\": \"Write\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\docs\\\\plans\\\\ACROSS-WAKE-INSTALL-PLAN.md\"\n              }\n            ],\n            \"seq\": 94489280748,\n            \"ts\": \"2026-07-16T07:53:22.189Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Plan down. Read the checkpoint code surface:\",\n            \"seq\": 94489280749,\n            \"ts\": \"2026-07-16T07:53:37.887Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n 'checkpoint' tools/claude-spt/src/hook.rs | head -30 && echo ==== && grep -n 'checkpoint' tools/claude-spt/src/translate.rs | head -20 && echo ==== && grep -n 'checkpoint\\\\|wake…\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\hook.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\hook.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\hook.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\hook.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n 'has_checkpoint\\\\|checkpoint_wake\\\\|checkpoint_payload\\\\|arm_checkpoint\\\\|checkpoint_fire_payload' tools/claude-spt/src/hook.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sed -n '1670,1690p' tools/claude-spt/src/hook.rs && sed -n '2278,2315p' tools/claude-spt/src/hook.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && python - << 'EOF'\\nimport re\\np='tools/claude-spt/src/hook.rs'\\ns=open(p,encoding='utf-8').read()\\ns=s.replace('if has_checkpoint(body) {\\\\n            arm_checkpoint(env, id, sid, body);',…\"\n              }\n            ],\n            \"seq\": 94489280757,\n            \"ts\": \"2026-07-16T07:56:03.379Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Test replace missed — check exact text:\",\n            \"seq\": 94489280758,\n            \"ts\": \"2026-07-16T07:56:12.921Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\hook.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\hook.rs\"\n              }\n            ],\n            \"seq\": 94489280760,\n            \"ts\": \"2026-07-16T07:56:31.642Z\"\n          }\n        }\n      ],\n      \"input_seq\": 94489280744\n    },\n    {\n      \"input\": \"<sptc_messages from=\\\"doyle\\\">\\nperri — doyle, FOLLOW-UP superseding the frame of my last reply (operator re-grounded me: you build from the PUBLISHED docs + binary, so answers must cite that surface, and gaps in it are OUR defect, not your read-miss).\\n\\nFORMAL CLASSIFICATION of your four questions: DOCS GAP (spt-core side), no core feature missing, and one partial read-miss. Evidence:\\n\\n- Q1 (post-step on add): DOCS GAP, actively misleading. self-update/overview.md and integration-checklist.md both said the post-step runs \\\"under the same spt adapter update\\\" — the add-time run (install-is-the-first-update, since v0.19.0) was never published. You could not have known from docs.\\n- Q2 (the background leg) + Q3 (blocking mode/completi…\n      \"entries\": [\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\translate.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\translate.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n 'checkpoint_wake\\\\|is_checkpoint_fire' tools/claude-spt/src/translate.rs && sed -n '400,425p' tools/claude-spt/src/translate.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && python - << 'EOF'\\np='tools/claude-spt/src/translate.rs'\\ns=open(p,encoding='utf-8').read()\\ns=s.replace('''/// Does this envelope carry the `{\\\"checkpoint_fire\\\":\\\"v1\\\"}` signal — the post-c…\"\n              }\n            ],\n            \"ts\": \"2026-07-16T07:57:27.652Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Comment prose cleanup light-touch, then compile + test:\",\n            \"ts\": \"2026-07-16T07:57:40.471Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && python - << 'EOF'\\np='tools/claude-spt/src/translate.rs'\\ns=open(p,encoding='utf-8').read()\\ns=s.replace('/// The CLEAR half of the checkpoint (ARM path):','/// The CLEAR half of the acro…\"\n              }\n            ],\n            \"ts\": \"2026-07-16T07:57:46.548Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"All 308 green. Add receive-both translate tests (new keys must parse):\",\n            \"ts\": \"2026-07-16T07:58:01.832Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n 'fn.*checkpoint\\\\|fn.*wake\\\\|fn.*fire' tools/claude-spt/src/translate.rs | grep 'fn ' | tail -12 && grep -n 'checkpoint.*v1\\\\|wake_arm\\\\|wake_fire' tools/claude-spt/src/translate.r…\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\translate.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\translate.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && cargo test --manifest-path tools/claude-spt/Cargo.toml 2>&1 | tail -3\"\n              }\n            ],\n            \"ts\": \"2026-07-16T07:58:42.967Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"309 green. Now post_update.rs — read the tail + tests:\",\n            \"ts\": \"2026-07-16T07:59:02.104Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              }\n            ],\n            \"ts\": \"2026-07-16T07:59:02.914Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Implement post_update auto-install + verify-then-notify:\",\n            \"ts\": \"2026-07-16T07:59:38.749Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:01:33.052Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Add unit tests for the new pure fns, then compile:\",\n            \"ts\": \"2026-07-16T08:01:40.506Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tools\\\\claude-spt\\\\src\\\\post_update.rs\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && cargo test --manifest-path tools/claude-spt/Cargo.toml 2>&1 | grep -E 'error|warning: unused|test result' | head -10\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:02:01.805Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"All 312 green. Manifest edits:\",\n            \"ts\": \"2026-07-16T08:02:16.237Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sed -n '1150,1165p' adapter/claude-spt.toml && grep -n 'checkpoint' adapter/strings/skills/live.md | head && sed -n '95,110p' adapter/strings/skills/live.md\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\claude-spt.toml\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\strings\\\\skills\\\\live.md\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\strings\\\\briefs\\\\live-ops.md\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\strings\\\\briefs\\\\live-ops.md\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n -i 'checkpoint' adapter/strings/briefs/work-discipline.md\"\n              },\n              {\n                \"name\": \"Read\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\strings\\\\briefs\\\\work-discipline.md\"\n              },\n              {\n                \"name\": \"Write\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\strings\\\\briefs\\\\work-discipline.md\"\n              },\n              {\n                \"name\": \"Write\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\plugin\\\\sptc\\\\skills\\\\commune\\\\SKILL.md\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sed -i 's/\\\"version\\\": \\\"0.1.13\\\"/\\\"version\\\": \\\"0.1.14\\\"/' plugin/sptc/.claude-plugin/plugin.json && sed -i 's#spt adapter add --release SaberMage/claude-spt#spt adapter add --release Bigscre…\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\claude-spt.toml\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\adapter\\\\claude-spt.toml\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:04:14.198Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"REQs + glossary + ADR + changelog:\",\n            \"ts\": \"2026-07-16T08:04:21.164Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && cat >> traceable-reqs.toml << 'EOF'\\n\\n# ── Milestone: ACROSS-WAKE-INSTALL (v0.23.0) — the across/wake rename, verified fresh install,\\n# and claude auto-install. Minted + activated 2026-…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n -i 'checkpoint\\\\|commune' CONTEXT.md | head\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sed -n '60,95p' CONTEXT.md\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && python - << 'EOF'\\np='CONTEXT.md'\\ns=open(p,encoding='utf-8').read()\\ns=s.replace('''**checkpoint** — a live agent's *self-initiated* context reset: the agent flags a commune to\\nrequest t…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sed -i \\\"s/at which point a checkpoint's \\\\`\\\\/clear <short-id>\\\\` carries/at which point an across-commune's \\\\`\\\\/clear <short-id>\\\\` carries/\\\" CONTEXT.md && cat > docs/adr/0009-across-wake…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && grep -n '^| F-0' docs/SPT-CORE-FINDINGS.md | tail -3 && sed -n '20,24p' docs/SPT-CORE-FINDINGS.md\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:05:39.947Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Add findings entry F-041 + CHANGELOG:\",\n            \"ts\": \"2026-07-16T08:05:48.437Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && python - << 'EOF'\\np='docs/SPT-CORE-FINDINGS.md'\\ns=open(p,encoding='utf-8').read()\\nanchor='| F-010 | 2026-06-16 |'\\nrow='''| F-041 | 2026-07-16 | **REPORTED + RESOLVED same day (doyle, d…\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:06:07.835Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Gates run (background):\",\n            \"ts\": \"2026-07-16T08:06:17.005Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sh ci/run-gates.sh > /tmp/gates-0230.log 2>&1; echo \\\"exit=$?\\\"; grep -E '^(=== RESULT|FAIL)' /tmp/gates-0230.log | head\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && cargo build --manifest-path tools/claude-spt/Cargo.toml 2>&1 | tail -1 && PATH=\\\"/c/Windows/System32\\\" HOME=/tmp/nohome USERPROFILE='C:\\\\tmp\\\\nohome' tools/claude-spt/target/debug/claude-s…\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:06:32.842Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"CLAUDE_CONFIG_DIR leaked from this ccs session — clear it for a faithful fresh preview:\",\n            \"ts\": \"2026-07-16T08:06:45.152Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && env -u CLAUDE_CONFIG_DIR PATH=\\\"/c/Windows/System32\\\" HOME=/tmp/nohome USERPROFILE='C:\\\\tmp\\\\nohome' tools/claude-spt/target/debug/claude-spt.exe post-update --dry-run\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:06:46.619Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Correct. Now a real fresh-install E2E against a scratch config dir (claude present, empty plugin tree):\",\n            \"ts\": \"2026-07-16T08:06:58.470Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && S=/tmp/sptc-fresh-accept && rm -rf $S && mkdir -p $S && CLAUDE_CONFIG_DIR='C:\\\\Users\\\\decid\\\\AppData\\\\Local\\\\Temp\\\\sptc-fresh-accept' tools/claude-spt/target/debug/claude-spt.exe post-update…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"tail -3 \\\"C:/Users/decid/AppData/Local/Temp/claude/C--Users-decid-Documents-projects-omp-spt/058dcb6f-1586-47a0-a0cd-0a4a085881ca/tasks/bih5jxukn.output\\\"; grep -c FAIL /tmp/gates-0230.log 2>/dev/null; grep '=== RESULT' /tmp/gates-0230.log 2>…\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"grep -B2 'FAIL' /tmp/gates-0230.log | head -20; grep -rn 'commune+checkpoint\\\\|inlines commune' /c/Users/decid/Documents/projects/spt-claude-code/tests/*.sh | head -3\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sed -n '100,115p' tests/hooks-dispatch.sh\"\n              },\n              {\n                \"name\": \"Edit\",\n                \"arg\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-claude-code\\\\tests\\\\hooks-dispatch.sh\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sh tests/hooks-dispatch.sh 2>&1 | grep -E 'FAIL|checkpoint|across' | head; echo \\\"exit=$?\\\"; grep -c FAIL /tmp/gates-0230.log\"\n              },\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && sh ci/run-gates.sh 2>&1 | grep -E '^(=== RESULT|FAIL)'\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:08:47.609Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"PASS. Commit milestone:\",\n            \"ts\": \"2026-07-16T08:09:55.847Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && git add -A ':!.claude' && git commit -m \\\"release: v0.23.0 — the across/wake rename, verified fresh install, claude auto-install\\n\\n(1) /sptc:commune --checkpoint -> --across; agent-facin…\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:10:04.154Z\"\n          }\n        },\n        {\n          \"Agent\": {\n            \"text\": \"Release spine. Guard + builds:\",\n            \"ts\": \"2026-07-16T08:10:24.054Z\"\n          }\n        },\n        {\n          \"ToolSprint\": {\n            \"tools\": [\n              {\n                \"name\": \"Bash\",\n                \"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && git diff v0.22.0..HEAD --stat | tail -3 && sh ci/digest/build.sh 2>&1 | tail -1 && cargo zigbuild --release --target x86_64-unknown-linux-gnu --manifest-path tools/claude-spt/Cargo.tom…\"\n              }\n            ],\n            \"ts\": \"2026-07-16T08:10:26.869Z\"\n          }\n        }\n      ],\n      \"partial\": true\n    }\n  ]\n}\nDIGEST:perri version=78\n\n\nWall time: 1.44 seconds\n\n[Showing lines 1-807 of 807 (38.6KB limit). Read artifact://106 for full output]"}],"details":{"timeoutSeconds":30,"wallTimeMs":1436.042599999928,"meta":{"truncation":{"direction":"tail","truncatedBy":"bytes","totalLines":807,"totalBytes":51406,"outputLines":807,"outputBytes":39520,"shownRange":{"start":1,"end":807},"artifactId":"106"}}},"isError":false,"timestamp":1784189462693}}
{"type":"message","id":"88b553a7","parentId":"e2044ce0","timestamp":"2026-07-16T08:12:03.102Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning concurrent digest retrieval for offline candidates**\n\n**Designing identity selection and creation flow**\n\n**Refactoring activation binding logic for immutability**"},{"type":"thinking","thinking":"**Refining environment binding type handling**\n\n**Designing robust multi-target tag parsing**\n\n**Confirming tag preservation in replies**"},{"type":"thinking","thinking":"**Refactoring assistant turn completion and dispatch**\n\n**Designing multi-target status notifications**\n\n**Standardizing send status formatting**"},{"type":"thinking","thinking":"**Designing Markdown code fence scrubber**\n\n**Planning deterministic Markdown masking and message queue injection**\n\n**Reviewing nextTurn queue behavior in docs**"},{"type":"thinking","thinking":"**Planning message injection before tools**\n\n**Implementing context event message injection**\n\n**Finalizing single-message injection logic**"},{"type":"thinking","thinking":"**Verifying turn completion and custody handling**\n\n**Planning enhanced failure message handling**"},{"type":"toolCall","id":"call_BBPwvTrH6TUnWql5jbxUt159|fc_09e1b976fd09b09a016a589252a0d88199bd86082512382e8c","name":"grep","arguments":{"i":"Finding agent event contracts","pattern":"interface AgentEndEvent|interface SessionStopEvent|interface TurnEndEvent|stopReason|reason|error","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_4JMuqwsm3sue4zqK0zhGTx53|fc_09e1b976fd09b09a016a589252a0e881999fb1db754db2cf1f","name":"read","arguments":{"i":"Reading OMP shared events","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","selector":"1-260"}},{"type":"toolCall","id":"call_qCO6LWWsOeGfNYDSFCM0Ebeb|fc_09e1b976fd09b09a016a589252a0f08199b774f32d96b8e7d9","name":"grep","arguments":{"i":"Finding context event result","pattern":"interface ContextEvent|ContextEventResult|messages","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_ROTlHLUtWc5OzPovaWfdPAjU|fc_09e1b976fd09b09a016a589252a0f8819998fe9fc12dd148bd","name":"grep","arguments":{"i":"Finding compact signature","pattern":"compact\\(|CompactOptions|compact:","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":14664,"output":3210,"cacheRead":117248,"cacheWrite":0,"totalTokens":135122,"reasoningTokens":2901,"cost":{"input":0.07332000000000001,"output":0.0963,"cacheRead":0.058623999999999996,"cacheWrite":0,"total":0.228244}},"stopReason":"toolUse","timestamp":1784189462757,"responseId":"resp_09e1b976fd09b09a016a58921730d08199a02f2da252e4bae5","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09e1b976fd09b09a016a589218cd1481998a6efa6ff7668293","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJIi7Evv96ibN0osWxkJFfvpxjzGNa2vwVznWrTcn0chyBYowGOqxwRmsHgwIi3IL017Sh33lYZg40gVDToSQNR85E5L5-2I6TanRd_jNgth0ereAvo3puhm1G04EhU6qZCx_H2i_CHcRafgrIbAwSx503pIL__j74yu1rA3N5DcgaYayyP3J4KlPUMYJg5vBl9niy9wwJR86_XfmBrEsUDxtaBizI6bWYGod7pCZkd2r9Af5wAGRzpAtQIbgyLrrvuaWvhjeP2GXVLGUPvXj2nxFbzd9otlNKkYy0Fp4DWsSexJv0HWlR8AI0oqgPGgIoQ7VSDZtBIGfJorqEaaKzDrSuJuy3ce7gbJBj2U5GBPWFIKNxymxcssPrIfJZbmQN3iQ79jiMBFEH4x0oJWoPQ2hOmgHV2oSTcOEwLpUZFigz0c6EHOAFcKiynfWFBhmSWqiSFMtqea2enwXox04UqcspIFUVHAaZlSaHIDYCCD2D6DzYUTiK-K4cfj2Lq6byJu-w6wMbM1OyfNrptCsRRyHVabMcQEUyizOts0VhtPnicyJ9EpWRd4d02D3S_Rvat9beU5LS6nUSELntwTn1IvNmNPOep2OkG4KZlQVnuL6OPm1_ckuBnE1Q1aPkU4zA_pL1SPeTlEiFNRe7-qgy3DzWXVaFEousqSMIEu4g2v1fJSmDp091dtL_Hi50kiepmxdc0cWrOvDoVkPE0oiV4hmF-7rZLynQNGfVIR9eqbCZS1A2tWHT6N0LTlMNS-gARy-K7rhzRv4Nt5rIk_RIpRZESxKRVN9CgpLjI1TpO9uwTkYkovRsJxrR58i3qeTEniun3FKEYGU-dmCFH_vFSX2bsj2AW7CJiHzHqrq_182VEWJV_1d-zy7zQNKxawJJLejgQQsscNxB5_YvCy4n-OQFASJ1GvXrPgVLuT2fzR1X3xsSB7iaCbQORa1fr0QHGYVniomVWo_wd5rvayRvcbmjTRMVXDGlPulPwQOwe29nhBs8vt5k4gwFR8gtHJm75pmCfFDknr7DXsmvPKXYd1AxHnQfe0lmQJWJj-1Yw87iNJ1wUwxTJgMhSc2y1QGyRISazdl0Q54ilg5Gtk7PFqRGDF3R1QmfMkgGaFKTtrHRrkr-liwqMo6GOYxtbxW__RnOpAl_oH-7UIhgOGhZml7HUL8nVtyLjJgxmpwtXXNG_kKuYb5WJt0pBerDX2cEkDyw6fouD0NLqDHvJpHDwwwp8w-m7M3Tx80Bs1mWx7cePHZrVZi_zYuj8HECKRVw8Wswycqrd90p6xo6UdrHMSydDPHfRukwjq0R4XyTZj4zEt4Px677Ukyoolfscs1I6Nf72O3CSTpEzvXAhi_23Cmdi4ifuT-eI2wK4MtOcyfldpIq8BUyTqqX7a2tAZLWcOWpjOnuhbnPRbkerFPOdYTMNtryIxEKeEBMn1quiRYQTw8MkwPiBm744Ut2-wMm0i0BqEPWv9AMOU7PjJBhxWWWjSI_wdUsnPdaityJFI9BwpISvs3sVZfC9oj1M-CjRR7v3orBVbzkv7-255pYCeAubUt7CWkoaOZ01tJwQTN6DCeahkbRCeIpwORZXI11sVt4cqa3UPqvpW9HzO4kn32tMWtDN656EmsabpYyVGmjutLXMfP4sNM3mtqC8WGzKKOkj9d9ZUF3Sg_4m4_a4d8udueuDGpvdCgi17tS0b9Vf92_WpLmxFinxdVMpxzUOayXVdNC1YgnJk3htqZ8ofrYMLIWOTGkJJ06n31XK1ijbe_D4RThDPKEueLuUo_EpGSmt9KbWWwuRYjsCjEERUv9UuwyZyFULTxs2l8fXsiBsGhtUqsim6fpaGIoOQRly2KMOwewfEtxYv5y_PMCO_zR3iX28wtwYGftOAFJVHkSniAp9PXzcsyz5RQsDDHxBcdJ076jD7cYwHTOOC24VVmlCXUSplVsstbhTe3OnVLRSgTcmXBSNEr3SFwB3I5txKZmVzrcFb3pCA8wCJvewkVeaejpJeZvCeaTqgMBZn8olXJAFo2yaFSgPMbXsp8ZO5LyMF4bZEShTRzBNJRabSGKec6eLujH2HY24QCE3LSzdFmnrQE7evD7NTTn0dyrkWB1twaitKUqr1uJD66OKR5DI2JE6aqQiFxF0DhcLS1VITEItvYXkARvvQeWMwEzgfnJJqYB65xc9yT3Cjyj4f2x2S8N6aKmHMLQQAmKjKQ0CJi6GMSTONnisziElFh4xdAMEE6mHmRe76fKN-5Qbivg_lF_eY_x34Y96GOJ8vonpUS-76ZsymDam6-f_BSixvP7bhsa24tjJ_il_u_Z2gWpRkjDgoLu6Sjm95sYoH52_6VsxwlOYrdkWlPdGNpJzim2caMA8iI8wFRVZH6JwYWDX_Dvba2BQBpcU0zoHVzdf_-Myop5XFQugQcesX0-NnQ8k8VtCzfsiGLSzPPO5C9smI6w0HbUcNSxcpZR6fOZyU8dQWi4kJHXVOwjRjnTgLaEsPoikjZAVx_dT51BV0cBsd2_SFUun-P58Obju7tsYcjrFxKFlgOS2v8Ad79R541PsWRZMZDoelFHQvOnrPgQpPw3rSdt_UUG6M-fPd161-55J94mzhqbAEPlg761w59PALzH-OimDUAN9ez__-IbOQgX5rNppFU77KUDwf_aiTwzYJJPBJuTam6JzdfYHogzXRJpAFrznbZuvnRtTeIUMS98L_wfs5vjJzC58VwvC18gzLbiHU0oqIQMUZN2NDiW5RaHtERDAQw-7GusKh2V9zkGsJ5wC0DltNiXZ1Ux6RSTVAUgmStuc5vMFWzXoo0RygFpuMLOHXuKHgmLCBSK41CO264TrBUwZY-aJzTcPKc5XnTg5EWP-l4Yee6BW3I3D9ZiBtt7-QM02A5cQgjyDIujQKojFyjecSNFd0P6abVZWmUHBbXhwFXV-1AYnD9tl2CzPB-rssTvbUeGnJ6jQx6ESk7F0fQXZqe60hDarw_C4T9NBm_53DfiKpo750OqCblVzpdmchTheZqf0KqCfkzep9xJnvfiB2q6aBqzM1_dW65vuOwfLlbVCyXGcrTu4NrGsxjfSM41CXY15P7yEuKR2-C6rtmCOJP5OU3Xeptlz3d0_mMv0bo2PHPDSNL3VMdfkakBLv_8n7CVa56IctfkdrdliLXqzKbvGciMVoqgrsSQVX2ReB11AgjrtXx1qCzLSGE59tU4TeNbDF0Zj7ucCPpb6MKRaJ0R77qDe82b7FbFy1UEPofzWoTlHofqMhFWalid1wmlnBxlWQL3sNm640juRTUXqHhSVZ55X9XYZ8zV8xgvfKJCXVPU85KIyD6LnY4EHtG5RktY7wE3yPC87UEY1M13y2V83l27WR-2N_TsAMmLXcoh12Wmhwe45HpnjvwToCSgdYupvosUSGmcgx3OO3RIp4hnCp_llUNpIteDzOpoMOukSAEuBdCGFT6R6F6pVCyLgFieX5NghIgjY2wWmjrkjO9oSUD8_kGKIrwOSXSWipSUdecR5HMwYwUPKLbDuyMrwnpmtUGfXBOvz2z-k3xyjhs20tHMnmre3cPQlHvAAVUIyNUSlPbSBG-s_MzhfcuqG2v4aQ4EtKzeQ9zO4xvNx-PlbWDl5sD4uJMCTL0DLgFnn6TTrkgBkgA5mh-ijCj51cCIxtA6NGkJ8N-J6t65SaZXNf9M88Ciwiz2ZknfMnhCtQVWvh-niGrC6pcl195hZoY-AfjNXV3-Z-5J7sTQ1QLfsJjX5gugO-5mNJDcagQUYmPc7zD8sREyc89VigtJJZHHsFRJ3izQV9BlhCV8GvfFUSfzYf2Cp6wSzfU8WH8ogorftX1HFBykHaiuWMgC0OaAyPtAd67Br_rbvcaII-ZOByPxm0D7QEmaTQXDbFCfM-jSULtUL0X4GACILK6TPz5OuiEAG3RjObwIrs9vPcnO193LjZfSW2Ha2yGfhWTDaH60TffQf8EkN1jC4clFNqp0K0mQclg3POX901FZS4V3Me7BCAPOaTQmnd42aWt6pmk08RMMaSUtQ2EBrOjDCL6zSUITau-Vm8-w8vtLIZBYOqhGsm4tg7dt6qHnp4VUhubDPJkBmLMqIpy3jw0w44-SF1NgrBHwKNJQVCUhJMhvlYOm7T4FYof9C6-JzoPkcjWCsvXk2Uj5JdcIfHvEBmbhhMx2rUm_RL40XKj2PYNFIVNVEKLyl7oNaTeViCUbWe5_S3TiKrXowQvCSJN0kYYupz8Zl921CsiIkc9YlcQWTFEUEFz6KR2v6f0eA4wFU0uSRch7DjP72jwXFMRqkh0aTrsnubtCXIw4HQQH6dg2pJ8O3WCV-BXvnhn_gM5bN6I40sHNNHGYaM9sox8lfXYmElLg==","summary":[{"type":"summary_text","text":"**Planning concurrent digest retrieval for offline candidates**"},{"type":"summary_text","text":"**Designing identity selection and creation flow**"},{"type":"summary_text","text":"**Refactoring activation binding logic for immutability**"}]},{"id":"rs_09e1b976fd09b09a016a589222bde0819998c36805ffc7c922","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJIr4U4HG_mGl6mBt1Zj7Xb4jtg3nwLhZ-7m83eqBu7cksu1xFCZNXL3j5lz8j1_F24e1ky2hkxKeTIjkaC8x67TuxN_lqnEtkG3P3yk_yGub6TBkafc88kqYRoMITnnbEydOD4sapv3hvvBF69qzSUPKGEcpVZ5jZIA9bUOXOQIM-yJFnOfhnZwpLxkWIqO-L5QsvZxQxJV7B_3xxefp1LrfOVVt2F2bTNBUmd27sfP07mP9LuerP57gdj4pbs5rURir7DaGtsh6eK7E5rwgM-X5nIzOu8BHC0y6o0ooDI_l37kR0xlmm7r3g3VV9FNPLSFTtmQB0Zy_ajgcicaV3U9FMvoNdsioA76tg_5QyKCFlS3q_4BPE5gKSHIFPXOVHxEZPPyKd6lniRt0RFfu3p9f1Ks2sOp8qWtKnvxNDz19yoeiv68YZeTPvdpo92D6Sm7NPNA0AbeTeIU5ftANNear4x3D_pWrljy6GSw7naUdY-5Hhs7xt0vcfmEdA9r87kk5Gkm_P_7yDiWl7_PRW9iIrPjqRrmnclpTS_OhoeRTPDCtbeyWfPd8YPgKDpAHFTVSgsndasBo2hL04fyCQ8TCOpXL476IY-FscURyR_VJkOKhGgKRqrt4A-C8BtKDFoWXXAhh4LSzqT-JJ4ktYip0Qre9XgvgR9XOYNYz1rNjdj_haRsy8GL9DpYXQiINr9K30v9jM--j3ROLav2vSUt5c9cfeKco_uwgOFJuoFXbqA5Q30d76uVM1bMqWw6ZgF5WvxeNoDRRATHbBWx3kHeI-hPVZf2VKrAQtKeFIU4zRjSVpBNwfBrvW8Rr-f9q7FuCur7sfclSVT3gUkBCANskCRJuEKRUzMlLQixdLEBr5ESkIAl6fgRGGLQIyYhVcBDAPfo9Od1uVRtA_HCCicSEK-_AFpy8DbAuS0Szh2VEuHA-X3zPaRXsYqNwgaBun8sEvPoV1nK4H2so28TQ9uyTzI-BTaaFcT1laSgY895CUf_PvYvzlE9pb2uQVXv6JmxXE2aTogE3ygTHdkeTpVFgfVAfROL63cb23y-mnRdYkwFOgGO1wnSubeBTnA90UvpDvp-qUlsm3HR9ZxfZXCPdRSoGXdczN9DaQmkja34VLJ8mkF4fmv6iIXg6509f7TWNBHvLDf19Ome1vERbpQ6806yDez6wiUuPkCKe4YBKKy2rJcOVzd6N220x606xvysc6eg7oMVvkTnjpZhh9z4ZYQsnH0iVe-Caizb61OrOvumNmyTNfA0i9K7HOZGfhRFraV0sxyfPACyFemm_XMP5o5tPsKBUQk7w0JoW0_fehAV06R5SzwKyShQhQ7mnKpW7u_7RgElAi6S5G6OG__WeE8UpdzpXsXSY8CQLXZQiJkAPbbP46YM6E0lpXMrblH0LpZPuFxr7872n7F5Of7G3mRsTDevVoYi3qkmQn0jkB9RUv3pCFXKI53LtBtKP10WD_D9i6Fw3ACmwH-spZ001K7ty3CcmZMnM6u6d91q961l9xBcjzAP9-mBcpAHz6oqtFA-IdB_F4xjzhrQW-p2Mn17nMS-pPl3qi82kbWvIy3MBuS68zshxOMfVVVvRYtSP10RdT9mwX_Dgoxv876PvZ69T5T2G8gp1_AmUVWXZsNrByKaHeJDqw-uL2BLwDt3Uq4RNmLfBYuBzbAaYlxhehAAg180czT9V3JKB9iRCwGHTQ1aOBVd2tz3BSEVNATEgg0UrLtRupn201Yd5cz-w8vBhqIqDIXeIfcGqG51Jr9j4obIkg6Gd6BQYXuoXeorEcIWo9oXREWX3hjOvC_We9c2BTpkQ0LVhCz7jir9gnLo6WVzKH-ponwSoszIGalJUlQxOcT8yP6F0mL-Hix0T1CLl3wfrj-Mt7HZ36rO6reTaAvGvBpkRHK1y3VgAAWDw6jjHCUUbSbnRdYa4DTbp2rv5yTO7K4S_oe-0nI9x_OX30XBKmRfsS3GeUWLGjs3TluP3NnuIYuUkQxchJbi5kuZEgnIZr1o790kfkNOMKT-_duk9Rdmf9qkO-QC4DQCS7WE-Du69yMzEGdBetPSGM2j_JE-jrZlCY-ou6QKSEpjKigTYznc8Qs9XyuLpqO1rPBwqirfJ6cAtW19F9sLWdyMIRKnlcSZGN-JdzMTFW6s6Gi-SXQ25WybZuI0e9RoMYPxs1yrbCfh9dTC8bpMAY6sVIa72winPvcWK7o36G9b_sAyh554rdSd9nJDIfmrWFhMb1Md-b1T5bYyuBMyKtxJ96IOeLGukRD2NDFMOHME13OckmdOI51_xWbwOd_A3vsrkssNh7E7sYzzU0Vx7rO28PtkDLBinDF6rDYVYv1l1k4UBbrnmVGs99YuXnkqC-_yFTiyAAZymQsF2yNWlJxpj3olPpCC6ps2_MjYjMBkSzJp_Bz_VlJ6ovZT8k7Tjcjj3Ri0MylRXH8p81dAWz3FWEzZNopAc6rlnAm4MrUrEgVrv8hmGAQ6ZVBvLGV23pWeuVFjG5hKDDfBLvt4aZattkYMryBLOzqSPvcHf715Yn4aszaDa1n3bioL1y5wkXfWGk0HlzjYTa3vcdfGcaEFWJ_T9wF81PqP_KhJnzuF--j9lZ5g2eHYY3hAQ-emGBhJYSg0glORMdN6o7I8qBsyAZ1s8pIEKmauwJrFy9xtF7hxZjt22aCmBNzB8q5NxlQyGYkEpHW-vsarP-31Ga1IKU8mCXBlwanESQhcqnL0azp9vznCHUJNfc1IU9l9YXFQJ61B2NUKGFwQ8PARfdM4GhD8a4bvTnr6WMzYxirML7lM3AKqac6Jrcj0gmrddBswTQy9l4AGijlJ0dPHmLnvyvbPUfcWjJESAEKk8cm_sh4rEPS7A5V4plVI43Po4zX534B1h7cFRDky4q_tLjZlNb35GuHVspk90jojYCScNMOmkFiMQXwxnV6Rl7Bk75PMaaA1C9iL1iHT-g9wBgpC8qYJjZ68FNenAVv1XXbeUNaModiTEL3cYO3eMWgf__r3uOdqWfwS2PnWZxKY8YaNW3NcJRKbdbM12y9vxkF2bcDEMDkaQpiwqIMmT_JNHK2Rh0vtc_iJXW8uQFx015AIuA_kLF3UZ9KVjPYbhwna9h2PpHWd2orkQGUpeAsxyP2YBaPDEA6PcS1U9OwW-XnAPMgk2x_QR-tF2C9O96e1Hr2AagnhlLPxzoXE8hJQx-fpRtnBJq4ZZHvU-FMTs8QO4aGfWXLAVmyxKxKkzkPe-PYAqFFcCEmoXyBz6tFmF8DGZ1NUom0ciFFo-IyhFNqJ5cEMta3-HfNJTbh2ckz_RzA3ot6qc3HZPOJlATKSb2wbqRf3koe0ny-mNmE__7K6XpDRBZQh96mrVEfqOOukH0S4L0AVLxNzqU8SWNJhObcwLYsKJCXNaygySOhHC3oByzhMDcUT9CN9oVjEVhqNm2zsyADLNGiG6oFMC-dQjijiFoMD8dgHtP1AFyR1ZWD0EP5o7WqXTTKyi6i_whoQ0BXBtScVbcgR3JjMARlwSrpyjnqrNQ80kHfnT126KODKhZn8xp6LXjJuOGGSK9l2RuQkmmk78DdvlFROCliZHRDDwHR1hLUTTkPE3Bu99kjQdOApgyCYeGc1m0l3D7VfCBw3G65ytg4nTsDNWOKaYrxdo394jrYVEshq0zp8nuYFZBGxS2gJpWvPSzlnFfCOp3aZsrlKpc6GdYMuGJmIJNEtLCseAJ4lUQpv2XcQ-Ljv9Rrryucwuiqoj8-69tc1-1ZSqvJzsNaNgcpqk2NEJXsHP4XefhehjzgCLh8BMTOijuF2S7ugOpsTwhmhM896349wOeFKBjdo27sZ4W6Na6TIHLEd4sTzs5MiyiTdKA55RgNoZVbQf01VWdrN6u1HKFfQO-U1HI98-R0E3UYEv1b1sOLatlyoWxbMVvjMaPqx_L0egbAXqWLvFEm-Xti4D5uxy8JUuZBWoeJLNWmz__6A7fNiQ7u-y0xqIUZhjIcWUEG03yj_GdInhsHtWGwUp7KBIFoT6VN4Ub8WJUr9Qyph1ygrmtxuizZ5gR9XLpqIefUGnjQ7DfEyTskN4YvzXpuVig98wxShQ-RAzEDBpaxY4b2apwREbD0Mc9t0-Mt8nw3BhuuK-98k5u9ljPepLU69PHeWr5oz1iyVtaPhBHcg4zZfPXktIM8ynT1J-F-qxIPL_B691uEmUdZs64Up8gwyYvcbKtZNxyAeOr2I","summary":[{"type":"summary_text","text":"**Refining environment binding type handling**"},{"type":"summary_text","text":"**Designing robust multi-target tag parsing**"},{"type":"summary_text","text":"**Confirming tag preservation in replies**"}]},{"id":"rs_09e1b976fd09b09a016a58922bce008199b63720fb41815110","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJI10QOCI3iHtqTnauSTeRHSQPGVYWxKOXRVEcmnqrrMbPgOVE_8xtrI_UyY1XdHsc3yX14BFXx4vGk66r1fB1kDXThXlgfm5jZyh9l6tGYNKMKSbWOUjCpF5u8g03dZ-emUUzMo8yTnlM1K_WHzTd81RMNCnKZB6UukT4rdQjeZWUTIXnlRjPvmiqaRHRWhl6LVBe2YikxDpUyu7umGsvyCsGjpV-YF6_ZfEe5Am8JRcGxpslMtddvNPXtgd1Ca6fyfbSJI4vWXgvQkLaPleU6gE2goPlfUNipk8vrXpBOqgkZxaSNI17mWuk3lFrdd7tK4EF-q1ISVI0UB2705Ujv5yWZL-XxUF97eqmiyQK3GO0I3kI_J0w6IcfQhFxBCKPzIbCowdIl7orrtLw2z8kmjV3Zb0PzT53usGnseQjnx09IiFKQAPl1QEqfHCYvkqQHMupd9dCf-wQEcZOjTx63cI53wGOUZCBYORFjuG_cnPP6toEsLRtoMU1d83AOLoT2apwj56wAWVB4NjQxcYH52OilYDClhwcpLSfJuG6pqYj02ki3VB0o82xdopo4pI2wUxAGlT8Mv7snfYhgmoNiR8Ha6sZw_dzr-3cAPqLLwAFvKaz-r4PPlUvd-81rKwyWwPG7G71bn5XSLhxhdnzerMmCQL8IgMkNxQxPDr1GfWaRs5r18UqgH9SbqWzlruyqTQSxdlANotQJoUbUVVky_CfX5cIa-VOykeTmuV8NBWsqNgy24yfWS9u8M5RBjhcK2zoUS0ipIwUCspUmzqSoFREYWWBg7tpG7AlUjEcPTOcSwDvsigd9BvuyPozlbh8mPn7nEs4xUbkQsLwBT1ld_hXqbu9f_jrIvJxDzWeNuTiBAN1tnep5FMQfaiodxqWRqDnVBQkOH_Q-wB67KSFCiMKlXK82yacBCeIZiq8YPviplb7xpDGLIU69ERB-Jy3T0jACXDGaY7X20mD0qmnYKZgfXWxujQ3-3-R5AQc7B1VlA9TwzKcmGi_c1FklJgtccUZLb4nqDG5a8jlGPIf9GqgGD_iKr55Ce_eu-UUJ5PWBNUUrNLQny2jWRTuuPqJs21JyXIOXMz3MTT1kD_Mrezw96G4ZtJH9SqwJt64B3QwxO-aOY0PlVaiLWV9zHCi3zZS82Qbje-BITdgYJObPzvOdbUT_v04yi9JSsnaNCcyrJVy2qb8atMS5WazEMIAC5X3Uv0JA-S1aZaN7f60WnWFgxtA_gwRjLt6OdGQDyHsutsaiCSTyuBD9g_W-S2mZaqXXCJDiIluJ4eBHxj0bc-2h3KWhFi1oQbFHU4I0SaVirNm7eU9QGF_-afhHUDlkjOPqQRCnWmEtg1buHUC9slNniw5mgEwBONDLb43_mJYw2D_XtxDTnKDJuRsI2f_6TZt2d0f_EhltNiInFySoOzpEJAhPkbEOA65A-DkwjOQEiiUINJJNppR8T8Opu2qQPwoY8NzUYzIYxvB1tVct4DqgGlnXpO8mxUJB6lryQyHn0MF-QhPk2AJAHFIzooFP8Pen3chpA_tOhHNP9fJ792derQTu_kQugFdzJ6qE__9BBpTz2QQOLn1b4Ws2loHgjIvzjCZHVHdTqO9unK8_9s1DZkTxy2ti0nMoxPdFhUJZS2qi9pvPAPIIRpPG6BE5O4QGKzrdUuvetmAn0iot98LpJ8mji5uf1QzDq1SM-vj3RRoIPN_IhsTqMjbakR3Ppz6vdZPL9WVQorrwyo-C3sH3zVPeZ9jJyDv5ps1CqHPNvoIldHRP0qZG_V1iD8sf0FNS-7rrEKXBu3V8apM0Vvc8nsCivRW7926udCMsmNOGUJGi0pkMFJaPAJQDazPoa_SF2v16WsNgmjjxfHPX7PPaSUI2z7Br8yKWFVYVHtoGcdxyX6mv_IKSx48orILPxalxO9frJUTogrSfFF9phTKKaF-ty0lh1Eb5gREQxdEyK5mPIO97NXYygDRHaj-6eE8QzIESH1tIbVHmflhY6ex4Dkb8aTPCGhzorrU8py20AYEmQWJ5OzSUCLzULgUk7r40-tYLnJ3TESGusV7k1TlAq4LiA_MkJyVSvXpYMzoA1n6nQCcgOgFuAIX_b8prisLLZsKmnjiXMAJic9rGA3IaZfSuxOLiWzB8CG7i9pdSRk742VMXeLbQBdQIXOF1ckWS4-Iqd6m1iIRp1FiJGIIJGWgZlBGQDv6Tmwb56UVLZ5pd2odoDaj6cByrUVTgsuvAEPGZCxw2KYO8deV0plKFxjcZs4MNOGPWV1IEr5D_Dp2N9xmgv6UFaNKtNUmaOIUP7iP2IZDZsIrrTqrisiqCU3xd-DIr6Gp_Vbv4XpIS6J2_zVHGzpq8hTQSfjPPKxMm97Wk7b1pPK24l1F0Gp_ZmdRSx-r01SiZmG7h_2jzkKlu86FnAK-tjI1qZEqk-0BU1XxJLz-Tq2KcQIp7rkhA9DFSbcDGSjOH-8nrvYdYxd7tSsiRS_grQvsn_sxOQPuvIn3Yq3qYaIYVqo65BfhoHksBTvThQY0z3o-Kodxe1Wa24atMMOdM2ixWHHbBMh3kvOjC-p3q16gckQjLUGYwpL9cG1HL_zEj9lK-boqsSDit3Nxxd4MciGz-JPEJNcBoYx8EPfkwTGi-sHXrOhXJOtSyx_r5l6nSZETIIJFJIPEMDOQc_PachQJSHuU0kL0OwqJowT-pGTsVkvOLEZqXJeRtFhIQOT0hdJ8Z8XUWYRAAduFNeEIsJ_MuR2ebXCH6uYNbAyVSTfej_UR7pDNpTd1nOUCN-8AjsiRd0mrHzZ1aawkELHaDGqtEDYoyAlcvOSw0RWD17G_icVRP53XpWk6GKxO5NUN4KN7NKNQ2nRbBtnjxE6EXsXuPdJqi17CwJrKXd0aZUWlc_-AbgTWtmOCspnPrtUv2ym2E0x-sA5SWmLT0aGTBVkhJzj8mxJ6F8lfa-TKcpHcgtpKMvirEZITdywCeIUA6ZlZaTaz8ZWXfKzgZ6tWPuGe_I21J__iPwo8Sefpt-A6nGJhkKcws6OYDn-AtJl6Dq8iCdb63DxIZXaPCNFh8aoIrPXREOwY_dwxQVgOnA-so6J3mtTm98IbvZgbvbuOx0Mhw0IUci5WBQBOLbgGV80oqI9rsawznDiQ4zPZ6iVCfBHHC_yd66neZz-pJnnYNdNDcnGj0UONX9QBSd-CHx-yEtQ2SXKgoadHeulN8EXtqX3ZbFnMS0eErWls6h5b-Xf4KJW9S6ePramLffn4n_hIspIxB_uZfQpmn4vGnDFn4UeMds9RtxEd5xAgmYaFUBgRDPFyVOpRorn50DRK8kKigArRwxTaezvPE0YEqlOgVVDVhyD9MKbbaNx7dYf_T2SpogowqM0hoEIp12aXDmSbOUhz92IGlwv6KqSpeLmXwDzlrR_nf1pDqm6guz1qudvlvnG7bPQOX7wVNr99NkawBIKyZ1DLFtdJ-gE7MAQAHV2jKOMHGzEJ1hEWLAFHli3OJmPUY2GV4qjSlLTdnOMBOAulIxDJ-hhYbpG4pJ9Oab2sTpzQsTCn0GHJ4k--WpLS-GNxtl9XlxJ1KvmCaxubj7qDD_LnqgMM8phatzKndLPTBJjYZDPFzAvbikBDjgedKr7KFOBbg776__ROQT6vv-pBVwVWxAasYxkFXvl8RcDVV1391D7UXvBDuO2ylhEWwmKknbYE2D3kvk36A5V9wWqVVelE2W8UtpRA7Rj7ECJ8LFt70Tq3trFPSp4nheVOlOyh5VLQa5pQ12lBig3ElMpuuO4mH1EYCHbz1iAYH_3awJagw12E4jyIgcJzsaDw3aVGJEgx2z7JaIH7rAPirz7nCec9NtkILCD5KBX-QxCKd0FHYtMzF_ZfzKG6BvREgkcGH_ahkbOmAeBa_UzYPirsxHVJqCU6DsyNSbliIRUsR8QCfalJGp3h0MVtXheFU35n587fGALApSYXc5vokij6HkCqHb1V4kzxqK9z040v4f2i_aVmnmO4Y8pmTHNbZdf6JwymPfac3rVWn-_5KEoqFKXrx4E0jHQwLzTJcBQyZ6tQr9Dzd20PMkT-RtLl9SWb3hw-SFv7xZCmV0SGLszcFKiGMmRFSQxplyR85UXjHsz2rzLqsQ1Ond6hzpBJc4jtFHlxwZ8EeR4oE2IEY_yyX-go1YbVjNcODe16BXMCCoUA==","summary":[{"type":"summary_text","text":"**Refactoring assistant turn completion and dispatch**"},{"type":"summary_text","text":"**Designing multi-target status notifications**"},{"type":"summary_text","text":"**Standardizing send status formatting**"}]},{"id":"rs_09e1b976fd09b09a016a58923576c08199ba2160da404464f9","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJI-UbwqxvTdUN3Ze0qcQy8RRLG2mldJl-FPHk_qccqkqdTktNThfrrEOIeJb44DkCNTZZL4u5BAqv5cKSmOsJVXdg640UeVnYUSEy9p3X_iN0lc6_t4S-oWw-2QQrwlXHz1v9bB0aojShRtwXxVEpiptza9yrrwWkcuJQ-17HT8oYSJsZSie1-2qRi_Y88b0reV_8_1-phgS3TJRTkfDfQAjj5CpFQYPZq6cM7nR3QuFqXUZ_AWDMQqsWx8wx8OmgzTfyTMdK2_B1CVsRl5EWkzHyF8PuH3m3Gz8vp9W2YJiUZ9FpHq3gJBTKjYP5vJTQCKFsV8OisGwd_D5XOxePd9MgDmlTSVeNWZkK6N33KiII5gw86OOVeuZ9qS8e3XuSUYvXaLExPIr1XyfU2ZexXxoL-bbHOhGgOrL-31OqaI3qqAlY4un_Y0uZvgOSsJUUikefOyGvwYp2omHYX0xfa4z_vwxWwXNT-Py9CZ8HsVA5J0LmZz3_A86eUoOP1-7Y0t6xUzSv3yZmnP6wBU4ZZBalI0Ql7R8OPGmVwk0PVK6qxCqSIrQmArRVjG2l8iAhcY_6Q1WqsA9A3f43AUzoWyUEhDvTgY8Aa0f4J7yUGa5_7xACmah6N7ofcj9EoynZvOUyOuTx4kOTivT9g6sDN_8bn86mGb7mIgBgmhK7WeRWIx2EHzpEePkXOhe6gJfcltXudm0F0DR6T1wZ7qbq6n6VYWZh_T6amm7EYwwF9iglnex23aW0zpUTwOp-pb4dp7cHVhs-x6HVM9TFjT99oa2bK9vq9_VFqnN9bi29-BXUSVq1xIw02xTVZBftoU7uDy69bTPqfh-Z_YvkeonlhVl5R6MSU0wvw2St3VHlz9Ol5AbfbZ6QLehJPKhOFuIMYHhIeRUQs66xzRvS29XG2mRCZvuz7HmTxcx6320IQAlHgZptxd0nlOq4Xbd1gNB7cKRZymT5zHfaGwBNHTip6Nes_6IuvVwzcIaHDJmlZx6nqIS2hwBNFnCaieZhD2PDk1ko8tSRNeFox2K97bb0108j42Ld8YVwwwnjdHUpHn9yESD6xd97N5JJhIle-5bmn1vigdgQTLUsG6YZnm0I1TiYtiBLDS4qTpDnhPBSH5X5cgYVOEry16_nxlHpqWsVYcdefvjSMzn9PaxohNJRFDjc5pz5J8_R_i3rFnEse7OGxzuizoir-YXzIk803gAuyVuJBYr1r7tG_1IVQbRg2fyKbHk_i5BDABimXAhK5EGyLIFoJobVr77MOvQxKdnHPl3YA01xodSQqH6u-leKBK1vgRecJoGDDE0k7oLEfFAc2IZ0aR-g9Szsu8OpLjrWxqqiIr3ilE00e4dHw9u61Em_rteJyya0UM86kVspa9jEolRN-Fq4zXEIlMBn6Wy4wfeySNKON5U1QjdeBy8hYWpXz02tcHJAGRdNGlTHwLnWBY45XPkGcTiXF0tI6b2WjzM1hdNKZoK7hSqzmC9_njbrMPNaTc2j8f4y3wZW_Qf5SkLUzuFFIzaiidO2e6LzZFVCJxEqkv-ujeDSa-JCo_aGcqvQPQGJsigCCGUzpooIOJXEiMuQIaZJ21WgxIl47KizvaVRT8TUvf2aejq6LpC70DE-Ser91ngRwirbq9jOyeT6qDAldDXo8WI5HRc_9bnmtyl-jShyMXmU1YzseR9PeEF_SMXUCZKYX0dY1hYBW78C8Rxg3p4RYZyAz3SdaSNUfS95QlGAMs1AjJsKDF-wU-1yC0M4WMDzcf_ISW4cJBj9BFsvG2HkCphUyY00_k39QQSiULR6pJl8rikFC2KYcGsbBq8Fg36fEs1_qEOXKT4oY98WnFQhfdxV1XBJMdDrr2ihO2Nfeu1cRC1hM996F1-d9an0C7P0uePuPiUSu5_VZsssVvCtFUu8vSNvHsBUuVtZuI-C7OJWgmOiboS2WHV4ezHW8K6ATLsIZHqFg4bpU93vqWJxFJ5KkVDr9mVALbglrCMkGy6XyR6sWIqI1ZZrBh0BJB2rZW0w4JZoIqpCQ2agbV03dixlgR5jw5zrvfQl8UCIPE5paGeB_cG6-xxqMKs3SSesS0scUhRaq87Y5XDnB2nv_aGUfSSDD6SoJO0IOG6TGj9rA2lpQ1BCkmmTHd6kgYbxT_ZBEpC-goaLCpS9qWs6CLSnNuqDorpTsGfM8SDN7HZU5iBDRYsOvrKci2hNrFfC5ttDDpSEtTGYUpiMh28P_Jcq9H4TDS4qZtN84o9ry5Wkx1BecOGe84KRMy0e-4C37LSuxjVAYStyd-EseHBcze-IFO3xGknokNXQc1eVLgbUGD8JHXEedFa8az5tl-DcIQejvm_55KoRhQgMoeqGNni_hv_8UcFw1bqb-56oZXPvK25DdeTSO-Y7JNUQxfkWA3azFFjQryU5j1vPnj3mZ0AL8lJWy-rGy2PDtYReUEGMObd8XTGoCwS29qoa1LziYv8WtAG1Bl0uF_7-jNnCBulaSVnIBedMjKm-Eq6s0XXG4tgzdnZUBYVxH32Wz69TE0HYJV0N2nkIbvqZKRJAokRZv-XnartQuiDaM-0xXTqcUMe5RsCHLGusNcx-Q7AoYWP5NFW-ah0aR7aafH89b46d7r_ubKCoqIyypAwTOueFXvKJlIvMMtmV2nh_urpc5vPfmKCJf6R24Tba3cZcbz0JODqR4gjXdixKUNMMGtGzWpEILkyrWW8Fao9p1MzHiZDRksgQm0iAqr6ebL8gRQuif187pQ8G_UvT5-UhT2PEBktv3kJcx09D_EcUNm9ykrdNLFagv53o89owc9sxf7hngAylcqS4IKy397GggqZiceyI3iDrFMVpPz3jF4e9spPDDcBW0qAng0lQCOkECSn0FY-jtD_k3aX1P2TveNjiF-U8td7d9BkoOmbz2in4JmZsF-KwHEfgvxcBSe81jLvh6Lch0cLQsz6kHXfKkdoj3zIZqIMS8iTbYhoegULs8jvh_HOTRpKI8h0EHYOq5FjuMQCb3msjOsO-7uEWQwBMfyQvTGradP5-LikH5t4rEMe6uSR_hxcYmQjdxuNplXmJOEuMziq2Ojh2Qa-FkXMHuWpkAQJPL1lQx_jsIr_8G3nEdAJbtNuJBVTu3I925yrtjc9Uaun0EGKiSF7XkiNMI_rHxZJaf2FhygbdDEfY8vh4fIyUI-nGTXFuzahDMuUAjPdYtjJECPdfQz-a91XtNZvbR10VENw2sFigFV15cNMUuLyiLRPjszNtVrDG1lanpA3oP1MkWLYKjtPFJd2XyqygBgpx82ZZaMxfpAv7ryvTiO80nCr1prtr53PJpvAHVpunCEw1Ok1_xdI02a09Z__3vBf8kYthYBhjlnQArw32QFIrLICI9_W0AG6ajsfIpcEvRLeid8Rmks99VVdeWNFsDFNC2Uea_4d0L53u1JFGiv_1E5g8fKGxeqYH8xjzXnai0yJd8LxSeSYanCZYhK4YuLsp8xmYD4av46PIHfmB0JiOLQMeCGRghkzAl3xA0n-G5ksT-_BHmWcZfTmT4ZECR6kIoXJKKQ_Rv4x4hdPHByTlhjCIqgcJqql3klFlsQGqqOOZZQl2PZaOUmFjKKCwaexoz0zIQiZdDY6Kfcf0vqTKgL-cBpMR_S27D8Tgp1AE9E0KWdngK_DZMsCXkHg-dZTmKKCrTd7OD4fBoBNU2kXp5V-_C8oeMSO52q3yhkV453SY6drFEcFIuXFNI32SxoIQbcxR1XSjLvPvTJfYsoM2WnslbImfDj8UZGpUR4Mf_ci-hm-xmFcsSNC8Cj6cq8jS__q8hjl--RrzV0H1y6fn0j2RgOJWaYG9YQ7KtKUTVo0YdlpszT2DMdEomblMd-CvNUHDeH765fDkzg_kiAlUMK1DKp2Oj6namVBYfK7lG3_E4MB7l4mRp0pLdxkQtJU_1ox6z46kHc6X5ZgniAKX0=","summary":[{"type":"summary_text","text":"**Designing Markdown code fence scrubber**"},{"type":"summary_text","text":"**Planning deterministic Markdown masking and message queue injection**"},{"type":"summary_text","text":"**Reviewing nextTurn queue behavior in docs**"}]},{"id":"rs_09e1b976fd09b09a016a58923eb6b4819981d2c6498c3dd2d0","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJJHGxR0gXRlkPandvHtOrj6npC0VWae2Q6lKT6ztE03-IKPLN_WhjvSYf5oaUjRht_4lcFIhC4FlswAOR6sKBaLinB8KIP_sGvFt-6afovYqS_R5C5FzZ0Wp3Y_thYIt27atrPNm5Gl5zzf6uRWTyLLUDMcmE77MWpyaSUBap8ARWhQE0Px7qTYQYWLbVppnejr5wN4RNW4XpgbGQvEqu-fZhKQ1PAAo1bd1tBkRp5fAl9Zp-juszYmyro8CttTQavX-4QthBpgTt8dE6fpVo2bx1tSZPO_JInv5EUymhTjYR9PvdlEVcJ8NujqmBozp63ockxIxcWD3h3ax_XsuuzM4ca4N_i7e5EdZzlAFP9Xjliu6QUj2AVWCIOCqOmybHj32g-KOSAtLIF-vDE_0HZmJ6jZXla1odUW14CLnhuc4wPsPlxGefpTBzXbZScn9gpsWBfoj_v5PWCIcXbuCl3ghBLCeqBBX00Tl_bhmFHk9EaHX8CO7JHJkQrnUqlcBILs_GfjpDm104-AYexT2TGIiKwPs1u5jNn3IueU2tN0WX0iNZ9jbNn1YtJF4qFPQhciwSqwfVk3zV_gIUDg3fUqF9usAxaxIyYYGTblXO4rV9G1hp5gNJ60YU5vacKmyVN5cXwtDOwRJ6MNdQeEfdky11-SEa07rgNWHAbJM7-DQDZm_FMwicjCrp4W6u8Qe1YLgqmAaLCmgoW7HH5E8T_l3fR48g4h9Hfctkxf0HOWlxdLciZKt_MkV6xeFd2FdTq6Oxj1AMNzCRqU1prVBrXq2Rwf-10Ni-Wb_nEYYSDAoaO4NCEQQP9qSw9tFFiT5KfSvBCQ28rTZozbmI-sJIDn79On-smYmaNIuaGk1H0arkYLqqXQpIeGSome83zZEQNyRWDTsJSDqjCFfUEkkvJW4Grr3OXum1z13ptpLGTV0hoIe7tkwOeimHjiHO2i2b6-xsU3rm_3PyumWYvJCZUF0kEL3Axg6QEvs2_oy6U0caGf5obTfOKzj8Hd2av1xu_JmYe70-3N8Jcj8-DAgWbBOTvbYYjIkyGmgQMTN69srI4HZ8YqfQZ8krlFM-7ixhZEtbDU_NJZZnJfBbskWK36W4TFCylb5i2vk8utwSMrKr7j4AYnYp7x-XS-F0xaEIngvWORPZRc9VpFzu7uwOiijiST_15XJt9TZO_taMp40r_ftM16O0s0GZioQfB0-zb_eGOTNKGnmWVmgc_SYzSbuaWeSR5jUzha7iapklFOQgGD4QvmXcXgJaeOF68xN8lJkBMfqn5BSoKh0wFNR6swifzXz5UYHtvuqJFOqnlfrxLkmJitVtjf2F2o_39qBnYnJ7-rYhW8tF5C0tjfUYC-qYXHDH6Q2d5XdCsQ-H0Xi_qGBwzt6aNALh_3BZTpefYVhPgsVCwEr_HcdT5ayKj_CcWAza4PaUtF01xm4HyKx_AYKw8VznDl9Y5v2zmgTZQnrlKkN_3LOEHs-xenGmc08iiymSUoE6kYvCSwDwXfCiB5u-rvLTJKRk4ocEw8sRAsuNYbtPx1rNdFL9a4djSuHl2yl0Bbv_QzI2qzUaEy_12gXhZfolE_uttIhn90OygF1HHLNj1Dv_gfWyB80gQr0qjzf9pROJUFoOW3kYsLI0RTtvjETojIWePyC0_PTrLqa_DvlkrGOj052wr6hiK-a3xNXflV90Ed-JUkTjeAhgHE7TFG34vJdMwbrcIbIEhSN8KLU_IaJWeavi-6xWws9q_2KAKvYqzUflfaAqo9rzHPhqQplOVz_dwZ0f1xdsBxA5azaLaR2R-mw3sHSp-0-biHI_8vpK0vj8bBCXZevo9GCIyeE_XrPEGGMsj6KF2aIlJYDm4XjOD3OJohnvTJ5wRgaDOUKZaMOwU2KjCWKeAJ-jzgU5MU0fLx6b7Fgnk1Y6mxMidyIqKBkRZcI8wIikqaNoBx9tNynJLqh95cIBB6xVkmMA1aoQiIT78ln9HeLHFllaXKDArxJmg4D7K0K_2zykTxURmxSXazQlDtjLI8GMBK84VxHDa7qGFr1rRWn0VPiyH2XXgd56AICoucmQJSNL-VyL_0CT4TaK3EHDB1qNGexRbh7nczRncOkxpLUkVgzhlfr18Srss1lZAc7zDQpY0Nkg9vLr92fZtrBcpeJHEltGS3yQLqcxq0uXnLZnfElIjGgvKTz_V6x3DbY10r8ZPC6ktuKn3KBUQcEmuHV8jfcy3-TzIAhsmx2qZH3-c6ef3Q5wJOUTcOshn_hCOscP45wgFa2FTAjmnxpT5QAqXTuTyaiCzCRV2DOPTIbhHsbI5cINcUpi8p6FT3OlHTjPrUlDAzSra2IQwjJPBW6SEH0corfxlhD13dJ12OTrihAEhCIWFdaq2tSTmFYdWvJjE2VQ4ITeQ2FRm1we9l2NmthTW7fl13pX6J_QQig0PkLl1CUHbSU_V4C2qcvPkznQwcFpQwntVtrMIkQHdVGd3eOQkm8zL014udhi-nbU6hRWqAHS33cqZs65ol8qhkpyTv4QYbuNoEe4V9lhL1Vnfr8er0bq2bVprDpN54Pdc1PEUMXqnKRIg4TywycPep64D5o8sFUSz-ift08rOygGmkdBzCWCKNprpQwHIOxtX7TrE6_J8g-l5XLyySC6WuPlnk0JUZHFmhp5KoSUpaMcn3jtEgNrBZfehQwgpLZfF1yzKssF-kTfpt67DJIcZmQk4WsOUJpC_ilxYkO173b-l0feHKY0qPO-SwZTdYx0P90yKvGeEu1J4X1Jv6nhZ9OEfYCBTXEqWd-dr52sX7Xe7Sr9fkvKCL4DrZl5VLKdem6Q7cdERqV2_xF_Kl9XT6UL1gYavMpNRK9vis9dxc_FoQ-STuBuRUmLy8mUdgSLfb1XMW6EGmQoUor9xoVsgt8bKBsr3B5PLt0F40xfV_9LOu0aF20SyRdVYVCaB5pviGbGBWx8H3nzfQt9XjtZEUo_4zuHG6vbwpYs2VhlJhqHOtiyIIl34j7SZIoDhWG9nSok8aSy1hLxgsTWG0XY8TuoF657kw2iLzxwIMc3DvJnnt4FxeyrIrSDbvmZ9ASD0ZBsXxHjBBrUrfJ1LwxEwvKd0uQyyU_80_udap-AqJbEirqvuEkI-02tdSgDofBOWx1ihm6pR_FgdubRTLTKZYg0gyhpkntjLVNkKTThJ0Bv0aMAQLaAOnSiDQfBet4-vD1GCX2bmGaG07fMldpfvw3atnWYN-hkfPx5tj7_9Ma-rJ3xMv9Uof9N-cATu1NzVcG-Y8do56ZycRyhiuWMbo8Bd2JGqGSl0mlTysdgo3ANkSN3zHsCwDVZ5ZRsWlVZeVzQidGoYfzXovb1Eu1vVKAqmJ_UxMWy_J9NEGlagSZ7VCq8OLwURdjPoVq5tfRytTMjFIAerm3tW4yhwFvYoPqj78RnK1ipnvhRXpO5PlBZJIwQ-4PR6p5BIsNYoYQ85BSCjcpl_29GNdIFTzJyaUiFEptfxWhpFPGMffI4-12xtFLBbx6bCHg8B6DCZiJG-izpO0MaGpWQDpnZzS04P7qkiRbQYpxoHMS63AcZP7qTp3q1G30-cD3jQ5fpjUFZYIL2kAM1Greuo3PbzqVo5Pa3jBEVUNgQfhXw7lbNJ6FtK3nK951ztMjNHQTIyuSzfCspSNua3C_NZBIjf7bYkhqEf1DjHnQDIYkqHgfp9SmtRwrX331Z3-Qso7U5qfDE8IFzf91XQItNwSmbp2TBzZLpdf9pvSBXtmaFQG5rvopozk-sIQOe4tIhi8_dvxez2KID9QLcyW3lROa0P9XfOMYRBDAH3N3cZTfiuEiAFawpn_W_8p_U5rdRP0BySOKxCklJr2Fx-H3EJl3oB3upjX-B59Tab-5G_3NJSqyuOqZqPfMYySaf1wYUsydk1FKyNQzNkul7_ev8fOU1iaja54ZOeP7s5z52tSJyQ5f-Oc0U6EdOUoY8wRuCzQ2jzp2n9dW_nk6WJbzqifhkkryEcUbm72rg_-iTXO3g_7Ph4iQfOASSPMkmo0N0whC75nDqp2XhJwjqlmqcMzqIdxWyYugLu1a_iJ_w7W4K00b4z0bJEgsG7jLbk6pptyWtu8kpS5C-KDn5C7OLcfen97Cegb97F9GiRGFRln4JoZZT2TnNkN8P_bOsaJ3J4bnKbmUHrCNHadOuCraYL9XqozJczxEjzgysI469HOWuzHPRaKI-qLdi36nCrVG2QHxjEsJ-uyTsL7vhaU8hRzqAqRgpM41q4SP2VqcbsA_gPHDFquq4P2NZDUDoGPrxv2lFMEMzVObIFlxbTZhfLBNlrz43QCHtPZUdosQLmm3wPgFsNrJCEqG8ZOX5Qzhywbg-fNa1WO1_gFC_82f7yy24_LHghaY4CJpzNsDq5AAjj_YVSvTxg7j56ZEoVIHgYMAq4HZuI6vb-wRp3xE-_lHG1GdsCQEBrh1CkdKXtvz60J9Je1BlVKpix1qApVFTFjYxPa","summary":[{"type":"summary_text","text":"**Planning message injection before tools**"},{"type":"summary_text","text":"**Implementing context event message injection**"},{"type":"summary_text","text":"**Finalizing single-message injection logic**"}]},{"id":"rs_09e1b976fd09b09a016a589247d2fc8199b44414b305cebba1","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJJSxYQYGGq34sFBbzzBopR_m-143OdKGGtKBeMgwSe7vJ67arbzuBrhTK7ZC8a6XKR2TiMGzLNcG1--ZlPM3CpHZ65vDyznWFvca7Jxs_ZJyXJ9SAiqzyB3ueXPNYjS6xETkq_L1DWsciJUzjTQ-daca54AvBtAjR0ui3DUx3cqqoA87V_5nenZFOUon0Uj8VL1e1nao4yZVmldtGuxXcIx7vSN_ELyrGx0YQB8Bj7k-M2IfUrftb1QiMV87ZA1G_5YV55oZEfdtOIDlGazZOTYWkPkHwy_klYujxiwLCmTg-74TcUvsv4YBFXHdvuIZh7nnroJC-ORi-WRLzo0gwiYs4jW10yt6_3__K45xNGdhQJ9CDfx5O7RMGB_8L5tXqh5CoO7lLsMvLBaglDc0578DDvZZAV1PwfGYDDTQHpMkuS_MR0-L5TntSnbuTNVHseKpr4gBrkQntBVQIExiwDteWT7rpXgzHSx0PQcKOHUYvaKwmsu6UyQReu8lIPSr0uvGNIft6aFRvCp4bIp7qxWysYvq2gs-FcYwa3UBEac19rnsRFVgXXgSMtfjaC0mK8bXVfMscMvFmibwq2ZXOXO6oEImdyI1zSyvTig2JOZtDCnU9CtPg_AQh_p8hbc2Wzqxyr0GDqp6a24o7LWvJqgafqEzPf5s6rzvQ_xWkN0dgQfjayz5DdNuMLJXpwiF8syKFtfFRbUr_rxIuedSmwEWDLE6FFy0hz-9aMSljYiCgD-xXTaOjp5NwWJWq-BkglPG50z-ZSbe_8558aYTfiSRml9re8T93BNjHa_qLY8ltr1T5MKWlWAwP_nSl52Oq9VQjWpSnJn-tjYQLUDItB288iVOp_D-aHrwZksTqZUfklAAZW_3IX7UlFyf96UEEffIR-aTiS5nlZFTsgx5CPLZKKfzOWsQ-xozk_pguj3fPWzElvV6cZ1-mfQV4E_G7tECNBzwrSEOHinCzM5VKUd0o9gA5elnpxbCjDV1EiJLKx-Jjrc-tSAWEe5jUSoU4loF-MFivkN6y1gNvINVrYB9QTgRUTG4kXqTOKkXyL-6J0JjJ1RzlXUNNns4XM9wKqyN4YskwlOQ4yQkUfQH3kyarMrzpHus-7H8AdEp1LUnPE6gxPJJBCF800rm_TkAdjQyKBznzlEC0qdqUQfs3hFp8mn17u4xoBikB6B1jDifs4rdIKNV1ij32xZmmlWh8b2Z8RvZGsTv9ajXf0g8M5BqS9Wos2kBtG2TZlv3d4lUmK3qXfNnHDrnZALqGqJ6doepKqilkfM2aWgkFFAlF-0W0BkrTEsbzBs6hNnXx-slG9sbeZOjGep1si7r6jqG3K6wP6d1jkNGjFD-hyaPQ8rEuw3CVBle1UkIrzCbDgWEPmVhEWkZJ1tYbgCblQ36JPAA8oKqgWCMRKyZv51B3f3_by7CuwdwyRD4BNtSaQlJMdBd-px_WOjxBA3Qq621f2rvZf56M5RuWwkML8KQWMwKy5oi8XASlj33e_pSH_JUBOsRbXJJsaccVwBfPtck-LnQPOHxm0YUyCMzg-xkUFYH4hpRySQqau6eC72-9gZ7A-jHVD170t9mqRCu3MUw9Zwu3bs4nBIZu2svXBe4H1hB3W9PfR9v-VM5DjnLWc0YXO-u5N_sPAXW22sVDl0JpQ5jWwH3rqxEPvwjxHyAsmQTs86cXUjam8i1NRB0c-q-_09bIxwoHFUfMC8beOKkBFxx8aGP2VboKlx5NJrme1Nt843A1mM4YRcnjZtZtMP71fxOZZPIIa1pq9gATDZI-oOmTrlckA99nfv_3qGAJCqXDJdCxmAeJ1Uuo_uO1Z3_vBJbOMh1vmgUo39Xz1ZVabDUvf1Sg9G3IKwCb8sZ1PAUTSW6NRLV2d55tjh8uO_B8WLU6qkskMG_Ly0Uu5ff6D8l0YPLu_JcSV9Ij3jxDsD4zCKrCiYv8EjBLdPbD8w7bqVwo228LoAt8LynsH86ovMlJLS3svILjK62p7AhNh797EHMSw_X5QyF1MNuBuvdc5fwwjVEnhQGoCTrYJ-qm_Jhl_4x2fYbbOtYNJWNtTaK2ACXWjPUE_oBfb8vBVwjW3e-3sFIN-TfeeQDw3X9iVHtdEVgqwYWvXsxlrIRFAV4G8xGn-fALK5XAvKlYb80ei17DwXGt_bFEv5ExEWx-4R_IWoVwy1hQAEwzaeIqF5cCr4DoF6TcV_qnw_OT5lIAFiRXUqo-fPIn-PbMzVrozdFRlB-Dn_b4-DRRZEQ3BTBxngu7ZB11nenjXfFSNl_5FLq5oQQY_FUv5MrdKvIjy6uDC8Z0qt-EKzxTcP6IvwFFHyERfxAXHrm_byDrGywreNpF2IP5iD_2lwCbm5Ecd9v1GBB1jO5Rj7Rj5cg42eFwnHwvetfN15c2MfrgcWy15gifcBD9wjNpJS9n_zRYSQYPrXaJkKycUaXcX9vKPjXdcD7r6-Bwq695zPPlOJUiWQezSekwRGLlrrBqn6CLG45B_u_mYutpZ9tg_H3nqoFOq_6h8KmlrkF_VFRrlUlzRndt4I2EsFuGsml4s7d-2gsgMVH_GlQ0Nbh547PZ-a6g6Wm2byeEQfoAotsE8OHeGQknK-ZzyWmczE2ZaLFpwF3htpZr-FH-MQ4Ivtq42PGl0IpAFMKTOw-Y26Z4U6NMx8XIIaRKw6qjsfAStpSAg_CNihYP2CIFqzUAUqZ-UcmcVqEkwn_vF7983I3gdFtT-k5Qt8UWXuigjrP7x6meZhk_CO4R1Ct3kLXMA41j2s-BGWGMWcK4aau8_HSb4vG5jpELjSAYRef6nGzElq5eGR5Dtn6F2mBPlT7ptRnDohnSuWevcTRrSH9wO3b9SA5M9hH0RNl-5HDI0Jsg1qDXu5ObdZDvzRCnmIg7DaJMeJDVDGQ71_cNvbv0j7-MkT-NutIHOU6otcsEvaccr9i0OeD06lvCwVA4Y9o1nzCZlGRIzjIs4tXhXiIEJ7kwfE5G3Msfawfw-R3ONDGB1vNDVi","summary":[{"type":"summary_text","text":"**Verifying turn completion and custody handling**"},{"type":"summary_text","text":"**Planning enhanced failure message handling**"}]},{"id":"fc_09e1b976fd09b09a016a589252a0d88199bd86082512382e8c","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding agent event contracts\",\"pattern\":\"interface AgentEndEvent|interface SessionStopEvent|interface TurnEndEvent|stopReason|reason|error\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_BBPwvTrH6TUnWql5jbxUt159","name":"grep"},{"id":"fc_09e1b976fd09b09a016a589252a0e881999fb1db754db2cf1f","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading OMP shared events\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\",\"selector\":\"1-260\"}","call_id":"call_4JMuqwsm3sue4zqK0zhGTx53","name":"read"},{"id":"fc_09e1b976fd09b09a016a589252a0f08199b774f32d96b8e7d9","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding context event result\",\"pattern\":\"interface ContextEvent|ContextEventResult|messages\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_qCO6LWWsOeGfNYDSFCM0Ebeb","name":"grep"},{"id":"fc_09e1b976fd09b09a016a589252a0f8819998fe9fc12dd148bd","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding compact signature\",\"pattern\":\"compact\\\\(|CompactOptions|compact:\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_ROTlHLUtWc5OzPovaWfdPAjU","name":"grep"}]},"duration":60195.16100000008,"ttft":2033.829800000065,"contextSnapshot":{"promptTokens":131912,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_BBPwvTrH6TUnWql5jbxUt159|fc_09e1b976fd09b09a016a589252a0d88199bd86082512382e8c","toolName":"grep","startedAt":"2026-07-16T08:12:03.103Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"},"intent":"Finding agent event contracts"},"id":"6f09a833","parentId":"88b553a7","timestamp":"2026-07-16T08:12:03.103Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_4JMuqwsm3sue4zqK0zhGTx53|fc_09e1b976fd09b09a016a589252a0e881999fb1db754db2cf1f","toolName":"read","startedAt":"2026-07-16T08:12:03.104Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"},"intent":"Reading OMP shared events"},"id":"065c614f","parentId":"6f09a833","timestamp":"2026-07-16T08:12:03.104Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_qCO6LWWsOeGfNYDSFCM0Ebeb|fc_09e1b976fd09b09a016a589252a0f08199b774f32d96b8e7d9","toolName":"grep","startedAt":"2026-07-16T08:12:03.104Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"},"intent":"Finding context event result"},"id":"ad5f532e","parentId":"065c614f","timestamp":"2026-07-16T08:12:03.104Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ROTlHLUtWc5OzPovaWfdPAjU|fc_09e1b976fd09b09a016a589252a0f8819998fe9fc12dd148bd","toolName":"grep","startedAt":"2026-07-16T08:12:03.104Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Finding compact signature"},"id":"a8ef0321","parentId":"ad5f532e","timestamp":"2026-07-16T08:12:03.104Z"}
{"type":"message","id":"d014d2a0","parentId":"a8ef0321","timestamp":"2026-07-16T08:12:03.252Z","message":{"role":"toolResult","toolCallId":"call_ROTlHLUtWc5OzPovaWfdPAjU|fc_09e1b976fd09b09a016a589252a0f8819998fe9fc12dd148bd","toolName":"grep","content":[{"type":"text","text":" 352|\n*353|export interface CompactOptions {\n 354|\tonComplete?: (result: CompactionResult) => void;\n 355|\tonError?: (error: Error) => void;\n 356|\t/**\n...\n 415|\t/** Compact the session context (interactive mode shows UI). */\n*416|\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n 417|\t/** Whether UI is available (false in print/RPC mode) */\n 418|\thasUI: boolean;\n 419|\t/** Current working directory */\n...\n 478|\t/** Compact the session context (interactive mode shows UI). */\n*479|\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n 480|}\n 481|\n 482|// ============================================================================\n...\n 1422|\tgetContextUsage: () => ContextUsage | undefined;\n*1423|\tcompact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;\n 1424|\tgetSystemPrompt: () => string[];\n 1425|}\n 1426|\n...\n 1436|\tnavigateTree: (targetId: string, options?: { summarize?: boolean }) => Promise<{ cancelled: boolean }>;\n*1437|\tcompact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;\n 1438|\tswitchSession: (sessionPath: string) => Promise<{ cancelled: boolean }>;\n 1439|\treload: () => Promise<void>;\n 1440|}"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":5,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","count":5}],"truncated":false,"displayContent":"  352│\n *353│export interface CompactOptions {\n  354│\tonComplete?: (result: CompactionResult) => void;\n  355│\tonError?: (error: Error) => void;\n  356│\t/**\n     │...\n  415│\t/** Compact the session context (interactive mode shows UI). */\n *416│\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n  417│\t/** Whether UI is available (false in print/RPC mode) */\n  418│\thasUI: boolean;\n  419│\t/** Current working directory */\n     │...\n  478│\t/** Compact the session context (interactive mode shows UI). */\n *479│\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n  480│}\n  481│\n  482│// ============================================================================\n     │...\n 1422│\tgetContextUsage: () => ContextUsage | undefined;\n*1423│\tcompact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;\n 1424│\tgetSystemPrompt: () => string[];\n 1425│}\n 1426│\n     │...\n 1436│\tnavigateTree: (targetId: string, options?: { summarize?: boolean }) => Promise<{ cancelled: boolean }>;\n*1437│\tcompact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;\n 1438│\tswitchSession: (sessionPath: string) => Promise<{ cancelled: boolean }>;\n 1439│\treload: () => Promise<void>;\n 1440│}"},"isError":false,"timestamp":1784189523251}}
{"type":"message","id":"1b0347e5","parentId":"d014d2a0","timestamp":"2026-07-16T08:12:03.253Z","message":{"role":"toolResult","toolCallId":"call_BBPwvTrH6TUnWql5jbxUt159|fc_09e1b976fd09b09a016a589252a0d88199bd86082512382e8c","toolName":"grep","content":[{"type":"text","text":"Skipped due to queued user message. Do not count this skipped result as completed work or verification. After the queued message is handled on the next step, retry the skipped tool if it is still needed."}],"details":{},"isError":true,"timestamp":1784189523251}}
{"type":"message","id":"fde41bd7","parentId":"1b0347e5","timestamp":"2026-07-16T08:12:03.253Z","message":{"role":"toolResult","toolCallId":"call_qCO6LWWsOeGfNYDSFCM0Ebeb|fc_09e1b976fd09b09a016a589252a0f08199b774f32d96b8e7d9","toolName":"grep","content":[{"type":"text","text":"Skipped due to queued user message. Do not count this skipped result as completed work or verification. After the queued message is handled on the next step, retry the skipped tool if it is still needed."}],"details":{},"isError":true,"timestamp":1784189523251}}
{"type":"message","id":"1e9805b5","parentId":"fde41bd7","timestamp":"2026-07-16T08:12:03.254Z","message":{"role":"toolResult","toolCallId":"call_4JMuqwsm3sue4zqK0zhGTx53|fc_09e1b976fd09b09a016a589252a0e881999fb1db754db2cf1f","toolName":"read","content":[{"type":"text","text":"Skipped due to queued user message. Do not count this skipped result as completed work or verification. After the queued message is handled on the next step, retry the skipped tool if it is still needed."}],"details":{},"isError":true,"timestamp":1784189523253}}
{"type":"message","id":"cd2c09c0","parentId":"1e9805b5","timestamp":"2026-07-16T08:12:03.280Z","message":{"role":"user","content":"Your current interruptible wait was interrupted because an IRC message arrived from your parent agent `Main`.\n\nParent IRC message:\n\nPlease own startup brief, targeted hints, and update-notice injection in omp-spt.mjs via the best public OMP event seam, including focused tests and REQ tags. Coordinate prose/keys with AgentSurface. This is now explicitly within your extension scope.","attribution":"agent","timestamp":1784189519816,"steering":true}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `AgentSurface`:\n\nPlease also own startup/hint/update injection in omp-spt.mjs (best public seam = before_agent_start appending systemPrompt; no-env lifecycle inert). Contract: when SPT_ENDPOINT_ID exists, first turn gets one concise brief covering `spt whoami --json`, `spt endpoint list`, `spt how-to send`, commune/checkpoint + signoff/role/setup skills, `/ready`+`/live`, `spt how-to subnet`, `spt --version`, `spt adapter version omp-spt`, `spt update`. Per-turn clear-intent hints only: live→`/live`; identity→`spt whoami --json`; messaging→`spt how-to send`; subnet→`spt how-to subnet`; checkpoint→read commune skill/use checkpoint mode. Update notice only when known newer: adapter version vs bounded GitHub latest release; core current vs non-dismissed newer `spt-update` consent notification from `spt notif list --json`; network/probe failure = no claim. Notice must give `spt update` or `spt adapter update omp-spt` + endpoint restart. Tag impl/unit for REQ-PARITY-STARTUP-BRIEF,TARGETED-HINTS,UPDATE-NOTICE beside real code/tests. Can you include this while owning file? I’ll keep package prose tests focused on skills and will activate these requirements after your test evidence lands.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nYou are mid-task, so a side-channel auto-reply was generated from your context and delivered to `AgentSurface` on your behalf (recorded after this message). Follow up with the `irc` tool (`op: \"send\"`, `to: \"AgentSurface\"`) only if that auto-reply needs correcting.\n</irc>","display":true,"details":{"id":"1531cc0b7c5b795d","from":"AgentSurface","message":"Please also own startup/hint/update injection in omp-spt.mjs (best public seam = before_agent_start appending systemPrompt; no-env lifecycle inert). Contract: when SPT_ENDPOINT_ID exists, first turn gets one concise brief covering `spt whoami --json`, `spt endpoint list`, `spt how-to send`, commune/checkpoint + signoff/role/setup skills, `/ready`+`/live`, `spt how-to subnet`, `spt --version`, `spt adapter version omp-spt`, `spt update`. Per-turn clear-intent hints only: live→`/live`; identity→`spt whoami --json`; messaging→`spt how-to send`; subnet→`spt how-to subnet`; checkpoint→read commune skill/use checkpoint mode. Update notice only when known newer: adapter version vs bounded GitHub latest release; core current vs non-dismissed newer `spt-update` consent notification from `spt notif list --json`; network/probe failure = no claim. Notice must give `spt update` or `spt adapter update omp-spt` + endpoint restart. Tag impl/unit for REQ-PARITY-STARTUP-BRIEF,TARGETED-HINTS,UPDATE-NOTICE beside real code/tests. Can you include this while owning file? I’ll keep package prose tests focused on skills and will activate these requirements after your test evidence lands."},"attribution":"agent","id":"d18832be","parentId":"cd2c09c0","timestamp":"2026-07-16T08:12:03.280Z"}
{"type":"custom_message","customType":"irc:autoreply","content":"[IRC you → `AgentSurface` (auto)]\n\nThose startup/hint/update requirements are outside my assigned Change/Acceptance, so I should not silently expand into them. Please ask Main to reassign or explicitly approve that scope. I will leave `before_agent_start` unclaimed; after my extension edits/tests land, you may add that isolated handler without colliding, or Main can redirect me.","display":true,"details":{"to":"AgentSurface","body":"Those startup/hint/update requirements are outside my assigned Change/Acceptance, so I should not silently expand into them. Please ask Main to reassign or explicitly approve that scope. I will leave `before_agent_start` unclaimed; after my extension edits/tests land, you may add that isolated handler without colliding, or Main can redirect me.","replyTo":"1531cc0b7c5b795d"},"attribution":"agent","id":"eeca27c2","parentId":"d18832be","timestamp":"2026-07-16T08:12:03.280Z"}
{"type":"message","id":"b24d1ff3","parentId":"eeca27c2","timestamp":"2026-07-16T08:12:10.673Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Correcting agent response scope**"},{"type":"toolCall","id":"call_3G2hOTXqrjjuSyuG37kyPf1w|fc_04021f03ca68093b016a589259082c819aa91daa8ee05175bd","name":"irc","arguments":{"i":"Confirming expanded extension scope","op":"send","to":"AgentSurface","message":"Correction: Main explicitly reassigned startup brief, targeted hints, and update notices into my extension scope. I’ll implement your stated contract in omp-spt.mjs/tests and own all corresponding impl/unit tags. Please keep prose/skill keys as described; no file overlap.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":4631,"output":141,"cacheRead":131584,"cacheWrite":0,"totalTokens":136356,"reasoningTokens":30,"cost":{"input":0.023155000000000002,"output":0.00423,"cacheRead":0.065792,"cacheWrite":0,"total":0.09317700000000001}},"stopReason":"toolUse","timestamp":1784189523485,"responseId":"resp_04021f03ca68093b016a589253d318819a9ca2a8a0b93d7c84","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_04021f03ca68093b016a589257fbf4819a9bf68ba06e48c93a","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJJZU7WlYvD319VDDBlSDaTyy_ep3jI37iRrKa9R47Sm9riuoMpSxNUnXBA0KXHLyQ2CU8ebRaI6PstGPV5B7_PNCABQuXjZURBEmGgHAkVXbLBG_s69DhL6gunVSHHeSjHMSfUW2LDfOIJNVGD-pG661fXAxORC0sJaFqG-Uq6VlbiGcz9F2yJh7UYLDK3KAXTMBoG8FMnKTZbe9RqElsObPUZMOgu7rjQifWlilaI9ewv9zUHHWo-pGnep2eSmP_ABFICyVLFC8UuWyr90IbUQ2Rae56zLntvWmD3i8LGe3nTniZao6E_qvzG1JWoKdmJO2J5TXaWCtvVbUzly2MtUwH8NJ2kA1A3Le3whFQRHVcFq8eYpVEdEGSmCulXThjXZmmQJgPePCgF5js0RZB3O7WsvP42rBcf1WsdOWtFJfhz4E_uxo5HZ6BN2_Hx9NPfvZBueEbSDiHX0GYNsy7rYB9jfM-URDyWzUzlBLLKcKvfiTqWzseKhcv9_YmbrcXW_aQ6monnFCbXxr4cqKvlmr9__mqMej6h5Q4apggNSBfR9NKQ-SF_xK0_T2brIEmlsPXrnv0X8L7Avjrk1Snloe5B9oynuwbkoyFXv5F6Dx3LyF324c1unHz4gP-w_FFWrPHeIKKdVMYI2IURsf4y_sSEFmseofuOK5TNVXKh7MXVD1ZSBXFMlHQUYIjEzFKNhzjBtIoKecY0wDWqNNu8o5Yir82HoF9D43Dsx6N2l-YWCmASJTq6M1SsdwzKxMMCzamCess_FDvkPpVhsAeOZEVd4Cwz-oOKmK4-EqfF2iWWBj4GvU6cOyYw4ETDul-RJKWKDwFeek_dgJobhWvO1ZPERaxh2CxEQVfLepNCKUZxIJg0zdVKbGNb3cxY9FIG_uq9-_1XHKQIhyDC2zVllOpwjRKYexRlyH0llBS4r1gxgO0SWkmdI8uKTKP0GJ4vZt_opWQ7Kds4e01agHxIRWmQIXVu_xpuM3Sat7Lzi5jCMvUts9jZpGWe1txcBXy3nTG7GNNAKtR1w7zmp9rTOzsD5iQXg3hxw6U5Vzzx_Q42tbBmQwYkBUojMZYBPE3y2FIjm7f7T-OK0vdmlNwTQcw==","summary":[{"type":"summary_text","text":"**Correcting agent response scope**"}]},{"id":"fc_04021f03ca68093b016a589259082c819aa91daa8ee05175bd","type":"function_call","status":"completed","arguments":"{\"i\":\"Confirming expanded extension scope\",\"op\":\"send\",\"to\":\"AgentSurface\",\"message\":\"Correction: Main explicitly reassigned startup brief, targeted hints, and update notices into my extension scope. I’ll implement your stated contract in omp-spt.mjs/tests and own all corresponding impl/unit tags. Please keep prose/skill keys as described; no file overlap.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_3G2hOTXqrjjuSyuG37kyPf1w","name":"irc"}]},"duration":7187.1883999999845,"ttft":4612.119400000083,"contextSnapshot":{"promptTokens":136215,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_3G2hOTXqrjjuSyuG37kyPf1w|fc_04021f03ca68093b016a589259082c819aa91daa8ee05175bd","toolName":"irc","startedAt":"2026-07-16T08:12:10.674Z","intent":"Confirming expanded extension scope"},"id":"337ebf1a","parentId":"b24d1ff3","timestamp":"2026-07-16T08:12:10.674Z"}
{"type":"message","id":"d11ccecd","parentId":"337ebf1a","timestamp":"2026-07-16T08:12:10.674Z","message":{"role":"toolResult","toolCallId":"call_3G2hOTXqrjjuSyuG37kyPf1w|fc_04021f03ca68093b016a589259082c819aa91daa8ee05175bd","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- AgentSurface: injected"}],"details":{"op":"send","from":"NativeExtension","to":"AgentSurface","receipts":[{"to":"AgentSurface","outcome":"injected"}]},"isError":false,"timestamp":1784189530674}}
{"type":"message","id":"d3b3410d","parentId":"d11ccecd","timestamp":"2026-07-16T08:12:21.195Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Investigating input and before_agent_start events**"},{"type":"toolCall","id":"call_g9raGdhpSeZpq6pt3ZMdW2j5|fc_07d9714368e86c14016a589264c20c819982255b77ac3b5a1e","name":"grep","arguments":{"i":"Finding agent event contracts","pattern":"interface AgentEndEvent|interface SessionStopEvent|interface TurnEndEvent|stopReason|reason|error","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_BTZZZgRTKSdpXs1dJNGjhTxd|fc_07d9714368e86c14016a589264c220819984dd8eea6d2060b9","name":"read","arguments":{"i":"Reading OMP shared events","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","selector":"1-280"}},{"type":"toolCall","id":"call_zabq8fIHOVkKXyPmw36IvK84|fc_07d9714368e86c14016a589264c22c81998a0c1e7f65d16d4e","name":"grep","arguments":{"i":"Finding context event result","pattern":"interface ContextEvent|ContextEventResult|messages","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_rj5zCqlAV90D7H6SyGHFEWRM|fc_07d9714368e86c14016a589264c23481999396269de29aeae7","name":"grep","arguments":{"i":"Finding prompt event contracts","pattern":"interface InputEvent|BeforeAgentStartEvent|InputEventResult|input","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_NiW1WEg3kd83SmZXw15OxIFO|fc_07d9714368e86c14016a589264c2408199aa851487d81c41f0","name":"grep","arguments":{"i":"Finding compact options","pattern":"export interface CompactOptions|customInstructions|instructionsOrOptions|onComplete|onError","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":"330-430","case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":699,"output":461,"cacheRead":135680,"cacheWrite":0,"totalTokens":136840,"reasoningTokens":61,"cost":{"input":0.0034950000000000003,"output":0.01383,"cacheRead":0.06784,"cacheWrite":0,"total":0.08516499999999999}},"stopReason":"toolUse","timestamp":1784189530689,"responseId":"resp_07d9714368e86c14016a58925b0ccc81999b47e79f25751141","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_07d9714368e86c14016a58925c60f08199ac00294439824aa6","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJJkRZMra3gQQgWmHpy_Txo3_S_--CtWLQJ3AUiBFT3qJIL9tpHZGvomBYdW9pS91aLa8vnfkPTK12p0Oelz_fgEJv-zvv0TTrQtoM1LvyMTguo_fQmG7QSS_f37uJjc_1cn56BgARB9GkCbvNDPZFqU6wxTIQPFcmkZz6H8yCJAaa7WxXo3M7xid93bV37Zp4m4GM4qm5A6pMGb-EwsF7ZB4VKbWGzbPCE35aZtQhO2qrEigynxNsvfftKmT7mgAvpLP2nK_d74qEmBENBK4n3AUXNcD-0iZZUJTuWmVf8mlwFcFmi2LCO30zVt1-WVDWf8UwBT6LeftZAcL4IDabE_xzQRXRUna2uPISpuLaNCN3vQzK3bx_jRuhDa328H50KMsJbKgV0An0iS9n8yDK0EjDDltRJL7zU_5UzLXNlASKx1ItrsBFL1i_Ml-IFszZjzmtCe3gb_QC1WbPAIOKWSSOHider1a0K4Ei1F1IEBRCHlY7ZkChdQKz5_GYCgEVCqmU3TA80vPSXggiRa9-pp2rFZt7U7VZEGhSO_mslnSCJ1r9zbcfnO4MoqjWwoKNrx0Wou5ekT4aEZ7AqCuAcGeW97L1zUK1QrNE2F__HZGyojZgGmnd3L4ISo75dwEKqnQBzIgtxMwcOkkyeaCSTesxjaPN0VTtI0ljI5YrDpzvbfr-9RaSUiF4n_rXlWUpo8z9pqdYadjPQeMZ-CiO-O-ZvcNi-KwK9_LHbpProV4ZmjAKW7wssLal4eQxWJJGleT8Gshk0Err0SJNtFMiRTrocza76KmvRbRou-OAv5YpS84Sbs-cvI78cynLbzTALEwnFCQLMhN6VX-CA95AbfRs0zszP58EAtiezaQI7OzO1euXF799J-p2Jny1XqHde4TUgmU5dPDh_nFIBif5i_MfOTI5PZs5QFGi2YAhuxwcXuMDnALxtjMXOfSHKbUfj1uRRMyNWvQwwYt-gYfqxMUj2QERcrF_lBaSghAq0CylJRmKOIyma9lo0GwVa7NOQGAHotO0aXbxeF0Ipqioeg6CT25_wsuVBrcxDk1tYruErK9dldZEpy-eSKVEivFNi4NDCKBuK08CpcGdUhuUFENKMruN0Gipo-S1YYnW8RnhDl4xntmH6hGNweswrVuw-A2JhO-znh27XGxmLhrBc09dsNf7v2ScHhP4F1GQ_f-w1H5hMGYwAXs8V__7_mUkWoD1mDJmS5sxlzzeBZXJ9jyMID0nq3b0a8lhCZ3vcQ42bi3F2d6vJTuCNJR9yO-raiNaAm8G2S4mhN836Gi5CEmimezkkJOztU7t-ZzoypskY=","summary":[{"type":"summary_text","text":"**Investigating input and before_agent_start events**"}]},{"id":"fc_07d9714368e86c14016a589264c20c819982255b77ac3b5a1e","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding agent event contracts\",\"pattern\":\"interface AgentEndEvent|interface SessionStopEvent|interface TurnEndEvent|stopReason|reason|error\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_g9raGdhpSeZpq6pt3ZMdW2j5","name":"grep"},{"id":"fc_07d9714368e86c14016a589264c220819984dd8eea6d2060b9","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading OMP shared events\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\",\"selector\":\"1-280\"}","call_id":"call_BTZZZgRTKSdpXs1dJNGjhTxd","name":"read"},{"id":"fc_07d9714368e86c14016a589264c22c81998a0c1e7f65d16d4e","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding context event result\",\"pattern\":\"interface ContextEvent|ContextEventResult|messages\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_zabq8fIHOVkKXyPmw36IvK84","name":"grep"},{"id":"fc_07d9714368e86c14016a589264c23481999396269de29aeae7","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding prompt event contracts\",\"pattern\":\"interface InputEvent|BeforeAgentStartEvent|InputEventResult|input\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_rj5zCqlAV90D7H6SyGHFEWRM","name":"grep"},{"id":"fc_07d9714368e86c14016a589264c2408199aa851487d81c41f0","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding compact options\",\"pattern\":\"export interface CompactOptions|customInstructions|instructionsOrOptions|onComplete|onError\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":\"330-430\",\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_NiW1WEg3kd83SmZXw15OxIFO","name":"grep"}]},"duration":10451.189600000042,"ttft":1678.4298999999883,"contextSnapshot":{"promptTokens":136379,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_g9raGdhpSeZpq6pt3ZMdW2j5|fc_07d9714368e86c14016a589264c20c819982255b77ac3b5a1e","toolName":"grep","startedAt":"2026-07-16T08:12:21.195Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"},"intent":"Finding agent event contracts"},"id":"7697c55d","parentId":"d3b3410d","timestamp":"2026-07-16T08:12:21.195Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_BTZZZgRTKSdpXs1dJNGjhTxd|fc_07d9714368e86c14016a589264c220819984dd8eea6d2060b9","toolName":"read","startedAt":"2026-07-16T08:12:21.195Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"},"intent":"Reading OMP shared events"},"id":"502c7f36","parentId":"7697c55d","timestamp":"2026-07-16T08:12:21.195Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_zabq8fIHOVkKXyPmw36IvK84|fc_07d9714368e86c14016a589264c22c81998a0c1e7f65d16d4e","toolName":"grep","startedAt":"2026-07-16T08:12:21.196Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"},"intent":"Finding context event result"},"id":"2a6cd38e","parentId":"502c7f36","timestamp":"2026-07-16T08:12:21.196Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_rj5zCqlAV90D7H6SyGHFEWRM|fc_07d9714368e86c14016a589264c23481999396269de29aeae7","toolName":"grep","startedAt":"2026-07-16T08:12:21.196Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Finding prompt event contracts"},"id":"c865586e","parentId":"2a6cd38e","timestamp":"2026-07-16T08:12:21.196Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_NiW1WEg3kd83SmZXw15OxIFO|fc_07d9714368e86c14016a589264c2408199aa851487d81c41f0","toolName":"grep","startedAt":"2026-07-16T08:12:21.196Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Finding compact options"},"id":"722edf2f","parentId":"c865586e","timestamp":"2026-07-16T08:12:21.196Z"}
{"type":"message","id":"a3a220cd","parentId":"722edf2f","timestamp":"2026-07-16T08:12:21.346Z","message":{"role":"toolResult","toolCallId":"call_BTZZZgRTKSdpXs1dJNGjhTxd|fc_07d9714368e86c14016a589264c220819984dd8eea6d2060b9","toolName":"read","content":[{"type":"text","text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\nContent-Type: text/plain\nMethod: text\n\n---\n\n/**\n * Event payload and result shapes shared between the extensions and hooks\n * subsystems.\n *\n * Both subsystems observe the same agent/session lifecycle, so the *event*\n * payloads (what happened) and the simpler *result* shapes (handler return\n * values that don't depend on subsystem-specific identifiers like\n * `AgentMessage` vs `Message`) are intentionally identical.\n *\n * Anything that diverges between the two subsystems — UI context, runtime\n * context, command context, tool-call discrimination, or return shapes that\n * carry subsystem-specific message types — lives in the per-subsystem\n * `types.ts` files and is documented there.\n */\nimport type { AgentMessage } from \"@oh-my-pi/pi-agent-core\";\nimport type { CompactionPreparation, CompactionResult } from \"@oh-my-pi/pi-agent-core/compaction\";\nimport type { AssistantRetryRecovery, ImageContent, TextContent, ToolResultMessage } from \"@oh-my-pi/pi-ai\";\nimport type { Rule } from \"../capability/rule\";\nimport type { Goal, GoalModeState } from \"../goals/state\";\nimport type { BranchSummaryEntry, CompactionEntry, SessionEntry } from \"../session/session-entries\";\nimport type { TodoItem } from \"../tools/todo\";\n\n// ============================================================================\n// Session Events\n// ============================================================================\n\n/** Fired on initial session load */\nexport interface SessionStartEvent {\n\ttype: \"session_start\";\n}\n\n/** Fired before switching to another session (can be cancelled) */\nexport interface SessionBeforeSwitchEvent {\n\ttype: \"session_before_switch\";\n\t/** Reason for the switch */\n\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n\t/** Session file we're switching to (only for \"resume\") */\n\ttargetSessionFile?: string;\n}\n\n/** Fired after switching to another session */\nexport interface SessionSwitchEvent {\n\ttype: \"session_switch\";\n\t/** Reason for the switch */\n\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n\t/** Session file we came from */\n\tpreviousSessionFile: string | undefined;\n}\n\n/** Fired before branching a session (can be cancelled) */\nexport interface SessionBeforeBranchEvent {\n\ttype: \"session_before_branch\";\n\t/** ID of the entry to branch from */\n\tentryId: string;\n}\n\n/** Fired after branching a session */\nexport interface SessionBranchEvent {\n\ttype: \"session_branch\";\n\tpreviousSessionFile: string | undefined;\n}\n\n/** Fired before context compaction (can be cancelled or customized) */\nexport interface SessionBeforeCompactEvent {\n\ttype: \"session_before_compact\";\n\t/** Compaction preparation with messages to summarize, file ops, previous summary, etc. */\n\tpreparation: CompactionPreparation;\n\t/** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */\n\tbranchEntries: SessionEntry[];\n\t/** Optional user-provided instructions for the summary */\n\tcustomInstructions?: string;\n\t/** Abort signal - handlers should pass this to LLM calls and check it periodically */\n\tsignal: AbortSignal;\n}\n\n/** Fired before compaction summarization to customize prompts/context */\nexport interface SessionCompactingEvent {\n\ttype: \"session.compacting\";\n\tsessionId: string;\n\tmessages: AgentMessage[];\n}\n\n/** Fired after context compaction */\nexport interface SessionCompactEvent {\n\ttype: \"session_compact\";\n\tcompactionEntry: CompactionEntry;\n\t/** Whether the compaction entry was provided by an extension/hook */\n\tfromExtension: boolean;\n}\n\n/** Fired on process exit (SIGINT/SIGTERM) */\nexport interface SessionShutdownEvent {\n\ttype: \"session_shutdown\";\n}\n\n/** Fired when a main-agent turn is about to settle; handlers may request one continuation turn. */\nexport interface SessionStopEvent {\n\ttype: \"session_stop\";\n\tmessages: AgentMessage[];\n\tturn_id: number;\n\tlast_assistant_message?: AgentMessage;\n\tsession_id: string;\n\tsession_file?: string;\n\tstop_hook_active: boolean;\n}\n\n/** Preparation data for tree navigation (used by session_before_tree event) */\nexport interface TreePreparation {\n\t/** Node being switched to */\n\ttargetId: string;\n\t/** Current active leaf (being abandoned), null if no current position */\n\toldLeafId: string | null;\n\t/** Common ancestor of target and old leaf, null if no common ancestor */\n\tcommonAncestorId: string | null;\n\t/** Entries to summarize (old leaf back to common ancestor or compaction) */\n\tentriesToSummarize: SessionEntry[];\n\t/** Whether user chose to summarize */\n\tuserWantsSummary: boolean;\n}\n\n/** Fired before navigating to a different node in the session tree (can be cancelled) */\nexport interface SessionBeforeTreeEvent {\n\ttype: \"session_before_tree\";\n\t/** Preparation data for the navigation */\n\tpreparation: TreePreparation;\n\t/** Abort signal - honors Escape during summarization (model available via ctx.model) */\n\tsignal: AbortSignal;\n}\n\n/** Fired after navigating to a different node in the session tree */\nexport interface SessionTreeEvent {\n\ttype: \"session_tree\";\n\t/** The new active leaf, null if navigated to before first entry */\n\tnewLeafId: string | null;\n\t/** Previous active leaf, null if there was no position */\n\toldLeafId: string | null;\n\t/** Branch summary entry if one was created */\n\tsummaryEntry?: BranchSummaryEntry;\n\t/** Whether summary came from extension/hook */\n\tfromExtension?: boolean;\n}\n\n/** Union of all session event types */\nexport interface GoalUpdatedEvent {\n\ttype: \"goal_updated\";\n\tgoal: Goal | null;\n\tstate?: GoalModeState;\n}\n\nexport type SessionEvent =\n\t| SessionStartEvent\n\t| SessionBeforeSwitchEvent\n\t| SessionSwitchEvent\n\t| SessionBeforeBranchEvent\n\t| SessionBranchEvent\n\t| SessionBeforeCompactEvent\n\t| SessionCompactingEvent\n\t| SessionCompactEvent\n\t| SessionStopEvent\n\t| SessionShutdownEvent\n\t| SessionBeforeTreeEvent\n\t| SessionTreeEvent\n\t| GoalUpdatedEvent;\n\n// ============================================================================\n// Agent / Turn Events\n// ============================================================================\n\n/**\n * Fired before each LLM call.\n *\n * Original session messages are NOT modified - only the messages sent to the\n * LLM are affected when a handler returns a replacement (the return shape\n * differs between extensions and hooks; see each subsystem's\n * `ContextEventResult`).\n */\nexport interface ContextEvent {\n\ttype: \"context\";\n\t/** Messages about to be sent to the LLM (deep copy, safe to modify) */\n\tmessages: AgentMessage[];\n}\n\n/**\n * Fired when an agent loop starts (once per user prompt).\n */\nexport interface AgentStartEvent {\n\ttype: \"agent_start\";\n}\n\n/** Fired when an agent loop ends */\nexport interface AgentEndEvent {\n\ttype: \"agent_end\";\n\tmessages: AgentMessage[];\n}\n\n/** Fired at the start of each turn */\nexport interface TurnStartEvent {\n\ttype: \"turn_start\";\n\tturnIndex: number;\n\ttimestamp: number;\n}\n\n/** Fired at the end of each turn */\nexport interface TurnEndEvent {\n\ttype: \"turn_end\";\n\tturnIndex: number;\n\tmessage: AgentMessage;\n\ttoolResults: ToolResultMessage[];\n}\n\n// ============================================================================\n// Auto-compaction / Auto-retry Events\n// ============================================================================\n\n/** Fired when auto-compaction starts */\nexport interface AutoCompactionStartEvent {\n\ttype: \"auto_compaction_start\";\n\treason: \"threshold\" | \"overflow\" | \"idle\" | \"incomplete\";\n\taction: \"context-full\" | \"handoff\" | \"shake\" | \"snapcompact\";\n}\n\n/** Fired when auto-compaction ends */\nexport interface AutoCompactionEndEvent {\n\ttype: \"auto_compaction_end\";\n\taction: \"context-full\" | \"handoff\" | \"shake\" | \"snapcompact\";\n\tresult: CompactionResult | undefined;\n\taborted: boolean;\n\twillRetry: boolean;\n\terrorMessage?: string;\n\t/** True when compaction was skipped for a benign reason (no model, no candidates, nothing to compact). */\n\tskipped?: boolean;\n}\n\n/** Fired when auto-retry starts */\nexport interface AutoRetryStartEvent {\n\ttype: \"auto_retry_start\";\n\tattempt: number;\n\tmaxAttempts: number;\n\tdelayMs: number;\n\terrorMessage: string;\n\terrorId?: number;\n}\n\nexport interface RecoveredRetryError {\n\tentryId: string;\n\tpersistenceKey?: string;\n\tnote: string;\n\tretryRecovery: AssistantRetryRecovery;\n}\n\n/** Fired when auto-retry ends */\nexport interface AutoRetryEndEvent {\n\ttype: \"auto_retry_end\";\n\tsuccess: boolean;\n\tattempt: number;\n\tfinalError?: string;\n\trecoveredErrors?: RecoveredRetryError[];\n}\n\n// ============================================================================\n// TTSR / Todo Reminders\n// ============================================================================\n\n/** Fired when TTSR rule matching interrupts generation */\nexport interface TtsrTriggeredEvent {\n\ttype: \"ttsr_triggered\";\n\trules: Rule[];\n}\n\n/** Fired when todo reminder logic detects unfinished todos */\nexport interface TodoReminderEvent {\n\ttype: \"todo_reminder\";\n\ttodos: TodoItem[];\n\tattempt: number;\n\tmaxAttempts: number;\n}\n\n\n[99 more lines in URL output. Use :284 to continue]"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"URL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\nContent-Type: text/plain\nMethod: text\n\n---\n\n/**\n * Event payload and result shapes shared between the extensions and hooks\n * subsystems.\n *\n * Both subsystems observe the same agent/session lifecycle, so the *event*\n * payloads (what happened) and the simpler *result* shapes (handler return\n * values that don't depend on subsystem-specific identifiers like\n * `AgentMessage` vs `Message`) are intentionally identical.\n *\n * Anything that diverges between the two subsystems — UI context, runtime\n * context, command context, tool-call discrimination, or return shapes that\n * carry subsystem-specific message types — lives in the per-subsystem\n * `types.ts` files and is documented there.\n */\nimport type { AgentMessage } from \"@oh-my-pi/pi-agent-core\";\nimport type { CompactionPreparation, CompactionResult } from \"@oh-my-pi/pi-agent-core/compaction\";\nimport type { AssistantRetryRecovery, ImageContent, TextContent, ToolResultMessage } from \"@oh-my-pi/pi-ai\";\nimport type { Rule } from \"../capability/rule\";\nimport type { Goal, GoalModeState } from \"../goals/state\";\nimport type { BranchSummaryEntry, CompactionEntry, SessionEntry } from \"../session/session-entries\";\nimport type { TodoItem } from \"../tools/todo\";\n\n// ============================================================================\n// Session Events\n// ============================================================================\n\n/** Fired on initial session load */\nexport interface SessionStartEvent {\n\ttype: \"session_start\";\n}\n\n/** Fired before switching to another session (can be cancelled) */\nexport interface SessionBeforeSwitchEvent {\n\ttype: \"session_before_switch\";\n\t/** Reason for the switch */\n\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n\t/** Session file we're switching to (only for \"resume\") */\n\ttargetSessionFile?: string;\n}\n\n/** Fired after switching to another session */\nexport interface SessionSwitchEvent {\n\ttype: \"session_switch\";\n\t/** Reason for the switch */\n\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n\t/** Session file we came from */\n\tpreviousSessionFile: string | undefined;\n}\n\n/** Fired before branching a session (can be cancelled) */\nexport interface SessionBeforeBranchEvent {\n\ttype: \"session_before_branch\";\n\t/** ID of the entry to branch from */\n\tentryId: string;\n}\n\n/** Fired after branching a session */\nexport interface SessionBranchEvent {\n\ttype: \"session_branch\";\n\tpreviousSessionFile: string | undefined;\n}\n\n/** Fired before context compaction (can be cancelled or customized) */\nexport interface SessionBeforeCompactEvent {\n\ttype: \"session_before_compact\";\n\t/** Compaction preparation with messages to summarize, file ops, previous summary, etc. */\n\tpreparation: CompactionPreparation;\n\t/** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */\n\tbranchEntries: SessionEntry[];\n\t/** Optional user-provided instructions for the summary */\n\tcustomInstructions?: string;\n\t/** Abort signal - handlers should pass this to LLM calls and check it periodically */\n\tsignal: AbortSignal;\n}\n\n/** Fired before compaction summarization to customize prompts/context */\nexport interface SessionCompactingEvent {\n\ttype: \"session.compacting\";\n\tsessionId: string;\n\tmessages: AgentMessage[];\n}\n\n/** Fired after context compaction */\nexport interface SessionCompactEvent {\n\ttype: \"session_compact\";\n\tcompactionEntry: CompactionEntry;\n\t/** Whether the compaction entry was provided by an extension/hook */\n\tfromExtension: boolean;\n}\n\n/** Fired on process exit (SIGINT/SIGTERM) */\nexport interface SessionShutdownEvent {\n\ttype: \"session_shutdown\";\n}\n\n/** Fired when a main-agent turn is about to settle; handlers may request one continuation turn. */\nexport interface SessionStopEvent {\n\ttype: \"session_stop\";\n\tmessages: AgentMessage[];\n\tturn_id: number;\n\tlast_assistant_message?: AgentMessage;\n\tsession_id: string;\n\tsession_file?: string;\n\tstop_hook_active: boolean;\n}\n\n/** Preparation data for tree navigation (used by session_before_tree event) */\nexport interface TreePreparation {\n\t/** Node being switched to */\n\ttargetId: string;\n\t/** Current active leaf (being abandoned), null if no current position */\n\toldLeafId: string | null;\n\t/** Common ancestor of target and old leaf, null if no common ancestor */\n\tcommonAncestorId: string | null;\n\t/** Entries to summarize (old leaf back to common ancestor or compaction) */\n\tentriesToSummarize: SessionEntry[];\n\t/** Whether user chose to summarize */\n\tuserWantsSummary: boolean;\n}\n\n/** Fired before navigating to a different node in the session tree (can be cancelled) */\nexport interface SessionBeforeTreeEvent {\n\ttype: \"session_before_tree\";\n\t/** Preparation data for the navigation */\n\tpreparation: TreePreparation;\n\t/** Abort signal - honors Escape during summarization (model available via ctx.model) */\n\tsignal: AbortSignal;\n}\n\n/** Fired after navigating to a different node in the session tree */\nexport interface SessionTreeEvent {\n\ttype: \"session_tree\";\n\t/** The new active leaf, null if navigated to before first entry */\n\tnewLeafId: string | null;\n\t/** Previous active leaf, null if there was no position */\n\toldLeafId: string | null;\n\t/** Branch summary entry if one was created */\n\tsummaryEntry?: BranchSummaryEntry;\n\t/** Whether summary came from extension/hook */\n\tfromExtension?: boolean;\n}\n\n/** Union of all session event types */\nexport interface GoalUpdatedEvent {\n\ttype: \"goal_updated\";\n\tgoal: Goal | null;\n\tstate?: GoalModeState;\n}\n\nexport type SessionEvent =\n\t| SessionStartEvent\n\t| SessionBeforeSwitchEvent\n\t| SessionSwitchEvent\n\t| SessionBeforeBranchEvent\n\t| SessionBranchEvent\n\t| SessionBeforeCompactEvent\n\t| SessionCompactingEvent\n\t| SessionCompactEvent\n\t| SessionStopEvent\n\t| SessionShutdownEvent\n\t| SessionBeforeTreeEvent\n\t| SessionTreeEvent\n\t| GoalUpdatedEvent;\n\n// ============================================================================\n// Agent / Turn Events\n// ============================================================================\n\n/**\n * Fired before each LLM call.\n *\n * Original session messages are NOT modified - only the messages sent to the\n * LLM are affected when a handler returns a replacement (the return shape\n * differs between extensions and hooks; see each subsystem's\n * `ContextEventResult`).\n */\nexport interface ContextEvent {\n\ttype: \"context\";\n\t/** Messages about to be sent to the LLM (deep copy, safe to modify) */\n\tmessages: AgentMessage[];\n}\n\n/**\n * Fired when an agent loop starts (once per user prompt).\n */\nexport interface AgentStartEvent {\n\ttype: \"agent_start\";\n}\n\n/** Fired when an agent loop ends */\nexport interface AgentEndEvent {\n\ttype: \"agent_end\";\n\tmessages: AgentMessage[];\n}\n\n/** Fired at the start of each turn */\nexport interface TurnStartEvent {\n\ttype: \"turn_start\";\n\tturnIndex: number;\n\ttimestamp: number;\n}\n\n/** Fired at the end of each turn */\nexport interface TurnEndEvent {\n\ttype: \"turn_end\";\n\tturnIndex: number;\n\tmessage: AgentMessage;\n\ttoolResults: ToolResultMessage[];\n}\n\n// ============================================================================\n// Auto-compaction / Auto-retry Events\n// ============================================================================\n\n/** Fired when auto-compaction starts */\nexport interface AutoCompactionStartEvent {\n\ttype: \"auto_compaction_start\";\n\treason: \"threshold\" | \"overflow\" | \"idle\" | \"incomplete\";\n\taction: \"context-full\" | \"handoff\" | \"shake\" | \"snapcompact\";\n}\n\n/** Fired when auto-compaction ends */\nexport interface AutoCompactionEndEvent {\n\ttype: \"auto_compaction_end\";\n\taction: \"context-full\" | \"handoff\" | \"shake\" | \"snapcompact\";\n\tresult: CompactionResult | undefined;\n\taborted: boolean;\n\twillRetry: boolean;\n\terrorMessage?: string;\n\t/** True when compaction was skipped for a benign reason (no model, no candidates, nothing to compact). */\n\tskipped?: boolean;\n}\n\n/** Fired when auto-retry starts */\nexport interface AutoRetryStartEvent {\n\ttype: \"auto_retry_start\";\n\tattempt: number;\n\tmaxAttempts: number;\n\tdelayMs: number;\n\terrorMessage: string;\n\terrorId?: number;\n}\n\nexport interface RecoveredRetryError {\n\tentryId: string;\n\tpersistenceKey?: string;\n\tnote: string;\n\tretryRecovery: AssistantRetryRecovery;\n}\n\n/** Fired when auto-retry ends */\nexport interface AutoRetryEndEvent {\n\ttype: \"auto_retry_end\";\n\tsuccess: boolean;\n\tattempt: number;\n\tfinalError?: string;\n\trecoveredErrors?: RecoveredRetryError[];\n}\n\n// ============================================================================\n// TTSR / Todo Reminders\n// ============================================================================\n\n/** Fired when TTSR rule matching interrupts generation */\nexport interface TtsrTriggeredEvent {\n\ttype: \"ttsr_triggered\";\n\trules: Rule[];\n}\n\n/** Fired when todo reminder logic detects unfinished todos */\nexport interface TodoReminderEvent {\n\ttype: \"todo_reminder\";\n\ttodos: TodoItem[];\n\tattempt: number;\n\tmaxAttempts: number;\n}\n","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"}}},"isError":false,"timestamp":1784189541346}}
{"type":"message","id":"1bef018d","parentId":"a3a220cd","timestamp":"2026-07-16T08:12:21.378Z","message":{"role":"toolResult","toolCallId":"call_NiW1WEg3kd83SmZXw15OxIFO|fc_07d9714368e86c14016a589264c2408199aa851487d81c41f0","toolName":"grep","content":[{"type":"text","text":" 352|\n*353|export interface CompactOptions {\n*354|\tonComplete?: (result: CompactionResult) => void;\n*355|\tonError?: (error: Error) => void;\n 356|\t/**\n 357|\t * Force a one-off compaction mode for this invocation, overriding the\n 358|\t * configured `compaction.strategy` / `remoteEnabled` (the `/compact`\n...\n 363|\t * Internal summarizer guidance — piped only to native summarization, never\n*364|\t * exposed as `customInstructions` on the `session_before_compact` extension\n 365|\t * hook. Used by plan-mode \"Approve and compact context\" so extensions that\n*366|\t * treat `customInstructions` as user focus don't mistake plan-mode\n 367|\t * boilerplate for the operator's intent (issue #4359).\n 368|\t *\n*369|\t * When both `customInstructions` and `internalGuidance` are set, the\n 370|\t * summarizer uses `internalGuidance`; the hook still sees only the public\n*371|\t * `customInstructions`.\n 372|\t */\n 373|\tinternalGuidance?: string;\n 374|}\n...\n 415|\t/** Compact the session context (interactive mode shows UI). */\n*416|\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n 417|\t/** Whether UI is available (false in print/RPC mode) */\n 418|\thasUI: boolean;\n 419|\t/** Current working directory */"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":8,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","count":8}],"truncated":false,"displayContent":" 352│\n*353│export interface CompactOptions {\n*354│\tonComplete?: (result: CompactionResult) => void;\n*355│\tonError?: (error: Error) => void;\n 356│\t/**\n 357│\t * Force a one-off compaction mode for this invocation, overriding the\n 358│\t * configured `compaction.strategy` / `remoteEnabled` (the `/compact`\n    │...\n 363│\t * Internal summarizer guidance — piped only to native summarization, never\n*364│\t * exposed as `customInstructions` on the `session_before_compact` extension\n 365│\t * hook. Used by plan-mode \"Approve and compact context\" so extensions that\n*366│\t * treat `customInstructions` as user focus don't mistake plan-mode\n 367│\t * boilerplate for the operator's intent (issue #4359).\n 368│\t *\n*369│\t * When both `customInstructions` and `internalGuidance` are set, the\n 370│\t * summarizer uses `internalGuidance`; the hook still sees only the public\n*371│\t * `customInstructions`.\n 372│\t */\n 373│\tinternalGuidance?: string;\n 374│}\n    │...\n 415│\t/** Compact the session context (interactive mode shows UI). */\n*416│\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n 417│\t/** Whether UI is available (false in print/RPC mode) */\n 418│\thasUI: boolean;\n 419│\t/** Current working directory */"},"isError":false,"timestamp":1784189541378}}
{"type":"message","id":"1d5f88e5","parentId":"1bef018d","timestamp":"2026-07-16T08:12:21.381Z","message":{"role":"toolResult","toolCallId":"call_rj5zCqlAV90D7H6SyGHFEWRM|fc_07d9714368e86c14016a589264c23481999396269de29aeae7","toolName":"grep","content":[{"type":"text","text":" 167|\ttimeout?: number;\n*168|\t/** Invoked when the UI times out while waiting for a selection/input */\n 169|\tonTimeout?: () => void;\n 170|\t/** Invoked when the UI-managed timeout countdown starts */\n 171|\tonTimeoutStart?: () => void;\n*172|\t/** Invoked when user input resets a UI-managed timeout countdown */\n 173|\tonTimeoutReset?: () => void;\n 174|\t/** Initial cursor position for select dialogs (0-indexed) */\n 175|\tinitialIndex?: number;\n...\n 198|\n*199|/** Raw terminal input listener for extensions. */\n 200|export type TerminalInputHandler = (data: string) => { consume?: boolean; data?: string } | undefined;\n 201|\n 202|export type WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n...\n 220|// Parallel to HookUIContext: extensions expose a strictly larger UI surface\n*221|// (custom editor component, header/footer, widgets, theming, terminal input)\n 222|// and may be invoked from event handlers that have already taken the agent\n 223|// loop's lock — hooks intentionally cannot.\n 224|export interface ExtensionUIContext {\n...\n 236|\n*237|\t/** Show a text input dialog. */\n*238|\tinput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions): Promise<string | undefined>;\n 239|\n 240|\t/** Show the rich ask dialog when the interactive TUI surface is available. */\n 241|\taskDialog?(\n...\n 248|\n*249|\t/** Listen to raw terminal input (interactive mode only). Returns an unsubscribe function. */\n 250|\tonTerminalInput(handler: TerminalInputHandler): () => void;\n 251|\n 252|\t/** Set status text in the footer/status bar. Pass undefined to clear. */\n...\n 280|\n*281|\t/** Set the text in the core input editor. */\n 282|\tsetEditorText(text: string): void;\n 283|\n 284|\t/**\n*285|\t * Paste text into the core input editor.\n 286|\t *\n 287|\t * Interactive mode should route through the editor's paste handling (e.g. large paste markers).\n 288|\t * Non-interactive modes may fall back to replacing the editor text.\n...\n 291|\n*292|\t/** Get the current text from the core input editor. */\n 293|\tgetEditorText(): string;\n 294|\n 295|\t/** Show a multi-line editor for text editing. */\n...\n 611|/** Fired after user submits prompt but before agent loop. */\n*612|export interface BeforeAgentStartEvent {\n 613|\ttype: \"before_agent_start\";\n 614|\tprompt: string;\n 615|\timages?: ImageContent[];\n...\n 725|\n*726|/** Fired when the user submits input (interactive mode only). */\n*727|export interface InputEvent {\n*728|\ttype: \"input\";\n 729|\ttext: string;\n 730|\timages?: ImageContent[];\n 731|\tsource: \"interactive\" | \"rpc\" | \"extension\";\n...\n 762|\ttoolName: \"bash\";\n*763|\tinput: BashToolInput;\n 764|}\n 765|\n 766|export interface ReadToolCallEvent extends ToolCallEventBase {\n 767|\ttoolName: \"read\";\n*768|\tinput: ReadToolInput;\n 769|}\n 770|\n 771|export interface EditToolCallEvent extends ToolCallEventBase {\n 772|\ttoolName: \"edit\";\n*773|\tinput: Record<string, unknown>;\n 774|}\n 775|\n 776|export interface WriteToolCallEvent extends ToolCallEventBase {\n 777|\ttoolName: \"write\";\n*778|\tinput: WriteToolInput;\n 779|}\n 780|\n 781|export interface GrepToolCallEvent extends ToolCallEventBase {\n 782|\ttoolName: \"grep\";\n*783|\tinput: GrepToolInput;\n 784|}\n 785|\n 786|export interface GlobToolCallEvent extends ToolCallEventBase {\n 787|\ttoolName: \"glob\";\n*788|\tinput: GlobToolInput;\n 789|}\n 790|\n 791|export interface CustomToolCallEvent extends ToolCallEventBase {\n 792|\ttoolName: string;\n*793|\tinput: Record<string, unknown>;\n 794|}\n 795|\n 796|/** Fired before a tool executes. Can block. */\n...\n 808|\ttoolCallId: string;\n*809|\tinput: Record<string, unknown>;\n 810|\tcontent: (TextContent | ImageContent)[];\n 811|\tisError: boolean;\n 812|}\n...\n 864| * if (isToolCallEventType(\"bash\", event)) {\n*865| *   event.input.command;  // string\n 866| * }\n 867| * ```\n 868| *\n...\n 871| * if (isToolCallEventType<\"my_tool\", MyToolInput>(\"my_tool\", event)) {\n*872| *   event.input.action;  // typed\n 873| * }\n 874| * ```\n 875| *\n...\n 887|\tevent: ToolCallEvent,\n*888|): event is ToolCallEvent & { toolName: TName; input: TInput };\n 889|export function isToolCallEventType(toolName: string, event: ToolCallEvent): boolean {\n 890|\treturn event.toolName === toolName;\n 891|}\n...\n 899|\t| AfterProviderResponseEvent\n*900|\t| BeforeAgentStartEvent\n 901|\t| AgentStartEvent\n 902|\t| AgentEndEvent\n 903|\t| SessionStopEvent\n...\n 939|\n*940|/** Result from input event handler */\n*941|export interface InputEventResult {\n*942|\t/** If true, the input was handled and should not continue through normal flow */\n 943|\thandled?: boolean;\n*944|\t/** Replace the input text */\n 945|\ttext?: string;\n 946|\t/** Replace any pending images */\n 947|\timages?: ImageContent[];\n...\n 963|\n*964|export interface BeforeAgentStartEventResult {\n 965|\tmessage?: CustomMessagePayload;\n 966|\t/** Replace the system prompt for this turn. If multiple extensions return this, they are chained. */\n 967|\tsystemPrompt?: string[];\n...\n 1078|\ton(event: \"after_provider_response\", handler: ExtensionHandler<AfterProviderResponseEvent>): void;\n*1079|\ton(event: \"before_agent_start\", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;\n 1080|\ton(event: \"agent_start\", handler: ExtensionHandler<AgentStartEvent>): void;\n 1081|\ton(event: \"agent_end\", handler: ExtensionHandler<AgentEndEvent>): void;\n 1082|\ton(event: \"session_stop\", handler: ExtensionHandler<SessionStopEvent, SessionStopEventResult>): void;\n...\n 1098|\ton(event: \"credential_disabled\", handler: ExtensionHandler<CredentialDisabledEvent>): void;\n*1099|\ton(event: \"input\", handler: ExtensionHandler<InputEvent, InputEventResult>): void;\n 1100|\ton(event: \"tool_approval_requested\", handler: ExtensionHandler<ToolApprovalRequestedEvent>): void;\n 1101|\ton(event: \"tool_approval_resolved\", handler: ExtensionHandler<ToolApprovalResolvedEvent>): void;\n 1102|\ton(event: \"tool_call\", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;\n...\n 1241|\t *       thinking: { mode: \"anthropic-adaptive\", efforts: [\"minimal\", \"low\", \"medium\", \"high\"] },\n*1242|\t *       input: [\"text\", \"image\"],\n*1243|\t *       cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },\n 1244|\t *       contextWindow: 200000,\n 1245|\t *       maxTokens: 64000,\n 1246|\t *   ]\n...\n 1314|\tthinking?: Model[\"thinking\"];\n*1315|\t/** Supported input types. */\n*1316|\tinput: (\"text\" | \"image\")[];\n 1317|\t/** Cost per million tokens. */\n*1318|\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\n 1319|\t/** Premium Copilot requests charged per user-initiated request. */\n 1320|\tpremiumMultiplier?: number;\n 1321|\t/** Maximum context window size in tokens. */"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":38,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/2numq3vbk77xa.ts","count":38}],"truncated":false,"displayContent":"  167│\ttimeout?: number;\n *168│\t/** Invoked when the UI times out while waiting for a selection/input */\n  169│\tonTimeout?: () => void;\n  170│\t/** Invoked when the UI-managed timeout countdown starts */\n  171│\tonTimeoutStart?: () => void;\n *172│\t/** Invoked when user input resets a UI-managed timeout countdown */\n  173│\tonTimeoutReset?: () => void;\n  174│\t/** Initial cursor position for select dialogs (0-indexed) */\n  175│\tinitialIndex?: number;\n     │...\n  198│\n *199│/** Raw terminal input listener for extensions. */\n  200│export type TerminalInputHandler = (data: string) => { consume?: boolean; data?: string } | undefined;\n  201│\n  202│export type WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n     │...\n  220│// Parallel to HookUIContext: extensions expose a strictly larger UI surface\n *221│// (custom editor component, header/footer, widgets, theming, terminal input)\n  222│// and may be invoked from event handlers that have already taken the agent\n  223│// loop's lock — hooks intentionally cannot.\n  224│export interface ExtensionUIContext {\n     │...\n  236│\n *237│\t/** Show a text input dialog. */\n *238│\tinput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions): Promise<string | undefined>;\n  239│\n  240│\t/** Show the rich ask dialog when the interactive TUI surface is available. */\n  241│\taskDialog?(\n     │...\n  248│\n *249│\t/** Listen to raw terminal input (interactive mode only). Returns an unsubscribe function. */\n  250│\tonTerminalInput(handler: TerminalInputHandler): () => void;\n  251│\n  252│\t/** Set status text in the footer/status bar. Pass undefined to clear. */\n     │...\n  280│\n *281│\t/** Set the text in the core input editor. */\n  282│\tsetEditorText(text: string): void;\n  283│\n  284│\t/**\n *285│\t * Paste text into the core input editor.\n  286│\t *\n  287│\t * Interactive mode should route through the editor's paste handling (e.g. large paste markers).\n  288│\t * Non-interactive modes may fall back to replacing the editor text.\n     │...\n  291│\n *292│\t/** Get the current text from the core input editor. */\n  293│\tgetEditorText(): string;\n  294│\n  295│\t/** Show a multi-line editor for text editing. */\n     │...\n  611│/** Fired after user submits prompt but before agent loop. */\n *612│export interface BeforeAgentStartEvent {\n  613│\ttype: \"before_agent_start\";\n  614│\tprompt: string;\n  615│\timages?: ImageContent[];\n     │...\n  725│\n *726│/** Fired when the user submits input (interactive mode only). */\n *727│export interface InputEvent {\n *728│\ttype: \"input\";\n  729│\ttext: string;\n  730│\timages?: ImageContent[];\n  731│\tsource: \"interactive\" | \"rpc\" | \"extension\";\n     │...\n  762│\ttoolName: \"bash\";\n *763│\tinput: BashToolInput;\n  764│}\n  765│\n  766│export interface ReadToolCallEvent extends ToolCallEventBase {\n  767│\ttoolName: \"read\";\n *768│\tinput: ReadToolInput;\n  769│}\n  770│\n  771│export interface EditToolCallEvent extends ToolCallEventBase {\n  772│\ttoolName: \"edit\";\n *773│\tinput: Record<string, unknown>;\n  774│}\n  775│\n  776│export interface WriteToolCallEvent extends ToolCallEventBase {\n  777│\ttoolName: \"write\";\n *778│\tinput: WriteToolInput;\n  779│}\n  780│\n  781│export interface GrepToolCallEvent extends ToolCallEventBase {\n  782│\ttoolName: \"grep\";\n *783│\tinput: GrepToolInput;\n  784│}\n  785│\n  786│export interface GlobToolCallEvent extends ToolCallEventBase {\n  787│\ttoolName: \"glob\";\n *788│\tinput: GlobToolInput;\n  789│}\n  790│\n  791│export interface CustomToolCallEvent extends ToolCallEventBase {\n  792│\ttoolName: string;\n *793│\tinput: Record<string, unknown>;\n  794│}\n  795│\n  796│/** Fired before a tool executes. Can block. */\n     │...\n  808│\ttoolCallId: string;\n *809│\tinput: Record<string, unknown>;\n  810│\tcontent: (TextContent | ImageContent)[];\n  811│\tisError: boolean;\n  812│}\n     │...\n  864│ * if (isToolCallEventType(\"bash\", event)) {\n *865│ *   event.input.command;  // string\n  866│ * }\n  867│ * ```\n  868│ *\n     │...\n  871│ * if (isToolCallEventType<\"my_tool\", MyToolInput>(\"my_tool\", event)) {\n *872│ *   event.input.action;  // typed\n  873│ * }\n  874│ * ```\n  875│ *\n     │...\n  887│\tevent: ToolCallEvent,\n *888│): event is ToolCallEvent & { toolName: TName; input: TInput };\n  889│export function isToolCallEventType(toolName: string, event: ToolCallEvent): boolean {\n  890│\treturn event.toolName === toolName;\n  891│}\n     │...\n  899│\t| AfterProviderResponseEvent\n *900│\t| BeforeAgentStartEvent\n  901│\t| AgentStartEvent\n  902│\t| AgentEndEvent\n  903│\t| SessionStopEvent\n     │...\n  939│\n *940│/** Result from input event handler */\n *941│export interface InputEventResult {\n *942│\t/** If true, the input was handled and should not continue through normal flow */\n  943│\thandled?: boolean;\n *944│\t/** Replace the input text */\n  945│\ttext?: string;\n  946│\t/** Replace any pending images */\n  947│\timages?: ImageContent[];\n     │...\n  963│\n *964│export interface BeforeAgentStartEventResult {\n  965│\tmessage?: CustomMessagePayload;\n  966│\t/** Replace the system prompt for this turn. If multiple extensions return this, they are chained. */\n  967│\tsystemPrompt?: string[];\n     │...\n 1078│\ton(event: \"after_provider_response\", handler: ExtensionHandler<AfterProviderResponseEvent>): void;\n*1079│\ton(event: \"before_agent_start\", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;\n 1080│\ton(event: \"agent_start\", handler: ExtensionHandler<AgentStartEvent>): void;\n 1081│\ton(event: \"agent_end\", handler: ExtensionHandler<AgentEndEvent>): void;\n 1082│\ton(event: \"session_stop\", handler: ExtensionHandler<SessionStopEvent, SessionStopEventResult>): void;\n     │...\n 1098│\ton(event: \"credential_disabled\", handler: ExtensionHandler<CredentialDisabledEvent>): void;\n*1099│\ton(event: \"input\", handler: ExtensionHandler<InputEvent, InputEventResult>): void;\n 1100│\ton(event: \"tool_approval_requested\", handler: ExtensionHandler<ToolApprovalRequestedEvent>): void;\n 1101│\ton(event: \"tool_approval_resolved\", handler: ExtensionHandler<ToolApprovalResolvedEvent>): void;\n 1102│\ton(event: \"tool_call\", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;\n     │...\n 1241│\t *       thinking: { mode: \"anthropic-adaptive\", efforts: [\"minimal\", \"low\", \"medium\", \"high\"] },\n*1242│\t *       input: [\"text\", \"image\"],\n*1243│\t *       cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },\n 1244│\t *       contextWindow: 200000,\n 1245│\t *       maxTokens: 64000,\n 1246│\t *   ]\n     │...\n 1314│\tthinking?: Model[\"thinking\"];\n*1315│\t/** Supported input types. */\n*1316│\tinput: (\"text\" | \"image\")[];\n 1317│\t/** Cost per million tokens. */\n*1318│\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\n 1319│\t/** Premium Copilot requests charged per user-initiated request. */\n 1320│\tpremiumMultiplier?: number;\n 1321│\t/** Maximum context window size in tokens. */"},"isError":false,"timestamp":1784189541381}}
{"type":"message","id":"6bacdd17","parentId":"1d5f88e5","timestamp":"2026-07-16T08:12:21.384Z","message":{"role":"toolResult","toolCallId":"call_zabq8fIHOVkKXyPmw36IvK84|fc_07d9714368e86c14016a589264c22c81998a0c1e7f65d16d4e","toolName":"grep","content":[{"type":"text","text":" 65|\ttype: \"session_before_compact\";\n*66|\t/** Compaction preparation with messages to summarize, file ops, previous summary, etc. */\n 67|\tpreparation: CompactionPreparation;\n 68|\t/** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */\n 69|\tbranchEntries: SessionEntry[];\n...\n 79|\tsessionId: string;\n*80|\tmessages: AgentMessage[];\n 81|}\n 82|\n 83|/** Fired after context compaction */\n...\n 98|\ttype: \"session_stop\";\n*99|\tmessages: AgentMessage[];\n 100|\tturn_id: number;\n 101|\tlast_assistant_message?: AgentMessage;\n 102|\tsession_id: string;\n...\n 171| *\n*172| * Original session messages are NOT modified - only the messages sent to the\n 173| * LLM are affected when a handler returns a replacement (the return shape\n 174| * differs between extensions and hooks; see each subsystem's\n*175| * `ContextEventResult`).\n 176| */\n*177|export interface ContextEvent {\n 178|\ttype: \"context\";\n 179|\t/** Messages about to be sent to the LLM (deep copy, safe to modify) */\n*180|\tmessages: AgentMessage[];\n 181|}\n 182|\n 183|/**\n...\n 192|\ttype: \"agent_end\";\n*193|\tmessages: AgentMessage[];\n 194|}\n 195|\n 196|/** Fired at the start of each turn */\n...\n 327|\t * - `cancel: true` → nothing happens, user stays in current session\n*328|\t * - `skipConversationRestore: true` → branch happens, but messages stay as-is\n*329|\t * - neither → branch happens AND messages rewind to branch point (default)\n 330|\t */\n 331|\tskipConversationRestore?: boolean;\n 332|}"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":10,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts","count":10}],"truncated":false,"displayContent":"  65│\ttype: \"session_before_compact\";\n *66│\t/** Compaction preparation with messages to summarize, file ops, previous summary, etc. */\n  67│\tpreparation: CompactionPreparation;\n  68│\t/** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */\n  69│\tbranchEntries: SessionEntry[];\n    │...\n  79│\tsessionId: string;\n *80│\tmessages: AgentMessage[];\n  81│}\n  82│\n  83│/** Fired after context compaction */\n    │...\n  98│\ttype: \"session_stop\";\n *99│\tmessages: AgentMessage[];\n 100│\tturn_id: number;\n 101│\tlast_assistant_message?: AgentMessage;\n 102│\tsession_id: string;\n    │...\n 171│ *\n*172│ * Original session messages are NOT modified - only the messages sent to the\n 173│ * LLM are affected when a handler returns a replacement (the return shape\n 174│ * differs between extensions and hooks; see each subsystem's\n*175│ * `ContextEventResult`).\n 176│ */\n*177│export interface ContextEvent {\n 178│\ttype: \"context\";\n 179│\t/** Messages about to be sent to the LLM (deep copy, safe to modify) */\n*180│\tmessages: AgentMessage[];\n 181│}\n 182│\n 183│/**\n    │...\n 192│\ttype: \"agent_end\";\n*193│\tmessages: AgentMessage[];\n 194│}\n 195│\n 196│/** Fired at the start of each turn */\n    │...\n 327│\t * - `cancel: true` → nothing happens, user stays in current session\n*328│\t * - `skipConversationRestore: true` → branch happens, but messages stay as-is\n*329│\t * - neither → branch happens AND messages rewind to branch point (default)\n 330│\t */\n 331│\tskipConversationRestore?: boolean;\n 332│}"},"isError":false,"timestamp":1784189541384}}
{"type":"message","id":"066cca09","parentId":"6bacdd17","timestamp":"2026-07-16T08:12:21.385Z","message":{"role":"toolResult","toolCallId":"call_g9raGdhpSeZpq6pt3ZMdW2j5|fc_07d9714368e86c14016a589264c20c819982255b77ac3b5a1e","toolName":"grep","content":[{"type":"text","text":" 35|\t/** Reason for the switch */\n*36|\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n 37|\t/** Session file we're switching to (only for \"resume\") */\n 38|\ttargetSessionFile?: string;\n 39|}\n...\n 44|\t/** Reason for the switch */\n*45|\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n 46|\t/** Session file we came from */\n 47|\tpreviousSessionFile: string | undefined;\n 48|}\n...\n 96|/** Fired when a main-agent turn is about to settle; handlers may request one continuation turn. */\n*97|export interface SessionStopEvent {\n 98|\ttype: \"session_stop\";\n 99|\tmessages: AgentMessage[];\n 100|\tturn_id: number;\n...\n 190|/** Fired when an agent loop ends */\n*191|export interface AgentEndEvent {\n 192|\ttype: \"agent_end\";\n 193|\tmessages: AgentMessage[];\n 194|}\n...\n 203|/** Fired at the end of each turn */\n*204|export interface TurnEndEvent {\n 205|\ttype: \"turn_end\";\n 206|\tturnIndex: number;\n 207|\tmessage: AgentMessage;\n...\n 217|\ttype: \"auto_compaction_start\";\n*218|\treason: \"threshold\" | \"overflow\" | \"idle\" | \"incomplete\";\n 219|\taction: \"context-full\" | \"handoff\" | \"shake\" | \"snapcompact\";\n 220|}\n 221|\n...\n 228|\twillRetry: boolean;\n*229|\terrorMessage?: string;\n*230|\t/** True when compaction was skipped for a benign reason (no model, no candidates, nothing to compact). */\n 231|\tskipped?: boolean;\n 232|}\n 233|\n...\n 239|\tdelayMs: number;\n*240|\terrorMessage: string;\n*241|\terrorId?: number;\n 242|}\n 243|\n 244|export interface RecoveredRetryError {\n...\n 288|\tblock?: boolean;\n*289|\t/** Reason for blocking (returned to LLM as error) */\n*290|\treason?: string;\n 291|}\n 292|\n 293|/**\n...\n 352|/** Return type for `session_stop` handlers */\n*353|export interface SessionStopEventResult {\n 354|\t/** Continue the main session with additional context before settling */\n 355|\tcontinue?: boolean;\n 356|\t/** OMP-native model-visible context for the continuation */\n...\n 359|\tdecision?: \"block\";\n*360|\t/** Claude/Codex-compatible model-visible continuation reason */\n*361|\treason?: string;\n 362|}\n 363|\n 364|/** Return type for `session_before_tree` handlers */"}],"details":{"scopePath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts","searchPath":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":15,"fileCount":1,"files":["C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts"],"fileMatches":[{"path":"C:/Users/decid/.omp/agent/sessions/-Documents-projects-omp-spt/2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7/url-search/3iixa85zfk6ru.ts","count":15}],"truncated":false,"displayContent":"  35│\t/** Reason for the switch */\n *36│\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n  37│\t/** Session file we're switching to (only for \"resume\") */\n  38│\ttargetSessionFile?: string;\n  39│}\n    │...\n  44│\t/** Reason for the switch */\n *45│\treason: \"new\" | \"resume\" | \"fork\" | \"handoff\";\n  46│\t/** Session file we came from */\n  47│\tpreviousSessionFile: string | undefined;\n  48│}\n    │...\n  96│/** Fired when a main-agent turn is about to settle; handlers may request one continuation turn. */\n *97│export interface SessionStopEvent {\n  98│\ttype: \"session_stop\";\n  99│\tmessages: AgentMessage[];\n 100│\tturn_id: number;\n    │...\n 190│/** Fired when an agent loop ends */\n*191│export interface AgentEndEvent {\n 192│\ttype: \"agent_end\";\n 193│\tmessages: AgentMessage[];\n 194│}\n    │...\n 203│/** Fired at the end of each turn */\n*204│export interface TurnEndEvent {\n 205│\ttype: \"turn_end\";\n 206│\tturnIndex: number;\n 207│\tmessage: AgentMessage;\n    │...\n 217│\ttype: \"auto_compaction_start\";\n*218│\treason: \"threshold\" | \"overflow\" | \"idle\" | \"incomplete\";\n 219│\taction: \"context-full\" | \"handoff\" | \"shake\" | \"snapcompact\";\n 220│}\n 221│\n    │...\n 228│\twillRetry: boolean;\n*229│\terrorMessage?: string;\n*230│\t/** True when compaction was skipped for a benign reason (no model, no candidates, nothing to compact). */\n 231│\tskipped?: boolean;\n 232│}\n 233│\n    │...\n 239│\tdelayMs: number;\n*240│\terrorMessage: string;\n*241│\terrorId?: number;\n 242│}\n 243│\n 244│export interface RecoveredRetryError {\n    │...\n 288│\tblock?: boolean;\n*289│\t/** Reason for blocking (returned to LLM as error) */\n*290│\treason?: string;\n 291│}\n 292│\n 293│/**\n    │...\n 352│/** Return type for `session_stop` handlers */\n*353│export interface SessionStopEventResult {\n 354│\t/** Continue the main session with additional context before settling */\n 355│\tcontinue?: boolean;\n 356│\t/** OMP-native model-visible context for the continuation */\n    │...\n 359│\tdecision?: \"block\";\n*360│\t/** Claude/Codex-compatible model-visible continuation reason */\n*361│\treason?: string;\n 362│}\n 363│\n 364│/** Return type for `session_before_tree` handlers */"},"isError":false,"timestamp":1784189541385}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `AgentSurface`:\n\nMain explicitly reassigned omp-spt.mjs startup brief, targeted hints, update notices, and checkpoint seam to you. Please implement the exact contract in my prior message; I can clarify prose or assertions. I will not touch your extension/tests.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"AgentSurface\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531cc42c49b7964","from":"AgentSurface","message":"Main explicitly reassigned omp-spt.mjs startup brief, targeted hints, update notices, and checkpoint seam to you. Please implement the exact contract in my prior message; I can clarify prose or assertions. I will not touch your extension/tests."},"attribution":"agent","id":"9c1d07eb","parentId":"066cca09","timestamp":"2026-07-16T08:12:21.411Z"}
{"type":"message","id":"893c1544","parentId":"9c1d07eb","timestamp":"2026-07-16T08:12:28.621Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Verifying systemPromptAppend necessity**"},{"type":"toolCall","id":"call_92Vti42FPlix5Y77tuDqSqIu|fc_005ac7d35da477b2016a58926c6df88198bbc66ef8b75422f0","name":"read","arguments":{"i":"Reading OMP prompt event shapes","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":"595-750"}},{"type":"toolCall","id":"call_S3LP9rVSngC4jLdJkRe6ZmeC|fc_005ac7d35da477b2016a58926c6e088198ad0baf76535dd367","name":"read","arguments":{"i":"Reading OMP prompt result shapes","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":"930-985"}},{"type":"toolCall","id":"call_gwIPL1kMzT0txnF9axpIQTA7|fc_005ac7d35da477b2016a58926c6e108198907f35d80f9fdc53","name":"read","arguments":{"i":"Reading OMP compact options","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","selector":"340-425"}},{"type":"toolCall","id":"call_UIwZBGdQpG4ihHy5ZbqMWbvL|fc_005ac7d35da477b2016a58926c6e148198a8e15af9c76f80f4","name":"read","arguments":{"i":"Reading stop continuation shape","path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","selector":"340-365"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6422,"output":274,"cacheRead":135680,"cacheWrite":0,"totalTokens":142376,"reasoningTokens":43,"cost":{"input":0.03211,"output":0.00822,"cacheRead":0.06784,"cacheWrite":0,"total":0.10816999999999999}},"stopReason":"toolUse","timestamp":1784189541425,"responseId":"resp_005ac7d35da477b2016a589265de708198ad883af2ebf722ac","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_005ac7d35da477b2016a589267664881989812dc48119a9e45","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJJso574dx0-GnSu2VMAUmOeFdU3nnfDQ35f-9ixIuEsziWjlYJOHOaOLlETrolwMr95zEVrUppEejOEf9LYbqyYxEkeWV7GOZJMdUVN5txyiYCdFHvpsfkCd43BU_UqAzOsZeuW2luqT65Giu2vTwNFhN2jDnKmrqyzoxwoOi09VkKpr7kjBbHb27d5U6C8SHLzl1V7d32y6T0rMqnGFicZHCOOsduzXjrX3VS_keAGli9hq40nCQ3gyf9s30tbEFu8gGE6g6Audl65bMAq8mkpJTeWRTIGGYtVZSSCLIAxgMF0-kTtvF1XBC1X3ACI34B4uuxD4w1xmODSbmUm-fTcW7Rn6iQ6rUHzJNI5FmNd1C61gPGy42AT1PLPkUFot1dr0N_fzJNjGTddr3wefjMtRm7F8aTOfS9LpOLC34aLNFrdUuV66vzbn_B0gHB2BIqMh9EqFiZGzoQmpOn2uxBasDReLR1jmP1sjXRYyEem4s-LpXMOvwEfQoByj0Zb9j0Jsh38Xxc-nBKA9dpAbkbOUc3Tjo9x4h0bWuwYu3i9OyboMC0i3sIv_zRNdfkDLa-otvREwQlj5pY0dgy61muRUAsMhFOUbRzZlimNv6VeB3LWQd2-16xAZU9KcmZwyLkuAZ2rl_ZIOpHMc_gEOJrpDLRY0aqI2MjZrRyVXRlk5NxCHO2RDNsz75jAKQNnI4-icTbViryXkIvI8Xv8Ni5IhEvmnVBrBME57MUknEMcJFLBTO0t5Xrc0C8kcOgY2adp4othDIGmOP7v3JqNezINRlrvWp-Cf4UyGxDMGgFv9oyFanCg0VToWCUSC1gTZcMeF-iJNGvH2YKxO0GHgrgCqwZeMNyJhsX7qbK4QtY4mb-eFyaRYN3lgJg-RjaAwCoUHwT1bgPMqjPU60psIe9_aGJT-lh5qMQTH9SKhYO0e6gUn_eCgtWfh9EwsDfpvhl1YZSVMjYPsmmZct_qMGYtN1h2WLudfLO4o4oT4ZfBHhQ2Eyrr4Fmay5PV-3fyuF171o8hF3m5vzCLoQq9LmwEQsBrnx48ArHEBxxtoHayEOdxWE3K2vmpENbLZQQMibrxhcBrXKCmv27fQqxs4jQsDQ-l5AxSi3fLS41-pmcqROsTVO7hH5Ujp93bq-RZhInV","summary":[{"type":"summary_text","text":"**Verifying systemPromptAppend necessity**"}]},{"id":"fc_005ac7d35da477b2016a58926c6df88198bbc66ef8b75422f0","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading OMP prompt event shapes\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":\"595-750\"}","call_id":"call_92Vti42FPlix5Y77tuDqSqIu","name":"read"},{"id":"fc_005ac7d35da477b2016a58926c6e088198ad0baf76535dd367","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading OMP prompt result shapes\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":\"930-985\"}","call_id":"call_S3LP9rVSngC4jLdJkRe6ZmeC","name":"read"},{"id":"fc_005ac7d35da477b2016a58926c6e108198907f35d80f9fdc53","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading OMP compact options\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\",\"selector\":\"340-425\"}","call_id":"call_gwIPL1kMzT0txnF9axpIQTA7","name":"read"},{"id":"fc_005ac7d35da477b2016a58926c6e148198a8e15af9c76f80f4","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading stop continuation shape\",\"path\":\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\",\"selector\":\"340-365\"}","call_id":"call_UIwZBGdQpG4ihHy5ZbqMWbvL","name":"read"}]},"duration":7194.682099999976,"ttft":1960.373499999987,"contextSnapshot":{"promptTokens":142102,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_92Vti42FPlix5Y77tuDqSqIu|fc_005ac7d35da477b2016a58926c6df88198bbc66ef8b75422f0","toolName":"read","startedAt":"2026-07-16T08:12:28.621Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Reading OMP prompt event shapes"},"id":"c3761b93","parentId":"893c1544","timestamp":"2026-07-16T08:12:28.621Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_S3LP9rVSngC4jLdJkRe6ZmeC|fc_005ac7d35da477b2016a58926c6e088198ad0baf76535dd367","toolName":"read","startedAt":"2026-07-16T08:12:28.621Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Reading OMP prompt result shapes"},"id":"5e354728","parentId":"c3761b93","timestamp":"2026-07-16T08:12:28.621Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_gwIPL1kMzT0txnF9axpIQTA7|fc_005ac7d35da477b2016a58926c6e108198907f35d80f9fdc53","toolName":"read","startedAt":"2026-07-16T08:12:28.621Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"},"intent":"Reading OMP compact options"},"id":"70065cfe","parentId":"5e354728","timestamp":"2026-07-16T08:12:28.621Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_UIwZBGdQpG4ihHy5ZbqMWbvL|fc_005ac7d35da477b2016a58926c6e148198a8e15af9c76f80f4","toolName":"read","startedAt":"2026-07-16T08:12:28.622Z","args":{"path":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"},"intent":"Reading stop continuation shape"},"id":"41e8a0b7","parentId":"70065cfe","timestamp":"2026-07-16T08:12:28.622Z"}
{"type":"message","id":"f2765892","parentId":"41e8a0b7","timestamp":"2026-07-16T08:12:28.652Z","message":{"role":"toolResult","toolCallId":"call_92Vti42FPlix5Y77tuDqSqIu|fc_005ac7d35da477b2016a58926c6df88198bbc66ef8b75422f0","toolName":"read","content":[{"type":"text","text":"export type {\n…\n\tSessionStartEvent,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tTreePreparation,\n} from \"../shared-events\";\n\n// ============================================================================\n// Agent Events\n// ============================================================================\n\nexport type { ContextEvent } from \"../shared-events\";\n\n/** Fired before a provider request is sent. Can replace the payload. */\nexport interface BeforeProviderRequestEvent {\n\ttype: \"before_provider_request\";\n\tpayload: unknown;\n}\n\n/** Fired after a provider response is received, before its stream body is consumed. */\nexport interface AfterProviderResponseEvent extends ProviderResponseMetadata {\n\ttype: \"after_provider_response\";\n}\n\n/** Fired after user submits prompt but before agent loop. */\nexport interface BeforeAgentStartEvent {\n\ttype: \"before_agent_start\";\n\tprompt: string;\n\timages?: ImageContent[];\n\tsystemPrompt: string[];\n}\n\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tSessionStopEvent,\n\tSessionStopEventResult,\n\tTurnEndEvent,\n\tTurnStartEvent,\n} from \"../shared-events\";\n\n/** Fired when a message starts (user, assistant, or toolResult) */\nexport interface MessageStartEvent {\n\ttype: \"message_start\";\n\tmessage: AgentMessage;\n}\n\n/** Fired during assistant message streaming with token-by-token updates */\nexport interface MessageUpdateEvent {\n\ttype: \"message_update\";\n\tmessage: AgentMessage;\n\tassistantMessageEvent: AssistantMessageEvent;\n}\n\n/** Fired when a message ends */\nexport interface MessageEndEvent {\n\ttype: \"message_end\";\n\tmessage: AgentMessage;\n}\n\n/** Fired when a tool starts executing */\nexport interface ToolExecutionStartEvent {\n\ttype: \"tool_execution_start\";\n\ttoolCallId: string;\n\ttoolName: string;\n\targs: unknown;\n\tintent?: string;\n}\n\n/** Fired during tool execution with partial/streaming output */\nexport interface ToolExecutionUpdateEvent {\n\ttype: \"tool_execution_update\";\n\ttoolCallId: string;\n\ttoolName: string;\n\targs: unknown;\n\tpartialResult: unknown;\n}\n\n/** Fired when a tool finishes executing */\nexport interface ToolExecutionEndEvent {\n\ttype: \"tool_execution_end\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tresult: unknown;\n\tisError: boolean;\n}\n\nexport type {\n\tAutoCompactionEndEvent,\n\tAutoCompactionStartEvent,\n\tAutoRetryEndEvent,\n\tAutoRetryStartEvent,\n\tTodoReminderEvent,\n\tTtsrTriggeredEvent,\n} from \"../shared-events\";\n\n/** Fired when AuthStorage automatically soft-disables a credential (e.g. OAuth `invalid_grant`). Not fired for user-initiated `remove()` or duplicate-credential dedup. */\nexport interface CredentialDisabledEvent {\n\ttype: \"credential_disabled\";\n\t/** Provider id whose credential was disabled (e.g. \"anthropic\"). */\n\tprovider: string;\n\t/** Verbatim error captured for forensics (truncated upstream). */\n\tdisabledCause: string;\n}\n\n// ============================================================================\n// User Bash Events\n// ============================================================================\n\n/** Fired when user executes a bash command via ! or !! prefix */\nexport interface UserBashEvent {\n\ttype: \"user_bash\";\n\t/** The command to execute */\n\tcommand: string;\n\t/** True if !! prefix was used (excluded from LLM context) */\n\texcludeFromContext: boolean;\n\t/** Current working directory */\n\tcwd: string;\n}\n\n// ============================================================================\n// User Python Events\n// ============================================================================\n\n/** Fired when user executes Python code via $ or $$ prefix */\nexport interface UserPythonEvent {\n\ttype: \"user_python\";\n\t/** The Python code to execute */\n\tcode: string;\n\t/** True if $$ prefix was used (excluded from LLM context) */\n\texcludeFromContext: boolean;\n\t/** Current working directory */\n\tcwd: string;\n}\n\n// ============================================================================\n// Input Events\n// ============================================================================\n\n/** Fired when the user submits input (interactive mode only). */\nexport interface InputEvent {\n\ttype: \"input\";\n\ttext: string;\n\timages?: ImageContent[];\n\tsource: \"interactive\" | \"rpc\" | \"extension\";\n}\n\n// ============================================================================\n// Tool Events\n// ============================================================================\n\nexport interface ToolApprovalRequestedEvent {\n\ttype: \"tool_approval_requested\";\n\tsessionId: string;\n\ttoolCallId: string;\n\ttoolName: string;\n\treason?: string;\n\tapprovalMode: ApprovalMode;\n}\n\nexport interface ToolApprovalResolvedEvent {\n…\n}\n\n[728 more lines in URL output. Use :754 to continue]"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"export type {\n…\n\tSessionStartEvent,\n\tSessionSwitchEvent,\n\tSessionTreeEvent,\n\tTreePreparation,\n} from \"../shared-events\";\n\n// ============================================================================\n// Agent Events\n// ============================================================================\n\nexport type { ContextEvent } from \"../shared-events\";\n\n/** Fired before a provider request is sent. Can replace the payload. */\nexport interface BeforeProviderRequestEvent {\n\ttype: \"before_provider_request\";\n\tpayload: unknown;\n}\n\n/** Fired after a provider response is received, before its stream body is consumed. */\nexport interface AfterProviderResponseEvent extends ProviderResponseMetadata {\n\ttype: \"after_provider_response\";\n}\n\n/** Fired after user submits prompt but before agent loop. */\nexport interface BeforeAgentStartEvent {\n\ttype: \"before_agent_start\";\n\tprompt: string;\n\timages?: ImageContent[];\n\tsystemPrompt: string[];\n}\n\nexport type {\n\tAgentEndEvent,\n\tAgentStartEvent,\n\tSessionStopEvent,\n\tSessionStopEventResult,\n\tTurnEndEvent,\n\tTurnStartEvent,\n} from \"../shared-events\";\n\n/** Fired when a message starts (user, assistant, or toolResult) */\nexport interface MessageStartEvent {\n\ttype: \"message_start\";\n\tmessage: AgentMessage;\n}\n\n/** Fired during assistant message streaming with token-by-token updates */\nexport interface MessageUpdateEvent {\n\ttype: \"message_update\";\n\tmessage: AgentMessage;\n\tassistantMessageEvent: AssistantMessageEvent;\n}\n\n/** Fired when a message ends */\nexport interface MessageEndEvent {\n\ttype: \"message_end\";\n\tmessage: AgentMessage;\n}\n\n/** Fired when a tool starts executing */\nexport interface ToolExecutionStartEvent {\n\ttype: \"tool_execution_start\";\n\ttoolCallId: string;\n\ttoolName: string;\n\targs: unknown;\n\tintent?: string;\n}\n\n/** Fired during tool execution with partial/streaming output */\nexport interface ToolExecutionUpdateEvent {\n\ttype: \"tool_execution_update\";\n\ttoolCallId: string;\n\ttoolName: string;\n\targs: unknown;\n\tpartialResult: unknown;\n}\n\n/** Fired when a tool finishes executing */\nexport interface ToolExecutionEndEvent {\n\ttype: \"tool_execution_end\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tresult: unknown;\n\tisError: boolean;\n}\n\nexport type {\n\tAutoCompactionEndEvent,\n\tAutoCompactionStartEvent,\n\tAutoRetryEndEvent,\n\tAutoRetryStartEvent,\n\tTodoReminderEvent,\n\tTtsrTriggeredEvent,\n} from \"../shared-events\";\n\n/** Fired when AuthStorage automatically soft-disables a credential (e.g. OAuth `invalid_grant`). Not fired for user-initiated `remove()` or duplicate-credential dedup. */\nexport interface CredentialDisabledEvent {\n\ttype: \"credential_disabled\";\n\t/** Provider id whose credential was disabled (e.g. \"anthropic\"). */\n\tprovider: string;\n\t/** Verbatim error captured for forensics (truncated upstream). */\n\tdisabledCause: string;\n}\n\n// ============================================================================\n// User Bash Events\n// ============================================================================\n\n/** Fired when user executes a bash command via ! or !! prefix */\nexport interface UserBashEvent {\n\ttype: \"user_bash\";\n\t/** The command to execute */\n\tcommand: string;\n\t/** True if !! prefix was used (excluded from LLM context) */\n\texcludeFromContext: boolean;\n\t/** Current working directory */\n\tcwd: string;\n}\n\n// ============================================================================\n// User Python Events\n// ============================================================================\n\n/** Fired when user executes Python code via $ or $$ prefix */\nexport interface UserPythonEvent {\n\ttype: \"user_python\";\n\t/** The Python code to execute */\n\tcode: string;\n\t/** True if $$ prefix was used (excluded from LLM context) */\n\texcludeFromContext: boolean;\n\t/** Current working directory */\n\tcwd: string;\n}\n\n// ============================================================================\n// Input Events\n// ============================================================================\n\n/** Fired when the user submits input (interactive mode only). */\nexport interface InputEvent {\n\ttype: \"input\";\n\ttext: string;\n\timages?: ImageContent[];\n\tsource: \"interactive\" | \"rpc\" | \"extension\";\n}\n\n// ============================================================================\n// Tool Events\n// ============================================================================\n\nexport interface ToolApprovalRequestedEvent {\n\ttype: \"tool_approval_requested\";\n\tsessionId: string;\n\ttoolCallId: string;\n\ttoolName: string;\n\treason?: string;\n\tapprovalMode: ApprovalMode;\n}\n\nexport interface ToolApprovalResolvedEvent {\n…\n}","startLine":584,"lineNumbers":[584,null,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,null,760]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"}}},"isError":false,"timestamp":1784189548652}}
{"type":"message","id":"24126c13","parentId":"f2765892","timestamp":"2026-07-16T08:12:28.664Z","message":{"role":"toolResult","toolCallId":"call_S3LP9rVSngC4jLdJkRe6ZmeC|fc_005ac7d35da477b2016a58926c6e088198ad0baf76535dd367","toolName":"read","content":[{"type":"text","text":"\t| ToolCallEvent\n\t| ToolResultEvent\n\t| ToolApprovalRequestedEvent\n\t| ToolApprovalResolvedEvent;\n\n// ============================================================================\n// Event Results\n// ============================================================================\n\nexport interface ContextEventResult {\n\tmessages?: AgentMessage[];\n}\n\nexport type BeforeProviderRequestEventResult = unknown;\n\nexport type { ToolCallEventResult } from \"../shared-events\";\n\n/** Result from input event handler */\nexport interface InputEventResult {\n\t/** If true, the input was handled and should not continue through normal flow */\n\thandled?: boolean;\n\t/** Replace the input text */\n\ttext?: string;\n\t/** Replace any pending images */\n\timages?: ImageContent[];\n}\n\n/** Result from user_bash event handler */\nexport interface UserBashEventResult {\n\t/** Full replacement: extension handled execution, use this result */\n\tresult?: BashResult;\n}\n\n/** Result from user_python event handler */\nexport interface UserPythonEventResult {\n\t/** Full replacement: extension handled execution, use this result */\n\tresult?: PythonResult;\n}\n\nexport type { ToolResultEventResult } from \"../shared-events\";\n\nexport interface BeforeAgentStartEventResult {\n\tmessage?: CustomMessagePayload;\n\t/** Replace the system prompt for this turn. If multiple extensions return this, they are chained. */\n\tsystemPrompt?: string[];\n}\n\nexport type {\n\tSessionBeforeBranchResult,\n\tSessionBeforeCompactResult,\n\tSessionBeforeSwitchResult,\n\tSessionBeforeTreeResult,\n\tSessionCompactingResult,\n} from \"../shared-events\";\n\n// ============================================================================\n// Message Rendering\n// ============================================================================\n\nexport interface MessageRenderOptions {\n…\n}\n\n[493 more lines in URL output. Use :989 to continue]"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"\t| ToolCallEvent\n\t| ToolResultEvent\n\t| ToolApprovalRequestedEvent\n\t| ToolApprovalResolvedEvent;\n\n// ============================================================================\n// Event Results\n// ============================================================================\n\nexport interface ContextEventResult {\n\tmessages?: AgentMessage[];\n}\n\nexport type BeforeProviderRequestEventResult = unknown;\n\nexport type { ToolCallEventResult } from \"../shared-events\";\n\n/** Result from input event handler */\nexport interface InputEventResult {\n\t/** If true, the input was handled and should not continue through normal flow */\n\thandled?: boolean;\n\t/** Replace the input text */\n\ttext?: string;\n\t/** Replace any pending images */\n\timages?: ImageContent[];\n}\n\n/** Result from user_bash event handler */\nexport interface UserBashEventResult {\n\t/** Full replacement: extension handled execution, use this result */\n\tresult?: BashResult;\n}\n\n/** Result from user_python event handler */\nexport interface UserPythonEventResult {\n\t/** Full replacement: extension handled execution, use this result */\n\tresult?: PythonResult;\n}\n\nexport type { ToolResultEventResult } from \"../shared-events\";\n\nexport interface BeforeAgentStartEventResult {\n\tmessage?: CustomMessagePayload;\n\t/** Replace the system prompt for this turn. If multiple extensions return this, they are chained. */\n\tsystemPrompt?: string[];\n}\n\nexport type {\n\tSessionBeforeBranchResult,\n\tSessionBeforeCompactResult,\n\tSessionBeforeSwitchResult,\n\tSessionBeforeTreeResult,\n\tSessionCompactingResult,\n} from \"../shared-events\";\n\n// ============================================================================\n// Message Rendering\n// ============================================================================\n\nexport interface MessageRenderOptions {\n…\n}","startLine":929,"lineNumbers":[929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,null,990]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"}}},"isError":false,"timestamp":1784189548664}}
{"type":"message","id":"6ece41a6","parentId":"24126c13","timestamp":"2026-07-16T08:12:28.664Z","message":{"role":"toolResult","toolCallId":"call_gwIPL1kMzT0txnF9axpIQTA7|fc_005ac7d35da477b2016a58926c6e108198907f35d80f9fdc53","toolName":"read","content":[{"type":"text","text":"export interface ExtensionUIContext {\n…\n\n\t/** Get current tool output expansion state. */\n\tgetToolsExpanded(): boolean;\n\n\t/** Set tool output expansion state. */\n\tsetToolsExpanded(expanded: boolean): void;\n}\n\n// ============================================================================\n// Extension Context\n// ============================================================================\n\nexport interface ContextUsage {\n\t/** Estimated context tokens. */\n\ttokens: number;\n\tcontextWindow: number;\n\t/** Context usage as percentage of context window. */\n\tpercent: number;\n}\n\nexport interface CompactOptions {\n\tonComplete?: (result: CompactionResult) => void;\n\tonError?: (error: Error) => void;\n\t/**\n\t * Force a one-off compaction mode for this invocation, overriding the\n\t * configured `compaction.strategy` / `remoteEnabled` (the `/compact`\n\t * subcommands: `soft` | `remote` | `snapcompact`). Omitted = configured behavior.\n\t */\n\tmode?: CompactMode;\n\t/**\n\t * Internal summarizer guidance — piped only to native summarization, never\n\t * exposed as `customInstructions` on the `session_before_compact` extension\n\t * hook. Used by plan-mode \"Approve and compact context\" so extensions that\n\t * treat `customInstructions` as user focus don't mistake plan-mode\n\t * boilerplate for the operator's intent (issue #4359).\n\t *\n\t * When both `customInstructions` and `internalGuidance` are set, the\n\t * summarizer uses `internalGuidance`; the hook still sees only the public\n\t * `customInstructions`.\n\t */\n\tinternalGuidance?: string;\n}\n\n/**\n * Context passed to extension event handlers.\n */\n// fallow-ignore-next-line code-duplication\n// Parallel to HookContext: extensions expose a strictly larger runtime\n// surface (model registry, system prompt, shutdown, full session manager\n// access). Field overlap is incidental; merging into a base would require\n// hooks to widen their public contract.\n/**\n * Read-only model query facade exposed at `ctx.models`. Lets an extension select a\n * model the same way core does — list authenticated models, read the session model,\n * resolve a model string or role alias, and compare model families — without reaching\n * into the mutable registry or re-implementing matching/family heuristics.\n */\nexport interface ExtensionModelQuery {\n\t/** Authenticated models available this session (the same set `--model` selection sees). */\n\tlist(): Model[];\n\t/** The current session model, if one is set. */\n\tcurrent(): Model | undefined;\n\t/**\n\t * Resolve a model string (`provider/id`, bare id) or role alias (`@slow`, a\n\t * configured role) to a Model, using the same settings-backed aliases and match\n\t * preferences as core selection. Thinking/routing suffixes are accepted and resolved\n\t * to the base model (pass effort separately). Returns undefined when nothing matches.\n\t */\n\tresolve(spec: string): Model | undefined;\n\t/**\n\t * Opaque lineage token for \"are these the same family?\" comparisons — every Claude\n\t * point release shares a token, Claude and GPT differ. Backed by catalog canonical\n\t * identity. Compare it; do not persist it (the vocabulary tracks new releases).\n\t */\n\tfamily(model: Model): string;\n}\n\nexport interface ExtensionContext {\n\t/** UI methods for user interaction */\n\tui: ExtensionUIContext;\n\t/** Get current context usage for the active model. */\n\tgetContextUsage(): ContextUsage | undefined;\n\t/** Compact the session context (interactive mode shows UI). */\n\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n\t/** Whether UI is available (false in print/RPC mode) */\n\thasUI: boolean;\n\t/** Current working directory */\n\tcwd: string;\n\t/** Session manager (read-only) */\n\tsessionManager: ReadonlySessionManager;\n…\n}\n\n[1053 more lines in URL output. Use :429 to continue]"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"export interface ExtensionUIContext {\n…\n\n\t/** Get current tool output expansion state. */\n\tgetToolsExpanded(): boolean;\n\n\t/** Set tool output expansion state. */\n\tsetToolsExpanded(expanded: boolean): void;\n}\n\n// ============================================================================\n// Extension Context\n// ============================================================================\n\nexport interface ContextUsage {\n\t/** Estimated context tokens. */\n\ttokens: number;\n\tcontextWindow: number;\n\t/** Context usage as percentage of context window. */\n\tpercent: number;\n}\n\nexport interface CompactOptions {\n\tonComplete?: (result: CompactionResult) => void;\n\tonError?: (error: Error) => void;\n\t/**\n\t * Force a one-off compaction mode for this invocation, overriding the\n\t * configured `compaction.strategy` / `remoteEnabled` (the `/compact`\n\t * subcommands: `soft` | `remote` | `snapcompact`). Omitted = configured behavior.\n\t */\n\tmode?: CompactMode;\n\t/**\n\t * Internal summarizer guidance — piped only to native summarization, never\n\t * exposed as `customInstructions` on the `session_before_compact` extension\n\t * hook. Used by plan-mode \"Approve and compact context\" so extensions that\n\t * treat `customInstructions` as user focus don't mistake plan-mode\n\t * boilerplate for the operator's intent (issue #4359).\n\t *\n\t * When both `customInstructions` and `internalGuidance` are set, the\n\t * summarizer uses `internalGuidance`; the hook still sees only the public\n\t * `customInstructions`.\n\t */\n\tinternalGuidance?: string;\n}\n\n/**\n * Context passed to extension event handlers.\n */\n// fallow-ignore-next-line code-duplication\n// Parallel to HookContext: extensions expose a strictly larger runtime\n// surface (model registry, system prompt, shutdown, full session manager\n// access). Field overlap is incidental; merging into a base would require\n// hooks to widen their public contract.\n/**\n * Read-only model query facade exposed at `ctx.models`. Lets an extension select a\n * model the same way core does — list authenticated models, read the session model,\n * resolve a model string or role alias, and compare model families — without reaching\n * into the mutable registry or re-implementing matching/family heuristics.\n */\nexport interface ExtensionModelQuery {\n\t/** Authenticated models available this session (the same set `--model` selection sees). */\n\tlist(): Model[];\n\t/** The current session model, if one is set. */\n\tcurrent(): Model | undefined;\n\t/**\n\t * Resolve a model string (`provider/id`, bare id) or role alias (`@slow`, a\n\t * configured role) to a Model, using the same settings-backed aliases and match\n\t * preferences as core selection. Thinking/routing suffixes are accepted and resolved\n\t * to the base model (pass effort separately). Returns undefined when nothing matches.\n\t */\n\tresolve(spec: string): Model | undefined;\n\t/**\n\t * Opaque lineage token for \"are these the same family?\" comparisons — every Claude\n\t * point release shares a token, Claude and GPT differ. Backed by catalog canonical\n\t * identity. Compare it; do not persist it (the vocabulary tracks new releases).\n\t */\n\tfamily(model: Model): string;\n}\n\nexport interface ExtensionContext {\n\t/** UI methods for user interaction */\n\tui: ExtensionUIContext;\n\t/** Get current context usage for the active model. */\n\tgetContextUsage(): ContextUsage | undefined;\n\t/** Compact the session context (interactive mode shows UI). */\n\tcompact(instructionsOrOptions?: string | CompactOptions): Promise<void>;\n\t/** Whether UI is available (false in print/RPC mode) */\n\thasUI: boolean;\n\t/** Current working directory */\n\tcwd: string;\n\t/** Session manager (read-only) */\n\tsessionManager: ReadonlySessionManager;\n…\n}","startLine":230,"lineNumbers":[230,null,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,null,449]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts"}}},"isError":false,"timestamp":1784189548664}}
{"type":"message","id":"4b99ed35","parentId":"6ece41a6","timestamp":"2026-07-16T08:12:28.680Z","message":{"role":"toolResult","toolCallId":"call_UIwZBGdQpG4ihHy5ZbqMWbvL|fc_005ac7d35da477b2016a58926c6e148198a8e15af9c76f80f4","toolName":"read","content":[{"type":"text","text":"\n/** Return type for `session_before_compact` handlers */\nexport interface SessionBeforeCompactResult {\n\t/** If true, cancel the compaction */\n\tcancel?: boolean;\n\t/** Custom compaction result - SessionManager adds id/parentId */\n\tcompaction?: CompactionResult;\n}\n\n/** Return type for `session.compacting` handlers */\nexport interface SessionCompactingResult {\n\t/** Additional context lines to include in summary */\n\tcontext?: string[];\n\t/** Override the default compaction prompt */\n\tprompt?: string;\n\t/** Custom data to store in compaction entry */\n\tpreserveData?: Record<string, unknown>;\n}\n\n/** Return type for `session_stop` handlers */\nexport interface SessionStopEventResult {\n\t/** Continue the main session with additional context before settling */\n\tcontinue?: boolean;\n\t/** OMP-native model-visible context for the continuation */\n\tadditionalContext?: string;\n\t/** Claude/Codex-compatible block decision; maps to a continuation */\n\tdecision?: \"block\";\n\t/** Claude/Codex-compatible model-visible continuation reason */\n\treason?: string;\n}\n\n[14 more lines in URL output. Use :369 to continue]"}],"details":{"kind":"url","url":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","finalUrl":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts","contentType":"text/plain","method":"text","truncated":false,"notes":[],"displayContent":{"text":"\n/** Return type for `session_before_compact` handlers */\nexport interface SessionBeforeCompactResult {\n\t/** If true, cancel the compaction */\n\tcancel?: boolean;\n\t/** Custom compaction result - SessionManager adds id/parentId */\n\tcompaction?: CompactionResult;\n}\n\n/** Return type for `session.compacting` handlers */\nexport interface SessionCompactingResult {\n\t/** Additional context lines to include in summary */\n\tcontext?: string[];\n\t/** Override the default compaction prompt */\n\tprompt?: string;\n\t/** Custom data to store in compaction entry */\n\tpreserveData?: Record<string, unknown>;\n}\n\n/** Return type for `session_stop` handlers */\nexport interface SessionStopEventResult {\n\t/** Continue the main session with additional context before settling */\n\tcontinue?: boolean;\n\t/** OMP-native model-visible context for the continuation */\n\tadditionalContext?: string;\n\t/** Claude/Codex-compatible block decision; maps to a continuation */\n\tdecision?: \"block\";\n\t/** Claude/Codex-compatible model-visible continuation reason */\n\treason?: string;\n}","startLine":339,"lineNumbers":[339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368]},"meta":{"source":{"type":"url","value":"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts"}}},"isError":false,"timestamp":1784189548680}}
{"type":"message","id":"641544d4","parentId":"4b99ed35","timestamp":"2026-07-16T08:12:47.430Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Redesigning systemPrompt replacement and startup briefing**\n\n**Defining clear-intent hint patterns and startup briefing rules**"},{"type":"thinking","thinking":"**Implementing fetch with AbortController for adapter version checks**"},{"type":"toolCall","id":"call_QBVnzRGMfyWZpxfS7Hfkbfxx|fc_06276c754c6605ba016a58927ef2c0819bb8c4cf92609c54d2","name":"bash","arguments":{"i":"Inspecting notification listing","command":"spt notif list --help","cwd":".","timeout":30}},{"type":"toolCall","id":"call_80XCFO2blEDAtLedYCfwpVmq|fc_06276c754c6605ba016a58927ef2d4819b83a5e673160ebd3f","name":"bash","arguments":{"i":"Inspecting update notifications","command":"spt --json notif list","cwd":".","timeout":30}},{"type":"toolCall","id":"call_eVpnsaxzvx9iFTYtXZiYuVQo|fc_06276c754c6605ba016a58927ef2e0819b8c07564834466728","name":"bash","arguments":{"i":"Inspecting adapter version","command":"spt adapter version omp-spt","cwd":".","timeout":30}},{"type":"toolCall","id":"call_4E5sv5Zm054d2Jiip0jBxXlz|fc_06276c754c6605ba016a58927ef2ec819b99a9fd1ad22d026e","name":"read","arguments":{"i":"Reading configured requirement roots","path":"traceable-reqs.toml","selector":"1-40"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2823,"output":839,"cacheRead":141824,"cacheWrite":0,"totalTokens":145486,"reasoningTokens":682,"cost":{"input":0.014115,"output":0.02517,"cacheRead":0.070912,"cacheWrite":0,"total":0.110197}},"stopReason":"toolUse","timestamp":1784189548839,"responseId":"resp_06276c754c6605ba016a58926d4d40819b9b9cb98d64dd1be3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_06276c754c6605ba016a58926f31d0819b9df15eeeeac1efb6","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJJ5v8LZrM-4JKCeAqojiV7l3pbGPRnVxEmV8-UPGUUxnWv1axYfiJy6PMkwBYmKyflH_kUN5zmXySRcqqWCEV-TWLlRFgLOLcPw_rVkYIDVwNGsemCg1-O6xTFb6a_zyNLTL0ixUm5qQbWucnenZftW6A5uqX44FrgbvgTDZiGGIAuOUmBM_yxLhuvR46gKkM_W4pv6qI6qRAimynG0TnX88NZFBmgYxO8u5XE5kRSc6oYniIwGgOJ4XvkhiOes0_WLH3kj7dMK0LK0Dv5mQ7hoC7VAY6uOoGBfH6h2KMO3jwPdS780019RIxsVsrT2dicLm4lMloa2hIFt4I9eUVm_eR81puaIMI4l0NRCUtbDi-mjkS_q4O3WkXuJeCdh0J0iObaVqLxWEFzcz5QgHDdA8gxZauZ68cVLrOBKEb_mTRkc1F-wAbXcuNfR5XTKK9sm66I98tn8ScqYEcuJIta89XWTybYvo7ktDW-iBSvb18a0L-y0CMqSS4j6Vvk-GrGK_a-iWOeCXiOeO6jWnTuM3U2D4z2sziixoiH_RHZ9isjHdFRs8h-tuKppdZphlMCW6Lbnffi-MOkGyrRmLrIaV_qNM33ignwKxwSR2ymGx22xxKM0v18xK_wvo0pJmnlXYr1dnHAiPYnCrLmSNAFL6s1s5MzvP26RHv3eveBtH7oL2anxWty6-e1gIPTX2_QYPPODlZoQ4H0xCb7YEQJ5xS27iHBy3ljWKcL2V30TeIaFmqDMLHSF6mDrZ6X5aUJ2-oEbYpUXlCz2i6W1sONETypl81SBIlxZj1dJpDdxD1eX5urLhdQDnWHl_2I570VDU66lfRy1YIOKscIcJJd3WvSY-jqDzYuQVGmoERCgpL8R6MluzCga72HyvkKpgW0I5s-oPte5QQrjk2IbS5Kk92GYqeFf6NdGUmbScWOyYjnE1uZ6_GWMKXdG0xoeiJuAfSI-Nvx8verDk76PNMtrYW08_CoJWKr6iOFoCvublcdv-UCry6f_X3WSqjINY7bXPaQLyqCJCzoQJqn_bfWqH2QBtATe0tZZbVQXxaWULC3MxdlKTyeyfo7qfyG0gMfv46UZ2eOmObEnAdvZzzjkr1CqpwbOw8gkYp_8O3_nakHFSL97S5IPhKkp0MS61aIm6hjlTuUAJDXXpE66Qga9gWR0aFXOOgRhEQZtw9njMUD8VAoQ9Isfzn--f2_GGk4bcoc1QcrNc2B_qjQy5deOtlSi9yRvUz2NBcJDnj2QQDzyNFne4SlmKxCZB_ciTtd-4iovxeXClCx-ZB_ieOuyXlDb-7oFoZDS7ppmUNmwQhl-Cp-oCe6ZEJ8E_AYH8CUhkwvuKYQ_pKx4kwWd0bAx3sokKQikCKZl9mCNUqXbhz1TiIM114JRTxb9gkIgYs43BEIaSXaj5-69CLLuMPHgqlfIFgr6nhoIFEwbDPcSwEKdRZYqxI72ZswL85EdaPUAI49VSgrP7JvIw_AgPrHMuL54JJk1b47c-8zwYx_g3MaiFbCfCOWwDJjYYowhLoN2h28BgIvEArpra7zE6Y_54hGlWcilYZNIyv_wrEqjIgEIt87asXTuc9qpdlQtG3J44X4NXQGtkLVbxfjlPOWdCebN6mdou3Jh-uYZHJplHMhy0b1GY2Ae0Y6JbK9EPMP2NRMmMq2_40qDud5eaC-SKp4ZjNhfghif3hzXAwptOtk6Ygwl4ZYv6UjOhNFWFjs7_hMxF2hAcvp2fahbpdkB_jHcMHOf4IBZYqqj7F0-t3FbqRg1ibRwIoX2gpS2Y-k7DaPvKYKSbTHw6W2lT3xXAjMHAoqDXr72vv_TIyPtDD_wfzlKwtCOV3TKz61gIpJvge34NtasqudtLCVxbAVLC0S65KjIKXim--MiyoyDceMFqrW-E4xSpPuhY6CKCPPd_58tzrrNk6i059bBCAyAp1YLb0QD_z7Ky9maPBRyHFF5fRfU9tsNxo8jcB7aJbLXg-1vbYBwzWxLwLbfj1IbLjdSJ0MGO774KpjI3_CbG3LVTk6D8VcqprXwAEd4EGXG4dMU2HkrbPivFPA-n8-Cn4iJiKhwfKXaenUAO5c0LuufBSQbniqa8J-4BRz0MR0cSAZre8B5ZjiDGL4sFHyC1PyYB3LMLPvrS3IPiFfZJkCBQkK-D0o3FrmtWmeZaSTTg7LKR9AyhWGLMFnf7XYvDc07bjuYzNuFbyDkKYaklvgCGP6OtOZoaoDqlvOy3EvMOFbgbG_40UydZ0zxi6v_JnJvlTa4GR_TYsGF0caZy2NPtdg_BCBHVxEeiXlt8YRq0_IryqDiY_LwRm7ziYRc2N8TG-rjuOKSzXQvB-GKlGoApANDGRq66Ou_VRsKk5qnFXJ0nmDC2etgPAuviktZKo6p0yGOtgy7KKpASs72Rgpssx0R7n9nqSDQctII0Djey32Skcm0G6O7jQoy2AfBF6webDhHGXCUu5vWcdO33j-nbIz0H-AbZ4HpdPdvNll1RgbslabcQeh170pUE-Ybbz0mUMIfkSaKqhEITjYQcpSdB8E7gWElQksvQFu8BOPRb_Ue0PB2Vb_K3OUqBAWryxG4bZ1OU0d1fI4SiCWFhRMoyMF3-4fNYlAvmT3PINLLmSUD5FOugxLXbjY2gDvlMiod80LL1FJjqPLj_RJEwAtFfB0YyPNGVIOuZNt7VQ8siFilt1l7UxBTxO35_9tRCx5V3HTkrHcJzGAbcu1ZUEpyB_xOoxg46jzPJkBl1mp-vVSiCex4w__jX5kbsa5tOd4WpqbF87pO6B04r7TRSdbPmAZs4N_88Lwn0t_Cs3eveRfnLCGyk8Ph_OS2mWfPx_icd623CDPY-56W5vi8EpQq9RnU_YNIRxCbsajbRy95V_yUk1S9tUgATUNBs3bj8KlDnddxdoeBZMvwItEfl8akin-KwcXiyWoBKl1PLW_mozhq-nVed9PMPOfplZZphjn1RwXJvQ71kPv9aTN97cPAlAGjzGowMvH68ed2dRCles3dK_RI3kzjFPwiOx_Uh7gK4iUF5Vcer97cIEVNaHTAyNwYw5IzWHT6BMPKu2130Yqz0sJzmjg2qggG3R_mZVCE8Y54YAZS9_GNhf84OcGtPTjG5HGSa6J-RUQGuX5b2whoFTeSpMFQxgYUpw72xY57JWHO3L1z19s4LMXv91rRWVZZstTKojnHP9by-MC_haYmPpB2IF7X-TpKdRbN8kg6ctREy5ZlxqTzfezjuXyFdFEgX0b0RvUo2Cshs__ta8Bf0y_eoUu3PIbjbqwiStCosmTzDNVr4fKzQAQmeMk9L5Xo7R5iq8qYhs1mZBEqYfhW0lqGS3rcsPLH856B-XmQejQhuL8lfy_2vCjETq1Fpnlt1ZlGkrh3qP5pWJ35RbVcyW9K8i3XgMOUlnc4P-vtdwC85nQ4fqeZ6WeS-eAwCQN4-9G838EKDGEgEErmGD5xqHovZkZH4I24Vo2E88vILaIaPI0GosJ7O0H_75_P6OI_NXsePQ2ofRK-Qzwv3_qJTf0m3L63aqCFoN9YSUr7XIEbQu21PbWRlPBMmiN7W08mMtnfS8GAEFxrufFlxDKQ_o3wZWrYhbSzeiuRW8blp6ojKOMt_-lxwGFVYi7TXPQDtvv5qD-V_dGON0rRewvOpost7fvAUdVRV2jWuYuIOtpfFn2bmxcZpLeHo3yF7i77LYLZYC8g1gahm3J4A8opLq-TMnupFY5rbzMw1017TnX6bK_SPz5JudqLGaOY9qMVJfjyuS4NEa9tV1g31nG4PqFaIOnXC3a0tvBj84q_RZA_OFe7zw2oUwxtHd4H6QcXaoKTUXps_f9SR041DtHdJmak5JpRto88UjoT2w==","summary":[{"type":"summary_text","text":"**Redesigning systemPrompt replacement and startup briefing**"},{"type":"summary_text","text":"**Defining clear-intent hint patterns and startup briefing rules**"}]},{"id":"rs_06276c754c6605ba016a5892795080819ba259ae287ff076dc","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJJ-WY5w-iTLGgvWNpqOIw6yXNsdGrnL_qq2Z7WE4dK5Mm_qfxE1FqlbnJMTWyyA1qDXtGEU5FFMwcW7f91DiYiLxni5IQJWYMNib7fmlTju06ssrcAwMMrPxnh5mJxmKwZG6ij2id_2RdtblEEmGw8ybStaWwSkGcS8oZ71r7qyhYrZBj3qVOfCiM8c3BFajjlvE-PdlBf3U0pktaAYRzX7fw2iI-C7fhwhL9aX97z_FqHFvlXltRR_Vy2REw_r0GNUdc61HoVs0ytqq6ruzGjNOwtvT5unsZhoeNp7seu04bRDPIC__Ol83_3utcweapFWam1wxpfj1_G79MkAzJb6m7zhW8lvj8n5g-v_GTAqYqaA9DZYXMgXQ7J5I-w8fkTkt540qBxW4D1KE27LBK1C8Sx36r658OiEwQmnnRIO5z7qowUZXsMQEhiXqe-hsktfSLxX-FwGWyeCJ7tejRZ6Y1dUWRxRpvEoLLO6aj_1wb1J6D6mEiwxXHCFlcVREUCA1drbQ4IRe4Jc_pmSvfB7JLOdDb8NDEn-nltzeavWqrcAvslfAC1xctb3_ZQRHB3OFV953OocPYv71RvevZr1dE-Ltp8fPztKfX0JvYyIEy4ASyskmgalTS_mBNNSo9mhprBJoDlSURhcGQI5jT0NvE2wkkJm3yP6S5TWWH5-_lTiMlV_VdcNsIIglJXQnD1m49dO4xCaXTahb22XuNupXuElHzgoYmbjmY0oZpryTDe4cwf2XZg_zfizMcf2tPZvY_dSCQkZPPbvrbVVgI4JN99c8HhH77Xvydz4Un3PcDkCZRLdn8mBNsELBJbiLeki-Y0kAgdr2jQFqV7eYy70Kg8k_WaDGsn-mq3xE3vJzraNWST7_ijm7vW9YhSP_2IUpeqDgWArZ813u1Da1xCunYQnCQf3DkmIaff9yuwI-OIxM9w3P-0a2OKxCDOXWrdoQ0NgcRihVhDXji9Y2fKTt8330zuZpFgcvPiwJRDlfIN8lgf1bcJ3bMh6_cWgrMun0qMDLivkfYCypBhbdB5UAClbtWTP9rzBcSMg9hylugbBNrCLy94A9f20gKiRKFjQbz2XQpuoAlcsiA3eFSnj6bvZy2-jRsMeGxPhhvLQiaODBl-NoUT05gA8haY-XH3f7hIf29tBYFoTTY5b8SRNesP_zTO2rcNi1BOEqPt65YyHxKqwWrNHyfDAjhIiEq7cTrJdREIwWV5ykO1k5u-bMEnTZCKyinRROKKNJLGqiMz1f8gJDSh-YsodU20kQzZisUdg_qWc4gqe99_BsDoY2nfJSzBYKzK9vDPpD_eI98ThMF92q81-aZ-bgGUk4II4bbMfUXThgUMqeqsZ-tVUyQGE4XvuuMzd0BJLD7L-gtbj8wiG3YxRSNZfPN8bQoJ-hDOW6RR8PWXlfz_91GXVsLT7nrX50d8ZlOXe90WwV2gca0xTAowmkFVhiEYDUxFI_0TAgj-C3kfUmZ69Q8E_18VBr6ffU3vcYA7x_w6pFgmre7Q4iA5W34Nmzo_lMdZ-iHiIOG-9imEFWT_LnShWWExMqtREX7k5UnHUflJg-Vwivgy1EiMMLmdytnJJoR8wvPqrWDXRZlQDwSUpLX087z1626UAgM48STrOMjoc50nWVdhPuMcVJ4HyHfHxwZZED1YjvVlZqGTote2g0EPu5o4DuBPh0QRJKSo9wEdinPtjo3I-wWFs0shNXeOZ_QsBfbcN1NdASwnsUixuqBydHFt6ZcuqvPZjnIEb5u1i6Fv6V-yztGV-47_o_tFD4ODpPewZwlE_bB42r4BJyxYLB02uEoWEx3aH4xG-swrNwIw=","summary":[{"type":"summary_text","text":"**Implementing fetch with AbortController for adapter version checks**"}]},{"id":"fc_06276c754c6605ba016a58927ef2c0819bb8c4cf92609c54d2","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting notification listing\",\"command\":\"spt notif list --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_QBVnzRGMfyWZpxfS7Hfkbfxx","name":"bash"},{"id":"fc_06276c754c6605ba016a58927ef2d4819b83a5e673160ebd3f","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting update notifications\",\"command\":\"spt --json notif list\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_80XCFO2blEDAtLedYCfwpVmq","name":"bash"},{"id":"fc_06276c754c6605ba016a58927ef2e0819b8c07564834466728","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting adapter version\",\"command\":\"spt adapter version omp-spt\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_eVpnsaxzvx9iFTYtXZiYuVQo","name":"bash"},{"id":"fc_06276c754c6605ba016a58927ef2ec819b99a9fd1ad22d026e","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading configured requirement roots\",\"path\":\"traceable-reqs.toml\",\"selector\":\"1-40\"}","call_id":"call_4E5sv5Zm054d2Jiip0jBxXlz","name":"read"}]},"duration":18589.63049999997,"ttft":2347.879799999995,"contextSnapshot":{"promptTokens":144647,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_QBVnzRGMfyWZpxfS7Hfkbfxx|fc_06276c754c6605ba016a58927ef2c0819bb8c4cf92609c54d2","toolName":"bash","startedAt":"2026-07-16T08:12:47.430Z","args":{"command":"spt notif list --help"},"intent":"Inspecting notification listing"},"id":"ecfc5eed","parentId":"641544d4","timestamp":"2026-07-16T08:12:47.430Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_80XCFO2blEDAtLedYCfwpVmq|fc_06276c754c6605ba016a58927ef2d4819b83a5e673160ebd3f","toolName":"bash","startedAt":"2026-07-16T08:12:47.430Z","args":{"command":"spt --json notif list"},"intent":"Inspecting update notifications"},"id":"8a7a8ccd","parentId":"ecfc5eed","timestamp":"2026-07-16T08:12:47.430Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_eVpnsaxzvx9iFTYtXZiYuVQo|fc_06276c754c6605ba016a58927ef2e0819b8c07564834466728","toolName":"bash","startedAt":"2026-07-16T08:12:47.430Z","args":{"command":"spt adapter version omp-spt"},"intent":"Inspecting adapter version"},"id":"01f2073b","parentId":"8a7a8ccd","timestamp":"2026-07-16T08:12:47.430Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_4E5sv5Zm054d2Jiip0jBxXlz|fc_06276c754c6605ba016a58927ef2ec819b99a9fd1ad22d026e","toolName":"read","startedAt":"2026-07-16T08:12:47.430Z","args":{"path":"traceable-reqs.toml"},"intent":"Reading configured requirement roots"},"id":"74daa003","parentId":"01f2073b","timestamp":"2026-07-16T08:12:47.430Z"}
{"type":"message","id":"57e7ebae","parentId":"74daa003","timestamp":"2026-07-16T08:12:47.436Z","message":{"role":"toolResult","toolCallId":"call_4E5sv5Zm054d2Jiip0jBxXlz|fc_06276c754c6605ba016a58927ef2ec819b99a9fd1ad22d026e","toolName":"read","content":[{"type":"text","text":"[traceable-reqs.toml#9F61]\n1:# OMP-native requirement registry. Evidence roots are intentionally limited to\n2:# the retained adapter surface; retired foreign-harness files are not scanned.\n3:\n4:[scan]\n5:roots = [\n6:  \"OMP-ADAPTER-PLAN.md\",\n7:  \"docs/KNOWN-HAZARDS.md\",\n8:  \"docs/adr/0007-native-omp-tui-hosts-spt-extension.md\",\n9:  \"docs/adr/0008-omp-native-product-boundary.md\",\n10:  \"docs/adr/0009-all-endpoints-use-native-omp.md\",\n11:  \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",\n12:  \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",\n13:  \"docs/adr/0012-continuity-drops-live-under-spt.md\",\n14:  \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",\n15:  \"adapter/omp-spt.toml\",\n16:  \"adapter/strings/omp-spt.mjs\",\n17:  \"tools/omp-spt/Cargo.toml\",\n18:  \"tools/omp-spt/src/main.rs\",\n19:  \"tools/omp-spt/src/digest_omp.rs\",\n20:  \"tools/omp-spt/src/history_omp.rs\",\n21:  \"tools/omp-spt/src/echo_commune_omp.rs\",\n22:  \"tools/omp-spt/src/psyche_omp.rs\",\n23:  \"tools/omp-spt/src/launch_omp.rs\",\n24:  \"tools/omp-spt/tests/launch_omp.rs\",\n25:  \"tools/omp-spt/tests/captured_session_env.rs\",\n26:  \"tests/manifest-shortcut.sh\",\n27:  \"tests/native-launch-manifest.sh\",\n28:  \"tests/omp-extension.mjs\",\n29:  \"tests/manifest-schema.sh\",\n30:  \"tests/adapter-archive.sh\",\n31:  \"ci/manifest/check-manifest.sh\",\n32:  \"ci/manifest/validate_manifest.py\",\n33:  \"ci/publish/package-adapter.sh\",\n34:  \"ci/publish/release-acquire-int.sh\",\n35:  \"ci/digest/build.sh\",\n36:  \"ci/digest/digest-proof-int.sh\",\n37:]\n38:\n39:[policy]\n40:required_stages = []\n41:\n42:[[requirements]]\n43:id = \"REQ-OMP-NATIVE-TUI\"\n…\n48:# fake-process launch evidence must never satisfy this live endpoint requirement.\n\n[Showing lines 1-43 of 213. Use :44 to continue]"}],"details":{"truncation":{"content":"# OMP-native requirement registry. Evidence roots are intentionally limited to\n# the retained adapter surface; retired foreign-harness files are not scanned.\n\n[scan]\nroots = [\n  \"OMP-ADAPTER-PLAN.md\",\n  \"docs/KNOWN-HAZARDS.md\",\n  \"docs/adr/0007-native-omp-tui-hosts-spt-extension.md\",\n  \"docs/adr/0008-omp-native-product-boundary.md\",\n  \"docs/adr/0009-all-endpoints-use-native-omp.md\",\n  \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",\n  \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",\n  \"docs/adr/0012-continuity-drops-live-under-spt.md\",\n  \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",\n  \"adapter/omp-spt.toml\",\n  \"adapter/strings/omp-spt.mjs\",\n  \"tools/omp-spt/Cargo.toml\",\n  \"tools/omp-spt/src/main.rs\",\n  \"tools/omp-spt/src/digest_omp.rs\",\n  \"tools/omp-spt/src/history_omp.rs\",\n  \"tools/omp-spt/src/echo_commune_omp.rs\",\n  \"tools/omp-spt/src/psyche_omp.rs\",\n  \"tools/omp-spt/src/launch_omp.rs\",\n  \"tools/omp-spt/tests/launch_omp.rs\",\n  \"tools/omp-spt/tests/captured_session_env.rs\",\n  \"tests/manifest-shortcut.sh\",\n  \"tests/native-launch-manifest.sh\",\n  \"tests/omp-extension.mjs\",\n  \"tests/manifest-schema.sh\",\n  \"tests/adapter-archive.sh\",\n  \"ci/manifest/check-manifest.sh\",\n  \"ci/manifest/validate_manifest.py\",\n  \"ci/publish/package-adapter.sh\",\n  \"ci/publish/release-acquire-int.sh\",\n  \"ci/digest/build.sh\",\n  \"ci/digest/digest-proof-int.sh\",\n]\n\n[policy]\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-OMP-NATIVE-TUI\"","truncated":true,"truncatedBy":"lines","totalLines":213,"totalBytes":1464,"outputLines":43,"outputBytes":1464,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"# OMP-native requirement registry. Evidence roots are intentionally limited to\n# the retained adapter surface; retired foreign-harness files are not scanned.\n\n[scan]\nroots = [\n  \"OMP-ADAPTER-PLAN.md\",\n  \"docs/KNOWN-HAZARDS.md\",\n  \"docs/adr/0007-native-omp-tui-hosts-spt-extension.md\",\n  \"docs/adr/0008-omp-native-product-boundary.md\",\n  \"docs/adr/0009-all-endpoints-use-native-omp.md\",\n  \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",\n  \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",\n  \"docs/adr/0012-continuity-drops-live-under-spt.md\",\n  \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",\n  \"adapter/omp-spt.toml\",\n  \"adapter/strings/omp-spt.mjs\",\n  \"tools/omp-spt/Cargo.toml\",\n  \"tools/omp-spt/src/main.rs\",\n  \"tools/omp-spt/src/digest_omp.rs\",\n  \"tools/omp-spt/src/history_omp.rs\",\n  \"tools/omp-spt/src/echo_commune_omp.rs\",\n  \"tools/omp-spt/src/psyche_omp.rs\",\n  \"tools/omp-spt/src/launch_omp.rs\",\n  \"tools/omp-spt/tests/launch_omp.rs\",\n  \"tools/omp-spt/tests/captured_session_env.rs\",\n  \"tests/manifest-shortcut.sh\",\n  \"tests/native-launch-manifest.sh\",\n  \"tests/omp-extension.mjs\",\n  \"tests/manifest-schema.sh\",\n  \"tests/adapter-archive.sh\",\n  \"ci/manifest/check-manifest.sh\",\n  \"ci/manifest/validate_manifest.py\",\n  \"ci/publish/package-adapter.sh\",\n  \"ci/publish/release-acquire-int.sh\",\n  \"ci/digest/build.sh\",\n  \"ci/digest/digest-proof-int.sh\",\n]\n\n[policy]\nrequired_stages = []\n\n[[requirements]]\nid = \"REQ-OMP-NATIVE-TUI\"\n…\n# fake-process launch evidence must never satisfy this live endpoint requirement.","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,null,48]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\traceable-reqs.toml"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":213,"totalBytes":1464,"outputLines":43,"outputBytes":1464,"shownRange":{"start":1,"end":43},"nextOffset":44}}},"isError":false,"timestamp":1784189567435}}
{"type":"message","id":"76cdd008","parentId":"57e7ebae","timestamp":"2026-07-16T08:12:47.560Z","message":{"role":"toolResult","toolCallId":"call_QBVnzRGMfyWZpxfS7Hfkbfxx|fc_06276c754c6605ba016a58927ef2c0819bb8c4cf92609c54d2","toolName":"bash","content":[{"type":"text","text":"List notifications (all member subnets, or one)\n\nUsage: spt.exe notif list [OPTIONS]\n\nOptions:\n      --json             Emit machine-readable JSON instead of the human view. Honored by the\n                         read/status commands (list, whoami, status, description, role, the *-list\n                         queries, how-to); action commands ignore it\n      --subnet <SUBNET>  Limit to one subnet\n  -h, --help             Print help\n\n\nWall time: 0.13 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":129.37789999996312},"isError":false,"timestamp":1784189567560}}
{"type":"message","id":"f1189e7b","parentId":"76cdd008","timestamp":"2026-07-16T08:12:47.707Z","message":{"role":"toolResult","toolCallId":"call_80XCFO2blEDAtLedYCfwpVmq|fc_06276c754c6605ba016a58927ef2d4819b83a5e673160ebd3f","toolName":"bash","content":[{"type":"text","text":"{\n  \"notifs\": [\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:106\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 5\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:190\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 5\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:154\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 5\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:141\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 5\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:142\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 6\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:255\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 6\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:322\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 7\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:389\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update-available 8\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:624\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.4.2 is available.\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:8080\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.5.0 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:11396\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.7.0 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:11464\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.7.1 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:11795\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.7.2 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:3746\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.7.2 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:13754\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.7.3 is available.\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:75916\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"rollback\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update v32 failed to come up — rolled back to v30, quarantined\"\n    },\n    {\n      \"notif_id\": \"5ff50e75cd91d3b88ae3a0aa863e4371ad810c9747a43ac6242661e8cf8738ce:6\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.16.0 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:14136\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.16.0 is available.\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:168084\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.17.0 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:11117\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.19.0 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:16106\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.19.1 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:93415\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.20.0 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:226355\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.22.0 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:324900\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.24.0 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:339697\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.25.0 is available.\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:284603\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.27.0 is available.\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:291808\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.28.0 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:17867\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.28.0 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:17870\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.29.0 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:362607\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.29.0 is available.\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:371432\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.30.0 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:19490\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.30.0 is available.\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:372696\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"rollback\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update v53 failed to come up — rolled back to v51, quarantined\"\n    },\n    {\n      \"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:371901\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.30.2 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:19710\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.30.2 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:19851\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.30.4 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:19968\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.30.5 is available.\"\n    },\n    {\n      \"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:20842\",\n      \"subnet\": \"SPT_DEV\",\n      \"kind\": \"consent\",\n      \"state\": \"seen:6\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.31.0 is available.\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:75917\",\n      \"subnet\": \"BIGNET\",\n      \"kind\": \"rollback\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update v32 failed to come up — rolled back to v30, quarantined\"\n    },\n    {\n      \"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:372697\",\n      \"subnet\": \"BIGNET\",\n      \"kind\": \"rollback\",\n      \"state\": \"dismissed\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"update v53 failed to come up — rolled back to v51, quarantined\"\n    },\n    {\n      \"notif_id\": \"c8939d2f12b7488cf658a694b500f2da3ab32fa478dfe078557a862534baa573:148\",\n      \"subnet\": \"BIGNET\",\n      \"kind\": \"consent\",\n      \"state\": \"seen:7\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.31.0 is available.\"\n    },\n    {\n      \"notif_id\": \"f15d837bdeff3d56f5d5a21bdcd6acb9632a764cb13c477cad966ccb811be884:24\",\n      \"subnet\": \"BIGNET\",\n      \"kind\": \"consent\",\n      \"state\": \"seen:2\",\n      \"from_id\": \"spt-update\",\n      \"head\": \"An spt-core update v0.32.0 is available.\"\n    }\n  ]\n}\n\n\nWall time: 0.28 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":276.12690000003204},"isError":false,"timestamp":1784189567707}}
{"type":"message","id":"1959bba7","parentId":"f1189e7b","timestamp":"2026-07-16T08:12:47.709Z","message":{"role":"toolResult","toolCallId":"call_eVpnsaxzvx9iFTYtXZiYuVQo|fc_06276c754c6605ba016a58927ef2e0819b8c07564834466728","toolName":"bash","content":[{"type":"text","text":"0.2.1\n\n\nWall time: 0.28 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":277.13120000006165},"isError":false,"timestamp":1784189567709}}
{"type":"message","id":"03d4b026","parentId":"1959bba7","timestamp":"2026-07-16T08:13:09.780Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning startup update probe**\n\n**Designing candidate activation flow**\n\n**Implementing auto-resume confirmation check**"},{"type":"thinking","thinking":"**Clarifying command argument parsing and error handling**\n\n**Refining bind failure handling to avoid session shutdown**\n\n**Implementing explicit endpoint identity handling and auto-resume**"},{"type":"thinking","thinking":"**Testing API endpoint adapter inclusion**"},{"type":"toolCall","id":"call_5rrDKb0BW37LAGVRkYNY6VxU|fc_0c059453405e8dd4016a58929553d48198a4690eb1cffb47d0","name":"bash","arguments":{"i":"Inspecting endpoint identity JSON","command":"spt --json api endpoint-info flynn","cwd":".","timeout":30}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6785,"output":1100,"cacheRead":143872,"cacheWrite":0,"totalTokens":151757,"reasoningTokens":1056,"cost":{"input":0.033925000000000004,"output":0.033,"cacheRead":0.071936,"cacheWrite":0,"total":0.138861}},"stopReason":"toolUse","timestamp":1784189567723,"responseId":"resp_0c059453405e8dd4016a589280134c819893f6af52f714f3c3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0c059453405e8dd4016a589281d0188198945afc5494aa0068","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJKLJ_E1UPSlsEghv2a4R-XBkC4Ucs3-VzGc2RgYyPL2FdAIuIIC4p19rKpKSVtJwzgRPmXJulRIiMnqtsKJ1t293gDoKeAL2ZfP6XOar-GZvYQsykYsLMFm9gkbF9SO9TUqlZKGweIXBth8fma_G_-9ITWf42um108K3j1Xn8mIagzwzIdJJQ9K6Wdbb2TSFxKTUXduRSIGN89v5DyxIm_hvbiG_FmtkOh4-FWkDY-Ee05gGk_BE1-d7RgHh41a3nBHLbGYyrIN2p0tWRo2Z-A4RSHVUzvZgeqzqhm8fhAAbCMjGUHD477SFHEbN9mTxXAnFjscCPSAxwjk2v1JywnaShYZCdBusFt9I1C3VaJZ_zv5i6Nvd7MR1EfLnxWN1kPxRdqob-EX4lXrBtoqfGtl7YagCnkABbnBGZeD6qOFTH33gxslCxqYjfNW5997S-zM36YO4j3y46llsjWMea6B3OsKUFbQzPX8SW59r8-hdMZhMa8ZN70VPV95xz_CXilYLMEDdbcNwQWspwpnEj3fKTMG1wZZNmdz21uIqt61Nif7OuMY7B89-CP2_gAgi1nzg_QWnNQj_63meR-gbxLArYCECu0TqmTIETt5N-37O4uejOf49Bnt7koNzzPd5rlUMx6kwTbvTeM3e7DUlbRbGhIwNVihUUCFsF_0Qpu8VekpVHJ4qZN2CVLSQ2MQQYcDub44PV9aOWdqVwooM-8GEcZ7sA4EP85BgNFiEdUu8FrEek2MDC2FTB5cSmZZsZGJGKgi-C9m8QjPxKXg8cxiYebFOTrEHyhW-glczyyCGUspX57yFSke-ekauWJt52YTdisurNHGh_xm8JrChfGZ1vgzecgr6k--20Z78qQkKQ5u3tzkYcUTq-YjzcBKb1pvJf4F7ZDmopPGjAj-vTr64ildGkTn_CedXGgI4x3eb0SoSmtmIQQNw7WmgffaOdWjBV4lASgzkbxN23wRMqSVTd0GLv_CvYl6wNJ5QVH7_yC35oLDtSrhnwFNI0kUk6c53-EUFwpAyZf-_OBFvpEAABBBZHl__pyQvlbuQ_QyEp8LVWRHwDxOH1bMMndQUl7si4eJ8hOaoMx-9T-YSvMGz2ruP4k_6PEIi6I2usQAlPh7AbIRcuPAZ1ZRHTRRFrIWrKXHvUs3x9L7-rt7S8KI3JnXHf-QW5pDBRWl9S65e7gQNQ3Tf0iqc5MKWRmkWWG3xVQEJmms0CnGsOsobgRakVUMyh-KHWaX77n1by-AiUyhJ39-L2HdrPRq2DQWXowLMSl5jqC4yLoFJYuiI6ZFb8w_8c5ylnVqk5zWlhj1aJy8lQF4Ol8mH_Pa90ZwiDOcaIvTLeqxX1auIIf0qYThoJxK6KsmIcVtYqR5JDuS0UCazYjdkpL6-GISt00t4ECdqvjqT898cYEH2Cub7EO9XXcE60aH_Izp7fcKHlTlmgv1wsnJyfl-34T9PD6pe60edIk2i5wJHNrLRDBgu6awUgIfC6AlvnWUxqQM2NjsGekjgNl332KUqsq3Wc1HyuwZLxAayfX9X1vELM9syfcQvSiNndQ1CmX1FpTSi8QWMTMrmaS3mekWUjb2M6FE-TcWeFH1LbOjAIboJzHeX8pJE0uaRAMhdJhMOZl-GJsSnWMZv71nXJkMMTasW9nwVD3nlmTe2jY7e-c34OjLfD7nxgAOo4lSFbTrNkDqSHObK7gCrLDm4LrywCbwhS9TDsvlIBERei9nRvtQaCtsPwgn_nSYbahjrt4LoQH8wnYmcX_XIC3vpcc7iutLSO-yYDHgRgKwXO_oBIYn7OzMVpr8jFpo9FdK3eDMKwp9f6BnZq79Z8iNcsQxzvx0kCYFKcQTdfjZMl516IUMU7KPxQ8s98c1drW2TIMN_fiQUkfQ4XEQ1r9KyjTjn5XTDGIK-bzuqRbHDJfMy3plfHEBbeJUDP-Rj6NKIAmfNvKngetkLeEOWAz85gtb3ZdoSi_iBaZcwLpVqxnVYUWGEhvElWNycAIpgZgDqb1Pikexrlnbgr2D2i4_gll0S9mbddlYuy1EXKI3BDUrijE-k3q7RbWdt53SIiYr03TOQNhG3aaUkRiOokqdErPS6IY-yPmMBM25oLgdRENoOkWNrR8vaFb1NlMEXYMGXjTdHcUHbvN4Tw6-jzqRHH9KJqqOmHt_2dOd0H1ygI5sIiJltjCJha_4IS7r5i9klLXfTqY1grnz3mBov2r1xC4tgB5jOTQvA39k7_SeSkWQ6hY_I9NXeU6YCo_TSGo3heaoGVdikeVG6TjAZDslOcoVdyu00nCAp35FuPJq4-piQrYPGCG6U1yZ9e_HOLRVAYLSXDW9ZJbWS8uZeoo9C--Kok1YYjKieFmESPNY-dIwYBizALj44plRQmphXVDYzJi8gLOrzwFP0XEFdkUnz_iydq-T_FOppMe-TTyXRVmvtpFkhV2Xto-y6izfDuyGvReVf6wFExk1s_nc35Mv1W_vuMlrs6vPCD-MmzKnHcMSHJqrQaKxOR-PHzABmOo-415EBnbimKVXq6W1zTMBpB8cSD801hv0bv1f8eh3WQ195eipnfs4aaAzvXe3cY2QfJG_kY3v_ZV8O9s1UQpdvQxXUcmvRiCk8PgkSc8O6wROTlrDvXYCcnZOd3ZqqGxr056n-VN2q9vCR2JZe_cZH24mVN3c8QosW1vxxZD8XX8p528nPPpDx5-4Aox4W3oAp7EEPvjbTw64oGTJtx0hjf2a1FYt5bEv1gAZtNrTVJRRRMPvwKadM2aDqUh8Yso0hF0yrAbqWKA_qPPONgPuvk_lRINVfvgCNmCorypyV0cODAL6qU66B547Dtm9V1Kjxds5tHZ3rNdIHu0Sh2mZ8Smgv3EIlVIUKNK59ZKqOjDCBxH4m-UkVF7-2xKeTNhOSrsj_2yPFwHIcUj_bl272--H5k7PAHZAA_W9Z__xy4u5q6w6lp2zISRBDYjyr1vvxtyYJswQrGJFG0dIy5FxQLOsYBI5CbtoM6qXwdXUck2VD5q25lPJd8XBbNgu_DrZcxVPCuAQ81jAT9pBAyX5A9pZFjWIzpsCVuSyYFtrkIr8yzqz3zwNypKk41zTMfnU6nBgqAPbFGOEaOxZjDSFBn6S-KyMjvPkTbKoTDQCV_wDvCM0PYZ0GEjnMKf1JMMVpYdTXe7hn_7g8dheYalGApGTxEDnUyLRVM5D0RqTXZAfza0XOv2ya35Q_N9CYQEScfe-21TbuxY7oIXmDYweYt1TIdAvkdO07Tx2ZLQag1oQKG99pmyKG60ysvG2I3lFqTU_Y4oycwk-WPPhKsXQqdPGxilX43X_gx4s1zx1JuYQE1KHa79m54M5n1w8NQczXuoDVAMDpsqtWCBlzQhf-2kYo4oDyS2s0ccolAUunRRAJgwDX9kacC_mADg9WlpaTgkTZTx3SHkECcPInwK7zGDTDBiEXGSG_g8wLDAiDKzDxnxLVgCsvBNx59i3IQOnVUGPN6-9TRBiLReCzwCaNy7tHQjQ07iArkZ8wIZXV6b1qiaOYqTFgble-mjJ7PLIwsYaiDS7n6w957GAtjHvZhKYfGKLhrp4SrT-TqZPZXu6aTznhisTuT8Hzx8q6ckJthEybCbnJZGaoD_eGLkhoJradWx_xusBmeVhF0mmDVtFX3lKuiRHRvUXy2q4eBCiMkm59SPoYu3ne5W5TP1IM3zVxDhoXa7xOznFbzgi6R7rnmt41-g_WpyY9y8NGf8AJ28LKvyg4zYIFuDhq3orUzyjL77x5wpXjaHRKCwuErYvkJJS_Cj1WANbueaH4lDaICziH3g4g5SzLSRrcBmwmfMYo-QLsaNBm4sWnuwHqkgXSbDf_l6if-_ideMS6oWh4Vdfy51b4GfAnILlzCdnkZeMnvwC-WLzBu8fGLli8mdlFqp7xe_4eC3OHOZrUwavfAIk09iuq3vA0qaTDjTq2vQsarjC6SNEAaxzs891BpCb3qJgIdIxFha5jT6_QVmGRopKTHAIFWXOGYAfac51lD0O65co8bclVL0idxMMtJ0KQri3ugWxeIXATZx8ET5Z-ylxywifu162ROr009Ga9cbvPY6IKqxQmlwLBDBn43rnOBM9IygOqK2xR3JYf3Xzpo-GTxum51z39Xd11zj0qvNcGHjPW3yTQUcZ4pL0NhTEVPjtILj1miNSxQ==","summary":[{"type":"summary_text","text":"**Planning startup update probe**"},{"type":"summary_text","text":"**Designing candidate activation flow**"},{"type":"summary_text","text":"**Implementing auto-resume confirmation check**"}]},{"id":"rs_0c059453405e8dd4016a58928b7678819882df0a4e57777cf3","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJKUsOpngBNEob0V_pZZN-X3zVaZ1R8xQ9b2ubYvYODGlrhlVevwmG57u1TzwtC-MBtk1JmWdh1bx_ZSKjgxbFIvK4eOIqYBT_JWEMhhm7Bl0vFDbzW4T9faP091I60d92RmAWC6buml3YSLwTyRf76rSiad32iDRFtYhDKcChDrd0nwep_ghQV61_1MDiEk96qwKQVpXnsCIUcQnku_vMf0EycwjUBcJUQeOA2CwQWx9qmLScqW9VJRYF3pEURpCm7GIpw-9Z84rf0RTm9wsfDYdM0VlvpZ5rKa2ifyIeN_APHlE0wdyVB2F1hrJT6m-pOBNEx2No5hxIujAfPsJhCA6fjxthad7XB-szwP8bKUry_hpqDi5j2lIJJ9Ojq9s6NNnVT7tvJTymT738NNsy0gJD-uxqq3GkGdV3sogHqlzv3IZARjIQDvmc2A66i2M0vpvIwLreXKSC6tX15IvhkYLuUcheXT1rAaqNAaWiUQjvJXsIJAEUzvMEnr-HqVVsHAKS_coFctdG3Yo-gwr2GluiivNRe4PwOdYGH0u9SJyPsSe484syuy1KIT5OOL06elI_Vji3s-vCVy8cxR0vx5DFkzOkeJUaQUJFe63MHURyvFEawyIYGvsAb3i7ZyFPLmh2RXvGlWqy2uQ0qM_i2nwSignL0yY6ifXQlOiEm6Gdib43vKxPjnF7Zc5MKgblaBBxoEtcUyl1pWrWMM6YFLck3JLuy8OYZTvYUQcZ95crZ17Kqg1zrgvyfQDY9EARW3iZjAtFte-T5OK_ooYdzjCl4nKrgQUrlZFrRYpYClrBTMIW6VkUwr_zYgKBloLuGK7wcFanSlYOnmdOE6bAWkZQ91ekl52z966jFNqMla3WRwWXC_lwghrxnjIksE6IXvYYK9HGH1Odz-vNlMKjdCDK0CUs0IdgAtbEwGtVG8LwFv0jHb2sA2yprbcB2-wlC3zmVWK5hv9kBl3npLmTna294G_U7tLA-q6l0vb78vN-TOj6xnJSPoTSiYx7WL6iYb783ZgO2rYIXT2cAluVd6FuwAieSLh-HKo5V4pvMAlrF8EdTL3fdiapFSn7ED1SFfiK5S4KZ4w0wAQcTTPz4NfLGtWsCs7QYpJCC-wqN8DhI-4AEKp4hFO_A0bKmwuQmwX8mR50K3oAe4MCWemczLdY3pBkE4lcRBWGgbAiQZGNgAuhhClQM2eJ968jt1qRHFxUl7W3hpWcwmwEuNt2M_6HDCphMWfkBC1vjTgHsuCecFt25b7bGGaAGKSpISrHCe9s8guEH2pInOF0sq0hKthVYfPivXgZRDNVOvYioWh_6wKOxzOUZOqcec6Ob0CV5paN8dUWYHoonbbGuWFz77K2dP03VSnY8N6ejPda_8nlkJJwwfIgiMwffPLYNqMaLbQcwUC5OVtkJcG6DKUQdqF9ynBP7adcy_GmaQ-HYw9awjg0BZZJLl2j3DZYbhH9Q_1_0RSZjR-8jSNkjc9NkKRSD7XgCAmEFzUn3DsnEiGnI9EJjanrsxri4qlomprvjaq6tOmcW3BfeNpIISPnM_BmYe5drEeVVbpfeVH9x-a0lUkZWXInQzAdmCdnFBVotNUyuvSelC21W5BbQWWaJZvXXkXUWhFlIDdMdfnHrpxdiirxu-XG4QL73uAkDXQ8SCnVHUIMr6vnyR2Pu0RmAZ5G2oafyP2CTVJ9PpGpM7jqYwIM4A-D8Wg_MGU-cv_jqvH8FY66FzvgwIag7VPq8uWC0PXEV3sOlBP4PBM7jKH690R5xiYg3NjMCBWH8nlVmZpXS3iBBAdN1gsxwthhbCTxmGjItLrNMicYMwzvWUL1upJ9RrIemaIFU8WIyVjLJaDPQBivi7ryLJ-ElH3YRk80UnnY9TWEEmee6a9xribzrKUN5iG5OmoUyOiBin3K9uYnam_hqV218qSUNRk0D5qwAz_TWB6vlNbr5WLf6PZhrHQo5W7bk9_hiioZwDvmcsoO1c3Y_TDnNNPUB0CDGLEJVuIIep7OWKTFTPHfoG3t3jkgjntk6etDmCenXQ7JU6bemhhTsxqRAkRFAiTi4Ipv4MkBpQd0dW2s1PRJWer5vhu9Ixne5Z2A5gJtiOm96xBmCybd1oRJP9qORb6CIBfL0qxrkjZCRWE8B9ROjbZYC7pyoJA0r8r2vZ1IgVcs6lz2Dm2MiBOp5TBP3XSTPRteG4VhRx1xhAhs7ts3kM6UQQKTbkhF0xPOKDRq-b9IWSgoTQ-VeqqbU1RuIqHXLWb91gbGRcoEU_PSFqnbRvEWY3hOCCf0koXu0vve4gRixEHi8c3MycHRWwShHtvM8Lh57cGS_3CCemtS5ZYWZ9VruSb5ZTtXTpAErarBuR-Y68ek6nRZm_VS_CBlXh4Q2NqeAXp2n216VRx-2e0rFujM7lc_n1DfhHeYoBEpKN9K0Wln3fa11rJ5KiCP-ZmJZBf4NMT5GsQI6rczeuWzB72Vzc2LrfqWe276BC_COv0OHqJIooxz7Icgs93eVJumQ8sis9-6tux3Op3L3GO05_8P31mcL4XPvR1Zd6daeRqE0cXExivKYRTOriYqfOg2vo3e7u809pAj7vcsOvl2c3lhdACxpveFqUaWc-2QemQowCRCpUbC6H4wK3jJBQ6_JZJDxNVZCYTPi41HMJunB38qzEzWgMFIlQXrDDmx5h8yktfJEFDjtmed53jy4m8Qi3uKAzlD835I-zTAy4_yeOoAgdzEyUCwlGW-kPT8P_aEcPfo6YUfKoXVywFVpQ7HxtWEJM9x3lmZdo8jaUrqeV10JbKFNTrFwN9NCbk1KrTEVVsi6svXjwFjkOc67yz9hva3ulaChcxoqeu-eQiAGSEbe9HemuoQMu73M3ve0-cZ_FE_0tgEnbTxImGq62-Vtt2kIKVmoM-Mw9UrhZcDfRXbZm4lhtOyoK0tJ8bje9_QaswkJCAakvlmP9dmM2qtxzfvHz_x_cNmJwrMUKbvvosq9bERIUiHL5YGjvtry-lRoM3WL2xKTJhqtlF4PYdHdoOohLQ7rTCsYmknwogjfTkOlaRaiG-epNTJHNKtWeq6htvorZ6TG6bGfeYlqWvZfzOb2uLZUmiVWQdqhlHnBj3c-JdJhdY-Uz1Lous-W8EA2FN_VP7i3LM8ZvhUVrVt9haGApg_EMthhNlDc5gQGJPZrXN3T59eIK_-SrZNruhXRMqcXHuJpnTd9r5A5qitiWaJBTzIO7Z_mM3mPbsYPuS7pPA6nXsN0t2mdbstjGW5Cvlwsw7Bz7S_6BluJVo-_ZDymBbbw-hrcTM7me5QzdALL-AQWfrWmJNji8maCYa2T3Z0yYYAz0XRbTeB6chVqfXWwziF2sZI3U1U9zFyC0TQjxid3MwBZ86XNdwqThidToIN5I0v0cW1wdwWlKHREEmHnK-c4sCVbf7VEO8EzXunqiDGCANcKW_JDhKoyjboBLxqaGdxLTyVw7zIUA4xmta1HTEVKt0863cKvoadDnQ48N-UUsPXO9X8gnyjmFHOIWuhyTLc1-yoB9W8Q563tSJ6gbbW_XTsEN3cwzv_nEllun9_MVFw3i6-HTB0oj3AVLoovHCgkUcGQYgBHDCbtLT8pA12aHOxuDnwMF4_BOVovl1fTI_9jYivUdrtlvdepcnCS7v1kUylPbr_xbEZkLwWov_UShDCtNceaqnwRjdRpDlxdz7peu7sk2yw8ecySuIGTE3ts2gJ2r9HETC6C8ZUQDNdgpclqqJjNiY2FH1yNE2KPill3q4TWqTx-F8uAG0999k40SG_ZyT12mO123cNbNyi8vxDWMLG8q56CHUWyFUHogi2qPx8Qvn2WAlePOHjKKllRoc1uGemb50IAUa2pSgwTqiOkgCVUEeh2DA-BdZBZjkJWpzEYT_yLQzqAYXT4DQUr06TA2mLVYBsooncf_2bzLmcvJ1pA32RmG6yrkH52olmjxwZIeJSR8ZPhgE_wl_VMQlPVFhonElWn9oAwHai4L7OePME7QhDPf29kOzeShmS4Sd1fcBWwJIK014lARlk1DhYRIQb1mbtGToyEqAJp3rUXj7bKfloI4cpajeCz5mVgskibtpCOsyAe1EPik5dZnufhf_aEAU3L-3-9TVFC2RSrgqB-9wcKa3ajfoX3ekKJbPJ4kwtYq3bAW9XENDVaj4aAXAzDr6b_LhP7aXQpBKilT8SxpB1m7jZL7-ncJJ34KC92I6VCGy_Kklv81cSAzMEmOd0ijayqMgtF830yNTp27CqI088AYHMI=","summary":[{"type":"summary_text","text":"**Clarifying command argument parsing and error handling**"},{"type":"summary_text","text":"**Refining bind failure handling to avoid session shutdown**"},{"type":"summary_text","text":"**Implementing explicit endpoint identity handling and auto-resume**"}]},{"id":"rs_0c059453405e8dd4016a589294e5a08198b8bed2ebeb30ce57","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJKVHw6ls1DLe8GdHlew5MGWAtOgE2xi9t5mdzjP2Yqog9as4q_ILgh1j_9H2P7-hzv7ca1KAqX_5pX5qDDtipvh0vzA0ijYmKp2DxoIPsEWBsXPDoAsP7lJL19dI4Fx4SAh1IrHPmLl5-7fvfuk4MDfO8YtOMlUvGN16bzsVzBa_To9XF7mbRdzLT0RTOYqXis4mVR1xQd6QXPDgLqs21EyjuwOdtOBhQSvW0t_TBq3fqBSpgkUfR8hM_ZtXH8p3g4U3K3UauEnr0q2KS_T6IdL0NJ3F0WO4B1tpBg3qKnfmG8UQL8XGp1VsG-zlgABoqUMuuy30O1Ti0Czf1fEeeESORoRg7CDAh6oQoORtKYcEdJl7YnFk8FO09r7Lno66NlZRgZ94HMALQOuhR6hixdRTQK1B__FGzitfyraw_P2tjCoj1RGXQMbegHAoM0F9Wz_76Zjfamws9rSzGrcF3jS_PN_iSBw5t0qwNp0NEnGQO8V1TQPpaksTV8grIpPBe8_EUtL-WR8CmqsBPeDSPNGBCL90wSGhuyTaNnOUPCaHVCY6mN2peNN-T6IaszO2p6SDy25oGDzkm08xuK3Qvt0LucZH2rK1F9bxr6FwJwYI2vgE_qk0o6LsLOGIaZ4jC8UvCGNdzVZFQajCkoXDPW4MH6RFc8k8vrdIyUiiMWEGat51yFOkQ9VyahykcD_xiTQ6bNqv3nkf2BgP5FQsRHrCAWSk-Cg9wab2puDJb17ubHsDtAw9YWNXGRsWZxtiw22v1lnr71XG1d9_Dr7-9BjSXQMEB3TZdwCl9GpAKqbtUytBWTNaNGpY4Tp2d3yesoGRloxTed_gQ6UOelcNECNTWryWBZ9oGUsrfrme6Y9kub7i4Tz31QQ_Dp5G-x5ybB7rEe6FusMr2NoY0owpJ4gN5eumOf3DzhAcFiqlPGmZQTdxdVKfefFiggOUEDSCI_p1OEpw8mw0Kc7EcXLwU_d3_H3Qp_SOJ9AvUdxfQXh4xuTguJhTwX3YndwsBL0jb-9","summary":[{"type":"summary_text","text":"**Testing API endpoint adapter inclusion**"}]},{"id":"fc_0c059453405e8dd4016a58929553d48198a4690eb1cffb47d0","type":"function_call","status":"completed","arguments":"{\"i\":\"Inspecting endpoint identity JSON\",\"command\":\"spt --json api endpoint-info flynn\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_5rrDKb0BW37LAGVRkYNY6VxU","name":"bash"}]},"duration":22056.858200000017,"ttft":2099.071899999981,"contextSnapshot":{"promptTokens":150657,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_5rrDKb0BW37LAGVRkYNY6VxU|fc_0c059453405e8dd4016a58929553d48198a4690eb1cffb47d0","toolName":"bash","startedAt":"2026-07-16T08:13:09.781Z","args":{"command":"spt --json api endpoint-info flynn"},"intent":"Inspecting endpoint identity JSON"},"id":"8e886c90","parentId":"03d4b026","timestamp":"2026-07-16T08:13:09.781Z"}
{"type":"message","id":"1564f3ac","parentId":"8e886c90","timestamp":"2026-07-16T08:13:11.086Z","message":{"role":"toolResult","toolCallId":"call_5rrDKb0BW37LAGVRkYNY6VxU|fc_0c059453405e8dd4016a58929553d48198a4690eb1cffb47d0","toolName":"bash","content":[{"type":"text","text":"{\n  \"id\": \"flynn\",\n  \"endpoint_type\": \"live_agent\",\n  \"adapter\": \"claude-spt:ccs\",\n  \"local_node\": {\n    \"label\": \"HFENDULEAM\",\n    \"key\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\"\n  },\n  \"attached_node\": null,\n  \"controlled\": false,\n  \"project\": \"github-com-sabermage-spt-mobile\",\n  \"cwd\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\",\n  \"subnets\": [\n    \"SPT_DEV\",\n    \"BIGNET\"\n  ]\n}\n\n\nWall time: 1.30 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":1304.7393999999622},"isError":false,"timestamp":1784189591086}}
{"type":"message","id":"83149d0e","parentId":"1564f3ac","timestamp":"2026-07-16T08:14:02.621Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Defining compatibility by adapter and cwd**\n\n**Filtering compatible endpoints and extending tool harness**\n\n**Testing tool registration with compact**"},{"type":"thinking","thinking":"**Planning tool error handling and nextTurn flow**\n\n**Defining endpoint types and refining context compaction**\n\n**Implementing update notice collection with fetch override**"},{"type":"thinking","thinking":"**Refining update test harness and coverage**\n\n**Configuring update check and session startup flow**\n\n**Handling asynchronous update notices and command timing**"},{"type":"thinking","thinking":"**Modifying context handler for active item injection**\n\n**Reviewing agent turn completion and dispatch logic**\n\n**Confirming agent_end and session_stop order handling**"},{"type":"thinking","thinking":"**Refining event message injection and activation handling**\n\n**Adjusting session switch blocking and traceable requirement roots**"},{"type":"toolCall","id":"call_33mqzHmMMfYFqUpXnmXV4Ept|fc_0dbcc0ca250b92f5016a5892c79304819a9e147284a026df89","name":"irc","arguments":{"i":"Coordinating traceability activation","op":"send","to":"TruthGates","message":"I’m adding impl/unit evidence for REQ-PARITY-READY-ACTIVATION, LIVE-ACTIVATION, LIVE-AUTO-RESUME, SAFE-BOUNDARY-DELIVERY, HAZARD-ABNORMAL-TURN-RECEIVABILITY, STARTUP-BRIEF, TARGETED-HINTS, UPDATE-NOTICE, PEER-SHORTFORM in omp-spt.mjs/tests. Are you editing traceable-reqs.toml roots/stages? Please activate these to doc+impl+unit and ensure docs/PARITY.md + ADR 0015/0017 are scanned; I’ll avoid the registry if you own it.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1923,"output":2692,"cacheRead":150016,"cacheWrite":0,"totalTokens":154631,"reasoningTokens":2498,"cost":{"input":0.009615,"output":0.08076,"cacheRead":0.07500799999999999,"cacheWrite":0,"total":0.165383}},"stopReason":"toolUse","timestamp":1784189591103,"responseId":"resp_0dbcc0ca250b92f5016a589298533c819ab6b68dbc0b8634f4","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0dbcc0ca250b92f5016a58929a0548819ab4df602dddc13929","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJKjug6P9SiC6w-pS9oLKpZL42poTiT_m_sDAWHQKeQi4WGHQE_XpqkOj6z5wIMTTsBQ_K8oTzMZbtXISFb8QknBaultC_v2AcwhefOhctG0baHRpiLD48iS8XKpqbOfSC5ilfmS_R88eCxQ-x1p2SHcktcKHaybzxJ4bieM-Y_9sXGbeDeCmjoOgtYvhUa9b_s9pF9VXQT_prWC_0H5lNVop4lvKYXjImNd8T6pZIPEE8JjcsUSvAUvmXO2MibEKJ7oj_fqnXNgzH7eHZzJ6jOkjJGz4zlDPokAAKl2pr5Yhw4tapAGPvjOlwG7aMA5VXfGDmPmrIHTW5ViPCpojipIqDIQQ8RL7xoAKNPpWaf-oMxRxlIOdRpl-82g90GMglKQ2pT8HWAatKW4G4tHBviUex6JLYp8TIWk2HnW4cnJBnqEUIIS2_Dqf5AzqTs4f87VTqKrPlE4KL5l9g35C4E3OsybdPPY0lp77eMiQ9EXevYmUQaLzgXGk-ZRWorI5CmlOcCv5ZlUG3btPnz7MjxxvxodpnjhgOwImYAq7-q04emH0us04-Lpxj0o9QsmwEbkZZTqkgRGm2z9eHkyNZsm9SXvzwg3boEQgLyM5jZ3GOSlH-auCD4XetelV7ZLAt7S9XmBmV5NP3I7e3hnvlQjEFwHP3r1dqWCeDR8MD2OMH__8sOeRfHdFWV13-s4tdx-m1itX45zs6Tg73n7Ifm9D1xtDMRe44Yqx21syc4yRsmjtXqrU-hr8XjugiGNVq9KfNM3hDEOGNGelSTrXRXgtkfsKCU4LDPyHGbgumwlYQWrBL9TPUjzgorKP6dUVvCgOlwEBn6B0rOXa0QV-DnMIJ5BeCDDlQTjer09v0_Jo1izYnsLvSK0DUssHZLnzFkeI996xmkUal83p9_JcfXREKI9JY2o4BEoe_EXYh48RTaUoAFBU0RKFY9TA9iCAwxtT9ppRv2VUpfZDSfM67zgrCU1mcUqXHAm4nxi_ZOmSNzxKpAlwfFLiTMs-gTx-sr1bvvu13BX8VcmyKRZrn-2e-6uoOUHvkxbm3SUd3sQKBy2LvHAqsG03lPRZTedwZskJJlzGgOIxwXj12eipvU2hXv0fbpIzn1l714lq5Dgvazx9-36XWwmvMVLOLvjarSo0u413jNF4vYXay1hOc9MRFcB8KbaRWLflKJyc9LHhyYxDcqY604LKu-JqHOqNbBFBnSZZbJ9qeoxeTTELZRuUT99GHh7OqTjMqcB0WFasFgyED2PlUtW_wCcaz3GEDa9vl2NLtYY1VHqPDfJR9JRWBdKzyE7in58JieYjOFCgnlSCMjX-BBmv5oKak9UlESkdaQu6lhIQQ8faOIq0IhSRHX6FTVtICRwe7Oq_DcGgv_l23iGoPfDtRF6jFJsVh72js9i9LLcuD3l9ti0uxY8f9BlfdTHaZ7PxVqWt_-AwINkmmXUw2b_cOh5vfGJZwLcDYxq0O7ZtXLtweo07UHW08mX79-BjAdPjUBBeZB3Xuil0-TM-30qd9_sc6wJSRi_rXIgTTq-xshYV76If3AciohwfLujD6vumuZ-VqeyAJit_Rei-5rUMHUInc7SWqMLnGZspphPKOECWBCxVc1MSiCa6sMo278yNnuFSdqJYPrMQyhe6pkVFbP3_zBetn2JFqkwsT8tJczlMpjtgQHZmeLj9Kct0Qle39b3BqZ0qSCdikktG4EFYBGA14dCvq6aGefMlzdzLVZQBQRmJH5W0oaWBQ6WMPctbUcdf5OC2udIR-pgJXuLxtPaedknmYy5pESaAt0EI85ltAjOpTOF8i0Xv6qKe-i8Q-iuScgF60Q8Co7ZPxFti1UJmN_mp_wrY3qDyaafG48h1AtEJIkqzgNhTQCrgWYOie59YSemdDZ4tN4N2aHMy5cXWvkkNQSP31-KOEljAcW92w98stfYVocUvFu5fyX17TqF2uYzyz5lfF1IFy4Qx7CC1NaTEfKhckfMvRHeQcmNHIvi1OUazlscZxKPhbmZUGN5ozyX46wCjvRXb4Uky7yKSdsh6kT2RpX_vfi7ss8Bu3rTgHYiZAinEyaWb1oPfgBXhgw8DfZ47Y1gjo2fT1FzVYNfdWIYeXg2CiUdS583-q1UFnVENfrFGh4Uu7AZZW_NahLTvBpcDiyUyAY40WwsH4_IK1Ca17VL69FOlj_AzKL1x3lOBNGaK228YK9hTUjilzjnX-Ssf-I5HgfOyeUrWJa-_BY6npIlsmgrXrZSLCOSJ6FVbd6itECRZQ78oOnqLZ1CPSvqKmjeOHeMooE5zo6ex4NaCkYxxX3vf3vzI6-HB0pjmFDE-Dquc2MvWUmZJ_YaBoXvp4Ueg8y1JsE8uCVXZxYhhdtbpF6X-05Z_oWn8NxYtevl7iY7vFLzlyVbma7NewPL7Wrsjp2jy3VKVOGwEW2D-95N0bgQ1viePM3TycLy-H1VedHe5Xph44e49108grMbcxo-rpG7v7gQcfg0lD8aWjtErytguRPuhF4BDPbWRIU9NKU0q7FVISrxQKzGz9W7NZkmqsx1hPQ_SCuN_7-x_B6_xqbf_bab2jyXaCC88L2JeyVZG7g7352ZAL3kNxXWPpUpdXVeFnTNKnam7srODdjqj5Zxp7R8UuqZyTiRVtkcn1kglgJvh48STbydCbTz69C88A0nEjWKrUZf7PV3rSE21k2GaWxHHLcbMcFOr87Nh7zEphtMWTdMEuifmpMj5sqaShS_ca6i07XqUM5ct3HM-hCBht4y7-Btl7z07ikGKbM32vvm6az3_HUuTwRoSeq8JyulgaTKbGtMaKaAEPHjKk1XhmiidHR9jdDT7HGQr2SMPp6khbypyM7xR1jio4n_wh2c60_HzuxIPL-_f9Oh1y2gm_dUmC_xREINWqz3aV0FDxDf5btpnamlr2m0K7JV1raOhgRvj-0gu_-TTUL5XGdoWKxMyLHjZceGAt78MN9DIVHxrOTlU55h-Jp4kCDH4lB_td3XF3M5En-rw1qyswIKakMhQ9KzjbQaS6bslGcP7ZVOO_irQgt4oxiVnECE44w3NvW87utykGWWTASQb_Gn-gtkqRBcIScT3yGCipDvFaxPHSkXzmLnWfBWBqWrYAgPLz7uNw2gM7I4gtu4NklwwmeEeXsgKS5igxeufILRA5vtCjiArESUlySpItuEHPN-uNxZfk2nGySkyeaIJ9PnOWHJFTz56kAfa0yKHSvwvtKtmQTAvsgf_mXBLY1qeZONgAL2TAY75j8XB-f7x3_ttuJkoX8K-2dqjlprBbILmxQhqRMeJfq09UK-UKdypkVWPgc6ojwQYs5Fvgt8klxX3hCAQmoSI6XN6BfUL5rurtI4bPsJb8kEWTE_eLxUJTeij6-HdM13-vSjEdWub4F4k-MS-k4xgbDTVJGD-D7AkNN89wi9bAgw8MYDxcLFBTYkSr40NJetIltH_qPv_9HwCF1YfWmDMk9MXQ-FzEkxi_ecODJvDvfj0KRXfoVVaFPk5cQvqYOmZ3TYIgyv9CJqBGabRqnU3ZCbBTUaMrMDSKUp2ZBx-bIudsbUwCjR8rTNTlqPwRvvrGKB5iEO4TkSeIt7TgZagRb0YMdFlYkQgoTbb5-Vj87XYhsrdQpTM7oMOZpcwpVsW-d-HSROhYgORR3EG7gplUjJXFSx13GJMinCV7h6b8JEealXDA50nkp5-UP_t9xg4MOAgRirI3R3rJ-zoxBWderIv53gpk0YpjQ4XyXzg7ve7O81xuHtIJsGct7Z6E3aPCf_3Aqrhvo9tWmqnk5EM_Tx8ha4w-3xYDFAMEuznrFWHmg7B3XFuWOkIiNkNvYbwxP7AS1BwEKRUeGuzzra2CEPKSJrJkz6vp83hjMFJkmHFV_jGFyiyrg6S-jOzpttzxDtlGVUxcYyonuPtTDp5HeW8G-sbF5Yuztgha5dqv1dUguI8q2Z-vj4S-v04HVYy_N4-HtPHUWXESEXrZbEq1L_cuh0UOJA_dKNNwSxhgudMM4FYJCkFYdyGwAlHdIgQ3vX75dMQTVeu4GJKVLvcCHahPk8zREm8KoAdOpSpbBj-sEcIzH4rPt9NpupvM7Aos5Y6jdwB0XxkSGoeuZK5XXqtMo16PZWebHuNHKW_jeyGhJ5NXftxPTiNeCohazB-TgD_0YMzf-hTUDoPcI7Ip7UTV7ZY0EhPwSnqtq10QoElxAgLJytWInKRDoNEEBreJNhThyAePaZiHdPBAdGigf4Aw==","summary":[{"type":"summary_text","text":"**Defining compatibility by adapter and cwd**"},{"type":"summary_text","text":"**Filtering compatible endpoints and extending tool harness**"},{"type":"summary_text","text":"**Testing tool registration with compact**"}]},{"id":"rs_0dbcc0ca250b92f5016a5892a39da8819a935779828ee53f40","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJKteKZWbasNe734ptaeC_6zXn1B2ihEBCIjdYQjGGaPxa1fejA5YI6mIPfPmCdS64xhN66PnKo9h2BDEdZlSqX_YCjD53N7rQdZqfY4YS3p6tVgd7vNBfwq0QhYMhcPSBVSswPcd5Ke9AB9N4VSuBbD1DcNIDmc9oivnpSgRextE7aLnKNZeScN-T1D5wretOjisxRtlHF9hksegCL2vC8R0mgDCPCWA8AfjsZPoqKDO6LnNfIMsdvh8hlwq-G32gHstZcvz5BTaW-P-hg4QZnwz8UHPRsTe5dzmTYZfLlFgiLqzl7M3hcFJ5oUimL2AxhN4xFqOfd5iRFSdFDBW_rakT6KuKbEemMn9bsduk90RqsntvSI4XtelSvOdJt6PfeiFfzZtFRVw48WDWufiTEN_iOeYXrxZA3Cxr7RCiTNl_L4bRWojpPUj2vYVRDZLTy7el9ZY6jCySM1GXJ0OzM5buyqka9_6ylBhc3092ENuw8d687XY6bEoSLAeWGR97Dli1uJwenYmIJlNtqvORhUG6_rdw3hmbpUW3Z1yimPCEavk97PMpQtFac9Ewl9axe_RwGdYQTdZfeKadpO7-gh0eZe4Gx5e7tYd-380KzwvmNtcY9aiLQ6iblRF_7VwYt_o7q8By4rsJ7uxr80CstMXcGVblRjrCZk0zLWbEA7RLrBCevzmUQF8Kf_mh--QZ3vQkncmF6ZMCdT796era91u4MgfErDzeQg-JPuVRBjLIlkkugIhcWYz1Wauim-aGvBFM5l19g9fSKOGKcTrG5JTYtnR09tF_1UDn0m9fx255rleyVdGumhbvmfVzUuzPinJeOc93lRJakoP38aJkn8x5a0aoXpUkboBx2tEr9L0_VjZuZ5ZjXAyQSPX0LhtJ1MnhbN2xHa5OK33j2noEiAJBPCAXfO2AVaDSDBzv3GS_fdiz-2PPiSwH_6XHwe1vdCXw_crZk17-YqQiB9x6yed4d7cVbNtOOpok3Mmf33bpNaxM7l8bx8pdz-myh8TdrpoFSrd3bKiKfc0N0WAAYH_pnXe_mrqZ2Z8vtnfmoEeKTONLFqPahq74AxJTD5KWF6dqpks5s6f0lGQrM6-Mrvt2pc3f59KR5NeLnkM0gdH-EdXyY2TJT-UI-Nt_R3VoB30NNV4ZiUvt57TZ1MfXkOq2uG22epM8awmSkruWfmtnDWW_kEaZ5uzceljcLojnokOHtKQVreYoxwNQ-g-XMM8bGyG0FAucqJ3aUC3Uv0XlDwQSSbIgdA5mcoExHEnOFJxaWKOgsc5-Y0Hrx_aUNC2VNrnwn0qWfPz8MoAPUQ5oMOh9vl7erOCuXubb0D68LVYd1kJKFmIx3HSfcrrlJa8onmxMF-rB7GcaOcOjk9KCq4UiSF1x70WUsOSSnIYfpI273YOyDtpehi-k4bq37u1r7PrM06o4lWBeXPvvntvPTzd7Cr-5qZENmGveW7Qbw4JFQWYOXhVJsvLFtTSUlfM9Uq030IYlrjlLV7WYmi6d3WzxQWvom-U1Js8mMqx10ZjrnvmvdK4StaNqLc1l3YOxNkSvVL7nyehM5J-n6qs88Mlpq5ZH_lCkNnpW4Oi7CD4hiJnlG501CATtOv-Q_JxcGoskyZ6Sydal5G6hkytR-kz0VwxHbwrbol6YmyuMBA2pebWZKncEZhYzmYO86heRGvWafDVww3YXa8eRDdkN9PD-21oAk9-TCnpgIbhA3unB3mLbuXOLsWH3Wciy6NN1hUT6KAtIqsiV-D2jsIIUy1APyoHExNGkOSj7eDzuSy40LNjMYZV6dMUQ7yQ0XdB-5f-A24cz0kjwr3BU1k5sUYpgcHm5uRDVq9bgzeXkuRQ5VFn9ds6xBUC2tehTXVPwsPx2ONyBelv3VdVytsx4QVA5b8462TCFlQYsop5vZjzwrizxE6_o2ERHUR1W4IVZkPHzbbDWdMpNUt55HNYtrB3dfeDAe5KEFc8SWEKjHWEfuaunRuK4n9eOsHnVPQduUJtvT-NWB04BFZKKmN-LftP5Onx3z3nDLk6grFX_Lz5LPGxJ_ddMFVSi3NdYQK-QeKP9Zor-pfbLHZIzLEEDyzqzLewNmxfB71amZKIOnOMr-g3wX5qzMlt8eQcznSiVPT43LxJVQ2DpS_-XKWV_EnRurINcq_o3VC9mUt22C7pplo4UU5YaglMv0b9EC-Hw8Crmpla4-glD8mu5R8Lls9c65TYiPihQJ3TTJug98dRagzXylZ4gfVGokYE3gXWggfz7w_5jT_8XPcKD_ixPI2ClwYsxneybpy_AFCOg2yvkyIkqVZe3Pw_mxUppkN6CLRP8GKxYtpYPx1sqZD904Hyl0pCBeeRAXk_ufc1elfQjHxcxVMEqqHX1EQfJ-PwJoNAu6IMwRLVc9nLY0gSPW_CNbREEG9YMQJuRLWzBX044ybeEfh6aiC1-GEmHzFsj7w7UsVWx141pyb7fCV-ZmAMTiGMM51wIyawJYQ4GwftdxHhIHK2piS6p7GT5nmvXzHuVv8fioYwW_MYIlx2my_uNGfxa-Dwjj9M_Ftt0Tp_7wWerrZtfNcAiSSLgfr8KR1JvSxsd54lujbCNSG-jvWmWJIeZwKPNYxSo64rt2ctckYHZ_A0nY9foN_4BekQGyGIDuyEpnJh9JifY44UfB7xgdu6CmXQY0B23wP8wx7UYXIeXf4qn0VWyAT2TfFWZNLmnPRzR0PgRoX_buW5v6Z-DGx3MZN-UZitp7e9j3T8yYQSMFQYfNUqww8bNGpxHyIuQJg1MZ95spDy-vr5VwNigatVm9CWKCAIzVQV0rdtYqEcRmNJY6xkwGSRGjiMaQyzSFO0E3w81_CufpEWYA6x_wMNFCdqYBBqZFiCzKnbcTliMGG-lqMkAkxwlHif89sCiTaCWyWZN0TTeccITMl1qV4-gNZNgKLlnstFIKkFJrgZHAcqEla6oaBrH2fJUzZlT5cd0XOXHVXhlNQSqS6EdWYffoVDX2DYov_T4-z1jz6tUTFwrxAsEUF-az9RWbVBqjdOnEQH0iAW4ussDIILFuv49bFLFYrA3iC2R7J4x9eb5XraROA4pUOfPKvZbQx-mmMOgmpC3pzoWzZk-fTNxkXEtgsU0rAn2woFq8WZwuhKkKnODC7hzO-WgDPo0Dfj-0mph8k-od03OGlH4xA4V-D8Oqqy0QuXD_jaWJ2c7vWI_U7XyE5Sv9GWq7USRIvEf4mghJsrOCE6B32R5fhX1DDLuBUfU05JvanYQC-v3puxB8x_ijMMJze8Hy_VHlXQ2HX7vormgxttJeF70OvVvnaIuoIKY3vXm9i0gd7ljhMV0FYrU8bHNxUv37BiHjJcdNkIjJfttCQo5xQb9PL9qKMPGZEHIo8ObuMNA0zYHXUzMN_tjvawvgKHrQlUY3orai3Q2ZP9KG9F3A2u1OzfeP15X1OSRxGW-xIUrb7NqObyLSlB7AKLfwRfiF_lnW0q5V3LCtXUT7JUYNbeGCX9YChVY3lj2RsckOpffM-H09kUD27LeVZTJTilSSZmMnzbK6r98Tw5ncgfIT4PANQYyxSm55O0HWuILAT6vTA9UI8ls__Cxl6ZS7utUd2WTKnowZwxH4Fvej5J3sgYU6eWEtNz0r3AeJw4sKGhnd8vVf2Ap354lktKBP3fx4gZjqeDPuX5K3R2JZdXLFRwDHgGX9AxaaVjDJBisdZ2A7qaD9YkVY7vPxDKTWjtnXXXAbUde5oeMRZaUrZibqRkbHiH_tIE1YbvsVwNN8H41YXsEVLly7-Gf_PbITmizFUPnZE_pPxboHx6zOc1p_PjDZUmdlDHid7ujlq1Ftn905qlUrRoalLXoiBIfIqZDYSsp6IRXJkYRFHuuYJHVMffY14gvfHHD6AwuOzHZDFPaGqK7szsFmQj2TJYXjYOYptUeZKrv7bIAkzqawUJfwgQMAS0qKwtnj4DGbJnOQpfpAh2sTweWD_w4HSuHorhrQIGGiq_qfwu2bUf3oO4ZTgawgeGptaNturbUMZb55ABlNmfXdHeFKtoHxrcqhFPfeiYbTQuRXikPmeNeIZ6_RuzNPsxxSckTVPPizzeOyQ1lnZm3MMl-xCb7Ao5TwXyABtZ-nw8C3xDqX0nj9FGwNlUCpv8nYFJRn3nNKlTTKjSjZdzKe_kDwVSyDOsPzXUNaxazka7IAmHqE-Vrj0sB8iDbkNCwM81eJP_8RPB0bekuMbjlYv0JIQgBMNyo9ukXVKivvF1H80jrQ-KOssgOvuPAFXvB6ckSoFq_mgyCb6ThGp-CgmyjC1Fx0mfVrSphuMiQ==","summary":[{"type":"summary_text","text":"**Planning tool error handling and nextTurn flow**"},{"type":"summary_text","text":"**Defining endpoint types and refining context compaction**"},{"type":"summary_text","text":"**Implementing update notice collection with fetch override**"}]},{"id":"rs_0dbcc0ca250b92f5016a5892ad11a0819a868994d78f48bf23","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJK2PtaZTFNWlMLgoKp9RWMDKtPwSpuwop3qMDekeJZLi_7cF1ApAch02t7CjZ04hlvZZcK-446CSlCSbuHQD92YtaF2BP5g_I1GkX3ctnY8kw2JXJobczwLxZVhXZ-yXdzbnYbMW0EdAjbHMlBF1AFbvXYxUaQX0DHTyX0uyASsNbzuSozFhcw8XWZMdw1Z4fRvIXcByO2APvxT_vs2i0_XJSB_EZkdhBMNT1ZTj0lP6YHLCb6FNyYR2to9dhvEa6vsrby2C3ch_uyuiFXfPz_gMYxVagwDcNKR_3WNuymjcaaX1yGIy_pOpNGg_vbZv67A76tFVZJFqUM_dUvVyyXcfFgJHPrzi1B1y24XvEN07KNqbBa-u7252u7Pu-ROsCKaYjGwyj2CWDF-XSoCgGNkn9wDKkIeXq-NPFNqPyxWNox02FRO6feLeUbTl0Sd5CAwLlYsbW6UBayVPnmp1MCsOa8j-wRjtMOlNHjUl3FVPGny8q8KBrtDZjOvJDVMc_lKv27kSjOcQhG94pAyCmvf45oExRDBXTF2EsoUSDUCWcnWhHC5QiG3Ef6rsGZX3E7LQPnA5pWrFSN06kmdnTioLF0_EjGYfnu5bYd71y0IMvBCEKBrZ4ZmeJ9b0-D2QpTjlCjaBZROrxILUoYIqC7YMzXml7tyfrdsyxWA1nkngWHvGAfBjbU6X4uH_u3lQdqgLNRG4Qmp1ISWPIMK0X1ru4hIFRL8XDmEaOY7EYdAvZNi9esfKAILpMj6LWenhRANryOverm6nwjtJMVQBW5BNl0MCHqPJ6Mv_GBsI38X3eScbM15x66TF-VmLSQBMpXKXbuMl_Wwn_oC0N_UKETPBw-qm7JfnEUTkFVYNlISoqb9oLHEF8Wju4R6Qf38Kuw0sl0fEgB1k9VJc0s-5hmqIiF6XKUlrplRssoUZb37PIij87u3SxF0QPJeieoXmjMVhbdILA9VlaZKhU2-WHZ65O90kjoOX6BjB5Plf5zcaC9-MrGLUuSx7OZhKfktYAKQLCjz5wcQ0vUBv7rIRVao8RbnNEpK71AkwmwLF3gdcCKGqz2cfukw-WqTPXo6DUorVDsRAamXJpIRlX_ECkg39jJC-7XVoXAZqvnzESsOvPtRW9Og6d0maUXl2vbaKQu4iY4FUmE-4umM1UpY7jiRlphZ1gzZMHf-R45gvoBgIkFK4HF13GM0s--eN9KlMNZNYDdoI7yGtFnuUVC8mNrYkV4MymZIUvCWubi3rUsxKgBHIkiCDDhEHlqyc1Iv2exs3RgHhDqSndL-Zh9SjNz1LFnmnv6CASoPOvYVupneoIoDdAe2OJkXGfgUnTpGsTvyChiXCpwOnS006gjQc1Ywf001yLHtnX6WVhoek9tuAMlNHIf7fxSBniwK_Jb9jbDrhwMNqGMmDJtcvPrF2QTmbJDHss9vVWjeYwDFUNiABoNXx6GC2ZMPVow4Q5eRYQJITv28DuuoOW0QhErSvlQ2qfD7ENeNR-PhO5QbAbJUtL01TrPeoGrm8lv-5QCHmAAd5I4UFLJVh9YZWaaJIqr6FNeS9A6qRkK_h2X_fMeikRIAP4pbqh5AI_G4GETt6cU4n4ahCMh-TtCDugToRtsa2Vqyp5HvdQ_no0UZqTwsKxk8TQ1VM3wtoDHPrwkNH3DFyL3L95WGJ4u_3ypyEc2x5FNzYsLzQ_9ZobmdycWJfVcde2lk2k3g4TjW_aQA-AJ0VIK7qZYrvVuy3p7puMNFxoZoG62w96lBOfPsQANgQ9QQWqOl-hk71unBklv0C-uRIXpT14MOWhUkncxmQ-bnfsdjAQfSpxz-Q971gdFZ8GtroHe2vZo_8hxaz67aXYBmicc3WJs-sr_I-V18wJoHy_ITPxDuiKXr6AncIYjF-UsiLeXmX-yck3--QktL1y0ZRUuIU7rJ5pJSvBTXPU75RMB1QVtsAfVRpaj6-GFtjCCFODf6TUHtU0y_3TlbVLUSJ76ZnQ8wXwvcnIrAeCx4lG-oJ4yBuvTjElfSOKav2Jc2mIyJOPXSyF6Dv6oImujM_Hy5W8jfwQsK7IrzrkKeOViVyrCOIDvwF9YxErMcbnRC0VNEDdgvtP6qsuAhBwGjdyxU0N3nZt9T3Zmh-tEls50BrOy6hFdO3HrOzgDG8xQ_6gJz0KATiptRhl0vO3mm-kTWuN9EGEQtuVQjvvDbsy6210ne9omtBiAQpVI_SMRPslgr0fMxb6_U6r2_Y5y2y67aXQfpQfiSwzyd4-eyF3xrotlfDbdsDV-wfyx4YwoDP6vGGgHP8pb5j2yquF1qnFihvX3V8WPWhYjFGpRetTxe3076Gfr79EBg05KjsAovm9yLzMQnMBEHFoinaiPXYRNlCHGPuSe7RmizOiNCPAD84I93BqQOpEjYgVxwBAvBPcb9pgpKNpy989FiNDJyGGoJspOADqyQrx4zG2PyRzgXuidoS0S_DZ6-UGOH8gHjor-Qy5QMixUMN19tYBIacVFTEQ0t5r5Mj1Of9g8hE1SYVQhIi1f1_szXpIY3hD3mJ8nzimlyHPb0yosDHC-bmdbyq7Xjpa52oIzKAs1jJWDhCjL5mE37A2jMI-3Hnau0LjFX6uwqlNows5_Vc55pfILIUi-gONQWMdyMMs_CIy2si4ZSgk5i2iiok-D1Sq_SmYONyc4G3OgRxyT-dYOedWNXOcmDzEmomaTF9Gv-fhy7ELJcFGUaO3RSRvzKdpVZI0PytkVrhGwqHYUR0xrQvwRcfHwNL_T3btTa7p8dBkbE9Osww5aynAL5eLc6fz-YbqWSYd7pU9i4iXZ4UKnPV4DNj6wAze8I6agf0hd4qX6l2e0mrT8Al_tPfaVrZZNBqjAFk8xm1LtGIVji8A4YS6dD1VO8rmLbxJPiXigny73fgMTCwkERzHHb7xb04FtenBAoJTScz2EWnCXt2IjowqCwg3gep0WSGyxI2rjgiZAdjwLiV3kZWuGvEqAGn0_gPG60zPLatbcAP0vZmIEQCy2Qxqbt01yLDghtFJEVEKgQ6GlYyrAVhK0jyFpBN6F0tkZ3QXXfFOEurl9aT-vIeyCggZ-76elhSOBlJutZFjRtWvJfyCQmuHS6WM68UT8E9TvO76aCXvlcNcy46p89_oVU9LPklU1oWU3AWVidr3KXHo-fu3qNSN_yOfKT2we2JqmPEhNdmZcQs9vJg9cD36Gpv5ser6jUHUwVUvnDPhg56FFiMMobCInMI1h0qaLVv3TKytVITfQXZt-aGkMz2cJvvtBiNdPlbXiwJavX7m_wkEppL1yZusXD7sG7pz9H49XBVLsn6LUBWi7H-BAZI8f_JdAh0nv-Xs8qWyM44H1k2_U9hqjeaU0UW2MItTKb4Um1S558U5p0uXXs8z7S3IRgvKf0rtwZSmiz6198XK2K-78DFwk_MhpbRPvE4X5aD86yZ2tPpzbLDRNQrDswos5rPSe4piLD78J-krt88YxboJq6qNfhmZT0-2KVKwJcBu5Q-s0VkHmfmbWUic_BAv-QRlq0NiDyNcWG2hUsSoWKgig2Pz1VsfbUggHbFw0Z1leI3hNWWtbKMa7r0p51tKVGMHPnPpFLsGj35zghjbSULpBNIKxq9ZY_W-53naOpMWGbh33GKjDPSjUIgmfH40JrJWHRSeFi_Frn6I4TkwOFTIphd3WGJNCaLqSCACjfcvWi2mr_300p6d8EZFAcu_Svh2oyJX_Zfq2OUhFcLBaLmgMU6B7nP6tqLHj8GX04Jwg1p37pEnuZV-7b83sQpm959usEpuOPy7jtZymcFUChtndy1cbasgnkGhXQKMuuVnUX0FNd_-W1bMlDkTcHe9QEy0X0LHg3u7rTz_KPWg5wvDXpVCKB1EX_nAijeRXX6ysHW4RFetIaKOzjSmixgKJ03WisVf31pE8lujWFJ3ITO0FxIqeEu7dwTgQszqzlkXMtRQBAfsAjWRe4Jp0HnR8nQMVKfvlxo6TMWo7TQT-oTFi_ByAtZJBrdSGl2qcuT3L2yaME6-9WOCzMK3CEnQ8Jnw7NXdPiIWNW3Rgm4Bty1a-7EC-sAACniBE6nYREfZwbwlMuwPV2k3yP5FYJoBpiekkU9dxi1dFDTm1LM0XNDNiiqpgDFGamxS-SGUzFMh5wP0NTz3J_EZIdmHW8PrtU-6D7ZsTyQQQen9LhcwLZwGNGKIPj3xT32yfqvzaock8sV7SUqcbAsJpz82YW238idP1Ewg2Agcj5N3NibGaneWAEq3w4NIQgCUxJvAXCHb-CnpMPR5F6MlW4fzZVX2aSnQmud9WivdTXe4gTAg==","summary":[{"type":"summary_text","text":"**Refining update test harness and coverage**"},{"type":"summary_text","text":"**Configuring update check and session startup flow**"},{"type":"summary_text","text":"**Handling asynchronous update notices and command timing**"}]},{"id":"rs_0dbcc0ca250b92f5016a5892b653a8819aa0a6ba54af86910d","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJK_KjwWdJszmtH-q-o9HXO9DLbK8UnOhBwLqN29PVkSqVo7hJL1NsllCnyZq4VdrY3n9yPULaTNg2-2_u-8vAq9A7YdACn5CpkdwvqJf97OF0dfqxs2GX-F34LQGjYbcvJl77ijMRlX0osmthJG81E2LRRYpdxZoXfIZZFt6imDBhAddidwqnJo0UBF8jp2SSzPPCR_6zi0w8EZpnJCEpw8JKYd-9eCtTJp2fForqB5vT-0r9vx1TzFj6BFFS4eRZdAKoGJ0INfirKj0tHJq8hwOklAZDQqtbTDNZ480d4z1HIaFQ4HVTN4C9Xros1rXkotp58zgFoYi56RzzRDcPP4eqSCdWU8fyUQLPvfd1VlNurZ3gnPQnOnFNV-N10lyAOcBSHG0sR6ta9YRJqy9IB7hiiCidKDW52nNZp23322VpbKeGDaJeB66E5gh80se1K0o9aKjxTALDwUgKEDQ1Pf8y_16vKQV_fxC4icKxwgd0J5r0JLuiuDtPetnnR76yUDBzTOORE9poWO77iI71gphBo3EKdPSzuTf2GtnJv5fIJOTh3WX-f6_oy3LOs91Lw-3w5OjnoInuC10YKInCKaOFizoY74Odd0Uol7vWMuOZoNWI9ascygKQYNOactFYskdPfPeE4eqvZ3NR1xXigdy77-A6fdWZZiboF_nj50gr7qKpNUwVm_oxNYBdtfcYFT4iqDdmF6V6zoZkhgen5iWpDB9GIY3mUnt8OB9VjuR2BnnqWXMUSgkFCKGNFwRLcy5C2HOjlwqV-T2EAPPmka99VsiZodF-7A9mCG2Y1J6tj6A-FlemTnSfOcseJFYSu7xsbp1WIBfPVq9VxfcYTyrjqCOShNBr4xDcIkykAdqEaw7Q5BLYH4hgzPPXmfViAQCrT6k4c-Sd20VEbAsYRqYbtmzxRYnhlyJT1ygyVU0T7OySMx3OkDFw7R0m27MIpsC2By50ismFQid-rSCtJ5g30WJeImdpaYKa8oE95Z_94Xvz67cL3CfZzHVlO8Y1k4-R5XKXdGL3rEX05skMxuybKN7PrKsXrtDg_Cn5M4FJJX4VmblbeJZj-l8TciIlv3QQ6fQjPp5LxA3YqOZj4wmNI4ugBDHV2KuXUWyrZRVdw5RNSn8sSK2hCsXyoqYaVlz-LH3Tl_4QUCEIyBmzA1VDhhRSb5_A2nba_rhaoeQBCjRxOC5kzegJpDXGJDKS7SOanLDII2A-ICdShZoB_h99jQGJBrhQGcuwiyGgmPB1-sOROYTBmo1wDnFOm-IYrgnRRSyxyJUvEdrP7Oal6f2ATNQbyD41-efTBxkDRNthAivmbCyHGnm47kBB_f1akg35tIV5p7JpL7uz-7WTJt9cSWfov9I6CyN2I6omB64VCiTAZzyaNcVJVJZMycNDADbnYDrZj3lbWxqMPK8wbCGHETRQKwLy1DgEJIQuc05gHAxF7SbdBv2lLbwpaPPlIu1qz7WYKJ-KKzYThfuJgOLSmPZCqiz4ZDZXmolKxwB6mAQPOuDFJJcoVR45BplPxaRATtcY-EfErLa3XXpPlQ4zn82Ngd-6TusRME2Wuj9kEg6xM7owGTDXgMXMK9zaE2IrJtybvk9Mhv63NXigfSvVvP7T4nWhayCSnqojw1iHvIi2BMOiV1t1HuE5NVAAtA-w6SN5HAIuz93Fd8_Q9yF5bJwHBY58C2nfO7Wipp1fAsH82sqlzPtH1hzkSWhZeuL-zMurQM_NNZIBKDuTuaLJ8XpN5esLpjdwcEpz7nv_eO8wjz1e6N_Br1Jfv2Za5TG256QGOJoe7LwP74RjTKsB1-QOBtJmh1uOgu1NJBRuwzXWHtm-Qd6Dv6RBQw2g7tf3oN0jWow2CGgeFlSd6s113GR0NRrM27Y-AF0zhb1xvpcLfMIlmvkwo-Sh5qop6_ZaVCj3L3ag4WFCj8RCC1iwoLja9o3hoMJePZcRbr2UPZuVU7Y95dMe-dpsjkkYMN7GGTf2EhdMLnamJJzbhlnAN0WARSyPNalPizITTNQqSR3Xv7iKfa1rjp-hxz6XjpwHchvgQhyGQO59gfA-1py-HXvZXjDL_yN_iYNxkquYNySraI6OkcufE4hCf6mNVrvuyz0-HMqSFF3NoFNKPlP-5u4MS0fDDyWpfJhjyJLaLWa7S5Ei4MwACnXNO5e7CkZCPb5A3ycJjvhEyXIi90-5ebtc5HJgUnUBaPcDorGFg5xxNOxpGjBuUtHnsS_gdlttZqIqmNZIacF60Z47VOhWQVb1yqX6cPC2q7gJxIS-dIeSLCxQ-sVTcgNrt7mjLhF19Ao7ekHnaxfpivvL6TrzGj2M3ErrE-qnQB2UVeJrLFUfV3HJtMnxE6a4K2q7KkAv15M-d5eYRpIJ76k5B0whA7bAdAJU6N_2eyakbL7DeVbvU07heQJsOzlD8sHMAoaQqIWGFoh6U3W8USpYHr-AjB8Yeg8FTFPjFp0kvrTBviWFZ4CwEHrVN5Y2-c7gAz_hKpssCcJjChJCYSoSWKAs87_eJelL8wB67_qczprWrQwQxXel7-ucj7xqOv4p3wwaJBkRbuQozD9y0El-WPcx0yX3pnNr1hOPyFnaz-d7xzJJ4csKUJ50sSMi6hDConNgiSfKZedSQ1hQgKVOdOh6iY1G3zt8VPOjVdZGtfRJMvMm69fHZBWFwD3FQZnTc42_79XAVCyFz3irm-P_73L8s3zqS5o-Fe32CV4oow92nXaXQAy5OTwPn4eA8Qs6HXmeAeiTjRlbEg6K1Alu7acW5RHfXB6C6M4SL-v_6Y_fRZp1puSdoVrJIBetJtILfXjRb3rG3SSywnKt45yQIhvbtBwlvoxiWcCgDBhlAMkgmCyjUxXbvac1leoVtDKO9gFCFlzTM0uqftVXKrJXjBRLhIeOV-1xNQt-SyER1dWXXWwvbC9bOg1icy_ttkjadshovcoPY20bmJ8Gv8YmHqqx7EZViIDS3ozCh4pEthHtjde3dpcj2zkkDW_DnnSj1uZVjhLyK0ASiMytzXmA5a2lI3cPjs7C_DQCcYZkYNm7ek3BXhShBF_giywrSAx80-zOMM0y5GqTyJfiql2A0aqs3VOz6aMlYsOm5kJrQMtS2sDQlUvAz2Zcco1MD7EOazdN7noYkoL94EK3eFc-_UndKNd0Rdkhr0Z1FZ4PdxCvZ9cNQKAyZfmyoTKrLL0k3sI2OqrmpiEW5sJcKcAIUii8E2TCLIfdHIw97a_xBF1pxMXXTkqVpTrcacDe-v5YUGwfyk4yIpu8YSzYlJPYam4kWF-pqaLUpnCmSjAzJnTg2o9VRAgDecX3Vcx8Thd-hORSU7ygglSu_t7Piym65_sT5_SZO2gv-LKN8l8ykUWzzONqi-x5GE1uYDraXSM0MKxs46-dyFq_u2OWHAF1QR1-6OifrHNtoJwBokDn699Kf9LP0KJGssZ1iIZT7Pek6bsGqLOri6m-vwq_Z5L1qfnFw42oCxDysAC4ARkLbZw4-K_C3kMJ-4yjO4AELG-7smHhjMg1CRNrS_sPuzifk60w3oyIGxJBZzTz32W5mP_OBFPHndNXwnFtH6YrTzdRQXzvMKeCyo6GHgxU0ktfwYBfKrQ9FVuaKPQ3_bN4_pnVTsAAjrXXgQmqtcIY5uUQ7FfhXWRS9CGed5HGr6gb9HA_bLGwlhR_nMaiKYpkvr9hdoCORaX1XkT8CamKtatiAaETcEsgm709jRdYmbtWqIgmpQf_HVIHxDv0xt9r9uFpx_dtxZaNp84JoVo9dIkE7evCIkJ-i5UoRI7oYhT4V0xrkBetOMNjPulW1FqBZa7ZKsn2LFwzXgrMrfQkpEkA8220ffSMG2OJc5CjzMLYJVytgEJHXzWNx9rLDaSe0PUARBUOmPXYZdvbLhRY-iftE_12ZSuh8-wwuYPPzTaSnYmduXcNYybX30BDmma5PU4aQ3OQeJry-_6aoYpqAe99tpwH-GXf7uHS_R493EFbi1L-lWYqfT3ag_PsPetHW2a8xv_BhgWEI1rm178CGbw8nNqtZFDuRWoH0BnbF13Ax3HeC9ZdQnKhKlPUeOgVy62EQ03z6Z7qQS7hiXJYrdeWlD4THJGlA8VeVQrTnZeqN_pm2f6lpoiuaz8TaHVVM5tA2hyfNBd8U2PZQYxQxxN6PZQxSNRrfjF9CZAbxbf6Y89ABWajaYvH2-6kH6V6ue5uyHsnd5DOWdO0jhwDX9y476G2H4IfB0U6nl6TtalbExpnXNLLgqWVmHNY1-CT-Gd_ONQ_HYo-Em0tkOFZLDMPJ1eh2rgcu2EbuWYV3nuCQz-EbwQ79p_sMCqEDdXpFO4zk=","summary":[{"type":"summary_text","text":"**Modifying context handler for active item injection**"},{"type":"summary_text","text":"**Reviewing agent turn completion and dispatch logic**"},{"type":"summary_text","text":"**Confirming agent_end and session_stop order handling**"}]},{"id":"rs_0dbcc0ca250b92f5016a5892bfb078819a9a5212190d560393","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJLHPFx19j_dkPPlBetLb8BYGGOxv5Exk64kK14L9glBfVaQIfed5-jnefsJrMYYwZ68mGf4yAC3x6hhtS4MXcLfCKqRQlIQl04DLmiW-7ISR3F5XmQ1cGv5dc0G5RCMsiKZsEXZp2-fVUqiaWyDXEz9lS6Ddy-P_kIUBiS9lwv2m5pvPNeKv7drs9bpTGybrdSFugrtw_s6UVCnmLb0d_kjy6kL290mimmqTEDqSHIpc0DrGphO9Jesrjz8Ls6IGPwI0Euq0yKgHc0vNl0Y4Alx3iUrxLC3SQubF00vwXL8_bYCMept59uFZrpyZ9LEwWoeZLdJI702laGz2D-cj5Mr5tWxFPRBNdfd-4JFsgGSn-5zZhWSkLi4bXVIEXLxU522c_lrVcHuImlk2-0ACxuBun_zYStRVR--L7ywR8wGWvoVJJhsFcVh103IbhlBAdyPTpsGjDa6YVQH_gg_p2ghLuwFH9NVVHaFYjL8xiTGNAZOnlkRX5fKylLNanT0Y9k52JIBGhBbqya9fPeAufEjdeipDjhp8WyQ2S7mBxK5xI3Lng5jK7_7ddI398FB2FfVWHxBFP-hGhWX4-pTKcy09TGhzL0HVTCXD45-BbqzRaFADXirhYXbg4RbF2y3r2V2Scrp4V25UU1VIS-7KSDEpdL_adTDQGw3Z2HTCP4Rfeekm-XR3RwWQkfTyBVr4CkOJNHiqMLEBSxjy0qj0pvO8dMWqArypBdvMJZs5tzdNT687y-3JA7m6YTvrMdz3P4fRpd7u3ayp9ZnRV8zirXUOq64alxaLEosA0J1youE_KgwAjc1_g8sit95UNk9jtYhgOYRX6KbYVdz8KmwU8H2kxS0mZcr6SM2CBOEOLm9Ge0pXvehuzX-RjWSRyhSaJ5CsgexVOkhwgWn59fvF_-xWH30e82DwOLvb9_uScPfEIeZTMzYmgGsS7HluSsw-d0zjR6cwZE_J-thOpXr37kXViq1HQ5QylFroLHO0pvF_Li7cbdAJOEIAppvYXpVAq4nPN4VFR-xg-IyV01PjGh6M9-O6ZSMWeIaRpZCKWMqcFeLZ5UoZ1j9z9cNrk-lDrhKuZCNwbC3wTr80j2p3d6uudjF-_mIu4jegfZPbZb-dFHb_vIN-ge_rCWL4fH7j0OE1RPioLRBgCR9nyhDBUS4WmANx6v8jHwxgMvrwvNCRnqN8nDfJbX0ROS9XkfaqrhwD4HKK4qDmwxB2FPz4Ka-WMaXcZC27HF0FqjebQfWpmSQ1lQiHJyrXZ53NI2Eah0uuUalseTgM1hYlqSJdN9Esz1Y_k4Au5DQ-sA8KCU-9U_Yh2DtTk6LF6kViff6IYMHrdzmQ_peSD55sNeFDROV8hAdsUg0grMZwsLyRaoNeSnrEaMZjAHTgI5A9SMo-Gp-OT4pZ8_0XJrj7JOBTonKAydhCSqx1QeKFhshYYOpZ3mhXeTdPqsxaoDu5WQnABED0lZjX6MMlAQVrxrZrbXY2muh2zJhmhHDv9e_ty3XFkWZKpltKBwC_EmkqhRY5GREMs75kf8ZOJo77E_afHwjNo73ZKXQYVyEkf-_Ztqo6x7VfmOmZ-e9Lukxyreq3xv_OWReJESy29iJVl2XwGPL_LHUnYQIFlB-42pYgErE6RKg2Rk3N1S69bG5jKtlUOn-O_J51jb-S8qxaZj4M18HpiMfRobppb8dN5rEDCeEzmfBwLqOi_BgEQvMAivfm0k7Cx95h-dXQD5l23cy6URbdbEuT7R3MBuQbqeOiZ4DBEzYu1EVPMidzeVBD6ZypCxDvh0Wy7adJOFlmDDPf-HZKRsuJWScCjj9h4VnNyTXO655uGrUpXHzDrp38YcEl4lBtsTqdcWHLbANhEd8_H6WxCNRCfjJU1Qm-ey0h1XHukxOvx28t16OXe8u57dcUFcvhXWX084XlTSSMBKiqzJktJMa7EaZ9c_zPgsdfjeIhyZJSK-namG-PgMJfZrg7xdAII6OtLd5_Tfdo293qyIMEAcUNIaIl8v_tBgnLXgYuGtJ_pILMHepGH8FO10e7Z5gH0MzAGM1ehwExn8TFBXB5dF6m-iNSgYC7nKwUOvCvfePINBmU8i8Ziw5kD_-1lG8ODI0B7M4xR9wKOmGJLu4Lk6-YQStGxhf2tj06phH67u_a2YyCunk90a9Rwtc-XbA2XNNvKdL8HIcJstnR4RzoFYQqifO96ZfxpdMSYFmw3UjzrBnIf1ZcWq0HCF4UYMFe7xoOgijadORR5uzVFLjOgysi5TiwYioRYv9sYzjLZYG0w3K7UcwDymqUpV2LDD05u76g0cwXeEcxOlXGSHQRjib65Z84K0SB5mPyEv9UxoHSDyF7E9lMvVjTIAQnuWYR31BP5_5oZle3XWkGmWcTsff9OLyfgN4DNROCW4SKDRjiZPTZKbuboolsns67xP2zcfN-jzfVUv_xklReIUCkI759kxoMIM3Wt7jXFxB53IZCSXT52wAiJypUys342IjtYJNAn9GDtvZOFLYZHciLjhygBivl66-Zm3ZN8QQ0D0kFnadDJwSeUc026gcoJI-lmoJnjq7wgYieKEB_IN10V9EqYORx64Wuvx3zt2F3Ll6UjcIMQrSGlwRO3pxwITuBUP9QyrSFhxgjpjJ6yH31QO5kdO5atJSjJl-fWGVPrKMJJv2Nx7OXwf3uiNSLDE_bsCGKlXlBtYXahwPEdbG9l4SbNIXsUaVv5X3cfW4W2Yvixp14Z1efp0okcQcQiOIMwLGuEodiqLFtWiUQW1PUqxOyfPVN6VlRFKSfP9nX-SwegT9klJp42JIoXqfG5r5kHHVQPt51UzBY58xxN9ElNAuXcemsIvg2Y49Gc9TPpiWh9Y0f-OR2BegcW4jncl_nCzS9qBwdpDHrkbbmkWU5ios2sIhCxjuShIffUteA3b2TtN-LBZcZaaJRtz0Ue_IGh1L1VUmsrvS9902VP4BWFIOlZ95Ed16cVTgHsXfe21IVVlDMMDvtGHSmu4rZRjDAHNP7TxF1fGF3YsvxabQ-ePjTew584gFqwRCJNpCBkV2FPNBhJr803SPf8XpZpIQkxiyaKtpOV1v_ABdSnT8dMIVAiv_dM0nGE8emg_46STNrLL0Q-AWbEBBUxpSmTAhuSXdogs2PQ2HJbRiU1vZlsjMZ2miz921Ll9-J_qzrwgYQ-2xEKNU2HvmM6jqfRNfTnvooHD4HPnpiAMjbCTqKb3-5ASf8bsxq5kszY9KOyv50hkP-VHl42z5sJQcYm-L3j0qbl2Zd0CcbwDho8z0EYDhNbWMHkwcZGZu7szcfSuyiNDKBFtkOxGqKm5BPjWfd11YsSej05ZISHpPURp-VV4KgkkYZPVv8LXeAeltYJMxrF9WoOjpn2C74phg8q5X1ldxqkUR1DVcBVECdi8cIwiUdFkKfzqLS_AlX5Fn2S-c1a-tt04aghkb7q_EAzfwa7Dx6_iUKpTqw66GJ1-oDV2xk85x2OAqCyp6UjCqvqvGP2Ncjbcjw2yTMMb3TIS5n-2eUxQjhsxleMw_SiJCvz57qyBLHZxCE9W9qoH7Pi3DIdAJeDGy6PFs-9Urko9DPdWytaw69ryQdaHdanjU0eRw52pt7838psimzmeqNOW7aitdKwKsThnXEVt4PRrmJTrQc4R9Jltc8whiodlvRZXii_PeJ2_19Wkc6QGreAaBj0-Z-HnYiPjGaWvJoS1KUhfxADOPDGdiKF_PdZgetGRDS3JbpGdavbHkBVqiHA_6u-1HFK9sNKmJWVw10E4rtTGXyprSLzXqRt_fcmPT7DcxDe6nBMF37BRL0nl-kRo=","summary":[{"type":"summary_text","text":"**Refining event message injection and activation handling**"},{"type":"summary_text","text":"**Adjusting session switch blocking and traceable requirement roots**"}]},{"id":"fc_0dbcc0ca250b92f5016a5892c79304819a9e147284a026df89","type":"function_call","status":"completed","arguments":"{\"i\":\"Coordinating traceability activation\",\"op\":\"send\",\"to\":\"TruthGates\",\"message\":\"I’m adding impl/unit evidence for REQ-PARITY-READY-ACTIVATION, LIVE-ACTIVATION, LIVE-AUTO-RESUME, SAFE-BOUNDARY-DELIVERY, HAZARD-ABNORMAL-TURN-RECEIVABILITY, STARTUP-BRIEF, TARGETED-HINTS, UPDATE-NOTICE, PEER-SHORTFORM in omp-spt.mjs/tests. Are you editing traceable-reqs.toml roots/stages? Please activate these to doc+impl+unit and ensure docs/PARITY.md + ADR 0015/0017 are scanned; I’ll avoid the registry if you own it.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_33mqzHmMMfYFqUpXnmXV4Ept","name":"irc"}]},"duration":51516.79560000007,"ttft":2909.9097000000766,"contextSnapshot":{"promptTokens":151939,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_33mqzHmMMfYFqUpXnmXV4Ept|fc_0dbcc0ca250b92f5016a5892c79304819a9e147284a026df89","toolName":"irc","startedAt":"2026-07-16T08:14:02.621Z","intent":"Coordinating traceability activation"},"id":"4bc70b5a","parentId":"83149d0e","timestamp":"2026-07-16T08:14:02.621Z"}
{"type":"message","id":"1a9ca9ac","parentId":"4bc70b5a","timestamp":"2026-07-16T08:14:02.622Z","message":{"role":"toolResult","toolCallId":"call_33mqzHmMMfYFqUpXnmXV4Ept|fc_0dbcc0ca250b92f5016a5892c79304819a9e147284a026df89","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- TruthGates: injected"}],"details":{"op":"send","from":"NativeExtension","to":"TruthGates","receipts":[{"to":"TruthGates","outcome":"injected"}]},"isError":false,"timestamp":1784189642621}}
{"type":"message","id":"29bb0400","parentId":"1a9ca9ac","timestamp":"2026-07-16T08:14:09.503Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning careful test file modification**"},{"type":"toolCall","id":"call_OSYxOQvwAt0o11z02hV3BiEh|fc_0ff5009ddaa2b3d9016a5892d147ac8199b58ae9b5c920382a","name":"read","arguments":{"i":"Reading test harness continuation","path":"tests/omp-extension.mjs","selector":"90-220"}},{"type":"toolCall","id":"call_cnZgqf3zRcF6DZU0pfvPmJzM|fc_0ff5009ddaa2b3d9016a5892d147ec8199b5de7b12a68a3533","name":"read","arguments":{"i":"Reading test runner tail","path":"tests/omp-extension.mjs","selector":"1320-1385"}},{"type":"toolCall","id":"call_jlpnVBjS5rYbx2GoID1Te92s|fc_0ff5009ddaa2b3d9016a5892d147f481998e49fbc2fb16174d","name":"read","arguments":{"i":"Reading extension registration tail","path":"adapter/strings/omp-spt.mjs","selector":"1000-1160"}},{"type":"toolCall","id":"call_7CoRqkFhbTIEJRUgbrtYjXW8|fc_0ff5009ddaa2b3d9016a5892d147fc81998d36474843b24f51","name":"read","arguments":{"i":"Reading extension state region","path":"adapter/strings/omp-spt.mjs","selector":"376-470"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":3615,"output":230,"cacheRead":151040,"cacheWrite":0,"totalTokens":154885,"reasoningTokens":74,"cost":{"input":0.018075,"output":0.0069,"cacheRead":0.07551999999999999,"cacheWrite":0,"total":0.10049499999999999}},"stopReason":"toolUse","timestamp":1784189642637,"responseId":"resp_0ff5009ddaa2b3d9016a5892cb01c88199ad480698ace06848","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0ff5009ddaa2b3d9016a5892cd1e14819995087a6ba2e27f84","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJLRzwN6D60IwMzvd7MKtYLRxSKQ2QpPuwY3rMdXq63EPTRpm6amzTns9jOAWqqfwetoLsHct6HfsuanxtPXfQxOynRpUKesJNKSeP8bwJxw65Rm17ZV51lWPS16VJKKnxrifnralQYAmQeyyvbw8ZeDhCC2vG8Il4d6tBBShNLp-b3eYkDqYUWzPOz65JCYbleT1GHuC_HWzibNbu_Hlwa_nUIKualLFHxYeVTbXKYbvDQx06ishH_MH1wZklFXIWJeyrIze_zUzmqy72N_uuKdlwMYm8R4OD7MBdlZYp9qIijYfwxpPOM77CYn_OpBENIIL9T-AxMQpuocE8IYLcdpeLVlKt3bKeBt1DQM8t4BKVt-CO4qQgPxkuD-vEgEtD90pP1NdOcsqWBSZsvb-VDX5T81-VPjl50HpziyPHYnApatmPKxi_zFLCArSryH7fxc4r1eKkPIuojzCAMZZBR781q0iA0NQFQRJi5JyQCplfDetmCS6oLuawvJEF2_EEa5ha3jDpOqfiMFb5vovMwDeilWyLwqmg02Lvff1q2s2eF4pjm7kAp2VGWtxPvR1uGctgIG0ELaBhFN19_irWhX1LZIDulXnzNvLjGWE_kTCqpAZRmcrht9sA3PiU3OJmtm2y-b9WcQIOz8YIWLfwW2jfYOZDySapIKO9p7hyHlMGtVoQrunJjJEXd7rzjLkCetj9Cb3uAKjPcV5-1rvXbY8aJA75ciq4DrNzAllSkFR7Cjwv8AfK8kLPkUZEl9VW_UVFqCiHJOSH7iT2IPA1pdu1dMqJiHoSG2V8X9-WIVhsqY7AYf5QDFkU69zg19x7dEQMEOt0oVj-XQ_m4yMPK5bVO7gSUGgofLDeLzjo_ARwjHUgkKcVaJuJi3Zz_p6LM_gg_GjURXB6i3A1ZU_JYCp_S-WclQ9-CeLVGudeRHfcL5p7s23HLF3WaHSttZyG_7kccTmVLtbuiTcJxdicybIw0gAgrRbAxPP1BRfuFhrFMjbOMNagmeduXv3wAoQ6efV8-BUGlowab5YptIziQsxc_NNMHcR4fRHmq8Iabnoazm4qFuMW7XTp_dfxaUxFfoo5n6FoCCInhtA8IN4_YU27AilUGJRufCd1AQmi0v1RaLl0K76oQ3bqBkq8qG7rMdF8zTFMIb2d_YxSrIP1FK0Jb3lJVOemNAt1eJtK8MQCl57-O03ovDkAFGfiJQCPNlq8kaY0Nz4akNXTb8Uvgxz_MBmW8RK1nGuyrht-mxk6dwDJrYcyAClCsey7lYkpSw6A0xlWXArYKEiLMCAGs6gkRkosrZOqvcnyJjuj2lLwnc-mHP40QBNXZdlamC6JQ0Tf0VQ2N-vBOz-KSGnhbelnZtRRNyCsCB88mv1rYK5kjiFuhP-ZztjeUvxtRO9QVFU5_NIluxpRlgeew9DfQTpw==","summary":[{"type":"summary_text","text":"**Planning careful test file modification**"}]},{"id":"fc_0ff5009ddaa2b3d9016a5892d147ac8199b58ae9b5c920382a","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading test harness continuation\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"90-220\"}","call_id":"call_OSYxOQvwAt0o11z02hV3BiEh","name":"read"},{"id":"fc_0ff5009ddaa2b3d9016a5892d147ec8199b5de7b12a68a3533","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading test runner tail\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1320-1385\"}","call_id":"call_cnZgqf3zRcF6DZU0pfvPmJzM","name":"read"},{"id":"fc_0ff5009ddaa2b3d9016a5892d147f481998e49fbc2fb16174d","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension registration tail\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1000-1160\"}","call_id":"call_jlpnVBjS5rYbx2GoID1Te92s","name":"read"},{"id":"fc_0ff5009ddaa2b3d9016a5892d147fc81998d36474843b24f51","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension state region\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"376-470\"}","call_id":"call_7CoRqkFhbTIEJRUgbrtYjXW8","name":"read"}]},"duration":6865.867099999916,"ttft":2467.5402999999933,"contextSnapshot":{"promptTokens":154655,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_OSYxOQvwAt0o11z02hV3BiEh|fc_0ff5009ddaa2b3d9016a5892d147ac8199b58ae9b5c920382a","toolName":"read","startedAt":"2026-07-16T08:14:09.504Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading test harness continuation"},"id":"a8e2a021","parentId":"29bb0400","timestamp":"2026-07-16T08:14:09.504Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_cnZgqf3zRcF6DZU0pfvPmJzM|fc_0ff5009ddaa2b3d9016a5892d147ec8199b5de7b12a68a3533","toolName":"read","startedAt":"2026-07-16T08:14:09.504Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading test runner tail"},"id":"b51d88be","parentId":"a8e2a021","timestamp":"2026-07-16T08:14:09.504Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_jlpnVBjS5rYbx2GoID1Te92s|fc_0ff5009ddaa2b3d9016a5892d147f481998e49fbc2fb16174d","toolName":"read","startedAt":"2026-07-16T08:14:09.504Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading extension registration tail"},"id":"4b0965bb","parentId":"b51d88be","timestamp":"2026-07-16T08:14:09.504Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_7CoRqkFhbTIEJRUgbrtYjXW8|fc_0ff5009ddaa2b3d9016a5892d147fc81998d36474843b24f51","toolName":"read","startedAt":"2026-07-16T08:14:09.504Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading extension state region"},"id":"b45f26b9","parentId":"4b0965bb","timestamp":"2026-07-16T08:14:09.504Z"}
{"type":"message","id":"4bb37263","parentId":"b45f26b9","timestamp":"2026-07-16T08:14:09.518Z","message":{"role":"toolResult","toolCallId":"call_OSYxOQvwAt0o11z02hV3BiEh|fc_0ff5009ddaa2b3d9016a5892d147ac8199b58ae9b5c920382a","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#8FB4]\n63:class FakeClock {\n…\n83:\tasync runNext(expectedDelay) {\n…\n89:\t\ttimer.fn();\n90:\t\tawait flush();\n91:\t}\n92:}\n93:\n94:function createHarness(options = {}) {\n95:\tconst handlers = new Map();\n96:\tconst calls = [];\n97:\tconst children = [];\n98:\tconst submitted = [];\n99:\tconst statuses = [];\n100:\tconst notifications = [];\n101:\tconst errors = [];\n102:\tconst debug = [];\n103:\tconst clock = new FakeClock();\n104:\tlet shutdowns = 0;\n105:\n106:\tconst ui = {\n107:\t\tnotify(message, type) {\n108:\t\t\tnotifications.push({ message, type });\n109:\t\t},\n110:\t\tsetStatus(key, text) {\n111:\t\t\tstatuses.push({ key, text });\n112:\t\t},\n113:\t};\n114:\tconst ctx = {\n115:\t\tui,\n116:\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\n117:\t\tshutdown() {\n118:\t\t\tshutdowns += 1;\n119:\t\t},\n120:\t};\n121:\tconst pi = {\n122:\t\tlogger: {\n123:\t\t\terror(message, details) {\n124:\t\t\t\terrors.push({ message, details });\n125:\t\t\t},\n126:\t\t\tdebug(message, details) {\n127:\t\t\t\tdebug.push({ message, details });\n128:\t\t\t},\n129:\t\t},\n130:\t\ton(name, handler) {\n131:\t\t\tconst registered = handlers.get(name) ?? [];\n132:\t\t\tregistered.push(handler);\n133:\t\t\thandlers.set(name, registered);\n134:\t\t},\n135:\t\tsendUserMessage(content) {\n136:\t\t\tsubmitted.push(content);\n137:\t\t\toptions.onSubmit?.(content);\n138:\t\t},\n139:\t};\n140:\tconst runSptCommand = async (args, input) => {\n141:\t\tconst call = { args: [...args], input };\n142:\t\tcalls.push(call);\n143:\t\tconst overridden = await options.onRun?.(call);\n144:\t\tif (overridden !== undefined) return overridden;\n145:\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\n146:\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\n147:\t\t}\n148:\t\treturn \"\";\n149:\t};\n150:\tconst spawnProcess = (binary, args, spawnOptions) => {\n151:\t\tconst child = new FakeChild();\n152:\t\tchild.binary = binary;\n153:\t\tchild.args = [...args];\n154:\t\tchild.spawnOptions = spawnOptions;\n155:\t\toptions.onSpawn?.(child);\n156:\t\tchildren.push(child);\n157:\t\treturn child;\n158:\t};\n159:\tconst extension = createOmpSpt({\n160:\t\tenv: {\n161:\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\n162:\t\t\tOMP_SPT_SUBNET: options.subnet,\n163:\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\n164:\t\t},\n165:\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n166:\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n167:\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\n168:\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\n169:\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\n170:\t\tshutdownBudgetMs: options.shutdownBudgetMs,\n171:\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\n172:\t\tlistenerStableMs: options.listenerStableMs ?? false,\n173:\t\tkillForceMs: options.killForceMs ?? 4,\n174:\t\tkillGraceMs: options.killGraceMs ?? 3,\n175:\t\tlistenerBufferLimit: options.listenerBufferLimit,\n176:\t\trunSptCommand,\n177:\t\tspawnProcess,\n178:\t\tsetTimeout: clock.setTimeout.bind(clock),\n179:\t\tclearTimeout: clock.clearTimeout.bind(clock),\n180:\t});\n181:\textension(pi);\n182:\n183:\tasync function emit(name, event = {}) {\n184:\t\tlet result;\n185:\t\tfor (const handler of handlers.get(name) ?? []) {\n186:\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\n187:\t\t\tif (returned !== undefined) result = returned;\n188:\t\t}\n189:\t\treturn result;\n190:\t}\n191:\n192:\treturn {\n193:\t\tcalls,\n194:\t\tchildren,\n195:\t\tclock,\n196:\t\tctx,\n197:\t\tdebug,\n198:\t\temit,\n199:\t\terrors,\n200:\t\thandlers,\n201:\t\tnotifications,\n202:\t\tstatuses,\n203:\t\tsubmitted,\n204:\t\tget shutdowns() {\n205:\t\t\treturn shutdowns;\n206:\t\t},\n207:\t};\n208:}\n209:\n210:function commandCalls(harness, command) {\n211:\treturn harness.calls.filter((call) => call.args[0] === command);\n212:}\n213:\n214:function stateCalls(harness) {\n215:\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n216:}\n217:\n218:async function testParsingAndReplies() {\n219:\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\n220:\n221:\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\n222:\tconst partial = drainEvents(`noise${partialEnvelope}`);\n223:\tassert.deepEqual(partial.events, []);\n…\n278:}\n\n[Showing lines 89-223 of 1378. Use :224 to continue]"}],"details":{"truncation":{"content":"\t\ttimer.fn();\r\n\t\tawait flush();\r\n\t}\r\n}\r\n\r\nfunction createHarness(options = {}) {\r\n\tconst handlers = new Map();\r\n\tconst calls = [];\r\n\tconst children = [];\r\n\tconst submitted = [];\r\n\tconst statuses = [];\r\n\tconst notifications = [];\r\n\tconst errors = [];\r\n\tconst debug = [];\r\n\tconst clock = new FakeClock();\r\n\tlet shutdowns = 0;\r\n\r\n\tconst ui = {\r\n\t\tnotify(message, type) {\r\n\t\t\tnotifications.push({ message, type });\r\n\t\t},\r\n\t\tsetStatus(key, text) {\r\n\t\t\tstatuses.push({ key, text });\r\n\t\t},\r\n\t};\r\n\tconst ctx = {\r\n\t\tui,\r\n\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\r\n\t\tshutdown() {\r\n\t\t\tshutdowns += 1;\r\n\t\t},\r\n\t};\r\n\tconst pi = {\r\n\t\tlogger: {\r\n\t\t\terror(message, details) {\r\n\t\t\t\terrors.push({ message, details });\r\n\t\t\t},\r\n\t\t\tdebug(message, details) {\r\n\t\t\t\tdebug.push({ message, details });\r\n\t\t\t},\r\n\t\t},\r\n\t\ton(name, handler) {\r\n\t\t\tconst registered = handlers.get(name) ?? [];\r\n\t\t\tregistered.push(handler);\r\n\t\t\thandlers.set(name, registered);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r\n\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\r\n\r\n\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\r\n\tconst partial = drainEvents(`noise${partialEnvelope}`);\r\n\tassert.deepEqual(partial.events, []);\r","truncated":true,"truncatedBy":"lines","totalLines":1290,"totalBytes":3605,"outputLines":135,"outputBytes":3605,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"class FakeClock {\n…\n\tasync runNext(expectedDelay) {\n…\n\t\ttimer.fn();\r\n\t\tawait flush();\r\n\t}\r\n}\r\n\r\nfunction createHarness(options = {}) {\r\n\tconst handlers = new Map();\r\n\tconst calls = [];\r\n\tconst children = [];\r\n\tconst submitted = [];\r\n\tconst statuses = [];\r\n\tconst notifications = [];\r\n\tconst errors = [];\r\n\tconst debug = [];\r\n\tconst clock = new FakeClock();\r\n\tlet shutdowns = 0;\r\n\r\n\tconst ui = {\r\n\t\tnotify(message, type) {\r\n\t\t\tnotifications.push({ message, type });\r\n\t\t},\r\n\t\tsetStatus(key, text) {\r\n\t\t\tstatuses.push({ key, text });\r\n\t\t},\r\n\t};\r\n\tconst ctx = {\r\n\t\tui,\r\n\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\r\n\t\tshutdown() {\r\n\t\t\tshutdowns += 1;\r\n\t\t},\r\n\t};\r\n\tconst pi = {\r\n\t\tlogger: {\r\n\t\t\terror(message, details) {\r\n\t\t\t\terrors.push({ message, details });\r\n\t\t\t},\r\n\t\t\tdebug(message, details) {\r\n\t\t\t\tdebug.push({ message, details });\r\n\t\t\t},\r\n\t\t},\r\n\t\ton(name, handler) {\r\n\t\t\tconst registered = handlers.get(name) ?? [];\r\n\t\t\tregistered.push(handler);\r\n\t\t\thandlers.set(name, registered);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r\n\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\r\n\r\n\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\r\n\tconst partial = drainEvents(`noise${partialEnvelope}`);\r\n\tassert.deepEqual(partial.events, []);\r\n…\n}","startLine":63,"lineNumbers":[63,null,83,null,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,null,278]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1378,"totalBytes":3605,"outputLines":135,"outputBytes":3605,"shownRange":{"start":89,"end":223},"nextOffset":224}}},"isError":false,"timestamp":1784189649518}}
{"type":"message","id":"6507d850","parentId":"4bb37263","timestamp":"2026-07-16T08:14:09.546Z","message":{"role":"toolResult","toolCallId":"call_cnZgqf3zRcF6DZU0pfvPmJzM|fc_0ff5009ddaa2b3d9016a5892d147ec8199b5de7b12a68a3533","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#8FB4]\n1163:async function testShutdownFallbackStaysBelowHostCap() {\n…\n1319:\n1320:\tconst hardCapHarness = createHarness({\n1321:\t\tshutdownBudgetMs: 1_800,\n1322:\t\tshutdownCommandTimeoutMs: 5_000,\n1323:\t\tkillForceMs: 100,\n1324:\t\tkillGraceMs: 100,\n1325:\t\tonRun(call) {\n1326:\t\t\tif (call.args[0] === \"send\") return never;\n1327:\t\t},\n1328:\t});\n1329:\tawait hardCapHarness.emit(\"session_start\");\n1330:\tawait hardCapHarness.emit(\"agent_start\");\n1331:\thardCapHarness.children[0].stdout.emit(\n1332:\t\t\"data\",\n1333:\t\t'<EVENT type=\"msg\" from=\"hard-cap\">work</EVENT>',\n1334:\t);\n1335:\tawait flush();\n1336:\tconst hardCappedShutdown = hardCapHarness.emit(\"session_shutdown\");\n1337:\tawait flush();\n1338:\tassert.deepEqual(\n1339:\t\thardCapHarness.clock.delays().sort((a, b) => a - b),\n1340:\t\t[600, 1_800],\n1341:\t);\n1342:\tawait hardCapHarness.clock.runNext(600);\n1343:\tawait hardCappedShutdown;\n1344:\tassert.equal(\n1345:\t\thardCapHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\n1346:\t\t1,\n1347:\t\t\"the phase clamp must reserve time for one session-end attempt\",\n1348:\t);\n1349:\tassert.ok(\n1350:\t\t!hardCapHarness.errors.some(({ message }) =>\n1351:\t\t\tmessage.includes(\"bounded shutdown expired\"),\n1352:\t\t),\n1353:\t);\n1354:\tassert.equal(hardCapHarness.children[0].kills, 1);\n1355:\tassert.deepEqual(hardCapHarness.clock.delays(), []);\n1356:}\n1357:\n1358:await testParsingAndReplies();\n1359:await testRunSptRejectsStdinErrorsAndHungCommands();\n1360:await testLifecycleCustodyAndContext();\n1361:await testDeferredBindLifecycleSerialization();\n1362:await testOutcomeSendRetriesAndExhaustion();\n1363:await testSubmissionFailureAdvancesQueue();\n1364:await testFailedIdleRecoveryFailsClosed();\n1365:await testListenerRestartExhaustion();\n1366:await testListenerStableIntervalResetsRetries();\n1367:await testFatalTeardownAwaitsInFlightOutcome();\n1368:await testSessionEndRetriesAfterTransientFailure();\n1369:await testHumanBusyFailureFailsClosed();\n1370:await testShutdownReapsAndFailsQueuedCustody();\n1371:await testListenerTerminationEscalatesAndReaps();\n1372:await testProtocolCorruptionFailsClosed();\n1373:await testInboundQueueOverflowReturnsAcceptedCustody();\n1374:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n1375:await testShutdownFallbackStaysBelowHostCap();\n1376:\n1377:console.log(\"OMP-EXTENSION OK\");\n1378:"}],"details":{"displayContent":{"text":"async function testShutdownFallbackStaysBelowHostCap() {\n…\n\r\n\tconst hardCapHarness = createHarness({\r\n\t\tshutdownBudgetMs: 1_800,\r\n\t\tshutdownCommandTimeoutMs: 5_000,\r\n\t\tkillForceMs: 100,\r\n\t\tkillGraceMs: 100,\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\") return never;\r\n\t\t},\r\n\t});\r\n\tawait hardCapHarness.emit(\"session_start\");\r\n\tawait hardCapHarness.emit(\"agent_start\");\r\n\thardCapHarness.children[0].stdout.emit(\r\n\t\t\"data\",\r\n\t\t'<EVENT type=\"msg\" from=\"hard-cap\">work</EVENT>',\r\n\t);\r\n\tawait flush();\r\n\tconst hardCappedShutdown = hardCapHarness.emit(\"session_shutdown\");\r\n\tawait flush();\r\n\tassert.deepEqual(\r\n\t\thardCapHarness.clock.delays().sort((a, b) => a - b),\r\n\t\t[600, 1_800],\r\n\t);\r\n\tawait hardCapHarness.clock.runNext(600);\r\n\tawait hardCappedShutdown;\r\n\tassert.equal(\r\n\t\thardCapHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t1,\r\n\t\t\"the phase clamp must reserve time for one session-end attempt\",\r\n\t);\r\n\tassert.ok(\r\n\t\t!hardCapHarness.errors.some(({ message }) =>\r\n\t\t\tmessage.includes(\"bounded shutdown expired\"),\r\n\t\t),\r\n\t);\r\n\tassert.equal(hardCapHarness.children[0].kills, 1);\r\n\tassert.deepEqual(hardCapHarness.clock.delays(), []);\r\n}\r\n\r\nawait testParsingAndReplies();\r\nawait testRunSptRejectsStdinErrorsAndHungCommands();\r\nawait testLifecycleCustodyAndContext();\r\nawait testDeferredBindLifecycleSerialization();\r\nawait testOutcomeSendRetriesAndExhaustion();\r\nawait testSubmissionFailureAdvancesQueue();\r\nawait testFailedIdleRecoveryFailsClosed();\r\nawait testListenerRestartExhaustion();\r\nawait testListenerStableIntervalResetsRetries();\r\nawait testFatalTeardownAwaitsInFlightOutcome();\r\nawait testSessionEndRetriesAfterTransientFailure();\r\nawait testHumanBusyFailureFailsClosed();\r\nawait testShutdownReapsAndFailsQueuedCustody();\r\nawait testListenerTerminationEscalatesAndReaps();\r\nawait testProtocolCorruptionFailsClosed();\r\nawait testInboundQueueOverflowReturnsAcceptedCustody();\r\nawait testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\r\nawait testShutdownFallbackStaysBelowHostCap();\r\n\r\nconsole.log(\"OMP-EXTENSION OK\");\r\n","startLine":1163,"lineNumbers":[1163,null,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"}}},"isError":false,"timestamp":1784189649545}}
{"type":"message","id":"fd8458aa","parentId":"6507d850","timestamp":"2026-07-16T08:14:09.546Z","message":{"role":"toolResult","toolCallId":"call_7CoRqkFhbTIEJRUgbrtYjXW8|fc_0ff5009ddaa2b3d9016a5892d147fc81998d36474843b24f51","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#CA60]\n375:\n376:export function createOmpSpt(overrides = {}) {\n377:\tconst spawnProcess = overrides.spawnProcess ?? spawn;\n378:\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\n379:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n380:\tconst env = overrides.env ?? process.env;\n381:\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n382:\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n383:\tconst customRunSptCommand = overrides.runSptCommand;\n384:\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n385:\tconst runSptCommand =\n386:\t\tcustomRunSptCommand ??\n387:\t\t((args, input, options = {}) =>\n388:\t\t\trunSpt(args, input, {\n389:\t\t\t\tclearTimeout: clearTimer,\n390:\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\n391:\t\t\t\tenv,\n392:\t\t\t\tkillForceMs,\n393:\t\t\t\tkillGraceMs,\n394:\t\t\t\tsetTimeout: setTimer,\n395:\t\t\t\tsignal: options.signal,\n396:\t\t\t\tspawnProcess,\n397:\t\t\t}));\n398:\tconst shutdownBudgetMs =\n399:\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\n400:\tconst requestedShutdownCommandTimeoutMs =\n401:\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\n402:\tconst terminationWindowMs = killGraceMs + killForceMs;\n403:\tconst maxShutdownCommandTimeoutMs = Math.max(\n404:\t\t1,\n405:\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\n406:\t);\n407:\tconst shutdownCommandTimeoutMs = Math.max(\n408:\t\t1,\n409:\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\n410:\t);\n411:\tconst listenerBufferLimit =\n412:\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\n413:\tconst acceptedQueueLimit =\n414:\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\n415:\tconst acceptedBytesLimit =\n416:\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\n417:\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\n418:\tconst outcomeRetryDelaysMs = [\n419:\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\n420:\t];\n421:\tconst sessionEndRetryDelaysMs = [\n422:\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\n423:\t];\n424:\tconst listenerStableMs =\n425:\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\n426:\n427:\treturn function ompSpt(pi) {\n428:\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n429:\t\tif (!id) return;\n430:\n431:\t\tlet sid;\n432:\t\tlet token;\n433:\t\tlet listener;\n434:\t\tlet listenerBuffer = \"\";\n435:\t\tlet listenerRestartCount = 0;\n436:\t\tlet listenerStableTimer;\n437:\t\tlet restartTimer;\n438:\t\tlet dispatchTimer;\n439:\t\tlet bindPromise;\n440:\t\tlet agentActive = false;\n441:\t\tlet desiredState = \"idle\";\n442:\t\tlet dispatching = false;\n443:\t\tlet turnCompletionPromise;\n444:\t\tlet listenerTerminationPromise;\n445:\t\tlet shutdownMode = false;\n446:\t\tlet shutdownDeadlineExpired = false;\n447:\t\tconst activeCommands = new Map();\n448:\t\tconst retryWaiters = new Set();\n449:\t\tlet current;\n450:\t\tlet stopping = false;\n451:\t\tlet ui;\n452:\t\tlet runtimeCtx;\n453:\t\tlet endpointState;\n454:\t\tlet stateOperation = Promise.resolve();\n455:\t\tlet endPromise;\n456:\t\tlet fatalPromise;\n457:\t\tlet teardownPromise;\n458:\t\tlet acceptedBytes = 0;\n459:\t\tlet overflowItem;\n460:\t\tconst queue = [];\n461:\n462:\t\tconst logError = (message, error) => {\n463:\t\t\tpi.logger.error(message, { error: errorSummary(error) });\n464:\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\n465:\t\t};\n466:\n467:\t\tfunction runCommand(args, input, options = {}) {\n468:\t\t\tif (shutdownDeadlineExpired) {\n469:\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\n470:\t\t\t}\n471:\t\t\tconst timeoutMs =\n472:\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\n473:\t\t\tconst controller = new AbortController();\n…\n528:\t\t}\n…\n1154:\t};\n1155:}\n\n[Showing lines 375-473 of 1158. Use :474 to continue]"}],"details":{"truncation":{"content":"\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r\n\tconst shutdownBudgetMs =\r\n\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\r\n\tconst requestedShutdownCommandTimeoutMs =\r\n\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\r\n\tconst terminationWindowMs = killGraceMs + killForceMs;\r\n\tconst maxShutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\r\n\t);\r\n\tconst shutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\r\n\t);\r\n\tconst listenerBufferLimit =\r\n\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst acceptedQueueLimit =\r\n\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\r\n\tconst acceptedBytesLimit =\r\n\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\r\n\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\r\n\tconst outcomeRetryDelaysMs = [\r\n\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\r\n\t];\r\n\tconst sessionEndRetryDelaysMs = [\r\n\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\r\n\t];\r\n\tconst listenerStableMs =\r\n\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n\t\tlet listenerBuffer = \"\";\r\n\t\tlet listenerRestartCount = 0;\r\n\t\tlet listenerStableTimer;\r\n\t\tlet restartTimer;\r\n\t\tlet dispatchTimer;\r\n\t\tlet bindPromise;\r\n\t\tlet agentActive = false;\r\n\t\tlet desiredState = \"idle\";\r\n\t\tlet dispatching = false;\r\n\t\tlet turnCompletionPromise;\r\n\t\tlet listenerTerminationPromise;\r\n\t\tlet shutdownMode = false;\r\n\t\tlet shutdownDeadlineExpired = false;\r\n\t\tconst activeCommands = new Map();\r\n\t\tconst retryWaiters = new Set();\r\n\t\tlet current;\r\n\t\tlet stopping = false;\r\n\t\tlet ui;\r\n\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r","truncated":true,"truncatedBy":"lines","totalLines":784,"totalBytes":3465,"outputLines":99,"outputBytes":3465,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r\n\tconst shutdownBudgetMs =\r\n\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\r\n\tconst requestedShutdownCommandTimeoutMs =\r\n\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\r\n\tconst terminationWindowMs = killGraceMs + killForceMs;\r\n\tconst maxShutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\r\n\t);\r\n\tconst shutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\r\n\t);\r\n\tconst listenerBufferLimit =\r\n\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst acceptedQueueLimit =\r\n\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\r\n\tconst acceptedBytesLimit =\r\n\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\r\n\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\r\n\tconst outcomeRetryDelaysMs = [\r\n\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\r\n\t];\r\n\tconst sessionEndRetryDelaysMs = [\r\n\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\r\n\t];\r\n\tconst listenerStableMs =\r\n\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n\t\tlet listenerBuffer = \"\";\r\n\t\tlet listenerRestartCount = 0;\r\n\t\tlet listenerStableTimer;\r\n\t\tlet restartTimer;\r\n\t\tlet dispatchTimer;\r\n\t\tlet bindPromise;\r\n\t\tlet agentActive = false;\r\n\t\tlet desiredState = \"idle\";\r\n\t\tlet dispatching = false;\r\n\t\tlet turnCompletionPromise;\r\n\t\tlet listenerTerminationPromise;\r\n\t\tlet shutdownMode = false;\r\n\t\tlet shutdownDeadlineExpired = false;\r\n\t\tconst activeCommands = new Map();\r\n\t\tconst retryWaiters = new Set();\r\n\t\tlet current;\r\n\t\tlet stopping = false;\r\n\t\tlet ui;\r\n\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n…\n\t\t}\n…\n\t};\n}","startLine":375,"lineNumbers":[375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,null,528,null,1154,1155]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1158,"totalBytes":3465,"outputLines":99,"outputBytes":3465,"shownRange":{"start":375,"end":473},"nextOffset":474}}},"isError":false,"timestamp":1784189649545}}
{"type":"message","id":"d0f213be","parentId":"fd8458aa","timestamp":"2026-07-16T08:14:09.546Z","message":{"role":"toolResult","toolCallId":"call_jlpnVBjS5rYbx2GoID1Te92s|fc_0ff5009ddaa2b3d9016a5892d147f481998e49fbc2fb16174d","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#CA60]\n376:export function createOmpSpt(overrides = {}) {\n…\n427:\treturn function ompSpt(pi) {\n…\n928:\t\tfunction startListener() {\n…\n965:\t\t\tchild.stdout.on(\"data\", (chunk) => {\n…\n977:\t\t\t\twhile (!stopping) {\n…\n991:\t\t\t\t\tif (\n…\n994:\t\t\t\t\t) {\n…\n996:\t\t\t\t\t\tvoid failClosed(\n…\n998:\t\t\t\t\t\t\tnew Error(\n999:\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\n1000:\t\t\t\t\t\t\t),\n1001:\t\t\t\t\t\t);\n1002:\t\t\t\t\t\treturn;\n1003:\t\t\t\t\t}\n1004:\t\t\t\t\tevent.acceptedBytes = eventBytes;\n1005:\t\t\t\t\tevent.accounted = true;\n1006:\t\t\t\t\tacceptedBytes += eventBytes;\n1007:\t\t\t\t\tqueue.push(event);\n1008:\t\t\t\t}\n1009:\t\t\t\tif (!agentActive && !current && !dispatching) void dispatchNext();\n1010:\t\t\t});\n1011:\t\t\tchild.stderr.on(\"data\", (chunk) =>\n1012:\t\t\t\tpi.logger.debug(\"omp-spt listener\", { output: String(chunk).trim() }),\n1013:\t\t\t);\n1014:\t\t\tchild.on(\"error\", (error) => died(error, false));\n1015:\t\t\tchild.on(\"close\", (code, signal) => {\n1016:\t\t\t\tconst status = signal ? `signal ${signal}` : code;\n1017:\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\n1018:\t\t\t});\n1019:\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\n1020:\t\t}\n1021:\n1022:\t\t// [impl->REQ-OMP-NATIVE-TUI]\n1023:\t\tpi.on(\"session_start\", async (_event, ctx) => {\n1024:\t\t\truntimeCtx = ctx;\n1025:\t\t\tui = ctx.ui;\n1026:\t\t\tsid = ctx.sessionManager.getSessionId();\n1027:\t\t\tconst bindArgs = [\"api\", \"--adapter\", ADAPTER, \"bind\", id, \"--set-session-id\", sid];\n1028:\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n1029:\t\t\tbindPromise = (async () => {\n1030:\t\t\t\tconst bound = await runCommand(bindArgs);\n1031:\t\t\t\ttoken = bound.match(/\\btoken=([^\\s]+)/)?.[1];\n1032:\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n1033:\t\t\t})();\n1034:\t\t\ttry {\n1035:\t\t\t\tawait bindPromise;\n1036:\t\t\t} catch (error) {\n1037:\t\t\t\tif (stopping) return;\n1038:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1039:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1040:\t\t\t\treturn;\n1041:\t\t\t}\n1042:\t\t\tif (stopping) {\n1043:\t\t\t\ttry {\n1044:\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n1045:\t\t\t\t} catch (error) {\n1046:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n1047:\t\t\t\t}\n1048:\t\t\t\treturn;\n1049:\t\t\t}\n1050:\t\t\ttry {\n1051:\t\t\t\tawait syncDesiredState();\n1052:\t\t\t\tif (stopping) {\n1053:\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n1054:\t\t\t\t\treturn;\n1055:\t\t\t\t}\n1056:\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n1057:\t\t\t\tstartListener();\n1058:\t\t\t} catch (error) {\n1059:\t\t\t\tif (stopping) {\n1060:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n1061:\t\t\t\t\treturn;\n1062:\t\t\t\t}\n1063:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1064:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1065:\t\t\t}\n1066:\t\t});\n1067:\n1068:\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\n1069:\t\tconst blockSessionChange = (description, ctx) => {\n1070:\t\t\tctx.ui.notify(\n1071:\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n1072:\t\t\t\t\"warning\",\n1073:\t\t\t);\n1074:\t\t\treturn { cancel: true };\n1075:\t\t};\n1076:\n1077:\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n1078:\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\n1079:\t\t);\n1080:\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\n1081:\t\t\tblockSessionChange(\"session branch\", ctx),\n1082:\t\t);\n1083:\n1084:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n1085:\t\tpi.on(\"context\", (event) => {\n1086:\t\t\tif (!current?.submitted || current.settling) return;\n1087:\t\t\tconst messages = injectEnvelope(event.messages, current);\n1088:\t\t\tif (messages !== event.messages) return { messages };\n1089:\t\t});\n1090:\n1091:\t\tasync function completeTurn(event) {\n1092:\t\t\tagentActive = false;\n1093:\t\t\tdesiredState = \"idle\";\n1094:\t\t\tif (stopping) return;\n1095:\t\t\tconst completed = current;\n1096:\t\t\tif (completed?.submitted && !completed.settled) {\n1097:\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\n1098:\t\t\t\ttry {\n1099:\t\t\t\t\tawait settleItem(\n1100:\t\t\t\t\t\tcompleted,\n1101:\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n1102:\t\t\t\t\t);\n1103:\t\t\t\t} catch (error) {\n1104:\t\t\t\t\tif (stopping) return;\n1105:\t\t\t\t\tawait failClosed(\n1106:\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n1107:\t\t\t\t\t\terror,\n1108:\t\t\t\t\t);\n1109:\t\t\t\t\treturn;\n1110:\t\t\t\t}\n1111:\t\t\t}\n1112:\t\t\tif (current === completed) {\n1113:\t\t\t\tcurrent = undefined;\n1114:\t\t\t\treleaseItem(completed);\n1115:\t\t\t}\n1116:\t\t\ttry {\n1117:\t\t\t\tawait setState(\"idle\");\n1118:\t\t\t} catch (error) {\n1119:\t\t\t\tif (stopping) return;\n1120:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n1121:\t\t\t\treturn;\n1122:\t\t\t}\n1123:\t\t\tscheduleDispatch();\n1124:\t\t}\n1125:\n1126:\t\tpi.on(\"agent_start\", async () => {\n1127:\t\t\tif (stopping) return;\n1128:\t\t\tturnCompletionPromise = undefined;\n1129:\t\t\tagentActive = true;\n1130:\t\t\tdesiredState = \"busy\";\n1131:\t\t\ttry {\n1132:\t\t\t\tawait syncDesiredState();\n1133:\t\t\t} catch (error) {\n1134:\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\n1135:\t\t\t}\n1136:\t\t});\n1137:\n1138:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1139:\t\tpi.on(\"agent_end\", (event) => {\n1140:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1141:\t\t\treturn turnCompletionPromise;\n1142:\t\t});\n1143:\n1144:\t\tpi.on(\"session_stop\", async (event) => {\n1145:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1146:\t\t\tawait turnCompletionPromise;\n1147:\t\t});\n1148:\n1149:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n1150:\t\t\truntimeCtx ??= ctx;\n1151:\t\t\tui?.setStatus(\"omp-spt\", undefined);\n1152:\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\n1153:\t\t});\n1154:\t};\n1155:}\n1156:\n1157:export default createOmpSpt();\n1158:"}],"details":{"displayContent":{"text":"export function createOmpSpt(overrides = {}) {\n…\n\treturn function ompSpt(pi) {\n…\n\t\tfunction startListener() {\n…\n\t\t\tchild.stdout.on(\"data\", (chunk) => {\n…\n\t\t\t\twhile (!stopping) {\n…\n\t\t\t\t\tif (\n…\n\t\t\t\t\t) {\n…\n\t\t\t\t\t\tvoid failClosed(\n…\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\r\n\t\t\t\t\t\t\t),\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tevent.acceptedBytes = eventBytes;\r\n\t\t\t\t\tevent.accounted = true;\r\n\t\t\t\t\tacceptedBytes += eventBytes;\r\n\t\t\t\t\tqueue.push(event);\r\n\t\t\t\t}\r\n\t\t\t\tif (!agentActive && !current && !dispatching) void dispatchNext();\r\n\t\t\t});\r\n\t\t\tchild.stderr.on(\"data\", (chunk) =>\r\n\t\t\t\tpi.logger.debug(\"omp-spt listener\", { output: String(chunk).trim() }),\r\n\t\t\t);\r\n\t\t\tchild.on(\"error\", (error) => died(error, false));\r\n\t\t\tchild.on(\"close\", (code, signal) => {\r\n\t\t\t\tconst status = signal ? `signal ${signal}` : code;\r\n\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\r\n\t\t\t});\r\n\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-NATIVE-TUI]\r\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\r\n\t\t\truntimeCtx = ctx;\r\n\t\t\tui = ctx.ui;\r\n\t\t\tsid = ctx.sessionManager.getSessionId();\r\n\t\t\tconst bindArgs = [\"api\", \"--adapter\", ADAPTER, \"bind\", id, \"--set-session-id\", sid];\r\n\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\r\n\t\t\tbindPromise = (async () => {\r\n\t\t\t\tconst bound = await runCommand(bindArgs);\r\n\t\t\t\ttoken = bound.match(/\\btoken=([^\\s]+)/)?.[1];\r\n\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\r\n\t\t\t})();\r\n\t\t\ttry {\r\n\t\t\t\tawait bindPromise;\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (stopping) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t\tif (stopping) {\r\n\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t\t\tstartListener();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\r\n\t\tconst blockSessionChange = (description, ctx) => {\r\n\t\t\tctx.ui.notify(\r\n\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\r\n\t\t\t\t\"warning\",\r\n\t\t\t);\r\n\t\t\treturn { cancel: true };\r\n\t\t};\r\n\r\n\t\tpi.on(\"session_before_switch\", (event, ctx) =>\r\n\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tif (!current?.submitted || current.settling) return;\r\n\t\t\tconst messages = injectEnvelope(event.messages, current);\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\tawait turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\r\n\t\t\truntimeCtx ??= ctx;\r\n\t\t\tui?.setStatus(\"omp-spt\", undefined);\r\n\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\r\n\t\t});\r\n\t};\r\n}\r\n\r\nexport default createOmpSpt();\r\n","startLine":376,"lineNumbers":[376,null,427,null,928,null,965,null,977,null,991,null,994,null,996,null,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"}}},"isError":false,"timestamp":1784189649545}}
{"type":"message","id":"0367a2f6","parentId":"d0f213be","timestamp":"2026-07-16T08:15:10.550Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Designing helper function exports**\n\n**Implementing backtick masking and target parsing**"},{"type":"thinking","thinking":"**Refining update detection logic**\n\n**Designing endpoint candidate selection**\n\n**Implementing tie-breaking with UI select**"},{"type":"thinking","thinking":"**Designing activation reset and failure handling**\n\n**Refining activation flow and listener management**\n\n**Resolving activation failure redirection cycle**"},{"type":"thinking","thinking":"**Implementing helper edit for commands and probes**"},{"type":"toolCall","id":"call_BQOOe3g1UcV0GrHRT1SLKr7U|ctc_099c3ced01f42a35016a5892f2d04881989ec431cb2da8a068","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#CA60]\nINS.PRE 178:\n+function maskMarkdownCode(text) {\n+\tconst lines = String(text).split(/(\\r?\\n)/);\n+\tlet fenceCharacter;\n+\tlet fenceLength = 0;\n+\treturn lines\n+\t\t.map((line) => {\n+\t\t\tif (/^\\r?\\n$/.test(line)) return line;\n+\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+\t\t\tif (fence) {\n+\t\t\t\tconst character = fence[1][0];\n+\t\t\t\tif (!fenceCharacter) {\n+\t\t\t\t\tfenceCharacter = character;\n+\t\t\t\t\tfenceLength = fence[1].length;\n+\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+\t\t\t\t\tfenceCharacter = undefined;\n+\t\t\t\t\tfenceLength = 0;\n+\t\t\t\t}\n+\t\t\t\treturn \" \".repeat(line.length);\n+\t\t\t}\n+\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\n+\n+\t\t\tconst masked = [...line];\n+\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\n+\t\t\t\tif (line[cursor] !== \"`\") continue;\n+\t\t\t\tlet runLength = 1;\n+\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\n+\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\n+\t\t\t\tif (closing < 0) {\n+\t\t\t\t\tcursor += runLength - 1;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\n+\t\t\t\tcursor = closing + runLength - 1;\n+\t\t\t}\n+\t\t\treturn masked.join(\"\");\n+\t\t})\n+\t\t.join(\"\");\n+}\n+\n+// [impl->REQ-PARITY-PEER-SHORTFORM]\n+export function parsePeerShortforms(text) {\n+\tconst source = String(text ?? \"\");\n+\tconst prose = maskMarkdownCode(source);\n+\tconst shortforms = [];\n+\tconst pattern = /@<([\\s\\S]*?)@>/g;\n+\tfor (const match of prose.matchAll(pattern)) {\n+\t\tconst inner = match[1];\n+\t\tconst separator = inner.search(/\\s/);\n+\t\tif (separator <= 0) continue;\n+\t\tconst targetList = inner.slice(0, separator);\n+\t\tconst body = inner.slice(separator).trim();\n+\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\n+\t\tshortforms.push({\n+\t\t\ttargets: targetList.split(\",\"),\n+\t\t\tbody,\n+\t\t\tindex: match.index,\n+\t\t\traw: match[0],\n+\t\t});\n+\t}\n+\treturn shortforms;\n+}\n+\n+function parseJson(raw, label) {\n+\ttry {\n+\t\treturn JSON.parse(raw);\n+\t} catch (error) {\n+\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\n+\t}\n+}\n+\n+function parseVersion(raw) {\n+\tconst match = String(raw ?? \"\").match(/\\bv?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+][0-9A-Za-z.-]+)?\\b/);\n+\treturn match ? match.slice(1, 4).map(Number) : undefined;\n+}\n+\n+function compareVersions(left, right) {\n+\tfor (let index = 0; index < 3; index += 1) {\n+\t\tif (left[index] !== right[index]) return left[index] - right[index];\n+\t}\n+\treturn 0;\n+}\n+\n+function formatVersion(version) {\n+\treturn `v${version.join(\".\")}`;\n+}\n+\n+function promptHints(prompt) {\n+\tconst text = String(prompt ?? \"\").trim();\n+\tif (!text) return [];\n+\tconst hints = [];\n+\tif (\n+\t\t/(?:^|\\s)\\/live(?:\\s|$)/i.test(text) ||\n+\t\t/\\b(?:go|become|start|resume|activate)\\s+(?:an?\\s+)?live(?:\\s+agent)?\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Use extension-native `/live`; use `/live --auto` only for explicit auto-resume.\");\n+\t}\n+\tif (\n+\t\t/\\bwho am i\\b/i.test(text) ||\n+\t\t/\\b(?:show|check|what(?:'s| is))\\s+(?:my\\s+)?(?:spt\\s+)?(?:identity|endpoint|perch)\\b/i.test(\n+\t\t\ttext,\n+\t\t)\n+\t) {\n+\t\thints.push(\"Run `spt whoami --json` for this endpoint's identity.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:send|message|contact|tell|reply to)\\s+(?:an?\\s+|the\\s+)?(?:agent|peer|endpoint)\\b/i.test(\n+\t\t\ttext,\n+\t\t) ||\n+\t\t/\\bhow (?:do|can|should) (?:i|we) (?:send|message|contact)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to send` for canonical peer messaging.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n+\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to subnet` for private-network onboarding.\");\n+\t}\n+\tif (\n+\t\t/\\bcheckpoint\\b/i.test(text) ||\n+\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n+\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Read the packaged commune skill and use its checkpoint mode.\");\n+\t}\n+\treturn hints;\n+}\n+\n+function startupBrief(id) {\n+\treturn [\n+\t\t`OMP SPT endpoint \\`${id}\\` is active. Keep lifecycle infrastructure extension-owned.`,\n+\t\t\"- Identity/roster: `spt whoami --json`; `spt endpoint list`.\",\n+\t\t\"- Messaging: `spt how-to send` (or explicit assistant shortform `@<target message @>`).\",\n+\t\t\"- Continuity/lifecycle: use the packaged commune (checkpoint mode), signoff, and role skills.\",\n+\t\t\"- Activation/setup: `/ready`, `/live`, and the packaged setup skill.\",\n+\t\t\"- Subnets: `spt how-to subnet`.\",\n+\t\t\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\",\n+\t].join(\"\\n\");\n+}\n+\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":5667,"output":3230,"cacheRead":154112,"cacheWrite":0,"totalTokens":163009,"reasoningTokens":1679,"cost":{"input":0.028335000000000003,"output":0.0969,"cacheRead":0.077056,"cacheWrite":0,"total":0.202291}},"stopReason":"toolUse","timestamp":1784189649664,"responseId":"resp_099c3ced01f42a35016a5892d23fe081989f0c3ff9fe42cebc","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_099c3ced01f42a35016a5892d427248198ad5c36dd53ffeb1c","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJLdatxV1ojZymJ6Obc5yBjoVWlLKxWtdRwJ-pXbmjR3fGx6lG0LGlTJxmjYbI5oB6H9sFKiYQ4u5DFOzox80symuBsYepHuO3Mw3TgsxQVPa6rDQMBvFuMDvxb6hd0DCvKcxmmu1oUoSRF_aNCpkUoiRtzzD_i9PDRk7lPvtJ1SD7LF3LQ7Z0bPyHr13l5YankwKPJpL1-eEjs0mayyJKIsRI9ZRSOejJh9CFhCFFRiujEAp0ZjMVavJAij-iiUvc2RSXetTVSXey_oYYz-lpxaxnaWx1Wwys_XDu1U6-S2UUiwwFgSUkb-2bIWKFe1dtxNTzxzC9COhxTqNTGddYqoTA7tYNldlGYUnYhijJqVZjKDMWAxkMSp2JBX14YsscvXZHW-rVexgn1FzjaBj2auHmRNspYY-A18vS_p7aFiX-6d0AQealjiDZ_WSf_5TyfL3GotBa4ygGizRbOYzdQSyiYOiUodoOLGRUkMje1TOKGSsmv_WvXIyH5CCHNaabNTszsW-6LXKWON7KgTTfkhIiUekduTnlA2ED6MTxPvRB6EhkDITfHbRUNgk0DKy0Gf9eOos0FdY8FdgxGbymOXmCYLheSlWpb3Ra1fWuzh36TU4W2x8U4VeZr2QhOxZLVlEjHDUEqtSiiC4qbckQdV3jScBnotmGgpGlS-SC1O_sGDntZtBqJJBNd4Ajs02hXsEaSXjIF8BVjbdoGJRKaG6uq5uBwv51BAleXJ8XJZKYudJH_TmGcRFMViyb9GgdYDNKc7jTsNsF7328MmMlbQ998cXxptcJISkeX4ImR-9_WiYx0WKRMRnU3DbOP7AEF1M4AtGQo9osdY_T4YgHlxRwOECMtqAX7DPl_Nx5awQz-2BKK3kvSi0HmcHjbaftbic3U-614cwV9HWxvetCCI3MFoN5K6T2BG2d5zpH4Mxlujk7CBCYDv1zSJtRz70-2J0Y1XsmWzJH0qlOadjAkq3HjbfKVBk-ob6x-2piE_Rl9o_5ykVeqaILD0acSVjZWW3PQycZtQm9GZod7nVSqWE1WyqZOGS3nQThs6kKO5Gds-SMmnaGcuWl6uSGZ1GCv2ZYzVyMw65wEZL9gC2NU8hlNzgeZXULZDMp7NPqHYNSps5iXPIgvhUnsKNsppmEz56SqqBxhzdn50IxyUXIfs9DzKSy350RMW5Gq8FTh-UWD42D2W75TBw88XucfpPXIT0xZW8JiIIB8JLyvv9lNoDDPSx0i2Alk7p4_PwG79xch0pBUOzP3VxE53nvOaiNcbT2RvyTdEafbKEo2hFd5xhGNmqScwCIDnvhQGNYeVRZ7DzCaqjri-aAHvZaVdrGpnKgBeknn0Z2malu4XoUHPdrZZtmzJmKoEtdyShebdnM2KzBXs6jlgufqQrgM7-w5NMmHYwOOgYZKzuVOZxluNefPQ7A3lsFLZDMWhXD_h4UIQGHi8vr8cnpw3YiP6nqnV3folJcIbRQcd-Q0-WLyV96hCaiVPDkvsnCLv4du_1j2p_6akYLnoqPihN3i3SzTyVqYhh1CGwAK__DZBL0gvQ2loKfGpsP4BS4vldNZN1QQzyhPDBJkGT_CQT5scqXU-qoONqBMlHU09NfhnQp-7n49UjnruLT4ZhlFeJoBsSKVXu5axRQ53D4_unF5R1Fe8UuuR98WfgmQ8cvzyeR_l0TUNplpDANsaE-_-F6m8esbyK5WXdTq2ff5saXuld9e4uaeUqTg1OA__K2dJQ2Rygy5JH9jBYrcuagw-Wpg9jR20aD4vhU4BfT9cAmF_6GjgqLaqJLShwggVfqK3m8_7w57W5Yw7xNd1Rjs1NHr4h4_V0v7Fd5cc_zkJsQJ-J3o7hiNhNzkrwzjT1UIBTOAtbKDyTWQrCoJQ2Bt0FLDTWe_bFiDycv3JH22jzIUFePFupK12H-cvLoaE1rAdSec4_8rqFpW7dA4eXhELwaNU6LMIq7akk9PdU837Y6CQK_heAu0wrZ3uo4hXGxp-MG-IJkvB8Rmb9VPx5JWY_VdC2BZNDSxNZpGtS0LxYwmUSD7Vjyas6g_ZhfdO0Ohrw0UiriYPZtEWrnp9Ln2_HQzRY9HSX4LSVlc2p6dtKkuecj1qwqB65jhpy8w4KdDl0rZH-gUnurpu0zwJQ5IrgzcjuznNVSfnSNdk8uxxlX0t9RSFJ8_rhx5KhPEusvuYH5kHpU33UKDTdrfA5niN_ZiyR6gQpRp8Hp97Gtd4Z4I9pghy5iUCpimeDLyaMfll44aOTw5q8AsGlhXwKR5rLw0nT1KaRacRh0QMRuUm-Q-26-TAYV7lGe6PIJqZjRN8WqbIC0HKVfcu3EUvZgeU9sgItiOzLpaB3Zub3GA67OjC3zuPDZF4v66X75KFMruuvKPIGKO9hlPsRu9FhPpjdTMU2LkTZCiYgyiAX90Xsm_vUbG_58zPSUvtwO5Dkc0aA92yPB0hwISVDHmdVI4BBI7LPqKxcahOKw9ouoqhy9VUNcpPaG49oxqO8uQUsMRK5ivGdfbfKjl6obBeFEW29ytVMQSIvONRjPg2EWpbDXkVbszhzsqPGW-Em-D2wqkz1VJDeo3giYIfTtooUWbvv_YROjtU_tT9Mjwf-8VRCljkFc7PiTWXyH0HNfMIdZm9I-t1pugnWDWYtlk3AtTGLHrFUuhTX9VCq11q3Svr4Ez8C-zHFcFAV0THGMsHg37fVIpfl9MEkjuXIbv3ch1-SzB77JxyqICMZHKu1-5m0EJ4ZuBmKNDKYrVE17B2LK2CbcGgp9ieijSsNpyREhOQ5LlRys6wECeWAzzC2C0CVTBIcWaFdgbKclo7f12ADIfbdzx57uuIgiS7E-lg1G8R-9Xc3hiEBgaNXlcu2uVPNQ5n9Y4GSOA9e1h4OtPGigG73EUqg5xsPjlMcpdHT7OYqG8Xfp0ZuA0K0-FDDnMqWZ3j1PO4FzSyHV8gpg9AQ5mqSqBK1XHL0DR_NxSoWGZcY3ZChFfktsUCWxscN75oa4dpEuIMZ5BC9w-RQBw0zvME3M_AJei4hwr5E3DL16-hyOhZZIwuTIzg0_GhvYrQxgzQdD_mZYjIb8ioF6ONJyM37AFa3uruweIxQR77CdVMxPjPVczSf5AoxuA668-oxgYZYHp9Yk_k4gL63Mcv4EwMjXOh5bsI_Axk6sN5y9E9ES2NnN1z0ZT8vQJVUe-bV9A1hrhOYCtJCQ6B4LksTkJaUVn0i3bofH4XO1hHlolCdb53r7uMt9fiwvDmwkqZn8W39h9zMJ5CFtFTVLpPIOdhRfx34SSw2MZVoBKBEDyC_pqubJ3mENUlnvf7Ownl0ewRVm1wNvp79P5yGfG7YqVT20zs_BuXxYrSN0_2MDJfVkbxosEcVsVOSn_Pk5QtkwPujW-cK00VTmc-66AJ7_EGeNQ3G8-LjVhy02PuIeDWaB5LOtqdlRZr-1zTQpH2A1Z4MJV1PAPMNQNu_RYrqUE1fUywKbVF2IXLXpGjGdeliTlZEZbycZlDpyWzAFwj75zo_7ClHhlc6YeB1RubeheG_SBuOVbQZ0Qo24_kHKIDar-NNSUpEZ1aOQOpAs7-DfWwC-9LEI4BDf3QnZXgmpt3UROTAl4QTFcw7mwIZ5HKHq6VtVIt2A4k6hKI4vZwrcVgv19MHw8Bq9L2hfGcAPr1oWVjryMAI2z0aXmavcCwT1PmBE0342bYxI46eN13tC4q5neH8g7CjDyXVPKZYn1Y2g3OTB4p0UazpX9E7rEM6herEBeZiAxacVInhy7Ofw77qoDLjJ2K9RvT5-zm_ue8D6A6FsdwqeUCUuEenF9dK9vCaU5z8LGpqigxe-Ppm8d-Gh5zxVstFahscB19q2C1hGQzQIDELdZOPzwUud07YUeRvBcwFe9j9RbX96UhHpxV-rxEEeu4s65qHFZqm44O1YOiI8447BEmVdjwc0vKwd7MLdh--uIyeexXb7kzcu15YZKyWb6sJfi5pzjYQ0Nx-X98QogxahEGSX_Hlhw8VwT20-IVr7KLg6LqjfjTwQwscAwqKR3BG1kaMkZH3b95FshqEiTDuyO921J8zAAfaDHQs7E=","summary":[{"type":"summary_text","text":"**Designing helper function exports**"},{"type":"summary_text","text":"**Implementing backtick masking and target parsing**"}]},{"id":"rs_099c3ced01f42a35016a5892dd7db481988b1c40615473c443","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJLn8EBYuvYBysYj-aoyLT5TDTCbUZuBvunHTarVIW5ps5kybHXnFYamIaMxLbVX3dV-w7isy03RhWkMJLb7H_Z9mRfllL9oDzo2ACflegz0kh584tMK2f53l18Jec8DHOd9wconwLh491Ya-1GrTHxoDlhYPuye6UQVXzEhuq1Lu8EkCbtAd0r713Azbm_aePK36q_09PgWpFHq4Up1QNYesClBG6_-bHkTaMm1qcs8U_5yTYZLtZvx39bxtYvZwyHRoOWBgAGw2gtLWBGanWMT0duGsV_gtJUE1R_Xa447rH__e5kYdhxSVY3cxF6ympLYm_o9Ggla5AmICr6f6DAJT2MpsXzkwxRnFDe3_ZOiBNX6EOAboxO_1sKvXjVBvpXFUmZ3dXvnXoPZjbrnncNVxU0AT45EQjsRRV7pN2Zr4NzJEdcaEVfMLETFpv4OApQiKMKnhepOaKT3jJM-1kcUadei35s1hUbfrraujBXfHlVmkqToMCBcVcTcAtcAZELvIced__dSlTiylpS6qegenK_HqwjSekfXw5W_CzjnYrv2ZyZ0xYAQ2YG1ngkY1SbE_TAOCHeUpEyuuyCDF8WTRkBAY1OJwe2DQbjXljbLygHWnbSH49a2LO0KaHfJAecG6-YUf5az2QnrhQ9UZbUzSKNQlwZlP-W4d2qlgF5n_VBSh7KOODnCKnkQ0IbXoO0qYO1IDa8bDonzXt_fB-bXJg62FB0ddUQv15JICE1R7bVeF73p-2Wj8Sv0-uLuSawNhmVNqamrAKutaaHsfXJNs2ddm5zh2x7m0oy88UH5S-VjjqLmp20BRHMdN2h-NVI5XgQM72GcFi0ljxdzWiEqBWUCAM3jvac4TSkbr8uOjBJ_pPE1gz5vn_oRsMVGnQbzZydgoIZU3fyb-KTcNAagZK7pyZR-A6YFEtOgHdEZAYwXX12RHVgiGeOqyYCr30_PyQYtpD-ujcMnrC4RIMIgWb27bRXOr_JR7jJktir6QhCe1ftVOUhKMUJNzht10WH77Uvg6bjXVAtrrIGELaofCYecI0_-uhT0PBOxM2NdNl4ySVaw60_HmyWgT9o92SFQJghmhxYMqhZ-XC9l7QupkHvafbvole7XXQaEgANujKrALbw4O9GtCmIBBJ-BubeRenud868bMCv-3H1xiMMM508RgbtLHgyyBjYY3AWCu8VN2whvEK-6134dDtogD5uVZnXzXTKXtTDbYrY_Fa4zw0TYcguQUq_uJYWwKA3gu_74TfTfBkV3RWcjYr80NocjIYep5XEXTqRQeYPWA4g13EvOuspQ4t4ngEQGgbUAyXwPAYGT_v9_mI1j2a4t32fgtlCxxNfq4G-Laz-sWHrWTrhHwLzUiN4td0nXY0pBjOV0va15DfIR51qPwkxacZ63gGb_RgIRITQqHH3PMtVNgLmz1P77HxnL1Nb3a13tnT40LxVyyrSMiQBijxdoRXE6gvswb61ENKW6DrmEXfno_C-FOaBo3F11zf5XAPp6ma3ojARNnREBEpjJ3c9fBdlGhnw1yYfrs3672Hcs_j1kHFnTqWKNtHTllOEZK0gV3pXtFLPrUTkNAJe_BSD97sN8KZQmnOgl4RlhcO7fw6aQqZFY32CBE3Nm8afIuUYFYybYk8RE-rNh9A4vjtiMOimG9eap2rCDZ7ABQbWXNqbwh56vB4VY5fN2pPi_ovGqrEPqwTW6bN8SNIZu782VSLIRdpNGJ6RXrFf5AdpjkWex5-xGs1HGva4dazZjDzLHJ4m0-IUfcF5X4HwMenotS3T9a9knMLc010KcXJqMKSBZS0gx5tQt5mt8c0vBLYcvmXoC6G-xEbY7qnQGrWX-tI-Ddu6LUGAjdI7UeSjLwAl6wmEwlLCHqQ7vAwUdAapFnPcEoNFTX0kzMIcgUGn--f8LM2C71ibr-cBvBoOaIQIe3PG4PnXciPOMoPwgivoMk4mxBG1WdIPsCYSyLPHJcz3_myP3aXKhE93lhk_qoa_7il_1DsdOgDAvQRljEa3-22_SRrW84GuGTootlCXNrzXqBSyp6_Ag8OEJ7C768ImatHHcyYkZ8OqgwTm-kI6dADa6bRHHQXhUnSt4ZTxSAJWOSTA6m7zziXfsOvsbApFXSfVmPmScjqMDX4WOKH6oIjMmAXtlKw1jdS2rxUm6jV1GFk6BpkxaqjN9RmX7c_KgMazL5WNh1AUUmWxxcjHNu3hkRxU7b-yUyRIQWAjJCm5jSKh-NnqZi5FA3uYlDCc8mZqYESgRsG1x0_66Pb8liUFxiQWYL5fNB6HL9ubIXcyW6mmuQe-YwR8FK_wNK-E8uIc0PeWEGcnBszsNAeQbcF7S8Dls9xDg-G1651D54p_svM-6lfWl0ZXt1-_OHr9Hj8DqfejfQKgmyuWgwcplwp5S9v5ayX8KHSJ59kNTajNISOmKTGU3u9TULozwUTkIJ-YQILSGOHEaH4KAjw6Kc4PAX-WNgmcTMHU2E4PGBXV1r0dLN1Lm_nKUwm_28PqrcFwL1edk_mTd3wHBmEa0HcIjamEjXfHPqMIN8xMYE6gWNQ0bIbjvmvE783hDS_YEYd7CBORgIYt2aeM-YNeOCiuak2Qe9ixMBoYO2kefSsqoCS8BskOc_07Rxvwcqe9y4zUEqUDjIl0uTAM1QuVXEhDFpWYGCQrA4h-2hOYikSfpodhZgrjturAZkj_g3RtvUQZLYuQiL0H8PwIfRzrnbt0e6yCAbNGzm8lZWva9KtK2Y9XExo6hF1ATOFLVKhFY2iPGhI4MIuuXwRI5GbMiJHIokpTKWnDJsBj42lEEqWtX_pYV22QG7AAympkwKy1t2u9ueQLu2XfMB5oL03mgY9o1mMRkTlxj-LjIU4q5uxlMK6cBL8heAyoVHegcDDpOo_pzz2jKxzlR8xkTNZxmhymFjPBQ2U-c-OdzmTVYsLsz3muV7qX_bzER71pDB8e2UQPGqhUIlULFashyq_OdYyGaDJq-IOyBRnXEFclp9vTlUkko_ZclfPosrW1ieizTpB4rMvuAi430238Yl1wVNYU5PlPDPUZsOO48w4mZPunZpwggFP994BcT0WdLpNJ-ubg7TvN2thbw17O6Y03fZIaoD0teOmBO7w_NM_eO14hELbcZ4mb_SKy0V0KH5WnWXj_G-xyn9WZpWT2bvxor9wnv7YLASChlI3BsZMXX9U_ZCd8elPh7IjvPWCAzKERs-C3SIJR2NLE5CHtlEZpW1R047o0brZam60aBLqWRaTI0BwnGH8C8RD48_XT1jKJmnkxbOwYCuJMzm1sjZXxVrGYEEGIaOhXtpr1kfj1NFdscFuPJpZCoKa-xG24k5eNwgGGnCImhYtJrz6SNwCi8PzHMFLi3H5Nhx_zhBSP_raSIcm54Tv9e_TJX7pNg3lsgRW0dRa_EqHcXNqf5Xv3oH3A76N8FkDpCBQ6AjS52Mp2oNKZ4lcs6nmGYzFlCeINah05P7Pxv9b51BiOzjQwu4Z5kalemjCxnu-hjVMcfAO7NtNDIRWOtNRF_hXWQ1g0uBnK9WyjrDHgHXNjTMh9nJ4xAEqTiS-JJpGK80-qU2AJ4emSok0bh6uIH41YHPNbWGm3ty-NPu6LL4rktcXWv0xIp_RPP1Etb5TU7sIb1sTwyMTrW1c_sa3-vswZI0bORRRADAmzA6duqODu2BGd_xC85xx54XVGs5bO-T5_qblSbyNY65nwaLLuMvkH94ho9W-h1FMNbc4IPJua-pCWVn5mCU7jdjE9GFoS1YPmoYvsCBPb78X5FNWLtjesp9fOI1qyfRhDrTSqlXPo0Ia8PAWGcHoyvDU3liSSJZ8LnpRv6sLBrfD8rPLUHJA84fDGd0Wm5Gd60mJ9T1Zn4JHzc83VrVlAdf2R689yGq0g_0AHWqLGOn19h8uMtIfsSBJHwW4v5dOdl8P4ui6_I5oGzH88ukNqLrKZi8bnZrshzHuphYew5G9WWmsJx6vQhq8JerMuVtJh-aBeYEBFt2z3S9wq_aHexR2IAe_WQNbuJLu6S5SODVKKcw5mZ-ULAR-wG1n5ImIlMNUbDb-CjSBn5FdiYKDPiJvrc-V80CapsXr3ca7EVYk3BWGkJLP4YWhOv-GUtU_9UqQdJIbvKAVXucDVjm_-ItD66P2X-j2N1a83p","summary":[{"type":"summary_text","text":"**Refining update detection logic**"},{"type":"summary_text","text":"**Designing endpoint candidate selection**"},{"type":"summary_text","text":"**Implementing tie-breaking with UI select**"}]},{"id":"rs_099c3ced01f42a35016a5892e720308198b65e7501feae8680","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJLwU4_PlMqwAc8eMKjxsKmkj-J6ayHSzTsoqoCVLzFfTVdT3K0bVdpkRFZ5KHYZzBYNVpW3WtZo7ikyR40umH-Am05XPn1yWzF0Raqj59fqZ_gn9gjCN6kOagsEtNpZ3nWjoiJq2ofOMBXxHVIPIvnsK51ALQmPODrCL7oueKtZVS_1rWWXZOytZv5VlphuVaKPI0Skd9XDoRN8irwTWeOZfuQEyv2pvqO_kMIERO3tM1rS4W1eoH37kpZO-gUjd5C0RdV7XMFCAFLCHlvWcHTndatFA-UuC40digtcOyIgVePmvGiPtpyDs2PnoadhdAev_LP5qdpuKx8861I3TKoYwoTQaYpC5ACX7g5PgX1shhJe3V7aPdo-GxKGiTKnOpHN0gX1Ag6ee06iUNfzUSZDf4ebnpOL6g-hcEXrAVVVxUlhS0LNzTrmuXfMyZNOziKAP-ChCUHf53m29hScxoDqKUReUxifX73Xs3rTtcOcSS6LVDjM9yN0dY8AsSV8TV6IQlRjRK11um0xbLZ5E8GKOw7UhFf1aYKWRMTSjju-rj7-hionxgfoWcl0WkpJiCvZE1PrjkI9ynkjeVbKj4pUV790DoQD79kthf8og1g77Ns8CFuWwVo1gFT3rJ6hA2Q6g6FcHL-5ZtMb-632RIdCXdEk5-4Q-5CUkrH9PLLfkhyz4lEQ7o1kwqlNBiRU0YclZVSA1d626jfssBzGZVRXNU2ky8nd_alm-5Hwr01mptJs_O1Ny1sJQWQXtiiGQltq8UHI_f3D5VbA2SGfgyRId3JeUqtePnQWu9SV4gQm2tr4u8DFQ7ecTj1eKDs8RwMYO0BfYblxDN8iXoakmKuEiz93vzAoVyoxK4nlVsr34MKTUE631lLY3hhUbKPIfwBx6f-AmGspGtCwyJXK-h6OJwxAPchjZHp0MFgEyZtddTtvfS1BJNztYpPPXI-vG_-DfKRxvJ9fSqyEgRVfhRudaozHFjiOzbqXu3zGUXXM1u5RjKA6hb2uSP-QvMEQG7T0_GSvoG1kiV8nZl7gwO1ZyCXVRNw17KQLnJSZp8utVqwa4gx8oZ7HdQ63pYYe8aHvlrTYDx1uJ9kNuXSVm00Y89W5rYPeTFPp_F3JL80FmIB5IcjgqMRbfJ1hg4g0UMOGWtvPAAMmJgPKWdDhtmWzX7qAhaYzGTm759BjdecrdxI_Kshewi1PhD54MLWSBIquFHq48W6u3EDHoCL7OQdjm3NqA3ZgaHB1AOqF8ID4qnp878gm1De-EqDpoTKQlSIBFcfN9OmCLy1eGhL36TlrcBWi6POmFEnKpUD4mTJIAb7VQZxjZo1Ak5j4u3wCuPRxiPaYACqFM53_4qIZYD9n-p5OCI0IHEzBYacHW02eijrx_ZFyFK_tXn9aRNESs6OTLr_cnM5jUhPFg0atJ8ZlRP_v6N8Zo_RY0zrorwTzTrm_kd0DkOhtos40BcQW6dQxmwxrym5ZEDde07coPdw9rz_RcGPjRqkxhnrwwIyGUakxXsWjgrJbUxM6tkcd9XUYT8n_TrcPWwpLMrMjJnMkD1uJCUApDP43f1SbVD70uKAbmHBqGXXvtBjZfowGrr4De_mjcTHCB2Y6HR6O7risl98ifedVJyOjpziUx-GUzrMbtYzI_EJ7nLBI2RK5VriXiibe0Z8A0Ie8XoUri5SsfuQ5tZrUVQBiUOfI7TKfQA5af6ULnpcvbIW-BVk5rCWXrJT7GZE4dSP5poEWJsYrMsDyAXYOyyIIwdlj0vDWB39wcfG_xHLFAh1qUj1AODviO9UDXVmD10Uw-3PCDKBJrwlosWfbbNKnleQP8XS6kgAvEaYrqLl1yIADnzhLi4Beps7NHPeTIPiEXzo_g5HBc6ryOAp8hwUx8rAzXQokabeCiKAPGPxWXfdmozdpjNJAuBdcgA4le58hFG1W7JXB8JJ0bA_PfGmO04w9HpNjPBVykcIkMt5BtPsVKgPLRv6KNj9x7JzPnCxBmPPpLV6nuEynyTBWJurjWnQAhx-7bFRXFm-aDxvsaP_ObcJ54qXMJKpOalq0GdxcmcztWZaQVkEQjnwhKBPe4-lPEAZlYtlR2to6pY0IVbjRVXZp7yXOny4GCuKggbrVed3BkE_LuoDi65Ugg0plmPrRFjxuGjMBwxi_Wh7379xIMILP8HYf4Urt_XxghQtZBO9FxijBwm9HzqY-D-_-4AfQU1aqOTcLnJB7xVIHEUYfrA7JqbLF5kIRZWzaS6hNfancbBTi7J80SX9kInq4MHHLkChm29-5N5t_5w_YS9P4QrXyMID8AV_ZNo7SdGFcVlmfxaAO3IBKKSl2JIzOoa5qwDRh1Rs_aE5_aprO3XOKuR7ejx5JCrvDaffnAqy0IeDGjh6qw_4PS_7TkK0hP_mffz_Gnzt-EP4q_Xq6orZ_FroqDa4c4cjYMxegEH7Nydfk_5OoBg9iKFZPJv_JVLgs6t0iYsQm9Ia4lpQb66ft-0W1gC8yuib80JgWvEroZHTRpK67INiv8yyMJAgriceAuJ99LNXzgJc10ddwayHuSAylJ4oaiA6yuJBP2dUbEiTCyLCjVpaj3nj20un3qHySU_j1mVgBPP9lH3xKWb9xnGdVFmegvEpvocEqDjShUB7dXncw5oBChy-U9W6JSSdo5Gxaf319DNDKWds4LNWpgDnQzZSHvQCojKfv2WlqzO-q4PH1bCPcJ8egI3W3wAUfl23XVhEhPi1bMmOrTyTkRne3juBxA-s67s-7-afenosjgSKB82YgjTSIUAc7IjOxJCXFbwD4wf18pjkbEdaV-Uf1iTZMiE_UOaIkfdF4rrnS66zEoz584V4SeXVq0E9rUAzYjoh1XLFm4_BXafcA3fARIUBiRSnqNJMXwm-HbVZZgg652RFTUdO1WOQ0RrKQjmsg3008y6UtYovuybTL0TcKvqK1pQbKF1nQ51DdiPlgj2s8TUzVhwfwdwivpXOGhtKF1O68g4Ld53kGYNVaR9KklTuzBv0Y7jJ-GB2jq8QUATk465IMbADTFZAFTQJ0oIugU6DEkA5hK8GVCbfu7m1rzG3Gt4rspx_296Ml1sg_6UlLfO_F__4jnywhriSr8R07KDRX_xYPcUCOvrvjj2qnIf-NUwNjTWxl6z9O3uJp7xg7EyRNufiPVYtUSvNXPShEy69N-9uAqRLnRUbTkZO6uzDT5n15I-PvX2iCS2ObF3eDjlVjjlMqs2KUdKm4ZOKcC9WLcmLzffSq2W04ZHZ_9MMdlrA_q5aGTpruyi-ToY0SLgGXJD7M0MHIGS5e695lUDhvLhbRC4zQ-jIV4lzh0nuD_nohfLLtwJAPdyAypm4u_oOs85HD6pWnIiAiSI5jMwfEgXIlRbmI9cFBW14uRm7fcRXaFCTXpE6_2iHMs2nRUZom6yu_9H1jxQ5ofYUNoajF5rfGqwPx8hLHhDrh_IzXuw49Lxe1fNxSWsa0eZtRY22FU9pr16jw9vxLoeiRklFfmq452YEhwlRF26feMifPMeU5rbdrdOiSiZ6cXXNFs5qoClLaFAXivgTrwjGN0O1k3RxQwqmBRBKSH8f2CPj5rLuZCH78N_GANn8vdipeUkRzQ8MbUoVII0UECSJ1-Xm7Sw4YPviR23EkWQlS5NCapN46w6Fo0MEi25zYZE43B9BWGh_W-T5cMrsW1NaJ7TNWzK6aaZk8CQKb_m-6AXK-XxaxDKDoxGe7QJ48zM4VgvP99Dfxid9GBZ0VUozTDa73AKXgLXh4laFqy1-_deuY4qXv2YCCKOG-ux1ogaN2vYOlQqK85mfOGU-cX-18CJFX2lxEsey4TmQeZpkaPg_Bsia5W5FCP5_aLjKrhf2dmy7XZ8qh5vWUvapCuo4YHhOZT-9DC6Kk4pJA6qLyxj3xPpJjRPoW6KGjBn_ZlBRW21PGu8YBwQmVGr6D5lRMHH4_uabo8KrnLBIjHgD3184cR51XejsARJlxkpKJ_sGZqAx-xleS4U_QWHXvpzo1IXaH_2iTjEgtaqX03ZSnEq6ekOQdE7SOCz18P6X0lDLEPS8UQd2h-29_uEFrMOJGQXJPa5WExJQGG_wSi3eX8kVLd6Y11qLb7DEmauqg9J19MKnNf0Y_ZqbZP-O9PRtcXAHMH5Tl1gkyHkuglE2QgC2uSEw6XabVYjllWPc70hsDoSjcAdU12KjnGqAOlfbtp7UojenVEJ_5lIiClgpyfjvpDNm2e9TILZ04NxAJwdsDn8zOdUJIUcBeoRXt5vUKWh1AV09GTh11z_g-5oam73FmZd5OmKtjRNp40BwjjRlh-lD5BeHBIl7uWX7rBLLKm-w=","summary":[{"type":"summary_text","text":"**Designing activation reset and failure handling**"},{"type":"summary_text","text":"**Refining activation flow and listener management**"},{"type":"summary_text","text":"**Resolving activation failure redirection cycle**"}]},{"id":"rs_099c3ced01f42a35016a5892f060848198878fc5520cb0f13c","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJLyDbpfvAogqWYeieK9t8W70q_6iogutgbQ0vVV32eglRi9-UpRldtsuX17hQ79ScbXfdFDIaBa51JVnW3SD67lwDdLAmyV1JOhzZkfdzVHOKOvdiaMid2FYY_rOzLiYyQ-wmP5amPneKkRtbgyBLP0pYwT5IoYU7apmQqjLM4gb9m6pdzw5m2VTh4Ymb8VLwFXbpCHtMyVAOo125lZLf_ty-qPPH8mftvuq1pPYcRI2jgdhHB84du_lDGZUZt7Zhi8znjYAalp2PmmCwbg_kPk2Pw1MgMMyWur0rpwIUJeVuW2H8SpY2DIuQYyap-yxrrJYWFu5cEpaXLjCmL8N2O4UsE1QQtP9we34lna2T3DCBT_XFicqDpq0s-qrGMEZPBVc-fiA3iI7hQmZO8G9UHkycemBPxB3WOZ2YVB7xkvsBi9AgVMZinaHHZAQztFoilRB0McDd3crN-ip8IyGyMzrWaB2fDXiU_do0rTfo6ovxEw2aPC9_PSHz99q-3R5WabS4Us9z_Qah-sYbZw0nzkrkHpdIuuR0Xpbg7LSQ9y85LtDl32k35qlIOfquzEro2nYO2uZisyM1qJJ4nq2M9A72PIyA3JhvVMANlA0h9buXXi-cZ1-BV2-ImqJtGSU8ZD9m76ocG-iXY7Q_P1fhQuW717VvVZtWam7AYskWBVnz8ZMAob-Jos7w__7hMYQDgPxtRSP6CNIOAc4bdNsVhw8fduupDiu-QVwmPvO9p3av0M9bgMR8oSW72ll1xF7QiW1FXcfgbaMedRo68wjKitWcrpCqPXE6V1CHGRipEw_BlCQ-ajdsKElLagUipDyTvWgZX4j_3oNc-jj_ZwjglvUBQBc06O_qKNix4Pk06zhuewjCGEBqEhxkt4V6uFsoWMHV4iQLKhavRklvt4VjaxqQht6HG5Pvm3Oy0rS-ZjA_U94GbWBBIpZQxghAGXc85HqIbY6n_P-LuL4MnyYBkw-PhSBG0ixy3RFtFkQ__j1Wh2mLgvm9or25ABoKrF2itUIMQsgNu4FAt0eGJoRUf3q-GhmKUR3v0Son_fuMbR-NffNemh7uMu4rkjstnlZLS5ABj54BSgpooHRc9OZwyxIMTKzYEsaLny43ODE5nAF_OhnNjE09UpL7cAZ_4tBf75ZJqi358VSWWEKIKsZp5ka4fl1L_DNds6k8v1Mm-HxIQeUSa54nW9ajwVgHPr1LsJMEGXMTVl67AobrwAoJe2dZtoIqdCuNW1RYAkjUGnMItQwVdqjA9jOTA597vxnidHULSSKHyUBoFpfwrVKHJGIWUDKaeWX_D50BMATsPIit446ldCB4u8tC7SclA4Uwh2thGlIcLJrgAsklAmaNOwiJZrCJPGJdlens7rPTzZDWp6isg6a79Gde6u15zob2pmEYWvdHHKKm7tFf0IXXPWm-KLDXcpG--ItCBUWUzO_-xMiXGy-bHhs0iq0rrLDUl3QYVoXzdHri-tWhW5iTWUj8MqOnHZvaFFtsv3sixqaXB6vMWoAptLX3gvBsWS5bijz7F7x1bhlTdRgSP0vwnNmfbXJPKydHvR3BjeYJARzRBpFtrS6Opk5HJThReq5oPRkMRQ9U-2DYgVcYJ2CCKnhTZOmHXYQ65_YxFFtlXHKXxZxQOsUrcJ7q9f0bb_29EYlYaCdchrc2xN8XenGeTvczxbySE7LcmrcJUs9FgjXfs=","summary":[{"type":"summary_text","text":"**Implementing helper edit for commands and probes**"}]},{"id":"ctc_099c3ced01f42a35016a5892f2d04881989ec431cb2da8a068","type":"custom_tool_call","status":"completed","call_id":"call_BQOOe3g1UcV0GrHRT1SLKr7U","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#CA60]\nINS.PRE 178:\n+function maskMarkdownCode(text) {\n+\tconst lines = String(text).split(/(\\r?\\n)/);\n+\tlet fenceCharacter;\n+\tlet fenceLength = 0;\n+\treturn lines\n+\t\t.map((line) => {\n+\t\t\tif (/^\\r?\\n$/.test(line)) return line;\n+\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+\t\t\tif (fence) {\n+\t\t\t\tconst character = fence[1][0];\n+\t\t\t\tif (!fenceCharacter) {\n+\t\t\t\t\tfenceCharacter = character;\n+\t\t\t\t\tfenceLength = fence[1].length;\n+\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+\t\t\t\t\tfenceCharacter = undefined;\n+\t\t\t\t\tfenceLength = 0;\n+\t\t\t\t}\n+\t\t\t\treturn \" \".repeat(line.length);\n+\t\t\t}\n+\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\n+\n+\t\t\tconst masked = [...line];\n+\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\n+\t\t\t\tif (line[cursor] !== \"`\") continue;\n+\t\t\t\tlet runLength = 1;\n+\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\n+\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\n+\t\t\t\tif (closing < 0) {\n+\t\t\t\t\tcursor += runLength - 1;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\n+\t\t\t\tcursor = closing + runLength - 1;\n+\t\t\t}\n+\t\t\treturn masked.join(\"\");\n+\t\t})\n+\t\t.join(\"\");\n+}\n+\n+// [impl->REQ-PARITY-PEER-SHORTFORM]\n+export function parsePeerShortforms(text) {\n+\tconst source = String(text ?? \"\");\n+\tconst prose = maskMarkdownCode(source);\n+\tconst shortforms = [];\n+\tconst pattern = /@<([\\s\\S]*?)@>/g;\n+\tfor (const match of prose.matchAll(pattern)) {\n+\t\tconst inner = match[1];\n+\t\tconst separator = inner.search(/\\s/);\n+\t\tif (separator <= 0) continue;\n+\t\tconst targetList = inner.slice(0, separator);\n+\t\tconst body = inner.slice(separator).trim();\n+\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\n+\t\tshortforms.push({\n+\t\t\ttargets: targetList.split(\",\"),\n+\t\t\tbody,\n+\t\t\tindex: match.index,\n+\t\t\traw: match[0],\n+\t\t});\n+\t}\n+\treturn shortforms;\n+}\n+\n+function parseJson(raw, label) {\n+\ttry {\n+\t\treturn JSON.parse(raw);\n+\t} catch (error) {\n+\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\n+\t}\n+}\n+\n+function parseVersion(raw) {\n+\tconst match = String(raw ?? \"\").match(/\\bv?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+][0-9A-Za-z.-]+)?\\b/);\n+\treturn match ? match.slice(1, 4).map(Number) : undefined;\n+}\n+\n+function compareVersions(left, right) {\n+\tfor (let index = 0; index < 3; index += 1) {\n+\t\tif (left[index] !== right[index]) return left[index] - right[index];\n+\t}\n+\treturn 0;\n+}\n+\n+function formatVersion(version) {\n+\treturn `v${version.join(\".\")}`;\n+}\n+\n+function promptHints(prompt) {\n+\tconst text = String(prompt ?? \"\").trim();\n+\tif (!text) return [];\n+\tconst hints = [];\n+\tif (\n+\t\t/(?:^|\\s)\\/live(?:\\s|$)/i.test(text) ||\n+\t\t/\\b(?:go|become|start|resume|activate)\\s+(?:an?\\s+)?live(?:\\s+agent)?\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Use extension-native `/live`; use `/live --auto` only for explicit auto-resume.\");\n+\t}\n+\tif (\n+\t\t/\\bwho am i\\b/i.test(text) ||\n+\t\t/\\b(?:show|check|what(?:'s| is))\\s+(?:my\\s+)?(?:spt\\s+)?(?:identity|endpoint|perch)\\b/i.test(\n+\t\t\ttext,\n+\t\t)\n+\t) {\n+\t\thints.push(\"Run `spt whoami --json` for this endpoint's identity.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:send|message|contact|tell|reply to)\\s+(?:an?\\s+|the\\s+)?(?:agent|peer|endpoint)\\b/i.test(\n+\t\t\ttext,\n+\t\t) ||\n+\t\t/\\bhow (?:do|can|should) (?:i|we) (?:send|message|contact)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to send` for canonical peer messaging.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n+\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to subnet` for private-network onboarding.\");\n+\t}\n+\tif (\n+\t\t/\\bcheckpoint\\b/i.test(text) ||\n+\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n+\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Read the packaged commune skill and use its checkpoint mode.\");\n+\t}\n+\treturn hints;\n+}\n+\n+function startupBrief(id) {\n+\treturn [\n+\t\t`OMP SPT endpoint \\`${id}\\` is active. Keep lifecycle infrastructure extension-owned.`,\n+\t\t\"- Identity/roster: `spt whoami --json`; `spt endpoint list`.\",\n+\t\t\"- Messaging: `spt how-to send` (or explicit assistant shortform `@<target message @>`).\",\n+\t\t\"- Continuity/lifecycle: use the packaged commune (checkpoint mode), signoff, and role skills.\",\n+\t\t\"- Activation/setup: `/ready`, `/live`, and the packaged setup skill.\",\n+\t\t\"- Subnets: `spt how-to subnet`.\",\n+\t\t\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\",\n+\t].join(\"\\n\");\n+}\n+\n*** End Patch\n","name":"edit"}]},"duration":60859.107499999925,"ttft":2507.971799999941,"contextSnapshot":{"promptTokens":159779,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_BQOOe3g1UcV0GrHRT1SLKr7U|ctc_099c3ced01f42a35016a5892f2d04881989ec431cb2da8a068","toolName":"edit","startedAt":"2026-07-16T08:15:10.551Z"},"id":"f18935b2","parentId":"0367a2f6","timestamp":"2026-07-16T08:15:10.551Z"}
{"type":"message","id":"9adfbc40","parentId":"f18935b2","timestamp":"2026-07-16T08:15:10.552Z","message":{"role":"toolResult","toolCallId":"call_BQOOe3g1UcV0GrHRT1SLKr7U|ctc_099c3ced01f42a35016a5892f2d04881989ec431cb2da8a068","toolName":"edit","content":[{"type":"text","text":"This edit anchors to lines 178 of adapter/strings/omp-spt.mjs that [adapter/strings/omp-spt.mjs#CA60] never displayed (it showed a partial range, a search hit, or a folded summary). Actual file content at those lines:\n  178:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\nVerify the content matches what you intend to touch, then re-issue the edit with the same [path#tag] header — a straight retry now succeeds without a re-read. If the content does NOT match, fix your line numbers."}],"details":{},"isError":true,"timestamp":1784189710552}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `TruthGates`:\n\nYes, I own the final traceable-reqs.toml consolidation. Avoid editing it. I’ll add docs/PARITY.md and docs/adr/0015*, 0017* roots and activate those nine reqs to doc+impl+unit after your tags land. Ping exact changed evidence paths when done.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"TruthGates\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531ccb54b1b7967","from":"TruthGates","message":"Yes, I own the final traceable-reqs.toml consolidation. Avoid editing it. I’ll add docs/PARITY.md and docs/adr/0015*, 0017* roots and activate those nine reqs to doc+impl+unit after your tags land. Ping exact changed evidence paths when done."},"attribution":"agent","id":"2a77377a","parentId":"9adfbc40","timestamp":"2026-07-16T08:15:10.553Z"}
{"type":"message","id":"a8286505","parentId":"2a77377a","timestamp":"2026-07-16T08:15:41.538Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Retrying failed edit**"},{"type":"toolCall","id":"call_ZszE0XtGsdUmN2DrqM0adywN|ctc_099536def416fe9f016a589311d62c819abe64639d13a9dab6","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#CA60]\nINS.PRE 178:\n+function maskMarkdownCode(text) {\n+\tconst lines = String(text).split(/(\\r?\\n)/);\n+\tlet fenceCharacter;\n+\tlet fenceLength = 0;\n+\treturn lines\n+\t\t.map((line) => {\n+\t\t\tif (/^\\r?\\n$/.test(line)) return line;\n+\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+\t\t\tif (fence) {\n+\t\t\t\tconst character = fence[1][0];\n+\t\t\t\tif (!fenceCharacter) {\n+\t\t\t\t\tfenceCharacter = character;\n+\t\t\t\t\tfenceLength = fence[1].length;\n+\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+\t\t\t\t\tfenceCharacter = undefined;\n+\t\t\t\t\tfenceLength = 0;\n+\t\t\t\t}\n+\t\t\t\treturn \" \".repeat(line.length);\n+\t\t\t}\n+\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\n+\n+\t\t\tconst masked = [...line];\n+\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\n+\t\t\t\tif (line[cursor] !== \"`\") continue;\n+\t\t\t\tlet runLength = 1;\n+\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\n+\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\n+\t\t\t\tif (closing < 0) {\n+\t\t\t\t\tcursor += runLength - 1;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\n+\t\t\t\tcursor = closing + runLength - 1;\n+\t\t\t}\n+\t\t\treturn masked.join(\"\");\n+\t\t})\n+\t\t.join(\"\");\n+}\n+\n+// [impl->REQ-PARITY-PEER-SHORTFORM]\n+export function parsePeerShortforms(text) {\n+\tconst source = String(text ?? \"\");\n+\tconst prose = maskMarkdownCode(source);\n+\tconst shortforms = [];\n+\tconst pattern = /@<([\\s\\S]*?)@>/g;\n+\tfor (const match of prose.matchAll(pattern)) {\n+\t\tconst inner = match[1];\n+\t\tconst separator = inner.search(/\\s/);\n+\t\tif (separator <= 0) continue;\n+\t\tconst targetList = inner.slice(0, separator);\n+\t\tconst body = inner.slice(separator).trim();\n+\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\n+\t\tshortforms.push({\n+\t\t\ttargets: targetList.split(\",\"),\n+\t\t\tbody,\n+\t\t\tindex: match.index,\n+\t\t\traw: match[0],\n+\t\t});\n+\t}\n+\treturn shortforms;\n+}\n+\n+function parseJson(raw, label) {\n+\ttry {\n+\t\treturn JSON.parse(raw);\n+\t} catch (error) {\n+\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\n+\t}\n+}\n+\n+function parseVersion(raw) {\n+\tconst match = String(raw ?? \"\").match(/\\bv?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+][0-9A-Za-z.-]+)?\\b/);\n+\treturn match ? match.slice(1, 4).map(Number) : undefined;\n+}\n+\n+function compareVersions(left, right) {\n+\tfor (let index = 0; index < 3; index += 1) {\n+\t\tif (left[index] !== right[index]) return left[index] - right[index];\n+\t}\n+\treturn 0;\n+}\n+\n+function formatVersion(version) {\n+\treturn `v${version.join(\".\")}`;\n+}\n+\n+function promptHints(prompt) {\n+\tconst text = String(prompt ?? \"\").trim();\n+\tif (!text) return [];\n+\tconst hints = [];\n+\tif (\n+\t\t/(?:^|\\s)\\/live(?:\\s|$)/i.test(text) ||\n+\t\t/\\b(?:go|become|start|resume|activate)\\s+(?:an?\\s+)?live(?:\\s+agent)?\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Use extension-native `/live`; use `/live --auto` only for explicit auto-resume.\");\n+\t}\n+\tif (\n+\t\t/\\bwho am i\\b/i.test(text) ||\n+\t\t/\\b(?:show|check|what(?:'s| is))\\s+(?:my\\s+)?(?:spt\\s+)?(?:identity|endpoint|perch)\\b/i.test(\n+\t\t\ttext,\n+\t\t)\n+\t) {\n+\t\thints.push(\"Run `spt whoami --json` for this endpoint's identity.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:send|message|contact|tell|reply to)\\s+(?:an?\\s+|the\\s+)?(?:agent|peer|endpoint)\\b/i.test(\n+\t\t\ttext,\n+\t\t) ||\n+\t\t/\\bhow (?:do|can|should) (?:i|we) (?:send|message|contact)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to send` for canonical peer messaging.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n+\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to subnet` for private-network onboarding.\");\n+\t}\n+\tif (\n+\t\t/\\bcheckpoint\\b/i.test(text) ||\n+\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n+\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Read the packaged commune skill and use its checkpoint mode.\");\n+\t}\n+\treturn hints;\n+}\n+\n+function startupBrief(id) {\n+\treturn [\n+\t\t`OMP SPT endpoint \\`${id}\\` is active. Keep lifecycle infrastructure extension-owned.`,\n+\t\t\"- Identity/roster: `spt whoami --json`; `spt endpoint list`.\",\n+\t\t\"- Messaging: `spt how-to send` (or explicit assistant shortform `@<target message @>`).\",\n+\t\t\"- Continuity/lifecycle: use the packaged commune (checkpoint mode), signoff, and role skills.\",\n+\t\t\"- Activation/setup: `/ready`, `/live`, and the packaged setup skill.\",\n+\t\t\"- Subnets: `spt how-to subnet`.\",\n+\t\t\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\",\n+\t].join(\"\\n\");\n+}\n+\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":4063,"output":1582,"cacheRead":159232,"cacheWrite":0,"totalTokens":164877,"reasoningTokens":31,"cost":{"input":0.020315000000000003,"output":0.04746,"cacheRead":0.07961599999999999,"cacheWrite":0,"total":0.147391}},"stopReason":"toolUse","timestamp":1784189710569,"responseId":"resp_099536def416fe9f016a58930eef4c819a86fade734ab38d07","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_099536def416fe9f016a589310dcd4819abb7f7f12b93e35be","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJMRiuzhJRn2-Vb7NPoesRVNcIK8UFIz45MCuw6rIkenUPXoK2Evfw-4StvvUROnQEekTtpys0wF606ndStJ0jtLY4Ii_jbkMusaCFbst2YJp2srFhGxwYRQmWsdBdBSsCKfaxSxIv_7tZ9GG_ghdzYjEfMpD0xiPEiuS7CZ2sn1CebCUqYPY_GjWwrHSo0GlWvpY7erAPT8W4pShQ8f8G8V_3gnaxWpfuyXZkSk0v8zlGa1RDbMgDL-iquJzoJOWfXm9JDenv_cUa4qwGCsgb-LCg42fqp37nGB8y18GGuaDxYEnidQoJDjbR-wgW5HV3cAOL3ZbinfIBKX_uID6b3M-neTfm4s01zVbaIvh0JV4gcN6xrNJKlGIpmxFLgKF2Bvyz6KLf5Mx2CEsNIMk7vQSmxmZmKi-TA8VDRFKNq5Tr1UWN05LhgRHklXPi27EmsQEX1uU7nMZ2viem10L_rZbBIu_L-1yDFCJO2-kKFG_lglrWsk305cWlm_VbmKkOY5dF__svmQD0GMlpyAGmFivSoEWPuiMfG9vEOaQy7OSW2BDT-HshyVivdzK_ljTBsBHP8tOpO1zEbvk14onvuIr4Ooh1mXTlO3VzSav3AUw5kWQwj4oJ3MYUk2i879nsLZgqcx0yiwJFEUhB1iUMc8cZIKdbSrHgaOvF97eUYGqi7BLXj4PNni_Rdk7Z6R__0wkLBzz8F1C0nfF1l0j2oleUlUjtZlpfysZHkchY5Xu73cS9CaSgD7zcNY9lJuRiEfnaFGFyaMTvrJDPdfjZGSF1MOGNAW7doZBRKg2jnLGIxzTjSyi0PZwhgkkNNKIDwKszCr_LxaCGyWP_33s8UWXh8BLR7lY-rMDTyHXqu5cQeYgiTH7ZtygFpTflgvu-6w4yBCwzurap6r4ux3JkNu7liwW1Rp3GFRSZ0VPYjo9VVCDfRDvGXpSVEi1aJWZL00Sj3VHwLPWE2_4Aqfh5tZkE_O5E99pxviMDLWjNeE5AicNCZjo2TCidLdOoQ7UwEnDlyCq-fR5NlbF_FV8KYSFny1Go_Msay83-0sRNmmB4ADArS0jSiIe0DJedHxht5L","summary":[{"type":"summary_text","text":"**Retrying failed edit**"}]},{"id":"ctc_099536def416fe9f016a589311d62c819abe64639d13a9dab6","type":"custom_tool_call","status":"completed","call_id":"call_ZszE0XtGsdUmN2DrqM0adywN","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#CA60]\nINS.PRE 178:\n+function maskMarkdownCode(text) {\n+\tconst lines = String(text).split(/(\\r?\\n)/);\n+\tlet fenceCharacter;\n+\tlet fenceLength = 0;\n+\treturn lines\n+\t\t.map((line) => {\n+\t\t\tif (/^\\r?\\n$/.test(line)) return line;\n+\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+\t\t\tif (fence) {\n+\t\t\t\tconst character = fence[1][0];\n+\t\t\t\tif (!fenceCharacter) {\n+\t\t\t\t\tfenceCharacter = character;\n+\t\t\t\t\tfenceLength = fence[1].length;\n+\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+\t\t\t\t\tfenceCharacter = undefined;\n+\t\t\t\t\tfenceLength = 0;\n+\t\t\t\t}\n+\t\t\t\treturn \" \".repeat(line.length);\n+\t\t\t}\n+\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\n+\n+\t\t\tconst masked = [...line];\n+\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\n+\t\t\t\tif (line[cursor] !== \"`\") continue;\n+\t\t\t\tlet runLength = 1;\n+\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\n+\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\n+\t\t\t\tif (closing < 0) {\n+\t\t\t\t\tcursor += runLength - 1;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\n+\t\t\t\tcursor = closing + runLength - 1;\n+\t\t\t}\n+\t\t\treturn masked.join(\"\");\n+\t\t})\n+\t\t.join(\"\");\n+}\n+\n+// [impl->REQ-PARITY-PEER-SHORTFORM]\n+export function parsePeerShortforms(text) {\n+\tconst source = String(text ?? \"\");\n+\tconst prose = maskMarkdownCode(source);\n+\tconst shortforms = [];\n+\tconst pattern = /@<([\\s\\S]*?)@>/g;\n+\tfor (const match of prose.matchAll(pattern)) {\n+\t\tconst inner = match[1];\n+\t\tconst separator = inner.search(/\\s/);\n+\t\tif (separator <= 0) continue;\n+\t\tconst targetList = inner.slice(0, separator);\n+\t\tconst body = inner.slice(separator).trim();\n+\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\n+\t\tshortforms.push({\n+\t\t\ttargets: targetList.split(\",\"),\n+\t\t\tbody,\n+\t\t\tindex: match.index,\n+\t\t\traw: match[0],\n+\t\t});\n+\t}\n+\treturn shortforms;\n+}\n+\n+function parseJson(raw, label) {\n+\ttry {\n+\t\treturn JSON.parse(raw);\n+\t} catch (error) {\n+\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\n+\t}\n+}\n+\n+function parseVersion(raw) {\n+\tconst match = String(raw ?? \"\").match(/\\bv?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+][0-9A-Za-z.-]+)?\\b/);\n+\treturn match ? match.slice(1, 4).map(Number) : undefined;\n+}\n+\n+function compareVersions(left, right) {\n+\tfor (let index = 0; index < 3; index += 1) {\n+\t\tif (left[index] !== right[index]) return left[index] - right[index];\n+\t}\n+\treturn 0;\n+}\n+\n+function formatVersion(version) {\n+\treturn `v${version.join(\".\")}`;\n+}\n+\n+function promptHints(prompt) {\n+\tconst text = String(prompt ?? \"\").trim();\n+\tif (!text) return [];\n+\tconst hints = [];\n+\tif (\n+\t\t/(?:^|\\s)\\/live(?:\\s|$)/i.test(text) ||\n+\t\t/\\b(?:go|become|start|resume|activate)\\s+(?:an?\\s+)?live(?:\\s+agent)?\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Use extension-native `/live`; use `/live --auto` only for explicit auto-resume.\");\n+\t}\n+\tif (\n+\t\t/\\bwho am i\\b/i.test(text) ||\n+\t\t/\\b(?:show|check|what(?:'s| is))\\s+(?:my\\s+)?(?:spt\\s+)?(?:identity|endpoint|perch)\\b/i.test(\n+\t\t\ttext,\n+\t\t)\n+\t) {\n+\t\thints.push(\"Run `spt whoami --json` for this endpoint's identity.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:send|message|contact|tell|reply to)\\s+(?:an?\\s+|the\\s+)?(?:agent|peer|endpoint)\\b/i.test(\n+\t\t\ttext,\n+\t\t) ||\n+\t\t/\\bhow (?:do|can|should) (?:i|we) (?:send|message|contact)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to send` for canonical peer messaging.\");\n+\t}\n+\tif (\n+\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n+\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Run `spt how-to subnet` for private-network onboarding.\");\n+\t}\n+\tif (\n+\t\t/\\bcheckpoint\\b/i.test(text) ||\n+\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n+\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n+\t) {\n+\t\thints.push(\"Read the packaged commune skill and use its checkpoint mode.\");\n+\t}\n+\treturn hints;\n+}\n+\n+function startupBrief(id) {\n+\treturn [\n+\t\t`OMP SPT endpoint \\`${id}\\` is active. Keep lifecycle infrastructure extension-owned.`,\n+\t\t\"- Identity/roster: `spt whoami --json`; `spt endpoint list`.\",\n+\t\t\"- Messaging: `spt how-to send` (or explicit assistant shortform `@<target message @>`).\",\n+\t\t\"- Continuity/lifecycle: use the packaged commune (checkpoint mode), signoff, and role skills.\",\n+\t\t\"- Activation/setup: `/ready`, `/live`, and the packaged setup skill.\",\n+\t\t\"- Subnets: `spt how-to subnet`.\",\n+\t\t\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\",\n+\t].join(\"\\n\");\n+}\n+\n*** End Patch\n","name":"edit"}]},"duration":30968.7098999999,"ttft":2283.0396999998484,"contextSnapshot":{"promptTokens":163295,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ZszE0XtGsdUmN2DrqM0adywN|ctc_099536def416fe9f016a589311d62c819abe64639d13a9dab6","toolName":"edit","startedAt":"2026-07-16T08:15:41.540Z"},"id":"e3988cb3","parentId":"a8286505","timestamp":"2026-07-16T08:15:41.540Z"}
{"type":"message","id":"c4df84a1","parentId":"e3988cb3","timestamp":"2026-07-16T08:15:41.567Z","message":{"role":"toolResult","toolCallId":"call_ZszE0XtGsdUmN2DrqM0adywN|ctc_099536def416fe9f016a589311d62c819abe64639d13a9dab6","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#5412]\n163:function injectEnvelope(messages, item) {\n\n176:}\n177:\n178:function maskMarkdownCode(text) {\n179:\tconst lines = String(text).split(/(\\r?\\n)/);\n…\n316:}\n317:\n318:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n319:const DEFAULT_KILL_GRACE_MS = 100;"}],"details":{"diff":" 163|function injectEnvelope(messages, item) {\n\n 176|}\n 177|\n+178|function maskMarkdownCode(text) {\n+179|\tconst lines = String(text).split(/(\\r?\\n)/);\n+180|\tlet fenceCharacter;\n+181|\tlet fenceLength = 0;\n+182|\treturn lines\n+183|\t\t.map((line) => {\n+184|\t\t\tif (/^\\r?\\n$/.test(line)) return line;\n+185|\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+186|\t\t\tif (fence) {\n+187|\t\t\t\tconst character = fence[1][0];\n+188|\t\t\t\tif (!fenceCharacter) {\n+189|\t\t\t\t\tfenceCharacter = character;\n+190|\t\t\t\t\tfenceLength = fence[1].length;\n+191|\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+192|\t\t\t\t\tfenceCharacter = undefined;\n+193|\t\t\t\t\tfenceLength = 0;\n+194|\t\t\t\t}\n+195|\t\t\t\treturn \" \".repeat(line.length);\n+196|\t\t\t}\n+197|\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\n+198|\n+199|\t\t\tconst masked = [...line];\n+200|\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\n+201|\t\t\t\tif (line[cursor] !== \"`\") continue;\n+202|\t\t\t\tlet runLength = 1;\n+203|\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\n+204|\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\n+205|\t\t\t\tif (closing < 0) {\n+206|\t\t\t\t\tcursor += runLength - 1;\n+207|\t\t\t\t\tcontinue;\n+208|\t\t\t\t}\n+209|\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\n+210|\t\t\t\tcursor = closing + runLength - 1;\n+211|\t\t\t}\n+212|\t\t\treturn masked.join(\"\");\n+213|\t\t})\n+214|\t\t.join(\"\");\n+215|}\n+216|\n+217|// [impl->REQ-PARITY-PEER-SHORTFORM]\n+218|export function parsePeerShortforms(text) {\n+219|\tconst source = String(text ?? \"\");\n+220|\tconst prose = maskMarkdownCode(source);\n+221|\tconst shortforms = [];\n+222|\tconst pattern = /@<([\\s\\S]*?)@>/g;\n+223|\tfor (const match of prose.matchAll(pattern)) {\n+224|\t\tconst inner = match[1];\n+225|\t\tconst separator = inner.search(/\\s/);\n+226|\t\tif (separator <= 0) continue;\n+227|\t\tconst targetList = inner.slice(0, separator);\n+228|\t\tconst body = inner.slice(separator).trim();\n+229|\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\n+230|\t\tshortforms.push({\n+231|\t\t\ttargets: targetList.split(\",\"),\n+232|\t\t\tbody,\n+233|\t\t\tindex: match.index,\n+234|\t\t\traw: match[0],\n+235|\t\t});\n+236|\t}\n+237|\treturn shortforms;\n+238|}\n+239|\n+240|function parseJson(raw, label) {\n+241|\ttry {\n+242|\t\treturn JSON.parse(raw);\n+243|\t} catch (error) {\n+244|\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\n+245|\t}\n+246|}\n+247|\n+248|function parseVersion(raw) {\n+249|\tconst match = String(raw ?? \"\").match(/\\bv?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+][0-9A-Za-z.-]+)?\\b/);\n+250|\treturn match ? match.slice(1, 4).map(Number) : undefined;\n+251|}\n+252|\n+253|function compareVersions(left, right) {\n+254|\tfor (let index = 0; index < 3; index += 1) {\n+255|\t\tif (left[index] !== right[index]) return left[index] - right[index];\n+256|\t}\n+257|\treturn 0;\n+258|}\n+259|\n+260|function formatVersion(version) {\n+261|\treturn `v${version.join(\".\")}`;\n+262|}\n+263|\n+264|function promptHints(prompt) {\n+265|\tconst text = String(prompt ?? \"\").trim();\n+266|\tif (!text) return [];\n+267|\tconst hints = [];\n+268|\tif (\n+269|\t\t/(?:^|\\s)\\/live(?:\\s|$)/i.test(text) ||\n+270|\t\t/\\b(?:go|become|start|resume|activate)\\s+(?:an?\\s+)?live(?:\\s+agent)?\\b/i.test(text)\n+271|\t) {\n+272|\t\thints.push(\"Use extension-native `/live`; use `/live --auto` only for explicit auto-resume.\");\n+273|\t}\n+274|\tif (\n+275|\t\t/\\bwho am i\\b/i.test(text) ||\n+276|\t\t/\\b(?:show|check|what(?:'s| is))\\s+(?:my\\s+)?(?:spt\\s+)?(?:identity|endpoint|perch)\\b/i.test(\n+277|\t\t\ttext,\n+278|\t\t)\n+279|\t) {\n+280|\t\thints.push(\"Run `spt whoami --json` for this endpoint's identity.\");\n+281|\t}\n+282|\tif (\n+283|\t\t/\\b(?:send|message|contact|tell|reply to)\\s+(?:an?\\s+|the\\s+)?(?:agent|peer|endpoint)\\b/i.test(\n+284|\t\t\ttext,\n+285|\t\t) ||\n+286|\t\t/\\bhow (?:do|can|should) (?:i|we) (?:send|message|contact)\\b/i.test(text)\n+287|\t) {\n+288|\t\thints.push(\"Run `spt how-to send` for canonical peer messaging.\");\n+289|\t}\n+290|\tif (\n+291|\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n+292|\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n+293|\t) {\n+294|\t\thints.push(\"Run `spt how-to subnet` for private-network onboarding.\");\n+295|\t}\n+296|\tif (\n+297|\t\t/\\bcheckpoint\\b/i.test(text) ||\n+298|\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n+299|\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n+300|\t) {\n+301|\t\thints.push(\"Read the packaged commune skill and use its checkpoint mode.\");\n+302|\t}\n+303|\treturn hints;\n+304|}\n+305|\n+306|function startupBrief(id) {\n+307|\treturn [\n+308|\t\t`OMP SPT endpoint \\`${id}\\` is active. Keep lifecycle infrastructure extension-owned.`,\n+309|\t\t\"- Identity/roster: `spt whoami --json`; `spt endpoint list`.\",\n+310|\t\t\"- Messaging: `spt how-to send` (or explicit assistant shortform `@<target message @>`).\",\n+311|\t\t\"- Continuity/lifecycle: use the packaged commune (checkpoint mode), signoff, and role skills.\",\n+312|\t\t\"- Activation/setup: `/ready`, `/live`, and the packaged setup skill.\",\n+313|\t\t\"- Subnets: `spt how-to subnet`.\",\n+314|\t\t\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\",\n+315|\t].join(\"\\n\");\n+316|}\n+317|\n 178|const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n 179|const DEFAULT_KILL_GRACE_MS = 100;","firstChangedLine":178,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784189741567}}
{"type":"message","id":"9a968179","parentId":"c4df84a1","timestamp":"2026-07-16T08:15:46.124Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding config options before state return**"},{"type":"toolCall","id":"call_peod5tbb6tMy3rwIErb0ilEy|fc_09d03f9da8d00304016a589331d32481998020ccb027eca214","name":"read","arguments":{"i":"Regrounding extension constructor","path":"adapter/strings/omp-spt.mjs","selector":"510-620"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2667,"output":66,"cacheRead":162304,"cacheWrite":0,"totalTokens":165037,"reasoningTokens":25,"cost":{"input":0.013335000000000001,"output":0.00198,"cacheRead":0.081152,"cacheWrite":0,"total":0.096467}},"stopReason":"toolUse","timestamp":1784189741574,"responseId":"resp_09d03f9da8d00304016a58932e447081999897abdbcab95090","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09d03f9da8d00304016a5893301e0c8199b1dfadcd8794d6b7","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJMxWnBg1l23JygYal6SQSeNf6xxZSiwf_Ii4ULgH_LviCY1zE6v9IUP2_qe5htfsdU_GaKomy3N6d3wM50VrbP6y3ia-ghdJq01a-8YWcw4Et1DZvORSVSOtXlkYqb9mDBzs_TR4aHVa4iXEZKTFLYTCclya5jzRWHPMNuSDx2Z0LqSguOyNUIc10K3qq2P5PiDxXIcY0XOQQ1gWVCYPp5IuRUDz4fRo6taoQLlIsbohWqJ67kEk2APwdcJR-1JqTD0X-TXtTEoYJ0DAy7z_VrjKjXh1M2zgplpa3aSrMB8t8V-vs_tXmGlrlQkcvICcWsFJFYitP-ZDihX-CO17jMmsUxlJZDwQf7jt3sW7-byCOQ4z9-wRRnF1jEDS6iBdHKjzN-udGMvzGDjWVtjij5sTfgZPtseGDI9ecNctBBfWGj42UxtI9TCfyXybSm-kXn62su1oCrF85tne5b2Lh3YjS2DYv9_MZCkGIfKC_c9cdF3ESyk8cYf8-49BRdC4ZdYWIvy0Zj_o8TOyA-TBrtpKScTxEisTHVWBeuN9Dq5tkmei6pOT67eS4i2_gjp8qN_g4Jx21Lw0nF7kx0iaknEyu5-z3iTDEuEwJsnDemOhL37_4qrgIQ1gqm0j5-b3pel5PNPz47AoI0U3sjhBD1sjw7yw3svMr6DiQRP1MhEsdo_lGp5OhbP6RQ2nk-yDuXmkMCvnHvyemku4TNMUjbXnDcjiK_fVHKRgMxTj994I9_i0Zg67IpzNliq7RcQ4Y9bUKhp9DmjQXi2iFWxCRYgtNU3ZhFYvh_Bkd4orNfpYHjCM9mN5vs0GaAHcQjFwP5Y2ICRYtcoZAqWw8PvKqnSEI-U6vTNLKnX_yxrRLCiKUdxmL5FF62OfHJtcK3CVnC98L9c1UesAmUsLNNMq-9qximxvmk5hKD6VIZDAIlRb0KrTqmopp4RssI9gm74Y-FPqnrZSygsIffL2sTgmoG5eUcjtjSD4-apP_5syBvJmN5i5GLWF5o0Dg0K3kKYvOoIQNykkrvdTXvjrIS0rgznscoxQssRNP8OYjx8KsmdYcNCjAN89ban98QNXgEVIo3m","summary":[{"type":"summary_text","text":"**Adding config options before state return**"}]},{"id":"fc_09d03f9da8d00304016a589331d32481998020ccb027eca214","type":"function_call","status":"completed","arguments":"{\"i\":\"Regrounding extension constructor\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"510-620\"}","call_id":"call_peod5tbb6tMy3rwIErb0ilEy","name":"read"}]},"duration":4549.805899999803,"ttft":2531.616699999897,"contextSnapshot":{"promptTokens":164971,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_peod5tbb6tMy3rwIErb0ilEy|fc_09d03f9da8d00304016a589331d32481998020ccb027eca214","toolName":"read","startedAt":"2026-07-16T08:15:46.125Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Regrounding extension constructor"},"id":"8e3fb31f","parentId":"9a968179","timestamp":"2026-07-16T08:15:46.125Z"}
{"type":"message","id":"2a7c88af","parentId":"8e3fb31f","timestamp":"2026-07-16T08:15:46.139Z","message":{"role":"toolResult","toolCallId":"call_peod5tbb6tMy3rwIErb0ilEy|fc_09d03f9da8d00304016a589331d32481998020ccb027eca214","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#5412]\n388:export function runSpt(args, input, overrides = {}) {\n…\n404:\treturn new Promise((resolve, reject) => {\n…\n506:\t\tif (input !== undefined) {\n507:\t\t\ttry {\n…\n509:\t\t\t} catch (error) {\n510:\t\t\t\tvoid terminateAndReject(error);\n511:\t\t\t}\n512:\t\t}\n513:\t});\n514:}\n515:\n516:export function createOmpSpt(overrides = {}) {\n517:\tconst spawnProcess = overrides.spawnProcess ?? spawn;\n518:\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\n519:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n520:\tconst env = overrides.env ?? process.env;\n521:\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n522:\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n523:\tconst customRunSptCommand = overrides.runSptCommand;\n524:\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n525:\tconst runSptCommand =\n526:\t\tcustomRunSptCommand ??\n527:\t\t((args, input, options = {}) =>\n528:\t\t\trunSpt(args, input, {\n529:\t\t\t\tclearTimeout: clearTimer,\n530:\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\n531:\t\t\t\tenv,\n532:\t\t\t\tkillForceMs,\n533:\t\t\t\tkillGraceMs,\n534:\t\t\t\tsetTimeout: setTimer,\n535:\t\t\t\tsignal: options.signal,\n536:\t\t\t\tspawnProcess,\n537:\t\t\t}));\n538:\tconst shutdownBudgetMs =\n539:\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\n540:\tconst requestedShutdownCommandTimeoutMs =\n541:\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\n542:\tconst terminationWindowMs = killGraceMs + killForceMs;\n543:\tconst maxShutdownCommandTimeoutMs = Math.max(\n544:\t\t1,\n545:\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\n546:\t);\n547:\tconst shutdownCommandTimeoutMs = Math.max(\n548:\t\t1,\n549:\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\n550:\t);\n551:\tconst listenerBufferLimit =\n552:\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\n553:\tconst acceptedQueueLimit =\n554:\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\n555:\tconst acceptedBytesLimit =\n556:\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\n557:\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\n558:\tconst outcomeRetryDelaysMs = [\n559:\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\n560:\t];\n561:\tconst sessionEndRetryDelaysMs = [\n562:\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\n563:\t];\n564:\tconst listenerStableMs =\n565:\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\n566:\n567:\treturn function ompSpt(pi) {\n568:\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n569:\t\tif (!id) return;\n570:\n571:\t\tlet sid;\n572:\t\tlet token;\n573:\t\tlet listener;\n574:\t\tlet listenerBuffer = \"\";\n575:\t\tlet listenerRestartCount = 0;\n576:\t\tlet listenerStableTimer;\n577:\t\tlet restartTimer;\n578:\t\tlet dispatchTimer;\n579:\t\tlet bindPromise;\n580:\t\tlet agentActive = false;\n581:\t\tlet desiredState = \"idle\";\n582:\t\tlet dispatching = false;\n583:\t\tlet turnCompletionPromise;\n584:\t\tlet listenerTerminationPromise;\n585:\t\tlet shutdownMode = false;\n586:\t\tlet shutdownDeadlineExpired = false;\n587:\t\tconst activeCommands = new Map();\n588:\t\tconst retryWaiters = new Set();\n589:\t\tlet current;\n590:\t\tlet stopping = false;\n591:\t\tlet ui;\n592:\t\tlet runtimeCtx;\n593:\t\tlet endpointState;\n594:\t\tlet stateOperation = Promise.resolve();\n595:\t\tlet endPromise;\n596:\t\tlet fatalPromise;\n597:\t\tlet teardownPromise;\n598:\t\tlet acceptedBytes = 0;\n599:\t\tlet overflowItem;\n600:\t\tconst queue = [];\n601:\n602:\t\tconst logError = (message, error) => {\n603:\t\t\tpi.logger.error(message, { error: errorSummary(error) });\n604:\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\n605:\t\t};\n606:\n607:\t\tfunction runCommand(args, input, options = {}) {\n608:\t\t\tif (shutdownDeadlineExpired) {\n609:\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\n610:\t\t\t}\n611:\t\t\tconst timeoutMs =\n612:\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\n613:\t\t\tconst controller = new AbortController();\n614:\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\n615:\t\t\tlet command;\n616:\t\t\ttry {\n617:\t\t\t\tcommand = Promise.resolve(\n618:\t\t\t\t\trunSptCommand(args, input, {\n619:\t\t\t\t\t\tsignal: controller.signal,\n620:\t\t\t\t\t\ttimeoutMs,\n621:\t\t\t\t\t}),\n622:\t\t\t\t);\n623:\t\t\t} catch (error) {\n…\n626:\t\t\t}\n…\n668:\t\t}\n…\n1294:\t};\n1295:}\n\n[Showing lines 509-623 of 1298. Use :624 to continue]"}],"details":{"truncation":{"content":"\t\t\t} catch (error) {\r\n\t\t\t\tvoid terminateAndReject(error);\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}\r\n\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r\n\tconst shutdownBudgetMs =\r\n\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\r\n\tconst requestedShutdownCommandTimeoutMs =\r\n\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\r\n\tconst terminationWindowMs = killGraceMs + killForceMs;\r\n\tconst maxShutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\r\n\t);\r\n\tconst shutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\r\n\t);\r\n\tconst listenerBufferLimit =\r\n\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst acceptedQueueLimit =\r\n\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\r\n\tconst acceptedBytesLimit =\r\n\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\r\n\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\r\n\tconst outcomeRetryDelaysMs = [\r\n\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\r\n\t];\r\n\tconst sessionEndRetryDelaysMs = [\r\n\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\r\n\t];\r\n\tconst listenerStableMs =\r\n\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n\t\tlet listenerBuffer = \"\";\r\n\t\tlet listenerRestartCount = 0;\r\n\t\tlet listenerStableTimer;\r\n\t\tlet restartTimer;\r\n\t\tlet dispatchTimer;\r\n\t\tlet bindPromise;\r\n\t\tlet agentActive = false;\r\n\t\tlet desiredState = \"idle\";\r\n\t\tlet dispatching = false;\r\n\t\tlet turnCompletionPromise;\r\n\t\tlet listenerTerminationPromise;\r\n\t\tlet shutdownMode = false;\r\n\t\tlet shutdownDeadlineExpired = false;\r\n\t\tconst activeCommands = new Map();\r\n\t\tconst retryWaiters = new Set();\r\n\t\tlet current;\r\n\t\tlet stopping = false;\r\n\t\tlet ui;\r\n\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\r\n\t\t\tlet command;\r\n\t\t\ttry {\r\n\t\t\t\tcommand = Promise.resolve(\r\n\t\t\t\t\trunSptCommand(args, input, {\r\n\t\t\t\t\t\tsignal: controller.signal,\r\n\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t}),\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r","truncated":true,"truncatedBy":"lines","totalLines":790,"totalBytes":3799,"outputLines":115,"outputBytes":3799,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"export function runSpt(args, input, overrides = {}) {\n…\n\treturn new Promise((resolve, reject) => {\n…\n\t\tif (input !== undefined) {\n\t\t\ttry {\n…\n\t\t\t} catch (error) {\r\n\t\t\t\tvoid terminateAndReject(error);\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}\r\n\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r\n\tconst shutdownBudgetMs =\r\n\t\toverrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;\r\n\tconst requestedShutdownCommandTimeoutMs =\r\n\t\toverrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS;\r\n\tconst terminationWindowMs = killGraceMs + killForceMs;\r\n\tconst maxShutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.floor((shutdownBudgetMs - 3 * terminationWindowMs) / 2),\r\n\t);\r\n\tconst shutdownCommandTimeoutMs = Math.max(\r\n\t\t1,\r\n\t\tMath.min(requestedShutdownCommandTimeoutMs, maxShutdownCommandTimeoutMs),\r\n\t);\r\n\tconst listenerBufferLimit =\r\n\t\toverrides.listenerBufferLimit ?? DEFAULT_LISTENER_BUFFER_LIMIT;\r\n\tconst acceptedQueueLimit =\r\n\t\toverrides.acceptedQueueLimit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;\r\n\tconst acceptedBytesLimit =\r\n\t\toverrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;\r\n\tconst restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];\r\n\tconst outcomeRetryDelaysMs = [\r\n\t\t...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),\r\n\t];\r\n\tconst sessionEndRetryDelaysMs = [\r\n\t\t...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),\r\n\t];\r\n\tconst listenerStableMs =\r\n\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n\t\tlet listenerBuffer = \"\";\r\n\t\tlet listenerRestartCount = 0;\r\n\t\tlet listenerStableTimer;\r\n\t\tlet restartTimer;\r\n\t\tlet dispatchTimer;\r\n\t\tlet bindPromise;\r\n\t\tlet agentActive = false;\r\n\t\tlet desiredState = \"idle\";\r\n\t\tlet dispatching = false;\r\n\t\tlet turnCompletionPromise;\r\n\t\tlet listenerTerminationPromise;\r\n\t\tlet shutdownMode = false;\r\n\t\tlet shutdownDeadlineExpired = false;\r\n\t\tconst activeCommands = new Map();\r\n\t\tconst retryWaiters = new Set();\r\n\t\tlet current;\r\n\t\tlet stopping = false;\r\n\t\tlet ui;\r\n\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\r\n\t\t\tlet command;\r\n\t\t\ttry {\r\n\t\t\t\tcommand = Promise.resolve(\r\n\t\t\t\t\trunSptCommand(args, input, {\r\n\t\t\t\t\t\tsignal: controller.signal,\r\n\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t}),\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n…\n\t\t\t}\n…\n\t\t}\n…\n\t};\n}","startLine":388,"lineNumbers":[388,null,404,null,506,507,null,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,null,626,null,668,null,1294,1295]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1298,"totalBytes":3799,"outputLines":115,"outputBytes":3799,"shownRange":{"start":509,"end":623},"nextOffset":624}}},"isError":false,"timestamp":1784189746139}}
{"type":"message","id":"055ab1f9","parentId":"2a7c88af","timestamp":"2026-07-16T08:30:47.304Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding update fetch timeout and config options**","thinkingSignature":"{\"id\":\"rs_01fde436e88425e0016a58933489f8819bb452766346273fd8\",\"type\":\"reasoning\",\"content\":[],\"encrypted_content\":\"gAAAAABqWJM36PJUOFkyakADokW64YVHH7SvA4s8Psz8wPR-QEDcdmHunZi5OdtrjG5GJC2Azn7EBvnx9JuQX2pD5UOYmUqA5meCPd8e9wMQtiGTrx8ZbAlgDzQqTnVv3bybQcg7NhAcpVlPmGreEb9fcq7bF0YoxgYekIOv8bLlPSwuygbfWJjsLqggwvy2ElsXXqo09P2jiImUijghXtL6QzhUAM8eZZpzFo_E_5bxLgmn7EMdS57jf9XfcQNqdQlvWJ8ssKGhMQP6SA8N0KCyxmIYXKVSA2_NS6SKcRPHN-5I-W1fe3fT6_uEz-lrcbnfX8RNDQUz9C9_QyxvxbbDU_bpzeZ2IOzMkv_E-lwMo4iWcgcbKoGDc9mjiEXNfsAzYip__0KLRKbsP1Op9z2r5_8OpedXjLKZldB1Sh4AstIoJV1MnF6GczADPbGXoyx95OHTsGUsk_Js5Sk6KiwTaPzWRG4niG4Hutnbo-ViXYW_XKN3-at0ON4x91EcDHbyA739qWJuJSkgz0feVUmbcA2BMs8e1uewrTR0Ikokyd7OoVedqtlJrfvtebARhI2QD0b7r1YPwCVm5UZ0EIkA4DG2jw3SVpTDhcRmZtx9lwl5AEsxNRt-jtt3mKLaurt3QMLTtSwbgYrMT-NkmVK7oK9clLCC_iT6HgdavJmq6MOf2M5CZu4qhyO3d1tSj7NrjCDttx_HS3E8oLMZ_8SPTSOulWbR64HA8-dAWXDvgSc6LcTfJ0YcxSbyPmLRQmCjPyy1RGb0Cp65HSiixSR_wNcvFc9Q4srTBxZk4OueI5uzlgApAEevuka9KzZkIamaZlDoUPXRVvdLmxeuvGHwYVdcjuaJIeEcAOVMNWPOi2z0wIxPqayDHveH92P-QGTQrt9yqOgVuip9RV1RxRxH_sfwYM8Ho-gF59QW5Foh8emaDh9w3VAm7wXueRTHqAMP24XdOyWxXjd0E-f_OmlKxH2vtr_xYLlyQgPOVnSTX3kQfsNsHglFreR75PtHyYdUVfmMmtxWaLCs1dTVRFChQhhjWM9EWC7HeFWrlhMQchqf1sIjUhqWlKpBViFoP6h5gyhDjuFDgokA8sWE1KrtUScEnx2r6L2bpXgobwslKZlOEJ4q3Hiidirx0cgqW_igAZm5rposi1Zmwb5dp-uFBK3FX77Iz0PS-dT5gEW-Exr_M5P3w65ygbpcF__9SD5II9Cl5lDuTNmhkHnx_2a1dneL6JCWwvD2cD3uRt3y8iYJX5PEbW3K2fI0eR6QHo5kIz7YXrJsdAkwleYIZuNGE7VGrs4fJTuGhuBBhzi5LxGg7l5bfD5jsWbu_x2z3BCx5A72M5ip5QlBbfc3ayp2sxhoKGw40Cj4Th4Ctx1LJO2DIscf8QqvbKy4ysiKN3CcBdVUznjMkBHWSD0oZEz09f52fCsMOtaCnWtEPG4b5XuR3CtxLsUhs0kN6xfSdEmcbYXvGp5UENt_MchUr_J-pwG7v8owocMHN7_fzsZIrIA97RZ8ZTyemY4dyptdsVB4d6yxPsDs2emsxLQQvX7fWuWzvzS5ID6W5ERdaSNtZFCc-Mg3YVSevXjOOYIuWUAhHGyy0UvOblRNyyU4oCwE6zAgVVkkUlaF26OU9f6pGsUUkHe8hOE_j95vKyKTxnK_VxFOEmdZW90IJKizLlsPn4UXczeqZw==\",\"summary\":[{\"type\":\"summary_text\",\"text\":\"**Adding update fetch timeout and config options**\"}]}"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0,"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"total":0}},"stopReason":"error","timestamp":1784189746155,"errorId":135168,"errorMessage":"The socket connection was closed unexpectedly. For more information, pass `verbose: true` in the second argument to fetch()","duration":901148.2336000002,"stopDetails":{"type":"stream_interrupted_after_content","category":null,"explanation":"The socket connection was closed unexpectedly. For more information, pass `verbose: true` in the second argument to fetch()"},"retryRecovery":{"kind":"auto-retry","status":"recovered","attempt":1,"recoveredAt":"2026-07-16T08:31:04.961Z","recovery":"plain","note":"error; retried","supersededBy":{"timestamp":1784190647847,"provider":"openai-codex","model":"gpt-5.6-sol","responseId":"resp_06d8ce471a892f46016a5896b83934819ba756fb689dac3587"}}}}
{"type":"message","id":"8695df2d","parentId":"055ab1f9","timestamp":"2026-07-16T08:31:04.959Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Implementing update check options**"},{"type":"toolCall","id":"call_Z5DX72lI0j1W83PvxavJLT9E|ctc_06d8ce471a892f46016a5896bbae28819ba3133adfed14bf31","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#5412]\nINS.POST 565:\n+\tconst checkUpdates = overrides.checkUpdates ?? true;\n+\tconst updateProbeTimeoutMs = overrides.updateProbeTimeoutMs ?? 1_500;\n+\tconst fetchLatestAdapterVersion =\n+\t\toverrides.fetchLatestAdapterVersion ??\n+\t\t(async () => {\n+\t\t\tconst controller = new AbortController();\n+\t\t\tconst timer = setTimer(() => controller.abort(), updateProbeTimeoutMs);\n+\t\t\ttimer?.unref?.();\n+\t\t\ttry {\n+\t\t\t\tconst response = await fetch(\n+\t\t\t\t\t\"https://api.github.com/repos/BigscreenVR/omp-spt/releases/latest\",\n+\t\t\t\t\t{\n+\t\t\t\t\t\theaders: { accept: \"application/vnd.github+json\" },\n+\t\t\t\t\t\tsignal: controller.signal,\n+\t\t\t\t\t},\n+\t\t\t\t);\n+\t\t\t\tif (!response.ok) return undefined;\n+\t\t\t\treturn (await response.json())?.tag_name;\n+\t\t\t} catch {\n+\t\t\t\treturn undefined;\n+\t\t\t} finally {\n+\t\t\t\tclearTimer(timer);\n+\t\t\t}\n+\t\t});\n+\n+\tconst checkpointParameters = (pi) => {\n+\t\tconst z = pi.zod?.z ?? pi.zod;\n+\t\treturn z.object({\n+\t\t\twake: z\n+\t\t\t\t.string()\n+\t\t\t\t.optional()\n+\t\t\t\t.describe(\"Instruction for the first continuation after native context compaction\"),\n+\t\t});\n+\t};\n+\n+\tconst endpointIdPattern = /^[A-Za-z0-9_-]+$/;\n+\n+\tconst commandCompletions = (cachedIds, includeAuto) => (prefix) => {\n+\t\tconst values = includeAuto ? [\"--auto\", ...cachedIds] : [...cachedIds];\n+\t\tconst matches = values\n+\t\t\t.filter((value) => value.startsWith(prefix.trim()))\n+\t\t\t.map((value) => ({ value, label: value }));\n+\t\treturn matches.length > 0 ? matches : null;\n+\t};\n+\n+\tfunction normalizePath(value) {\n+\t\treturn String(value ?? \"\")\n+\t\t\t.replaceAll(\"\\\\\", \"/\")\n+\t\t\t.replace(/\\/+$/, \"\")\n+\t\t\t.toLowerCase();\n+\t}\n+\n+\tfunction latestDigestTimestamp(digest) {\n+\t\tlet latest = Number.NEGATIVE_INFINITY;\n+\t\tfor (const turn of digest?.turns ?? []) {\n+\t\t\tfor (const entry of turn?.entries ?? []) {\n+\t\t\t\tfor (const value of Object.values(entry ?? {})) {\n+\t\t\t\t\tconst parsed = Date.parse(value?.ts ?? \"\");\n+\t\t\t\t\tif (Number.isFinite(parsed)) latest = Math.max(latest, parsed);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\treturn latest;\n+\t}\n+\n+\tfunction newestCoreUpdate(rawNotifications, currentVersion) {\n+\t\tconst notifications = parseJson(rawNotifications, \"spt notif list\").notifs ?? [];\n+\t\tlet newest;\n+\t\tfor (const notification of notifications) {\n+\t\t\tif (\n+\t\t\t\tnotification?.from_id !== \"spt-update\" ||\n+\t\t\t\tnotification?.kind !== \"consent\" ||\n+\t\t\t\tnotification?.state === \"dismissed\"\n+\t\t\t) {\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tconst version = parseVersion(notification.head);\n+\t\t\tif (!version || compareVersions(version, currentVersion) <= 0) continue;\n+\t\t\tif (!newest || compareVersions(version, newest) > 0) newest = version;\n+\t\t}\n+\t\treturn newest;\n+\t}\n+\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":915,"output":812,"cacheRead":165376,"cacheWrite":0,"totalTokens":167103,"reasoningTokens":62,"cost":{"input":0.004575,"output":0.02436,"cacheRead":0.082688,"cacheWrite":0,"total":0.111623}},"stopReason":"toolUse","timestamp":1784190647847,"responseId":"resp_06d8ce471a892f46016a5896b83934819ba756fb689dac3587","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_06d8ce471a892f46016a5896ba09f0819ba68a2febddf890c3","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJa7ZrH_EYVrHWMmu4raoS6xF0n8YHPtR0PyjrOHoZMZSNDuxA-9EuRnZQ6IdkvfyOWll8KpzEYc0GTMQhgqppTDIFrAIDtU1KyDIjaYA27fY_jHSG8i3IaRpuKiioBNG6C2CuVJZTE7Wu5Qs2l_5lxUC4V8QHhte_Gm0ty7GVkb7WfzEQbzPX_WkxgykCu_Rvlu_BV2MbvR6G4eKqNCWMy77BuhR--lEBBhfZO8STk1QenbQgsSO3D9OMaUWQYgmo1ZQtR0DFCy96nSy50rGgvle8h0M17KQ9kddOlZMI6ycuhNRBBJ0zI-rEBhpYUgr_zX-n1WTKntwbZiGJbmlaM5IctO2n3IEh0t89dN5E3nk-I57Yasa9mmuKSBmcxV-lykt-7v0MedrfNv3z8cfiHRPeIq6TqM3ITmvKLpV2CuzuRYbPDCopMs8UNH0sP01j2HGalMkWlTNQrimc331q_TgLS54vG17r-xOxAdiSYXmezt2MvgiVrckwCbzZla3XycDYdRTFNQMRqgrrjRGMvqx0A6lBkp0oumWAxemVDGokCbbSzNIbggAv4vdPDx7LThvb2gTe4kSH6AgcrFNxBUwzTkURB50LO-Tke5ON-toPj3Lf0nof0a-XjeBTTwNdglcB9f5iRaxcUNvkvJi6G1QvrELr6udoth6XAgasFN7SjwnPMXUofqdQIbV5gsHM9H1oe3g2uWGS4u309eDLK1SyC9SHTOFsqDbKwLDLvibh5GvkweQ5Hngn3ZYr-inOvczQ6Z_vyWpZfAhnN9ynIzBLtw8MdhKzKleWPufNymMgkYl1euqeG23hj2CfnKV9Kr8qhp3xhMkbW3Ew6REQV9jjWQ46dP3RmOT6XTHtA7kwGXADFskwgQIYTCS2Kr-Ccn7Pj52pH9sVwkZfAU3kp39tvpHybnTGC51OcBTZK16c9IeHjGxh4FBu-ABqvD1oVZWdN5bZewQgSKx9tpBynLJ8tzcmChsel1om3XaLnXdqNv5ur34OhfmUIK0GOLv64blmcW014dc_5geuvXewavii6GsTEuwLEr_eBbamt0uPsPJ2ZCj9XGqQkkuOuK21gUj0nyayqSNSBdKNqCoqDWptOuBb9fe0gWdScofiRCRuAJ_hefKu95EajdRitcWHEaJqGGt6NDwBtmt55mO7Sj4ONxGFJs-tAkmU5NUfj8LSSpNEXLEGEopuzqhV04a74-QDHylcCNycFpNuKNhIhIweBZfBYo7Ajn3KfpAGq6Sm3wVokx0rQD7J3V-y037FkG3KmZZJGKxw4GvTPOlNY6Yg==","summary":[{"type":"summary_text","text":"**Implementing update check options**"}]},{"id":"ctc_06d8ce471a892f46016a5896bbae28819ba3133adfed14bf31","type":"custom_tool_call","status":"completed","call_id":"call_Z5DX72lI0j1W83PvxavJLT9E","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#5412]\nINS.POST 565:\n+\tconst checkUpdates = overrides.checkUpdates ?? true;\n+\tconst updateProbeTimeoutMs = overrides.updateProbeTimeoutMs ?? 1_500;\n+\tconst fetchLatestAdapterVersion =\n+\t\toverrides.fetchLatestAdapterVersion ??\n+\t\t(async () => {\n+\t\t\tconst controller = new AbortController();\n+\t\t\tconst timer = setTimer(() => controller.abort(), updateProbeTimeoutMs);\n+\t\t\ttimer?.unref?.();\n+\t\t\ttry {\n+\t\t\t\tconst response = await fetch(\n+\t\t\t\t\t\"https://api.github.com/repos/BigscreenVR/omp-spt/releases/latest\",\n+\t\t\t\t\t{\n+\t\t\t\t\t\theaders: { accept: \"application/vnd.github+json\" },\n+\t\t\t\t\t\tsignal: controller.signal,\n+\t\t\t\t\t},\n+\t\t\t\t);\n+\t\t\t\tif (!response.ok) return undefined;\n+\t\t\t\treturn (await response.json())?.tag_name;\n+\t\t\t} catch {\n+\t\t\t\treturn undefined;\n+\t\t\t} finally {\n+\t\t\t\tclearTimer(timer);\n+\t\t\t}\n+\t\t});\n+\n+\tconst checkpointParameters = (pi) => {\n+\t\tconst z = pi.zod?.z ?? pi.zod;\n+\t\treturn z.object({\n+\t\t\twake: z\n+\t\t\t\t.string()\n+\t\t\t\t.optional()\n+\t\t\t\t.describe(\"Instruction for the first continuation after native context compaction\"),\n+\t\t});\n+\t};\n+\n+\tconst endpointIdPattern = /^[A-Za-z0-9_-]+$/;\n+\n+\tconst commandCompletions = (cachedIds, includeAuto) => (prefix) => {\n+\t\tconst values = includeAuto ? [\"--auto\", ...cachedIds] : [...cachedIds];\n+\t\tconst matches = values\n+\t\t\t.filter((value) => value.startsWith(prefix.trim()))\n+\t\t\t.map((value) => ({ value, label: value }));\n+\t\treturn matches.length > 0 ? matches : null;\n+\t};\n+\n+\tfunction normalizePath(value) {\n+\t\treturn String(value ?? \"\")\n+\t\t\t.replaceAll(\"\\\\\", \"/\")\n+\t\t\t.replace(/\\/+$/, \"\")\n+\t\t\t.toLowerCase();\n+\t}\n+\n+\tfunction latestDigestTimestamp(digest) {\n+\t\tlet latest = Number.NEGATIVE_INFINITY;\n+\t\tfor (const turn of digest?.turns ?? []) {\n+\t\t\tfor (const entry of turn?.entries ?? []) {\n+\t\t\t\tfor (const value of Object.values(entry ?? {})) {\n+\t\t\t\t\tconst parsed = Date.parse(value?.ts ?? \"\");\n+\t\t\t\t\tif (Number.isFinite(parsed)) latest = Math.max(latest, parsed);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\treturn latest;\n+\t}\n+\n+\tfunction newestCoreUpdate(rawNotifications, currentVersion) {\n+\t\tconst notifications = parseJson(rawNotifications, \"spt notif list\").notifs ?? [];\n+\t\tlet newest;\n+\t\tfor (const notification of notifications) {\n+\t\t\tif (\n+\t\t\t\tnotification?.from_id !== \"spt-update\" ||\n+\t\t\t\tnotification?.kind !== \"consent\" ||\n+\t\t\t\tnotification?.state === \"dismissed\"\n+\t\t\t) {\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tconst version = parseVersion(notification.head);\n+\t\t\tif (!version || compareVersions(version, currentVersion) <= 0) continue;\n+\t\t\tif (!newest || compareVersions(version, newest) > 0) newest = version;\n+\t\t}\n+\t\treturn newest;\n+\t}\n+\n*** End Patch\n","name":"edit"}]},"duration":17110.221900000004,"ttft":2175.22070000018,"contextSnapshot":{"promptTokens":166291,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Z5DX72lI0j1W83PvxavJLT9E|ctc_06d8ce471a892f46016a5896bbae28819ba3133adfed14bf31","toolName":"edit","startedAt":"2026-07-16T08:31:04.962Z"},"id":"987d97d4","parentId":"8695df2d","timestamp":"2026-07-16T08:31:04.962Z"}
{"type":"message","id":"582134f0","parentId":"987d97d4","timestamp":"2026-07-16T08:31:05.080Z","message":{"role":"toolResult","toolCallId":"call_Z5DX72lI0j1W83PvxavJLT9E|ctc_06d8ce471a892f46016a5896bbae28819ba3133adfed14bf31","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#13DF]\n564:\tconst listenerStableMs =\n565:\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\n566:\tconst checkUpdates = overrides.checkUpdates ?? true;\n567:\tconst updateProbeTimeoutMs = overrides.updateProbeTimeoutMs ?? 1_500;\n…\n588:\t\t\t}\n589:\t\t});\n590:\n591:\tconst checkpointParameters = (pi) => {\n592:\t\tconst z = pi.zod?.z ?? pi.zod;\n…\n648:\n649:\n650:\treturn function ompSpt(pi) {\n651:\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n\n1377:\t};"}],"details":{"diff":" 564|\tconst listenerStableMs =\n 565|\t\toverrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);\n+566|\tconst checkUpdates = overrides.checkUpdates ?? true;\n+567|\tconst updateProbeTimeoutMs = overrides.updateProbeTimeoutMs ?? 1_500;\n+568|\tconst fetchLatestAdapterVersion =\n+569|\t\toverrides.fetchLatestAdapterVersion ??\n+570|\t\t(async () => {\n+571|\t\t\tconst controller = new AbortController();\n+572|\t\t\tconst timer = setTimer(() => controller.abort(), updateProbeTimeoutMs);\n+573|\t\t\ttimer?.unref?.();\n+574|\t\t\ttry {\n+575|\t\t\t\tconst response = await fetch(\n+576|\t\t\t\t\t\"https://api.github.com/repos/BigscreenVR/omp-spt/releases/latest\",\n+577|\t\t\t\t\t{\n+578|\t\t\t\t\t\theaders: { accept: \"application/vnd.github+json\" },\n+579|\t\t\t\t\t\tsignal: controller.signal,\n+580|\t\t\t\t\t},\n+581|\t\t\t\t);\n+582|\t\t\t\tif (!response.ok) return undefined;\n+583|\t\t\t\treturn (await response.json())?.tag_name;\n+584|\t\t\t} catch {\n+585|\t\t\t\treturn undefined;\n+586|\t\t\t} finally {\n+587|\t\t\t\tclearTimer(timer);\n+588|\t\t\t}\n+589|\t\t});\n 566|\n+591|\tconst checkpointParameters = (pi) => {\n+592|\t\tconst z = pi.zod?.z ?? pi.zod;\n+593|\t\treturn z.object({\n+594|\t\t\twake: z\n+595|\t\t\t\t.string()\n+596|\t\t\t\t.optional()\n+597|\t\t\t\t.describe(\"Instruction for the first continuation after native context compaction\"),\n+598|\t\t});\n+599|\t};\n+600|\n+601|\tconst endpointIdPattern = /^[A-Za-z0-9_-]+$/;\n+602|\n+603|\tconst commandCompletions = (cachedIds, includeAuto) => (prefix) => {\n+604|\t\tconst values = includeAuto ? [\"--auto\", ...cachedIds] : [...cachedIds];\n+605|\t\tconst matches = values\n+606|\t\t\t.filter((value) => value.startsWith(prefix.trim()))\n+607|\t\t\t.map((value) => ({ value, label: value }));\n+608|\t\treturn matches.length > 0 ? matches : null;\n+609|\t};\n+610|\n+611|\tfunction normalizePath(value) {\n+612|\t\treturn String(value ?? \"\")\n+613|\t\t\t.replaceAll(\"\\\\\", \"/\")\n+614|\t\t\t.replace(/\\/+$/, \"\")\n+615|\t\t\t.toLowerCase();\n+616|\t}\n+617|\n+618|\tfunction latestDigestTimestamp(digest) {\n+619|\t\tlet latest = Number.NEGATIVE_INFINITY;\n+620|\t\tfor (const turn of digest?.turns ?? []) {\n+621|\t\t\tfor (const entry of turn?.entries ?? []) {\n+622|\t\t\t\tfor (const value of Object.values(entry ?? {})) {\n+623|\t\t\t\t\tconst parsed = Date.parse(value?.ts ?? \"\");\n+624|\t\t\t\t\tif (Number.isFinite(parsed)) latest = Math.max(latest, parsed);\n+625|\t\t\t\t}\n+626|\t\t\t}\n+627|\t\t}\n+628|\t\treturn latest;\n+629|\t}\n+630|\n+631|\tfunction newestCoreUpdate(rawNotifications, currentVersion) {\n+632|\t\tconst notifications = parseJson(rawNotifications, \"spt notif list\").notifs ?? [];\n+633|\t\tlet newest;\n+634|\t\tfor (const notification of notifications) {\n+635|\t\t\tif (\n+636|\t\t\t\tnotification?.from_id !== \"spt-update\" ||\n+637|\t\t\t\tnotification?.kind !== \"consent\" ||\n+638|\t\t\t\tnotification?.state === \"dismissed\"\n+639|\t\t\t) {\n+640|\t\t\t\tcontinue;\n+641|\t\t\t}\n+642|\t\t\tconst version = parseVersion(notification.head);\n+643|\t\t\tif (!version || compareVersions(version, currentVersion) <= 0) continue;\n+644|\t\t\tif (!newest || compareVersions(version, newest) > 0) newest = version;\n+645|\t\t}\n+646|\t\treturn newest;\n+647|\t}\n+648|\n+649|\n 567|\treturn function ompSpt(pi) {\n 568|\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n\n 1294|\t};","firstChangedLine":565,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190665079}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `MuslRelease`:\n\nAre you editing adapter/omp-spt.toml? Its [update] comment still says archive contains 'both supported target binaries'; musl makes that stale. If you own manifest, please change to 'all three supported target binaries'. Otherwise I can do the comment-only fix after you finish.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"MuslRelease\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531cd49f81b796e","from":"MuslRelease","message":"Are you editing adapter/omp-spt.toml? Its [update] comment still says archive contains 'both supported target binaries'; musl makes that stale. If you own manifest, please change to 'all three supported target binaries'. Otherwise I can do the comment-only fix after you finish."},"attribution":"agent","id":"a57e93ba","parentId":"582134f0","timestamp":"2026-07-16T08:31:05.132Z"}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `MuslRelease`:\n\nCleanup search found only adapter/omp-spt.toml:23 stale ('both supported target binaries'). Are you changing that file now? Reply yes/no; if yes please make it 'all three supported target binaries'.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"MuslRelease\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531ce4090db7978","from":"MuslRelease","message":"Cleanup search found only adapter/omp-spt.toml:23 stale ('both supported target binaries'). Are you changing that file now? Reply yes/no; if yes please make it 'all three supported target binaries'."},"attribution":"agent","id":"e6c9522f","parentId":"a57e93ba","timestamp":"2026-07-16T08:31:05.132Z"}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `MuslRelease`:\n\nI made the isolated adapter/omp-spt.toml:23 comment correction ('all three supported target binaries plus shared native plugin') after two coordination pings and no response. No behavioral manifest fields changed; preserve that line if your later edit touches the file.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"MuslRelease\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531cee4215b797c","from":"MuslRelease","message":"I made the isolated adapter/omp-spt.toml:23 comment correction ('all three supported target binaries plus shared native plugin') after two coordination pings and no response. No behavioral manifest fields changed; preserve that line if your later edit touches the file."},"attribution":"agent","id":"182207c1","parentId":"e6c9522f","timestamp":"2026-07-16T08:31:05.132Z"}
{"type":"message","id":"964d10de","parentId":"182207c1","timestamp":"2026-07-16T08:31:08.903Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_Txq19C7qs1AmiaRRu1RX9xPT|fc_08508bc02f1b7f3e016a5896cbafa081988a322664e9d9db70","name":"irc","arguments":{"i":"Acknowledging manifest ownership","op":"send","to":"MuslRelease","message":"Acknowledged; I am not touching adapter/omp-spt.toml. Your isolated comment correction is safe.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2316,"output":97,"cacheRead":165376,"cacheWrite":0,"totalTokens":167789,"reasoningTokens":18,"cost":{"input":0.011580000000000002,"output":0.0029100000000000003,"cacheRead":0.082688,"cacheWrite":0,"total":0.097178}},"stopReason":"toolUse","timestamp":1784190665154,"responseId":"resp_08508bc02f1b7f3e016a5896c988b881988b55ce5d5a83c2ef","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_08508bc02f1b7f3e016a5896caf9748198bfa7d87654355646","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJbLCdgc9heDKHWwv-NVub_7dtWRfwjY17cEv6JbwkZUHRnBBjQfNfMFFq9VH5y_icJRb0xXdGYLP1QhUoF2FaEYjkDls8HDWLv0gRKxZM7VEjqbrKOCMhAc6Guc8JYUpQCCKwiXsC1wktBI35TaPnfCzrJtJEbQqwrpJ5ck4bL9yCmT1dlULbsJrbdcmJf0xBU2auQlFxpvGk97mriH6XPwoVk3zwNKaR9iZ25qo_vNVtvd2BiLh4yXyH7COo9ESInWSVAMMW6z0qaGS41G1BAVMAqHFYlNtqmehbJ5UWGIcVSfkUUIxvLYS2eOLhT43fFzpYFp9hn0hgH0nYiOcp2Nd4Sd6wKKrhYxXOlk0C2bldnEyemCb1rnUTgWpcT90nyJoYPP80c5uCNfCKJrBlJDeYOsxKh34QEFlTErIwUT3N1CejFNe6-sorAogXtp-V3syOBVwRWSv1T9i0bYLgWvBNIJKUfJi29vxEGEWXluHAMREC1N4CLJTb89xEXUWvEmvDnO2uY1whXyUNaN1Xw3LI9R5iCVqEch_SPNbSqwLGQlB_ilvP58Mg-DQAlC0tUWUSNnqOrDk8c_it5ch0z19BAWppx6G8ixNXeTa2O6NXpVEe6p3CnbrehsT0vOI6wTVLbN9vjD4b7OSgZzMfBTIdZIPpvpPhFwOOkKl6yjU4M0naWh77ccDsvMQhrm9LDWFt8PxE4eTUnOmKSpcMq2nTFNufv4IRb7RNly0Wz5vomdKOExJnsi4gQFqvLyC6vNErNOyZqwG-nEKU_g6b7DYp7hFiALEX6_gzNkgJd_ZJcTOrEtpoWlddAcB-nYpYp_9VzWU8fOGiJ6gdj8YRl8851TAuM5jFZSfvKJ4-fN-ihJEdfk9vWMIu_ywSqInSAiX1W58i_2vLK_CVU7AsLhukoNwGsBdGEOqrD7ZcsWIXsbjj-CvMlge7pOnWSXjh2mloKDG4Fa3VQ0-uSvp1Biq4vGjugnLHcU8sRvGLRYS6g=","summary":[]},{"id":"fc_08508bc02f1b7f3e016a5896cbafa081988a322664e9d9db70","type":"function_call","status":"completed","arguments":"{\"i\":\"Acknowledging manifest ownership\",\"op\":\"send\",\"to\":\"MuslRelease\",\"message\":\"Acknowledged; I am not touching adapter/omp-spt.toml. Your isolated comment correction is safe.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_Txq19C7qs1AmiaRRu1RX9xPT","name":"irc"}]},"duration":3735.029799999902,"ttft":1806.68889999995,"contextSnapshot":{"promptTokens":167692,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Txq19C7qs1AmiaRRu1RX9xPT|fc_08508bc02f1b7f3e016a5896cbafa081988a322664e9d9db70","toolName":"irc","startedAt":"2026-07-16T08:31:08.904Z","intent":"Acknowledging manifest ownership"},"id":"fccc8045","parentId":"964d10de","timestamp":"2026-07-16T08:31:08.904Z"}
{"type":"message","id":"8b4259d7","parentId":"fccc8045","timestamp":"2026-07-16T08:31:08.905Z","message":{"role":"toolResult","toolCallId":"call_Txq19C7qs1AmiaRRu1RX9xPT|fc_08508bc02f1b7f3e016a5896cbafa081988a322664e9d9db70","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- MuslRelease: woken"}],"details":{"op":"send","from":"NativeExtension","to":"MuslRelease","receipts":[{"to":"MuslRelease","outcome":"woken"}]},"isError":false,"timestamp":1784190668905}}
{"type":"message","id":"5d71f98e","parentId":"8b4259d7","timestamp":"2026-07-16T08:31:12.342Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning precise text replacement**"},{"type":"toolCall","id":"call_zY8NEgibvgnBlGUnFbKQmn8B|fc_0d29a396780baea2016a5896cfeff0819899f45507c891ec1d","name":"read","arguments":{"i":"Reading extension state after insert","path":"adapter/strings/omp-spt.mjs","selector":"645-715"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":390,"output":58,"cacheRead":167424,"cacheWrite":0,"totalTokens":167872,"reasoningTokens":17,"cost":{"input":0.0019500000000000001,"output":0.00174,"cacheRead":0.083712,"cacheWrite":0,"total":0.087402}},"stopReason":"toolUse","timestamp":1784190668985,"responseId":"resp_0d29a396780baea2016a5896cd87048198b115f67bca769fd0","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0d29a396780baea2016a5896cf223c8198a3593227f4bc7dbd","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJbPXLEaKxNwkrQdEST3yP3DmNri4OVuL71BPyS9P0oyQh76To2yAkYkoUFp5SDQvmKaBKFmVHcAD4p1VU4ircpQHsmXerLDE0OnAcDeNTukHdkURu8lwqMeNBapCUtKgcBEYZa9706IB2oScLebjtmehbdG7t9kuow0kRJmsm5fs3W-HKFNNIckDKKSdaJQ8s-pG44ir7c72V1fG9aBnJeLD_fbjedlds32pFYhWrj6cfEcLaoVDvy0tjihoRovU5WIws6Mp0RUPQCto-hZ8nZHGQAT-43FPFhYQwvWM1j_bgMHT5SKflNW8AEsYOnV7kldBPQ-T6fMXsTpTUY1kmvyu1ChzE__yuABlRAHCsk84C_-YYI7E4gb66BSC0-0FjEhq76yac02MAXLj0k4E8FW4GAGa6P7GVgfFgjoV8oW4Kn58ywQ2ExrIZM2OWaHOIiSdvdUiHH5CWUoezaREgCUyesq3DrNjJFp3qyv-xK2oA8KAdzIMf0gwKSVRYQ5SrcBu22RYOAIHSQOb0e7_Zxs0GBjiazNryrPn0AVRa3gdUFHxsEVg7tnlpn445m5lz8dpTGuM2yTUwiMwKbD08LJpTxp8JkhtbHLSJ6OJzU0DFpkBeir2SAMzxAcUSM8-KpYOVGbADs4pGNWWJZNKb2P0fx7OD4mF9jNmbl3iXU3Cgxhtxiy1-9ejmJhv13viVHPynNJgwZHDbD26Nyz2SIo7tBTc_jctsoXzk10JcfBqmYSqq4JmfcDyhscoa9a0jpdBACZkkCFdJhgA2WnYdGF0YeEVFxwiDi4Cv1W2L6f7_kDDBSRWH_Und-lvV3z-oMQtP7zq94Gme1rmnm020LSXJYlcelMcqROO8W0YhhEwz6SsbfqarHrAxlYXWoAZkTemsSKEsBPQ3O_Rxb6aoSOt90RuC1Iu12bHA870JGO4gQVuo9bYEbPveX3yUa0ZhKKVHzDpw12aYfve_NNAFetmaTHSIXvLm6D2PSkvtAI1OU=","summary":[{"type":"summary_text","text":"**Planning precise text replacement**"}]},{"id":"fc_0d29a396780baea2016a5896cfeff0819899f45507c891ec1d","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension state after insert\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"645-715\"}","call_id":"call_zY8NEgibvgnBlGUnFbKQmn8B","name":"read"}]},"duration":3355.8906999998726,"ttft":2204.716199999908,"contextSnapshot":{"promptTokens":167814,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_zY8NEgibvgnBlGUnFbKQmn8B|fc_0d29a396780baea2016a5896cfeff0819899f45507c891ec1d","toolName":"read","startedAt":"2026-07-16T08:31:12.342Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading extension state after insert"},"id":"560b9b6e","parentId":"5d71f98e","timestamp":"2026-07-16T08:31:12.342Z"}
{"type":"message","id":"d83cfdb9","parentId":"560b9b6e","timestamp":"2026-07-16T08:31:12.378Z","message":{"role":"toolResult","toolCallId":"call_zY8NEgibvgnBlGUnFbKQmn8B|fc_0d29a396780baea2016a5896cfeff0819899f45507c891ec1d","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#13DF]\n631:\tfunction newestCoreUpdate(rawNotifications, currentVersion) {\n…\n634:\t\tfor (const notification of notifications) {\n…\n644:\t\t\tif (!newest || compareVersions(version, newest) > 0) newest = version;\n645:\t\t}\n646:\t\treturn newest;\n647:\t}\n648:\n649:\n650:\treturn function ompSpt(pi) {\n651:\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n652:\t\tif (!id) return;\n653:\n654:\t\tlet sid;\n655:\t\tlet token;\n656:\t\tlet listener;\n657:\t\tlet listenerBuffer = \"\";\n658:\t\tlet listenerRestartCount = 0;\n659:\t\tlet listenerStableTimer;\n660:\t\tlet restartTimer;\n661:\t\tlet dispatchTimer;\n662:\t\tlet bindPromise;\n663:\t\tlet agentActive = false;\n664:\t\tlet desiredState = \"idle\";\n665:\t\tlet dispatching = false;\n666:\t\tlet turnCompletionPromise;\n667:\t\tlet listenerTerminationPromise;\n668:\t\tlet shutdownMode = false;\n669:\t\tlet shutdownDeadlineExpired = false;\n670:\t\tconst activeCommands = new Map();\n671:\t\tconst retryWaiters = new Set();\n672:\t\tlet current;\n673:\t\tlet stopping = false;\n674:\t\tlet ui;\n675:\t\tlet runtimeCtx;\n676:\t\tlet endpointState;\n677:\t\tlet stateOperation = Promise.resolve();\n678:\t\tlet endPromise;\n679:\t\tlet fatalPromise;\n680:\t\tlet teardownPromise;\n681:\t\tlet acceptedBytes = 0;\n682:\t\tlet overflowItem;\n683:\t\tconst queue = [];\n684:\n685:\t\tconst logError = (message, error) => {\n686:\t\t\tpi.logger.error(message, { error: errorSummary(error) });\n687:\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\n688:\t\t};\n689:\n690:\t\tfunction runCommand(args, input, options = {}) {\n691:\t\t\tif (shutdownDeadlineExpired) {\n692:\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\n693:\t\t\t}\n694:\t\t\tconst timeoutMs =\n695:\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\n696:\t\t\tconst controller = new AbortController();\n697:\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\n698:\t\t\tlet command;\n699:\t\t\ttry {\n700:\t\t\t\tcommand = Promise.resolve(\n701:\t\t\t\t\trunSptCommand(args, input, {\n702:\t\t\t\t\t\tsignal: controller.signal,\n703:\t\t\t\t\t\ttimeoutMs,\n704:\t\t\t\t\t}),\n705:\t\t\t\t);\n706:\t\t\t} catch (error) {\n707:\t\t\t\tactiveCommands.delete(controller);\n708:\t\t\t\treturn Promise.reject(error);\n709:\t\t\t}\n710:\t\t\tif (customRunSptCommand) {\n711:\t\t\t\tconst rawCommand = command;\n712:\t\t\t\tcommand = new Promise((resolve, reject) => {\n713:\t\t\t\t\tlet timer;\n714:\t\t\t\t\tlet finished = false;\n715:\t\t\t\t\tconst finish = (error, value) => {\n716:\t\t\t\t\t\tif (finished) return;\n717:\t\t\t\t\t\tfinished = true;\n718:\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n…\n722:\t\t\t\t\t};\n…\n744:\t\t\t\t});\n745:\t\t\t}\n…\n751:\t\t}\n…\n1377:\t};\n\n[Showing lines 644-718 of 1381. Use :719 to continue]"}],"details":{"truncation":{"content":"\t\t\tif (!newest || compareVersions(version, newest) > 0) newest = version;\r\n\t\t}\r\n\t\treturn newest;\r\n\t}\r\n\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n\t\tlet listenerBuffer = \"\";\r\n\t\tlet listenerRestartCount = 0;\r\n\t\tlet listenerStableTimer;\r\n\t\tlet restartTimer;\r\n\t\tlet dispatchTimer;\r\n\t\tlet bindPromise;\r\n\t\tlet agentActive = false;\r\n\t\tlet desiredState = \"idle\";\r\n\t\tlet dispatching = false;\r\n\t\tlet turnCompletionPromise;\r\n\t\tlet listenerTerminationPromise;\r\n\t\tlet shutdownMode = false;\r\n\t\tlet shutdownDeadlineExpired = false;\r\n\t\tconst activeCommands = new Map();\r\n\t\tconst retryWaiters = new Set();\r\n\t\tlet current;\r\n\t\tlet stopping = false;\r\n\t\tlet ui;\r\n\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\r\n\t\t\tlet command;\r\n\t\t\ttry {\r\n\t\t\t\tcommand = Promise.resolve(\r\n\t\t\t\t\trunSptCommand(args, input, {\r\n\t\t\t\t\t\tsignal: controller.signal,\r\n\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t}),\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t\treturn Promise.reject(error);\r\n\t\t\t}\r\n\t\t\tif (customRunSptCommand) {\r\n\t\t\t\tconst rawCommand = command;\r\n\t\t\t\tcommand = new Promise((resolve, reject) => {\r\n\t\t\t\t\tlet timer;\r\n\t\t\t\t\tlet finished = false;\r\n\t\t\t\t\tconst finish = (error, value) => {\r\n\t\t\t\t\t\tif (finished) return;\r\n\t\t\t\t\t\tfinished = true;\r\n\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r","truncated":true,"truncatedBy":"lines","totalLines":738,"totalBytes":2098,"outputLines":75,"outputBytes":2098,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\tfunction newestCoreUpdate(rawNotifications, currentVersion) {\n…\n\t\tfor (const notification of notifications) {\n…\n\t\t\tif (!newest || compareVersions(version, newest) > 0) newest = version;\r\n\t\t}\r\n\t\treturn newest;\r\n\t}\r\n\r\n\r\n\treturn function ompSpt(pi) {\r\n\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\r\n\t\tif (!id) return;\r\n\r\n\t\tlet sid;\r\n\t\tlet token;\r\n\t\tlet listener;\r\n\t\tlet listenerBuffer = \"\";\r\n\t\tlet listenerRestartCount = 0;\r\n\t\tlet listenerStableTimer;\r\n\t\tlet restartTimer;\r\n\t\tlet dispatchTimer;\r\n\t\tlet bindPromise;\r\n\t\tlet agentActive = false;\r\n\t\tlet desiredState = \"idle\";\r\n\t\tlet dispatching = false;\r\n\t\tlet turnCompletionPromise;\r\n\t\tlet listenerTerminationPromise;\r\n\t\tlet shutdownMode = false;\r\n\t\tlet shutdownDeadlineExpired = false;\r\n\t\tconst activeCommands = new Map();\r\n\t\tconst retryWaiters = new Set();\r\n\t\tlet current;\r\n\t\tlet stopping = false;\r\n\t\tlet ui;\r\n\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\r\n\t\t\tlet command;\r\n\t\t\ttry {\r\n\t\t\t\tcommand = Promise.resolve(\r\n\t\t\t\t\trunSptCommand(args, input, {\r\n\t\t\t\t\t\tsignal: controller.signal,\r\n\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t}),\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t\treturn Promise.reject(error);\r\n\t\t\t}\r\n\t\t\tif (customRunSptCommand) {\r\n\t\t\t\tconst rawCommand = command;\r\n\t\t\t\tcommand = new Promise((resolve, reject) => {\r\n\t\t\t\t\tlet timer;\r\n\t\t\t\t\tlet finished = false;\r\n\t\t\t\t\tconst finish = (error, value) => {\r\n\t\t\t\t\t\tif (finished) return;\r\n\t\t\t\t\t\tfinished = true;\r\n\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r\n…\n\t\t\t\t\t};\n…\n\t\t\t\t});\n\t\t\t}\n…\n\t\t}\n…\n\t};","startLine":631,"lineNumbers":[631,null,634,null,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,null,722,null,744,745,null,751,null,1377]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1381,"totalBytes":2098,"outputLines":75,"outputBytes":2098,"shownRange":{"start":644,"end":718},"nextOffset":719}}},"isError":false,"timestamp":1784190672378}}
{"type":"message","id":"e89181c6","parentId":"d83cfdb9","timestamp":"2026-07-16T08:31:17.517Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Refactoring identifier and state handling**"},{"type":"toolCall","id":"call_AngvMhPHCIPU8GyWpFGO1xwW|ctc_01bc2a2fd2a0765c016a5896d32180819980748d367f06be32","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#13DF]\nSWAP 651.=652:\n+\t\tlet id = env.SPT_ENDPOINT_ID?.trim() || undefined;\n+\t\tconst initialId = id;\n+\t\tlet activationType;\n+\t\tlet activationPromise;\n+\t\tlet activated = false;\n+\t\tlet startupBriefPending = false;\n+\t\tlet updateNoticesPromise = Promise.resolve([]);\n+\t\tlet updateNoticesPending = true;\n+\t\tlet cachedReadyIds = [];\n+\t\tlet cachedLiveIds = [];\nINS.POST 662:\n+\t\tlet listenerGeneration = 0;\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1191,"output":153,"cacheRead":167424,"cacheWrite":0,"totalTokens":168768,"reasoningTokens":9,"cost":{"input":0.005955,"output":0.00459,"cacheRead":0.083712,"cacheWrite":0,"total":0.094257}},"stopReason":"toolUse","timestamp":1784190672440,"responseId":"resp_01bc2a2fd2a0765c016a5896d0caf08199acf8cb4cabafac8d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_01bc2a2fd2a0765c016a5896d28c248199a2f5a227df53af88","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJbTqrDVLFXYHkjepE6PUaNNTAhxeonODaTLL2lz2iR7hycYSgjrrq1Z3rq9B0DIJeXTRkZLDIIeSAqkDAPFEHQxHOGWQJDS8QAlIBT6EvA1_300I_HnZFhvS6xD151RKXAlHqUfo_rW9aoeBnJqhJd41_y-R-oDfOwZ_RZePjZ08DjYuNCHEqbS-dAXGqZ-SoI6Z31bVzzBGdbgWteOS-dr0868d4pbjpXjEM-nBaoOZPlDj_Avfdg7p1Vp_Qm1V0xo2F_1jxU5hp99c36TrGOFK-aPFYdblsiF7idyYbOPk8vT2Kknqt0F6gIMMV8S87wfFiqwRGAJkYzNDALhXg4_WazapzyvNadAz9CiD1gJSMSoOYXlXbdp5fZ6aOJEOTwzyvkx-EaMdWn0P_9ia5Q26hEaUu7KLv842dinZnmbcj4-FACs2wKO3bJzdSwgiTPdKD9PVgQU5YzwX3Rb4TQS1K0NBj6K6Pcpwg4NkoFTjDUx4IcFVbayruIqo1ceIqCCLsk3fXYjqgCwQKKOJm8_CADN7J_CMtgFGR9mIVYUImCtGYcP1ZWGIh0nDeSqP1LidfzsFu33wZ-sHUkGf8Hw-8boqA84yN6tQyUztU95z8xD2SShIWhvwPBH1hcVtAe2ZCRv60pkqWAWBF9CqY1kKS9MOthFWZfIztccnRwIsGUpPOkv0kMRnTck9JjSJxAlkWLXYJ6CQHqmk4XegbtbSTdKtUJxHkwIcNP1Cvpe2O-F5mgqil7JaHfbNrmngAWrqkliYk8EjDO8pzbhNInwW7j-kWrflKCx7uaV582fVOmpP0MLTAXGgovEZ16UicZ5UbZ_b-Q75jYgELG7jOeoPgqZ4FF12L2z_Vi9MSZpFalaRV_n49gQH2oGMSyk49dXfuOhjk9MwGv3FXlT4ZDkcLYn-f2xB6J_3bEDQWe0Hj_qkS6t6QVMdAn7x42w9-5Q","summary":[{"type":"summary_text","text":"**Refactoring identifier and state handling**"}]},{"id":"ctc_01bc2a2fd2a0765c016a5896d32180819980748d367f06be32","type":"custom_tool_call","status":"completed","call_id":"call_AngvMhPHCIPU8GyWpFGO1xwW","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#13DF]\nSWAP 651.=652:\n+\t\tlet id = env.SPT_ENDPOINT_ID?.trim() || undefined;\n+\t\tconst initialId = id;\n+\t\tlet activationType;\n+\t\tlet activationPromise;\n+\t\tlet activated = false;\n+\t\tlet startupBriefPending = false;\n+\t\tlet updateNoticesPromise = Promise.resolve([]);\n+\t\tlet updateNoticesPending = true;\n+\t\tlet cachedReadyIds = [];\n+\t\tlet cachedLiveIds = [];\nINS.POST 662:\n+\t\tlet listenerGeneration = 0;\n*** End Patch\n","name":"edit"}]},"duration":5076.532299999846,"ttft":2119.0387999999803,"contextSnapshot":{"promptTokens":168615,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_AngvMhPHCIPU8GyWpFGO1xwW|ctc_01bc2a2fd2a0765c016a5896d32180819980748d367f06be32","toolName":"edit","startedAt":"2026-07-16T08:31:17.519Z"},"id":"1fab3a2c","parentId":"e89181c6","timestamp":"2026-07-16T08:31:17.519Z"}
{"type":"message","id":"365a6111","parentId":"1fab3a2c","timestamp":"2026-07-16T08:31:17.580Z","message":{"role":"toolResult","toolCallId":"call_AngvMhPHCIPU8GyWpFGO1xwW|ctc_01bc2a2fd2a0765c016a5896d32180819980748d367f06be32","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#8E1D]\n649:\n650:\treturn function ompSpt(pi) {\n651:\t\tlet id = env.SPT_ENDPOINT_ID?.trim() || undefined;\n652:\t\tconst initialId = id;\n…\n659:\t\tlet cachedReadyIds = [];\n660:\t\tlet cachedLiveIds = [];\n661:\n662:\t\tlet sid;\n669:\t\tlet dispatchTimer;\n670:\t\tlet bindPromise;\n671:\t\tlet listenerGeneration = 0;\n672:\t\tlet agentActive = false;\n673:\t\tlet desiredState = \"idle\";\n\n1386:\t};"}],"details":{"diff":" 649|\n 650|\treturn function ompSpt(pi) {\n-651|\t\tconst id = env.SPT_ENDPOINT_ID?.trim();\n-652|\t\tif (!id) return;\n+651|\t\tlet id = env.SPT_ENDPOINT_ID?.trim() || undefined;\n+652|\t\tconst initialId = id;\n+653|\t\tlet activationType;\n+654|\t\tlet activationPromise;\n+655|\t\tlet activated = false;\n+656|\t\tlet startupBriefPending = false;\n+657|\t\tlet updateNoticesPromise = Promise.resolve([]);\n+658|\t\tlet updateNoticesPending = true;\n+659|\t\tlet cachedReadyIds = [];\n+660|\t\tlet cachedLiveIds = [];\n 653|\n 654|\t\tlet sid;\n 661|\t\tlet dispatchTimer;\n 662|\t\tlet bindPromise;\n+671|\t\tlet listenerGeneration = 0;\n 663|\t\tlet agentActive = false;\n 664|\t\tlet desiredState = \"idle\";\n\n 1377|\t};","firstChangedLine":651,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190677580}}
{"type":"message","id":"e8d4e024","parentId":"365a6111","timestamp":"2026-07-16T08:31:24.158Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Evaluating listenerGeneration usage**"},{"type":"toolCall","id":"call_o1jq3cA7B2g1YXfDSq8akyN4|fc_0c3f1c8503c75d24016a5896db3864819ba7059e907bb4e9e3","name":"read","arguments":{"i":"Reading command runner boundary","path":"adapter/strings/omp-spt.mjs","selector":"685-785"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":459,"output":111,"cacheRead":168448,"cacheWrite":0,"totalTokens":169018,"reasoningTokens":71,"cost":{"input":0.002295,"output":0.00333,"cacheRead":0.084224,"cacheWrite":0,"total":0.089849}},"stopReason":"toolUse","timestamp":1784190677737,"responseId":"resp_0c3f1c8503c75d24016a5896d6bc20819b86121920fcf848b3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0c3f1c8503c75d24016a5896d93684819bb0622b36bd28fdce","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJbbGR5f-VJxmIWljjSVmlcshQAV069StNJur8H98WdNn8xRyZQO2ElDPYzV34yKNYMFSbHdLbTp85PF61z8wyZM7Tvc-k9fNLA7-4Pd6eAj8r6zJ-lVDe7IvvUWcI0fRVwPvL9CiSErgD2MGUeLq-hXL70osGnKCjiSLbY0T4p2yaD9GVYrVcs93OKYM_23PKjxUuchQtVhbasUstNa8Y_t5DCDHFSNIIg2XRMbMHQ0kkRDw6ZaWbcAmAI6QPhtLShvkFNKPBfCG6tN3KYBJYbW_0_wlDodhrrTSaNSfwYExv6BRhSZoQuJWgcByNYDyUrqTVkmFfWVGoIOvVYad0bDNcvipelEjuPZafwZzPJ2f67KAXkkIhDNdGex3RS99ujH2_Pdm4x4R-J1cidgr7cZ7x9Mp17Kngmo-MoaQRjoKVOM6I_Y5M-h73GUD5L4dRGCl9flPSgSo7PZuQU0xvyQ5UbZnn54V5IK8hWlunmjntL5g3ldX02qqnr25_C0Xra2CtNaro3Y2OWsTB3S4cayOCkY4qzwefCN3ZxxVMUEKZLE6WwM5-08kiqwSC_gCyPSGQujNx9BLetL0Dey3ygx4izXBpe7wtvG99h94gp7kQXWXaKo8xXD4RAawXYrR3WwGFR6GBMePTtixy4gdj1YnID80hlwtQLQxNr8owCN01HQ9YmtZN4oRt7nBcqzH1NEVo1YEXGmCZww00ASeHrFZg4E0A--XsIC8lIGC5S-KvbAPmUC_YOxeSe7xWhg2Mmy_-zainS06hoKAv3xUsRrn9nnZB58u6xiqOED9yZ-PeXFVy62NAq33sm0tDY3kr7HHJ1oQszuPX9RXKE6ftkvm_C5c_d88TWbbML3XMdp3uHmi6C5FARhnPHIPnLsxQvvN_peIMk3n8B1dEYKtHfO3mt-k9vAkUoWUEuR65TbyD0IOOrjqhA3DDVGiCYl7mlyA96XyEb5sNCm0p4iSEatiWEevTy-Tc4NQtK2LlCKF9OPTPVa1-ElqUDXNy016NJMHLvzjdrdh2WK_vLsYc4k1Ft0wjxd3Ik4oidHllgcAwG7TmQUMAbB8YiYxUS15Wfa33PRqSWPRWqITJ-uZX-jzuwBokb2JFcHdMb7diVVteKcEhvLhQxgTrZXGc5CO4aebFw9MeTOHWRJ3LxBZCGNcMloqf9Jq3QMDzAHj2EZ7lEHHPDCB1e8qBTC5mS2EhO6JV-VCw6h19PqNX8TkVJqnAT4-C2je59LDnfWEDb_Duts6v2yCg_OcIABExK7f9TUZwo7xEZH-UsIGkXpS_Br4QmjTvVjF5909u0d13wcnrV1mcVmxqXrJyk7iWBJ-YEe_yi2GaPtTuyaLOKlFFmsbw==","summary":[{"type":"summary_text","text":"**Evaluating listenerGeneration usage**"}]},{"id":"fc_0c3f1c8503c75d24016a5896db3864819ba7059e907bb4e9e3","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading command runner boundary\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"685-785\"}","call_id":"call_o1jq3cA7B2g1YXfDSq8akyN4","name":"read"}]},"duration":6420.40839999984,"ttft":3486.347700000042,"contextSnapshot":{"promptTokens":168907,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_o1jq3cA7B2g1YXfDSq8akyN4|fc_0c3f1c8503c75d24016a5896db3864819ba7059e907bb4e9e3","toolName":"read","startedAt":"2026-07-16T08:31:24.158Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading command runner boundary"},"id":"82b82733","parentId":"e8d4e024","timestamp":"2026-07-16T08:31:24.158Z"}
{"type":"message","id":"24bd63d7","parentId":"82b82733","timestamp":"2026-07-16T08:31:24.191Z","message":{"role":"toolResult","toolCallId":"call_o1jq3cA7B2g1YXfDSq8akyN4|fc_0c3f1c8503c75d24016a5896db3864819ba7059e907bb4e9e3","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#8E1D]\n684:\t\tlet runtimeCtx;\n685:\t\tlet endpointState;\n686:\t\tlet stateOperation = Promise.resolve();\n687:\t\tlet endPromise;\n688:\t\tlet fatalPromise;\n689:\t\tlet teardownPromise;\n690:\t\tlet acceptedBytes = 0;\n691:\t\tlet overflowItem;\n692:\t\tconst queue = [];\n693:\n694:\t\tconst logError = (message, error) => {\n695:\t\t\tpi.logger.error(message, { error: errorSummary(error) });\n696:\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\n697:\t\t};\n698:\n699:\t\tfunction runCommand(args, input, options = {}) {\n700:\t\t\tif (shutdownDeadlineExpired) {\n701:\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\n702:\t\t\t}\n703:\t\t\tconst timeoutMs =\n704:\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\n705:\t\t\tconst controller = new AbortController();\n706:\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\n707:\t\t\tlet command;\n708:\t\t\ttry {\n709:\t\t\t\tcommand = Promise.resolve(\n710:\t\t\t\t\trunSptCommand(args, input, {\n711:\t\t\t\t\t\tsignal: controller.signal,\n712:\t\t\t\t\t\ttimeoutMs,\n713:\t\t\t\t\t}),\n714:\t\t\t\t);\n715:\t\t\t} catch (error) {\n716:\t\t\t\tactiveCommands.delete(controller);\n717:\t\t\t\treturn Promise.reject(error);\n718:\t\t\t}\n719:\t\t\tif (customRunSptCommand) {\n720:\t\t\t\tconst rawCommand = command;\n721:\t\t\t\tcommand = new Promise((resolve, reject) => {\n722:\t\t\t\t\tlet timer;\n723:\t\t\t\t\tlet finished = false;\n724:\t\t\t\t\tconst finish = (error, value) => {\n725:\t\t\t\t\t\tif (finished) return;\n726:\t\t\t\t\t\tfinished = true;\n727:\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n728:\t\t\t\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\n729:\t\t\t\t\t\tif (error === undefined) resolve(value);\n730:\t\t\t\t\t\telse reject(error);\n731:\t\t\t\t\t};\n732:\t\t\t\t\tconst onAbort = () =>\n733:\t\t\t\t\t\tfinish(\n734:\t\t\t\t\t\t\tcontroller.signal.reason instanceof Error\n735:\t\t\t\t\t\t\t\t? controller.signal.reason\n736:\t\t\t\t\t\t\t\t: new Error(`${commandLabel(args)} aborted`),\n737:\t\t\t\t\t\t);\n738:\t\t\t\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\n739:\t\t\t\t\tif (shutdownMode) {\n740:\t\t\t\t\t\ttimer = setTimer(\n741:\t\t\t\t\t\t\t() =>\n742:\t\t\t\t\t\t\t\tcontroller.abort(\n743:\t\t\t\t\t\t\t\t\tnew Error(`${commandLabel(args)} timed out after ${timeoutMs}ms`),\n744:\t\t\t\t\t\t\t\t),\n745:\t\t\t\t\t\t\ttimeoutMs,\n746:\t\t\t\t\t\t);\n747:\t\t\t\t\t\ttimer?.unref?.();\n748:\t\t\t\t\t}\n749:\t\t\t\t\trawCommand.then(\n750:\t\t\t\t\t\t(value) => finish(undefined, value),\n751:\t\t\t\t\t\t(error) => finish(error),\n752:\t\t\t\t\t);\n753:\t\t\t\t});\n754:\t\t\t}\n755:\t\t\treturn command.finally(() => {\n756:\t\t\t\tconst active = activeCommands.get(controller);\n757:\t\t\t\tif (active?.abortTimer !== undefined) clearTimer(active.abortTimer);\n758:\t\t\t\tactiveCommands.delete(controller);\n759:\t\t\t});\n760:\t\t}\n761:\n762:\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n763:\t\t\tfor (const [controller, active] of activeCommands) {\n764:\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\n765:\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\n766:\t\t\t\t\tactive.abortTimer = setTimer(\n767:\t\t\t\t\t\t() => controller.abort(reason),\n768:\t\t\t\t\t\tshutdownCommandTimeoutMs,\n769:\t\t\t\t\t);\n770:\t\t\t\t\tactive.abortTimer?.unref?.();\n771:\t\t\t\t\tcontinue;\n772:\t\t\t\t}\n773:\t\t\t\tcontroller.abort(reason);\n774:\t\t\t}\n775:\t\t}\n776:\n777:\t\tfunction waitForRetry(delay) {\n778:\t\t\tif (shutdownMode) return Promise.resolve();\n779:\t\t\treturn new Promise((resolve) => {\n780:\t\t\t\tlet timer;\n781:\t\t\t\tconst finish = () => {\n782:\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\n783:\t\t\t\t\tretryWaiters.delete(finish);\n784:\t\t\t\t\tresolve();\n785:\t\t\t\t};\n786:\t\t\t\tretryWaiters.add(finish);\n787:\t\t\t\ttimer = setTimer(finish, delay);\n788:\t\t\t\ttimer?.unref?.();\n789:\t\t\t});\n790:\t\t}\n\n[Showing lines 684-788 of 1390. Use :789 to continue]"}],"details":{"truncation":{"content":"\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\r\n\t\t\tlet command;\r\n\t\t\ttry {\r\n\t\t\t\tcommand = Promise.resolve(\r\n\t\t\t\t\trunSptCommand(args, input, {\r\n\t\t\t\t\t\tsignal: controller.signal,\r\n\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t}),\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t\treturn Promise.reject(error);\r\n\t\t\t}\r\n\t\t\tif (customRunSptCommand) {\r\n\t\t\t\tconst rawCommand = command;\r\n\t\t\t\tcommand = new Promise((resolve, reject) => {\r\n\t\t\t\t\tlet timer;\r\n\t\t\t\t\tlet finished = false;\r\n\t\t\t\t\tconst finish = (error, value) => {\r\n\t\t\t\t\t\tif (finished) return;\r\n\t\t\t\t\t\tfinished = true;\r\n\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\t\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\r\n\t\t\t\t\t\tif (error === undefined) resolve(value);\r\n\t\t\t\t\t\telse reject(error);\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst onAbort = () =>\r\n\t\t\t\t\t\tfinish(\r\n\t\t\t\t\t\t\tcontroller.signal.reason instanceof Error\r\n\t\t\t\t\t\t\t\t? controller.signal.reason\r\n\t\t\t\t\t\t\t\t: new Error(`${commandLabel(args)} aborted`),\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\r\n\t\t\t\t\tif (shutdownMode) {\r\n\t\t\t\t\t\ttimer = setTimer(\r\n\t\t\t\t\t\t\t() =>\r\n\t\t\t\t\t\t\t\tcontroller.abort(\r\n\t\t\t\t\t\t\t\t\tnew Error(`${commandLabel(args)} timed out after ${timeoutMs}ms`),\r\n\t\t\t\t\t\t\t\t),\r\n\t\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\ttimer?.unref?.();\r\n\t\t\t\t\t}\r\n\t\t\t\t\trawCommand.then(\r\n\t\t\t\t\t\t(value) => finish(undefined, value),\r\n\t\t\t\t\t\t(error) => finish(error),\r\n\t\t\t\t\t);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn command.finally(() => {\r\n\t\t\t\tconst active = activeCommands.get(controller);\r\n\t\t\t\tif (active?.abortTimer !== undefined) clearTimer(active.abortTimer);\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\r\n\t\t\tfor (const [controller, active] of activeCommands) {\r\n\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\r\n\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\r\n\t\t\t\t\tactive.abortTimer = setTimer(\r\n\t\t\t\t\t\t() => controller.abort(reason),\r\n\t\t\t\t\t\tshutdownCommandTimeoutMs,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tactive.abortTimer?.unref?.();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tcontroller.abort(reason);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction waitForRetry(delay) {\r\n\t\t\tif (shutdownMode) return Promise.resolve();\r\n\t\t\treturn new Promise((resolve) => {\r\n\t\t\t\tlet timer;\r\n\t\t\t\tconst finish = () => {\r\n\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\t\t\tretryWaiters.delete(finish);\r\n\t\t\t\t\tresolve();\r\n\t\t\t\t};\r\n\t\t\t\tretryWaiters.add(finish);\r\n\t\t\t\ttimer = setTimer(finish, delay);\r\n\t\t\t\ttimer?.unref?.();\r","truncated":true,"truncatedBy":"lines","totalLines":707,"totalBytes":3214,"outputLines":105,"outputBytes":3214,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\t\tlet runtimeCtx;\r\n\t\tlet endpointState;\r\n\t\tlet stateOperation = Promise.resolve();\r\n\t\tlet endPromise;\r\n\t\tlet fatalPromise;\r\n\t\tlet teardownPromise;\r\n\t\tlet acceptedBytes = 0;\r\n\t\tlet overflowItem;\r\n\t\tconst queue = [];\r\n\r\n\t\tconst logError = (message, error) => {\r\n\t\t\tpi.logger.error(message, { error: errorSummary(error) });\r\n\t\t\tui?.notify(`${message}: ${errorSummary(error)}`, \"error\");\r\n\t\t};\r\n\r\n\t\tfunction runCommand(args, input, options = {}) {\r\n\t\t\tif (shutdownDeadlineExpired) {\r\n\t\t\t\treturn Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));\r\n\t\t\t}\r\n\t\t\tconst timeoutMs =\r\n\t\t\t\toptions.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);\r\n\t\t\tconst controller = new AbortController();\r\n\t\t\tactiveCommands.set(controller, { args, abortTimer: undefined });\r\n\t\t\tlet command;\r\n\t\t\ttry {\r\n\t\t\t\tcommand = Promise.resolve(\r\n\t\t\t\t\trunSptCommand(args, input, {\r\n\t\t\t\t\t\tsignal: controller.signal,\r\n\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t}),\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t\treturn Promise.reject(error);\r\n\t\t\t}\r\n\t\t\tif (customRunSptCommand) {\r\n\t\t\t\tconst rawCommand = command;\r\n\t\t\t\tcommand = new Promise((resolve, reject) => {\r\n\t\t\t\t\tlet timer;\r\n\t\t\t\t\tlet finished = false;\r\n\t\t\t\t\tconst finish = (error, value) => {\r\n\t\t\t\t\t\tif (finished) return;\r\n\t\t\t\t\t\tfinished = true;\r\n\t\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\t\t\t\tcontroller.signal.removeEventListener(\"abort\", onAbort);\r\n\t\t\t\t\t\tif (error === undefined) resolve(value);\r\n\t\t\t\t\t\telse reject(error);\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst onAbort = () =>\r\n\t\t\t\t\t\tfinish(\r\n\t\t\t\t\t\t\tcontroller.signal.reason instanceof Error\r\n\t\t\t\t\t\t\t\t? controller.signal.reason\r\n\t\t\t\t\t\t\t\t: new Error(`${commandLabel(args)} aborted`),\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\tcontroller.signal.addEventListener(\"abort\", onAbort, { once: true });\r\n\t\t\t\t\tif (shutdownMode) {\r\n\t\t\t\t\t\ttimer = setTimer(\r\n\t\t\t\t\t\t\t() =>\r\n\t\t\t\t\t\t\t\tcontroller.abort(\r\n\t\t\t\t\t\t\t\t\tnew Error(`${commandLabel(args)} timed out after ${timeoutMs}ms`),\r\n\t\t\t\t\t\t\t\t),\r\n\t\t\t\t\t\t\ttimeoutMs,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\ttimer?.unref?.();\r\n\t\t\t\t\t}\r\n\t\t\t\t\trawCommand.then(\r\n\t\t\t\t\t\t(value) => finish(undefined, value),\r\n\t\t\t\t\t\t(error) => finish(error),\r\n\t\t\t\t\t);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn command.finally(() => {\r\n\t\t\t\tconst active = activeCommands.get(controller);\r\n\t\t\t\tif (active?.abortTimer !== undefined) clearTimer(active.abortTimer);\r\n\t\t\t\tactiveCommands.delete(controller);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\r\n\t\t\tfor (const [controller, active] of activeCommands) {\r\n\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\r\n\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\r\n\t\t\t\t\tactive.abortTimer = setTimer(\r\n\t\t\t\t\t\t() => controller.abort(reason),\r\n\t\t\t\t\t\tshutdownCommandTimeoutMs,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tactive.abortTimer?.unref?.();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tcontroller.abort(reason);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction waitForRetry(delay) {\r\n\t\t\tif (shutdownMode) return Promise.resolve();\r\n\t\t\treturn new Promise((resolve) => {\r\n\t\t\t\tlet timer;\r\n\t\t\t\tconst finish = () => {\r\n\t\t\t\t\tif (timer !== undefined) clearTimer(timer);\r\n\t\t\t\t\tretryWaiters.delete(finish);\r\n\t\t\t\t\tresolve();\r\n\t\t\t\t};\r\n\t\t\t\tretryWaiters.add(finish);\r\n\t\t\t\ttimer = setTimer(finish, delay);\r\n\t\t\t\ttimer?.unref?.();\r\n\t\t\t});\n\t\t}","startLine":684,"lineNumbers":[684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1390,"totalBytes":3214,"outputLines":105,"outputBytes":3214,"shownRange":{"start":684,"end":788},"nextOffset":789}}},"isError":false,"timestamp":1784190684191}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `MuslRelease`:\n\nThanks; manifest comment coordination is closed.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"MuslRelease\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531d0a1d05b7982","from":"MuslRelease","message":"Thanks; manifest comment coordination is closed."},"attribution":"agent","id":"fd8e3dde","parentId":"24bd63d7","timestamp":"2026-07-16T08:31:24.192Z"}
{"type":"message","id":"f418fb72","parentId":"fd8e3dde","timestamp":"2026-07-16T08:32:29.356Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Inserting detection functions after runCommand**\n\n**Detailing endpoint activation and error handling**\n\n**Implementing activation promise cleanup and failClosed logic**"},{"type":"thinking","thinking":"**Refining update detection and probe sequencing**\n\n**Fixing probe empty result handling**"},{"type":"toolCall","id":"call_JeT1q9RNeXQGVPm0vSHrCKz1|ctc_072e3873bd2f9b2a016a5896ec5ccc8198b5c11dc3f13ca74f","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#8E1D]\nINS.POST 760:\n+\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n+\t\tasync function detectUpdateNotices() {\n+\t\t\tconst [coreVersionResult, notificationsResult, adapterVersionResult, latestAdapterResult] =\n+\t\t\t\tawait Promise.allSettled([\n+\t\t\t\t\trunCommand([\"--version\"]),\n+\t\t\t\t\trunCommand([\"--json\", \"notif\", \"list\"]),\n+\t\t\t\t\trunCommand([\"adapter\", \"version\", ADAPTER]),\n+\t\t\t\t\tfetchLatestAdapterVersion(),\n+\t\t\t\t]);\n+\t\t\tconst notices = [];\n+\n+\t\t\tif (\n+\t\t\t\tcoreVersionResult.status === \"fulfilled\" &&\n+\t\t\t\tnotificationsResult.status === \"fulfilled\"\n+\t\t\t) {\n+\t\t\t\tconst current = parseVersion(coreVersionResult.value);\n+\t\t\t\tif (current) {\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst latest = newestCoreUpdate(notificationsResult.value, current);\n+\t\t\t\t\t\tif (latest) {\n+\t\t\t\t\t\t\tnotices.push(\n+\t\t\t\t\t\t\t\t`spt-core ${formatVersion(latest)} is available; run \\`spt update\\`.`,\n+\t\t\t\t\t\t\t);\n+\t\t\t\t\t\t}\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\tpi.logger.debug(\"omp-spt update notification probe skipped\", {\n+\t\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t\t});\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tif (\n+\t\t\t\tadapterVersionResult.status === \"fulfilled\" &&\n+\t\t\t\tlatestAdapterResult.status === \"fulfilled\"\n+\t\t\t) {\n+\t\t\t\tconst current = parseVersion(adapterVersionResult.value);\n+\t\t\t\tconst latest = parseVersion(latestAdapterResult.value);\n+\t\t\t\tif (current && latest && compareVersions(latest, current) > 0) {\n+\t\t\t\t\tnotices.push(\n+\t\t\t\t\t\t`omp-spt ${formatVersion(latest)} is available; run \\`spt adapter update omp-spt\\`, then restart this endpoint.`,\n+\t\t\t\t\t);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\treturn notices;\n+\t\t}\n+\n+\t\tfunction beginUpdateProbe() {\n+\t\t\tupdateNoticesPending = true;\n+\t\t\tupdateNoticesPromise = checkUpdates\n+\t\t\t\t? detectUpdateNotices().catch((error) => {\n+\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\n+\t\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn [];\n+\t\t\t\t\t})\n+\t\t\t\t: Promise.resolve([]);\n+\t\t}\n+\n+\t\tasync function compatibleCandidates(type, ctx) {\n+\t\t\tconst listing = parseJson(\n+\t\t\t\tawait runCommand([\"--json\", \"endpoint\", \"list\", \"--show-all\"]),\n+\t\t\t\t\"spt endpoint list\",\n+\t\t\t);\n+\t\t\tconst local = (listing.local ?? []).filter(\n+\t\t\t\t(candidate) =>\n+\t\t\t\t\tcandidate?.state === type &&\n+\t\t\t\t\tcandidate?.alive !== true &&\n+\t\t\t\t\tendpointIdPattern.test(candidate?.id ?? \"\"),\n+\t\t\t);\n+\t\t\tconst currentDirectory = normalizePath(ctx.cwd);\n+\t\t\tconst detailed = await Promise.all(\n+\t\t\t\tlocal.map(async (candidate) => {\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst info = parseJson(\n+\t\t\t\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", candidate.id]),\n+\t\t\t\t\t\t\t`spt api endpoint-info ${candidate.id}`,\n+\t\t\t\t\t\t);\n+\t\t\t\t\t\tif (String(info.adapter ?? \"\").split(\":\")[0] !== ADAPTER) return undefined;\n+\t\t\t\t\t\tif (\n+\t\t\t\t\t\t\tcurrentDirectory &&\n+\t\t\t\t\t\t\tinfo.cwd &&\n+\t\t\t\t\t\t\tnormalizePath(info.cwd) !== currentDirectory\n+\t\t\t\t\t\t) {\n+\t\t\t\t\t\t\treturn undefined;\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\treturn { id: candidate.id, info };\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\tpi.logger.debug(\"omp-spt activation candidate skipped\", {\n+\t\t\t\t\t\t\tid: candidate.id,\n+\t\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn undefined;\n+\t\t\t\t\t}\n+\t\t\t\t}),\n+\t\t\t);\n+\t\t\tconst candidates = detailed.filter(Boolean);\n+\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n+\t\t\tif (type === \"ready_agent\") cachedReadyIds = ids;\n+\t\t\telse cachedLiveIds = ids;\n+\t\t\treturn candidates;\n+\t\t}\n+\n+\t\tasync function chooseIdentity(type, ctx) {\n+\t\t\tif (!ctx.hasUI) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t`/${type === \"live_agent\" ? \"live\" : \"ready\"} requires an endpoint id when native selection is unavailable`,\n+\t\t\t\t\t\"error\",\n+\t\t\t\t);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tlet candidates;\n+\t\t\ttry {\n+\t\t\t\tcandidates = await compatibleCandidates(type, ctx);\n+\t\t\t} catch (error) {\n+\t\t\t\tlogError(\"omp-spt could not list compatible endpoint identities\", error);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tconst createLabel = \"Create a new endpoint id\";\n+\t\t\tconst selected =\n+\t\t\t\tcandidates.length > 0\n+\t\t\t\t\t? await ctx.ui.select(\n+\t\t\t\t\t\t\t`Select ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint`,\n+\t\t\t\t\t\t\t[...candidates.map((candidate) => candidate.id), createLabel],\n+\t\t\t\t\t\t)\n+\t\t\t\t\t: createLabel;\n+\t\t\tif (!selected) return undefined;\n+\t\t\tif (selected !== createLabel) return selected;\n+\t\t\treturn (await ctx.ui.input(\"New SPT endpoint id\", \"letters, numbers, - or _\"))?.trim();\n+\t\t}\n+\n+\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\n+\t\tasync function chooseAutoResume(ctx) {\n+\t\t\tif (!ctx.hasUI) {\n+\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tlet candidates;\n+\t\t\ttry {\n+\t\t\t\tcandidates = await compatibleCandidates(\"live_agent\", ctx);\n+\t\t\t} catch (error) {\n+\t\t\t\tlogError(\"omp-spt could not list live auto-resume candidates\", error);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tconst recent = (\n+\t\t\t\tawait Promise.all(\n+\t\t\t\t\tcandidates.map(async (candidate) => {\n+\t\t\t\t\t\ttry {\n+\t\t\t\t\t\t\tconst digest = parseJson(\n+\t\t\t\t\t\t\t\tawait runCommand([\n+\t\t\t\t\t\t\t\t\t\"--json\",\n+\t\t\t\t\t\t\t\t\t\"endpoint\",\n+\t\t\t\t\t\t\t\t\t\"digest\",\n+\t\t\t\t\t\t\t\t\tcandidate.id,\n+\t\t\t\t\t\t\t\t\t\"--last\",\n+\t\t\t\t\t\t\t\t\t\"1\",\n+\t\t\t\t\t\t\t\t]),\n+\t\t\t\t\t\t\t\t`spt endpoint digest ${candidate.id}`,\n+\t\t\t\t\t\t\t);\n+\t\t\t\t\t\t\treturn {\n+\t\t\t\t\t\t\t\t...candidate,\n+\t\t\t\t\t\t\t\tlastActiveAt: latestDigestTimestamp(digest),\n+\t\t\t\t\t\t\t};\n+\t\t\t\t\t\t} catch {\n+\t\t\t\t\t\t\treturn { ...candidate, lastActiveAt: Number.NEGATIVE_INFINITY };\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}),\n+\t\t\t\t)\n+\t\t\t).filter((candidate) => Number.isFinite(candidate.lastActiveAt));\n+\t\t\trecent.sort(\n+\t\t\t\t(left, right) =>\n+\t\t\t\t\tright.lastActiveAt - left.lastActiveAt || left.id.localeCompare(right.id),\n+\t\t\t);\n+\t\t\tif (recent.length === 0) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t\"No compatible prior omp-spt live identity has recorded activity; use `/live <id>`\",\n+\t\t\t\t\t\"error\",\n+\t\t\t\t);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tlet candidate = recent[0];\n+\t\t\tconst ties = recent.filter((item) => item.lastActiveAt === candidate.lastActiveAt);\n+\t\t\tif (ties.length > 1) {\n+\t\t\t\tconst selected = await ctx.ui.select(\n+\t\t\t\t\t\"Select equally recent live endpoint\",\n+\t\t\t\t\tties.map((item) => item.id),\n+\t\t\t\t);\n+\t\t\t\tif (!selected) return undefined;\n+\t\t\t\tcandidate = ties.find((item) => item.id === selected);\n+\t\t\t}\n+\t\t\tconst confirmed = await ctx.ui.confirm(\n+\t\t\t\t\"Resume live endpoint?\",\n+\t\t\t\t`${candidate.id} was the most recently active compatible live endpoint (${new Date(\n+\t\t\t\t\tcandidate.lastActiveAt,\n+\t\t\t\t).toISOString()}). Bind this OMP session to it?`,\n+\t\t\t);\n+\t\t\treturn confirmed ? candidate.id : undefined;\n+\t\t}\n+\n+\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\n+\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\n+\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n+\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t\"SPT endpoint ids may contain only letters, numbers, `-`, and `_`\",\n+\t\t\t\t\t\"error\",\n+\t\t\t\t);\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t\tif (activated || token) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t`This OMP session is immutably bound to ${id}; stop it before activating another identity`,\n+\t\t\t\t\t\"warning\",\n+\t\t\t\t);\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t\tif (stopping) {\n+\t\t\t\tctx.ui.notify(\"This OMP session is already shutting down\", \"error\");\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t\tif (activationPromise) return activationPromise;\n+\n+\t\t\truntimeCtx = ctx;\n+\t\t\tui = ctx.ui;\n+\t\t\tsid = ctx.sessionManager.getSessionId();\n+\t\t\tid = nextId;\n+\t\t\tactivationType = type;\n+\t\t\tlet bound = false;\n+\t\t\tconst operation = (async () => {\n+\t\t\t\tconst bindArgs = [\n+\t\t\t\t\t\"api\",\n+\t\t\t\t\t\"--adapter\",\n+\t\t\t\t\tADAPTER,\n+\t\t\t\t\t\"bind\",\n+\t\t\t\t\tid,\n+\t\t\t\t\t\"--set-session-id\",\n+\t\t\t\t\tsid,\n+\t\t\t\t];\n+\t\t\t\tif (type) bindArgs.push(\"--type\", type);\n+\t\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n+\t\t\t\tbindPromise = (async () => {\n+\t\t\t\t\tconst response = await runCommand(bindArgs);\n+\t\t\t\t\ttoken = response.match(/\\btoken=([^\\s]+)/)?.[1];\n+\t\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n+\t\t\t\t\tbound = true;\n+\t\t\t\t})();\n+\t\t\t\ttry {\n+\t\t\t\t\tawait bindPromise;\n+\t\t\t\t\tawait syncDesiredState();\n+\t\t\t\t\tif (stopping) {\n+\t\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n+\t\t\t\t\t\treturn false;\n+\t\t\t\t\t}\n+\t\t\t\t\tactivated = true;\n+\t\t\t\t\tstartupBriefPending = true;\n+\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n+\t\t\t\t\tstartListener();\n+\t\t\t\t\tbeginUpdateProbe();\n+\t\t\t\t\tif (options.announce) {\n+\t\t\t\t\t\tui.notify(\n+\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\n+\t\t\t\t\t\t\t\"info\",\n+\t\t\t\t\t\t);\n+\t\t\t\t\t}\n+\t\t\t\t\treturn true;\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n+\t\t\t\t\tif (options.fatal || bound) {\n+\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n+\t\t\t\t\t\treturn false;\n+\t\t\t\t\t}\n+\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\n+\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t});\n+\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\n+\t\t\t\t\tid = undefined;\n+\t\t\t\t\tactivationType = undefined;\n+\t\t\t\t\tbindPromise = undefined;\n+\t\t\t\t\ttoken = undefined;\n+\t\t\t\t\treturn false;\n+\t\t\t\t}\n+\t\t\t})();\n+\t\t\tactivationPromise = operation;\n+\t\t\ttry {\n+\t\t\t\treturn await operation;\n+\t\t\t} finally {\n+\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\n+\t\t\t}\n+\t\t}\n+\n+\t\tasync function handleActivationCommand(type, args, ctx) {\n+\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\n+\t\t\tconst trimmed = args.trim();\n+\t\t\tlet nextId;\n+\t\t\tif (trimmed === \"--auto\") {\n+\t\t\t\tif (type !== \"live_agent\") {\n+\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t\tnextId = await chooseAutoResume(ctx);\n+\t\t\t} else if (!trimmed) {\n+\t\t\t\tnextId = await chooseIdentity(type, ctx);\n+\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\n+\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\n+\t\t\t\treturn;\n+\t\t\t} else {\n+\t\t\t\tnextId = trimmed;\n+\t\t\t}\n+\t\t\tif (!nextId) return;\n+\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\n+\t\t}\n+\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1680,"output":3499,"cacheRead":168448,"cacheWrite":0,"totalTokens":173627,"reasoningTokens":699,"cost":{"input":0.008400000000000001,"output":0.10497000000000001,"cacheRead":0.084224,"cacheWrite":0,"total":0.197594}},"stopReason":"toolUse","timestamp":1784190684261,"responseId":"resp_072e3873bd2f9b2a016a5896dcac4481988b35e0b8b12f7b6f","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_072e3873bd2f9b2a016a5896de31588198813ca755107db394","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJbpfNB0qmj60xiWM_dXIJ8e9tqYKCGCRuXfxRxynl8OVwfBlQj1rJmlG4VHWTsj7VhOcRfKCB1HV7xuE2bepkK93MFuKppNbEL9HNxt7HrI6qbOJFsbNK3XIEBL4mKq3Pjf6qGTKKDSb5HuaXFlzNuITUZ_gE2M2jEIRmEuih8dW4S8gyN5Cm8D1b1Lwj2zZoYdXViuZs2GACn3QhTXP8MQKwb4IWP1_VPfcp_r9jv-NVeZLKEl5TyfNifXv9oSSW7DYLjtPZNYBe_d44AlwyaZqMCkyWnfRAyOKZbZUN8Dx5tzOq0yTzjgSR7hYass5fQQ_lsK0Obg2-yAqLOFXNv1rhFyGo2GYKNaYJGmLAmaqRgNyORxLTNR9WfOx_VNxrCY-NFfiI8MWFaLo41TUYLbdbQ-l-5ziFpurHPLFPf8il-SKgqtq6QU4-904ralHVUpng4yq3uFNSRO7ZO5YmF_J3xDM--AHTSNfWz_MDVLEYLB9gbHsbb6ijjM7dMu7m0TQ3wQD0jpFvBFe-KP9e2AXlFpMZAEh_z3mA578Wa87B60_lkapbJHHeQzUMw0t2GBFYtJcrwzYg3WjXH8WcCEnfTL0uvTTntk6n6TtnD7c7eKYU-pIocobdjuD8J3ynOpoZs5A6J2sCnp76J5F1Y8H8R6_pug_ZMBjyRwri5npUtqDESv5NtSnqLvtzjnGDKtW8NzZivsaT2qv937Y3gWt6NKWiohUXGmKRLeC-ZcktbFay7-UbRn6Y6bxAnyBo3d2t2HF25Az65OYHh0f6JpwR-9aCnZv0WpPkEMIfpuI07cNuxlFYG3M5O0I9iKFu_a1V6vYOYnUE2c0tcSgjTMkWto7Oz_S8-Z-sFsBtZyHBWCRu9GB1Fp9wvA3qDS1_S6Z4xHyIMhcEvjcw98crPNtFequWFZBtlfRJcRQvGSHCBuUyuzGuCElAF9BfdqNQcBnV8NDN-kn7VGzfOHNuOWimbor1HmIOHQbNsUJ37kxra6VCXWgheYpVq_TpSEBuxrtV-FUUbeA3T4inc5qTp_O0tOHav9D-_m312bWGydoKrlBehaB9VWYvyT08DhMWcRd2_aqdwx3ajvGp_iJUgQtxeLc5Ff6eSUpSXfh_Mj3lP3O1pE2ISEvp5PeJRB7tIF4IsFYXyVMiwVbrE6N1DotuURpAywxR7SOCJiQqaKs8KYjwj9_zCHE7CmBo9Yxnhwma_Xgn33lrt_SMJpeWdNYA1137XiJOTs3WjiMhjmrfB8KCM2iZMB3wbLptnFbwme2ItAxS7loX6SC5bKG4O69vVTfLGIWxAul8z8NS40CQWDllS-MxL9IFC9avLhn-CsBoKjTV-XwguV02WUyCqfeb5_XGU7I8cjFiWUx1ZyhMgCGFbUO5UxGe-Sw9SbQqpxQS2_nR0UCtqovVqKAXrKg_cLlGACFD3sV_MKJ6LGbbRADG0fqNOYAkDBtRn2WVeu7MDHbnhBHIOw3HOb8MUE2TJ0-iWp1DS6O50EIQdcJXYJzjv6nTSvlRD9uLZYYJvXa8ca-AmonL0O8Uil5oiRU4atqz8b5ub_mEHYCoRbPjckoDOLjLzlRGBOXteFMUzIiYjit_9k6NIhNUF4IVe6qneQa5lPI0808vfa3F6wRlQBIl_AGz-j0ZLuiRK-xp0GTJmTe1xETuz-H9ObvS_OTcvkqvQLX7rXD9CwGEMurs-dDD41aAwfWljbBKbROy4_ULik5JolyGHmkn7x1ETQ1XXb5j8ct56GbMT0OuAq4suCSLRpp3tz5cVRdi90hksipSAHxJx62x5-ik0cGbQUCnuqkl2cYeIPQbzaF3bGyoxqQueFShNMKdo55hBAYHwbWQxfuqPZhPwA6GF7gXt5vo3JrGy_bLchO8yyjFSNNRQl4t5II1tkbV7nVhPSdIeCPc0Vwaq1rY77VcbfUzFZPUVbLk-Ns3q0q420VxsC5agdWDwaU1COg5kL5bJqpgM2B45eTbCQ0o__IAc6QHQZV8-UUrgr4j9rL2HnZEH6hD6HRqObkoQfm9erK5JvmElb_2OCCW4-x2M6k_SkcpfcfjFyTpbTw1BMaL_pBiSicc9Ey8mIhL96jR8i9Jkykhc0Mqwtpb7hWfJO7JvVpzfdOF4O9_hNkSGQVVU2FuxG6EtzxueEXHLmZg1_pIee6n33KQeU-StZgUvw9HQBCiTZIW6xpm0Pzb0F2prwWJOrX355sez9Y0-q5L6UzFCw4MSNq6jERixqLLZG7ZcsV3tpc-hIpcD3Yl4-KrxjlD47EfwHGDLVMJyJvv-ZToqBPQkEnMhA7wQb7j2IQ17wkTS42vM524EACZeAb5XeTnfOeDiVWAuxZ-3OGB3o2WIjug3G3pWZVooFKzJgZoCbKf56xDga_hrwN6oVGgTd_fRtcyHnd22lPdsVMExsrjTf3T_M5eS2piPmz1vtAW6RWP4HJKdQ0i0sX0w44CuPpIic475g_3AZk273jNpYzmnb6LcMjdITEdnqQwd4oXk6LcU5X8IjUb3JPOn7ezgvCNAaJZEIbtzl7mFPJBa-8KkOhjpls3O45w4nimUZTtIgzw5xGSxe5fJ5vwGInOxYf_2twROGClGbHvimvAOuGO2ieOI58HmcmENCEWsSkV41nVXdFuDb5r_QrObVIdgzoUPdzVNNigSQ89XTXDLG7X9F863L3nJYozTw29_O2Yybl5BixBTqiE4gtgSp3iwzUUFDnB_60y13Q7I76j3nVhfrZ3-_k5Cc1WCfXNzm7Sba9gEDdZP5Gg6FWofayyZT08qpxEABEZ8vBtdLRzcpD00IDtk3w3reIgNOCuOZh1DRC4qtc6zOJzk68nGrqjAnx-qkwtEX9cMwCcfyNjZ7ySLeunuWNGK_rJC_gtOPHjV3A-jLYRKsHkV8eBrCjjqceM3cDQYRIDcbWcg2bO23JMVqiMPU-lr97gzLMB1Ibl_f_UNryBzsiuwC9RlPYRpMNTwtuD9FqO9wcCrUgr8VRoAPZ8V1P5gJ3WPRP3vLd3PTStIG9HlI7z5DdROFrFUFeje9n0Xv2Cfc83JN0qFfsF-ZOA7Zd9wiAHOAGuhrqWguFlzJIXJAM6zObRPEuYufJiDOV-Lp9aIvuMbaCNzvnJktCkCGnOw98vD2Bpy9QC51_gwsQJ93ky3a424mdRjMHMsxIDTXbqijvUoVu1rUe4zYeeAXNgXAmiAFvazp0acxBSqYPkWkLF4xsjhzIOsDE3-AM5KmSjFA-Hy-HQslRciKdfnOFH4TWcbBSYUzTLLj4PqaAtN7uKQ0YRNmwcAd1qxalWFiY5vI56NqbDaYLDXOE9yFQedtAvDfmU_-dH45b4fie6SB_WbgiEhGUFEtc4SyPgwL0cB7-_A6u9jLdOutfHpckP6ZPFwTyQArRFTDWZVCO4dflL_mganplhEQa56U0FQxPSxerrmyABW1Pc-jLIFR_BXxfgpgWm6wKGSF-NvpnDhsKdSqZjayl1efsbeWP4YmsarP7NmSmW9aNSVhrbOFd1RDn-Kruux1ty0hHXW7_DEXKbcLcXYwBfJqksuX0xP5PXtOPXX2DeVolLtoekPkQa6PFJhOeazyLpEkc7GfMtCyD5Y2QRtu8N9828mDZCgM_hdYEHsAra8yONWbP5l9yzgXsi0W617xutsCRQ4dM2Bd63Fr2paRS1NhEm-ro1lfvoT67FWjGmxjI2UREZ56dh91xQI98u6Ga_htDEeYaZy1hwZ6QwfyVrqHadWjGU-VA3hXbPb7Nr3koZM3luvtAXHwsytjfDMWy4RVQjGmE5m820S0tW7QwEYBLOCt9lvOtJZgQ6NH7AedgeCDYu_w4D5ausc6PvKZd3iYrRX0FM8TX4vmJSvcXPy7HeP28t_tl3bYzkvz4tHHzism3EXvKbavJOMJVzm--69YpWKUxW5ncULMaD9dWt68qG8AviD6JS8N3ISBtFPkv-77iqE5phTdoGJ-KeKh7tZzjlxPPUA2dzdp-GF6yUR9csTEs7ZjF4Gf3rDqvwP-f1McFyQImFOuvoEY8F0LowJocewmysmAfU5SUCUokMsITJ-vJh12ewdbXOWsUjLmgV7CXq-nwnjH4IFu64aIEuI7aJ4ih-yrsOz9IC9HZ3e6N8a7nDArVofRhNKtDepoPlI4aCNGmAMA072QRhLDngJLt0xr_w==","summary":[{"type":"summary_text","text":"**Inserting detection functions after runCommand**"},{"type":"summary_text","text":"**Detailing endpoint activation and error handling**"},{"type":"summary_text","text":"**Implementing activation promise cleanup and failClosed logic**"}]},{"id":"rs_072e3873bd2f9b2a016a5896e948f481988809c64814384740","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJbso4OLbgtulFpeSTpZuNdz8JaJlnSooLMMUWK7y0GVHIE2epNuxbeUAtaydJqYBvhOC7EquKqNVkUaWbwyMRXUCz90Ssoh9t4FjC5YCHIk6SInli6W-kFipNK_5ewI2mEtIh2vyG-dKnkFq9rpHeC0hsceTK_6vvMhRmjRKgp7XdlUYQ0-sTmRiT9Npf236YEKI6B8SSOyRX17_9qI_9ugkRO81t4y5L7Wg3tTBtm4RRDem8MSE_PPIFkXwe0YzJrpLkCtDOUwN5HekkAm-aY2bckKOFTyO7Ib2rdzbXJk9Z_Gp1Gno7AUk_2f93tXcTJEZhSPENmKYxaqk2h-BuCAEmp-q3us_iZmLwVKHlHXNGEp7bg_wo7t8IEHNXP1J46Ru2l8DBFunQxjvQVHzz-IFEn_dpGfCIp6JBzgQIKC_5f5NbS-an18hXWSJbX6b0TmZAEtxUtGVnRTF8zNcJyKaAsHudK01ZkY_5qjKYKgdOre3xS6OTaO3mYaSQMgOESYSbq39wpVTEoK1lW8FiuQIzxpTfn05GASiOqQwEs2NaxTfetTC6CBS44yq31Gv4CJKjLrr_lLyimrg9KecWbHySUXmPGNMBq9e1EXGeD6to52iNGqXCmvMFsxwCAROo_uNFX5Iie5xMAwL-E6Uv8nHFAn7YQi8CB--W4LzDTClIpmnjLIQt0kwuWV8iGghJ3im4ttRsHOqGGzjtkwRtV32Z8L_eVzqm9OoCsnlcaYVVymu9m721LiLOh65Usw85mt2JHwt3aldL5mE71gpsQr_x3GwvfDaOMONGwK-gX2M24f3Rbh8E55BIQJhkXBBbxpffDEEVqPCHafm5iVv_Zf2hBPVSy_RhIe8tUWsmPfD3LH8YgDlpg3-CS8ywNocNIloonw8JMwn3wBZZhBS3JNUaQVunCoGVpsHSIWUXKV18NUVWBK_ZpMPy_qAzOGaGdKsP0cuTETJ5K-Q2BZZiWDiAToy9TgddTmWS9JDs8Gd35bXsDz_4wf6mGLyXU18pX53MNsr7ELi4i6zlojuIeZiarnCdRFHPYKDd3Xj8ZofZvt4im9QzZdQlFbDvv6sbjH8kFTfqBXABvo_QAEwaLYQBHgXO0sTnEn09ok1Nd79aZIksC6zTUs_wYccsw0wCCTjp_1wg2Ilx29nENUloqOc_Weyt47XqW06Ln_XzsXt9oRvgMLHswlpkXQxEdXU2XtMYDPwBnEYNDlxi-xNaiOwHoUeEfn-TTBbfF4kNG8K8jI6nEcsyS7JoY2J1xc5f2vdxxq1n05VN0miYrC9zJrBJtUjzUTVjTi1FdmAQpEJudGuDqeJD4b-duj9vlMz7jzLJPAM2XlIHZeuFdaxL-SQUo4nLICXYtxgh_cXDfv1I4eGXEx3J49D4bXWfOIpFr0DC6QwToUIP-aZ5f1I28j5WW3mOgnPD4MI7UgXhyr_jidYA-iTakC_FJOmnsaZtT2l7gUgkU2g188BrWPsEYrCfvkFY5kgGVYysxMMfvNubBMXBLZ4j01mR3-vm3XLjqdsTn7C1OfXQjQ3osIormc34rcGVI8mrGLSEBMz2vpYLxHQnmLeQbnokPM_05CgP-wHvThZJKJOGf2Pr0f0QeqlYcZMEzUWlsZ_Yg_QsunkXRodP5X9FA_riCN8wcLX3fanSy4U3hNeMAKNO3XCQ6zTJZ7lOEg6o1yAjzgMypUgkGpDZQBxJh9qUx8dr8H_fRKHv6q4cMvtwH3256zHTYGEAEwKwGzW4HWv-gaTphCZGESfUd9iIK8NCDxR-ifMHWOgcwuCstpzmOwcEqB2Y_mQJQOGp-eLSJCL3eQlEuzZJJBTdkTvsrX0kSHl0UYGRgOe5jxmjNcQELYwyQMFH_kb3DUxrFOFBbRZPvlwa3cDkkDYetXM2nzWjo9jW1zvI9DUQ3qP_abcLQmn3ueJAmuh1JP0L7YWqj1jeZvo6o3k1JpY2-KbOHX-NiFEmgbl3ItopyHI-f8upWl-QUq9ojpWp0TtMpUDltu315WN_fAapw=","summary":[{"type":"summary_text","text":"**Refining update detection and probe sequencing**"},{"type":"summary_text","text":"**Fixing probe empty result handling**"}]},{"id":"ctc_072e3873bd2f9b2a016a5896ec5ccc8198b5c11dc3f13ca74f","type":"custom_tool_call","status":"completed","call_id":"call_JeT1q9RNeXQGVPm0vSHrCKz1","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#8E1D]\nINS.POST 760:\n+\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n+\t\tasync function detectUpdateNotices() {\n+\t\t\tconst [coreVersionResult, notificationsResult, adapterVersionResult, latestAdapterResult] =\n+\t\t\t\tawait Promise.allSettled([\n+\t\t\t\t\trunCommand([\"--version\"]),\n+\t\t\t\t\trunCommand([\"--json\", \"notif\", \"list\"]),\n+\t\t\t\t\trunCommand([\"adapter\", \"version\", ADAPTER]),\n+\t\t\t\t\tfetchLatestAdapterVersion(),\n+\t\t\t\t]);\n+\t\t\tconst notices = [];\n+\n+\t\t\tif (\n+\t\t\t\tcoreVersionResult.status === \"fulfilled\" &&\n+\t\t\t\tnotificationsResult.status === \"fulfilled\"\n+\t\t\t) {\n+\t\t\t\tconst current = parseVersion(coreVersionResult.value);\n+\t\t\t\tif (current) {\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst latest = newestCoreUpdate(notificationsResult.value, current);\n+\t\t\t\t\t\tif (latest) {\n+\t\t\t\t\t\t\tnotices.push(\n+\t\t\t\t\t\t\t\t`spt-core ${formatVersion(latest)} is available; run \\`spt update\\`.`,\n+\t\t\t\t\t\t\t);\n+\t\t\t\t\t\t}\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\tpi.logger.debug(\"omp-spt update notification probe skipped\", {\n+\t\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t\t});\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tif (\n+\t\t\t\tadapterVersionResult.status === \"fulfilled\" &&\n+\t\t\t\tlatestAdapterResult.status === \"fulfilled\"\n+\t\t\t) {\n+\t\t\t\tconst current = parseVersion(adapterVersionResult.value);\n+\t\t\t\tconst latest = parseVersion(latestAdapterResult.value);\n+\t\t\t\tif (current && latest && compareVersions(latest, current) > 0) {\n+\t\t\t\t\tnotices.push(\n+\t\t\t\t\t\t`omp-spt ${formatVersion(latest)} is available; run \\`spt adapter update omp-spt\\`, then restart this endpoint.`,\n+\t\t\t\t\t);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\treturn notices;\n+\t\t}\n+\n+\t\tfunction beginUpdateProbe() {\n+\t\t\tupdateNoticesPending = true;\n+\t\t\tupdateNoticesPromise = checkUpdates\n+\t\t\t\t? detectUpdateNotices().catch((error) => {\n+\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\n+\t\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn [];\n+\t\t\t\t\t})\n+\t\t\t\t: Promise.resolve([]);\n+\t\t}\n+\n+\t\tasync function compatibleCandidates(type, ctx) {\n+\t\t\tconst listing = parseJson(\n+\t\t\t\tawait runCommand([\"--json\", \"endpoint\", \"list\", \"--show-all\"]),\n+\t\t\t\t\"spt endpoint list\",\n+\t\t\t);\n+\t\t\tconst local = (listing.local ?? []).filter(\n+\t\t\t\t(candidate) =>\n+\t\t\t\t\tcandidate?.state === type &&\n+\t\t\t\t\tcandidate?.alive !== true &&\n+\t\t\t\t\tendpointIdPattern.test(candidate?.id ?? \"\"),\n+\t\t\t);\n+\t\t\tconst currentDirectory = normalizePath(ctx.cwd);\n+\t\t\tconst detailed = await Promise.all(\n+\t\t\t\tlocal.map(async (candidate) => {\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst info = parseJson(\n+\t\t\t\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", candidate.id]),\n+\t\t\t\t\t\t\t`spt api endpoint-info ${candidate.id}`,\n+\t\t\t\t\t\t);\n+\t\t\t\t\t\tif (String(info.adapter ?? \"\").split(\":\")[0] !== ADAPTER) return undefined;\n+\t\t\t\t\t\tif (\n+\t\t\t\t\t\t\tcurrentDirectory &&\n+\t\t\t\t\t\t\tinfo.cwd &&\n+\t\t\t\t\t\t\tnormalizePath(info.cwd) !== currentDirectory\n+\t\t\t\t\t\t) {\n+\t\t\t\t\t\t\treturn undefined;\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\treturn { id: candidate.id, info };\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\tpi.logger.debug(\"omp-spt activation candidate skipped\", {\n+\t\t\t\t\t\t\tid: candidate.id,\n+\t\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn undefined;\n+\t\t\t\t\t}\n+\t\t\t\t}),\n+\t\t\t);\n+\t\t\tconst candidates = detailed.filter(Boolean);\n+\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n+\t\t\tif (type === \"ready_agent\") cachedReadyIds = ids;\n+\t\t\telse cachedLiveIds = ids;\n+\t\t\treturn candidates;\n+\t\t}\n+\n+\t\tasync function chooseIdentity(type, ctx) {\n+\t\t\tif (!ctx.hasUI) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t`/${type === \"live_agent\" ? \"live\" : \"ready\"} requires an endpoint id when native selection is unavailable`,\n+\t\t\t\t\t\"error\",\n+\t\t\t\t);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tlet candidates;\n+\t\t\ttry {\n+\t\t\t\tcandidates = await compatibleCandidates(type, ctx);\n+\t\t\t} catch (error) {\n+\t\t\t\tlogError(\"omp-spt could not list compatible endpoint identities\", error);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tconst createLabel = \"Create a new endpoint id\";\n+\t\t\tconst selected =\n+\t\t\t\tcandidates.length > 0\n+\t\t\t\t\t? await ctx.ui.select(\n+\t\t\t\t\t\t\t`Select ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint`,\n+\t\t\t\t\t\t\t[...candidates.map((candidate) => candidate.id), createLabel],\n+\t\t\t\t\t\t)\n+\t\t\t\t\t: createLabel;\n+\t\t\tif (!selected) return undefined;\n+\t\t\tif (selected !== createLabel) return selected;\n+\t\t\treturn (await ctx.ui.input(\"New SPT endpoint id\", \"letters, numbers, - or _\"))?.trim();\n+\t\t}\n+\n+\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\n+\t\tasync function chooseAutoResume(ctx) {\n+\t\t\tif (!ctx.hasUI) {\n+\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tlet candidates;\n+\t\t\ttry {\n+\t\t\t\tcandidates = await compatibleCandidates(\"live_agent\", ctx);\n+\t\t\t} catch (error) {\n+\t\t\t\tlogError(\"omp-spt could not list live auto-resume candidates\", error);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tconst recent = (\n+\t\t\t\tawait Promise.all(\n+\t\t\t\t\tcandidates.map(async (candidate) => {\n+\t\t\t\t\t\ttry {\n+\t\t\t\t\t\t\tconst digest = parseJson(\n+\t\t\t\t\t\t\t\tawait runCommand([\n+\t\t\t\t\t\t\t\t\t\"--json\",\n+\t\t\t\t\t\t\t\t\t\"endpoint\",\n+\t\t\t\t\t\t\t\t\t\"digest\",\n+\t\t\t\t\t\t\t\t\tcandidate.id,\n+\t\t\t\t\t\t\t\t\t\"--last\",\n+\t\t\t\t\t\t\t\t\t\"1\",\n+\t\t\t\t\t\t\t\t]),\n+\t\t\t\t\t\t\t\t`spt endpoint digest ${candidate.id}`,\n+\t\t\t\t\t\t\t);\n+\t\t\t\t\t\t\treturn {\n+\t\t\t\t\t\t\t\t...candidate,\n+\t\t\t\t\t\t\t\tlastActiveAt: latestDigestTimestamp(digest),\n+\t\t\t\t\t\t\t};\n+\t\t\t\t\t\t} catch {\n+\t\t\t\t\t\t\treturn { ...candidate, lastActiveAt: Number.NEGATIVE_INFINITY };\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}),\n+\t\t\t\t)\n+\t\t\t).filter((candidate) => Number.isFinite(candidate.lastActiveAt));\n+\t\t\trecent.sort(\n+\t\t\t\t(left, right) =>\n+\t\t\t\t\tright.lastActiveAt - left.lastActiveAt || left.id.localeCompare(right.id),\n+\t\t\t);\n+\t\t\tif (recent.length === 0) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t\"No compatible prior omp-spt live identity has recorded activity; use `/live <id>`\",\n+\t\t\t\t\t\"error\",\n+\t\t\t\t);\n+\t\t\t\treturn undefined;\n+\t\t\t}\n+\t\t\tlet candidate = recent[0];\n+\t\t\tconst ties = recent.filter((item) => item.lastActiveAt === candidate.lastActiveAt);\n+\t\t\tif (ties.length > 1) {\n+\t\t\t\tconst selected = await ctx.ui.select(\n+\t\t\t\t\t\"Select equally recent live endpoint\",\n+\t\t\t\t\tties.map((item) => item.id),\n+\t\t\t\t);\n+\t\t\t\tif (!selected) return undefined;\n+\t\t\t\tcandidate = ties.find((item) => item.id === selected);\n+\t\t\t}\n+\t\t\tconst confirmed = await ctx.ui.confirm(\n+\t\t\t\t\"Resume live endpoint?\",\n+\t\t\t\t`${candidate.id} was the most recently active compatible live endpoint (${new Date(\n+\t\t\t\t\tcandidate.lastActiveAt,\n+\t\t\t\t).toISOString()}). Bind this OMP session to it?`,\n+\t\t\t);\n+\t\t\treturn confirmed ? candidate.id : undefined;\n+\t\t}\n+\n+\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\n+\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\n+\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n+\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t\"SPT endpoint ids may contain only letters, numbers, `-`, and `_`\",\n+\t\t\t\t\t\"error\",\n+\t\t\t\t);\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t\tif (activated || token) {\n+\t\t\t\tctx.ui.notify(\n+\t\t\t\t\t`This OMP session is immutably bound to ${id}; stop it before activating another identity`,\n+\t\t\t\t\t\"warning\",\n+\t\t\t\t);\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t\tif (stopping) {\n+\t\t\t\tctx.ui.notify(\"This OMP session is already shutting down\", \"error\");\n+\t\t\t\treturn false;\n+\t\t\t}\n+\t\t\tif (activationPromise) return activationPromise;\n+\n+\t\t\truntimeCtx = ctx;\n+\t\t\tui = ctx.ui;\n+\t\t\tsid = ctx.sessionManager.getSessionId();\n+\t\t\tid = nextId;\n+\t\t\tactivationType = type;\n+\t\t\tlet bound = false;\n+\t\t\tconst operation = (async () => {\n+\t\t\t\tconst bindArgs = [\n+\t\t\t\t\t\"api\",\n+\t\t\t\t\t\"--adapter\",\n+\t\t\t\t\tADAPTER,\n+\t\t\t\t\t\"bind\",\n+\t\t\t\t\tid,\n+\t\t\t\t\t\"--set-session-id\",\n+\t\t\t\t\tsid,\n+\t\t\t\t];\n+\t\t\t\tif (type) bindArgs.push(\"--type\", type);\n+\t\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n+\t\t\t\tbindPromise = (async () => {\n+\t\t\t\t\tconst response = await runCommand(bindArgs);\n+\t\t\t\t\ttoken = response.match(/\\btoken=([^\\s]+)/)?.[1];\n+\t\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n+\t\t\t\t\tbound = true;\n+\t\t\t\t})();\n+\t\t\t\ttry {\n+\t\t\t\t\tawait bindPromise;\n+\t\t\t\t\tawait syncDesiredState();\n+\t\t\t\t\tif (stopping) {\n+\t\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n+\t\t\t\t\t\treturn false;\n+\t\t\t\t\t}\n+\t\t\t\t\tactivated = true;\n+\t\t\t\t\tstartupBriefPending = true;\n+\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n+\t\t\t\t\tstartListener();\n+\t\t\t\t\tbeginUpdateProbe();\n+\t\t\t\t\tif (options.announce) {\n+\t\t\t\t\t\tui.notify(\n+\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\n+\t\t\t\t\t\t\t\"info\",\n+\t\t\t\t\t\t);\n+\t\t\t\t\t}\n+\t\t\t\t\treturn true;\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n+\t\t\t\t\tif (options.fatal || bound) {\n+\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n+\t\t\t\t\t\treturn false;\n+\t\t\t\t\t}\n+\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\n+\t\t\t\t\t\terror: errorSummary(error),\n+\t\t\t\t\t});\n+\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\n+\t\t\t\t\tid = undefined;\n+\t\t\t\t\tactivationType = undefined;\n+\t\t\t\t\tbindPromise = undefined;\n+\t\t\t\t\ttoken = undefined;\n+\t\t\t\t\treturn false;\n+\t\t\t\t}\n+\t\t\t})();\n+\t\t\tactivationPromise = operation;\n+\t\t\ttry {\n+\t\t\t\treturn await operation;\n+\t\t\t} finally {\n+\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\n+\t\t\t}\n+\t\t}\n+\n+\t\tasync function handleActivationCommand(type, args, ctx) {\n+\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\n+\t\t\tconst trimmed = args.trim();\n+\t\t\tlet nextId;\n+\t\t\tif (trimmed === \"--auto\") {\n+\t\t\t\tif (type !== \"live_agent\") {\n+\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t\tnextId = await chooseAutoResume(ctx);\n+\t\t\t} else if (!trimmed) {\n+\t\t\t\tnextId = await chooseIdentity(type, ctx);\n+\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\n+\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\n+\t\t\t\treturn;\n+\t\t\t} else {\n+\t\t\t\tnextId = trimmed;\n+\t\t\t}\n+\t\t\tif (!nextId) return;\n+\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\n+\t\t}\n+\n*** End Patch\n","name":"edit"}]},"duration":65094.31789999991,"ttft":1960.8807999999262,"contextSnapshot":{"promptTokens":170128,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_JeT1q9RNeXQGVPm0vSHrCKz1|ctc_072e3873bd2f9b2a016a5896ec5ccc8198b5c11dc3f13ca74f","toolName":"edit","startedAt":"2026-07-16T08:32:29.358Z"},"id":"d35e39ad","parentId":"f418fb72","timestamp":"2026-07-16T08:32:29.358Z"}
{"type":"message","id":"3baeb9f6","parentId":"d35e39ad","timestamp":"2026-07-16T08:32:29.392Z","message":{"role":"toolResult","toolCallId":"call_JeT1q9RNeXQGVPm0vSHrCKz1|ctc_072e3873bd2f9b2a016a5896ec5ccc8198b5c11dc3f13ca74f","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#60FE]\n699:\t\tfunction runCommand(args, input, options = {}) {\n\n755:\t\t\treturn command.finally(() => {\n\n759:\t\t\t});\n760:\t\t}\n761:\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n762:\t\tasync function detectUpdateNotices() {\n…\n769:\t\t\t\t]);\n770:\t\t\tconst notices = [];\n771:\n772:\t\t\tif (\n773:\t\t\t\tcoreVersionResult.status === \"fulfilled\" &&\n…\n1072:\n1073:\n1074:\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n1075:\t\t\tfor (const [controller, active] of activeCommands) {\n\n1086:\t\t\t}\n1087:\t\t}"}],"details":{"diff":" 699|\t\tfunction runCommand(args, input, options = {}) {\n\n 755|\t\t\treturn command.finally(() => {\n\n 759|\t\t\t});\n 760|\t\t}\n+761|\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n+762|\t\tasync function detectUpdateNotices() {\n+763|\t\t\tconst [coreVersionResult, notificationsResult, adapterVersionResult, latestAdapterResult] =\n+764|\t\t\t\tawait Promise.allSettled([\n+765|\t\t\t\t\trunCommand([\"--version\"]),\n+766|\t\t\t\t\trunCommand([\"--json\", \"notif\", \"list\"]),\n+767|\t\t\t\t\trunCommand([\"adapter\", \"version\", ADAPTER]),\n+768|\t\t\t\t\tfetchLatestAdapterVersion(),\n+769|\t\t\t\t]);\n+770|\t\t\tconst notices = [];\n 761|\n+772|\t\t\tif (\n+773|\t\t\t\tcoreVersionResult.status === \"fulfilled\" &&\n+774|\t\t\t\tnotificationsResult.status === \"fulfilled\"\n+775|\t\t\t) {\n+776|\t\t\t\tconst current = parseVersion(coreVersionResult.value);\n+777|\t\t\t\tif (current) {\n+778|\t\t\t\t\ttry {\n+779|\t\t\t\t\t\tconst latest = newestCoreUpdate(notificationsResult.value, current);\n+780|\t\t\t\t\t\tif (latest) {\n+781|\t\t\t\t\t\t\tnotices.push(\n+782|\t\t\t\t\t\t\t\t`spt-core ${formatVersion(latest)} is available; run \\`spt update\\`.`,\n+783|\t\t\t\t\t\t\t);\n+784|\t\t\t\t\t\t}\n+785|\t\t\t\t\t} catch (error) {\n+786|\t\t\t\t\t\tpi.logger.debug(\"omp-spt update notification probe skipped\", {\n+787|\t\t\t\t\t\t\terror: errorSummary(error),\n+788|\t\t\t\t\t\t});\n+789|\t\t\t\t\t}\n+790|\t\t\t\t}\n+791|\t\t\t}\n+792|\n+793|\t\t\tif (\n+794|\t\t\t\tadapterVersionResult.status === \"fulfilled\" &&\n+795|\t\t\t\tlatestAdapterResult.status === \"fulfilled\"\n+796|\t\t\t) {\n+797|\t\t\t\tconst current = parseVersion(adapterVersionResult.value);\n+798|\t\t\t\tconst latest = parseVersion(latestAdapterResult.value);\n+799|\t\t\t\tif (current && latest && compareVersions(latest, current) > 0) {\n+800|\t\t\t\t\tnotices.push(\n+801|\t\t\t\t\t\t`omp-spt ${formatVersion(latest)} is available; run \\`spt adapter update omp-spt\\`, then restart this endpoint.`,\n+802|\t\t\t\t\t);\n+803|\t\t\t\t}\n+804|\t\t\t}\n+805|\t\t\treturn notices;\n+806|\t\t}\n+807|\n+808|\t\tfunction beginUpdateProbe() {\n+809|\t\t\tupdateNoticesPending = true;\n+810|\t\t\tupdateNoticesPromise = checkUpdates\n+811|\t\t\t\t? detectUpdateNotices().catch((error) => {\n+812|\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\n+813|\t\t\t\t\t\t\terror: errorSummary(error),\n+814|\t\t\t\t\t\t});\n+815|\t\t\t\t\t\treturn [];\n+816|\t\t\t\t\t})\n+817|\t\t\t\t: Promise.resolve([]);\n+818|\t\t}\n+819|\n+820|\t\tasync function compatibleCandidates(type, ctx) {\n+821|\t\t\tconst listing = parseJson(\n+822|\t\t\t\tawait runCommand([\"--json\", \"endpoint\", \"list\", \"--show-all\"]),\n+823|\t\t\t\t\"spt endpoint list\",\n+824|\t\t\t);\n+825|\t\t\tconst local = (listing.local ?? []).filter(\n+826|\t\t\t\t(candidate) =>\n+827|\t\t\t\t\tcandidate?.state === type &&\n+828|\t\t\t\t\tcandidate?.alive !== true &&\n+829|\t\t\t\t\tendpointIdPattern.test(candidate?.id ?? \"\"),\n+830|\t\t\t);\n+831|\t\t\tconst currentDirectory = normalizePath(ctx.cwd);\n+832|\t\t\tconst detailed = await Promise.all(\n+833|\t\t\t\tlocal.map(async (candidate) => {\n+834|\t\t\t\t\ttry {\n+835|\t\t\t\t\t\tconst info = parseJson(\n+836|\t\t\t\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", candidate.id]),\n+837|\t\t\t\t\t\t\t`spt api endpoint-info ${candidate.id}`,\n+838|\t\t\t\t\t\t);\n+839|\t\t\t\t\t\tif (String(info.adapter ?? \"\").split(\":\")[0] !== ADAPTER) return undefined;\n+840|\t\t\t\t\t\tif (\n+841|\t\t\t\t\t\t\tcurrentDirectory &&\n+842|\t\t\t\t\t\t\tinfo.cwd &&\n+843|\t\t\t\t\t\t\tnormalizePath(info.cwd) !== currentDirectory\n+844|\t\t\t\t\t\t) {\n+845|\t\t\t\t\t\t\treturn undefined;\n+846|\t\t\t\t\t\t}\n+847|\t\t\t\t\t\treturn { id: candidate.id, info };\n+848|\t\t\t\t\t} catch (error) {\n+849|\t\t\t\t\t\tpi.logger.debug(\"omp-spt activation candidate skipped\", {\n+850|\t\t\t\t\t\t\tid: candidate.id,\n+851|\t\t\t\t\t\t\terror: errorSummary(error),\n+852|\t\t\t\t\t\t});\n+853|\t\t\t\t\t\treturn undefined;\n+854|\t\t\t\t\t}\n+855|\t\t\t\t}),\n+856|\t\t\t);\n+857|\t\t\tconst candidates = detailed.filter(Boolean);\n+858|\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n+859|\t\t\tif (type === \"ready_agent\") cachedReadyIds = ids;\n+860|\t\t\telse cachedLiveIds = ids;\n+861|\t\t\treturn candidates;\n+862|\t\t}\n+863|\n+864|\t\tasync function chooseIdentity(type, ctx) {\n+865|\t\t\tif (!ctx.hasUI) {\n+866|\t\t\t\tctx.ui.notify(\n+867|\t\t\t\t\t`/${type === \"live_agent\" ? \"live\" : \"ready\"} requires an endpoint id when native selection is unavailable`,\n+868|\t\t\t\t\t\"error\",\n+869|\t\t\t\t);\n+870|\t\t\t\treturn undefined;\n+871|\t\t\t}\n+872|\t\t\tlet candidates;\n+873|\t\t\ttry {\n+874|\t\t\t\tcandidates = await compatibleCandidates(type, ctx);\n+875|\t\t\t} catch (error) {\n+876|\t\t\t\tlogError(\"omp-spt could not list compatible endpoint identities\", error);\n+877|\t\t\t\treturn undefined;\n+878|\t\t\t}\n+879|\t\t\tconst createLabel = \"Create a new endpoint id\";\n+880|\t\t\tconst selected =\n+881|\t\t\t\tcandidates.length > 0\n+882|\t\t\t\t\t? await ctx.ui.select(\n+883|\t\t\t\t\t\t\t`Select ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint`,\n+884|\t\t\t\t\t\t\t[...candidates.map((candidate) => candidate.id), createLabel],\n+885|\t\t\t\t\t\t)\n+886|\t\t\t\t\t: createLabel;\n+887|\t\t\tif (!selected) return undefined;\n+888|\t\t\tif (selected !== createLabel) return selected;\n+889|\t\t\treturn (await ctx.ui.input(\"New SPT endpoint id\", \"letters, numbers, - or _\"))?.trim();\n+890|\t\t}\n+891|\n+892|\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\n+893|\t\tasync function chooseAutoResume(ctx) {\n+894|\t\t\tif (!ctx.hasUI) {\n+895|\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\n+896|\t\t\t\treturn undefined;\n+897|\t\t\t}\n+898|\t\t\tlet candidates;\n+899|\t\t\ttry {\n+900|\t\t\t\tcandidates = await compatibleCandidates(\"live_agent\", ctx);\n+901|\t\t\t} catch (error) {\n+902|\t\t\t\tlogError(\"omp-spt could not list live auto-resume candidates\", error);\n+903|\t\t\t\treturn undefined;\n+904|\t\t\t}\n+905|\t\t\tconst recent = (\n+906|\t\t\t\tawait Promise.all(\n+907|\t\t\t\t\tcandidates.map(async (candidate) => {\n+908|\t\t\t\t\t\ttry {\n+909|\t\t\t\t\t\t\tconst digest = parseJson(\n+910|\t\t\t\t\t\t\t\tawait runCommand([\n+911|\t\t\t\t\t\t\t\t\t\"--json\",\n+912|\t\t\t\t\t\t\t\t\t\"endpoint\",\n+913|\t\t\t\t\t\t\t\t\t\"digest\",\n+914|\t\t\t\t\t\t\t\t\tcandidate.id,\n+915|\t\t\t\t\t\t\t\t\t\"--last\",\n+916|\t\t\t\t\t\t\t\t\t\"1\",\n+917|\t\t\t\t\t\t\t\t]),\n+918|\t\t\t\t\t\t\t\t`spt endpoint digest ${candidate.id}`,\n+919|\t\t\t\t\t\t\t);\n+920|\t\t\t\t\t\t\treturn {\n+921|\t\t\t\t\t\t\t\t...candidate,\n+922|\t\t\t\t\t\t\t\tlastActiveAt: latestDigestTimestamp(digest),\n+923|\t\t\t\t\t\t\t};\n+924|\t\t\t\t\t\t} catch {\n+925|\t\t\t\t\t\t\treturn { ...candidate, lastActiveAt: Number.NEGATIVE_INFINITY };\n+926|\t\t\t\t\t\t}\n+927|\t\t\t\t\t}),\n+928|\t\t\t\t)\n+929|\t\t\t).filter((candidate) => Number.isFinite(candidate.lastActiveAt));\n+930|\t\t\trecent.sort(\n+931|\t\t\t\t(left, right) =>\n+932|\t\t\t\t\tright.lastActiveAt - left.lastActiveAt || left.id.localeCompare(right.id),\n+933|\t\t\t);\n+934|\t\t\tif (recent.length === 0) {\n+935|\t\t\t\tctx.ui.notify(\n+936|\t\t\t\t\t\"No compatible prior omp-spt live identity has recorded activity; use `/live <id>`\",\n+937|\t\t\t\t\t\"error\",\n+938|\t\t\t\t);\n+939|\t\t\t\treturn undefined;\n+940|\t\t\t}\n+941|\t\t\tlet candidate = recent[0];\n+942|\t\t\tconst ties = recent.filter((item) => item.lastActiveAt === candidate.lastActiveAt);\n+943|\t\t\tif (ties.length > 1) {\n+944|\t\t\t\tconst selected = await ctx.ui.select(\n+945|\t\t\t\t\t\"Select equally recent live endpoint\",\n+946|\t\t\t\t\tties.map((item) => item.id),\n+947|\t\t\t\t);\n+948|\t\t\t\tif (!selected) return undefined;\n+949|\t\t\t\tcandidate = ties.find((item) => item.id === selected);\n+950|\t\t\t}\n+951|\t\t\tconst confirmed = await ctx.ui.confirm(\n+952|\t\t\t\t\"Resume live endpoint?\",\n+953|\t\t\t\t`${candidate.id} was the most recently active compatible live endpoint (${new Date(\n+954|\t\t\t\t\tcandidate.lastActiveAt,\n+955|\t\t\t\t).toISOString()}). Bind this OMP session to it?`,\n+956|\t\t\t);\n+957|\t\t\treturn confirmed ? candidate.id : undefined;\n+958|\t\t}\n+959|\n+960|\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\n+961|\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\n+962|\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n+963|\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\n+964|\t\t\t\tctx.ui.notify(\n+965|\t\t\t\t\t\"SPT endpoint ids may contain only letters, numbers, `-`, and `_`\",\n+966|\t\t\t\t\t\"error\",\n+967|\t\t\t\t);\n+968|\t\t\t\treturn false;\n+969|\t\t\t}\n+970|\t\t\tif (activated || token) {\n+971|\t\t\t\tctx.ui.notify(\n+972|\t\t\t\t\t`This OMP session is immutably bound to ${id}; stop it before activating another identity`,\n+973|\t\t\t\t\t\"warning\",\n+974|\t\t\t\t);\n+975|\t\t\t\treturn false;\n+976|\t\t\t}\n+977|\t\t\tif (stopping) {\n+978|\t\t\t\tctx.ui.notify(\"This OMP session is already shutting down\", \"error\");\n+979|\t\t\t\treturn false;\n+980|\t\t\t}\n+981|\t\t\tif (activationPromise) return activationPromise;\n+982|\n+983|\t\t\truntimeCtx = ctx;\n+984|\t\t\tui = ctx.ui;\n+985|\t\t\tsid = ctx.sessionManager.getSessionId();\n+986|\t\t\tid = nextId;\n+987|\t\t\tactivationType = type;\n+988|\t\t\tlet bound = false;\n+989|\t\t\tconst operation = (async () => {\n+990|\t\t\t\tconst bindArgs = [\n+991|\t\t\t\t\t\"api\",\n+992|\t\t\t\t\t\"--adapter\",\n+993|\t\t\t\t\tADAPTER,\n+994|\t\t\t\t\t\"bind\",\n+995|\t\t\t\t\tid,\n+996|\t\t\t\t\t\"--set-session-id\",\n+997|\t\t\t\t\tsid,\n+998|\t\t\t\t];\n+999|\t\t\t\tif (type) bindArgs.push(\"--type\", type);\n+1000|\t\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n+1001|\t\t\t\tbindPromise = (async () => {\n+1002|\t\t\t\t\tconst response = await runCommand(bindArgs);\n+1003|\t\t\t\t\ttoken = response.match(/\\btoken=([^\\s]+)/)?.[1];\n+1004|\t\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n+1005|\t\t\t\t\tbound = true;\n+1006|\t\t\t\t})();\n+1007|\t\t\t\ttry {\n+1008|\t\t\t\t\tawait bindPromise;\n+1009|\t\t\t\t\tawait syncDesiredState();\n+1010|\t\t\t\t\tif (stopping) {\n+1011|\t\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n+1012|\t\t\t\t\t\treturn false;\n+1013|\t\t\t\t\t}\n+1014|\t\t\t\t\tactivated = true;\n+1015|\t\t\t\t\tstartupBriefPending = true;\n+1016|\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n+1017|\t\t\t\t\tstartListener();\n+1018|\t\t\t\t\tbeginUpdateProbe();\n+1019|\t\t\t\t\tif (options.announce) {\n+1020|\t\t\t\t\t\tui.notify(\n+1021|\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\n+1022|\t\t\t\t\t\t\t\"info\",\n+1023|\t\t\t\t\t\t);\n+1024|\t\t\t\t\t}\n+1025|\t\t\t\t\treturn true;\n+1026|\t\t\t\t} catch (error) {\n+1027|\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n+1028|\t\t\t\t\tif (options.fatal || bound) {\n+1029|\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n+1030|\t\t\t\t\t\treturn false;\n+1031|\t\t\t\t\t}\n+1032|\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\n+1033|\t\t\t\t\t\terror: errorSummary(error),\n+1034|\t\t\t\t\t});\n+1035|\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\n+1036|\t\t\t\t\tid = undefined;\n+1037|\t\t\t\t\tactivationType = undefined;\n+1038|\t\t\t\t\tbindPromise = undefined;\n+1039|\t\t\t\t\ttoken = undefined;\n+1040|\t\t\t\t\treturn false;\n+1041|\t\t\t\t}\n+1042|\t\t\t})();\n+1043|\t\t\tactivationPromise = operation;\n+1044|\t\t\ttry {\n+1045|\t\t\t\treturn await operation;\n+1046|\t\t\t} finally {\n+1047|\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\n+1048|\t\t\t}\n+1049|\t\t}\n+1050|\n+1051|\t\tasync function handleActivationCommand(type, args, ctx) {\n+1052|\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\n+1053|\t\t\tconst trimmed = args.trim();\n+1054|\t\t\tlet nextId;\n+1055|\t\t\tif (trimmed === \"--auto\") {\n+1056|\t\t\t\tif (type !== \"live_agent\") {\n+1057|\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\n+1058|\t\t\t\t\treturn;\n+1059|\t\t\t\t}\n+1060|\t\t\t\tnextId = await chooseAutoResume(ctx);\n+1061|\t\t\t} else if (!trimmed) {\n+1062|\t\t\t\tnextId = await chooseIdentity(type, ctx);\n+1063|\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\n+1064|\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\n+1065|\t\t\t\treturn;\n+1066|\t\t\t} else {\n+1067|\t\t\t\tnextId = trimmed;\n+1068|\t\t\t}\n+1069|\t\t\tif (!nextId) return;\n+1070|\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\n+1071|\t\t}\n+1072|\n+1073|\n 762|\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n 763|\t\t\tfor (const [controller, active] of activeCommands) {\n\n 774|\t\t\t}\n 775|\t\t}","firstChangedLine":760,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190749392}}
{"type":"message","id":"c3b8f0aa","parentId":"3baeb9f6","timestamp":"2026-07-16T08:32:34.445Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning command and tool registration insertion**"},{"type":"toolCall","id":"call_5uixNRWhHqeyzuNZ6lFczJu3|fc_08130c76df0d8af8016a5897220810819a934c2cc02395663a","name":"read","arguments":{"i":"Reading activation handler boundary","path":"adapter/strings/omp-spt.mjs","selector":"1015-1090"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":4327,"output":136,"cacheRead":169472,"cacheWrite":0,"totalTokens":173935,"reasoningTokens":94,"cost":{"input":0.021635,"output":0.00408,"cacheRead":0.08473599999999999,"cacheWrite":0,"total":0.110451}},"stopReason":"toolUse","timestamp":1784190749401,"responseId":"resp_08130c76df0d8af8016a58971dbe88819ab85b53d5871c80ef","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_08130c76df0d8af8016a58971fd8cc819a8d6561ffef5751a6","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJciMyz5xCKED1BxxqXlJ8wML-ybGr162wnhDPgaSQH2XbpKRE_GUzLLARJ-t9rHfkzBJ_0XS_CMTVv2cBN2CD8ERlJnvFdY8tvdeFgBZ3wDXBl3UsyKIwhfy8QdNFbZSaIH9epLkSKf2arm7zGMLanrzs20fDVIVlW-8AiGEWYmktYWtUkXZJfIY1_amGEnsNbzmDjnUMPBy66Dj9mpXZ4fVcVkwZsO8_7SW88zaFEcGRu-KF2_6XcIYHi2JxWPyXebbefVCgwe4ZR_vcE8fXPbBZJgjBCuZ2MP4lUkiCg5scpuSppA4RKwtZV18GhskZ2kHPUdZ8r2GbpU7U-i6LX1ZDEPBuRXXiqdxsM2VDWXGD0PVvecQXhl6G8PeWpxWrJyyCDM1TukorIyKIoJJxXmaMWE5phd1X4pbpxx8QPb_PIHuAtSg8QSDWZmLsiDIq8EWm62u59Lnz_kusd3gzt_Vv6D9QXSDoam3oE9B2HzrML8jlT3wBS4w2peRpNR-CajzTKlSQg1_s6QO8pJnTeLYL2UXOxyf-0lMnMYsuPa_OuScAXLAINy5_SPk0ndQ_5YpQmUELO1zxm2VPGAYc2y-eDGH0ACeA6GdJGt6t9UCMn1gyJV5YJL9cFQfHetOYf8N8bVud8TyKaNSVHZi1X1DzdUR9Q4VLQNICdsSd2raXVQd-dsQF0_eONC3OuPAb3Y1pOlVusjRspvlcBsOpuUtk-HbZR0ewRGLCEJL1NezHPNgFWCASZiKtWPdmC83PnwZ-NJAJYnMMJKGgQxELvjGGWU96xI6j7yujBWnyOIQxRzNjGWCITiiXl-K-EYOg0XehO6N3jgEWcrf3AUGuIDl-_LhIIqbkkaAu6GHrQKPLqtlKD41QHAt5-Owb9xznyBWIhBb2xKDw_zz0U41BC50t09uIT38VZL_Wyuc-nc8e7XHiBiwS9_vlOsQaRlAvOk533xtjbnM74g9_IV0yjIAgQDL1JfUznev5cUTVfsPZEBVJF5HCfU6Jqt0kXw2OWD7kaH6OC2enn6WBr79sdPQJAHIiFrgzmUWvcQnN62FYByn-pyOnRNVbUOc4n5qMEryoFVC_lQtMZLyWuLdpBxWbAgE7NyppcoVtssUNBT7uyXyMAyBFtJ4z56NzEbcIuy6n1XTUoiOKEWgAd0-E7V5GUqFNLW6wEvfrt0GQup4dROx6YhPuUjhHf8UdqwcQZp4HqrbmWASYhUsnJIfBVq9dvgdTsuPfy4rbamQWKPtnqlocEtbiYIFIOe05csgMsGB2Szj91MHgpRb4ofL0KQhfsaxaZhbYdrmuqJUctFCR8KD6Nqc4o2VBrdyBmBzS8GOizTT--aTEa9fn5U8d5Nj_3ek9z1g28DXVNsorAm73DKjJAQfl8Odv2kha_QYCiAYvu8YPF2QIpf-bZ99cShY3PU1y0-xc4QPeFmoCOB9ivXCfOi7R3W28WfZRYJ3S1NSifecvNWgaWUQ3CfMzJbIQDHl7P-ky90_x2K1Nuaj67pB7oN6qHSt24YQyTy2Ec-","summary":[{"type":"summary_text","text":"**Planning command and tool registration insertion**"}]},{"id":"fc_08130c76df0d8af8016a5897220810819a934c2cc02395663a","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading activation handler boundary\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1015-1090\"}","call_id":"call_5uixNRWhHqeyzuNZ6lFczJu3","name":"read"}]},"duration":5043.465299999807,"ttft":2429.560399999842,"contextSnapshot":{"promptTokens":173799,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_5uixNRWhHqeyzuNZ6lFczJu3|fc_08130c76df0d8af8016a5897220810819a934c2cc02395663a","toolName":"read","startedAt":"2026-07-16T08:32:34.445Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading activation handler boundary"},"id":"f4b7d900","parentId":"c3b8f0aa","timestamp":"2026-07-16T08:32:34.445Z"}
{"type":"message","id":"14a60ac2","parentId":"f4b7d900","timestamp":"2026-07-16T08:32:34.464Z","message":{"role":"toolResult","toolCallId":"call_5uixNRWhHqeyzuNZ6lFczJu3|fc_08130c76df0d8af8016a5897220810819a934c2cc02395663a","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#60FE]\n962:\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n…\n989:\t\t\tconst operation = (async () => {\n…\n1007:\t\t\t\ttry {\n…\n1014:\t\t\t\t\tactivated = true;\n1015:\t\t\t\t\tstartupBriefPending = true;\n1016:\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n1017:\t\t\t\t\tstartListener();\n1018:\t\t\t\t\tbeginUpdateProbe();\n1019:\t\t\t\t\tif (options.announce) {\n1020:\t\t\t\t\t\tui.notify(\n1021:\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\n1022:\t\t\t\t\t\t\t\"info\",\n1023:\t\t\t\t\t\t);\n1024:\t\t\t\t\t}\n1025:\t\t\t\t\treturn true;\n1026:\t\t\t\t} catch (error) {\n1027:\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1028:\t\t\t\t\tif (options.fatal || bound) {\n1029:\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1030:\t\t\t\t\t\treturn false;\n1031:\t\t\t\t\t}\n1032:\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\n1033:\t\t\t\t\t\terror: errorSummary(error),\n1034:\t\t\t\t\t});\n1035:\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\n1036:\t\t\t\t\tid = undefined;\n1037:\t\t\t\t\tactivationType = undefined;\n1038:\t\t\t\t\tbindPromise = undefined;\n1039:\t\t\t\t\ttoken = undefined;\n1040:\t\t\t\t\treturn false;\n1041:\t\t\t\t}\n1042:\t\t\t})();\n1043:\t\t\tactivationPromise = operation;\n1044:\t\t\ttry {\n1045:\t\t\t\treturn await operation;\n1046:\t\t\t} finally {\n1047:\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\n1048:\t\t\t}\n1049:\t\t}\n1050:\n1051:\t\tasync function handleActivationCommand(type, args, ctx) {\n1052:\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\n1053:\t\t\tconst trimmed = args.trim();\n1054:\t\t\tlet nextId;\n1055:\t\t\tif (trimmed === \"--auto\") {\n1056:\t\t\t\tif (type !== \"live_agent\") {\n1057:\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\n1058:\t\t\t\t\treturn;\n1059:\t\t\t\t}\n1060:\t\t\t\tnextId = await chooseAutoResume(ctx);\n1061:\t\t\t} else if (!trimmed) {\n1062:\t\t\t\tnextId = await chooseIdentity(type, ctx);\n1063:\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\n1064:\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\n1065:\t\t\t\treturn;\n1066:\t\t\t} else {\n1067:\t\t\t\tnextId = trimmed;\n1068:\t\t\t}\n1069:\t\t\tif (!nextId) return;\n1070:\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\n1071:\t\t}\n1072:\n1073:\n1074:\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n1075:\t\t\tfor (const [controller, active] of activeCommands) {\n1076:\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\n1077:\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\n1078:\t\t\t\t\tactive.abortTimer = setTimer(\n1079:\t\t\t\t\t\t() => controller.abort(reason),\n1080:\t\t\t\t\t\tshutdownCommandTimeoutMs,\n1081:\t\t\t\t\t);\n1082:\t\t\t\t\tactive.abortTimer?.unref?.();\n1083:\t\t\t\t\tcontinue;\n1084:\t\t\t\t}\n1085:\t\t\t\tcontroller.abort(reason);\n1086:\t\t\t}\n1087:\t\t}\n1088:\n1089:\t\tfunction waitForRetry(delay) {\n1090:\t\t\tif (shutdownMode) return Promise.resolve();\n1091:\t\t\treturn new Promise((resolve) => {\n1092:\t\t\t\tlet timer;\n1093:\t\t\t\tconst finish = () => {\n…\n1097:\t\t\t\t};\n…\n1101:\t\t\t});\n1102:\t\t}\n\n[Showing lines 1014-1093 of 1702. Use :1094 to continue]"}],"details":{"truncation":{"content":"\t\t\t\t\tactivated = true;\r\n\t\t\t\t\tstartupBriefPending = true;\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t\t\t\tstartListener();\r\n\t\t\t\t\tbeginUpdateProbe();\r\n\t\t\t\t\tif (options.announce) {\r\n\t\t\t\t\t\tui.notify(\r\n\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\r\n\t\t\t\t\t\t\t\"info\",\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\t\tif (options.fatal || bound) {\r\n\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\r\n\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t});\r\n\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\r\n\t\t\t\t\tid = undefined;\r\n\t\t\t\t\tactivationType = undefined;\r\n\t\t\t\t\tbindPromise = undefined;\r\n\t\t\t\t\ttoken = undefined;\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t})();\r\n\t\t\tactivationPromise = operation;\r\n\t\t\ttry {\r\n\t\t\t\treturn await operation;\r\n\t\t\t} finally {\r\n\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tasync function handleActivationCommand(type, args, ctx) {\r\n\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\r\n\t\t\tconst trimmed = args.trim();\r\n\t\t\tlet nextId;\r\n\t\t\tif (trimmed === \"--auto\") {\r\n\t\t\t\tif (type !== \"live_agent\") {\r\n\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tnextId = await chooseAutoResume(ctx);\r\n\t\t\t} else if (!trimmed) {\r\n\t\t\t\tnextId = await chooseIdentity(type, ctx);\r\n\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\r\n\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\r\n\t\t\t\treturn;\r\n\t\t\t} else {\r\n\t\t\t\tnextId = trimmed;\r\n\t\t\t}\r\n\t\t\tif (!nextId) return;\r\n\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\r\n\t\t}\r\n\r\n\r\n\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\r\n\t\t\tfor (const [controller, active] of activeCommands) {\r\n\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\r\n\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\r\n\t\t\t\t\tactive.abortTimer = setTimer(\r\n\t\t\t\t\t\t() => controller.abort(reason),\r\n\t\t\t\t\t\tshutdownCommandTimeoutMs,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tactive.abortTimer?.unref?.();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tcontroller.abort(reason);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction waitForRetry(delay) {\r\n\t\t\tif (shutdownMode) return Promise.resolve();\r\n\t\t\treturn new Promise((resolve) => {\r\n\t\t\t\tlet timer;\r\n\t\t\t\tconst finish = () => {\r","truncated":true,"truncatedBy":"lines","totalLines":689,"totalBytes":2496,"outputLines":80,"outputBytes":2496,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n…\n\t\t\tconst operation = (async () => {\n…\n\t\t\t\ttry {\n…\n\t\t\t\t\tactivated = true;\r\n\t\t\t\t\tstartupBriefPending = true;\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t\t\t\tstartListener();\r\n\t\t\t\t\tbeginUpdateProbe();\r\n\t\t\t\t\tif (options.announce) {\r\n\t\t\t\t\t\tui.notify(\r\n\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\r\n\t\t\t\t\t\t\t\"info\",\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\t\tif (options.fatal || bound) {\r\n\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\r\n\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t});\r\n\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\r\n\t\t\t\t\tid = undefined;\r\n\t\t\t\t\tactivationType = undefined;\r\n\t\t\t\t\tbindPromise = undefined;\r\n\t\t\t\t\ttoken = undefined;\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t})();\r\n\t\t\tactivationPromise = operation;\r\n\t\t\ttry {\r\n\t\t\t\treturn await operation;\r\n\t\t\t} finally {\r\n\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tasync function handleActivationCommand(type, args, ctx) {\r\n\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\r\n\t\t\tconst trimmed = args.trim();\r\n\t\t\tlet nextId;\r\n\t\t\tif (trimmed === \"--auto\") {\r\n\t\t\t\tif (type !== \"live_agent\") {\r\n\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tnextId = await chooseAutoResume(ctx);\r\n\t\t\t} else if (!trimmed) {\r\n\t\t\t\tnextId = await chooseIdentity(type, ctx);\r\n\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\r\n\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\r\n\t\t\t\treturn;\r\n\t\t\t} else {\r\n\t\t\t\tnextId = trimmed;\r\n\t\t\t}\r\n\t\t\tif (!nextId) return;\r\n\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\r\n\t\t}\r\n\r\n\r\n\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\r\n\t\t\tfor (const [controller, active] of activeCommands) {\r\n\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\r\n\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\r\n\t\t\t\t\tactive.abortTimer = setTimer(\r\n\t\t\t\t\t\t() => controller.abort(reason),\r\n\t\t\t\t\t\tshutdownCommandTimeoutMs,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tactive.abortTimer?.unref?.();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tcontroller.abort(reason);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction waitForRetry(delay) {\r\n\t\t\tif (shutdownMode) return Promise.resolve();\r\n\t\t\treturn new Promise((resolve) => {\r\n\t\t\t\tlet timer;\r\n\t\t\t\tconst finish = () => {\r\n…\n\t\t\t\t};\n…\n\t\t\t});\n\t\t}","startLine":962,"lineNumbers":[962,null,989,null,1007,null,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,null,1097,null,1101,1102]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1702,"totalBytes":2496,"outputLines":80,"outputBytes":2496,"shownRange":{"start":1014,"end":1093},"nextOffset":1094}}},"isError":false,"timestamp":1784190754463}}
{"type":"message","id":"ee99a8e5","parentId":"14a60ac2","timestamp":"2026-07-16T08:32:55.204Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Refining activation type checks**\n\n**Fixing closure array mutation**"},{"type":"toolCall","id":"call_loTYgWVoqMuAwuUMBnd53T6r|ctc_0f36c92426b13ab2016a58972a0fe08198af7d9f2f4b99bafb","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#60FE]\nINS.POST 1071:\n+\t\tpi.registerCommand(\"ready\", {\n+\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\n+\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\n+\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n+\t\t});\n+\n+\t\tpi.registerCommand(\"live\", {\n+\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\n+\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\n+\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n+\t\t});\n+\n+\t\t// [impl->REQ-PARITY-CHECKPOINT]\n+\t\tpi.registerTool({\n+\t\t\tname: \"spt_checkpoint\",\n+\t\t\tlabel: \"SPT Checkpoint\",\n+\t\t\tdescription:\n+\t\t\t\t\"After the commune skill has saved this live endpoint's continuity drop, compact native OMP context and wake the same endpoint.\",\n+\t\t\tparameters: checkpointParameters(pi),\n+\t\t\tasync execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {\n+\t\t\t\tif (!activated || !id) {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"SPT checkpoint failed: no active endpoint.\" }],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"not-activated\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t\tif (activationType === \"ready_agent\") {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t\tconst wake =\n+\t\t\t\t\tparameters.wake?.trim() ||\n+\t\t\t\t\t\"Resume from the saved commune context and continue the prior work.\";\n+\t\t\t\ttry {\n+\t\t\t\t\tawait ctx.compact({\n+\t\t\t\t\t\tinternalGuidance:\n+\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n+\t\t\t\t\t});\n+\t\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t\t{\n+\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n+\t\t\t\t\t\t\tcontent: wake,\n+\t\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t\t},\n+\t\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t\t);\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: `SPT checkpoint complete for ${id}; native continuation queued.`,\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: true, endpoint: id },\n+\t\t\t\t\t};\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: ${errorSummary(error)}`,\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: errorSummary(error) },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t},\n+\t\t});\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1351,"output":1020,"cacheRead":173568,"cacheWrite":0,"totalTokens":175939,"reasoningTokens":277,"cost":{"input":0.006755000000000001,"output":0.030600000000000002,"cacheRead":0.086784,"cacheWrite":0,"total":0.124139}},"stopReason":"toolUse","timestamp":1784190754480,"responseId":"resp_0f36c92426b13ab2016a589722ce508198b660d7dcb8f8cbf3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0f36c92426b13ab2016a589724a9488198b0617346e748d018","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJcqFK-2iULuwWFW0qfdb9CeraG_5ZO1Q54TkapDBCJysRyp5mmJ-KCUDG1M2z18ZJhC0f3GXAtCO7OiFPfjrUF-zjJDn6ZtZg0QFjcbmOWzA4rW3rAxmlUBnG3mTnMqCNRYbgiAvqRfGi9zpDPVhFrDan-TEJ683f4vIsG-87v6Su9-4uAEFcrtToaDcRX37Mup2Pw8VgbxkhgfMQPu3H5soXSwnf9pdMclTiz2xcHY7ND-2xVVqX7KPv8mGWGsGTaxlUufOcofdy9CI5EJ4Q_8vdW6t_ntg1fsMyJrtov4qFT34pnjIB62sXeIw1xUgRgVQpoLB-iPHx0rqQXQEkCpbmasflEHfrP58lXDxWnXfZR0OGi3t0nEHlDf63p2OZ-0RhOlE4P8NiGMkc8tbdhvMgfsjaLOHXzCc9n4hlrfp_PXRB4VYuZWKw8MxgQkz6mJcrpLCOvq8F52IiVMZ24uacXrMVt-cgVlm-vza3W0Ep82kLepC-s4OVCxohRTVYGCPXnSsCHfjV2Mct4fcL-IKucKDSa8OUX3Sjkddr6ePdHoandZXVYd_LvRGqU_6t6I1-okGGhudAwzxGK7kOZcepPdFIONxyvWnynOSgqaR2uCUSkWz9zZzlm2CZN1fJeV-8FwPjFkKlWKsdwO3YLFi6ox8ZuAYGPDKbNzl8Fo_zeawNlfgkVwlQ8K8C7s_sknsYQFQNfZ7KSqtafpeD0qwrrt46UJ5HV0dBCVFBXWiRyvrX1xqwA1wk2CdDEmtAw8odthNwr_6rTxGuSZwUSR-XU6Z5mHVVd0-tDTYYIS5T2z2Tw6fxbHXx-tJTwViUpejkiWdZ8Eok78YDPct_vQ0pMbqFO9h4KGOPtkcQpmMTDzpKATNs2BxlB6i5rp5nCDgKFJZ5KKeaIhDEmkVs8fk0s0-4IeL3cHv4L9HIJez7ar3XKjHNOFRyt1dKBOD_XT2NiUddffWS6Fme1MLUSp4WReqvAyGXYA2bBq0mg-5vu6pLVCCSn75zquuj3t8u30-zl5SgqAFhL8QJbtBM_TpbJARGASs5gb0eyc3XT-qoOM5tdrmtCOBUBouHTF8tMeTibYJ1fYpxGEYmZDh5Vxfrl4sN_XW1-hFCxQ4lnCDx6A3dZ67lTnCkAOK7Kr-n01vAUXBaZgjpFiFdJ5sdqrUUvBzuKcdwDuWtDKm_VFqeil-dEClOBwAn-qrxmOsHwgK3eepFdYnD8DNufh1PqRw47qjElf7sEaLZRxpuP2xusB1qvffFwCd_LoHOt58zYOVXiC7ih4MLXKA079ChZMLp61XQ8TKk351zPoisohfB_uxO7WgxKetTUlmmyHV3vVD6yCZW8CxIpWwzmcoKxSl_991UW7drEX-OH5JBJq5-U62sLsw3_RRuj5GUBwK4X_kROmySirazBme7YzYnC4YsxcYkj7xtT0vwUo3c03aF1U6_V7WC_ACX5ByItk6brKO3Il15xa40x0vBFsqdV0lkk4FD2aCitMvmqz7pNr5EtgWciRy-pDIAhjqzzdJ1YTAyIXXHnXCXi2QXpYyyMH4oVW-RPEb0TdBDUtjJS1u2CJ72sCJBe8oOtIBOtxX-4vkpzpHBCBM2HahHIfqBCemhg_t0dFUe2PwYiMcgbNIjXvuxsxIQ5Aiy2yzXhg5X7wocnDyfLojWvdieNsjeMUyPLcxZp65jRlzX6Q2p9YyuYkr6cWEgx92keqLgxFJIpDX5XRty1rAmGft3XoWxJwrOzLrY5JHaTWXOKWvE2JzCne6zzdi71Ww7IndvtxrAhpj0cWr6bTv5sSfNc-eanR_jHaBU_6batozgXJun1TgiWk3OQDonzmX1VvDlPqcPLPrJNloU8djWybC_BuyMYtSXfqsGzE3N-B94XrZvgbntzX6qeSt_4Sp9DbeVoR664uD106B2Z_59_TOZAms4WAFv0u_2X4Rj2PVLrTkJQlf6yebir3yFKk2zmMOk1Zr8LsKZV-MbQp38NIpXz95MpBHS4wkdnHpV-qK1yo_-K75nD6764l7yUMNwe1GAxY_0nwPfYHoEMipMi2PTOEmWLVdPVSMoep3V6KL3bijItIw2Ry9pNdgS8zarFotxiB0Z0_DbJ0RzJeUtuK0Sts6GelIaEkTDPMbKxey27YAYdERqnRcOOAirpdpIPg-o6oJw0mILbYNuAt-8aqy9mw5xXhyT-daa_unMhHqnm3lfId30RoWNNbFMnunqiASyb4-ikNr1S2HQiRq7LmLNcrZlLZfaECN1G_B8tpOX8ywjS3eN3lUlhHlTm6xEQQV6pJrBGJMElhsb7Ro40as83JQ1MC3xUQ1PgS1iO9cS2jpHmEdYPytYWlX8gzimvQTAcdfjfu0WLmY18_ndn5MVWzr_Gxr3vx5RgRwl0bmCMgj_nTRiQTBpP2cUR2umKtUXsTKjLKJV9Kgtq8mJkYT6Boxj9_hMADmVFCtyg99Tv8pk3O-VKUcfJoqZCHP_SM58tNyV3FWIT957Fwfw1ALhTwr0TyZQeRkEb-4tVvDnlrwwmT5rc0Dz5sI5v6SURDt7vvOXfmHu1VHSdWo90b5cUcrrJ_Q6tfyiqGMS6uvow5j5SRL4XA4pwzvu_tdibC_64Z6ChtvNy-ZSGOIXVXgBDSdkq9HqBdBG6bxUM_naU6z4_CQsRbtNYN0ErWW2Ded1w2THJ7JOAL6Hm6yPjJ2dNuETH1VhaGhQSbu_7Vgbl_pfhlgWg=","summary":[{"type":"summary_text","text":"**Refining activation type checks**"},{"type":"summary_text","text":"**Fixing closure array mutation**"}]},{"id":"ctc_0f36c92426b13ab2016a58972a0fe08198af7d9f2f4b99bafb","type":"custom_tool_call","status":"completed","call_id":"call_loTYgWVoqMuAwuUMBnd53T6r","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#60FE]\nINS.POST 1071:\n+\t\tpi.registerCommand(\"ready\", {\n+\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\n+\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\n+\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n+\t\t});\n+\n+\t\tpi.registerCommand(\"live\", {\n+\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\n+\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\n+\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n+\t\t});\n+\n+\t\t// [impl->REQ-PARITY-CHECKPOINT]\n+\t\tpi.registerTool({\n+\t\t\tname: \"spt_checkpoint\",\n+\t\t\tlabel: \"SPT Checkpoint\",\n+\t\t\tdescription:\n+\t\t\t\t\"After the commune skill has saved this live endpoint's continuity drop, compact native OMP context and wake the same endpoint.\",\n+\t\t\tparameters: checkpointParameters(pi),\n+\t\t\tasync execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {\n+\t\t\t\tif (!activated || !id) {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"SPT checkpoint failed: no active endpoint.\" }],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"not-activated\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t\tif (activationType === \"ready_agent\") {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t\tconst wake =\n+\t\t\t\t\tparameters.wake?.trim() ||\n+\t\t\t\t\t\"Resume from the saved commune context and continue the prior work.\";\n+\t\t\t\ttry {\n+\t\t\t\t\tawait ctx.compact({\n+\t\t\t\t\t\tinternalGuidance:\n+\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n+\t\t\t\t\t});\n+\t\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t\t{\n+\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n+\t\t\t\t\t\t\tcontent: wake,\n+\t\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t\t},\n+\t\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t\t);\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: `SPT checkpoint complete for ${id}; native continuation queued.`,\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: true, endpoint: id },\n+\t\t\t\t\t};\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: ${errorSummary(error)}`,\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: errorSummary(error) },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t},\n+\t\t});\n*** End Patch\n","name":"edit"}]},"duration":20723.76049999986,"ttft":2186.238099999726,"contextSnapshot":{"promptTokens":174919,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_loTYgWVoqMuAwuUMBnd53T6r|ctc_0f36c92426b13ab2016a58972a0fe08198af7d9f2f4b99bafb","toolName":"edit","startedAt":"2026-07-16T08:32:55.206Z"},"id":"617cd346","parentId":"ee99a8e5","timestamp":"2026-07-16T08:32:55.206Z"}
{"type":"message","id":"120d4715","parentId":"617cd346","timestamp":"2026-07-16T08:32:55.232Z","message":{"role":"toolResult","toolCallId":"call_loTYgWVoqMuAwuUMBnd53T6r|ctc_0f36c92426b13ab2016a58972a0fe08198af7d9f2f4b99bafb","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#D27D]\n1051:\t\tasync function handleActivationCommand(type, args, ctx) {\n\n1070:\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\n1071:\t\t}\n1072:\t\tpi.registerCommand(\"ready\", {\n1073:\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\n1074:\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\n1075:\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n1076:\t\t});\n1077:\n1078:\t\tpi.registerCommand(\"live\", {\n1079:\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\n1080:\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\n1081:\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n1082:\t\t});\n1083:\n1084:\t\t// [impl->REQ-PARITY-CHECKPOINT]\n1085:\t\tpi.registerTool({\n…\n1151:\n1152:\n1153:\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n1154:\t\t\tfor (const [controller, active] of activeCommands) {\n\n1165:\t\t\t}\n1166:\t\t}"}],"details":{"diff":" 1051|\t\tasync function handleActivationCommand(type, args, ctx) {\n\n 1070|\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\n 1071|\t\t}\n+1072|\t\tpi.registerCommand(\"ready\", {\n+1073|\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\n+1074|\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\n+1075|\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n+1076|\t\t});\n 1072|\n+1078|\t\tpi.registerCommand(\"live\", {\n+1079|\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\n+1080|\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\n+1081|\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n+1082|\t\t});\n 1073|\n+1084|\t\t// [impl->REQ-PARITY-CHECKPOINT]\n+1085|\t\tpi.registerTool({\n+1086|\t\t\tname: \"spt_checkpoint\",\n+1087|\t\t\tlabel: \"SPT Checkpoint\",\n+1088|\t\t\tdescription:\n+1089|\t\t\t\t\"After the commune skill has saved this live endpoint's continuity drop, compact native OMP context and wake the same endpoint.\",\n+1090|\t\t\tparameters: checkpointParameters(pi),\n+1091|\t\t\tasync execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {\n+1092|\t\t\t\tif (!activated || !id) {\n+1093|\t\t\t\t\treturn {\n+1094|\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"SPT checkpoint failed: no active endpoint.\" }],\n+1095|\t\t\t\t\t\tdetails: { ok: false, reason: \"not-activated\" },\n+1096|\t\t\t\t\t\tisError: true,\n+1097|\t\t\t\t\t};\n+1098|\t\t\t\t}\n+1099|\t\t\t\tif (activationType === \"ready_agent\") {\n+1100|\t\t\t\t\treturn {\n+1101|\t\t\t\t\t\tcontent: [\n+1102|\t\t\t\t\t\t\t{\n+1103|\t\t\t\t\t\t\t\ttype: \"text\",\n+1104|\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n+1105|\t\t\t\t\t\t\t},\n+1106|\t\t\t\t\t\t],\n+1107|\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\n+1108|\t\t\t\t\t\tisError: true,\n+1109|\t\t\t\t\t};\n+1110|\t\t\t\t}\n+1111|\t\t\t\tconst wake =\n+1112|\t\t\t\t\tparameters.wake?.trim() ||\n+1113|\t\t\t\t\t\"Resume from the saved commune context and continue the prior work.\";\n+1114|\t\t\t\ttry {\n+1115|\t\t\t\t\tawait ctx.compact({\n+1116|\t\t\t\t\t\tinternalGuidance:\n+1117|\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n+1118|\t\t\t\t\t});\n+1119|\t\t\t\t\tpi.sendMessage(\n+1120|\t\t\t\t\t\t{\n+1121|\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n+1122|\t\t\t\t\t\t\tcontent: wake,\n+1123|\t\t\t\t\t\t\tdisplay: true,\n+1124|\t\t\t\t\t\t\tattribution: \"user\",\n+1125|\t\t\t\t\t\t},\n+1126|\t\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+1127|\t\t\t\t\t);\n+1128|\t\t\t\t\treturn {\n+1129|\t\t\t\t\t\tcontent: [\n+1130|\t\t\t\t\t\t\t{\n+1131|\t\t\t\t\t\t\t\ttype: \"text\",\n+1132|\t\t\t\t\t\t\t\ttext: `SPT checkpoint complete for ${id}; native continuation queued.`,\n+1133|\t\t\t\t\t\t\t},\n+1134|\t\t\t\t\t\t],\n+1135|\t\t\t\t\t\tdetails: { ok: true, endpoint: id },\n+1136|\t\t\t\t\t};\n+1137|\t\t\t\t} catch (error) {\n+1138|\t\t\t\t\treturn {\n+1139|\t\t\t\t\t\tcontent: [\n+1140|\t\t\t\t\t\t\t{\n+1141|\t\t\t\t\t\t\t\ttype: \"text\",\n+1142|\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: ${errorSummary(error)}`,\n+1143|\t\t\t\t\t\t\t},\n+1144|\t\t\t\t\t\t],\n+1145|\t\t\t\t\t\tdetails: { ok: false, reason: errorSummary(error) },\n+1146|\t\t\t\t\t\tisError: true,\n+1147|\t\t\t\t\t};\n+1148|\t\t\t\t}\n+1149|\t\t\t},\n+1150|\t\t});\n+1151|\n+1152|\n 1074|\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n 1075|\t\t\tfor (const [controller, active] of activeCommands) {\n\n 1086|\t\t\t}\n 1087|\t\t}","firstChangedLine":1071,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190775231}}
{"type":"message","id":"bd2de902","parentId":"120d4715","timestamp":"2026-07-16T08:32:59.988Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Assigning AgentSurface checkpoint and planning tests**"},{"type":"toolCall","id":"call_6LODvOYZenmPnwGXCFWQAUGB|fc_0b430c62077a6ffa016a58973bac34819b846f81e5394b1e4d","name":"grep","arguments":{"i":"Locating activation candidate cache","pattern":"cachedReadyIds =|cachedLiveIds =","path":"adapter/strings/omp-spt.mjs","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1660,"output":129,"cacheRead":174592,"cacheWrite":0,"totalTokens":176381,"reasoningTokens":64,"cost":{"input":0.0083,"output":0.00387,"cacheRead":0.087296,"cacheWrite":0,"total":0.099466}},"stopReason":"toolUse","timestamp":1784190775257,"responseId":"resp_0b430c62077a6ffa016a5897379240819ba5cd93890393dbbd","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0b430c62077a6ffa016a5897390004819bb0fa6c04e28ef91e","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJc7UezUzusve3Lrg5R59C42b4NwYATYGZ1io2SNbX4AyR03qwJPxR18Fc_PuNmD9eGTRafa_tQv52bhRX7RT6k6SF_JvXx1641aAltbJO2XZimlFZkPELTZ8dJAPK3tzzjLGnyr7S43thSexAU1CHSSUqZgLovoMjrIZ3EJ-YGfgZ2S12tmOJfM2LeJPz1rASAjQ7N_6d_C8rD8B2Hfr-t1yUG6mkInElcBo5awjoCoRfQsSYVN2Cq7A7DevK7LRIMKqzbB1Fwi2krL_usdYrT2aqHWbd5JrJqHC9TGavMAZh7nIrF62EpNM4SVRT6vGDGyw5wBODqoTLg0jEaH_8m5yZVwZnKh5w-SVrHgAju0ApwtzDKaAkHh_Az2-2n5rbZNxOYF-f_fdy3opzvlEBiotzNGPE5oo2g-kFgp1q_nyfC2mKif3p9W1FNOqnBBwuzGx6Xqfkcyn-3akVY7BBWwTI8T0q6CWJqVLiGhrMfDJvgShOlMZT9JXRNFyTynTF0BEaW5zeI8NMq84C8Z3VJ4BFD8NnmTvGtD-PJx9GRfJdgxe1K8oYMMsUrkorHvMzztDcn8YT_e5aTDkBZnEv5J6-AG30I7GIYsOfR-rs4Z4QV9h8WmIoZ0cobIltiXcq0CGHL80MSFtqPCVzxf6x46uMC7wDfuUps8t1i_2_9qi2q8b17Sj9FN-caj_MuIxzg8nEX5pQW0vgaiaRP5xIRtiuPucggqHQic04X5uRMX_niv9NJo2hSsG5Exg68oiK1DxB7QmDPgYqoLBS4Rzgmqc0TAM26WwEdqUfuYKx5o5hdle0q6OHs8XzWBMbE2lbrMnMOJbHwNRD_0-QPSXsh2H_mwVb79E3JQPQGwFCw9U92Dq4m9OqgXas2O1Go-xPWWvLcuIgy4d5NdL4TAneh7At-MMv1DwOUWyod1nWZ9aF-VRLyXqEb_Ycd4tDdSpdPQB2ljdWIf0DN26gQglz3HkoBy2ltLNTHfXefvJGp0w5uTFfMsMU7CnFzJX74gLHCesr0tFz2GQtHe4sTR-z7_40bwiXzByPqmYwAV8gvLcGHtDc1nCw_n6ZLVfWA_DMU1ESTDLgP3Fpo8XKBShvOK5r264ytmVRPranNqXjYflWI_-nXCB0vIx0THwE2FWt2qUcgFUUG7p4wpE4tsOgTsP-q6JFUptPf2oR5-S6RBjbfRt5c4Fv9Nq4S24DJaORiO4c_aGz2AKvQAqTQ4EJjmKafe3zcP0uZ-qSUiXpLmTPf3b-iqp6BqG3oD50YHWTHHm9eRZz2PyKxGxTyIGGuChWLoaRyCx5PZqLdLPLtxVsOZM9fWMvdFEsAzAthjK1SJ","summary":[{"type":"summary_text","text":"**Assigning AgentSurface checkpoint and planning tests**"}]},{"id":"fc_0b430c62077a6ffa016a58973bac34819b846f81e5394b1e4d","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating activation candidate cache\",\"pattern\":\"cachedReadyIds =|cachedLiveIds =\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_6LODvOYZenmPnwGXCFWQAUGB","name":"grep"}]},"duration":4730.7634999998845,"ttft":1745.5962999998592,"contextSnapshot":{"promptTokens":176252,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_6LODvOYZenmPnwGXCFWQAUGB|fc_0b430c62077a6ffa016a58973bac34819b846f81e5394b1e4d","toolName":"grep","startedAt":"2026-07-16T08:32:59.988Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Locating activation candidate cache"},"id":"427ee01f","parentId":"bd2de902","timestamp":"2026-07-16T08:32:59.988Z"}
{"type":"message","id":"2e55b1ef","parentId":"427ee01f","timestamp":"2026-07-16T08:32:59.991Z","message":{"role":"toolResult","toolCallId":"call_6LODvOYZenmPnwGXCFWQAUGB|fc_0b430c62077a6ffa016a58973bac34819b846f81e5394b1e4d","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#D27D]\n 658:\t\tlet updateNoticesPending = true;\n*659:\t\tlet cachedReadyIds = [];\n*660:\t\tlet cachedLiveIds = [];\n 661:\n 662:\t\tlet sid;\n 663:\t\tlet token;\n...\n 858:\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n*859:\t\t\tif (type === \"ready_agent\") cachedReadyIds = ids;\n*860:\t\t\telse cachedLiveIds = ids;\n 861:\t\t\treturn candidates;\n 862:\t\t}\n 863:"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":4,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":4}],"truncated":false,"displayContent":" 658│\t\tlet updateNoticesPending = true;\n*659│\t\tlet cachedReadyIds = [];\n*660│\t\tlet cachedLiveIds = [];\n 661│\n 662│\t\tlet sid;\n 663│\t\tlet token;\n    │...\n 858│\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n*859│\t\t\tif (type === \"ready_agent\") cachedReadyIds = ids;\n*860│\t\t\telse cachedLiveIds = ids;\n 861│\t\t\treturn candidates;\n 862│\t\t}\n 863│"},"isError":false,"timestamp":1784190779991}}
{"type":"message","id":"5316ef99","parentId":"2e55b1ef","timestamp":"2026-07-16T08:33:04.456Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Editing targeted code lines**"},{"type":"toolCall","id":"call_P0syCTRMTdaNnKY7zm47Ce3d|ctc_0d5d9a673ec9d120016a58973f405081999aff35e80d55eab9","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#D27D]\nSWAP 859.=860:\n+\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\n+\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":904,"output":92,"cacheRead":175616,"cacheWrite":0,"totalTokens":176612,"reasoningTokens":7,"cost":{"input":0.004520000000000001,"output":0.00276,"cacheRead":0.087808,"cacheWrite":0,"total":0.09508799999999999}},"stopReason":"toolUse","timestamp":1784190780035,"responseId":"resp_0d5d9a673ec9d120016a58973cacd481999f7b21f67118b695","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0d5d9a673ec9d120016a58973ed8b08199a8449e343fab4b06","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJc_DHHq3_0hc58AU70qGCTrtBCDvwdPjpbWD7thDK2u9FqTSDcc-AaHEqEJrzLb-JUTRb91sJ-LvHZELPR5VeyGkWCRUHkA7m-4SzZF8Zbf63kHRipm8DCQXb_DKg_43lpZa6JhRx44hyub2YdNFhm-3bQzECp2obnr8ViOvVNGA2oa2BVCBGWz7VBIe5W3mzQPFe7Q33UeeI3oOa0T78C2YW3qiJrlstdA_r5mRmWATEOViISUNryUpkHjPtqpts-MMRkEq__AhK32C3FbWD3VxznOITLD1hzRmm_u9J98fXCl40JT7GkXToWX7z8EbFlM7fHda1vp4jkvouQbb818rhhsUgOhR4Pyv5184ShP2XW9GCyfzPGwuWug8qjUWyCSpp_FIISmXutiYs3rqT717xJq22DZ8x4HQqWiRS2I6E9-PwyhSca-QjdnX1ieoj8Kzwq5UQpUuyf49GKdg9XHJvV78JCqc9b75NzUNBUd1kiaCqX9wHZxA7iFy41N29wPKqLn6uVGk6DG8UNMLBbEh6J2V15UKEHPPyGXsZgcarKxuTSqFC1bgbet0V0hS9W6zNSG-HhwZgIqCaprJQlLhMxzWUK6pa89iykt3zWP2u1IM-JPcH6zIALIYsMz65QSL_EJPmtvz36zRIZKTaRugNFkq_e78Jplry1iti8qAMwQRoJEalLDHnopxpgUKbVYGspqbjsuiFuD-TczNcbDrsWtjxBt66pg9vZTxoKdJ7DqypxtlsILsYCQ4FOQlLiVI0KWm7mkh9qeP5t8Y8akH7DvCLtbSiuNq_48LfEztT5Q1Na728k9JHFody8SUusbIGHQVrN6fcDibdROy8_lei0l3P7-VhEAZSUQ92GgXK0Dl-h4t4ymDuvblRVkSUluq1Rtt0c4wdqwvg6nkDZrdDBenuwzfw2jbBGWmKHglW8=","summary":[{"type":"summary_text","text":"**Editing targeted code lines**"}]},{"id":"ctc_0d5d9a673ec9d120016a58973f405081999aff35e80d55eab9","type":"custom_tool_call","status":"completed","call_id":"call_P0syCTRMTdaNnKY7zm47Ce3d","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#D27D]\nSWAP 859.=860:\n+\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\n+\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\n*** End Patch\n","name":"edit"}]},"duration":4412.5,"ttft":2852.817700000014,"contextSnapshot":{"promptTokens":176520,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_P0syCTRMTdaNnKY7zm47Ce3d|ctc_0d5d9a673ec9d120016a58973f405081999aff35e80d55eab9","toolName":"edit","startedAt":"2026-07-16T08:33:04.457Z"},"id":"45f0ebfb","parentId":"5316ef99","timestamp":"2026-07-16T08:33:04.457Z"}
{"type":"message","id":"6f42697c","parentId":"45f0ebfb","timestamp":"2026-07-16T08:33:04.481Z","message":{"role":"toolResult","toolCallId":"call_P0syCTRMTdaNnKY7zm47Ce3d|ctc_0d5d9a673ec9d120016a58973f405081999aff35e80d55eab9","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#17B7]\n820:\t\tasync function compatibleCandidates(type, ctx) {\n\n857:\t\t\tconst candidates = detailed.filter(Boolean);\n858:\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n859:\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\n860:\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\n861:\t\t\treturn candidates;\n862:\t\t}"}],"details":{"diff":" 820|\t\tasync function compatibleCandidates(type, ctx) {\n\n 857|\t\t\tconst candidates = detailed.filter(Boolean);\n 858|\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n-859|\t\t\tif (type === \"ready_agent\") cachedReadyIds = ids;\n-860|\t\t\telse cachedLiveIds = ids;\n+859|\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\n+860|\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\n 861|\t\t\treturn candidates;\n 862|\t\t}","firstChangedLine":859,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190784481}}
{"type":"message","id":"804f18d9","parentId":"6f42697c","timestamp":"2026-07-16T08:33:09.356Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Refactoring listener generation and session start**"},{"type":"toolCall","id":"call_ahN41nXKrhrwEIRbQbUMBuiI|fc_07af0aed016be589016a589744ef2c819a930531fb61f927f1","name":"read","arguments":{"i":"Reading extension lifecycle after activation additions","path":"adapter/strings/omp-spt.mjs","selector":"1480-1785"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1116,"output":124,"cacheRead":175616,"cacheWrite":0,"totalTokens":176856,"reasoningTokens":80,"cost":{"input":0.005580000000000001,"output":0.00372,"cacheRead":0.087808,"cacheWrite":0,"total":0.097108}},"stopReason":"toolUse","timestamp":1784190784493,"responseId":"resp_07af0aed016be589016a589740defc819a9bb708154d278229","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_07af0aed016be589016a589742f928819aa328414ec057f8a4","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJdEqrFvjBp8WKxX38-pAEZk4ZO8GzzHajjmk4XXau-4tK-653sRMFavOOudv6s4mw2XIpkCT0ES1b6b3Ktm5Ht06E5zXv3NQMCToC9R1c5BS-yNZ5HtNeuLgqtWFDJuMf_nfI6rUGzwkibf5wltTOuwh_qMKoyNtjsPlzgcSOKcTOiBuboMOfAUHzp_vj_e8HNLl2SlXOB4octxQT9UW0-Di68Biu0e6DPauKqxYZCdOFi_063M9Hq4OZgU4eihSmTWDvJwsuaWJJAWSmf5oOYG27u3N8KAuKZsPQdMqCshqnjQwJZhlTytfuP7I_lNM2ZuIwaA2L5V6_7IesTu2eOmALNOCTvNWSl5Nrkj_sSqmQtTSQfaFkhlcJroglWhTiVRwYEqfjKO_6Kph9kdflPh67Ssb9KSiEeAB3C2DDzdWqfxhpzqPHL1JhLN4DzGKb1uPqIEsWFcXTAnHcnFPEfozaIwK0wIWz2HTL3HubRdg0mGzx0TxDieFJuTZrxqST0jRWAz_RQS-l4U8gND7okMo4wDpo8YLyBsAi2ZjIaUERkwPESx31OFkm3j7x7hRL18FxjRYFqE5oDnYOtojfZQFxNTpGinnTo8CkAjvxQIX7IlHBOrkchnnmVXgzas3gK97aBWE3CxAXoc6bLciI7f9MOsTEjvAXXCKGSOGmNfR2TyDwa-q4RdGGwv5bV1Z5qeY5rIBdwC0asY8duXuDFrMleHnuJ9KQz_F2sTz3oiDR0eo2wbJzHd9eqs9qNRaHlrY97V8MI4kPvXGcEbNeToSJDRvPzYS567opqicQ18YgdLkxkjJKfflzgc5W85dVyFtj_hsGm9-MtXA74Dfm9dywTsoPXvOst4ztqWeRwbCYFl6Auvi56ZsOGrwRHPI-d0yGiCKWRsLLC7CuG9bj0EArHkTs7xMesgyzdrtV7qWwennR1K7vblfxEogP3CLBwaDr6t5erF8hTzkVKmn6E4-CJ9YOgQIcFlZFz4oYSL-XPOSlWlxxGGsg7lV2TNSnDpbTgPpC085YRY6kD_S4qTGu99uyjRnncwzsIrPQDO4wNeUUZE1Ufs5iXV6VVzlkniv13RzR-1mj-U-QzWxsD5BHdLmeG7CZ6ivx3BDTX1Ayd2omsbjNOtIsWfb6QIoZxpnNdxgL-qQIL_EzCvSi9i3KlPCmaxgyN5DKdOK6J0dppRjEIiCbb91BGArC1pCY0U1HoK_EHfJTaKZpr2lbciK9hxysPskA-KVxZ5BM_-mD2lL2JyF2qZPkFmJUDQUKOoyKhIEKbOtWUa9F_P3F0LwUxjh9scw2KrPssnpCAvNyUrJHa71Y2uY9RnH8ET9JrA2y8kc7i2JfTjdYu-_1faC_208fwEroup64tzrWO_pTNb7MJDyKmEBVZi0PIXARIE9lfH3KM8fW-7UEk0aTK9BA==","summary":[{"type":"summary_text","text":"**Refactoring listener generation and session start**"}]},{"id":"fc_07af0aed016be589016a589744ef2c819a930531fb61f927f1","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading extension lifecycle after activation additions\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1480-1785\"}","call_id":"call_ahN41nXKrhrwEIRbQbUMBuiI","name":"read"}]},"duration":4862.404399999883,"ttft":2539.0483999997377,"contextSnapshot":{"promptTokens":176732,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ahN41nXKrhrwEIRbQbUMBuiI|fc_07af0aed016be589016a589744ef2c819a930531fb61f927f1","toolName":"read","startedAt":"2026-07-16T08:33:09.356Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading extension lifecycle after activation additions"},"id":"cfb809ad","parentId":"804f18d9","timestamp":"2026-07-16T08:33:09.356Z"}
{"type":"message","id":"361a2e5f","parentId":"cfb809ad","timestamp":"2026-07-16T08:33:09.375Z","message":{"role":"toolResult","toolCallId":"call_ahN41nXKrhrwEIRbQbUMBuiI|fc_07af0aed016be589016a589744ef2c819a930531fb61f927f1","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#17B7]\n516:export function createOmpSpt(overrides = {}) {\n…\n650:\treturn function ompSpt(pi) {\n…\n1464:\t\tasync function rejectItem(item, reason, error) {\n…\n1478:\t\t\tif (!stopping) {\n1479:\t\t\t\tdesiredState = \"idle\";\n1480:\t\t\t\ttry {\n1481:\t\t\t\t\tawait setState(\"idle\");\n1482:\t\t\t\t} catch (stateError) {\n1483:\t\t\t\t\tawait failClosed(\n1484:\t\t\t\t\t\t\"omp-spt could not restore idle state after a failed submission\",\n1485:\t\t\t\t\t\tstateError,\n1486:\t\t\t\t\t);\n1487:\t\t\t\t}\n1488:\t\t\t}\n1489:\t\t}\n1490:\n1491:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1492:\t\tasync function dispatchNext() {\n1493:\t\t\tif (stopping || agentActive || dispatching || current || queue.length === 0) return;\n1494:\t\t\tdispatching = true;\n1495:\t\t\tconst item = queue.shift();\n1496:\t\t\tcurrent = item;\n1497:\t\t\ttry {\n1498:\t\t\t\ttry {\n1499:\t\t\t\t\tdesiredState = \"busy\";\n1500:\t\t\t\t\tawait setState(\"busy\");\n1501:\t\t\t\t} catch (error) {\n1502:\t\t\t\t\tawait rejectItem(item, \"could not accept your message\", error);\n1503:\t\t\t\t\treturn;\n1504:\t\t\t\t}\n1505:\t\t\t\tif (stopping) return;\n1506:\t\t\t\tif (agentActive) {\n1507:\t\t\t\t\tif (current === item) current = undefined;\n1508:\t\t\t\t\tqueue.unshift(item);\n1509:\t\t\t\t\treturn;\n1510:\t\t\t\t}\n1511:\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n1512:\t\t\t\titem.submitted = true;\n1513:\t\t\t\ttry {\n1514:\t\t\t\t\tpi.sendUserMessage(item.stub);\n1515:\t\t\t\t} catch (error) {\n1516:\t\t\t\t\titem.submitted = false;\n1517:\t\t\t\t\tawait rejectItem(item, \"could not submit your message to OMP\", error);\n1518:\t\t\t\t}\n1519:\t\t\t} finally {\n1520:\t\t\t\tdispatching = false;\n1521:\t\t\t\tscheduleDispatch();\n1522:\t\t\t}\n1523:\t\t}\n1524:\n1525:\t\t// [impl->REQ-OMP-LISTENER-FAIL-CLOSED]\n1526:\t\tfunction handleListenerDeath(reason) {\n1527:\t\t\tlistenerBuffer = \"\";\n1528:\t\t\tif (listenerStableTimer !== undefined) {\n1529:\t\t\t\tclearTimer(listenerStableTimer);\n1530:\t\t\t\tlistenerStableTimer = undefined;\n1531:\t\t\t}\n1532:\t\t\tif (stopping || restartTimer !== undefined) return;\n1533:\t\t\tif (listenerRestartCount >= restartDelaysMs.length) {\n1534:\t\t\t\tvoid failClosed(\"omp-spt listener restart budget exhausted\", reason);\n1535:\t\t\t\treturn;\n1536:\t\t\t}\n1537:\t\t\tconst attempt = listenerRestartCount + 1;\n1538:\t\t\tconst delay = restartDelaysMs[listenerRestartCount];\n1539:\t\t\tlistenerRestartCount = attempt;\n1540:\t\t\tconst message = `omp-spt listener stopped; restarting ${attempt}/${restartDelaysMs.length} in ${delay}ms`;\n1541:\t\t\tpi.logger.error(message, { error: errorSummary(reason) });\n1542:\t\t\tui?.setStatus(\"omp-spt\", `spt reconnecting (${attempt}/${restartDelaysMs.length})`);\n1543:\t\t\tui?.notify(message, \"warning\");\n1544:\t\t\trestartTimer = setTimer(() => {\n1545:\t\t\t\trestartTimer = undefined;\n1546:\t\t\t\tstartListener();\n1547:\t\t\t}, delay);\n1548:\t\t\trestartTimer?.unref?.();\n1549:\t\t}\n1550:\n1551:\t\tfunction startListener() {\n1552:\t\t\tif (stopping) return;\n1553:\t\t\tconst args = [\"api\", \"--adapter\", ADAPTER, \"listen\", id, \"--session-id\", sid];\n1554:\t\t\tif (env.OMP_SPT_SUBNET) args.push(\"--subnet\", env.OMP_SPT_SUBNET);\n1555:\t\t\tlet child;\n1556:\t\t\ttry {\n1557:\t\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\n1558:\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n1559:\t\t\t\t\twindowsHide: true,\n1560:\t\t\t\t});\n1561:\t\t\t} catch (error) {\n1562:\t\t\t\thandleListenerDeath(error);\n1563:\t\t\t\treturn;\n1564:\t\t\t}\n1565:\t\t\tlistener = child;\n1566:\t\t\tlistenerBuffer = \"\";\n1567:\t\t\tlet dead = false;\n1568:\t\t\tconst died = (reason, alreadyExited) => {\n1569:\t\t\t\tif (dead) return;\n1570:\t\t\t\tdead = true;\n1571:\t\t\t\tif (listener === child) listener = undefined;\n1572:\t\t\t\tif (stopping || alreadyExited) {\n1573:\t\t\t\t\thandleListenerDeath(reason);\n1574:\t\t\t\t\treturn;\n1575:\t\t\t\t}\n1576:\t\t\t\tconst termination = beginListenerTermination(child, \"dead spt api listener\");\n1577:\t\t\t\tvoid termination.then(() => handleListenerDeath(reason));\n1578:\t\t\t};\n1579:\t\t\tif (listenerStableMs !== undefined) {\n1580:\t\t\t\tlistenerStableTimer = setTimer(() => {\n1581:\t\t\t\t\tlistenerStableTimer = undefined;\n1582:\t\t\t\t\tif (listener === child && !stopping) listenerRestartCount = 0;\n1583:\t\t\t\t}, listenerStableMs);\n1584:\t\t\t\tlistenerStableTimer?.unref?.();\n1585:\t\t\t}\n1586:\t\t\tchild.stdout.setEncoding(\"utf8\");\n1587:\t\t\tchild.stderr.setEncoding(\"utf8\");\n1588:\t\t\tchild.stdout.on(\"data\", (chunk) => {\n1589:\t\t\t\tif (listener !== child || stopping) return;\n1590:\t\t\t\tlistenerBuffer += String(chunk);\n1591:\t\t\t\tif (listenerBuffer.length > listenerBufferLimit) {\n1592:\t\t\t\t\tvoid failClosed(\n1593:\t\t\t\t\t\t\"omp-spt listener protocol corruption\",\n1594:\t\t\t\t\t\tprotocolError(\n1595:\t\t\t\t\t\t\t`EVENT buffer exceeded ${listenerBufferLimit} characters without a complete drain`,\n1596:\t\t\t\t\t\t),\n1597:\t\t\t\t\t);\n1598:\t\t\t\t\treturn;\n1599:\t\t\t\t}\n1600:\t\t\t\twhile (!stopping) {\n1601:\t\t\t\t\tconst drained = drainEvents(listenerBuffer, {\n1602:\t\t\t\t\t\tmaxEvents: 1,\n1603:\t\t\t\t\t\tmaxFrameChars: listenerBufferLimit,\n1604:\t\t\t\t\t});\n1605:\t\t\t\t\tlistenerBuffer = drained.rest;\n1606:\t\t\t\t\tif (drained.error) {\n1607:\t\t\t\t\t\tvoid failClosed(\"omp-spt listener protocol corruption\", drained.error);\n1608:\t\t\t\t\t\treturn;\n1609:\t\t\t\t\t}\n1610:\t\t\t\t\tif (drained.events.length === 0) break;\n1611:\t\t\t\t\tconst event = drained.events[0];\n1612:\t\t\t\t\tconst acceptedCount = queue.length + (current ? 1 : 0);\n1613:\t\t\t\t\tconst eventBytes = Buffer.byteLength(event.envelope, \"utf8\");\n1614:\t\t\t\t\tif (\n1615:\t\t\t\t\t\tacceptedCount >= acceptedQueueLimit ||\n1616:\t\t\t\t\t\tacceptedBytes + eventBytes > acceptedBytesLimit\n1617:\t\t\t\t\t) {\n1618:\t\t\t\t\t\toverflowItem = event;\n1619:\t\t\t\t\t\tvoid failClosed(\n1620:\t\t\t\t\t\t\t\"omp-spt inbound custody capacity exceeded\",\n1621:\t\t\t\t\t\t\tnew Error(\n1622:\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\n1623:\t\t\t\t\t\t\t),\n1624:\t\t\t\t\t\t);\n1625:\t\t\t\t\t\treturn;\n1626:\t\t\t\t\t}\n1627:\t\t\t\t\tevent.acceptedBytes = eventBytes;\n1628:\t\t\t\t\tevent.accounted = true;\n1629:\t\t\t\t\tacceptedBytes += eventBytes;\n1630:\t\t\t\t\tqueue.push(event);\n1631:\t\t\t\t}\n1632:\t\t\t\tif (!agentActive && !current && !dispatching) void dispatchNext();\n1633:\t\t\t});\n1634:\t\t\tchild.stderr.on(\"data\", (chunk) =>\n1635:\t\t\t\tpi.logger.debug(\"omp-spt listener\", { output: String(chunk).trim() }),\n1636:\t\t\t);\n1637:\t\t\tchild.on(\"error\", (error) => died(error, false));\n1638:\t\t\tchild.on(\"close\", (code, signal) => {\n1639:\t\t\t\tconst status = signal ? `signal ${signal}` : code;\n1640:\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\n1641:\t\t\t});\n1642:\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\n1643:\t\t}\n1644:\n1645:\t\t// [impl->REQ-OMP-NATIVE-TUI]\n1646:\t\tpi.on(\"session_start\", async (_event, ctx) => {\n1647:\t\t\truntimeCtx = ctx;\n1648:\t\t\tui = ctx.ui;\n1649:\t\t\tsid = ctx.sessionManager.getSessionId();\n1650:\t\t\tconst bindArgs = [\"api\", \"--adapter\", ADAPTER, \"bind\", id, \"--set-session-id\", sid];\n1651:\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n1652:\t\t\tbindPromise = (async () => {\n1653:\t\t\t\tconst bound = await runCommand(bindArgs);\n1654:\t\t\t\ttoken = bound.match(/\\btoken=([^\\s]+)/)?.[1];\n1655:\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n1656:\t\t\t})();\n1657:\t\t\ttry {\n1658:\t\t\t\tawait bindPromise;\n1659:\t\t\t} catch (error) {\n1660:\t\t\t\tif (stopping) return;\n1661:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1662:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1663:\t\t\t\treturn;\n1664:\t\t\t}\n1665:\t\t\tif (stopping) {\n1666:\t\t\t\ttry {\n1667:\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n1668:\t\t\t\t} catch (error) {\n1669:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n1670:\t\t\t\t}\n1671:\t\t\t\treturn;\n1672:\t\t\t}\n1673:\t\t\ttry {\n1674:\t\t\t\tawait syncDesiredState();\n1675:\t\t\t\tif (stopping) {\n1676:\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n1677:\t\t\t\t\treturn;\n1678:\t\t\t\t}\n1679:\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n1680:\t\t\t\tstartListener();\n1681:\t\t\t} catch (error) {\n1682:\t\t\t\tif (stopping) {\n1683:\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n1684:\t\t\t\t\treturn;\n1685:\t\t\t\t}\n1686:\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1687:\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1688:\t\t\t}\n1689:\t\t});\n1690:\n1691:\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\n1692:\t\tconst blockSessionChange = (description, ctx) => {\n1693:\t\t\tctx.ui.notify(\n1694:\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n1695:\t\t\t\t\"warning\",\n1696:\t\t\t);\n1697:\t\t\treturn { cancel: true };\n1698:\t\t};\n1699:\n1700:\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n1701:\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\n1702:\t\t);\n1703:\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\n1704:\t\t\tblockSessionChange(\"session branch\", ctx),\n1705:\t\t);\n1706:\n1707:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n1708:\t\tpi.on(\"context\", (event) => {\n1709:\t\t\tif (!current?.submitted || current.settling) return;\n1710:\t\t\tconst messages = injectEnvelope(event.messages, current);\n1711:\t\t\tif (messages !== event.messages) return { messages };\n1712:\t\t});\n1713:\n1714:\t\tasync function completeTurn(event) {\n1715:\t\t\tagentActive = false;\n1716:\t\t\tdesiredState = \"idle\";\n1717:\t\t\tif (stopping) return;\n1718:\t\t\tconst completed = current;\n1719:\t\t\tif (completed?.submitted && !completed.settled) {\n1720:\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\n1721:\t\t\t\ttry {\n1722:\t\t\t\t\tawait settleItem(\n1723:\t\t\t\t\t\tcompleted,\n1724:\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n1725:\t\t\t\t\t);\n1726:\t\t\t\t} catch (error) {\n1727:\t\t\t\t\tif (stopping) return;\n1728:\t\t\t\t\tawait failClosed(\n1729:\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n1730:\t\t\t\t\t\terror,\n1731:\t\t\t\t\t);\n1732:\t\t\t\t\treturn;\n1733:\t\t\t\t}\n1734:\t\t\t}\n1735:\t\t\tif (current === completed) {\n1736:\t\t\t\tcurrent = undefined;\n1737:\t\t\t\treleaseItem(completed);\n1738:\t\t\t}\n1739:\t\t\ttry {\n1740:\t\t\t\tawait setState(\"idle\");\n1741:\t\t\t} catch (error) {\n1742:\t\t\t\tif (stopping) return;\n1743:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n1744:\t\t\t\treturn;\n1745:\t\t\t}\n1746:\t\t\tscheduleDispatch();\n1747:\t\t}\n1748:\n1749:\t\tpi.on(\"agent_start\", async () => {\n1750:\t\t\tif (stopping) return;\n1751:\t\t\tturnCompletionPromise = undefined;\n1752:\t\t\tagentActive = true;\n1753:\t\t\tdesiredState = \"busy\";\n1754:\t\t\ttry {\n1755:\t\t\t\tawait syncDesiredState();\n1756:\t\t\t} catch (error) {\n1757:\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\n1758:\t\t\t}\n1759:\t\t});\n1760:\n1761:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1762:\t\tpi.on(\"agent_end\", (event) => {\n1763:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1764:\t\t\treturn turnCompletionPromise;\n1765:\t\t});\n1766:\n1767:\t\tpi.on(\"session_stop\", async (event) => {\n1768:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1769:\t\t\tawait turnCompletionPromise;\n1770:\t\t});\n1771:\n1772:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n1773:\t\t\truntimeCtx ??= ctx;\n1774:\t\t\tui?.setStatus(\"omp-spt\", undefined);\n1775:\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\n1776:\t\t});\n1777:\t};\n1778:}\n1779:\n1780:export default createOmpSpt();\n1781:"}],"details":{"displayContent":{"text":"export function createOmpSpt(overrides = {}) {\n…\n\treturn function ompSpt(pi) {\n…\n\t\tasync function rejectItem(item, reason, error) {\n…\n\t\t\tif (!stopping) {\n\t\t\t\tdesiredState = \"idle\";\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait setState(\"idle\");\r\n\t\t\t\t} catch (stateError) {\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t\"omp-spt could not restore idle state after a failed submission\",\r\n\t\t\t\t\t\tstateError,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tasync function dispatchNext() {\r\n\t\t\tif (stopping || agentActive || dispatching || current || queue.length === 0) return;\r\n\t\t\tdispatching = true;\r\n\t\t\tconst item = queue.shift();\r\n\t\t\tcurrent = item;\r\n\t\t\ttry {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tdesiredState = \"busy\";\r\n\t\t\t\t\tawait setState(\"busy\");\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tawait rejectItem(item, \"could not accept your message\", error);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tif (agentActive) {\r\n\t\t\t\t\tif (current === item) current = undefined;\r\n\t\t\t\t\tqueue.unshift(item);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\ttry {\r\n\t\t\t\t\tpi.sendUserMessage(item.stub);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\titem.submitted = false;\r\n\t\t\t\t\tawait rejectItem(item, \"could not submit your message to OMP\", error);\r\n\t\t\t\t}\r\n\t\t\t} finally {\r\n\t\t\t\tdispatching = false;\r\n\t\t\t\tscheduleDispatch();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-LISTENER-FAIL-CLOSED]\r\n\t\tfunction handleListenerDeath(reason) {\r\n\t\t\tlistenerBuffer = \"\";\r\n\t\t\tif (listenerStableTimer !== undefined) {\r\n\t\t\t\tclearTimer(listenerStableTimer);\r\n\t\t\t\tlistenerStableTimer = undefined;\r\n\t\t\t}\r\n\t\t\tif (stopping || restartTimer !== undefined) return;\r\n\t\t\tif (listenerRestartCount >= restartDelaysMs.length) {\r\n\t\t\t\tvoid failClosed(\"omp-spt listener restart budget exhausted\", reason);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tconst attempt = listenerRestartCount + 1;\r\n\t\t\tconst delay = restartDelaysMs[listenerRestartCount];\r\n\t\t\tlistenerRestartCount = attempt;\r\n\t\t\tconst message = `omp-spt listener stopped; restarting ${attempt}/${restartDelaysMs.length} in ${delay}ms`;\r\n\t\t\tpi.logger.error(message, { error: errorSummary(reason) });\r\n\t\t\tui?.setStatus(\"omp-spt\", `spt reconnecting (${attempt}/${restartDelaysMs.length})`);\r\n\t\t\tui?.notify(message, \"warning\");\r\n\t\t\trestartTimer = setTimer(() => {\r\n\t\t\t\trestartTimer = undefined;\r\n\t\t\t\tstartListener();\r\n\t\t\t}, delay);\r\n\t\t\trestartTimer?.unref?.();\r\n\t\t}\r\n\r\n\t\tfunction startListener() {\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst args = [\"api\", \"--adapter\", ADAPTER, \"listen\", id, \"--session-id\", sid];\r\n\t\t\tif (env.OMP_SPT_SUBNET) args.push(\"--subnet\", env.OMP_SPT_SUBNET);\r\n\t\t\tlet child;\r\n\t\t\ttry {\r\n\t\t\t\tchild = spawnProcess(env.OMP_SPT_SPT_BIN || \"spt\", args, {\r\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\r\n\t\t\t\t\twindowsHide: true,\r\n\t\t\t\t});\r\n\t\t\t} catch (error) {\r\n\t\t\t\thandleListenerDeath(error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tlistener = child;\r\n\t\t\tlistenerBuffer = \"\";\r\n\t\t\tlet dead = false;\r\n\t\t\tconst died = (reason, alreadyExited) => {\r\n\t\t\t\tif (dead) return;\r\n\t\t\t\tdead = true;\r\n\t\t\t\tif (listener === child) listener = undefined;\r\n\t\t\t\tif (stopping || alreadyExited) {\r\n\t\t\t\t\thandleListenerDeath(reason);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tconst termination = beginListenerTermination(child, \"dead spt api listener\");\r\n\t\t\t\tvoid termination.then(() => handleListenerDeath(reason));\r\n\t\t\t};\r\n\t\t\tif (listenerStableMs !== undefined) {\r\n\t\t\t\tlistenerStableTimer = setTimer(() => {\r\n\t\t\t\t\tlistenerStableTimer = undefined;\r\n\t\t\t\t\tif (listener === child && !stopping) listenerRestartCount = 0;\r\n\t\t\t\t}, listenerStableMs);\r\n\t\t\t\tlistenerStableTimer?.unref?.();\r\n\t\t\t}\r\n\t\t\tchild.stdout.setEncoding(\"utf8\");\r\n\t\t\tchild.stderr.setEncoding(\"utf8\");\r\n\t\t\tchild.stdout.on(\"data\", (chunk) => {\r\n\t\t\t\tif (listener !== child || stopping) return;\r\n\t\t\t\tlistenerBuffer += String(chunk);\r\n\t\t\t\tif (listenerBuffer.length > listenerBufferLimit) {\r\n\t\t\t\t\tvoid failClosed(\r\n\t\t\t\t\t\t\"omp-spt listener protocol corruption\",\r\n\t\t\t\t\t\tprotocolError(\r\n\t\t\t\t\t\t\t`EVENT buffer exceeded ${listenerBufferLimit} characters without a complete drain`,\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\twhile (!stopping) {\r\n\t\t\t\t\tconst drained = drainEvents(listenerBuffer, {\r\n\t\t\t\t\t\tmaxEvents: 1,\r\n\t\t\t\t\t\tmaxFrameChars: listenerBufferLimit,\r\n\t\t\t\t\t});\r\n\t\t\t\t\tlistenerBuffer = drained.rest;\r\n\t\t\t\t\tif (drained.error) {\r\n\t\t\t\t\t\tvoid failClosed(\"omp-spt listener protocol corruption\", drained.error);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (drained.events.length === 0) break;\r\n\t\t\t\t\tconst event = drained.events[0];\r\n\t\t\t\t\tconst acceptedCount = queue.length + (current ? 1 : 0);\r\n\t\t\t\t\tconst eventBytes = Buffer.byteLength(event.envelope, \"utf8\");\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\tacceptedCount >= acceptedQueueLimit ||\r\n\t\t\t\t\t\tacceptedBytes + eventBytes > acceptedBytesLimit\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\toverflowItem = event;\r\n\t\t\t\t\t\tvoid failClosed(\r\n\t\t\t\t\t\t\t\"omp-spt inbound custody capacity exceeded\",\r\n\t\t\t\t\t\t\tnew Error(\r\n\t\t\t\t\t\t\t\t`accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,\r\n\t\t\t\t\t\t\t),\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tevent.acceptedBytes = eventBytes;\r\n\t\t\t\t\tevent.accounted = true;\r\n\t\t\t\t\tacceptedBytes += eventBytes;\r\n\t\t\t\t\tqueue.push(event);\r\n\t\t\t\t}\r\n\t\t\t\tif (!agentActive && !current && !dispatching) void dispatchNext();\r\n\t\t\t});\r\n\t\t\tchild.stderr.on(\"data\", (chunk) =>\r\n\t\t\t\tpi.logger.debug(\"omp-spt listener\", { output: String(chunk).trim() }),\r\n\t\t\t);\r\n\t\t\tchild.on(\"error\", (error) => died(error, false));\r\n\t\t\tchild.on(\"close\", (code, signal) => {\r\n\t\t\t\tconst status = signal ? `signal ${signal}` : code;\r\n\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\r\n\t\t\t});\r\n\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-NATIVE-TUI]\r\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\r\n\t\t\truntimeCtx = ctx;\r\n\t\t\tui = ctx.ui;\r\n\t\t\tsid = ctx.sessionManager.getSessionId();\r\n\t\t\tconst bindArgs = [\"api\", \"--adapter\", ADAPTER, \"bind\", id, \"--set-session-id\", sid];\r\n\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\r\n\t\t\tbindPromise = (async () => {\r\n\t\t\t\tconst bound = await runCommand(bindArgs);\r\n\t\t\t\ttoken = bound.match(/\\btoken=([^\\s]+)/)?.[1];\r\n\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\r\n\t\t\t})();\r\n\t\t\ttry {\r\n\t\t\t\tawait bindPromise;\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (stopping) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t\tif (stopping) {\r\n\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t\t\tstartListener();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) {\r\n\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\r\n\t\tconst blockSessionChange = (description, ctx) => {\r\n\t\t\tctx.ui.notify(\r\n\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\r\n\t\t\t\t\"warning\",\r\n\t\t\t);\r\n\t\t\treturn { cancel: true };\r\n\t\t};\r\n\r\n\t\tpi.on(\"session_before_switch\", (event, ctx) =>\r\n\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tif (!current?.submitted || current.settling) return;\r\n\t\t\tconst messages = injectEnvelope(event.messages, current);\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\tawait turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\r\n\t\t\truntimeCtx ??= ctx;\r\n\t\t\tui?.setStatus(\"omp-spt\", undefined);\r\n\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\r\n\t\t});\r\n\t};\r\n}\r\n\r\nexport default createOmpSpt();\r\n","startLine":516,"lineNumbers":[516,null,650,null,1464,null,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"}}},"isError":false,"timestamp":1784190789374}}
{"type":"message","id":"5edf5bef","parentId":"361a2e5f","timestamp":"2026-07-16T08:33:41.886Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Replacing session_start block**\n\n**Implementing dispatch function error handling**\n\n**Handling multi-target dispatch statuses**"},{"type":"thinking","thinking":"**Refining update and startup flow**\n\n**Adding timestamps to user messages**\n\n**Ensuring idle state before shutdown**"},{"type":"toolCall","id":"call_KBjtAXZtvmJwnPbc1hAPymIR|ctc_0179ee910f20ada4016a58975eaae0819bbf01e48d480cee01","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#17B7]\nSWAP.BLK 1646:\n+\t\tpi.on(\"session_start\", async (_event, ctx) => {\n+\t\t\truntimeCtx = ctx;\n+\t\t\tui = ctx.ui;\n+\t\t\tsid = ctx.sessionManager.getSessionId();\n+\t\t\tif (!initialId) return;\n+\t\t\tawait activateEndpoint(initialId, undefined, ctx, { fatal: true });\n+\t\t});\nSWAP.BLK 1692:\n+\t\tconst blockSessionChange = (description, ctx) => {\n+\t\t\tif (!activated && !token) return;\n+\t\t\tctx.ui.notify(\n+\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n+\t\t\t\t\"warning\",\n+\t\t\t);\n+\t\t\treturn { cancel: true };\n+\t\t};\nSWAP.BLK 1708:\n+\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n+\t\tpi.on(\"context\", (event) => {\n+\t\t\tlet messages = event.messages;\n+\t\t\tif (\n+\t\t\t\tagentActive &&\n+\t\t\t\t!current &&\n+\t\t\t\t!dispatching &&\n+\t\t\t\tqueue.length > 0\n+\t\t\t) {\n+\t\t\t\tconst item = queue.shift();\n+\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n+\t\t\t\titem.submitted = true;\n+\t\t\t\titem.activeInjected = true;\n+\t\t\t\tcurrent = item;\n+\t\t\t\tmessages = [\n+\t\t\t\t\t...messages,\n+\t\t\t\t\t{\n+\t\t\t\t\t\trole: \"user\",\n+\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n+\t\t\t\t\t},\n+\t\t\t\t];\n+\t\t\t}\n+\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n+\t\t\t\tmessages = injectEnvelope(messages, current);\n+\t\t\t}\n+\t\t\tif (messages !== event.messages) return { messages };\n+\t\t});\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":3622,"output":1460,"cacheRead":176640,"cacheWrite":0,"totalTokens":181722,"reasoningTokens":1030,"cost":{"input":0.01811,"output":0.0438,"cacheRead":0.08832,"cacheWrite":0,"total":0.15023}},"stopReason":"toolUse","timestamp":1784190789393,"responseId":"resp_0179ee910f20ada4016a589745de70819bba7a65fd10186c1b","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0179ee910f20ada4016a58974b7c74819bbfaddf8d5252d930","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJdVeGJy3_TJTtd0Br8EoDHUPvn6Cft8KgtG_pYEkU7NTI4gmg-mPqgYuVfv3Kj9VpZRY3mDtG4EaKVTPcH7OrbGJT1LshPJW-KXpGxoY_JGSo7JF7XJlGoKs5riyVqIbTjoCuSPAMuadu65RV2WGFcj__B6L682qgQDz7XcDf5ECRiM_1gBhuElf2bZ-BRITKyrBVMk397s8G4Xyt8cgtc2T8fpk2vnaPK7oJJhhF-TAWYJVllSP44-Djj3BZaPSz9DvDptDNZpqPFahEZPzd1otXY0n8nLaFMRdzCwgtCyMD6tTyxceoIal-GEvk1QRZxZbISbKxLHHL-Rq019NpoVZ5tmXJcvFMiaSkfTLv2KnySCABbfoO2DNk8MPZVIlHtQnQnfmrO9IKQ4bXu7mff-eSirMvKAM6QVKJzv0YmUu0lRGN4Ews0vwhjYaEkbsUCD5ef4VYh2ba18GckJUwovx1TE_Vz7XUbEe2bnB1a-XBNoYXnrRfQEjNunXRBBVPaOHSn-1T-5sw93sls9D4vt2ebiwx3ZujnKZknp1bgNpBtUSUfPseG1dnjXWRRxafk0JiDigZmbe0jKrbX3EuDZUkXD08_v_Kojdj_7rOrMB2iwdAY1QIiwICxL6tUaynDwXO5S_zTq6TlypohP4PFDgvrrqppKkIhL2xNPIysBV9PqbpSLSh7Y6bpZ4h-xfhSTYKkt9-TRTE3u97MeTMSecX1G_W0Kk3vBPinLP__IEy6BhbpVIfLqm3axpFhTL1DeMc0nkbG9SqhOvK2lRvUfcI2FJD-K__jU3w9mURy5K5U5t9-H-_ROfDQU3PwPgtOxFX2ZbKhu6MvqUTBSwyjTfrwgj21RqsJXEqFYig7g5Dp_icxJyK5seqgtpHENu6yv-SwAlP3kFvW_cuMCEd5DNeJ7VV72vEu5sCbdFcZ54neZFPG_6Z0GvUPYZIMGZq0dZX-FFsAbbYPTAhbkYESzmohB8EilgJ96N7qxAcprl3lGIFze5Gfm46ntkml7tGxx1-IE-SQb34vsiTG03MNuvcOJhib66GMkh-0NIiYbHOK1GDygJj0vNmm4f4emjZW3yqcJPSdbwreaEIDT9_kCaMGMNSIm5YLEKf1_RgZ_2_6knUmMR1UXgGQXzQ3MxntLR6DN0IIsOnopdJXzouC15t8gusuKRlSl5n7sfnCnLEuKWm0KumNhjp0fEyNjlx06uDDoXxCXUxIuCtUpY-j3w6wgLe35SAhqhTSwDO0KAeLbzFV1g8DixHkTlQVEJUqjSpoxRG6omLH8fOgtY8tsjbbyVFtOS_uUUR6vXiGVOXciQ3Us9Hx9rpQw_MY0vSFFGvCops-FDht-wSjkhKw94cczJogreGMzfubFMHIdcUc7jnmIR_Cmk18wUiiMwU9O0j5fIcT3_9PWHvJETD7AMHhp7mm1RRS2iRCTJIj59QaziLraUKO0QKR6wZ4ks_iihxIJ6Ho5I_rZS8v4cUs1L3gCGKpbk3pDdZWyuFueJKxkxfT-zo9Trd3hIeRmMOyzyWIdUEMV2_wRNEIeySkXTrPN4-rKblOs7jIp35APqQFD3c7x0Tlmpx2glu_wSWD8A1TjQOCUTE_i9r50DGa0vkqBX3TB1JMOytbonLCBO6KtBbnMD-k-ZVtgwxbpkMOU8CGkq__uQdObbgmenaiP0WlZ7P2SLNZBhLzRUWbQ0rIyZZcpD8poAuhsMKN-xd4Da52jHzoX97SjHp3m7FkWmmy5_itgl0zoKQVg_6lbzx7Km5zwtRNNTmkqQS8ZIGKxK38QVC9rqdk-1Ztt57eG86CcPrDaDKXsJqdqScerfUXmTeKW2RhuJv-Lat7SkDGsRRI1mflPptTBLSRCYE0EKb47AW0JwTP8hShPxes_tNB-Rj_RVVCFlif3yGQKdLrv7AWmv8wGojMt-Tqbz5RCDmuTe_cgqrLddH_8oEuDTTyVDUDk0Q_lsnX0j-VRd_vJMxt_OWpZnfoq8BnpqzK3qKbu87W6bfuncdp2jRtNlwGuINh0KP_rvwGcidxaGgF1DVBtbhWboMZafzwL5QIcK7vHpycrybLHsLhSpnFXFiPg9pCEeg6KScwH5amaXm-bwMcSMRJXWR7-rdW1oQL3WazMnsmt-5QYef-yKRmAOny1nIOYLzwOc1iIlNO8l7CKo2hlp9M0Yzm9rVWzlkfPy3jqGUQWPncnlkRwLeEoieLar2zis7MuyL0TrrSrWR3zrWbiUFynPxdYOCXp3t0i2NwvHHvviMjfKYMuACuJPyO2b2p5fHlEBHPqfayMEwfIqh037ZjTerFsEcwhXSHhasGI9h9zBILo-rO0lXLFi-_WJLfUF5jaoM2j4-HqhIQXDLIdHiryw5_a4CH0qaVnsEVzqw--lRGlz6DqYIZMvfsOwiZpWYZwItIu0DgNcjMkbIrCoHaZ0L4ZLqMWe2fTcS8guZNUDsOIe6mkcRHY-7JvG-kOuL28v_X_pNPOSlml_26O3KIyAGdf4-obhva55B4uS2dkc4zWtbk2i9QjCK7cl7ZPyOIo5LChEXyctSzSn_iaiRQY6UK60K4hKwbGIrYGFh1ADcuubvxS-p-LbKsQnFXN_NUMS_9KTVN2RkEl0sWJ3uolY78PooF0avotJ0GTUReubUWTRGn0BLcewh7DaojxkzkvuCFSi2S8PUnm8yQYW4zRtdisqug89Uy0TxDIYbwd-vTJEzZsr89CXxsJDaFLtrJf0D8bcRwss2PZ2NguNk9vXB44pxktch4ejYvtJOdmaL0QW-KhF87ADsMYmAhHWLfdEn4zkFW8hzBAZobljzq4z23ehLpIX13nW_rJjA7yGf3sYg2eGy3-Wul-tpVdH8EL71_G2_CLavyb8n7VUeuuZATqfxbb3FZMIfHIXb0aPB0s8BHCu8HbJgsimsY_1pGs8mHylj8JJd0coIIpUR238MGRYRc0PdZMXjuokgfIuaVGtUJOntbmjn0Cm3dj3jsFtUgQ2o-zp9sE57KvzK9Cwky_8I7DBzPe05Yi4SAUimBI44jk_xPgYsfV-hS_IN7D1TdS-r7v8dVFgYu4UD-2Ay9G8b4wM8BQVOr_KT9pH8rQhvt95lJdxttO4Zm9JJtoi7SnGTBCDD_Qo4NtfOWoMczZRWs5Fj1PCVZrvpciNBZvGWKew6Wx118f15NNB-lqs_oHdQ1ByObiogEvhYZoXVF9BRSRuH_GXedc713CAQhn2NxH7tggtWK4Y2zNofCCjJS2FHML2uiUdAIAK5ZAxp0yJ7evvxM-TbSClO37peza840aDZQuKbEmXOJZb1PsR5CiDCTT3Ye01ygngG6bCLaIPbeQSgvmHe32G8HJQnhPb127MpG9m9QtT4qe-5NmTqrXWtZZqwpPmMhOE92q5dtqY-TRr6cYxgiBgoJGT-R9YyFrZWPjLnLAKUFJp3WM_InGFC_EeziOq619Z8jRbkfpmK1H6tozJ2Z_RQjlYaBr3YAo-FieElyzvGi6FRzjQe2X261JlwssWisVu_9B-LLk7tPchBuS07ve895NPKaDiQywiBLFQ3yuDnbn1VnxHpQeBQdAAabC9LXCnFlgXKQ_Lr1-VFuzGIUU9Gs0XzHK2EG9B0zGBPaMI7ZdH-1HuLkEiFyK9C3R9lcY3cRXjG3RWSFdQcrOfGBdIiNTrEyNhQHo4nC0gCb_OHhIXRQdCg2HDjcB_vXPbb_kntZb5rtvy_XIUaZGU2KysLxg7UX6XIvmB8WmCufWm_blyUhcNOQ3KwKJ-yP38XCbZjO0OcM31g0TA1duGqIpaNiL0zAs4MyRE8JmBkK6ag5zq4iaxc4IlxCnnhQ_ai91TK9GrovKvWFmHryEjmMQKVmrvlNJvZs7PwF0ainpwLPfG1CMlzyba7MlirpN1TGdCrx6K-Hp8JGuAxfsvr8NofuQVQUPuIOjsZy2_3cxvc3ZcYFgOziCI2TnkZ3ZKJ2BtaDm5Z87hvSNK0X7ETjZ3NmZQjNrZPIbLzoh3utoOU_di9RMvvx1tzV-FcWCf9aBj7Iuq3Z0il5EbyrfBT3AW86hO_6edrD4VSXusLR_x9wpWJz_ukUMqeF6eCbLWy8lBK9rD-zbF6_XE7ydc271Mwgy3zjtL_NmwGZNWHUdWobaYhSjE6hKjnI2vzJ6XiOv_u8niF4inaxifFZ2pXFIBGZEe9EVPWapoQOJo0eWFFLf5fxO9XOcAv03iwLp8miugJ_4SHZ1QLr-0dgAJSaNDnOSt5rtM_INRmRhF4c=","summary":[{"type":"summary_text","text":"**Replacing session_start block**"},{"type":"summary_text","text":"**Implementing dispatch function error handling**"},{"type":"summary_text","text":"**Handling multi-target dispatch statuses**"}]},{"id":"rs_0179ee910f20ada4016a589755c4dc819b96146026e02d0b68","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJdeBGjhNp9z6hHRwQiIjnxPKzqZ9BibLt-7ukqeqPcWpUPFmNMoWiPozFOZdqEyrSYhr5bC5WZfLe0PS6IrJH-KpM2NAK8zxJSKDfK5Fy8L6Np5xY7ETHz6KBsKj3-AbYUo8QNWg2eaiNA8KUdQ2Z_L4LJsHJmu4NZ-1YSkP4uCh7ydEiLGFRZodePvkofLu-EKCqJ_p_e9eJUsOPbhjx1L7yWvJDGbFZzfKLG9cb9kEEfeyMt_vqtLu1O5HIHD1mMXR9-tiKK22S2NTCtSCbKVt8rFlDx_Qnc2Mm7iX2JcIgouhYBjb_M6W0-iTHXinBASDZFC1OkOZn2Y0A9VJbnRzBoZs4EsKctv9CFY9K3qYAY41FqkBkBalqNF2DTNXyS5G6iLAZBHe633Bo_4nrWEdKBLeaboBJieRjkCgB1x4peUA5wQ1jnaYn5nZNTolqvIICBU0MeovdbD_WEwcAh5OJkQxAhVGhckHG3J7V4FLs1zQnsyI7vwMiCoN-oTWriQm8yPhWm6meqWWHWG90lgB2yzN4T6z21TBiVpd1yGeSP8Q8Xvt7vdcsv6QlQ9prU5nie0YsoKPdWfiuk2MEvXi85gXvHqj2bycXN5tDstyhQIz0LsPZJcPl9wJX81cJWO0R5pyzSdqfyM5xUb8vXiWiBZsBOieyRVIwAtxbPGU6X1if8Aq2iT-RkB4Au3VGgmPI5JWvIjd-FdX5tfw-RuHP5BC7fwMsqDpNMh5SopUCssfqIHXIVhpLa53HNrtGcTeVtEabjeiHZ1Btajbvz_cKAWOxX8x8BP9DHwotQ4_vcNSAZ-2Jo7ObLy0vGchYZtNkCSFdCD7quujLSVaBMVPKV_oI8DptfJPauX7KZNLa9BC6lLDVLL-eG7krEEZLJ00RWA6FrQWrbLb6fVg4Nvypq5snlK6MpwJsP1dNLXxv-qPy97Uz0W2lXmphVb4UazUaZSmn0qtE6WvhrZvdUkbx2EMGi2Z9MZZTnkJZkotBiw6tr7tHN6vFoPsFrPxiLiKcKATT30bB1kH61GRQFe_bi6T6MABSE1NdxgPO-dE4dq1PjLEPlJIjOHRUY65OCXQPY0xC75BxcFFQuUwvQzKbmRjgm0Uy3v9YuaMY_agdkyTE6lRkqKnA6Nk-DLMM4BgCYAHfhGMcFk0pzkvyPmKBrtZQ-L7I_d5GzEfeHQu6g8GZs14Wa0LfCBrpA5j8bUjWyc5MKbTV3DDLbT3CJRN8hgUQY-pFWm3717UWiF386BshAUrbgnj8mQAkYjYdMUGfnxDrNxZx1vXDE0tlfsFbiaSemLWbHPk8YvnRVhylcnIoH7wGeFy6lWUQg53QaqgigSCSmDoHq4EtKr7VaaNVvBNKjBjF3SMdmV6iFpEyP9FF7-KAP4v2j8iFN48rtL3SSCkYo4RXG6UXYKLbCa76io9Y_5K--382AVFYOCZi0J7UcpeGGZPYMie9rd60bHKGV3uhaID7lpiEcoc1edVu5P37H623VvGu5z91RK6sssP0S_iFpHfguJeOWSLwq2BHXLZY6aLIxxmw0s7pDPNpjVmZVAw0KxlqFM8R8EvhuVVrQEL08R5M9Ofyat3yCOIJjDosDlWB-9vLWDGmNfWfEAc8KjScgYBIlbem4HK-Ed8UPd0Qk4iAIAbGJcoVwlovZM3F0buWFD4HkLG6xqi8nyaT72sukeCKvqovlGLqInp2v0t0nECKunXmI1GA7szJfbkxivjQCvp-3xY1Zc8z_u9m_CFEpbuj5q1dWVRQY9olwqmis0yz2L9VWefIH_QvHFQXqzUu12tBeyCG600KesAoIjRXfs34ryWaVDaj8NuJcQaVTnJH9KitryxkuhDApRhNutrK57xw87HLO4pD-ZW3P_F-4oK-u4BfEG1ZNo67pC_vRLaGzCCDoTYdCfwy-0ETtTFuSRO3tWkXLU1YESSf5kfN6C01ymKSfMjKiDnqQ9ooeymZqTaa7eO7_zFvCbhGUUNq8cUOL49xJFPOJqM7_V4Gkn4vzlpHeonx9L8kI-HFFxp0ePBifoI1m3hlgI69Stuf6HhApZxZT19tAIKg6by-7lHXSvK7NIomHUSuS3ngjXCTkuPR6XK4__d96pTUQSHtj9koS8NsI8IYno77dF36it5Y6Am4dvJmg-lqtid6fakSKFRJE2CenjdIa0yulgEGjbc6ENJXgyVm9M3aTFC5hWXGJBMTHv4Y4UY-EpzMCkVx0f47vOMLOdgUa9efLgWHz9r_NoF33baVdfmKfoO_u2oSgpUq5dxmD0fESgt7yA5kmQXMOmXBx9wcHyEaMGNny5AClzPjN5W5za_UpEKKIUi5cwuuGHlcsHhW4KJk9lbdV1ovLp0tilgCAOixMq3zTCg_bUNwIXEcBXauCuy4u4b9V06gn0f9KDVb2dWap2MPkN57FA6-8BoScY24CkY8brDMLI-WBhPa2fTbsUrC9AjMplz4X9FsiIxN2sDef-y--6VHyxVI1PFogRX6QjyYoJacf29IWpFhR8DisrRs60q1tP3G0sUzCe1u7a2HkqW4AGfEKZ1n5bzD1a4TgBRkYU95EmPlrCJEel6JCIu3fgbrjE1PBkFOBHZsCs5t__kb4zg1EQhfbUCOV2SZ2Itz0pyu7uXTVWPM8Q0wg0JipPRwmb4Och6R6ipTEBY8I7qiN5AU6KWlyujKtKHyJ9CadQFobW3c60xMtDmDfGa-ShAdAmStuSzisN66HSWsCQTTBKhJSJO-9fNaz-OWaCnygMOyjLtZtY57gjHA-rab2u8hZX3V104V7bXB3hPZ-onwtc1hYMpmFEHlxbQ9umz3SPKR4PsBVMidotHg8Yl0EcQ6HXkqCRk3Y7fcz0V0LLEEXdRsUIBCbrwC-DQFyfJ0ztn3yuCtWblQ7H--1aWSKUDs26LLtCJvdALz5DwrgRIewGQs9b9O1rlySGV23oXacPzi3iZJFGKFZouMBfLYf1_HK4owuJcmzZV1ejQ25s9GKUfCe2f06jM_bP2i9LBx_hGV1osr50X20FfOVZWiD28D1-z3lSkMZzj-FA4gZ8q-8E70TJdJyjxOxu4vVlXAM9YQCBX95wJ3oZ-DLT8Ycpc0StcuysbDmLqyUjePMEtbh4VvQI-opvKQEk2PA4yJCxJk7HPRgUTopi0QDHgX10v-ZYdqplCqCdVaZwpq8b4PixtIGkFAeDBKmr5empKmuWbsDytTv72TU7B5zFsXtfgokLKnG2otfPyqEm8Etuq0dSlfWwDl8VkNgoisEItvinhIyKo51uMytRxjj1MZ7a6mtZhwKEj3V-JzTVuppxxTzI2E1PrF6RxwxCUBf4tI4yphSs-8gjnIpMiRbmyo-wFe0deqv-Pw3qagTspid8f8PCuRMKlRnac4iFoF_nPSefpQF5RSKbCRo5OkzMdtdnO2Ulf6hpVp5k_twV8JUEh0n_8xFeQLDje-vFdohSjktdU3n7aSe6qWvG6b9KU3eIbV1NDb4LJ4qq8gzxT5vKAdmT7OL_u7jaLgLqxbO6uCMdD2t7Q-9Wg1HW5MNnoLwiBqLWoN8OW-Bxbc9c8xHEeldY1l0RO456Fxx99qKfCZ5vG63Q6SEwKXECCPzzqFg-XFyvRmWphRdJewOcE4XLzCQTXMv3_yyg6UachiiSVAIeTn-YU6aZqSF_5hc9li-VSFeu_EQl324CfgiBNzBbs9kCdQvsTIyz1VOcHuw4xFnLQlBumsDTxq2N5kRrf0zx296RasuOlJ1xNMa0_Ov5JYd4INJ7ccRuS_j615sd5JwgGWkO0ALld5vHPHMeOwXEsjfqRAll2Kv3Y4Z_5jKKr_Wy_X1KO0WxHHJXkDx1WBH6Fkbwyn4cTROEs82KNJrb1_vzvAAIgbe8nimAP4PgVWz7PdlPI-r_fpRPGXrq3kf14Fh4F5u-g8I_zgfOzh8jzA9algnNkR_yQ4jwOOHafpt9dJyavHMWR3Vh6hJtvNqSiGZRJbdSq93G_lAEL6QdC09WyFIY7acNBSYGB7Ec7cUGc2ZbhXug5G9dTdxxi2XpuUszWuJdjbKbTv1yjgSHGgD3kV9w-w7F_fwYucYG2eBToBIO08Lhc2QvhrRyHbK7QNCwv2RKNxZywZGav5ei7ntnk2IhcfY7S-VFoARhTX0SuVkUetHHUCY9qvzQGZuzMso3YEfXmGWG2OZtYKhfkecttQGBI_3RhqSlLmJelhB6UKvMoYrhg_g5iq78iph490fPBYBViYIsBwmArOSfLVY0XTCnX37RDrZi_8Yn4dpDiFWhCnxKceDoEHAtPQcDYOsmnTYCijmeqEiNmtJE74gJk03_FX0=","summary":[{"type":"summary_text","text":"**Refining update and startup flow**"},{"type":"summary_text","text":"**Adding timestamps to user messages**"},{"type":"summary_text","text":"**Ensuring idle state before shutdown**"}]},{"id":"ctc_0179ee910f20ada4016a58975eaae0819bbf01e48d480cee01","type":"custom_tool_call","status":"completed","call_id":"call_KBjtAXZtvmJwnPbc1hAPymIR","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#17B7]\nSWAP.BLK 1646:\n+\t\tpi.on(\"session_start\", async (_event, ctx) => {\n+\t\t\truntimeCtx = ctx;\n+\t\t\tui = ctx.ui;\n+\t\t\tsid = ctx.sessionManager.getSessionId();\n+\t\t\tif (!initialId) return;\n+\t\t\tawait activateEndpoint(initialId, undefined, ctx, { fatal: true });\n+\t\t});\nSWAP.BLK 1692:\n+\t\tconst blockSessionChange = (description, ctx) => {\n+\t\t\tif (!activated && !token) return;\n+\t\t\tctx.ui.notify(\n+\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n+\t\t\t\t\"warning\",\n+\t\t\t);\n+\t\t\treturn { cancel: true };\n+\t\t};\nSWAP.BLK 1708:\n+\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n+\t\tpi.on(\"context\", (event) => {\n+\t\t\tlet messages = event.messages;\n+\t\t\tif (\n+\t\t\t\tagentActive &&\n+\t\t\t\t!current &&\n+\t\t\t\t!dispatching &&\n+\t\t\t\tqueue.length > 0\n+\t\t\t) {\n+\t\t\t\tconst item = queue.shift();\n+\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n+\t\t\t\titem.submitted = true;\n+\t\t\t\titem.activeInjected = true;\n+\t\t\t\tcurrent = item;\n+\t\t\t\tmessages = [\n+\t\t\t\t\t...messages,\n+\t\t\t\t\t{\n+\t\t\t\t\t\trole: \"user\",\n+\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n+\t\t\t\t\t},\n+\t\t\t\t];\n+\t\t\t}\n+\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n+\t\t\t\tmessages = injectEnvelope(messages, current);\n+\t\t\t}\n+\t\t\tif (messages !== event.messages) return { messages };\n+\t\t});\n*** End Patch\n","name":"edit"}]},"duration":32492.637500000186,"ttft":6081.706400000025,"contextSnapshot":{"promptTokens":180262,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_KBjtAXZtvmJwnPbc1hAPymIR|ctc_0179ee910f20ada4016a58975eaae0819bbf01e48d480cee01","toolName":"edit","startedAt":"2026-07-16T08:33:41.888Z"},"id":"51f1727a","parentId":"5edf5bef","timestamp":"2026-07-16T08:33:41.888Z"}
{"type":"message","id":"50684060","parentId":"51f1727a","timestamp":"2026-07-16T08:33:41.970Z","message":{"role":"toolResult","toolCallId":"call_KBjtAXZtvmJwnPbc1hAPymIR|ctc_0179ee910f20ada4016a58975eaae0819bbf01e48d480cee01","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#4F98]\nSWAP.BLK 1646 → resolved lines 1646-1689 (44 lines)\nSWAP.BLK 1692 → resolved lines 1692-1698 (7 lines)\nSWAP.BLK 1708 → resolved lines 1708-1712 (5 lines)\n1646:\t\tpi.on(\"session_start\", async (_event, ctx) => {\n\n1648:\t\t\tui = ctx.ui;\n1649:\t\t\tsid = ctx.sessionManager.getSessionId();\n1650:\t\t\tif (!initialId) return;\n1651:\t\t\tawait activateEndpoint(initialId, undefined, ctx, { fatal: true });\n1652:\t\t});\n1653:\n1654:\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\n1655:\t\tconst blockSessionChange = (description, ctx) => {\n1656:\t\t\tif (!activated && !token) return;\n1657:\t\t\tctx.ui.notify(\n1658:\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n\n1660:\t\t\t);\n\n1662:\t\t};\n\n1670:\n1671:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n1672:\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n1673:\t\tpi.on(\"context\", (event) => {\n1674:\t\t\tlet messages = event.messages;\n1675:\t\t\tif (\n…\n1695:\t\t\t\tmessages = injectEnvelope(messages, current);\n1696:\t\t\t}\n1697:\t\t\tif (messages !== event.messages) return { messages };\n1698:\t\t});"}],"details":{"diff":" 1646|\t\tpi.on(\"session_start\", async (_event, ctx) => {\n\n 1648|\t\t\tui = ctx.ui;\n 1649|\t\t\tsid = ctx.sessionManager.getSessionId();\n-1650|\t\t\tconst bindArgs = [\"api\", \"--adapter\", ADAPTER, \"bind\", id, \"--set-session-id\", sid];\n-1651|\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n-1652|\t\t\tbindPromise = (async () => {\n-1653|\t\t\t\tconst bound = await runCommand(bindArgs);\n-1654|\t\t\t\ttoken = bound.match(/\\btoken=([^\\s]+)/)?.[1];\n-1655|\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n-1656|\t\t\t})();\n-1657|\t\t\ttry {\n-1658|\t\t\t\tawait bindPromise;\n-1659|\t\t\t} catch (error) {\n-1660|\t\t\t\tif (stopping) return;\n-1661|\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n-1662|\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n-1663|\t\t\t\treturn;\n-1664|\t\t\t}\n-1665|\t\t\tif (stopping) {\n-1666|\t\t\t\ttry {\n-1667|\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n-1668|\t\t\t\t} catch (error) {\n-1669|\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n-1670|\t\t\t\t}\n-1671|\t\t\t\treturn;\n-1672|\t\t\t}\n-1673|\t\t\ttry {\n-1674|\t\t\t\tawait syncDesiredState();\n-1675|\t\t\t\tif (stopping) {\n-1676|\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n-1677|\t\t\t\t\treturn;\n-1678|\t\t\t\t}\n-1679|\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n-1680|\t\t\t\tstartListener();\n-1681|\t\t\t} catch (error) {\n-1682|\t\t\t\tif (stopping) {\n-1683|\t\t\t\t\tlogError(\"omp-spt session teardown failed\", error);\n-1684|\t\t\t\t\treturn;\n-1685|\t\t\t\t}\n-1686|\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n-1687|\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n-1688|\t\t\t}\n+1650|\t\t\tif (!initialId) return;\n+1651|\t\t\tawait activateEndpoint(initialId, undefined, ctx, { fatal: true });\n 1689|\t\t});\n 1690|\n 1691|\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\n 1692|\t\tconst blockSessionChange = (description, ctx) => {\n+1656|\t\t\tif (!activated && !token) return;\n 1693|\t\t\tctx.ui.notify(\n 1694|\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n\n 1696|\t\t\t);\n\n 1698|\t\t};\n\n 1706|\n 1707|\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n+1672|\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n 1708|\t\tpi.on(\"context\", (event) => {\n-1709|\t\t\tif (!current?.submitted || current.settling) return;\n-1710|\t\t\tconst messages = injectEnvelope(event.messages, current);\n+1674|\t\t\tlet messages = event.messages;\n+1675|\t\t\tif (\n+1676|\t\t\t\tagentActive &&\n+1677|\t\t\t\t!current &&\n+1678|\t\t\t\t!dispatching &&\n+1679|\t\t\t\tqueue.length > 0\n+1680|\t\t\t) {\n+1681|\t\t\t\tconst item = queue.shift();\n+1682|\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n+1683|\t\t\t\titem.submitted = true;\n+1684|\t\t\t\titem.activeInjected = true;\n+1685|\t\t\t\tcurrent = item;\n+1686|\t\t\t\tmessages = [\n+1687|\t\t\t\t\t...messages,\n+1688|\t\t\t\t\t{\n+1689|\t\t\t\t\t\trole: \"user\",\n+1690|\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n+1691|\t\t\t\t\t},\n+1692|\t\t\t\t];\n+1693|\t\t\t}\n+1694|\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n+1695|\t\t\t\tmessages = injectEnvelope(messages, current);\n+1696|\t\t\t}\n 1711|\t\t\tif (messages !== event.messages) return { messages };\n 1712|\t\t});","firstChangedLine":1646,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190821970}}
{"type":"message","id":"a1891388","parentId":"50684060","timestamp":"2026-07-16T08:33:46.678Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Inserting before_agent_start and shortform functions**"},{"type":"toolCall","id":"call_na5neUZqurBDXIhe6dwnDqjo|fc_0dcbb9f572ff5071016a5897692660819b8fd03dd9cfafa165","name":"read","arguments":{"i":"Reading lifecycle insertion point","path":"adapter/strings/omp-spt.mjs","selector":"1640-1775"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2384,"output":67,"cacheRead":179712,"cacheWrite":0,"totalTokens":182163,"reasoningTokens":25,"cost":{"input":0.011920000000000002,"output":0.00201,"cacheRead":0.08985599999999999,"cacheWrite":0,"total":0.10378599999999999}},"stopReason":"toolUse","timestamp":1784190822016,"responseId":"resp_0dcbb9f572ff5071016a5897665b14819b97bfae99ffe7fac3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0dcbb9f572ff5071016a58976829f8819bb17f36ec0a9e3c38","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJdp8gCzdKrXur2vKHEwN--XoAUztXmvUJG0d4TuM-H_0yOawyX8Ui44IOS012vUuY5zk13Ua9F4jwZ1OAliJkixKGyufbm-eqHeXUdJlcK9c-OGThr2Z8lpfcVxVEpVV83HA4yROjL149Bue3ssUFHehEKAvh2L3yiKDB5w1vLm0Dx2pACq5ic9ZDwdBKXN8tt3ByCEZIYDj8pPklo0kCk7CUiYslOVp5v8iRGVj_dYGNyoahaK5shBlivsxNza_RvVEl-wM7L68wLfgGo8w0_cC1Jz7QATL9quL1EWE_Uo5J2-HB5BiE9zsRhSBNvLvwwszBSYP-6_zsBmyIRUg42r1nQ43ltr-_onpyXynwAlAtP570MDS4DVerYPopeTK2NQr3aMDyVz_p06f8UlTG42g1LW8nXrAo-lZvUKkgAf1yuO0GB128eKUqpS2TFADD00r_MM_zRFFG6UO6slmXyMp-1D9E_tiKJo0CFpheHpzihfp-6Mx8o9WvrsvKAxQIyvXcNEQlNToAM1tsKQjcq0fHyQGJsBZ404vXWuV-rScmV1XQSv-8gbjweXVMBCCekzy9Bsz1d5v3FoyC-ct_pXQyk68hlE62ajzSrFg7a5fouIaFz9Vy33RjzmYCivuXj48QDWFUa5ZW2Gfwtpwd6IOGm9qQEHFNGBHiOGaf1UlGW_ChomR_Gm8v7WPKA2biqeTob2eI1tm690cCUTwnnpG06XKDOptFacha1VZGhKiFIAPpR2KUWXoigT1_YkgXZxluqGmMHqJkt48DEf7Kmb_nQ0eiLs1f7hjpJo-jqqv-NNS5BQGH4jUbVGFxWE0gLM8PzLeGu5RTmqnOl9MdXpiIY6ho64Db0P3qFyt4NMww8bz1dsLlcOKXTUBqLw2tQCGXZ0tQ9VTICeVsehSbl_66oAs0K9eGxtsFqbhqP3FfLdaLRPV5VWmc5BQEp1a3f9CDQAhVNOUCDVgH6sFKr-8vX-3NnV7Bx1ujd-sym3i_aF6gD1UoJmWq7ojbDzAySgiZqD4kM0bRgTW-5zRDkQaVOAJ5lUbGg-zaH_3CeHn_w=","summary":[{"type":"summary_text","text":"**Inserting before_agent_start and shortform functions**"}]},{"id":"fc_0dcbb9f572ff5071016a5897692660819b8fd03dd9cfafa165","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading lifecycle insertion point\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1640-1775\"}","call_id":"call_na5neUZqurBDXIhe6dwnDqjo","name":"read"}]},"duration":4647.26220000023,"ttft":4632.4585000001825,"contextSnapshot":{"promptTokens":182096,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_na5neUZqurBDXIhe6dwnDqjo|fc_0dcbb9f572ff5071016a5897692660819b8fd03dd9cfafa165","toolName":"read","startedAt":"2026-07-16T08:33:46.679Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading lifecycle insertion point"},"id":"1bc0072a","parentId":"a1891388","timestamp":"2026-07-16T08:33:46.679Z"}
{"type":"message","id":"7d84c5c9","parentId":"1bc0072a","timestamp":"2026-07-16T08:33:46.873Z","message":{"role":"toolResult","toolCallId":"call_na5neUZqurBDXIhe6dwnDqjo|fc_0dcbb9f572ff5071016a5897692660819b8fd03dd9cfafa165","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#4F98]\n516:export function createOmpSpt(overrides = {}) {\n…\n650:\treturn function ompSpt(pi) {\n…\n1551:\t\tfunction startListener() {\n…\n1638:\t\t\tchild.on(\"close\", (code, signal) => {\n1639:\t\t\t\tconst status = signal ? `signal ${signal}` : code;\n1640:\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\n1641:\t\t\t});\n1642:\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\n1643:\t\t}\n1644:\n1645:\t\t// [impl->REQ-OMP-NATIVE-TUI]\n1646:\t\tpi.on(\"session_start\", async (_event, ctx) => {\n1647:\t\t\truntimeCtx = ctx;\n1648:\t\t\tui = ctx.ui;\n1649:\t\t\tsid = ctx.sessionManager.getSessionId();\n1650:\t\t\tif (!initialId) return;\n1651:\t\t\tawait activateEndpoint(initialId, undefined, ctx, { fatal: true });\n1652:\t\t});\n1653:\n1654:\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\n1655:\t\tconst blockSessionChange = (description, ctx) => {\n1656:\t\t\tif (!activated && !token) return;\n1657:\t\t\tctx.ui.notify(\n1658:\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\n1659:\t\t\t\t\"warning\",\n1660:\t\t\t);\n1661:\t\t\treturn { cancel: true };\n1662:\t\t};\n1663:\n1664:\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n1665:\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\n1666:\t\t);\n1667:\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\n1668:\t\t\tblockSessionChange(\"session branch\", ctx),\n1669:\t\t);\n1670:\n1671:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n1672:\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n1673:\t\tpi.on(\"context\", (event) => {\n1674:\t\t\tlet messages = event.messages;\n1675:\t\t\tif (\n1676:\t\t\t\tagentActive &&\n1677:\t\t\t\t!current &&\n1678:\t\t\t\t!dispatching &&\n1679:\t\t\t\tqueue.length > 0\n1680:\t\t\t) {\n1681:\t\t\t\tconst item = queue.shift();\n1682:\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n1683:\t\t\t\titem.submitted = true;\n1684:\t\t\t\titem.activeInjected = true;\n1685:\t\t\t\tcurrent = item;\n1686:\t\t\t\tmessages = [\n1687:\t\t\t\t\t...messages,\n1688:\t\t\t\t\t{\n1689:\t\t\t\t\t\trole: \"user\",\n1690:\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n1691:\t\t\t\t\t},\n1692:\t\t\t\t];\n1693:\t\t\t}\n1694:\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n1695:\t\t\t\tmessages = injectEnvelope(messages, current);\n1696:\t\t\t}\n1697:\t\t\tif (messages !== event.messages) return { messages };\n1698:\t\t});\n1699:\n1700:\t\tasync function completeTurn(event) {\n1701:\t\t\tagentActive = false;\n1702:\t\t\tdesiredState = \"idle\";\n1703:\t\t\tif (stopping) return;\n1704:\t\t\tconst completed = current;\n1705:\t\t\tif (completed?.submitted && !completed.settled) {\n1706:\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\n1707:\t\t\t\ttry {\n1708:\t\t\t\t\tawait settleItem(\n1709:\t\t\t\t\t\tcompleted,\n1710:\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n1711:\t\t\t\t\t);\n1712:\t\t\t\t} catch (error) {\n1713:\t\t\t\t\tif (stopping) return;\n1714:\t\t\t\t\tawait failClosed(\n1715:\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n1716:\t\t\t\t\t\terror,\n1717:\t\t\t\t\t);\n1718:\t\t\t\t\treturn;\n1719:\t\t\t\t}\n1720:\t\t\t}\n1721:\t\t\tif (current === completed) {\n1722:\t\t\t\tcurrent = undefined;\n1723:\t\t\t\treleaseItem(completed);\n1724:\t\t\t}\n1725:\t\t\ttry {\n1726:\t\t\t\tawait setState(\"idle\");\n1727:\t\t\t} catch (error) {\n1728:\t\t\t\tif (stopping) return;\n1729:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n1730:\t\t\t\treturn;\n1731:\t\t\t}\n1732:\t\t\tscheduleDispatch();\n1733:\t\t}\n1734:\n1735:\t\tpi.on(\"agent_start\", async () => {\n1736:\t\t\tif (stopping) return;\n1737:\t\t\tturnCompletionPromise = undefined;\n1738:\t\t\tagentActive = true;\n1739:\t\t\tdesiredState = \"busy\";\n1740:\t\t\ttry {\n1741:\t\t\t\tawait syncDesiredState();\n1742:\t\t\t} catch (error) {\n1743:\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\n1744:\t\t\t}\n1745:\t\t});\n1746:\n1747:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1748:\t\tpi.on(\"agent_end\", (event) => {\n1749:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1750:\t\t\treturn turnCompletionPromise;\n1751:\t\t});\n1752:\n1753:\t\tpi.on(\"session_stop\", async (event) => {\n1754:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1755:\t\t\tawait turnCompletionPromise;\n1756:\t\t});\n1757:\n1758:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n1759:\t\t\truntimeCtx ??= ctx;\n1760:\t\t\tui?.setStatus(\"omp-spt\", undefined);\n1761:\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\n1762:\t\t});\n1763:\t};\n1764:}\n1765:\n1766:export default createOmpSpt();\n1767:"}],"details":{"displayContent":{"text":"export function createOmpSpt(overrides = {}) {\n…\n\treturn function ompSpt(pi) {\n…\n\t\tfunction startListener() {\n…\n\t\t\tchild.on(\"close\", (code, signal) => {\n\t\t\t\tconst status = signal ? `signal ${signal}` : code;\r\n\t\t\t\tdied(new Error(`spt api listen exited ${status}`), true);\r\n\t\t\t});\r\n\t\t\tui?.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-OMP-NATIVE-TUI]\r\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\r\n\t\t\truntimeCtx = ctx;\r\n\t\t\tui = ctx.ui;\r\n\t\t\tsid = ctx.sessionManager.getSessionId();\r\n\t\t\tif (!initialId) return;\r\n\t\t\tawait activateEndpoint(initialId, undefined, ctx, { fatal: true });\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-SESSION-IMMUTABLE]\r\n\t\tconst blockSessionChange = (description, ctx) => {\r\n\t\t\tif (!activated && !token) return;\r\n\t\t\tctx.ui.notify(\r\n\t\t\t\t`omp-spt blocked the in-TUI ${description}; end this SPT session first`,\r\n\t\t\t\t\"warning\",\r\n\t\t\t);\r\n\t\t\treturn { cancel: true };\r\n\t\t};\r\n\r\n\t\tpi.on(\"session_before_switch\", (event, ctx) =>\r\n\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tlet messages = event.messages;\r\n\t\t\tif (\r\n\t\t\t\tagentActive &&\r\n\t\t\t\t!current &&\r\n\t\t\t\t!dispatching &&\r\n\t\t\t\tqueue.length > 0\r\n\t\t\t) {\r\n\t\t\t\tconst item = queue.shift();\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\titem.activeInjected = true;\r\n\t\t\t\tcurrent = item;\r\n\t\t\t\tmessages = [\r\n\t\t\t\t\t...messages,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\trole: \"user\",\r\n\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}\r\n\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\r\n\t\t\t\tmessages = injectEnvelope(messages, current);\r\n\t\t\t}\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\tawait turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\r\n\t\t\truntimeCtx ??= ctx;\r\n\t\t\tui?.setStatus(\"omp-spt\", undefined);\r\n\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\r\n\t\t});\r\n\t};\r\n}\r\n\r\nexport default createOmpSpt();\r\n","startLine":516,"lineNumbers":[516,null,650,null,1551,null,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"}}},"isError":false,"timestamp":1784190826873}}
{"type":"message","id":"4c739171","parentId":"7d84c5c9","timestamp":"2026-07-16T08:34:12.366Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning agent handler registration**\n\n**Handling shortform dispatch failures**"},{"type":"toolCall","id":"call_bc9Jg6Ly40GTl7CmO356ArBl|ctc_0f53b91ae4689055016a58977633408198b3e492e6df24c3a6","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#4F98]\nINS.POST 1698:\n+\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n+\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n+\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n+\t\tpi.on(\"before_agent_start\", async (event) => {\n+\t\t\tif (!activated || !id || stopping) return;\n+\t\t\tconst additions = [];\n+\t\t\tif (startupBriefPending) {\n+\t\t\t\tstartupBriefPending = false;\n+\t\t\t\tadditions.push(startupBrief(id));\n+\t\t\t}\n+\t\t\tconst hints = promptHints(event.prompt);\n+\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\n+\t\t\tif (updateNoticesPending) {\n+\t\t\t\tupdateNoticesPending = false;\n+\t\t\t\tconst notices = await updateNoticesPromise;\n+\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\n+\t\t\t}\n+\t\t\tif (additions.length === 0) return;\n+\t\t\treturn {\n+\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\n+\t\t\t};\n+\t\t});\n+\n+\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n+\t\tasync function dispatchShortforms(messages, afterUserMessage) {\n+\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\n+\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n+\t\t\tif (shortforms.length === 0) return;\n+\t\t\tconst statuses = [];\n+\t\t\tfor (const shortform of shortforms) {\n+\t\t\t\tfor (const target of shortform.targets) {\n+\t\t\t\t\tif (!id) {\n+\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\n+\t\t\t\t\t\tcontinue;\n+\t\t\t\t\t}\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\n+\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\ttry {\n+\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t{\n+\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n+\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n+\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t},\n+\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t);\n+\t\t\t} catch (error) {\n+\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\n+\t\t\t}\n+\t\t}\n+\nSWAP.BLK 1700:\n+\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+\t\tasync function completeTurn(event) {\n+\t\t\tagentActive = false;\n+\t\t\tdesiredState = \"idle\";\n+\t\t\tif (stopping) return;\n+\t\t\tconst messages = event.messages ?? [];\n+\t\t\tconst completed = current;\n+\t\t\tif (completed?.submitted && !completed.settled) {\n+\t\t\t\tconst reply = extractReply(messages, completed.stub);\n+\t\t\t\ttry {\n+\t\t\t\t\tawait settleItem(\n+\t\t\t\t\t\tcompleted,\n+\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n+\t\t\t\t\t);\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tif (stopping) return;\n+\t\t\t\t\tawait failClosed(\n+\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n+\t\t\t\t\t\terror,\n+\t\t\t\t\t);\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tawait dispatchShortforms(messages, completed?.stub);\n+\t\t\tif (current === completed) {\n+\t\t\t\tcurrent = undefined;\n+\t\t\t\treleaseItem(completed);\n+\t\t\t}\n+\t\t\ttry {\n+\t\t\t\tawait setState(\"idle\");\n+\t\t\t} catch (error) {\n+\t\t\t\tif (stopping) return;\n+\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t\tscheduleDispatch();\n+\t\t}\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1813,"output":1201,"cacheRead":181760,"cacheWrite":0,"totalTokens":184774,"reasoningTokens":238,"cost":{"input":0.009065,"output":0.03603,"cacheRead":0.09088,"cacheWrite":0,"total":0.135975}},"stopReason":"toolUse","timestamp":1784190826921,"responseId":"resp_0f53b91ae4689055016a58976b42fc81988aaf543857250da3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0f53b91ae4689055016a58976e59288198a1d34422f74e1919","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJd2leDYfzzN0QcIYayNjhIKB05GQYmYekpBli_ZTwEFY2eyJngcB4TYD3Em1vrTnnwNYWGy7DyYq5aVu6WJF7W2iucHiKf0J7Mo__0dWMlUm6jCH4cNHp5-uDn5_E1Fw4syNl439yRZcw00tLxFmb_3DubZMb8ZqEZ6RbxT9BzI8Dd-6vj2DjW-t9zeVOoa-ZzlmJBqC6Tbcd74rk_xkNyKk2mcmxhbWodZMCAiQ29BT4QdaSJWCT8a0N6dXwnl1woHrKcsu1Ut2vvewUlNyW9P30O8xNClzFtA9bMmKIeKkEJelf-q-hiequSjJ3o8kfh2AnMEn79vw9CWSaMqOtk8a4tMMTrt-3PVfZB2JB19Ok-HPcrSf7w_TDFkg4HYnEVx0BaXPqMeknF6v5ZnR2YCS7RiK42N_DDc0y3q20uPckuZe8g3aJ5lequUdkAT-nEVfw2z7devXzuRJDZoUbfqEH9Zv4xzLEh1RzWZDd7wN2UDjzfgjbJZoVdI9AxExRaH8IHSIH4BNSDXjXd_Tl792s6wQsaTJt6IaCtyNKR1qrt5AJjvZBw2sC-8Hpnea0hYYxBJhoBuk046W1X6NXIVa5bzE2rvm2BhCWQaz0RUka7TZmvIi-x4VRSLJ1ysLbUi5g3OwjUHIuA5wHJj0fQrHiU53s2D6GuVXz3EigHQs6LJZZZXWRgFmR1Hx70e-DjSlzEVCzPOeORKd0IDxcX4tn1jet6uC7UkrYoMFvENneU7IiZWUDsN5TlBeXRTPh-k3SIlhz80aPa0GK4h9DRrspjQ9wHQCES0kEWhwIuVOrWCSxLOBFsY1Ud95awJcWain4zXHAqeSkBltgiYn7i3QcCTtMIvNXtoLn8vx_GOzOb_XhwAFz8LelOwsldS-ONXKqayw8JSqfzoWWcBeCyxEwOS59hIdDkmAyfoQww2VIPM_wO66oNS2TqQeoI2Fivkh8D-d8YuSywWJi3QPn1h4LJLR8lyLMw56hzbM4hyZy5MOCFANvyosumz0_dNaZdFHA2dSZRG-PmCgjrWqx182QjNoe960vIh4XWV8RfJcArtQZwubkYiFEIG5lcDdogN_-aK9fhaFOPAt5XaPa_INPM99HXlcIq6XCb0SNwe1Ifkvl-Rsw8caKtG8UZqGQQlFrZwKfMd7OepJ8YsOwVTo9HApqbGPl2A-9xbldFjEr7FS523MipG5nr9ZMA1l8swfYvD6UYgx9DF69ENv3SYFVdVXhO6Q7pHw0MAFWH3yfbXzIxqBOE6QzRBr-CllUeo9ND6ZkltnkspaHXN_d_qBedDwMQIPS7pMp2SnEypTORruzxEYQq3mID_ysgSkSlhjrALitomn7-qVgPoHAFceKq0NoKbn1jQWrd99uer1beJMcoWcbw_uSQeU1zGk1AaO-KOQmOsxpp1e4ggh-TL8KAO4IuW07yV2UNqOpu5Bn7pySpRU6WRKDB6MqWTHsttsfyjHRHmLgz1jewU2bKwXNI-6GtcCyQlIEanMPYoOsoMjtPzqKMhORN2w-tEcEPv1Nzx6G9Vf0UrgtV5nlIQ_11UNfdAJ-RjncZUPKVVTUbIZ2GjxABv856-q_-SD0C6D2pSodjOl8AFrZIaONCJ6C-HB8iiNvAT3cNXaGTwMRx9QLNXW4yQPRsrDnaPF7ghuO9Dq559DJCmMR5OeXKjJMLjUyPg0XdVGvfhaE8yNGoh1jYRy9TIeo0JyrdwTMsDGLj4LcXNvv3mQDlH4DreH0JV_w8hyD3iutfh5zPwmWa998C7ZckmkiiOlsKqfIyRlGKJL4yoXdnOf_mRiN-V-HEJatNt3J90MNyBbmhU5xXoJzhPTlryfy08qQh9w9Lq0tOyYlKbaz1434KtecuYTDtztnaZb_5Ikkjtwu_F0ZBJ0Eu2KFghUwsmPUtQ1RiNuALnNTIFPeH2KJheK4XZ2pp5nhqrYSOW6HRyV5ImerXjOz55DsOiQ6goy8559ZkH9gq2XhAa9pmNTUysT5c5f9N22suOxzuwyruZntz9U_RrD0zT9EgPLUp5iYA9Q5H_3Zcjpp06U_BjApRFKq_P_x8zpvIrcktSogiYjRcqPdEWGGgnMMsQWFjBVpnzi8toEh2QlF3tcjYGXZvOkLkeiHstZzWBD96JUIqwfkKV55fEtgvmErIx0ofkyIfIT21-o5omBKc0o59qmAFFkkgutEv-XtCYmmfwGWM-bZ9rVvQOnSI16nrYdPJiTg0dDYlQbvWNTS0JnBdHDx31hLTD54-nuvmq3-Lalt1jp_8RrJev7OOkkzC7K-7_nI4V7WmEkd1GmNJs3D4NOIK9WPprU9AHaGfQ-U4qShE1Gv7LzAht7cIGbeCKEJsAcfqaxM70b2Aoy5Gs2PaH2z1eyehAvkUQmdw1QNf2zR0B5CQDQ-2FeQXRDb4VhkbuY-H5MmjmJEwIG0fzyTaV1QqEMyyFtsxVoLTkaUSHtkFhFl-C7HJaGj7jRqVbgTrPpYiPBw5_","summary":[{"type":"summary_text","text":"**Planning agent handler registration**"},{"type":"summary_text","text":"**Handling shortform dispatch failures**"}]},{"id":"ctc_0f53b91ae4689055016a58977633408198b3e492e6df24c3a6","type":"custom_tool_call","status":"completed","call_id":"call_bc9Jg6Ly40GTl7CmO356ArBl","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#4F98]\nINS.POST 1698:\n+\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n+\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n+\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n+\t\tpi.on(\"before_agent_start\", async (event) => {\n+\t\t\tif (!activated || !id || stopping) return;\n+\t\t\tconst additions = [];\n+\t\t\tif (startupBriefPending) {\n+\t\t\t\tstartupBriefPending = false;\n+\t\t\t\tadditions.push(startupBrief(id));\n+\t\t\t}\n+\t\t\tconst hints = promptHints(event.prompt);\n+\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\n+\t\t\tif (updateNoticesPending) {\n+\t\t\t\tupdateNoticesPending = false;\n+\t\t\t\tconst notices = await updateNoticesPromise;\n+\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\n+\t\t\t}\n+\t\t\tif (additions.length === 0) return;\n+\t\t\treturn {\n+\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\n+\t\t\t};\n+\t\t});\n+\n+\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n+\t\tasync function dispatchShortforms(messages, afterUserMessage) {\n+\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\n+\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n+\t\t\tif (shortforms.length === 0) return;\n+\t\t\tconst statuses = [];\n+\t\t\tfor (const shortform of shortforms) {\n+\t\t\t\tfor (const target of shortform.targets) {\n+\t\t\t\t\tif (!id) {\n+\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\n+\t\t\t\t\t\tcontinue;\n+\t\t\t\t\t}\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\n+\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\ttry {\n+\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t{\n+\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n+\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n+\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t},\n+\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t);\n+\t\t\t} catch (error) {\n+\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\n+\t\t\t}\n+\t\t}\n+\nSWAP.BLK 1700:\n+\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+\t\tasync function completeTurn(event) {\n+\t\t\tagentActive = false;\n+\t\t\tdesiredState = \"idle\";\n+\t\t\tif (stopping) return;\n+\t\t\tconst messages = event.messages ?? [];\n+\t\t\tconst completed = current;\n+\t\t\tif (completed?.submitted && !completed.settled) {\n+\t\t\t\tconst reply = extractReply(messages, completed.stub);\n+\t\t\t\ttry {\n+\t\t\t\t\tawait settleItem(\n+\t\t\t\t\t\tcompleted,\n+\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n+\t\t\t\t\t);\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tif (stopping) return;\n+\t\t\t\t\tawait failClosed(\n+\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n+\t\t\t\t\t\terror,\n+\t\t\t\t\t);\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tawait dispatchShortforms(messages, completed?.stub);\n+\t\t\tif (current === completed) {\n+\t\t\t\tcurrent = undefined;\n+\t\t\t\treleaseItem(completed);\n+\t\t\t}\n+\t\t\ttry {\n+\t\t\t\tawait setState(\"idle\");\n+\t\t\t} catch (error) {\n+\t\t\t\tif (stopping) return;\n+\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t\tscheduleDispatch();\n+\t\t}\n*** End Patch\n","name":"edit"}]},"duration":25399.09819999989,"ttft":3426.1131000001915,"contextSnapshot":{"promptTokens":183573,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_bc9Jg6Ly40GTl7CmO356ArBl|ctc_0f53b91ae4689055016a58977633408198b3e492e6df24c3a6","toolName":"edit","startedAt":"2026-07-16T08:34:12.368Z"},"id":"f0993929","parentId":"4c739171","timestamp":"2026-07-16T08:34:12.368Z"}
{"type":"message","id":"f6209d21","parentId":"f0993929","timestamp":"2026-07-16T08:34:12.403Z","message":{"role":"toolResult","toolCallId":"call_bc9Jg6Ly40GTl7CmO356ArBl|ctc_0f53b91ae4689055016a58977633408198b3e492e6df24c3a6","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#F56A]\nSWAP.BLK 1700 → resolved lines 1700-1733 (34 lines)\n1673:\t\tpi.on(\"context\", (event) => {\n\n1697:\t\t\tif (messages !== event.messages) return { messages };\n1698:\t\t});\n1699:\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n1700:\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n…\n1719:\t\t\t};\n1720:\t\t});\n1721:\n1722:\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n1723:\t\tasync function dispatchShortforms(messages, afterUserMessage) {\n…\n1757:\n1758:\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n1759:\t\tasync function completeTurn(event) {\n1760:\t\t\tagentActive = false;\n1761:\t\t\tdesiredState = \"idle\";\n1762:\t\t\tif (stopping) return;\n1763:\t\t\tconst messages = event.messages ?? [];\n1764:\t\t\tconst completed = current;\n1765:\t\t\tif (completed?.submitted && !completed.settled) {\n1766:\t\t\t\tconst reply = extractReply(messages, completed.stub);\n1767:\t\t\t\ttry {\n1768:\t\t\t\t\tawait settleItem(\n\n1771:\t\t\t\t\t);\n1772:\t\t\t\t} catch (error) {\n\n1779:\t\t\t\t}\n1780:\t\t\t}\n1781:\t\t\tawait dispatchShortforms(messages, completed?.stub);\n1782:\t\t\tif (current === completed) {\n1783:\t\t\t\tcurrent = undefined;\n\n1785:\t\t\t}\n\n1794:\t\t}"}],"details":{"diff":" 1673|\t\tpi.on(\"context\", (event) => {\n\n 1697|\t\t\tif (messages !== event.messages) return { messages };\n 1698|\t\t});\n+1699|\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n+1700|\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n+1701|\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n+1702|\t\tpi.on(\"before_agent_start\", async (event) => {\n+1703|\t\t\tif (!activated || !id || stopping) return;\n+1704|\t\t\tconst additions = [];\n+1705|\t\t\tif (startupBriefPending) {\n+1706|\t\t\t\tstartupBriefPending = false;\n+1707|\t\t\t\tadditions.push(startupBrief(id));\n+1708|\t\t\t}\n+1709|\t\t\tconst hints = promptHints(event.prompt);\n+1710|\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\n+1711|\t\t\tif (updateNoticesPending) {\n+1712|\t\t\t\tupdateNoticesPending = false;\n+1713|\t\t\t\tconst notices = await updateNoticesPromise;\n+1714|\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\n+1715|\t\t\t}\n+1716|\t\t\tif (additions.length === 0) return;\n+1717|\t\t\treturn {\n+1718|\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\n+1719|\t\t\t};\n+1720|\t\t});\n 1699|\n+1722|\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n+1723|\t\tasync function dispatchShortforms(messages, afterUserMessage) {\n+1724|\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\n+1725|\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n+1726|\t\t\tif (shortforms.length === 0) return;\n+1727|\t\t\tconst statuses = [];\n+1728|\t\t\tfor (const shortform of shortforms) {\n+1729|\t\t\t\tfor (const target of shortform.targets) {\n+1730|\t\t\t\t\tif (!id) {\n+1731|\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\n+1732|\t\t\t\t\t\tcontinue;\n+1733|\t\t\t\t\t}\n+1734|\t\t\t\t\ttry {\n+1735|\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\n+1736|\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\n+1737|\t\t\t\t\t} catch (error) {\n+1738|\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\n+1739|\t\t\t\t\t}\n+1740|\t\t\t\t}\n+1741|\t\t\t}\n+1742|\t\t\ttry {\n+1743|\t\t\t\tpi.sendMessage(\n+1744|\t\t\t\t\t{\n+1745|\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n+1746|\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n+1747|\t\t\t\t\t\tdisplay: true,\n+1748|\t\t\t\t\t\tattribution: \"user\",\n+1749|\t\t\t\t\t},\n+1750|\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+1751|\t\t\t\t);\n+1752|\t\t\t} catch (error) {\n+1753|\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\n+1754|\t\t\t}\n+1755|\t\t}\n+1756|\n+1757|\n+1758|\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n 1700|\t\tasync function completeTurn(event) {\n 1701|\t\t\tagentActive = false;\n 1702|\t\t\tdesiredState = \"idle\";\n 1703|\t\t\tif (stopping) return;\n+1763|\t\t\tconst messages = event.messages ?? [];\n 1704|\t\t\tconst completed = current;\n 1705|\t\t\tif (completed?.submitted && !completed.settled) {\n-1706|\t\t\t\tconst reply = extractReply(event.messages, completed.stub);\n+1766|\t\t\t\tconst reply = extractReply(messages, completed.stub);\n 1707|\t\t\t\ttry {\n 1708|\t\t\t\t\tawait settleItem(\n\n 1711|\t\t\t\t\t);\n 1712|\t\t\t\t} catch (error) {\n\n 1719|\t\t\t\t}\n 1720|\t\t\t}\n+1781|\t\t\tawait dispatchShortforms(messages, completed?.stub);\n 1721|\t\t\tif (current === completed) {\n 1722|\t\t\t\tcurrent = undefined;\n\n 1724|\t\t\t}\n\n 1733|\t\t}","firstChangedLine":1698,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190852402}}
{"type":"message","id":"737aa0a6","parentId":"f6209d21","timestamp":"2026-07-16T08:34:18.032Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Confirming SWAP.BLK line adjustments**"},{"type":"toolCall","id":"call_MKPEY4YdmRtv2kfQ0jzFtUtz|fc_0755b4eee615cb72016a5897890eb08199a00d70036fc18e14","name":"grep","arguments":{"i":"Checking extension state usage","pattern":"listenerGeneration|activationType|updateNoticesPending|cachedReadyIds","path":"adapter/strings/omp-spt.mjs","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2374,"output":158,"cacheRead":182784,"cacheWrite":0,"totalTokens":185316,"reasoningTokens":89,"cost":{"input":0.01187,"output":0.00474,"cacheRead":0.091392,"cacheWrite":0,"total":0.108002}},"stopReason":"toolUse","timestamp":1784190852422,"responseId":"resp_0755b4eee615cb72016a589784ca1081998798c8f36a64f02a","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0755b4eee615cb72016a589786b34c81998d106d9acd34f4c3","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJeJI7r2KVdSjs8x2xzSF_6C16KiYSdel7NSwL1zEpofh5Fhaju0oIUaAAv2ExbyUTGmrPFepRpano0UTXHQFER2zSxiR4wNmNMHf12E-SbA15KBjMrT2rXRjAgak6epA_D2Um_bG89_m0Ro0bYoNOqfQKZsIiKEl1ibWmy1ocXJrh3fpWEwnRulwsLwxmwJQtxYGuo3PNsYyEOiPnScuRGwfKeY0otoJRuBA9K2GpDJX9SJZe8H_csaVc8oVN7kuMzmiNY0pNa6Jss4mib8AktHfLvP7dR1Gq1mrT6d9zufCWFLiYqzRgj5qe4uxQZNIlhFY4bepz0DGE80KjJskM8yeq8VgQZxJQDvLm_uOD0hZbnpH8uAE8fTVncldE7odTDqI23u8-QajTC56TMcMxVgLoOvuX4MmmVVrR9MHdS7jgEcWbY2jw0AJwP5mOARvzK8OZ8iiTv0RD7JQvn6SXX3N-5zA2ZRYOTZHhNsbjSAFxPcBYcbXJOqPHb6WT44JY6ItqjOkZPUUUqQYfYk9p451Y_LiTfV8nvUnk9F7t6bNPR7s8PGlY0VMqexTkUnDnC5uVgR-ewqo3aFXXazWsUxJpRMcg00_nfEmYHj8u4eHYQ4QyTbbisBXYUm1gDNWt6Dsc1EapLjyfNmq43-QEWgZZK7BEMxJRHpVUMFjSDqNvNBbCO5Go86KAQ2UeD0kg_qxOPo--Jk3Ws5lQLa9X36dP4DL5HCUXSnyBkGs_zwPD-GmZWIySdg9PW9iwhQHJB24VMcvYcJAB8LA-RZ1JJBqD6ztwksBPZxTfL6_fa4tXRLUdyk12rKfAncHU1CEkpvgmGusg2JKmeV6vfOFDSNDcdiQrveKcW6kLEiJDBJS3siBtm20WJTjhzqibkyFGiGXZ4WunclZYLajkyjN-SPLruFvi1d0SLlyb8I4UJz-6uw2f9WOso1Yu6SWiolKf3Qho0jJgXa1x-QD17NUNVjWk6nNYmr0J_I6B6IZXyzarLoKx58kDY-y-3tISE0ESknemSqfVjKVFALdESa5K_ydldIlZBCl2DG-3sIXlkQPmXBU08qeTmmYgbyx58HOeESxjhQckq1_vrd_BSAszvr_ucauqHSXeYCInggURfuZ_DMV2Bt1yN5t6CaicDwybO4SdgmUtcrTYlSt2RpgwCEmQKYW-P3VYDzkU85aDm0x7WURipCeH62TskHrsERELemWWHAg5NaQ2CdrRmllocOnvoXwcKgdoXqzrPpHoZ01fihm3kVMHMDTmIlOLRgUxl0nB2M2JuVm38F0zajBSDrmEZhYpiiytJYs2ADDxVrEHxcfO_WOAj8due2L-sLvMw3fn-NudbbFeK1Y5mYZMlWItASFOQ_vCJtOeh0BTtkM4U-V8UYfmGMnRlBTXmXOUlC4FWcj87r5iAG4WbyzMltGQDSmzDMz66QzWA5fQG_rAA=","summary":[{"type":"summary_text","text":"**Confirming SWAP.BLK line adjustments**"}]},{"id":"fc_0755b4eee615cb72016a5897890eb08199a00d70036fc18e14","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking extension state usage\",\"pattern\":\"listenerGeneration|activationType|updateNoticesPending|cachedReadyIds\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_MKPEY4YdmRtv2kfQ0jzFtUtz","name":"grep"}]},"duration":5564.854999999981,"ttft":2262.906100000255,"contextSnapshot":{"promptTokens":185158,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_MKPEY4YdmRtv2kfQ0jzFtUtz|fc_0755b4eee615cb72016a5897890eb08199a00d70036fc18e14","toolName":"grep","startedAt":"2026-07-16T08:34:18.032Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Checking extension state usage"},"id":"ed30377b","parentId":"737aa0a6","timestamp":"2026-07-16T08:34:18.032Z"}
{"type":"message","id":"05bdc955","parentId":"ed30377b","timestamp":"2026-07-16T08:34:18.054Z","message":{"role":"toolResult","toolCallId":"call_MKPEY4YdmRtv2kfQ0jzFtUtz|fc_0755b4eee615cb72016a5897890eb08199a00d70036fc18e14","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#F56A]\n 652:\t\tconst initialId = id;\n*653:\t\tlet activationType;\n 654:\t\tlet activationPromise;\n 655:\t\tlet activated = false;\n 656:\t\tlet startupBriefPending = false;\n 657:\t\tlet updateNoticesPromise = Promise.resolve([]);\n*658:\t\tlet updateNoticesPending = true;\n*659:\t\tlet cachedReadyIds = [];\n 660:\t\tlet cachedLiveIds = [];\n 661:\n 662:\t\tlet sid;\n...\n 670:\t\tlet bindPromise;\n*671:\t\tlet listenerGeneration = 0;\n 672:\t\tlet agentActive = false;\n 673:\t\tlet desiredState = \"idle\";\n 674:\t\tlet dispatching = false;\n...\n 808:\t\tfunction beginUpdateProbe() {\n*809:\t\t\tupdateNoticesPending = true;\n 810:\t\t\tupdateNoticesPromise = checkUpdates\n 811:\t\t\t\t? detectUpdateNotices().catch((error) => {\n 812:\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\n...\n 858:\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n*859:\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\n 860:\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\n 861:\t\t\treturn candidates;\n 862:\t\t}\n...\n 986:\t\t\tid = nextId;\n*987:\t\t\tactivationType = type;\n 988:\t\t\tlet bound = false;\n 989:\t\t\tconst operation = (async () => {\n 990:\t\t\t\tconst bindArgs = [\n...\n 1036:\t\t\t\t\tid = undefined;\n*1037:\t\t\t\t\tactivationType = undefined;\n 1038:\t\t\t\t\tbindPromise = undefined;\n 1039:\t\t\t\t\ttoken = undefined;\n 1040:\t\t\t\t\treturn false;\n...\n 1073:\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\n*1074:\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\n 1075:\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n 1076:\t\t});\n 1077:\n...\n 1098:\t\t\t\t}\n*1099:\t\t\t\tif (activationType === \"ready_agent\") {\n 1100:\t\t\t\t\treturn {\n 1101:\t\t\t\t\t\tcontent: [\n 1102:\t\t\t\t\t\t\t{\n...\n 1710:\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\n*1711:\t\t\tif (updateNoticesPending) {\n*1712:\t\t\t\tupdateNoticesPending = false;\n 1713:\t\t\t\tconst notices = await updateNoticesPromise;\n 1714:\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\n 1715:\t\t\t}"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":12,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":12}],"truncated":false,"displayContent":"  652│\t\tconst initialId = id;\n *653│\t\tlet activationType;\n  654│\t\tlet activationPromise;\n  655│\t\tlet activated = false;\n  656│\t\tlet startupBriefPending = false;\n  657│\t\tlet updateNoticesPromise = Promise.resolve([]);\n *658│\t\tlet updateNoticesPending = true;\n *659│\t\tlet cachedReadyIds = [];\n  660│\t\tlet cachedLiveIds = [];\n  661│\n  662│\t\tlet sid;\n     │...\n  670│\t\tlet bindPromise;\n *671│\t\tlet listenerGeneration = 0;\n  672│\t\tlet agentActive = false;\n  673│\t\tlet desiredState = \"idle\";\n  674│\t\tlet dispatching = false;\n     │...\n  808│\t\tfunction beginUpdateProbe() {\n *809│\t\t\tupdateNoticesPending = true;\n  810│\t\t\tupdateNoticesPromise = checkUpdates\n  811│\t\t\t\t? detectUpdateNotices().catch((error) => {\n  812│\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\n     │...\n  858│\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n *859│\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\n  860│\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\n  861│\t\t\treturn candidates;\n  862│\t\t}\n     │...\n  986│\t\t\tid = nextId;\n *987│\t\t\tactivationType = type;\n  988│\t\t\tlet bound = false;\n  989│\t\t\tconst operation = (async () => {\n  990│\t\t\t\tconst bindArgs = [\n     │...\n 1036│\t\t\t\t\tid = undefined;\n*1037│\t\t\t\t\tactivationType = undefined;\n 1038│\t\t\t\t\tbindPromise = undefined;\n 1039│\t\t\t\t\ttoken = undefined;\n 1040│\t\t\t\t\treturn false;\n     │...\n 1073│\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\n*1074│\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\n 1075│\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n 1076│\t\t});\n 1077│\n     │...\n 1098│\t\t\t\t}\n*1099│\t\t\t\tif (activationType === \"ready_agent\") {\n 1100│\t\t\t\t\treturn {\n 1101│\t\t\t\t\t\tcontent: [\n 1102│\t\t\t\t\t\t\t{\n     │...\n 1710│\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\n*1711│\t\t\tif (updateNoticesPending) {\n*1712│\t\t\t\tupdateNoticesPending = false;\n 1713│\t\t\t\tconst notices = await updateNoticesPromise;\n 1714│\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\n 1715│\t\t\t}"},"isError":false,"timestamp":1784190858054}}
{"type":"message","id":"b02a17a4","parentId":"05bdc955","timestamp":"2026-07-16T08:34:21.661Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Removing listenerGeneration and updating tag line**"},{"type":"toolCall","id":"call_KM5RYdvQRKdG10KnBhDn9qTt|ctc_07aaa605cc6f2ef2016a58978d2d40819a8ecb749519bcaf94","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#F56A]\nDEL 671.=671\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1145,"output":57,"cacheRead":184832,"cacheWrite":0,"totalTokens":186034,"reasoningTokens":16,"cost":{"input":0.005725,"output":0.0017100000000000001,"cacheRead":0.092416,"cacheWrite":0,"total":0.099851}},"stopReason":"toolUse","timestamp":1784190858067,"responseId":"resp_07aaa605cc6f2ef2016a58978a6ee0819a9106414c9d7cd390","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_07aaa605cc6f2ef2016a58978c6190819a947d6a1d14b40e50","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJeNAtp38Pseu6U2o9kb1U-b1Q42VznhiV1_uMEhLPjB7l3sthE2fqdraaPi5EXOH8u_wxKJmpUJzqDUClYnRnrfyyyQ1tADsUEZ-WpIIGkwVuEBlzEVUwMBtSq8Gj1ZDY9lxYSUv4Br9UTEqwf_K1OnFkPyjyIeANYa0OhAjw4WTIlmrlm4k8ep4GHGHRydlDH6uOjkQFpDpaWnIKI8x-iG4V6c3mLDQSoHowZ3kXKLSPHkdabqnOFzRI1lLQ2ZeQiwUuvx-QxpuCY7OSX1Y8k4rg67-lKdaq7zpmMnipy6AYoa79o1HR9a5V4MdbAODpNnoixgvlFcra5abEpaGfA3Ae9uZhbtPX151m_NgEL2zaCSDn-9SJoE_IVQ59Epo8CB_Td74Pjh0hvWu4yWBaBLeXSA2Axuh6Sx9ygUzsTS4dQxnw1sLNt8WWlcANZKI1L7-Eg-wRPhux1IhUriWU7hU573ToRl9rGu-HbLbOK91TIKNTJUoaa0SKUyPQ5OG0U1lXzcJWeCwop0F8F2G8rTDmEL6-Ic06_PoU05GFb8tIjqVUnIEYp4vzWCLFO6yJUx_11YFpGi-enTsGbuKVHX__cZh4oKB9nV4zuDtL_Ots7vmefGNbiDf3tDLvz3NdPUa67BPJ2yT34Q7BMxO5YFi3kzWDA-QRa7KWvHlqOkKhjarBDMEu4YRqI8YWxJAL0EviMkVjhPCnUgmV9CpSrRZPSsNkNJG1xFK5sTHRTXXobtwsJWIzTzGsBweOby8dtvUMNdl0Kfd-riE2rTbANxVWCKtbyTBaDCvriB5-wBDMlOL864Lfv4_S99tvONqhmashmFUXtcFCGVtitaA270iPeihYu8sid9L-QhBVt3gy15vl71-auHh7hljKW0tUAR86gaH6peygiYmuFn1n1Xgi9lOEXu0ph6zeEbDAK-8LVUEZ42YPROXfqVNQi1oC2q85J0M54zKgYDj9w8h3UcusvZEHlA_FAk06spFUIe8_AY9yMZhnOwmXcr5WRhsUKC","summary":[{"type":"summary_text","text":"**Removing listenerGeneration and updating tag line**"}]},{"id":"ctc_07aaa605cc6f2ef2016a58978d2d40819a8ecb749519bcaf94","type":"custom_tool_call","status":"completed","call_id":"call_KM5RYdvQRKdG10KnBhDn9qTt","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#F56A]\nDEL 671.=671\n*** End Patch\n","name":"edit"}]},"duration":3593.348000000231,"ttft":2304.099200000055,"contextSnapshot":{"promptTokens":185977,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_KM5RYdvQRKdG10KnBhDn9qTt|ctc_07aaa605cc6f2ef2016a58978d2d40819a8ecb749519bcaf94","toolName":"edit","startedAt":"2026-07-16T08:34:21.662Z"},"id":"c55f2d97","parentId":"b02a17a4","timestamp":"2026-07-16T08:34:21.662Z"}
{"type":"message","id":"923f60f8","parentId":"c55f2d97","timestamp":"2026-07-16T08:34:21.693Z","message":{"role":"toolResult","toolCallId":"call_KM5RYdvQRKdG10KnBhDn9qTt|ctc_07aaa605cc6f2ef2016a58978d2d40819a8ecb749519bcaf94","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#C069]\n669:\t\tlet dispatchTimer;\n670:\t\tlet bindPromise;\n671:\t\tlet agentActive = false;\n672:\t\tlet desiredState = \"idle\";"}],"details":{"diff":" 669|\t\tlet dispatchTimer;\n 670|\t\tlet bindPromise;\n-671|\t\tlet listenerGeneration = 0;\n 672|\t\tlet agentActive = false;\n 673|\t\tlet desiredState = \"idle\";","firstChangedLine":671,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190861692}}
{"type":"message","id":"3f718dd5","parentId":"923f60f8","timestamp":"2026-07-16T08:34:26.201Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Checking syntax with Node.js**"},{"type":"toolCall","id":"call_3MH3CmCeeK9S9Ya4LEi4Cx19|fc_0e2ad9ea5299a8f7016a589791cb8c81998777946c669ea5b4","name":"bash","arguments":{"i":"Checking extension syntax","command":"node --check adapter/strings/omp-spt.mjs","cwd":".","timeout":30}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":235,"output":69,"cacheRead":185856,"cacheWrite":0,"totalTokens":186160,"reasoningTokens":24,"cost":{"input":0.001175,"output":0.0020700000000000002,"cacheRead":0.092928,"cacheWrite":0,"total":0.096173}},"stopReason":"toolUse","timestamp":1784190861722,"responseId":"resp_0e2ad9ea5299a8f7016a58978e5aec8199a0f2494dc0851b4a","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0e2ad9ea5299a8f7016a589790c0808199bce38b545589a110","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJeR73gcRgjhTtV3pnGkT1-kvxwLNuUNGlsRuipO9Qu0Mp6n1t79Lv6i1Nlh6Fc429aZ6A-H95UlDIVQHdXrN3P3UMYOycSfzz99QAnT5Wq6lF2mhu100RWsKksIdu593enQFm_oClWBG-H5MHUTu1o3ArqT8bkHg6byQGYtxlj3u0Def76Ugi-EhHeQJt41gRUInHCOWzr8nRNH6hvk6Wpg_g24o9YWffHi0zfrsYzU1Sl87ssxjHipLGFIiTVgkwOKZ0d5HPyfWBBYa1Heu6EdEH9Vuu6mwg2FmGA3YTpSyHBwgkhCLvuvCYSeMbREeDIr7mHA18gbn3WLjSvakUZqoGIEddTAxI4oBuAdS1afShFyYQxP0K1hVSe1OpTnw6gcIhlpKCN0rfGul8ssPQR-kaWARRfZNKumA-lhsob88zealMD81RFVMLrKq_kLWCHMYXPebBoGYssQP2rH6dV88U3yu8Ynp7FiWDmhUjxDEzM3W6q3fBYLtYzSfUxYVBreF6HBTSemdoTLokz-vmSGg4QA6jAxo8WtfFbwC4DLKtO3KZyVjhi1m-PRrwLP5XugUOg2y__WDTEMIJ2WsH6fEiP16eyYOorhFn4CgzmSTTR6kPEJCjNdI5FsRU8m1S10TwJ5OYgqaSIaIGsTzzFLL8oq_ZYpQqctIZvlobcCo-OAv12W9ZUuicN4mUxaOrnL6-9G7Y3NsdPfLez3WqSxf8fqhL_mHO1SMSODxAslFWFnI4Z1Tg6Ori-kCr3fR9bGyXdUljd780iq_UJ4rKe5YYHizW0fEKt1Diw3Mza_1pVdtM5HsUxzWhxk52EOF16n2WelZWmoiTiSfGHSmadQVPZC2nI291-L3fVjZuHVWNocNJJikQHuyD8sK9Dm5fL1chpH_sHITzpvlSLFf93MREW_90H56Cypezv_JMzJZUKnVc9aK8bn8HxzFgL_WIBeNdcOZ1dKrPSkR4z0Bkh5hluDrpdNi1eU41z3uVsfIWGfDzrCn8vNEEmqy1--4oHrvn1VqfSYDMccNtTvkSzuWw==","summary":[{"type":"summary_text","text":"**Checking syntax with Node.js**"}]},{"id":"fc_0e2ad9ea5299a8f7016a589791cb8c81998777946c669ea5b4","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking extension syntax\",\"command\":\"node --check adapter/strings/omp-spt.mjs\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_3MH3CmCeeK9S9Ya4LEi4Cx19","name":"bash"}]},"duration":4477.977799999993,"ttft":3028.9506000000983,"contextSnapshot":{"promptTokens":186091,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_3MH3CmCeeK9S9Ya4LEi4Cx19|fc_0e2ad9ea5299a8f7016a589791cb8c81998777946c669ea5b4","toolName":"bash","startedAt":"2026-07-16T08:34:26.202Z","args":{"command":"node --check adapter/strings/omp-spt.mjs"},"intent":"Checking extension syntax"},"id":"ad4d6817","parentId":"3f718dd5","timestamp":"2026-07-16T08:34:26.202Z"}
{"type":"message","id":"186ab12c","parentId":"ad4d6817","timestamp":"2026-07-16T08:34:26.391Z","message":{"role":"toolResult","toolCallId":"call_3MH3CmCeeK9S9Ya4LEi4Cx19|fc_0e2ad9ea5299a8f7016a589791cb8c81998777946c669ea5b4","toolName":"bash","content":[{"type":"text","text":"(no output)\n\nWall time: 0.19 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":188.74200000008568},"isError":false,"timestamp":1784190866391}}
{"type":"message","id":"2eed8c9c","parentId":"186ab12c","timestamp":"2026-07-16T08:34:39.147Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Extending tests harness options and imports**\n\n**Verifying activation and shutdown lifecycle handling**"},{"type":"toolCall","id":"call_ZPxjlfGuPkJOiI7EUfvkMHCQ|fc_01edb8e1d4655458016a58979ec5788198ba3c036c88ecfe67","name":"read","arguments":{"i":"Regrounding extension test harness","path":"tests/omp-extension.mjs","selector":"1-215"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":326,"output":493,"cacheRead":185856,"cacheWrite":0,"totalTokens":186675,"reasoningTokens":454,"cost":{"input":0.0016300000000000002,"output":0.014790000000000001,"cacheRead":0.092928,"cacheWrite":0,"total":0.109348}},"stopReason":"toolUse","timestamp":1784190866447,"responseId":"resp_01edb8e1d4655458016a58979307548198a558a88c587bae98","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_01edb8e1d4655458016a589794fc0c819897a8608e555a9a44","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJee-jpCKrQ0Ao3jyVg2n59Ro-EsTSN9bTiBrFjiDZCc967qP6sMlsOpVb7eACu79e8SmtljvfkiPu2MF26zLkY63He9m2IbFgrK3jGiWbxi5edPdbmMwsFV9cJN1JsdnXPRdPVwXkeqQJZM1iX5GCKvsqO8prx1FwKX9_OJz869WFzkZzJzCMdkyiNoepcQKUyg0viE8roCO_nJsWrEJUhHsYWdV1aTlIaQjOoOn1VEDv29-ecdSq0X7TW2ZQQMk4wmiukN9PCf5QFY8391Owr8MltSFrd77TswIeeBWNA1-4p61JQVVoFH5o5H4rSrsquovigf-xyY8D0455O5VAvc8T_mTZ-gCuoJYWtcnYex_MopSQwB0Bh6wyg1QhBbVE-4l_K5_lfaAIZgGK0ShlOCm1spJiRtOhG2h6wJwgJpkVCOl200xwUBRfYxlNcDfGsS3-OiXgjGMWMqoB3y7_fe0ZZ75fukDdG-ZZ-a38B-N0a3HjJKpw4i4nsbBoBJOSCOaDs3jgEd9W-0UIvEwPW12xA5s710bgFOY6E8l6a94u4hqVf0WyewEBInSnw4pvu2vCwUO8nHqBEmn2RDXJZp440r4Qur1RbFcDijnmSpZlOg1F3jgSAGzXK3v6RutsHRhbn2b9dz2gkuJ0B-8pwihOQCF25PzkI8J12aw_cUSzzgQMTOfZNEKQaQKgHF9-O9CvUrp6xEN0f5tKSmgeHDaZiiWmex6aHx4JoITKyFXCg6c4MRycAKjsc6oP8z9aZ7B2TtIbUKQ8fpYVrcBp_4esKkVqTqpdX54Fq3aCVnwfqN9ocnhhhjxwtaKs3jIHXQW4QVzo23EmB-xyPDlqjgqbSIsBkH-zGpUQJxeo_UHvaQ4DCBo0-FCK5hC71uPONqRmqwex363cKmJ4jAVXBQPJzve4joI7lf_mB8LLQOwXb-OytPIttBcYEaGCojFcoIDIeJjUNpLHlbFlcnIVuo8Rvs1pwaomP2R-6mdicP71nUINF9SHml7Gb6VGH80ndD0b5ekZm9Zh1xdzVOrRQ1sFNilz1JUpU65UGapm5NPYwpvLhWfxW0AkDx9nHiog0nJpV-G8WZTLIY8p_fs9aLzYS7HMRhKOTevO5QCjdHR1AQbxWsJhQ_MAMYx3CUeSzbkzzsLo65G7GYbHzlKfnLoes10Ee7Z-Aqlxo0BYVWjJAMdaoOArbccsYYZepp5t1MUzIOL5y8zBLxbnGVDT6OUGviRhog97OS94hsUNbkReEoFNWrHbQkgpMJmnTYpu2jf8iHknT1WBbW4hyZRilRQMln7jKZ9uQR-HYcJcU2gmdIgeVFWlfsZVh8KSYSSb115_nQx6jsHpkXwrGe0F1o72brxyFEyOy5MF-iLZ7JuCQ-NkebDPBNumyg5REEQ0Vx8GZapLnejdtYIMev1aOa_U0kXo_J-JZeI2Zpkg55asmarVouXq-ViT-5VX3Jo9pg2Jkku0w0Axx6GlNKOaKMsaHnuz3qy94mZbslJYnPMdW3Cu8oRvY7QTjG0XqyJxbQG4LzC1FKCRP6VgzFyeRAsIrKiJM2l_szPiCdr2Mc3k5yaVCdfYw3Hht_FG3TE41ejj1S080isdxTZDMZ08sPutt3kmRgWrr9hzG7OvbP5zGCFEbGJf1BOMUUeGpl6sqZJU3NBgbl-TMiRm3_7yC9PvH6LNA0x2BUQb6cSbsmhf-eCE98hk8Ate9sD6cwK-c-31Xw-xIP0s00mVKCZ2iLv4QKiIiavb74q2zeY1FM7AVQHHPaVIi1wrXrgiirndOgjUB9QNldDovO9AKRrxWLjHUR63y5OkZbge08Il7UrtsoAcfzO72NaBUSNdsLdbi0OfldOOrRIQ-NynfKdUcmGTqOvDm9ZWEphUdAXEvKK2PHw-ptBLUIefhDZOQF5Yg_J5Y3pURyLE0_n2tDgQEltbl1a2NxFPfoMA6RlLQiFibkKz_h30B9fJEWaYOLn6eXo2fiDrmzUEJLMc151hGtJ3fyVI_64HsigmkdBZqLI9o_9_5HqdEDF9uI5KOjEm4yOBdrsxLNp93NEEly47pvXXt6ds3GzCkCFmJUdqrILnc5m9jStlwFcEE_xBIcbw0NYXm62_hY4z2-r6a9cQjG8iWxQbHHSGdz-1rKRqOXJxLHkdJzXBftVn1Ef01NeJQH_ZeiK1j01k1tWGHxxsWFfvHNIBtUxvSpjB2s1aK0m51JPN0N22vSoz1TYrhp5sm1-xGQyZFVXZ0ULbx4uNbuht1vaVgGA7eN-qatenrDXpzXR4kMC8Jc6k9uE7bkv8VCtfmWcOoVdpnZzlI5nfxMl10x482qC-SQW3uFOODGojBAloPZoHy70a36IYKQa5Fz9v6VPw3J8wAqpRpJFx9pIGWqDghmKb1DKzD6WUyZkYMSgjTel2-HO3KjZTPiPkoUqKXoPcRmkBrzaeynhhBqTIJJUbYGjK4JFZYK0jACD7AHhRkf2MnhOwF_GXekVcjb9aC-PYhKCoDBtr_3YaW7s9Y7zP8reMuMZRB6LflCARWm2Gb0N8o0ZjQfGVYfxX8aeXwmKPUTfgGb0Pk1MH_u4pdq0_zqBwnbm80mkJzw7y0Atb2uij8-6qZaIOAMmIHe2FUzNlpBpBWk2t8g7haRWD77Ucmm8Dver0av5PuuAX1TFkSG3r-PbDX0C0IK2njBs9Rdug-Vh2dkeVga5NLFb5pTbHaKLLVxhMFOHZWVLVCUYa3BQkphUlRH4jL8Zl6nQJ1qATqV8ExBjbg5d5Ra7fMnkgfoYcGAXYOKYjdsRUvOf9kR7rlyzgzsW5ehJWOyq3rhceDlNzY5KR84kOMmwAKILoTiWnER48quvxH9_irfmMkykBkWdGy3KxANeSCg2Fyjo6oWNIS6g8gfyaiUVWVpNvhtu_aUsktxdHLn6hwlrFujllW8pNcxuJGVUcYfRULtbkaxkw0uTVO8We1GQUkjUVemdEJl4kG5S4tTkBNtDHFsCYUG9iK152wyCimcPmNBLQtKNH4ZXKhoWcU_MHJETitGfQLU69hgFkYV4AR6Qt5Ips-ZIruV-gn3gBuxRo2Pt84q2QWLliKX0tnkut5WcPS-KaNWcCgVicXAraMio_4Ra07bCsijXTNJ3oxXabafBmS6Mbd3gVl0e1CsXf72Eq_-TjA1_rR11gmeUt6WVxpmrsYZaM2Eaclm7Fbaru1JHtYptZUhP8mu7DlsYwOcM5T8qUJE7NyKbwYkmPVsmREKCnlnMt6Z80i6mPdkNYWnjZOaOX06w9lVZOtkg0IRDYZ46Y4ik4Noo1UaHl0ausrgtOPeifcn_bmmndA1Lf9pcShED5Jh98mhd82fxTHInwwDlpWhRpFytCTUGfdgcUu4VUzDmFN9an7BEBeW4dZzZ8HfrGN_40JyfwW8C2YCKh3cDOwfwfoadXhDiDh6bfY4qaxOan0zoWAEUuappw7Ixfxenw68pl9q2U5pW54C6tfgaeusBZPtJCiuyvtayi2HOwi2x7asU8o-JYlNpZPltJ45L468UOaMojQWKss82jNYU-JzPUDCJxd56s01tI5RNH6YrR8Bj62vHDQKtRHbtTAxS4ynme6GKVUS7qGC3Qn7NyEzyfyYFQD9_P-H0RnHGofLUZNPcpHEMgDEldfmyjID6zF-CQLqi4HfULeyE4OLFbRpV0U0q7jQk-UFS6jxWWaecIALQtVD6y8aqiFxYntO-eSNL9xhGx9QN13_tS-EKp2fO-yR5G1Y39GpKtjR2kntmeQ49-lT8r7SOLgpvzcp0YuU25kzE3mMkEAQRMVw8yrMJoEg1ffdbxqQy0RO_M6K9bhBHdfPzxrsnTtozjpoyFA5QF33pgejjHP6edBz6kkbDNFGEZZHpf9CUl5e10twvZRpeqRqT9KtJfxsQS2ajn3R7QWKbD7--qvZM1EayNlqBefehRK3z_V0IpKJozJeot9KvqBS8YjF","summary":[{"type":"summary_text","text":"**Extending tests harness options and imports**"},{"type":"summary_text","text":"**Verifying activation and shutdown lifecycle handling**"}]},{"id":"fc_01edb8e1d4655458016a58979ec5788198ba3c036c88ecfe67","type":"function_call","status":"completed","arguments":"{\"i\":\"Regrounding extension test harness\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1-215\"}","call_id":"call_ZPxjlfGuPkJOiI7EUfvkMHCQ","name":"read"}]},"duration":12667.510699999984,"ttft":2522.0082999998704,"contextSnapshot":{"promptTokens":186182,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ZPxjlfGuPkJOiI7EUfvkMHCQ|fc_01edb8e1d4655458016a58979ec5788198ba3c036c88ecfe67","toolName":"read","startedAt":"2026-07-16T08:34:39.147Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Regrounding extension test harness"},"id":"dc1c704b","parentId":"2eed8c9c","timestamp":"2026-07-16T08:34:39.147Z"}
{"type":"message","id":"902b0b94","parentId":"dc1c704b","timestamp":"2026-07-16T08:34:39.160Z","message":{"role":"toolResult","toolCallId":"call_ZPxjlfGuPkJOiI7EUfvkMHCQ|fc_01edb8e1d4655458016a58979ec5788198ba3c036c88ecfe67","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#8FB4]\n1:import assert from \"node:assert/strict\";\n2:import { EventEmitter } from \"node:events\";\n3:import {\n4:\tcreateOmpSpt,\n5:\tdecodeBody,\n6:\tdrainEvents,\n7:\textractReply,\n8:\trunSpt,\n9:} from \"../adapter/strings/omp-spt.mjs\";\n10:\n11:const flush = () => new Promise((resolve) => setImmediate(resolve));\n12:function deferred() {\n13:\tlet resolve;\n14:\tlet reject;\n15:\tconst promise = new Promise((resolvePromise, rejectPromise) => {\n16:\t\tresolve = resolvePromise;\n17:\t\treject = rejectPromise;\n18:\t});\n19:\treturn { promise, reject, resolve };\n20:}\n21:\n22:class FakeStream extends EventEmitter {\n23:\tsetEncoding(encoding) {\n24:\t\tthis.encoding = encoding;\n25:\t}\n26:\n27:\tend(input) {\n28:\t\tthis.input = input;\n29:\t\tif (this.onEnd?.(input) === false) return;\n30:\t\tthis.emit(\"finish\");\n31:\t}\n32:}\n33:\n34:class FakeChild extends EventEmitter {\n35:\tconstructor(options = {}) {\n36:\t\tsuper();\n37:\t\tthis.stdin = new FakeStream();\n38:\t\tthis.stdout = new FakeStream();\n39:\t\tthis.stderr = new FakeStream();\n40:\t\tthis.exitCode = null;\n41:\t\tthis.signalCode = null;\n42:\t\tthis.kills = 0;\n43:\t\tthis.killSignals = [];\n44:\t\tthis.onKill = options.onKill;\n45:\t}\n46:\n47:\tclose(code = 0, signal = null) {\n48:\t\tthis.exitCode = code;\n49:\t\tthis.signalCode = signal;\n50:\t\tthis.emit(\"close\", code, signal);\n51:\t}\n52:\n53:\tkill(signal = \"SIGTERM\") {\n54:\t\tthis.kills += 1;\n55:\t\tthis.killSignals.push(signal);\n56:\t\tconst handled = this.onKill?.(signal, this);\n57:\t\tif (handled !== undefined) return handled;\n58:\t\tthis.close(null, signal);\n59:\t\treturn true;\n60:\t}\n61:}\n62:\n63:class FakeClock {\n64:\tconstructor() {\n65:\t\tthis.nextId = 1;\n66:\t\tthis.timers = new Map();\n67:\t}\n68:\n69:\tsetTimeout(fn, delay) {\n70:\t\tconst handle = { id: this.nextId++, unref() {} };\n71:\t\tthis.timers.set(handle, { fn, delay });\n72:\t\treturn handle;\n73:\t}\n74:\n75:\tclearTimeout(handle) {\n76:\t\tthis.timers.delete(handle);\n77:\t}\n78:\n79:\tdelays() {\n80:\t\treturn [...this.timers.values()].map(({ delay }) => delay);\n81:\t}\n82:\n83:\tasync runNext(expectedDelay) {\n84:\t\tconst entry = [...this.timers.entries()].sort((left, right) => left[1].delay - right[1].delay)[0];\n85:\t\tassert.ok(entry, `expected a ${expectedDelay}ms timer`);\n86:\t\tconst [handle, timer] = entry;\n87:\t\tassert.equal(timer.delay, expectedDelay);\n88:\t\tthis.timers.delete(handle);\n89:\t\ttimer.fn();\n90:\t\tawait flush();\n91:\t}\n92:}\n93:\n94:function createHarness(options = {}) {\n95:\tconst handlers = new Map();\n96:\tconst calls = [];\n97:\tconst children = [];\n98:\tconst submitted = [];\n99:\tconst statuses = [];\n100:\tconst notifications = [];\n101:\tconst errors = [];\n102:\tconst debug = [];\n103:\tconst clock = new FakeClock();\n104:\tlet shutdowns = 0;\n105:\n106:\tconst ui = {\n107:\t\tnotify(message, type) {\n108:\t\t\tnotifications.push({ message, type });\n109:\t\t},\n110:\t\tsetStatus(key, text) {\n111:\t\t\tstatuses.push({ key, text });\n112:\t\t},\n113:\t};\n114:\tconst ctx = {\n115:\t\tui,\n116:\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\n117:\t\tshutdown() {\n118:\t\t\tshutdowns += 1;\n119:\t\t},\n120:\t};\n121:\tconst pi = {\n122:\t\tlogger: {\n123:\t\t\terror(message, details) {\n124:\t\t\t\terrors.push({ message, details });\n125:\t\t\t},\n126:\t\t\tdebug(message, details) {\n127:\t\t\t\tdebug.push({ message, details });\n128:\t\t\t},\n129:\t\t},\n130:\t\ton(name, handler) {\n131:\t\t\tconst registered = handlers.get(name) ?? [];\n132:\t\t\tregistered.push(handler);\n133:\t\t\thandlers.set(name, registered);\n134:\t\t},\n135:\t\tsendUserMessage(content) {\n136:\t\t\tsubmitted.push(content);\n137:\t\t\toptions.onSubmit?.(content);\n138:\t\t},\n139:\t};\n140:\tconst runSptCommand = async (args, input) => {\n141:\t\tconst call = { args: [...args], input };\n142:\t\tcalls.push(call);\n143:\t\tconst overridden = await options.onRun?.(call);\n144:\t\tif (overridden !== undefined) return overridden;\n145:\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\n146:\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\n147:\t\t}\n148:\t\treturn \"\";\n149:\t};\n150:\tconst spawnProcess = (binary, args, spawnOptions) => {\n151:\t\tconst child = new FakeChild();\n152:\t\tchild.binary = binary;\n153:\t\tchild.args = [...args];\n154:\t\tchild.spawnOptions = spawnOptions;\n155:\t\toptions.onSpawn?.(child);\n156:\t\tchildren.push(child);\n157:\t\treturn child;\n158:\t};\n159:\tconst extension = createOmpSpt({\n160:\t\tenv: {\n161:\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\n162:\t\t\tOMP_SPT_SUBNET: options.subnet,\n163:\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\n164:\t\t},\n165:\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n166:\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n167:\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\n168:\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\n169:\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\n170:\t\tshutdownBudgetMs: options.shutdownBudgetMs,\n171:\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\n172:\t\tlistenerStableMs: options.listenerStableMs ?? false,\n173:\t\tkillForceMs: options.killForceMs ?? 4,\n174:\t\tkillGraceMs: options.killGraceMs ?? 3,\n175:\t\tlistenerBufferLimit: options.listenerBufferLimit,\n176:\t\trunSptCommand,\n177:\t\tspawnProcess,\n178:\t\tsetTimeout: clock.setTimeout.bind(clock),\n179:\t\tclearTimeout: clock.clearTimeout.bind(clock),\n180:\t});\n181:\textension(pi);\n182:\n183:\tasync function emit(name, event = {}) {\n184:\t\tlet result;\n185:\t\tfor (const handler of handlers.get(name) ?? []) {\n186:\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\n187:\t\t\tif (returned !== undefined) result = returned;\n188:\t\t}\n189:\t\treturn result;\n190:\t}\n191:\n192:\treturn {\n193:\t\tcalls,\n194:\t\tchildren,\n195:\t\tclock,\n196:\t\tctx,\n197:\t\tdebug,\n198:\t\temit,\n199:\t\terrors,\n200:\t\thandlers,\n201:\t\tnotifications,\n202:\t\tstatuses,\n203:\t\tsubmitted,\n204:\t\tget shutdowns() {\n205:\t\t\treturn shutdowns;\n206:\t\t},\n207:\t};\n208:}\n209:\n210:function commandCalls(harness, command) {\n211:\treturn harness.calls.filter((call) => call.args[0] === command);\n212:}\n213:\n214:function stateCalls(harness) {\n215:\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n216:}\n217:\n218:async function testParsingAndReplies() {\n…\n278:}\n\n[Showing lines 1-218 of 1378. Use :219 to continue]"}],"details":{"truncation":{"content":"import assert from \"node:assert/strict\";\r\nimport { EventEmitter } from \"node:events\";\r\nimport {\r\n\tcreateOmpSpt,\r\n\tdecodeBody,\r\n\tdrainEvents,\r\n\textractReply,\r\n\trunSpt,\r\n} from \"../adapter/strings/omp-spt.mjs\";\r\n\r\nconst flush = () => new Promise((resolve) => setImmediate(resolve));\r\nfunction deferred() {\r\n\tlet resolve;\r\n\tlet reject;\r\n\tconst promise = new Promise((resolvePromise, rejectPromise) => {\r\n\t\tresolve = resolvePromise;\r\n\t\treject = rejectPromise;\r\n\t});\r\n\treturn { promise, reject, resolve };\r\n}\r\n\r\nclass FakeStream extends EventEmitter {\r\n\tsetEncoding(encoding) {\r\n\t\tthis.encoding = encoding;\r\n\t}\r\n\r\n\tend(input) {\r\n\t\tthis.input = input;\r\n\t\tif (this.onEnd?.(input) === false) return;\r\n\t\tthis.emit(\"finish\");\r\n\t}\r\n}\r\n\r\nclass FakeChild extends EventEmitter {\r\n\tconstructor(options = {}) {\r\n\t\tsuper();\r\n\t\tthis.stdin = new FakeStream();\r\n\t\tthis.stdout = new FakeStream();\r\n\t\tthis.stderr = new FakeStream();\r\n\t\tthis.exitCode = null;\r\n\t\tthis.signalCode = null;\r\n\t\tthis.kills = 0;\r\n\t\tthis.killSignals = [];\r\n\t\tthis.onKill = options.onKill;\r\n\t}\r\n\r\n\tclose(code = 0, signal = null) {\r\n\t\tthis.exitCode = code;\r\n\t\tthis.signalCode = signal;\r\n\t\tthis.emit(\"close\", code, signal);\r\n\t}\r\n\r\n\tkill(signal = \"SIGTERM\") {\r\n\t\tthis.kills += 1;\r\n\t\tthis.killSignals.push(signal);\r\n\t\tconst handled = this.onKill?.(signal, this);\r\n\t\tif (handled !== undefined) return handled;\r\n\t\tthis.close(null, signal);\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nclass FakeClock {\r\n\tconstructor() {\r\n\t\tthis.nextId = 1;\r\n\t\tthis.timers = new Map();\r\n\t}\r\n\r\n\tsetTimeout(fn, delay) {\r\n\t\tconst handle = { id: this.nextId++, unref() {} };\r\n\t\tthis.timers.set(handle, { fn, delay });\r\n\t\treturn handle;\r\n\t}\r\n\r\n\tclearTimeout(handle) {\r\n\t\tthis.timers.delete(handle);\r\n\t}\r\n\r\n\tdelays() {\r\n\t\treturn [...this.timers.values()].map(({ delay }) => delay);\r\n\t}\r\n\r\n\tasync runNext(expectedDelay) {\r\n\t\tconst entry = [...this.timers.entries()].sort((left, right) => left[1].delay - right[1].delay)[0];\r\n\t\tassert.ok(entry, `expected a ${expectedDelay}ms timer`);\r\n\t\tconst [handle, timer] = entry;\r\n\t\tassert.equal(timer.delay, expectedDelay);\r\n\t\tthis.timers.delete(handle);\r\n\t\ttimer.fn();\r\n\t\tawait flush();\r\n\t}\r\n}\r\n\r\nfunction createHarness(options = {}) {\r\n\tconst handlers = new Map();\r\n\tconst calls = [];\r\n\tconst children = [];\r\n\tconst submitted = [];\r\n\tconst statuses = [];\r\n\tconst notifications = [];\r\n\tconst errors = [];\r\n\tconst debug = [];\r\n\tconst clock = new FakeClock();\r\n\tlet shutdowns = 0;\r\n\r\n\tconst ui = {\r\n\t\tnotify(message, type) {\r\n\t\t\tnotifications.push({ message, type });\r\n\t\t},\r\n\t\tsetStatus(key, text) {\r\n\t\t\tstatuses.push({ key, text });\r\n\t\t},\r\n\t};\r\n\tconst ctx = {\r\n\t\tui,\r\n\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\r\n\t\tshutdown() {\r\n\t\t\tshutdowns += 1;\r\n\t\t},\r\n\t};\r\n\tconst pi = {\r\n\t\tlogger: {\r\n\t\t\terror(message, details) {\r\n\t\t\t\terrors.push({ message, details });\r\n\t\t\t},\r\n\t\t\tdebug(message, details) {\r\n\t\t\t\tdebug.push({ message, details });\r\n\t\t\t},\r\n\t\t},\r\n\t\ton(name, handler) {\r\n\t\t\tconst registered = handlers.get(name) ?? [];\r\n\t\t\tregistered.push(handler);\r\n\t\t\thandlers.set(name, registered);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r","truncated":true,"truncatedBy":"lines","totalLines":1378,"totalBytes":5436,"outputLines":218,"outputBytes":5436,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"import assert from \"node:assert/strict\";\r\nimport { EventEmitter } from \"node:events\";\r\nimport {\r\n\tcreateOmpSpt,\r\n\tdecodeBody,\r\n\tdrainEvents,\r\n\textractReply,\r\n\trunSpt,\r\n} from \"../adapter/strings/omp-spt.mjs\";\r\n\r\nconst flush = () => new Promise((resolve) => setImmediate(resolve));\r\nfunction deferred() {\r\n\tlet resolve;\r\n\tlet reject;\r\n\tconst promise = new Promise((resolvePromise, rejectPromise) => {\r\n\t\tresolve = resolvePromise;\r\n\t\treject = rejectPromise;\r\n\t});\r\n\treturn { promise, reject, resolve };\r\n}\r\n\r\nclass FakeStream extends EventEmitter {\r\n\tsetEncoding(encoding) {\r\n\t\tthis.encoding = encoding;\r\n\t}\r\n\r\n\tend(input) {\r\n\t\tthis.input = input;\r\n\t\tif (this.onEnd?.(input) === false) return;\r\n\t\tthis.emit(\"finish\");\r\n\t}\r\n}\r\n\r\nclass FakeChild extends EventEmitter {\r\n\tconstructor(options = {}) {\r\n\t\tsuper();\r\n\t\tthis.stdin = new FakeStream();\r\n\t\tthis.stdout = new FakeStream();\r\n\t\tthis.stderr = new FakeStream();\r\n\t\tthis.exitCode = null;\r\n\t\tthis.signalCode = null;\r\n\t\tthis.kills = 0;\r\n\t\tthis.killSignals = [];\r\n\t\tthis.onKill = options.onKill;\r\n\t}\r\n\r\n\tclose(code = 0, signal = null) {\r\n\t\tthis.exitCode = code;\r\n\t\tthis.signalCode = signal;\r\n\t\tthis.emit(\"close\", code, signal);\r\n\t}\r\n\r\n\tkill(signal = \"SIGTERM\") {\r\n\t\tthis.kills += 1;\r\n\t\tthis.killSignals.push(signal);\r\n\t\tconst handled = this.onKill?.(signal, this);\r\n\t\tif (handled !== undefined) return handled;\r\n\t\tthis.close(null, signal);\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nclass FakeClock {\r\n\tconstructor() {\r\n\t\tthis.nextId = 1;\r\n\t\tthis.timers = new Map();\r\n\t}\r\n\r\n\tsetTimeout(fn, delay) {\r\n\t\tconst handle = { id: this.nextId++, unref() {} };\r\n\t\tthis.timers.set(handle, { fn, delay });\r\n\t\treturn handle;\r\n\t}\r\n\r\n\tclearTimeout(handle) {\r\n\t\tthis.timers.delete(handle);\r\n\t}\r\n\r\n\tdelays() {\r\n\t\treturn [...this.timers.values()].map(({ delay }) => delay);\r\n\t}\r\n\r\n\tasync runNext(expectedDelay) {\r\n\t\tconst entry = [...this.timers.entries()].sort((left, right) => left[1].delay - right[1].delay)[0];\r\n\t\tassert.ok(entry, `expected a ${expectedDelay}ms timer`);\r\n\t\tconst [handle, timer] = entry;\r\n\t\tassert.equal(timer.delay, expectedDelay);\r\n\t\tthis.timers.delete(handle);\r\n\t\ttimer.fn();\r\n\t\tawait flush();\r\n\t}\r\n}\r\n\r\nfunction createHarness(options = {}) {\r\n\tconst handlers = new Map();\r\n\tconst calls = [];\r\n\tconst children = [];\r\n\tconst submitted = [];\r\n\tconst statuses = [];\r\n\tconst notifications = [];\r\n\tconst errors = [];\r\n\tconst debug = [];\r\n\tconst clock = new FakeClock();\r\n\tlet shutdowns = 0;\r\n\r\n\tconst ui = {\r\n\t\tnotify(message, type) {\r\n\t\t\tnotifications.push({ message, type });\r\n\t\t},\r\n\t\tsetStatus(key, text) {\r\n\t\t\tstatuses.push({ key, text });\r\n\t\t},\r\n\t};\r\n\tconst ctx = {\r\n\t\tui,\r\n\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\r\n\t\tshutdown() {\r\n\t\t\tshutdowns += 1;\r\n\t\t},\r\n\t};\r\n\tconst pi = {\r\n\t\tlogger: {\r\n\t\t\terror(message, details) {\r\n\t\t\t\terrors.push({ message, details });\r\n\t\t\t},\r\n\t\t\tdebug(message, details) {\r\n\t\t\t\tdebug.push({ message, details });\r\n\t\t\t},\r\n\t\t},\r\n\t\ton(name, handler) {\r\n\t\t\tconst registered = handlers.get(name) ?? [];\r\n\t\t\tregistered.push(handler);\r\n\t\t\thandlers.set(name, registered);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r\n…\n}","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,null,278]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1378,"totalBytes":5436,"outputLines":218,"outputBytes":5436,"shownRange":{"start":1,"end":218},"nextOffset":219}}},"isError":false,"timestamp":1784190879159}}
{"type":"message","id":"5d05d37d","parentId":"902b0b94","timestamp":"2026-07-16T08:34:56.132Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Refactoring imports and command helpers**"},{"type":"toolCall","id":"call_aneHjvR52TbMEdzBaLZN4CzZ|ctc_0273f6f0e6456bb0016a5897a5bfac8199a2f7b4e17b9af6d8","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#8FB4]\nINS.POST 7:\n+\tparsePeerShortforms,\nINS.POST 102:\n+\tconst commands = new Map();\n+\tconst tools = new Map();\n+\tconst sentMessages = [];\n+\tconst selections = [];\n+\tconst confirmations = [];\n+\tconst inputs = [];\n+\tconst compactions = [];\nINS.PRE 106:\n+\tconst fakeSchema = {\n+\t\tdescribe() {\n+\t\t\treturn this;\n+\t\t},\n+\t\toptional() {\n+\t\t\treturn this;\n+\t\t},\n+\t};\n+\tconst z = {\n+\t\tobject(shape) {\n+\t\t\treturn { ...fakeSchema, shape };\n+\t\t},\n+\t\tstring() {\n+\t\t\treturn { ...fakeSchema };\n+\t\t},\n+\t};\n+\nINS.POST 112:\n+\t\tasync select(title, values) {\n+\t\t\tselections.push({ title, values });\n+\t\t\treturn options.onSelect?.(title, values) ?? options.selectResults?.shift();\n+\t\t},\n+\t\tasync confirm(title, message) {\n+\t\t\tconfirmations.push({ title, message });\n+\t\t\treturn options.onConfirm?.(title, message) ?? options.confirmResults?.shift() ?? false;\n+\t\t},\n+\t\tasync input(title, placeholder) {\n+\t\t\tinputs.push({ title, placeholder });\n+\t\t\treturn options.onInput?.(title, placeholder) ?? options.inputResults?.shift();\n+\t\t},\nINS.POST 115:\n+\t\thasUI: options.hasUI ?? true,\n+\t\tcwd: options.cwd ?? \"C:\\\\work\\\\project\",\n+\t\tasync compact(compactionOptions) {\n+\t\t\tcompactions.push(compactionOptions);\n+\t\t\treturn options.onCompact?.(compactionOptions);\n+\t\t},\nINS.POST 121:\n+\t\tzod: { z },\nINS.POST 134:\n+\t\tregisterCommand(name, command) {\n+\t\t\tcommands.set(name, command);\n+\t\t},\n+\t\tregisterTool(tool) {\n+\t\t\ttools.set(tool.name, tool);\n+\t\t},\n+\t\tsendMessage(message, delivery) {\n+\t\t\tsentMessages.push({ message, delivery });\n+\t\t\toptions.onSendMessage?.(message, delivery);\n+\t\t},\nSWAP 161.=161:\n+\t\t\tSPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",\nINS.POST 164:\n+\t\tcheckUpdates: options.checkUpdates ?? false,\n+\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\nINS.POST 192:\n+\t\tcommands,\n+\t\tconfirmations,\n+\t\tcompactions,\nINS.POST 198:\n+\t\tinputs,\nINS.POST 201:\n+\t\tselections,\n+\t\tsentMessages,\nINS.POST 203:\n+\t\ttools,\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2687,"output":759,"cacheRead":185856,"cacheWrite":0,"totalTokens":189302,"reasoningTokens":165,"cost":{"input":0.013435,"output":0.022770000000000002,"cacheRead":0.092928,"cacheWrite":0,"total":0.129133}},"stopReason":"toolUse","timestamp":1784190879167,"responseId":"resp_0273f6f0e6456bb0016a58979f9b5c8199a8e8caa832d64d72","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0273f6f0e6456bb0016a5897a243d88199b3789e77c813cc35","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJel3TnFo4CVYW4WWEoQeFwL21NleZAO-2jjR670sbKZLo7pKeAmLYgIQGqgH7n1GGxbzUqdrDqqRUCGO4MhBvJ4BzEPusnGTxx3QqnEztiMX-k7It3Zut5ONFzKHiZ_DPs2gxSdjJiqfyBu8ILqQVThuTiQ8KvF6B26Kp4TLaCyJxOXOXL6qXhiH2UdkTkskdkgEpfNgFfpBjukWJ7FaY913dCr98i3pQjG-PYKZeg04Cdezyu460VLsHuNB0Kj7m333nt0SeIVPSsbc6nZJ_ycbhkfSjfNNZBBKeKXtq4xDFc5dadhpGqVqkpZ6o_ttbzjAWj1RaPWEMjFAPrPXDqykJuuAAaOC6ykAFgD5p2Diq8kMZPevchT4eIfbm47Ln44GSoQ2ygIUNzTJVSChcdWxSPYy3HrW3Z4BGKzyErohjJYHFC8F5XOgpGAZwdqePQ2CCmVKjcPpebGaaAzY230xcVzzf93kl4kJAhW0HSVPDZjaXqDx63UjBEvPPeOrblM-nwiJrS7E5rc33mJ5nQBmZOG_MoOjI0qRuf0POr-9ae4rwhEtNckDi49-C6tx2oz_Zx4XknEigRlcUaKxUbYdALgOGzMUXaUfFZeE9vRQhQh7VyIgt3V2JO0I8A1yJakZlqeEXuL_N2Vp7NRrhSyw4nzihuKYW1oY2SwE33f5xno4aqPpj6G9mRHkZqLhGfFEEm4fZ9I6OWJhNP8cugpPkpfYzknZykGNI_y9zRWLSuJ5hgVjnZ2EgVa-XwdrzS2iqQv6ZcHp-VUbHDYTE6Z7B0BW92g7xN34aRSoS7FjMzQceTonmGo3W4Z45IZYvTaHC9elKRZ23VJAdIvdCpjDkGv8tA9rpZ-_VODnaevXhX-5R6WQUUNU9ECTOlr87bHHk4EJ7g8v5qLwJLNntDqW-8WbGPeNXpDxda3Bmv53DscwZb2czd9ANffxAEgcsh6MM4icgRGoouYqsiyNOmUTEke9DSpE9GqNf0KjKPdWOp1cm5W9rkuKuJxlJIaUgremK6HIQEo52DUQkzd9p6-U0Y9fqhfJhAxPMfjCyLAh9V16lopyGyI13FU_LBRFUEFqDLk2e-A3OBRn4eBqgjg7aAfbtLB3pFZJmfJsKgtWL5N3-IxHcd1r3CE8VfoByv3bF0WBZXqK_k90oL8ZHJxxpsLwg0P3aigLOEXe0AlxjfbOfIMy7z0GFexz-aT_VwklXsv5fRRWXBg2rxIMkMiv3qW7NVm1mDGbwVwEDtMTttwLapbBjNkFYnExrOZJ6MBrlGIq5YQCqKIFnuf6XuE-e0ApUAleM3nIfp4cuHJeS9gyQTWDTURWf97_lv-QHXuEUXcK--o-hd5j4yR1iAPqB-zd_-i_nxt6xZ0D5YwvKl_bHulTPTf70r23rkTyVYXtc44KERVUgVRPjJQ3SF-ErORWria31snbEqky2DdPHrDkH5fT_ReK1BZdjL64TAA-4nVcr7Wqw5hybssJKAEl7DA9XCrmdmY_EoorGlhc1LzuYNSpcGYE-mFHTqtM7QSFFRVSjnzJMqImDxPkdO-SXE-DxZA42IUC5LzeGMTYBsgk49su9HuN-eznbWg38ExgzhyYOakKKaYhb-cdxsTQQVKiNzsZc2UxyJJ01O6_ruAiP42fcGjtr-loec7cBOoLiBQFUEQ_ttxdOjXeE0G5WdMdsnkTWFG8hCkrYQEdjk2ma4LJG_QZ9OkLmKSTlJAWop8YjXOn_ydrMEzwOFieBmZzSo4cDDlUTDK82ezv5h_2G0i7fsegWxkerUXG67VZiQNTkMdtqnRA-j03YFfFCJDcrDmG_P9KL5ABYx895sd3jK3RJliqwvavlJMH03MeoGrnhZ3evTvBDBB9_oAjIJftOHlB9OBvlWD4MS2J1dCooUciRZKCUFY1dBbBH0A","summary":[{"type":"summary_text","text":"**Refactoring imports and command helpers**"}]},{"id":"ctc_0273f6f0e6456bb0016a5897a5bfac8199a2f7b4e17b9af6d8","type":"custom_tool_call","status":"completed","call_id":"call_aneHjvR52TbMEdzBaLZN4CzZ","input":"*** Begin Patch\n[tests/omp-extension.mjs#8FB4]\nINS.POST 7:\n+\tparsePeerShortforms,\nINS.POST 102:\n+\tconst commands = new Map();\n+\tconst tools = new Map();\n+\tconst sentMessages = [];\n+\tconst selections = [];\n+\tconst confirmations = [];\n+\tconst inputs = [];\n+\tconst compactions = [];\nINS.PRE 106:\n+\tconst fakeSchema = {\n+\t\tdescribe() {\n+\t\t\treturn this;\n+\t\t},\n+\t\toptional() {\n+\t\t\treturn this;\n+\t\t},\n+\t};\n+\tconst z = {\n+\t\tobject(shape) {\n+\t\t\treturn { ...fakeSchema, shape };\n+\t\t},\n+\t\tstring() {\n+\t\t\treturn { ...fakeSchema };\n+\t\t},\n+\t};\n+\nINS.POST 112:\n+\t\tasync select(title, values) {\n+\t\t\tselections.push({ title, values });\n+\t\t\treturn options.onSelect?.(title, values) ?? options.selectResults?.shift();\n+\t\t},\n+\t\tasync confirm(title, message) {\n+\t\t\tconfirmations.push({ title, message });\n+\t\t\treturn options.onConfirm?.(title, message) ?? options.confirmResults?.shift() ?? false;\n+\t\t},\n+\t\tasync input(title, placeholder) {\n+\t\t\tinputs.push({ title, placeholder });\n+\t\t\treturn options.onInput?.(title, placeholder) ?? options.inputResults?.shift();\n+\t\t},\nINS.POST 115:\n+\t\thasUI: options.hasUI ?? true,\n+\t\tcwd: options.cwd ?? \"C:\\\\work\\\\project\",\n+\t\tasync compact(compactionOptions) {\n+\t\t\tcompactions.push(compactionOptions);\n+\t\t\treturn options.onCompact?.(compactionOptions);\n+\t\t},\nINS.POST 121:\n+\t\tzod: { z },\nINS.POST 134:\n+\t\tregisterCommand(name, command) {\n+\t\t\tcommands.set(name, command);\n+\t\t},\n+\t\tregisterTool(tool) {\n+\t\t\ttools.set(tool.name, tool);\n+\t\t},\n+\t\tsendMessage(message, delivery) {\n+\t\t\tsentMessages.push({ message, delivery });\n+\t\t\toptions.onSendMessage?.(message, delivery);\n+\t\t},\nSWAP 161.=161:\n+\t\t\tSPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",\nINS.POST 164:\n+\t\tcheckUpdates: options.checkUpdates ?? false,\n+\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\nINS.POST 192:\n+\t\tcommands,\n+\t\tconfirmations,\n+\t\tcompactions,\nINS.POST 198:\n+\t\tinputs,\nINS.POST 201:\n+\t\tselections,\n+\t\tsentMessages,\nINS.POST 203:\n+\t\ttools,\n*** End Patch\n","name":"edit"}]},"duration":16964.501699999906,"ttft":3100.592199999839,"contextSnapshot":{"promptTokens":188543,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_aneHjvR52TbMEdzBaLZN4CzZ|ctc_0273f6f0e6456bb0016a5897a5bfac8199a2f7b4e17b9af6d8","toolName":"edit","startedAt":"2026-07-16T08:34:56.134Z"},"id":"e7a443db","parentId":"5d05d37d","timestamp":"2026-07-16T08:34:56.134Z"}
{"type":"message","id":"d74cc5ba","parentId":"e7a443db","timestamp":"2026-07-16T08:34:56.156Z","message":{"role":"toolResult","toolCallId":"call_aneHjvR52TbMEdzBaLZN4CzZ|ctc_0273f6f0e6456bb0016a5897a5bfac8199a2f7b4e17b9af6d8","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#835A]\n3:import {\n\n6:\tdrainEvents,\n7:\textractReply,\n8:\tparsePeerShortforms,\n9:\trunSpt,\n10:} from \"../adapter/strings/omp-spt.mjs\";\n102:\tconst errors = [];\n103:\tconst debug = [];\n104:\tconst commands = new Map();\n105:\tconst tools = new Map();\n…\n109:\tconst inputs = [];\n110:\tconst compactions = [];\n111:\tconst clock = new FakeClock();\n112:\tlet shutdowns = 0;\n113:\n114:\tconst fakeSchema = {\n115:\t\tdescribe() {\n…\n129:\t};\n130:\n131:\tconst ui = {\n132:\t\tnotify(message, type) {\n\n134:\t\t},\n135:\t\tsetStatus(key, text) {\n136:\t\t\tstatuses.push({ key, text });\n137:\t\t},\n138:\t\tasync select(title, values) {\n139:\t\t\tselections.push({ title, values });\n…\n148:\t\t\treturn options.onInput?.(title, placeholder) ?? options.inputResults?.shift();\n149:\t\t},\n150:\t};\n151:\tconst ctx = {\n152:\t\tui,\n153:\t\thasUI: options.hasUI ?? true,\n154:\t\tcwd: options.cwd ?? \"C:\\\\work\\\\project\",\n…\n157:\t\t\treturn options.onCompact?.(compactionOptions);\n158:\t\t},\n159:\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\n160:\t\tshutdown() {\n\n162:\t\t},\n163:\t};\n164:\tconst pi = {\n165:\t\tzod: { z },\n166:\t\tlogger: {\n167:\t\t\terror(message, details) {\n\n169:\t\t\t},\n\n173:\t\t},\n174:\t\ton(name, handler) {\n\n177:\t\t\thandlers.set(name, registered);\n178:\t\t},\n179:\t\tregisterCommand(name, command) {\n180:\t\t\tcommands.set(name, command);\n…\n187:\t\t\toptions.onSendMessage?.(message, delivery);\n188:\t\t},\n189:\t\tsendUserMessage(content) {\n190:\t\t\tsubmitted.push(content);\n\n192:\t\t},\n193:\t};\n\n213:\tconst extension = createOmpSpt({\n214:\t\tenv: {\n215:\t\t\tSPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",\n216:\t\t\tOMP_SPT_SUBNET: options.subnet,\n217:\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\n218:\t\t},\n219:\t\tcheckUpdates: options.checkUpdates ?? false,\n220:\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\n221:\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n222:\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n\n236:\t});\n\n247:\n248:\treturn {\n249:\t\tcommands,\n250:\t\tconfirmations,\n251:\t\tcompactions,\n252:\t\tcalls,\n253:\t\tchildren,\n256:\t\tdebug,\n257:\t\temit,\n258:\t\tinputs,\n259:\t\terrors,\n260:\t\thandlers,\n261:\t\tnotifications,\n262:\t\tselections,\n263:\t\tsentMessages,\n264:\t\tstatuses,\n265:\t\tsubmitted,\n266:\t\ttools,\n267:\t\tget shutdowns() {\n268:\t\t\treturn shutdowns;\n269:\t\t},\n270:\t};"}],"details":{"diff":" 3|import {\n\n 6|\tdrainEvents,\n 7|\textractReply,\n+8|\tparsePeerShortforms,\n 8|\trunSpt,\n 9|} from \"../adapter/strings/omp-spt.mjs\";\n 101|\tconst errors = [];\n 102|\tconst debug = [];\n+104|\tconst commands = new Map();\n+105|\tconst tools = new Map();\n+106|\tconst sentMessages = [];\n+107|\tconst selections = [];\n+108|\tconst confirmations = [];\n+109|\tconst inputs = [];\n+110|\tconst compactions = [];\n 103|\tconst clock = new FakeClock();\n 104|\tlet shutdowns = 0;\n 105|\n+114|\tconst fakeSchema = {\n+115|\t\tdescribe() {\n+116|\t\t\treturn this;\n+117|\t\t},\n+118|\t\toptional() {\n+119|\t\t\treturn this;\n+120|\t\t},\n+121|\t};\n+122|\tconst z = {\n+123|\t\tobject(shape) {\n+124|\t\t\treturn { ...fakeSchema, shape };\n+125|\t\t},\n+126|\t\tstring() {\n+127|\t\t\treturn { ...fakeSchema };\n+128|\t\t},\n+129|\t};\n+130|\n 106|\tconst ui = {\n 107|\t\tnotify(message, type) {\n\n 109|\t\t},\n 110|\t\tsetStatus(key, text) {\n 111|\t\t\tstatuses.push({ key, text });\n 112|\t\t},\n+138|\t\tasync select(title, values) {\n+139|\t\t\tselections.push({ title, values });\n+140|\t\t\treturn options.onSelect?.(title, values) ?? options.selectResults?.shift();\n+141|\t\t},\n+142|\t\tasync confirm(title, message) {\n+143|\t\t\tconfirmations.push({ title, message });\n+144|\t\t\treturn options.onConfirm?.(title, message) ?? options.confirmResults?.shift() ?? false;\n+145|\t\t},\n+146|\t\tasync input(title, placeholder) {\n+147|\t\t\tinputs.push({ title, placeholder });\n+148|\t\t\treturn options.onInput?.(title, placeholder) ?? options.inputResults?.shift();\n+149|\t\t},\n 113|\t};\n 114|\tconst ctx = {\n 115|\t\tui,\n+153|\t\thasUI: options.hasUI ?? true,\n+154|\t\tcwd: options.cwd ?? \"C:\\\\work\\\\project\",\n+155|\t\tasync compact(compactionOptions) {\n+156|\t\t\tcompactions.push(compactionOptions);\n+157|\t\t\treturn options.onCompact?.(compactionOptions);\n+158|\t\t},\n 116|\t\tsessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },\n 117|\t\tshutdown() {\n\n 119|\t\t},\n 120|\t};\n 121|\tconst pi = {\n+165|\t\tzod: { z },\n 122|\t\tlogger: {\n 123|\t\t\terror(message, details) {\n\n 125|\t\t\t},\n\n 129|\t\t},\n 130|\t\ton(name, handler) {\n\n 133|\t\t\thandlers.set(name, registered);\n 134|\t\t},\n+179|\t\tregisterCommand(name, command) {\n+180|\t\t\tcommands.set(name, command);\n+181|\t\t},\n+182|\t\tregisterTool(tool) {\n+183|\t\t\ttools.set(tool.name, tool);\n+184|\t\t},\n+185|\t\tsendMessage(message, delivery) {\n+186|\t\t\tsentMessages.push({ message, delivery });\n+187|\t\t\toptions.onSendMessage?.(message, delivery);\n+188|\t\t},\n 135|\t\tsendUserMessage(content) {\n 136|\t\t\tsubmitted.push(content);\n\n 138|\t\t},\n 139|\t};\n\n 159|\tconst extension = createOmpSpt({\n 160|\t\tenv: {\n-161|\t\t\tSPT_ENDPOINT_ID: options.id ?? \"omp-agent\",\n+215|\t\t\tSPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",\n 162|\t\t\tOMP_SPT_SUBNET: options.subnet,\n 163|\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\n 164|\t\t},\n+219|\t\tcheckUpdates: options.checkUpdates ?? false,\n+220|\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\n 165|\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n 166|\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n\n 180|\t});\n\n 191|\n 192|\treturn {\n+249|\t\tcommands,\n+250|\t\tconfirmations,\n+251|\t\tcompactions,\n 193|\t\tcalls,\n 194|\t\tchildren,\n 197|\t\tdebug,\n 198|\t\temit,\n+258|\t\tinputs,\n 199|\t\terrors,\n 200|\t\thandlers,\n 201|\t\tnotifications,\n+262|\t\tselections,\n+263|\t\tsentMessages,\n 202|\t\tstatuses,\n 203|\t\tsubmitted,\n+266|\t\ttools,\n 204|\t\tget shutdowns() {\n 205|\t\t\treturn shutdowns;\n 206|\t\t},\n 207|\t};","firstChangedLine":7,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190896156}}
{"type":"message","id":"4ededc44","parentId":"d74cc5ba","timestamp":"2026-07-16T08:34:59.899Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Verifying context retention in return values**"},{"type":"toolCall","id":"call_woiwZbo8z18pFPX0RPDXCxNl|fc_06b116ddf069c7e5016a5897b37b68819884f754bb56a92ae5","name":"read","arguments":{"i":"Checking harness return shape","path":"tests/omp-extension.mjs","selector":"230-275"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2130,"output":57,"cacheRead":187904,"cacheWrite":0,"totalTokens":190091,"reasoningTokens":20,"cost":{"input":0.010650000000000001,"output":0.0017100000000000001,"cacheRead":0.093952,"cacheWrite":0,"total":0.10631199999999999}},"stopReason":"toolUse","timestamp":1784190896180,"responseId":"resp_06b116ddf069c7e5016a5897b08f4881989d1bbc415fdf5614","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_06b116ddf069c7e5016a5897b2a19c8198b1896f8ce2c69ed3","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJezV_o7bUeXctAD4uGgbItCB28tNN4J5r0eeNZkDRAhKlcXw_A3SWLR_CMksG6MJF2bQFXi6RJq1KRlJPVEjppNUbzREFTsU7BnOWQMg6TkbL37T6e4OByLY0D-Vawp6HoRGzARVLJPa0xId8EWdD7Gt0eW2go2v0EWqkmkjDYh6PT6ZQujNKd-a95d4gMADwKdfcuRbd9KsdzJ-RxQ6fXNcW_jnWSsZvATq395LC5yzGwAFWqfbeRCXtC4Vvc0uBeF4wVau6ixwKcOwcKZ2SNUFSzd9D6IgLhWKwICXyE6Uib8qfh1NGqZH36-lwZmQ9AJJPGTay6boZtsueYIEWPnXaRCA3A6jxvgYhiG2udErokEaQWLUpI3Wf9-DE90mdIRFn8CbjjFd2MpknuA3Yv1IQNq3HUJoCgptlpbovhWaBj_PNqJHJ4M0RCbL3y2ZxfqquvOFjeZNLw4R-ywQiqdTYzWSlFLF7uX536elEB14e4QqROsB2f--Es-R2wW9iozCtj2W_ne9mqV5zi21wy8HaRuzPhAPu6nYv76OSKiS7BZwtb7S-vyytfWoGfh4vBigtOlkJnYGF8wpjDqr0W5NfTbGBu8TI1AUtwKNjdPslcWIDSUhoB2otZ3JJimnlEqTVqUNyJnk9X-j2qLaNYjMNiibRHfy9iRatXrngdwT7dLdZOUAAfkHY3xF3PI94FxGpIHpNcPjWd9yGMM3aedMQlbWbFUtZ5QIAUlHsJHVuhqKhGjNTWvTwfNSgrY6o5mtpBigRUPvmyOxTUs4xagea_Zq42hmaK7jKbXi_wkpOatsk0obVafzrxEeDbpmYRVxwyxOt41VrJ-nd9sEFThH87ukSii0jYRCrv3HolY6IL6Ju07DL53VpW_8Qm8np7yirL7BxHmJFqZet0sTHp9agCZUrawuXXKLnZqe5RYMmmJRJ_3XDP9qsP5Lo30Hb67sSCHeYhE4viuSlZJC9SKhO32YaAF4KcTmN7cX6egypSptZgUrm_ZJ8MstkBl2eAN","summary":[{"type":"summary_text","text":"**Verifying context retention in return values**"}]},{"id":"fc_06b116ddf069c7e5016a5897b37b68819884f754bb56a92ae5","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking harness return shape\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"230-275\"}","call_id":"call_woiwZbo8z18pFPX0RPDXCxNl","name":"read"}]},"duration":3718.0753000001423,"ttft":2434.4028000002727,"contextSnapshot":{"promptTokens":190034,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_woiwZbo8z18pFPX0RPDXCxNl|fc_06b116ddf069c7e5016a5897b37b68819884f754bb56a92ae5","toolName":"read","startedAt":"2026-07-16T08:34:59.899Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Checking harness return shape"},"id":"a85a2a37","parentId":"4ededc44","timestamp":"2026-07-16T08:34:59.899Z"}
{"type":"message","id":"7d3596d3","parentId":"a85a2a37","timestamp":"2026-07-16T08:34:59.915Z","message":{"role":"toolResult","toolCallId":"call_woiwZbo8z18pFPX0RPDXCxNl|fc_06b116ddf069c7e5016a5897b37b68819884f754bb56a92ae5","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#835A]\n95:function createHarness(options = {}) {\n…\n213:\tconst extension = createOmpSpt({\n…\n229:\t\tkillForceMs: options.killForceMs ?? 4,\n230:\t\tkillGraceMs: options.killGraceMs ?? 3,\n231:\t\tlistenerBufferLimit: options.listenerBufferLimit,\n232:\t\trunSptCommand,\n233:\t\tspawnProcess,\n234:\t\tsetTimeout: clock.setTimeout.bind(clock),\n235:\t\tclearTimeout: clock.clearTimeout.bind(clock),\n236:\t});\n237:\textension(pi);\n238:\n239:\tasync function emit(name, event = {}) {\n240:\t\tlet result;\n241:\t\tfor (const handler of handlers.get(name) ?? []) {\n242:\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\n243:\t\t\tif (returned !== undefined) result = returned;\n244:\t\t}\n245:\t\treturn result;\n246:\t}\n247:\n248:\treturn {\n249:\t\tcommands,\n250:\t\tconfirmations,\n251:\t\tcompactions,\n252:\t\tcalls,\n253:\t\tchildren,\n254:\t\tclock,\n255:\t\tctx,\n256:\t\tdebug,\n257:\t\temit,\n258:\t\tinputs,\n259:\t\terrors,\n260:\t\thandlers,\n261:\t\tnotifications,\n262:\t\tselections,\n263:\t\tsentMessages,\n264:\t\tstatuses,\n265:\t\tsubmitted,\n266:\t\ttools,\n267:\t\tget shutdowns() {\n268:\t\t\treturn shutdowns;\n269:\t\t},\n270:\t};\n271:}\n272:\n273:function commandCalls(harness, command) {\n274:\treturn harness.calls.filter((call) => call.args[0] === command);\n275:}\n276:\n277:function stateCalls(harness) {\n278:\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n279:}\n\n[Showing lines 229-278 of 1441. Use :279 to continue]"}],"details":{"truncation":{"content":"\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcommands,\r\n\t\tconfirmations,\r\n\t\tcompactions,\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\tinputs,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tselections,\r\n\t\tsentMessages,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\ttools,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r","truncated":true,"truncatedBy":"lines","totalLines":1213,"totalBytes":1086,"outputLines":50,"outputBytes":1086,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"function createHarness(options = {}) {\n…\n\tconst extension = createOmpSpt({\n…\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\treturn {\r\n\t\tcommands,\r\n\t\tconfirmations,\r\n\t\tcompactions,\r\n\t\tcalls,\r\n\t\tchildren,\r\n\t\tclock,\r\n\t\tctx,\r\n\t\tdebug,\r\n\t\temit,\r\n\t\tinputs,\r\n\t\terrors,\r\n\t\thandlers,\r\n\t\tnotifications,\r\n\t\tselections,\r\n\t\tsentMessages,\r\n\t\tstatuses,\r\n\t\tsubmitted,\r\n\t\ttools,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}","startLine":95,"lineNumbers":[95,null,213,null,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1441,"totalBytes":1086,"outputLines":50,"outputBytes":1086,"shownRange":{"start":229,"end":278},"nextOffset":279}}},"isError":false,"timestamp":1784190899914}}
{"type":"message","id":"5b2063bb","parentId":"7d3596d3","timestamp":"2026-07-16T08:35:03.237Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Running focused tests on failures**"},{"type":"toolCall","id":"call_ubGjmeaE1tCfbNaIwkN6sbsT|fc_0d8f7e9f748edb03016a5897b6b970819986c40867449bab21","name":"bash","arguments":{"i":"Running extension tests","command":"node tests/omp-extension.mjs","cwd":".","timeout":120}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":585,"output":54,"cacheRead":189952,"cacheWrite":0,"totalTokens":190591,"reasoningTokens":14,"cost":{"input":0.002925,"output":0.0016200000000000001,"cacheRead":0.09497599999999999,"cacheWrite":0,"total":0.099521}},"stopReason":"toolUse","timestamp":1784190899928,"responseId":"resp_0d8f7e9f748edb03016a5897b4391881999b77add498d29b46","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0d8f7e9f748edb03016a5897b5e0cc81999f43d1f8cdf1cdcc","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJe2pzh3_3baQ6hfYYIgKR4r9w1yAb3IYjzwVgK_77CvUCsQOQhxDzHpmACgwku9KPM5OGpihis5JaCJNUozcT7WGEih9apb2gU26yK_B-u_Fv55-be-RYRlQ3wcOHuEF_HcBG0dKNuxd5PjerUAqwaunncUkjIvJ95oIrEIAeRJE_EklLWThweFQ91-OPUNKK4qUlBBI2nnwrDKr4y2X2gY8zKt2LHRuf5s6hu-olLlcGZi0XNTn2VPxzKWOczFRq1xcSOeKGaMbX946ROWRcC0TbL2yRAFgYc4g3Am6kCddoA0H8XW8vLNYFd3DyvHVLwh26RXw_BnPOdIwtmmIpN7UdTPsTZD3uji0Q4chvhkBqlEQwckYNOMSqJZ4ZLXVJHHpj4l_EECty3pfe1hkOHPRD2QYp5Aubgb0xWFeksgWQPyhEuE1MjV12IwNZW1NbP-6FD3DGfxVSiofWQ_E-g2XlrF3lMDUJVFKJk5b92ApCtSBe1GC0J5xmPaMhHD7kogFPG8w0mMwpDmnTXUc9ijvikZNlH-bUy-Eu7QET-63sj06L6pQEe5hhEBrNsDLzO9RMw__K6RozvG4N5A3uNTzYyMZ0TKMs-16Pm_ADvzb1N5vZ8c44LpbBfoLUmXzCjswLHJT0qNi-UiDqCUXOq8kytGwMf7cYGrJt0DnxexGLpzVfePhhYorvjbtkKZD9Z5IT-imuuZKxPcy_PAVPAhIltXcDsaR07JCrRpGN3rxC-VTh0Obd2mseLcyCRcO3Tlk_J6diKbvFf_oQKiCptfzqvir_AuhV1GlBN1fH5nQpmpSofiQAuH7uDM-sIe9h9Ejb78-DWfISrt3RIYky0ljcW47lB9gs3zl1mytE2526feKevS-OnvTAvPv_IRp7QWZrxOQyhqUCPyxu0ih4BkiAIfD1Efl8A7NxRtVU60deQR1nLxnuEIY9xmpNSX6-aSkpNJmDbBhWkZqadzC19mOV2S_smIz283wem8KIdDDXA=","summary":[{"type":"summary_text","text":"**Running focused tests on failures**"}]},{"id":"fc_0d8f7e9f748edb03016a5897b6b970819986c40867449bab21","type":"function_call","status":"completed","arguments":"{\"i\":\"Running extension tests\",\"command\":\"node tests/omp-extension.mjs\",\"cwd\":\".\",\"timeout\":120}","call_id":"call_ubGjmeaE1tCfbNaIwkN6sbsT","name":"bash"}]},"duration":3308.591699999757,"ttft":1958.6348999999464,"contextSnapshot":{"promptTokens":190537,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ubGjmeaE1tCfbNaIwkN6sbsT|fc_0d8f7e9f748edb03016a5897b6b970819986c40867449bab21","toolName":"bash","startedAt":"2026-07-16T08:35:03.237Z","args":{"command":"node tests/omp-extension.mjs"},"intent":"Running extension tests"},"id":"8c54130a","parentId":"5b2063bb","timestamp":"2026-07-16T08:35:03.237Z"}
{"type":"message","id":"4cc40a53","parentId":"8c54130a","timestamp":"2026-07-16T08:35:03.299Z","message":{"role":"toolResult","toolCallId":"call_ubGjmeaE1tCfbNaIwkN6sbsT|fc_0d8f7e9f748edb03016a5897b6b970819986c40867449bab21","toolName":"bash","content":[{"type":"text","text":"node:internal/modules/run_main:107\n    triggerUncaughtException(\n    ^\n\nAssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:\n+ actual - expected\n\n  [\n    'session_start',\n    'session_before_switch',\n    'session_before_branch',\n    'context',\n+   'before_agent_start',\n    'agent_start',\n    'agent_end',\n    'session_stop',\n    'session_shutdown'\n  ]\n\n    at testLifecycleCustodyAndContext (file:///C:/Users/decid/Documents/projects/omp-spt/tests/omp-extension.mjs:349:9)\n    at file:///C:/Users/decid/Documents/projects/omp-spt/tests/omp-extension.mjs:1423:7 {\n  generatedMessage: true,\n  code: 'ERR_ASSERTION',\n  actual: [\n    'session_start',\n    'session_before_switch',\n    'session_before_branch',\n    'context',\n    'before_agent_start',\n    'agent_start',\n    'agent_end',\n    'session_stop',\n    'session_shutdown'\n  ],\n  expected: [\n    'session_start',\n    'session_before_switch',\n    'session_before_branch',\n    'context',\n    'agent_start',\n    'agent_end',\n    'session_stop',\n    'session_shutdown'\n  ],\n  operator: 'deepStrictEqual',\n  diff: 'simple'\n}\n\nNode.js v25.8.2\n\n\nWall time: 0.06 seconds\n\nCommand exited with code 1"}],"details":{"timeoutSeconds":120,"wallTimeMs":61.18400000035763,"exitCode":1},"isError":true,"timestamp":1784190903298}}
{"type":"message","id":"e073d5f6","parentId":"4cc40a53","timestamp":"2026-07-16T08:35:11.234Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_7ctQTP3LuF1q4Az3ZXZZbQOY|fc_0ab475e0b9a18b7f016a5897be9de88198b06f3f9165571230","name":"read","arguments":{"i":"Reading lifecycle handler assertion","path":"tests/omp-extension.mjs","selector":"335-365"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":956,"output":53,"cacheRead":189952,"cacheWrite":0,"totalTokens":190961,"reasoningTokens":16,"cost":{"input":0.00478,"output":0.00159,"cacheRead":0.09497599999999999,"cacheWrite":0,"total":0.10134599999999999}},"stopReason":"toolUse","timestamp":1784190903346,"responseId":"resp_0ab475e0b9a18b7f016a5897bbcb1c8198b3833ab84c8cb99e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0ab475e0b9a18b7f016a5897be01548198855e84a890edb54c","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJe-ZL2p0NM3VxhfBKlqGny5VMGp7vDqyql1RDY1mAydBBBcsaTWMhesgxo7RZstEQxHRPMktY6Ddk8g5ICB5V_FH41rijrTrLXWLAHpuajqU-vOsfsiYCU0yUysRX5Puxh79Xoh4zt6HOpfXYqIcrk4APl2fHRoRdOn3MsgZD4WBgjDwzWy2bcjUnp7z69SDrM45tnTkg67WzfNc6IVsE7sXWaZdG8s6lcf-23ltlwJi5W4Dp3AI-RFetUCJjhFf71euElkV40pZCGwmZXYVCNf9E_HOfazHLwVzqC0ORzbpt88TBkzBdnIj_vMJ2LbuaOYnzwLNL7WDgKpbfaITcGLG2KhulCAh-6S502zLpKQSQ3TZrnXYn-BRSytaGM_1Bl5Sr7qMYpf002YIaGVMTrp6KMR_HGUVATw51ImgELOdC3mQbgK28J164EVx1_7kQwSmc1uYcMMzkrz8zWVVOwFV9AC0WyYCGt8kj7FgTM1p2sqZJw96GWOy24gLZTG4fxIKrgWgu2bgQ7WBIVlx7GkV85DgFgyWKW5E40pvuxvG3eucZtc_fwQlOJX1rw1dw9BmYtvczkhd9znsnGImCxMx_eoiPv0ayA2DVKmAfmkb0910_wRTmSzW2yeoRL4qE6sxpswznHvCm_sQv2n7wTEH_GCHTwarIknM1b10BMeXEF_JUQZu7-i8N0sBHCFMLQMaXdKrXzAVu075-X09BfDMTXDTwozxzKN-gCKcVuuWm0h9wjJ93li3ktPmtvDvyfIEcRMrpyHd9Vg4Ypgv8QF7XVQ4L5QzJWoune07KO8_jH_ujpeLtRw9ETnFm2kOQBe9t-6zSYTVg5WEa3mOyytRI2Yg11rt2r-YwFi9uKIzBsUmDAS6VzV4HaBzU6I4EQRIecCljKCiulPMXdEfvxXgWN1TwU331tVz1AOVuCVGn6vQ8afByXEk6iibSgM8lahJnwNklIo194rd-hLhFRonqjGpYijyptjANFVB2Hmmgg=","summary":[]},{"id":"fc_0ab475e0b9a18b7f016a5897be9de88198b06f3f9165571230","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading lifecycle handler assertion\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"335-365\"}","call_id":"call_7ctQTP3LuF1q4Az3ZXZZbQOY","name":"read"}]},"duration":7887.862199999858,"ttft":6654.002399999648,"contextSnapshot":{"promptTokens":190908,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_7ctQTP3LuF1q4Az3ZXZZbQOY|fc_0ab475e0b9a18b7f016a5897be9de88198b06f3f9165571230","toolName":"read","startedAt":"2026-07-16T08:35:11.234Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading lifecycle handler assertion"},"id":"d703c7b9","parentId":"e073d5f6","timestamp":"2026-07-16T08:35:11.234Z"}
{"type":"message","id":"821541d2","parentId":"d703c7b9","timestamp":"2026-07-16T08:35:11.246Z","message":{"role":"toolResult","toolCallId":"call_7ctQTP3LuF1q4Az3ZXZZbQOY|fc_0ab475e0b9a18b7f016a5897be9de88198b06f3f9165571230","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#835A]\n281:async function testParsingAndReplies() {\n…\n331:\tassert.equal(\n332:\t\textractReply(\n333:\t\t\t[\n334:\t\t\t\t{ role: \"assistant\", content: \"stale answer\" },\n335:\t\t\t\t{ role: \"user\", content: '<msg from=\"doyle\"/>' },\n336:\t\t\t],\n337:\t\t\t'<msg from=\"doyle\"/>',\n338:\t\t),\n339:\t\t\"\",\n340:\t);\n341:}\n342:\n343:// [unit->REQ-OMP-EXTENSION-CUSTODY]\n344:// [unit->REQ-OMP-SESSION-IMMUTABLE]\n345:// [unit->REQ-OMP-MESSAGE-CONTEXT]\n346:// [unit->REQ-OMP-NATIVE-TUI]\n347:async function testLifecycleCustodyAndContext() {\n348:\tconst harness = createHarness({ subnet: \"mesh-a\" });\n349:\tassert.deepEqual([...harness.handlers.keys()], [\n350:\t\t\"session_start\",\n351:\t\t\"session_before_switch\",\n352:\t\t\"session_before_branch\",\n353:\t\t\"context\",\n354:\t\t\"agent_start\",\n355:\t\t\"agent_end\",\n356:\t\t\"session_stop\",\n357:\t\t\"session_shutdown\",\n358:\t]);\n359:\n360:\tawait harness.emit(\"session_start\");\n361:\tassert.deepEqual(harness.calls[0], {\n362:\t\targs: [\n363:\t\t\t\"api\",\n364:\t\t\t\"--adapter\",\n365:\t\t\t\"omp-spt\",\n366:\t\t\t\"bind\",\n367:\t\t\t\"omp-agent\",\n368:\t\t\t\"--set-session-id\",\n…\n372:\t\t],\n…\n374:\t});\n…\n486:}\n\n[Showing lines 334-368 of 1441. Use :369 to continue]"}],"details":{"truncation":{"content":"\t\t\t\t{ role: \"assistant\", content: \"stale answer\" },\r\n\t\t\t\t{ role: \"user\", content: '<msg from=\"doyle\"/>' },\r\n\t\t\t],\r\n\t\t\t'<msg from=\"doyle\"/>',\r\n\t\t),\r\n\t\t\"\",\r\n\t);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-SESSION-IMMUTABLE]\r\n// [unit->REQ-OMP-MESSAGE-CONTEXT]\r\n// [unit->REQ-OMP-NATIVE-TUI]\r\nasync function testLifecycleCustodyAndContext() {\r\n\tconst harness = createHarness({ subnet: \"mesh-a\" });\r\n\tassert.deepEqual([...harness.handlers.keys()], [\r\n\t\t\"session_start\",\r\n\t\t\"session_before_switch\",\r\n\t\t\"session_before_branch\",\r\n\t\t\"context\",\r\n\t\t\"agent_start\",\r\n\t\t\"agent_end\",\r\n\t\t\"session_stop\",\r\n\t\t\"session_shutdown\",\r\n\t]);\r\n\r\n\tawait harness.emit(\"session_start\");\r\n\tassert.deepEqual(harness.calls[0], {\r\n\t\targs: [\r\n\t\t\t\"api\",\r\n\t\t\t\"--adapter\",\r\n\t\t\t\"omp-spt\",\r\n\t\t\t\"bind\",\r\n\t\t\t\"omp-agent\",\r\n\t\t\t\"--set-session-id\",\r","truncated":true,"truncatedBy":"lines","totalLines":1108,"totalBytes":823,"outputLines":35,"outputBytes":823,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"async function testParsingAndReplies() {\n…\n\tassert.equal(\n\t\textractReply(\n\t\t\t[\n\t\t\t\t{ role: \"assistant\", content: \"stale answer\" },\r\n\t\t\t\t{ role: \"user\", content: '<msg from=\"doyle\"/>' },\r\n\t\t\t],\r\n\t\t\t'<msg from=\"doyle\"/>',\r\n\t\t),\r\n\t\t\"\",\r\n\t);\r\n}\r\n\r\n// [unit->REQ-OMP-EXTENSION-CUSTODY]\r\n// [unit->REQ-OMP-SESSION-IMMUTABLE]\r\n// [unit->REQ-OMP-MESSAGE-CONTEXT]\r\n// [unit->REQ-OMP-NATIVE-TUI]\r\nasync function testLifecycleCustodyAndContext() {\r\n\tconst harness = createHarness({ subnet: \"mesh-a\" });\r\n\tassert.deepEqual([...harness.handlers.keys()], [\r\n\t\t\"session_start\",\r\n\t\t\"session_before_switch\",\r\n\t\t\"session_before_branch\",\r\n\t\t\"context\",\r\n\t\t\"agent_start\",\r\n\t\t\"agent_end\",\r\n\t\t\"session_stop\",\r\n\t\t\"session_shutdown\",\r\n\t]);\r\n\r\n\tawait harness.emit(\"session_start\");\r\n\tassert.deepEqual(harness.calls[0], {\r\n\t\targs: [\r\n\t\t\t\"api\",\r\n\t\t\t\"--adapter\",\r\n\t\t\t\"omp-spt\",\r\n\t\t\t\"bind\",\r\n\t\t\t\"omp-agent\",\r\n\t\t\t\"--set-session-id\",\r\n…\n\t\t],\n…\n\t});\n…\n}","startLine":281,"lineNumbers":[281,null,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,null,372,null,374,null,486]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1441,"totalBytes":823,"outputLines":35,"outputBytes":823,"shownRange":{"start":334,"end":368},"nextOffset":369}}},"isError":false,"timestamp":1784190911246}}
{"type":"message","id":"fe74c6f0","parentId":"821541d2","timestamp":"2026-07-16T08:35:17.855Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_yoWrzoebcoKGCcG6X8FJr0Oe|ctc_01cef7fadff328bc016a5897c4e8d081999a13806a374831e4","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#835A]\nINS.POST 353:\n+\t\t\"before_agent_start\",\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1404,"output":51,"cacheRead":189952,"cacheWrite":0,"totalTokens":191407,"reasoningTokens":7,"cost":{"input":0.00702,"output":0.0015300000000000001,"cacheRead":0.09497599999999999,"cacheWrite":0,"total":0.10352599999999999}},"stopReason":"toolUse","timestamp":1784190911284,"responseId":"resp_01cef7fadff328bc016a5897bfec2c8199a193512cd03d1843","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_01cef7fadff328bc016a5897c4654081999219df5e4549da4b","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJfEjkXbbKIJN6XbN3w_06teXstFmej17uJbP8IesZmOwSS8J2SzQqjI0HOmXqMrJBxnNrFswm6wiXftOlmUxX9iqhTggvTrJiMaaGxO9nxxVuDca4WnziP_e4Nu92Y--AUWGWb-rdRr_beSiBwV1w5stpZ6aleeNsF0-gM6WXWuyl8wbs-reLRzAU7FjwctUBayCqUZjSziBZJ5sgArHGZro5BccRX-oAuOqLDFd2WVNF9bqA6JV7SV2_v06n1cVb6iAx4qlpnK4SHWQexuoJKp8lWnNYzmnIBFgwWdnwlJop-AYIMawhNOUYf44lkjvr3N5V46uLc8n9ZEPzRkDd1K-WmM9_Jh1RYBXTPSsUjSb54-mY_57jrd5aonqYfS355pAi-66C_sTrZJo2sU6SXwQZW8hmVle8k8R9lKcei7xBoJMqFBQ_S-XgM3jdN626DPm-VK-PLMuPmoOGK2gNpeWZuP5wrpevaYYNYb0V3jrhE7-RTD396hRuvbIq2_ateACD1g-MJhiS7NMiFV2GFucUoTyYOaOCEYjnJPYf8_nZPa4pDxG-F7w6IgePtDH2vzpnKMu_ZQXORD3k9-S9OPYbnTwNhORvOaOjD0rUrbJZ_dlCbj4OQ7dtmIaiyi3-NVAyDHDp3rsKF4iHfpEWFAMBIIMlOY_2V6Wt0oeqpGUL890wWG8dwzko5brfKw4YJ8KyfvoKKh7Eju9NMsOGJTpSxVGDb83sfIeH9zcBmFDRhTpGxVy1E3fzoEP8z1vCJJ5d0tS4j59zctdmAi5QqKx0R_R3_Xo0uEIHHby9RUaxuXlsK5ucs8yksyonSjMNzwXCjQm-dkIcirzDipx0F251yH__u6gkp4OkJ5-lJ8kzj_rCfs8zqd-thjA9f-5cOkxV3AvXbNlqFqsHU_lFWzlu2a5Z5ceQVtWCLsS64uEQQ=","summary":[]},{"id":"ctc_01cef7fadff328bc016a5897c4e8d081999a13806a374831e4","type":"custom_tool_call","status":"completed","call_id":"call_yoWrzoebcoKGCcG6X8FJr0Oe","input":"*** Begin Patch\n[tests/omp-extension.mjs#835A]\nINS.POST 353:\n+\t\t\"before_agent_start\",\n*** End Patch\n","name":"edit"}]},"duration":6570.473199999891,"ttft":5098.171399999876,"contextSnapshot":{"promptTokens":191356,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_yoWrzoebcoKGCcG6X8FJr0Oe|ctc_01cef7fadff328bc016a5897c4e8d081999a13806a374831e4","toolName":"edit","startedAt":"2026-07-16T08:35:17.856Z"},"id":"93dfd321","parentId":"fe74c6f0","timestamp":"2026-07-16T08:35:17.856Z"}
{"type":"message","id":"01ca76ac","parentId":"93dfd321","timestamp":"2026-07-16T08:35:17.877Z","message":{"role":"toolResult","toolCallId":"call_yoWrzoebcoKGCcG6X8FJr0Oe|ctc_01cef7fadff328bc016a5897c4e8d081999a13806a374831e4","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#3EE9]\n352:\t\t\"session_before_branch\",\n353:\t\t\"context\",\n354:\t\t\"before_agent_start\",\n355:\t\t\"agent_start\",\n356:\t\t\"agent_end\","}],"details":{"diff":" 352|\t\t\"session_before_branch\",\n 353|\t\t\"context\",\n+354|\t\t\"before_agent_start\",\n 354|\t\t\"agent_start\",\n 355|\t\t\"agent_end\",","firstChangedLine":353,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190917876}}
{"type":"message","id":"c0eda05d","parentId":"01ca76ac","timestamp":"2026-07-16T08:35:21.233Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_jBMUn9IqULMbpkbMlLk3pzz4|fc_04e7e6b73da3fa44016a5897c8ad04819aa21e39d659669432","name":"bash","arguments":{"i":"Rerunning extension tests","command":"node tests/omp-extension.mjs","cwd":".","timeout":120}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":493,"output":49,"cacheRead":190976,"cacheWrite":0,"totalTokens":191518,"reasoningTokens":7,"cost":{"input":0.002465,"output":0.00147,"cacheRead":0.09548799999999999,"cacheWrite":0,"total":0.09942299999999998}},"stopReason":"toolUse","timestamp":1784190917933,"responseId":"resp_04e7e6b73da3fa44016a5897c68c58819aa74a61d27186187e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_04e7e6b73da3fa44016a5897c81ff0819aa1843fa638483e99","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJfIBhBDD1QXYT4-jA9NpqR7QHOict35T4bL_qxg_bXz4zW4Bv2YYxTux2Xv8JrERkhg4Ryu0TbTv7Jx3B43i7TzdNLYN6Vl6JSAaz98-qAC4cmjHkW6C8sS91wCrg6P_PszRF_sXXY7PSBp8LPi4laQ05HoFd9Zs4EyQQGSi_TGQWV2bBNNLtcuFfvu9pVgpM1TTPnpCVcK8ePcdMCQ8RUZS-guJbcl-f4c4_qKbm5fXD2cVk6_Mt17pWUZyIgo0mDIb0sb534pykoxwU4kuHzl9Vw17FqJIPDNaGpdm4t0Jfa_BKRKQwLaMcztxsHBypHvFYFedAJc8HRgTOTEJQB74KaZfmGWV6_vqnwT5afvYl3rRKBkCKnvCQPpwpHSFBjblxOOQcPwzyLbNdUlrM5snSKeBP1aHtSYQ8uWHhhLEu1UktFFIAWMVqn210W5FrM6vUW3uDD8czthQ0abkWlJid2c2XFc2ZJGImavJInRoPIQ4eDCoOs-2R3HP7GpNdvtdDzNO1L6CemYasnnF_AbaMOyzuqhcjHHeeWE33t3klD2Ua12aEBfzsQuMqUlLzpv_Q1_UbDFWV24odMASnL24NC6sjIns3WQzPN8gI3BkLgTy7DnZk6A6Oo0vOzY7knqP08GzSkl0WJP4Y3KfKG-rciD_rIYOtY_7Cb9ynIGk82HRUcBmKr4ZtvZNtsj-AXJG-aARcM5qI1rTbUCiXpJ6k8u68ZfhUUVAEHs8wt_XddOYsqMknXFC-BUV_AtbwctNipEkAC0BUIWl4BtfI-qBFfohYRx6L9CGkS8KYaoh5d9FfC7ZOP-hGQsHIquuRjmdpH3YmZ-q2Jh5ZY8wzJnZYB7rbJiTbKFMNQ5ErEC12Yt7NV15jBhCHRNdqbOCuceLvxXISD6RXjhtYT32JBij0wdpfyS5WK6eo5IAwssEr8=","summary":[]},{"id":"fc_04e7e6b73da3fa44016a5897c8ad04819aa21e39d659669432","type":"function_call","status":"completed","arguments":"{\"i\":\"Rerunning extension tests\",\"command\":\"node tests/omp-extension.mjs\",\"cwd\":\".\",\"timeout\":120}","call_id":"call_jBMUn9IqULMbpkbMlLk3pzz4","name":"bash"}]},"duration":3299.4849999998696,"ttft":2175.2617000001483,"contextSnapshot":{"promptTokens":191469,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_jBMUn9IqULMbpkbMlLk3pzz4|fc_04e7e6b73da3fa44016a5897c8ad04819aa21e39d659669432","toolName":"bash","startedAt":"2026-07-16T08:35:21.233Z","args":{"command":"node tests/omp-extension.mjs"},"intent":"Rerunning extension tests"},"id":"ff3f2748","parentId":"c0eda05d","timestamp":"2026-07-16T08:35:21.233Z"}
{"type":"message","id":"168e06f3","parentId":"ff3f2748","timestamp":"2026-07-16T08:35:21.301Z","message":{"role":"toolResult","toolCallId":"call_jBMUn9IqULMbpkbMlLk3pzz4|fc_04e7e6b73da3fa44016a5897c8ad04819aa21e39d659669432","toolName":"bash","content":[{"type":"text","text":"OMP-EXTENSION OK\n\n\nWall time: 0.07 seconds"}],"details":{"timeoutSeconds":120,"wallTimeMs":66.59220000030473},"isError":false,"timestamp":1784190921300}}
{"type":"message","id":"34cc4e1b","parentId":"168e06f3","timestamp":"2026-07-16T08:35:50.796Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning focused acceptance tests**\n\n**Detailing ready selection and error path tests**"},{"type":"thinking","thinking":"**Refining subnet and checkpoint patterns**\n\n**Designing cancellation and failure recovery tests**"},{"type":"thinking","thinking":"**Verifying multi-target send statuses**\n\n**Identifying production bugs and fixing prompt regex**"},{"type":"toolCall","id":"call_Qhb0jmslv4FrJqoQ469yUXNa|fc_02481840ef3d3be4016a5897e5ef048198b217d9b6c02c01b9","name":"grep","arguments":{"i":"Locating targeted hint patterns","pattern":"spt\\\\s\\+\\)\\?subnet|checkpoint\\\\b","path":"adapter/strings/omp-spt.mjs","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":567,"output":1351,"cacheRead":190976,"cacheWrite":0,"totalTokens":192894,"reasoningTokens":1279,"cost":{"input":0.0028350000000000003,"output":0.040530000000000004,"cacheRead":0.09548799999999999,"cacheWrite":0,"total":0.138853}},"stopReason":"toolUse","timestamp":1784190921353,"responseId":"resp_02481840ef3d3be4016a5897c9bb4881988680a07e0f722b10","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_02481840ef3d3be4016a5897ce45948198aca96069625d42d8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJfXEW-8Syr9kEWSP-tETVbAxyhnXsozD3rVWrUuEPbPQEx_o-S4cTlbxlo32Zk9tob1OAJ92mKM9V5VOkCOtFqRalFLyWXQbAhd0f0ktWp7uihDKaGBlH8alc0LLIGEue0X1HcJWvj45pN7XEwqI1NjRi0ZAjqImtTWanXYjFx06DLUzzTKgFo_ofCACGAPrYQ25FA828xOjMRUH-5iV5lu2okU7hYeGv86ynMv9pX4cyILZ354uTxqnrNDwz14KymZOPv_m40SvVR0tUmPvG9KdxrIsPuuoPv9mTLPxu24sVVhf6mqNGMe1hKAQUsvKw_OTiaMbYFtsKbubaHFnTSbDel_PKC8jt1SgY4EnU5jen7sNTaPgyZZedC9tHiHC9AkGG-Z5m7o80cKLuuzKEbATPQpiBTBXgWlxfrU26o9EbCb12FvNf3-QLOM-KAxdzV_DoQm3bcNFI6GOMfqJfdtJ3PueWvqLOU7-qoWMclDJIMZ86_7YqhzODz2fPKj7DO00ZFCgnciqZd3eBUfjV9Njwgqa0_FIEiBo4HnXO67pY_cferE7Np3J8pzxnyu9ZTZsI0xrCv3-BWAj4tOs0QQ-FQp-XbMvFgX2okBekPCG0hgtCo5d5jSBCBEL72Acb0sF5cQ18d6CYUonYeDKulGsSaS-IfnXlxJ73YJrO7pF3Fhsf5VJs2tzzuR_0En3EiHEjC411BSMgpyW3vu_4zPMJ3M4v7XSwquZafusoX7njSLDxb10uHpyzapQAH3wNSDkT_OWGB_GIAM_GDXZPqv8oSPvcN8RnzycumRpktpVmKq3QgHbOyBun5siBuDcIvPBzD4NT9Q_FFw1mpAx9FLbwSPHaLB8E84niWiaL3KM1sMqlUyAaBM28R_l3FPYo-2Egp4yGO5cLGsJq44vDEmJlr9_-o8b8T0_6P8BjFilEnd8ZwGs8GwLtWW9-KginE9ylMsr4LXYcTB7caXyTE6oJtRBqVw6wSuCupqzhBStAuRKYHr6S9SjETTW1VwBJ8NMXNI-gcCgD8_nOY3FdacnrGZku2BuRCAE6bQ5NB8EnZWJtgCzC246mja44MfpvD8w6c_k0z0AIUV0dGB9k5-VTIYIWasXbjP6uggvQswQR7X5KmYwu5dTpMYWZ-a7Or6slNEfkmHrS4yfyK3kpYJknc8rsUxKOvSGU5QR-Ly1ReP_kfbxMofNZ9JV0RTS9u_c0CQdURO9cNHVSs9iXXQiQXjKRFAY5Ph_c5lZBdu-ZEZSZN6zZb1WZtBNJqRVO0TqTKIbpqmgPjGTcIfsW1yfQmulXQugfTKGilCHagHx0jgOwqwAn7hjdk3Zu4PbWNJVU18CMDqumomBP2_QG7lIEVdwXN2t7LwcorTdihFRfzo9Nh1bRUpzUZHqjV4Q7prmdWPbb3kdF9oQqJCyq9Bkq00zxL_iyDfd0wxWVnJSuwUteVRyDbSh2E7xE7YJB4Av9ZEu7wOeLd34b78E695Gv1F1h58pCp5xkI9tyFY9NhQpw8z1mBngMnObsgQWefdiutOuShIHYtT3Pg3EMsljvVTvixX_ICsIiXoCXnnJJodcTrJ_XM4NDM03gQr_ZLJBJ8bEtPHkfEMqpKGZPdehZYnRZwwVCn2HX4uSftk69XvNRmv8sYRqfCGpauexZtMpHZEDNJd5P-gWIUK_Xbp1haUYFG7G-ox5BDHhyceK4I22i7XlLCq30ABer_agITF1tNqNr8WWFVlkxo5BtH_B5nR_PtOHsNLU_BbQ7oNsQs_PxqtMIljr-KOd29bkfRArNpihE5iQUJJDSWECYCQGTy01Fpce6MvVFRrxOjaC6vjrcKhlcx-QE4sOktP0y5sKT7FvBF2D04JJQXnjyTcSiiyT9MRqppLgESPgLVQupXhvY47NWzicWJVQGX5BB4RN28XJqUIVpxp-VnyboOwAx_ecJMoVCy5LICyK75vuZMXNikkjnRK7sym8NJyVcEVyTAivcFh58yFrywnG4l0yyEd-31_YHjP9aCRgYMAk7CNJoFjQjLyU043OXjNUf1U4ypzZe1M-DyqyqdwttYgshXIEkOz1lSOxACygH5Ht4OThvZNl-6Xpogm4xwe4gAQwkkzdLGwKx0C8BgqXtptnxe3naIjEwwBF8KZtWh0GJWQpq4A-tgk9Cr-TET64OKx7UlHNS3sVo7mNFJi52pK-foPo7DqU7ZttZrdl7lGfrU_sAP34GeBYlVMXPhRs_l29CuFt4gGH2Z_wL2TBr6_6Ixs0N7amxHVHh25_SkhKG6ZxvRPa7gglrQC5gqfnXm0KhCbBA9x-W9quv9klvvzOFQ6TzVu2kVI2A4JVf57_TAqDkrjDVUQvD8hPG2QLneeVudFY_COWjEcmqwg70vlXtlz163cHmr3dKtZl15jh9QNtvGeLqRBYhazBMfhBf3_S9fo1ihHS1T7m4sIl-NBoDcGcg5nXoZibQjYmFiQBNhD6egZc9TuSVq7jj5ePJTUHRUu8YIGh9_ZEzmMU8pGmnHHQjUtoTemelKTFhIqzGzpuiDom6KJxYUn_F_FJ-ftNN0xxlRvdqo6nnFjiPdtc64iZ0nAg06XFsz3H9A2JTmFrszrJdNt4vwWUzuXSE2972tW2vRq5lUiHscAKtt1tiBSwsDNWoQiopOedmcbP4rkDVOvMb8W1TagvwWMtwd2Wt9WX06WL1T78L5BXcX6KhQu-ivddphEQFhn75ZrcezGjJ5Yxa8qPeB_tQ-pfH7mYlmtoBZmaHaEnGmnHL8jk-oWj2qx3Pdp4irBInswxTA2UDCBDuTRq3zczOqM0NihfnZUH8m2EoRUGjCQ8zgLP7RDZoZ1SziNWQVweuXhrE10OnvrdSwS7dnj45OKPcCmjykTtldgxnU1qdQ7MY50Lloc-eSGDBOrKNFnvQlHnRn8bdyZnF7adaSiTEyMf3y2jINIergc0FpgR8LEmA4Idvau7lkivW9P-TwJets05r32HmLmQ5w8sng5KD7oUFRGjRCMHmXl80o620hVkukhy7fbQ-Dy8E5bhlW7BdUuqw---JGusgk5JbhXTBzqKI0LAN-sqtYtlFXMbMsJyUL0c1KLCdsgW6sEhi5gxPKcTa8xIV3DrkGcKGz_xSPcFzQIwYvJPFhHvBDwUa5DGx5oU988uuf-7QjV6sjNTT5_W3n9JtsR_QAHDzGKHi3iq82BbsO1_idPZdOfsvfjc1uB_N2YzgiVvrR4hTtG1vKSyh8K34EpNhxFRIJ6XsmaAw_NxpM74ogvBxo0pvlcW42sMjymmzPXjj3-UHpOPAGBsZoYtUUXnSHtUyGRNIbZA9fJ_menLvEt-A8N-XGqGRgQibHaedsKM37jIfc7KNZ-ZW2JD0O0MoDF5kc6iifNMtG_cBjTEeMJv00q8HhLrty_ex0swYRG-VdGhoTY6xypkWAoyUiUnjYie9Gn9SEys4tdiruHx1K2apkr-UT3Tj9eg-POXlLTF8jsHtz3HAgss-hgU_8n_gE_ReRmtodPlHnQxdBL1ay_0tpo-9ix2DPHpZpe8IVfrHpZ2vI-NEkegH3GFGlJ5ADLYfkmtGuI5isAPzulQdkXsy3GhbN4UrMY-QlAx4KhVl4enRHJj8xOwBqjDFPDaUXkazr7N-pZGKqcBY_GnVeIGTsRZvuKyRlJbt3wcFgOyqxW0E2ZU-qwHyQZ3f3BwJ42pnDsXn2STRQqvEMTUtQG8SzL-X1zryBtrSp4EcgWOfDQUV8Ci-6H4WWMkJcJMdyxomc6H5O_VQ2IQaPl9rHa4wZXTqkjeyaa6mQksf5lPvug00GfOSKvZVWnlex19do5FfoBlm4OdIxwiTQPx3a651C2VfTuahs3RdJDlZsWsyR2cs3eMnuHZPiHM42-5FtglWCmo3W0pufDPzAh4QFyQgrLd8xLEH7nd5u59mCXuwjRbfdOBL1v-SBPruiZdH_dRH7EASOf__jLS1AsJZ4orbn7pS_TaK8MBR14bRBODvlABrDeJyw1sjtUpVGzQx-rL7orqUh1ckU2V3_J-Ps3oCxzKBwDakEIcw==","summary":[{"type":"summary_text","text":"**Planning focused acceptance tests**"},{"type":"summary_text","text":"**Detailing ready selection and error path tests**"}]},{"id":"rs_02481840ef3d3be4016a5897d796908198a4557f28be3aa834","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJfhUmb9DhKapoV5FJGodEvwptN5PdGv922H4Ivs875bZZd6rbboG6lRTit9EzmFTD6Epl4KLf0v8YaTGTi0YKPGkaF2QJ-g313zTTaOCQEPVpTBTAlT-9EmXKQPFf1xuthFk8OqeNI2-cdh-nvE_Wa0iOnrXxniyaXW-3zW8qLMGG_DV2wYjHrY_FVR_8jmze8847Up5KGG1r6a2e8rZWGZe5Ytoejc_fg6j_9hK-84C_NXLhJ0Bn6SHJ9ZhqjO5zqnGb_V6WaY8Lo8tiZ-Bip2Kd6OYp-p5iB3R76op3M1e62rUcte6F2WKbcXwUCRAS0S-Vl_2aXcKR0VCu9n_JrBh5vhFfcMfdYb-f5ygxpudeU4xVpe7tel5mCAtdeO-OMYbzbYm6bfYRtrxinPgLtOuPUm6Ue8nBHLaup_7FD-uWGOv5UKBVHWkEHkfonoaceycSMOlh_2lOzPOzcA78plV5K_hM-GigMvMytrO42sJIMgB_nWQeaht_I9erpZ7l1f9wB7-qUadpOcaLEI0HmgsDa7Cw2OG_afJ4C5xGKseK3U_Lt5lypiF-7L_RaKPM6qxDXpJLUNHjy902vn9wWfMTWN7YiNLzyfrh5X-43vzoj-gQAN26YdbZMZNtR2LpU7k9sd3dkHoPuVnV20pwZNfGxVwhW6kg60zpA5A5eZjW1NQ6SEmqUeLdOBfMwv4uCFUpLj-h81_QvhCWi2A5VHFp6cxrR97yGnbgviwdOppFHU9O-irojDu8_tpvF4AbxCmv6ioqGzKcMPWxTCmnK6xJ46Hv0X2GFemZh2ciwnrBSzojUcmkQxdo0vlBJm61KHSSelXVkDlskc5n-pD29_dE8hR4JGyU2dXIV0B2M1Pku0bjNMyNlJbVaP3q2xhSZPjERT7LR6fUjfYJEHsyUI9ChRaO8MDPaOjRBn6MWMpL-RYcnOLzhM7CPCv85qpQi840q8U5a7kOssAQHdBphiWKhmquwmaksxdvuwj-izZHUnVNRMTI6RKW9LioLE7fJygXyVqqF8zuQ9eez9DkN6W6LJ5XooRSE5DRUVukO7mP1f_IYIFidhxbrkNfuGdcWjqsbnoe9BH7NPMFSy1whN5e1scgBQlmsHZ-WMdbapnERvmbTWPi5C2lXfEp0ulZecisXKfuoTN-NJeaUJQ3dKTlMHP5ymeNqnxcNBFr3f3x8riVV8xJlfQr7Eys4syAv0urEIZdS8cvXAV126G1gU7TkrxKUfto8OoKiagP4queX-oZkqoeAEkjelRJYAHfRnnKSRUvMtsat2b8o63Rs_kI92Rer6KIyk43Snqkkn_tzdprAbKCwlI7t4OXCFxYE3eefFQbG9-fzSTlf1D8-hqWmqJaf_Qcuz8c6bRUasWz7STwsXDcCyRkdYVnSZbbAWOpQwZbmNqigPw8R6QRkKq-Hubv0Em5s3--OGO3fkFF7NRY7CHkaiZYVmplqUB6OrN3yxj5TLcB1hhUH5EiZHuls75AKmsMnD5oc1MUQQDr4IXw-DT_ygWij0nrPsWRzW7BZDpn1sNghR6zRjGEp-ltxXcFIR8QYcw6yzXtPphR0xCPif9eEWZu39P6Klze4l8vUnTmGgcQ93WczYDZtf4WZWCEhyJFc1YRAVeMqjV1k35-bEBXUdB4jSE1KHr_51cfoVa2qw22Swl88HGbY2_fBct8qkkQNC2TcNS995lDGt6x4sQQQL-ZobbZM1s9n2OwYowl1VYZW7wps2OgTSRO9ziDv6ej7PzLqxxZJMVicK0Kea6SJKn8CJWv5364rEvKHufN_SE8wXs5IedIY9ejn2d0mf7qdhDskFDxNJCfbU63q9YMPx4zBD3TbkApWjhD8rZ4WiUzsD85fGl1YjDkjRIBPHy5rKakefVZc93NpIzBTTTEhoQ0YdGnnLta4wpK-n-TfN7ownbu205MXYxTY37WodQU4aegQwnnXPIU40rZWdi60qhTQ7MiVHcQ_9yBm7VXjTaDuN8Y_s_SWCDK9wYlqGPnAa_8eYh2NH6xzWskB82mUq4xv53dMl6zoDw66M-sjqQIYFOSpJBaDj3LiiIgzhezDxYqbNQyPkhPgy9Y6PwyAUsLHWRUaX_REFqRPxFgp-14_1IVdAn_RyszIbLJ60OzCNnQgSwtbug-OPI0Simf-DtPMqonMWSZMfhaYOC3MIbEY0YuX5X2qYaXsufvmI9yMszlMOJqvIr9CEwPMO_Tp71zRFGfevUvuGAy3VH85k0E__S-AWChmBJe7v-hwr7x3gW15212K-0AoPlzNGO5RU1qowK1sK4YK3_4HoH7NlY7pLt3emyP3Y4YJgtXVKo176W3SAbbFrTV7Qwp34O0E8O13GHPuhrf6zn1tkWt-m-PtOzjz9TzzLQNHipLAC_GSH8BJBPvd1YGMyAJr9DWcdNq58V3gEqv4XXVaB4a8_FmggEQFUUE8FgnnlG8QKjX4w-JOB0NQPg1BGBM05RZ5R2G7ko7L7qG9k49y8cghW2LVroGOTuBudTkO2YevLFxz6X-rA9P3UrWHwv7vYEEcegrQ0dgMbCE4Kzz9jP0N2uz2pwCgijvl6cd93BTfhog3lvUG5rJ6hYpkX3uwfF__FFKetPVm3x2jiNYlk12bqCY-2c0w2oinlqYgnzoRN3v1oI-RkBbWHaiGD3bF5B86hsImSryTrbDpnc6DEszMzn_YGQuxhssx-UfvfKa-SCLPOHa-kU_4TQb54UbsnGQ9xU6u919O49yp_Yan9J4nEyV-JV7v8iDpmVIOdaMt_qopLrM6wvc4tvxSiDtiDuDY_BEtBCcOkiHaLVAk5XNpzxMViSwpwyXhpc39rvg9jDL10wvdCzX7-k_3oeU0GrsbDPbvFvjnwI5qRw4QXBZaADJH1z41t3fvluut9nBysPQDj_cNZ1T9cd25ykrk5N5oviyFjX3oVNBGy8EgBfgguSUfWYXXhsS3_nyQdAnTo-zAsdJrbZCt2qCuaXlt_wOCCzyJbbKiuJkzKjdoHFhorHUkz_91MO2n5FFAN2eaUkGS0x0Xi9-WGSKL8e13MY-yVzGEmMrdKYz-b0yNLYFY66NFljDFzBnqFmoXwfSvg5JJ1kgcR8bz8863KdtSiKR2gjb4rpdtVXy2Fn6gyQdYBsoe-fGJeCBn03sJaA2OKuMEl43izm7nDThPpdjBKZLdhVjHoZG9fyLLlP3ZcR2OpGZkJVqmrvz6X73d9KaTzueSbe9X33ZQv1rj4JTFt0MDxQYPbDKXif--5aM91mxL5VLjENqVc2dZ5urSyO8JLOcsSVlme0g3rDpyEl77ZjxodCaB53_l2aSbm9TVRdoSwnKExmzgKFbswNjWQ1AIuRrl13w5JuQLtE32jJXPWZjJPxM5IVyTOD2apm6OYo9fcaH2jPmDATwfmIjnL7vRyNJY6Xt0vIGKMhgQxG_HsEWLiyIHCNaJMf5GkUzcMQ5UKtIr4YMNx1RuVVKqF0PorKhXIVTuebM9Ss9GFarxa_kFUZGu1OXGMWjH2M2CQHeNHbKZ5KPfgvKL-ohRA0m4i_kqfliXOs_NWzhlGxtgCxTCB1vZCFQS_Gc2VLEdqmnTUZ3-uk7w2wHbWWMjEuqIB7jPpVo2TVNE5WBPUR_TYshOY2gYs4blcEsJvqJI2W3yu7wf9LCZtjWuULfy41Hy_uWS1VpTAV_i80y2vou0BQ8_qBr7dN_v-07nZ2PWR6dauVNSdSCesmfsCG3VbTaT7I8XKjRdmK_ryBzarZTvXVjZeMRIDPKtUgVbKpLo3OFxFFjcXidd9nivdjUjoJnTwta4ptlN8oHjvMjDvfIqBgOlAqstg53G4r9Sea_2XIKQQw5VEs0XZxoxc_lXtGdatf2woILjQgivrEwi9yX9VOCMFskpt7DF_aYSRLHnjvllg-48tvLAC3g2-se4dPXWIHedliSCphfEg3u_6XaFBU_iHp0RevKQdihEIiCdjIAb-QV3chyRW2GDP332z7w1hhVxQrrMa0sGwKAoTkYHg8HEMdxJBuxB1zLD8gE7hJpIoWoUZYXBNh-J1JOimXMfDV-wuFfW4gpWVy6nSwWHidZzTyzdnXDOjg0un898xU3vH6dWamJwDfsHGOE6YDxjjW6XjLk392LJjjVW9tcRPdRSQay4WdEny3rpXqpIfM7Dly7xlGcdSsEwswmuVg0uNbGwd4Z6XqT0-l3E=","summary":[{"type":"summary_text","text":"**Refining subnet and checkpoint patterns**"},{"type":"summary_text","text":"**Designing cancellation and failure recovery tests**"}]},{"id":"rs_02481840ef3d3be4016a5897e107fc819884789aba06463005","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJfl0NXrpYbAhN-0QZSteG8BsyrbQzsQ-i_E6RDtZL6E-WxpR0iHRIlPQvtFGpxM4Q__hNSb6EpEvxRTGLXS-1T72OmcsXS8e1-ExZWx_2L1OEaCppQ54OtW7kLLfO0AvG2P-Ohi4YmYewXKlE9N45v2epb91hqTzoNam-LuMjKf-Qb6J-n55gim6EiMftITHWO1Udi4KeggOLd2h58LmoaEIOJVWLou9cRr8ZyojuZu4jrvCQiDwvCCS4yL5ja03kkg9Lt6stIswOc0nzO_YpuoHGu43vlZNchjLpcgb0oZXrVhJ9BAm6Q0pRiFspJ78W1fh8lSrYk9WXIPWkpmI050JW8Tz1ris4I2MbMLpDjfkkIgCuguBOgr3Vj_0fQ6T4osD2sjNHP2WR-bwYLb8LhHeXQlp0M-nRrJcgUSZQyGaH1wbDh-n3QlWwcdDcSRm6FtBJpnQNGvceDZmqXR_N2lSdd5ujNoYOf6-CiF776Bs1RG9ZCnPvboypIS8jf0kEbOBvrFuWNHV9z_ZYMC1Ud2DMlh6GdnviJ89JVsSSaartxpVTy1qkAU_Mr6jPLtDeF9SU-UnDJ2hLbPxQb1RSW2zJJV4Wx1kUU5LMv1UbpVOpfMu3DlUB7cGSWoVUED6gjSsiMKaV__jYbetC7U--OeNE0AVSenSh-175D6rH96kBy0btylZI4fSwfHeShkH_ECValj0Y-iXGZrEhGR1-xLkBwywNs-RJ9Y3TPVCIm-virj7JHwa-4tSaR0KYurYHkkIH-asr_magDF2mNe_vw8kiVipyMa4RtqHeK2Rz5fiP_jbAGeUwGMmrsm1unhrKtKOlWyCB9zS3fj3FvQFvfoUSjkhZSjKfpkF0kj7lFJKVznqPEPYDh1PS69jS4OWlXhQMJqnSKv-2kNBzLOuSb-1OmZJEMjcOqGH0WiEfzc8Gc9Utp7CbXz3UbUScWxavms9St5b0FobrGY8NS_vuD7R9aKdmTWum6CcifhpeuofxywPsTZ4uUwmNkhzNKJLxvTTmypO-1AUm7_f4vbBX_w6bMFjiyrED4RNheMd6b2x2Y9JgxtaAE1FpDhgk2rKKFUwBsPN4fQchqXH0JK0IuPbC9eenpASF9maPfSgn-WbKbFJ3TJOo8F1OCERx3V61tZeWEoz5ie6xCwvxBEqpBZG2WzWz2QrkDvrVBvITB1KpDG5-3FyohrikyDASY2bFmDpFBCw5vaQtbgEavzQ6wDF5ieh_j8mrrRdnIcEoTBor_mfdfj1va17Qpx7ifJ1B0pPTO7ImPrza7Mh4d6CjRxLs5IS8vQHI-MfAQS5WuoLt6Pe3VfgO_mhWkiWCZY6A52QJDVtJkl1qy6usaGHGKrT3H51g0lTYBaG0AobDoXzxzMK5GvPQz1B_1YvPeGVQJ4U_QjxJmfv1E877mryn6blC2oWUctlFuYMQ9UPBrUB4BYmM6tW2vmhb-o0fQT8C0Z5X-Fs1O9wvpvy4TPZjfULCed8qDZak9sWdGnLufh_rnV_a-j5dCZNeOODUL3_fvcVG6iGQOxvFOAtQrZWwPJcbTHU-AoqmF8ElFNXSdtGuxVQQoCpn63wl9drVDFJz5c80DY3VOkWLscrjyAphRG-S3xWHv0-JKqkMsPzLMW773xjAocuEDMydC1QSH4Ld0e-wdzyUXraMOc6rYC4DfVFEOX36xQ64a_Fo5sCYN5GzRJDW-69ZMfIOgwOHkUw33b29wzbU709GltKdAqPoob3PjlYBIm-aZI0LbmEK81NHnHmTBZ1Tq4Ss4HUmlabZEdgoRJEvjiz1Box0N3Q1b5cPU0Xhp1l8My2dFNXtLfrit_8U_XJqmGK3K3UzcO3a0PtH6RLUAD1TBAuYsH5CQaYjbjNJgpARjdYClEJQXOkqsMaTP11AlmC_sQLw5kJplsiSsJWX_BV1Wry8oDLhu8-WZZnPHBodFPzzo5aV5X_dkn9-XYx9yKNrfClfA7ekSAKmeWaJ_0Bc6L7GdAefeptaLFhTTlfEcI985Wazow7ZFCztfmAHEM_EyUw3ZbnGBpqJl7WcSGHeFKhd3mU5LavA1vRa23VmxlGjL8COXWkhbBmIOMD9s2QGkxLT2ur0iiz5PIAr3iPCytz70_Z2GUudF_gmrBGoB8bVdTZw1nhGUmXDzs1uuSd8Vtz7yjsdF2HCbgYp2AF9A1MiUpLS8xQGPnpAE2X_F0i1MgWHS9IbyqzvNmbc6sYozURTk3BwjsBxo7xQWYprDGTjgHDbwkJlTSr15yFKdHyuyPxTkfKVT-rHYb_SoNdeFMfaRF3sI37k51i_5vr49gNRqz0ptp0q5bjGUKAHv8I8xYVxgF7nhhQporiSfWRCp_JmYo3-mKzjOqxjh2xnSaOCn3OhRIb74uH6gq5FYcWkQCABdsRTinC2Ygim2nwIlUhNFaIjcD3fkX2TJatteQ3aoY3nJEcQ==","summary":[{"type":"summary_text","text":"**Verifying multi-target send statuses**"},{"type":"summary_text","text":"**Identifying production bugs and fixing prompt regex**"}]},{"id":"fc_02481840ef3d3be4016a5897e5ef048198b217d9b6c02c01b9","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating targeted hint patterns\",\"pattern\":\"spt\\\\\\\\s\\\\+\\\\)\\\\?subnet|checkpoint\\\\\\\\b\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_Qhb0jmslv4FrJqoQ469yUXNa","name":"grep"}]},"duration":29443.05200000014,"ttft":4900.331199999899,"contextSnapshot":{"promptTokens":191543,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Qhb0jmslv4FrJqoQ469yUXNa|fc_02481840ef3d3be4016a5897e5ef048198b217d9b6c02c01b9","toolName":"grep","startedAt":"2026-07-16T08:35:50.797Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Locating targeted hint patterns"},"id":"2edd2052","parentId":"34cc4e1b","timestamp":"2026-07-16T08:35:50.797Z"}
{"type":"message","id":"4742e480","parentId":"2edd2052","timestamp":"2026-07-16T08:35:50.803Z","message":{"role":"toolResult","toolCallId":"call_Qhb0jmslv4FrJqoQ469yUXNa|fc_02481840ef3d3be4016a5897e5ef048198b217d9b6c02c01b9","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#C069]\n 290:\tif (\n*291:\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n 292:\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n 293:\t) {\n 294:\t\thints.push(\"Run `spt how-to subnet` for private-network onboarding.\");\n...\n 296:\tif (\n*297:\t\t/\\bcheckpoint\\b/i.test(text) ||\n 298:\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n 299:\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n 300:\t) {"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":2,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":2}],"truncated":false,"displayContent":" 290│\tif (\n*291│\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n 292│\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n 293│\t) {\n 294│\t\thints.push(\"Run `spt how-to subnet` for private-network onboarding.\");\n    │...\n 296│\tif (\n*297│\t\t/\\bcheckpoint\\b/i.test(text) ||\n 298│\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n 299│\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n 300│\t) {"},"isError":false,"timestamp":1784190950803}}
{"type":"message","id":"ab0589d6","parentId":"4742e480","timestamp":"2026-07-16T08:35:57.342Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_6q5Dz6dcLtzMTASKQGSND3rI|ctc_0f813cc3e220f1f0016a5897e9a46c8199bb27fda321c9e705","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#C069]\nSWAP 291.=292:\n+\t\t/\\bspt\\s+(?:how-to\\s+)?subnet\\b/i.test(text) ||\n+\t\t/\\bsubnet\\s+(?:status|create|join|code|onboarding|setup)\\b/i.test(text) ||\n+\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\nSWAP 297.=297:\n+\t\t/(?:^|\\s)\\/checkpoint(?:\\s|$)/i.test(text) ||\n+\t\t/\\b(?:make|take|create|use|run|perform|need|want)\\b.{0,20}\\bcheckpoint\\b/i.test(text) ||\n+\t\t/\\bcheckpoint\\s+(?:my|this|the)\\s+(?:context|session|work)\\b/i.test(text) ||\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2125,"output":228,"cacheRead":190976,"cacheWrite":0,"totalTokens":193329,"reasoningTokens":8,"cost":{"input":0.010625,"output":0.006840000000000001,"cacheRead":0.09548799999999999,"cacheWrite":0,"total":0.112953}},"stopReason":"toolUse","timestamp":1784190950816,"responseId":"resp_0f813cc3e220f1f0016a5897e764ec81999b283cc0182d9102","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0f813cc3e220f1f0016a5897e8e7dc8199aed2849bab95bd4e","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJfpjUdSrezpkxNAhrr_UuC7613wv7bKpHIvi3IQ_kW_9-SnbV0xhUj-VaK6VTWB2-onPfngcv-Uqow1eRNx_O_4XGwUMELCo_4VkLzi5LpnlLTu_RS7k8dsPFTz5gix0IfJ-x6daICT38V4Sn8mDGjNNenD5aZs1-pyk9fTL2jWqawr52vuZekWcjf7euU4Dw1beODymrvcetTqtbddO6GdgqLrw5hAb8AydW5zEu1yPaET9FrMlasJxkOqt4wTaOcB6sy0EnlWDSEzuZUue7d90c6NjS9BXRXUB6qL-O0BKw1iTMbeMnpvTnNVEu9VgTuyRnfClCNd3TvoJ4MVp8DC2nO0cJskdJreK7CutKOw5GGIiQ9IpPwrMJpa_g4iTHMGQn37FMVIU_9gg9YJVZd-K6l8BSCuOMtEYohuNVgnlnf1olNdu5GkhQ8f3ZFhKm8IbuRFg3f9x839CFeJoutCBlAc2euJvi4rJBR6Trj5Q4V63_hV26PpHihSgXKJLRf2aBVXVa1vBeVY6xy-9Vn0OlXNndHnz8jQ6LVF9C-nRRY8s7yyOwMAytuOdn5RiDXW34-ct3m_41epn6qgXR7ff3eLZhbPrHOUWqUtCfQkNZE_M72HVELqPQyLqk9bYmvhWrok9nsSp8jU3jFDKMtBrKIsDFepVsTLoq3ZTyvXNz95ZfW6xlRAzrFTDiN_GLytHZDg3GjQsDBmiwOBCgpmi_wp5Xz0203i1DK24-7Z-uqbkR86EPvKKF7EdLiseBXRee9PWu3arNebW39cEQb38b0tUcbONpqo4Ao4GTJDiU2yFwQFxkaA6k7TImpqGtgushEvE78Iebb5ZyiZRzctRXIEEOVtdgDpMjRCoBL5e21LLytJ_HFU9bj9aOuzcI2Mi-N5TunCfdD-e7ubHD7G_ndymKJOvL7BBRXNb1OsoZ3F1gKNJCmGvzZebZUyosXT","summary":[]},{"id":"ctc_0f813cc3e220f1f0016a5897e9a46c8199bb27fda321c9e705","type":"custom_tool_call","status":"completed","call_id":"call_6q5Dz6dcLtzMTASKQGSND3rI","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#C069]\nSWAP 291.=292:\n+\t\t/\\bspt\\s+(?:how-to\\s+)?subnet\\b/i.test(text) ||\n+\t\t/\\bsubnet\\s+(?:status|create|join|code|onboarding|setup)\\b/i.test(text) ||\n+\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\nSWAP 297.=297:\n+\t\t/(?:^|\\s)\\/checkpoint(?:\\s|$)/i.test(text) ||\n+\t\t/\\b(?:make|take|create|use|run|perform|need|want)\\b.{0,20}\\bcheckpoint\\b/i.test(text) ||\n+\t\t/\\bcheckpoint\\s+(?:my|this|the)\\s+(?:context|session|work)\\b/i.test(text) ||\n*** End Patch\n","name":"edit"}]},"duration":6525.881599999964,"ttft":2070.88720000023,"contextSnapshot":{"promptTokens":193101,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_6q5Dz6dcLtzMTASKQGSND3rI|ctc_0f813cc3e220f1f0016a5897e9a46c8199bb27fda321c9e705","toolName":"edit","startedAt":"2026-07-16T08:35:57.343Z"},"id":"2fa9d15d","parentId":"ab0589d6","timestamp":"2026-07-16T08:35:57.343Z"}
{"type":"message","id":"55c9ce7b","parentId":"2fa9d15d","timestamp":"2026-07-16T08:35:57.375Z","message":{"role":"toolResult","toolCallId":"call_6q5Dz6dcLtzMTASKQGSND3rI|ctc_0f813cc3e220f1f0016a5897e9a46c8199bb27fda321c9e705","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#F43A]\n282:\tif (\n\n287:\t) {\n\n289:\t}\n290:\tif (\n291:\t\t/\\bspt\\s+(?:how-to\\s+)?subnet\\b/i.test(text) ||\n292:\t\t/\\bsubnet\\s+(?:status|create|join|code|onboarding|setup)\\b/i.test(text) ||\n293:\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n294:\t) {\n296:\t}\n297:\tif (\n298:\t\t/(?:^|\\s)\\/checkpoint(?:\\s|$)/i.test(text) ||\n299:\t\t/\\b(?:make|take|create|use|run|perform|need|want)\\b.{0,20}\\bcheckpoint\\b/i.test(text) ||\n300:\t\t/\\bcheckpoint\\s+(?:my|this|the)\\s+(?:context|session|work)\\b/i.test(text) ||\n301:\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n302:\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n303:\t) {\n\n305:\t}"}],"details":{"diff":" 282|\tif (\n\n 287|\t) {\n\n 289|\t}\n 290|\tif (\n-291|\t\t/\\b(?:spt\\s+)?subnet\\b/i.test(text) ||\n+291|\t\t/\\bspt\\s+(?:how-to\\s+)?subnet\\b/i.test(text) ||\n+292|\t\t/\\bsubnet\\s+(?:status|create|join|code|onboarding|setup)\\b/i.test(text) ||\n 292|\t\t/\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)\n 293|\t) {\n 295|\t}\n 296|\tif (\n-297|\t\t/\\bcheckpoint\\b/i.test(text) ||\n+298|\t\t/(?:^|\\s)\\/checkpoint(?:\\s|$)/i.test(text) ||\n+299|\t\t/\\b(?:make|take|create|use|run|perform|need|want)\\b.{0,20}\\bcheckpoint\\b/i.test(text) ||\n+300|\t\t/\\bcheckpoint\\s+(?:my|this|the)\\s+(?:context|session|work)\\b/i.test(text) ||\n 298|\t\t/\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||\n 299|\t\t/\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)\n 300|\t) {\n\n 302|\t}","firstChangedLine":291,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784190957375}}
{"type":"message","id":"c8c47140","parentId":"55c9ce7b","timestamp":"2026-07-16T08:36:01.246Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning test insertion before runner**"},{"type":"toolCall","id":"call_W2bZ6yr2k1H1Wjj0yL7emj0v|fc_0b54382fd9f289e8016a5897f0cb7c81989bc09cbac9f58673","name":"read","arguments":{"i":"Reading updated test tail","path":"tests/omp-extension.mjs","selector":"1370-1460"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1637,"output":96,"cacheRead":192000,"cacheWrite":0,"totalTokens":193733,"reasoningTokens":57,"cost":{"input":0.008185000000000001,"output":0.00288,"cacheRead":0.096,"cacheWrite":0,"total":0.10706500000000001}},"stopReason":"toolUse","timestamp":1784190957389,"responseId":"resp_0b54382fd9f289e8016a5897edbaf8819893a6becfed5c298e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0b54382fd9f289e8016a5897ef58f8819892012b1675fcc785","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJfw3pL_7y3ccHk4zVpu4oL1SL8JbFPGciqiQOHcGmdTlvsWMpjFWrsaH9L3uufM1585dEd-nNpmfGWXH-ml-nt_LsiKwkl_S7ctekraqWDBlRXMaWPh3sDJZXkXUq05BiCCyo46xjUr_PTqEdOXV2z2UqvbVuQNCfesrbpH3xXZG52i_cxgo5sZaYDxRclN9tcA4TRLqkdHabwiS1AG0faFR6sTWSdwVxa33bE3SSGWT2l1T9bbjtrdi4JpFztBTnMJ8Rki4lfocPAVTNN2fQB8Hus6v0AZZHfISTXWq0NtTOfBaOvlfu5umgNSD4ab6vE116RRT8eoCrJDYfM8Y9LeQ_RAq8NlV83GqT2SG4pv0Q8ivJjFE3ELW15dcOOEduCM974iDNNhQA4PHo6jytfm-_ThyXVjQt-dErJ5TJxy3BpHKq5kwmtFtPQ-kB2gw0bUAgEOXULYxMD2QeinAogNdMICzuuvurU8YFaoqjTdQS-At61GjdX7l4ZXyF6p-eIOyVn01f9PCSd8Q5EvKCyIceX0n4CedFU3LEfE2qyY483Hq05I_NmGScFgq0yQnzQhYl5ncty7zThFwG7EzXKiAHFfozE-4Qg7iNHsofpeuXxvpW7EfcSjGZs0XppLgMd0i4uXlBstYCa2wHOGHwpXfEVNcP9JD_tP-663l9rTNJjJEzyF9H3RsjoQ7gfZ56ufhqCh8oBlI85DRGV1IJJKFOdVTJ4lw2ZBq7lv6V7FQGZFCZnRF5I87gNwTPuElihXjS24u1xxxAQNLE1LSV46R_-J8QFANIb1Yh847nXDY-vkuKNlEdIAMqkbigabXReWek_UN72Jtwfe0Kw_foKUOboC8yZUiSQSgrNiUT5inieWUfANDTna4DuNuQGen9Raylltx1yw3xNenIPRs_qt0N_DBMf4Zo7M57kpJETJcvtet2zH7WRCUQJBm6mWz4_7ymosD0D-x4OY605dAWc__OzDFNZYVkdQarcr-akRNiSjnyhoIIKs0rfynXV_pDPxvwEeC80IFVzP5Gj8gl5ogho4upSUymJCFaYNudEXz1Htm_joc94T3m07KltWqQWggHcChOoOrqnEKhnVeCuLWcmExVyF2VlKKy_HIm34wwJiEKDR8dTd6P1rwjnTxpAEkSbJ5dHI5PckExQpE-85ujUHOVcYHXqywfJRSXMTVt3t75cdOiKTo34leTkvisXQN0qaMS7C7Gq4qIS1K2PUVHnVgwUL1X9k951yCvQj5MwSRwXeNe8UUoTo0owSk8Ku","summary":[{"type":"summary_text","text":"**Planning test insertion before runner**"}]},{"id":"fc_0b54382fd9f289e8016a5897f0cb7c81989bc09cbac9f58673","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading updated test tail\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1370-1460\"}","call_id":"call_W2bZ6yr2k1H1Wjj0yL7emj0v","name":"read"}]},"duration":3854.9263000003994,"ttft":1939.563599999994,"contextSnapshot":{"promptTokens":193637,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_W2bZ6yr2k1H1Wjj0yL7emj0v|fc_0b54382fd9f289e8016a5897f0cb7c81989bc09cbac9f58673","toolName":"read","startedAt":"2026-07-16T08:36:01.247Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading updated test tail"},"id":"846955ad","parentId":"c8c47140","timestamp":"2026-07-16T08:36:01.247Z"}
{"type":"message","id":"cf4048b0","parentId":"846955ad","timestamp":"2026-07-16T08:36:01.259Z","message":{"role":"toolResult","toolCallId":"call_W2bZ6yr2k1H1Wjj0yL7emj0v|fc_0b54382fd9f289e8016a5897f0cb7c81989bc09cbac9f58673","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#3EE9]\n1227:async function testShutdownFallbackStaysBelowHostCap() {\n…\n1369:\tassert.deepEqual(\n1370:\t\tcommandCalls(inFlightHarness, \"send\").map((call) => call.args[1]),\n1371:\t\t[\"in-flight\", \"in-flight\"],\n1372:\t);\n1373:\tassert.match(commandCalls(inFlightHarness, \"send\")[1].input, /OMP session shut down/);\n1374:\tassert.equal(\n1375:\t\tinFlightHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\n1376:\t\t1,\n1377:\t);\n1378:\tassert.equal(inFlightHarness.shutdowns, 0);\n1379:\tassert.deepEqual(inFlightHarness.clock.delays(), []);\n1380:\tinFlightOutcome.resolve();\n1381:\tawait flush();\n1382:\tassert.equal(commandCalls(inFlightHarness, \"send\").length, 2);\n1383:\n1384:\tconst hardCapHarness = createHarness({\n1385:\t\tshutdownBudgetMs: 1_800,\n1386:\t\tshutdownCommandTimeoutMs: 5_000,\n1387:\t\tkillForceMs: 100,\n1388:\t\tkillGraceMs: 100,\n1389:\t\tonRun(call) {\n1390:\t\t\tif (call.args[0] === \"send\") return never;\n1391:\t\t},\n1392:\t});\n1393:\tawait hardCapHarness.emit(\"session_start\");\n1394:\tawait hardCapHarness.emit(\"agent_start\");\n1395:\thardCapHarness.children[0].stdout.emit(\n1396:\t\t\"data\",\n1397:\t\t'<EVENT type=\"msg\" from=\"hard-cap\">work</EVENT>',\n1398:\t);\n1399:\tawait flush();\n1400:\tconst hardCappedShutdown = hardCapHarness.emit(\"session_shutdown\");\n1401:\tawait flush();\n1402:\tassert.deepEqual(\n1403:\t\thardCapHarness.clock.delays().sort((a, b) => a - b),\n1404:\t\t[600, 1_800],\n1405:\t);\n1406:\tawait hardCapHarness.clock.runNext(600);\n1407:\tawait hardCappedShutdown;\n1408:\tassert.equal(\n1409:\t\thardCapHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\n1410:\t\t1,\n1411:\t\t\"the phase clamp must reserve time for one session-end attempt\",\n1412:\t);\n1413:\tassert.ok(\n1414:\t\t!hardCapHarness.errors.some(({ message }) =>\n1415:\t\t\tmessage.includes(\"bounded shutdown expired\"),\n1416:\t\t),\n1417:\t);\n1418:\tassert.equal(hardCapHarness.children[0].kills, 1);\n1419:\tassert.deepEqual(hardCapHarness.clock.delays(), []);\n1420:}\n1421:\n1422:await testParsingAndReplies();\n1423:await testRunSptRejectsStdinErrorsAndHungCommands();\n1424:await testLifecycleCustodyAndContext();\n1425:await testDeferredBindLifecycleSerialization();\n1426:await testOutcomeSendRetriesAndExhaustion();\n1427:await testSubmissionFailureAdvancesQueue();\n1428:await testFailedIdleRecoveryFailsClosed();\n1429:await testListenerRestartExhaustion();\n1430:await testListenerStableIntervalResetsRetries();\n1431:await testFatalTeardownAwaitsInFlightOutcome();\n1432:await testSessionEndRetriesAfterTransientFailure();\n1433:await testHumanBusyFailureFailsClosed();\n1434:await testShutdownReapsAndFailsQueuedCustody();\n1435:await testListenerTerminationEscalatesAndReaps();\n1436:await testProtocolCorruptionFailsClosed();\n1437:await testInboundQueueOverflowReturnsAcceptedCustody();\n1438:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n1439:await testShutdownFallbackStaysBelowHostCap();\n1440:\n1441:console.log(\"OMP-EXTENSION OK\");\n1442:"}],"details":{"displayContent":{"text":"async function testShutdownFallbackStaysBelowHostCap() {\n…\n\tassert.deepEqual(\r\n\t\tcommandCalls(inFlightHarness, \"send\").map((call) => call.args[1]),\r\n\t\t[\"in-flight\", \"in-flight\"],\r\n\t);\r\n\tassert.match(commandCalls(inFlightHarness, \"send\")[1].input, /OMP session shut down/);\r\n\tassert.equal(\r\n\t\tinFlightHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t1,\r\n\t);\r\n\tassert.equal(inFlightHarness.shutdowns, 0);\r\n\tassert.deepEqual(inFlightHarness.clock.delays(), []);\r\n\tinFlightOutcome.resolve();\r\n\tawait flush();\r\n\tassert.equal(commandCalls(inFlightHarness, \"send\").length, 2);\r\n\r\n\tconst hardCapHarness = createHarness({\r\n\t\tshutdownBudgetMs: 1_800,\r\n\t\tshutdownCommandTimeoutMs: 5_000,\r\n\t\tkillForceMs: 100,\r\n\t\tkillGraceMs: 100,\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\") return never;\r\n\t\t},\r\n\t});\r\n\tawait hardCapHarness.emit(\"session_start\");\r\n\tawait hardCapHarness.emit(\"agent_start\");\r\n\thardCapHarness.children[0].stdout.emit(\r\n\t\t\"data\",\r\n\t\t'<EVENT type=\"msg\" from=\"hard-cap\">work</EVENT>',\r\n\t);\r\n\tawait flush();\r\n\tconst hardCappedShutdown = hardCapHarness.emit(\"session_shutdown\");\r\n\tawait flush();\r\n\tassert.deepEqual(\r\n\t\thardCapHarness.clock.delays().sort((a, b) => a - b),\r\n\t\t[600, 1_800],\r\n\t);\r\n\tawait hardCapHarness.clock.runNext(600);\r\n\tawait hardCappedShutdown;\r\n\tassert.equal(\r\n\t\thardCapHarness.calls.filter((call) => call.args[3] === \"session-end\").length,\r\n\t\t1,\r\n\t\t\"the phase clamp must reserve time for one session-end attempt\",\r\n\t);\r\n\tassert.ok(\r\n\t\t!hardCapHarness.errors.some(({ message }) =>\r\n\t\t\tmessage.includes(\"bounded shutdown expired\"),\r\n\t\t),\r\n\t);\r\n\tassert.equal(hardCapHarness.children[0].kills, 1);\r\n\tassert.deepEqual(hardCapHarness.clock.delays(), []);\r\n}\r\n\r\nawait testParsingAndReplies();\r\nawait testRunSptRejectsStdinErrorsAndHungCommands();\r\nawait testLifecycleCustodyAndContext();\r\nawait testDeferredBindLifecycleSerialization();\r\nawait testOutcomeSendRetriesAndExhaustion();\r\nawait testSubmissionFailureAdvancesQueue();\r\nawait testFailedIdleRecoveryFailsClosed();\r\nawait testListenerRestartExhaustion();\r\nawait testListenerStableIntervalResetsRetries();\r\nawait testFatalTeardownAwaitsInFlightOutcome();\r\nawait testSessionEndRetriesAfterTransientFailure();\r\nawait testHumanBusyFailureFailsClosed();\r\nawait testShutdownReapsAndFailsQueuedCustody();\r\nawait testListenerTerminationEscalatesAndReaps();\r\nawait testProtocolCorruptionFailsClosed();\r\nawait testInboundQueueOverflowReturnsAcceptedCustody();\r\nawait testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\r\nawait testShutdownFallbackStaysBelowHostCap();\r\n\r\nconsole.log(\"OMP-EXTENSION OK\");\r\n","startLine":1227,"lineNumbers":[1227,null,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"}}},"isError":false,"timestamp":1784190961259}}
{"type":"message","id":"532b47ed","parentId":"cf4048b0","timestamp":"2026-07-16T08:37:56.139Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Inserting test helpers and verifying session behavior**\n\n**Refining onRun argument filtering and bind logic**\n\n**Updating startup argument handling and version probing**"},{"type":"thinking","thinking":"**Tracing agent shutdown sequence**\n\n**Differentiating shutdown event modes**\n\n**Testing argument completion fallback**"},{"type":"thinking","thinking":"**Adding comprehensive tests**"},{"type":"toolCall","id":"call_skhLfO53mQthFB8WP2EIwWGy|ctc_020671dfcc618bf6016a589809d9e4819b9cba3e688007e39a","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#3EE9]\nINS.PRE 1422:\n+// [unit->REQ-PARITY-READY-ACTIVATION]\n+// [unit->REQ-PARITY-LIVE-ACTIVATION]\n+async function testNativeActivationCommandsAndErrors() {\n+\tconst inert = createHarness({ id: null });\n+\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\n+\tassert.ok(inert.tools.has(\"spt_checkpoint\"));\n+\tawait inert.emit(\"session_start\");\n+\tassert.deepEqual(inert.calls, [], \"an ordinary OMP session must remain lifecycle-inert\");\n+\tassert.equal(\n+\t\tawait inert.emit(\"session_before_switch\", { reason: \"new\" }),\n+\t\tundefined,\n+\t\t\"an unbound extension must not block native session changes\",\n+\t);\n+\n+\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\n+\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");\n+\tassert.deepEqual(readyBind.args, [\n+\t\t\"api\",\n+\t\t\"--adapter\",\n+\t\t\"omp-spt\",\n+\t\t\"bind\",\n+\t\t\"ready-one\",\n+\t\t\"--set-session-id\",\n+\t\t\"session-1\",\n+\t\t\"--type\",\n+\t\t\"ready_agent\",\n+\t]);\n+\tassert.deepEqual(inert.children[0].args, [\n+\t\t\"api\",\n+\t\t\"--adapter\",\n+\t\t\"omp-spt\",\n+\t\t\"listen\",\n+\t\t\"ready-one\",\n+\t\t\"--session-id\",\n+\t\t\"session-1\",\n+\t]);\n+\tassert.ok(\n+\t\tinert.notifications.some(({ message, type }) =>\n+\t\t\ttype === \"info\" && message.includes(\"ready endpoint ready-one\"),\n+\t\t),\n+\t);\n+\tawait inert.commands.get(\"live\").handler(\"other-id\", inert.ctx);\n+\tassert.equal(inert.calls.filter((call) => call.args[3] === \"bind\").length, 1);\n+\tassert.ok(\n+\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\n+\t);\n+\tawait inert.emit(\"session_shutdown\");\n+\n+\tlet bindAttempts = 0;\n+\tconst retryable = createHarness({\n+\t\tid: null,\n+\t\tonRun(call) {\n+\t\t\tif (call.args[3] === \"bind\") {\n+\t\t\t\tbindAttempts += 1;\n+\t\t\t\tif (bindAttempts === 1) throw new Error(\"identity already active\");\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait retryable.emit(\"session_start\");\n+\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n+\tassert.equal(retryable.children.length, 0);\n+\tassert.equal(retryable.shutdowns, 0, \"a pre-token command error must keep ordinary OMP usable\");\n+\tassert.ok(\n+\t\tretryable.notifications.some(({ message }) => message.includes(\"identity already active\")),\n+\t);\n+\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n+\tassert.equal(retryable.children.length, 1, \"a corrected activation may retry after a bind error\");\n+\tassert.ok(\n+\t\tretryable.calls\n+\t\t\t.findLast((call) => call.args[3] === \"bind\")\n+\t\t\t.args.includes(\"live_agent\"),\n+\t);\n+\tawait retryable.emit(\"session_shutdown\");\n+\n+\tconst headless = createHarness({ id: null, hasUI: false });\n+\tawait headless.emit(\"session_start\");\n+\tawait headless.commands.get(\"ready\").handler(\"\", headless.ctx);\n+\tassert.deepEqual(headless.calls, []);\n+\tassert.ok(\n+\t\theadless.notifications.some(({ message }) => message.includes(\"requires an endpoint id\")),\n+\t\t\"ordinary activation must never guess an identity when native selection is unavailable\",\n+\t);\n+\tawait headless.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-READY-ACTIVATION]\n+async function testNativeActivationSelectionAndCompletion() {\n+\tconst harness = createHarness({\n+\t\tid: null,\n+\t\tselectResults: [\"ready-old\"],\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tlocal: [\n+\t\t\t\t\t\t{ id: \"ready-old\", state: \"ready_agent\", alive: false },\n+\t\t\t\t\t\t{ id: \"ready-busy\", state: \"ready_agent\", alive: true },\n+\t\t\t\t\t\t{ id: \"live-old\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tid: call.args[3],\n+\t\t\t\t\tadapter: \"omp-spt\",\n+\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+\t\t\t\t});\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\n+\tassert.deepEqual(harness.selections[0].values, [\n+\t\t\"ready-old\",\n+\t\t\"Create a new endpoint id\",\n+\t]);\n+\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], \"ready-old\");\n+\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\n+\t\t{ value: \"ready-old\", label: \"ready-old\" },\n+\t]);\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n+\t\t\"selection and activation must not start an agent-managed background poll\",\n+\t);\n+\tawait harness.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n+async function testExplicitLiveAutoResume() {\n+\tconst activity = {\n+\t\told: \"2026-07-10T00:00:00.000Z\",\n+\t\tnewest: \"2026-07-15T00:00:00.000Z\",\n+\t};\n+\tconst harness = createHarness({\n+\t\tid: null,\n+\t\tconfirmResults: [true],\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tlocal: [\n+\t\t\t\t\t\t{ id: \"old\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t\t{ id: \"newest\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t\t{ id: \"active\", state: \"live_agent\", alive: true },\n+\t\t\t\t\t\t{ id: \"foreign\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tid: call.args[3],\n+\t\t\t\t\tadapter: call.args[3] === \"foreign\" ? \"claude-spt\" : \"omp-spt\",\n+\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n+\t\t\t\tconst id = call.args[3];\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: activity[id], text: id } }] }],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tassert.deepEqual(harness.commands.get(\"live\").getArgumentCompletions(\"--\"), [\n+\t\t{ value: \"--auto\", label: \"--auto\" },\n+\t]);\n+\tawait harness.commands.get(\"live\").handler(\"--auto\", harness.ctx);\n+\tassert.match(harness.confirmations[0].message, /newest.*most recently active/s);\n+\tconst bind = harness.calls.find((call) => call.args[3] === \"bind\");\n+\tassert.equal(bind.args[4], \"newest\");\n+\tassert.ok(bind.args.includes(\"live_agent\"));\n+\tassert.ok(\n+\t\t!harness.calls.some(\n+\t\t\t(call) => call.args[2] === \"digest\" && [\"active\", \"foreign\"].includes(call.args[3]),\n+\t\t),\n+\t\t\"auto-resume must inspect only inactive compatible identities\",\n+\t);\n+\tawait harness.emit(\"session_shutdown\");\n+\n+\tconst declined = createHarness({\n+\t\tid: null,\n+\t\tconfirmResults: [false],\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tlocal: [{ id: \"prior\", state: \"live_agent\", alive: false }],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tid: \"prior\",\n+\t\t\t\t\tadapter: \"omp-spt\",\n+\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: \"2026-07-15T01:00:00.000Z\" } }] }],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait declined.emit(\"session_start\");\n+\tawait declined.commands.get(\"live\").handler(\"--auto\", declined.ctx);\n+\tassert.equal(declined.calls.filter((call) => call.args[3] === \"bind\").length, 0);\n+\tawait declined.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-STARTUP-BRIEF]\n+// [unit->REQ-PARITY-TARGETED-HINTS]\n+// [unit->REQ-PARITY-UPDATE-NOTICE]\n+async function testStartupBriefHintsAndUpdateNotices() {\n+\tconst harness = createHarness({\n+\t\tcheckUpdates: true,\n+\t\tfetchLatestAdapterVersion: async () => \"v0.3.0\",\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--version\") return \"spt 1.0.0\";\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tnotifs: [\n+\t\t\t\t\t\t{\n+\t\t\t\t\t\t\tfrom_id: \"spt-update\",\n+\t\t\t\t\t\t\tkind: \"consent\",\n+\t\t\t\t\t\t\tstate: \"seen:1\",\n+\t\t\t\t\t\t\thead: \"An spt-core update v1.2.0 is available.\",\n+\t\t\t\t\t\t},\n+\t\t\t\t\t\t{\n+\t\t\t\t\t\t\tfrom_id: \"spt-update\",\n+\t\t\t\t\t\t\tkind: \"consent\",\n+\t\t\t\t\t\t\tstate: \"dismissed\",\n+\t\t\t\t\t\t\thead: \"An spt-core update v9.0.0 is available.\",\n+\t\t\t\t\t\t},\n+\t\t\t\t\t],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") return \"0.2.1\";\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tconst first = await harness.emit(\"before_agent_start\", {\n+\t\tprompt:\n+\t\t\t\"Go live, show my endpoint identity, send a message to an agent, join two machines, and create a checkpoint.\",\n+\t\tsystemPrompt: [\"base\"],\n+\t});\n+\tassert.equal(first.systemPrompt[0], \"base\");\n+\tconst injected = first.systemPrompt.at(-1);\n+\tfor (const expected of [\n+\t\t\"spt whoami --json\",\n+\t\t\"spt endpoint list\",\n+\t\t\"spt how-to send\",\n+\t\t\"commune (checkpoint mode), signoff, and role\",\n+\t\t\"/ready\",\n+\t\t\"/live\",\n+\t\t\"spt how-to subnet\",\n+\t\t\"spt --version\",\n+\t\t\"spt adapter version omp-spt\",\n+\t\t\"spt update\",\n+\t\t\"Use extension-native `/live`\",\n+\t\t\"omp-spt v0.3.0 is available\",\n+\t\t\"spt adapter update omp-spt\",\n+\t\t\"spt-core v1.2.0 is available\",\n+\t]) {\n+\t\tassert.match(injected, new RegExp(expected.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\n+\t}\n+\tconst quiet = await harness.emit(\"before_agent_start\", {\n+\t\tprompt: \"Review live reload, identity matrices, message queues, subnet masks, and checkpoint files.\",\n+\t\tsystemPrompt: [\"base\"],\n+\t});\n+\tassert.equal(quiet, undefined, \"related technical nouns without clear SPT intent must not hint\");\n+\tawait harness.emit(\"session_shutdown\");\n+\n+\tconst unavailable = createHarness({\n+\t\tcheckUpdates: true,\n+\t\tfetchLatestAdapterVersion: async () => {\n+\t\t\tthrow new Error(\"network down\");\n+\t\t},\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--version\") throw new Error(\"version unavailable\");\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\n+\t\t\t\tthrow new Error(\"notification store unavailable\");\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") {\n+\t\t\t\tthrow new Error(\"adapter version unavailable\");\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait unavailable.emit(\"session_start\");\n+\tconst noClaim = await unavailable.emit(\"before_agent_start\", {\n+\t\tprompt: \"Continue the task.\",\n+\t\tsystemPrompt: [],\n+\t});\n+\tassert.ok(noClaim.systemPrompt.at(-1).includes(\"OMP SPT endpoint\"));\n+\tassert.ok(!noClaim.systemPrompt.at(-1).includes(\"OMP SPT updates:\"));\n+\tawait unavailable.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n+// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+async function testActiveTurnBoundaryDeliveryAndFallback() {\n+\tconst harness = createHarness();\n+\tawait harness.emit(\"session_start\");\n+\tawait harness.emit(\"agent_start\");\n+\tconst firstEnvelope = '<EVENT type=\"msg\" from=\"first\">one</EVENT>';\n+\tconst secondEnvelope = '<EVENT type=\"msg\" from=\"second\">two</EVENT>';\n+\tharness.children[0].stdout.emit(\"data\", `${firstEnvelope}${secondEnvelope}`);\n+\tawait flush();\n+\tassert.deepEqual(harness.submitted, []);\n+\n+\tconst boundary = await harness.emit(\"context\", {\n+\t\tmessages: [{ role: \"user\", content: \"operator prompt\" }],\n+\t});\n+\tassert.equal(\n+\t\tboundary.messages.at(-1).content,\n+\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\n+\t\t\"the first accepted message must enter at the next model boundary\",\n+\t);\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [...boundary.messages, { role: \"assistant\", content: \"first outcome\" }],\n+\t});\n+\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");\n+\tassert.equal(commandCalls(harness, \"send\")[0].input, \"first outcome\");\n+\tassert.deepEqual(harness.clock.delays(), [0]);\n+\tawait harness.clock.runNext(0);\n+\tassert.deepEqual(\n+\t\tharness.submitted,\n+\t\t['<msg from=\"second\"/>'],\n+\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\n+\t);\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n+\t\t\"active-turn delivery must use the extension listener, never a background poll\",\n+\t);\n+\tawait harness.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+async function testAbnormalTurnsRestoreReceivability() {\n+\tfor (const [label, completionEvent] of [\n+\t\t[\"cancelled\", \"session_stop\"],\n+\t\t[\"interrupted\", \"session_stop\"],\n+\t\t[\"failed\", \"agent_end\"],\n+\t]) {\n+\t\tconst harness = createHarness();\n+\t\tawait harness.emit(\"session_start\");\n+\t\tawait harness.emit(\"agent_start\");\n+\t\tharness.children[0].stdout.emit(\n+\t\t\t\"data\",\n+\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\n+\t\t);\n+\t\tawait flush();\n+\t\tconst boundary = await harness.emit(\"context\", {\n+\t\t\tmessages: [{ role: \"user\", content: \"active work\" }],\n+\t\t});\n+\t\tawait harness.emit(completionEvent, { messages: boundary.messages });\n+\t\tconst outcome = commandCalls(harness, \"send\")[0];\n+\t\tassert.equal(outcome.args[1], label);\n+\t\tassert.match(outcome.input, /turn ended without an assistant response/);\n+\t\tassert.equal(stateCalls(harness).at(-1).args[4], \"idle\");\n+\n+\t\tharness.children[0].stdout.emit(\n+\t\t\t\"data\",\n+\t\t\t`<EVENT type=\"msg\" from=\"${label}-next\">next</EVENT>`,\n+\t\t);\n+\t\tawait flush();\n+\t\tassert.deepEqual(harness.submitted, [`<msg from=\"${label}-next\"/>`]);\n+\t\tawait harness.emit(\"session_shutdown\");\n+\t}\n+}\n+\n+// [unit->REQ-PARITY-PEER-SHORTFORM]\n+async function testPeerShortformParsingAndDispatch() {\n+\tassert.deepEqual(\n+\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\n+\t\t\t({ targets, body }) => ({ targets, body }),\n+\t\t),\n+\t\t[\n+\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\n+\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\n+\t\t],\n+\t);\n+\tassert.deepEqual(\n+\t\tparsePeerShortforms(\n+\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\n+\t\t),\n+\t\t[],\n+\t);\n+\n+\tconst harness = createHarness({\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\n+\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tawait harness.emit(\"agent_start\");\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n+\t\t\t},\n+\t\t],\n+\t});\n+\tassert.deepEqual(\n+\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\n+\t\t[\n+\t\t\t[\"alpha\", \"ship the patch\"],\n+\t\t\t[\"beta\", \"ship the patch\"],\n+\t\t\t[\"gamma\", \"inspect release\"],\n+\t\t],\n+\t);\n+\tassert.equal(harness.sentMessages.length, 1);\n+\tassert.deepEqual(harness.sentMessages[0].delivery, {\n+\t\tdeliverAs: \"nextTurn\",\n+\t\ttriggerTurn: true,\n+\t});\n+\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\n+\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\n+\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\n+\n+\tawait harness.emit(\"agent_start\");\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n+\t\t\t},\n+\t\t],\n+\t});\n+\tassert.equal(commandCalls(harness, \"send\").length, 3);\n+\tassert.equal(harness.sentMessages.length, 1);\n+\tawait harness.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-CHECKPOINT]\n+async function testNativeCheckpointTool() {\n+\tconst harness = createHarness();\n+\tawait harness.emit(\"session_start\");\n+\tconst tool = harness.tools.get(\"spt_checkpoint\");\n+\tconst result = await tool.execute(\n+\t\t\"tool-1\",\n+\t\t{ wake: \"Continue release preparation.\" },\n+\t\tundefined,\n+\t\tundefined,\n+\t\tharness.ctx,\n+\t);\n+\tassert.equal(result.details.ok, true);\n+\tassert.equal(harness.compactions.length, 1);\n+\tassert.deepEqual(harness.sentMessages[0], {\n+\t\tmessage: {\n+\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n+\t\t\tcontent: \"Continue release preparation.\",\n+\t\t\tdisplay: true,\n+\t\t\tattribution: \"user\",\n+\t\t},\n+\t\tdelivery: { deliverAs: \"nextTurn\", triggerTurn: true },\n+\t});\n+\tawait harness.emit(\"session_shutdown\");\n+\n+\tconst ready = createHarness({ id: null });\n+\tawait ready.emit(\"session_start\");\n+\tawait ready.commands.get(\"ready\").handler(\"plain-ready\", ready.ctx);\n+\tconst refused = await ready.tools\n+\t\t.get(\"spt_checkpoint\")\n+\t\t.execute(\"tool-2\", {}, undefined, undefined, ready.ctx);\n+\tassert.equal(refused.isError, true);\n+\tassert.equal(refused.details.reason, \"not-live\");\n+\tassert.deepEqual(ready.compactions, []);\n+\tawait ready.emit(\"session_shutdown\");\n+\n+\tconst failed = createHarness({\n+\t\tonCompact() {\n+\t\t\tthrow new Error(\"native compaction cancelled\");\n+\t\t},\n+\t});\n+\tawait failed.emit(\"session_start\");\n+\tconst failure = await failed.tools\n+\t\t.get(\"spt_checkpoint\")\n+\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\n+\tassert.equal(failure.isError, true);\n+\tassert.match(failure.content[0].text, /native compaction cancelled/);\n+\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\n+\tawait failed.emit(\"session_shutdown\");\n+}\n+\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1581,"output":6058,"cacheRead":193024,"cacheWrite":0,"totalTokens":200663,"reasoningTokens":1063,"cost":{"input":0.007905,"output":0.18174,"cacheRead":0.096512,"cacheWrite":0,"total":0.286157}},"stopReason":"toolUse","timestamp":1784190961269,"responseId":"resp_020671dfcc618bf6016a5897f41cb4819b8a83ec8edf0426e8","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_020671dfcc618bf6016a5897f668c8819bac626d30f1881913","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJgBAVEA0UTz-Pq-eCJDSynXT2CmdWgy1IQzxt21DpiFJHMJ6Wm7NDYs_aIMnZYanViSLFpcxnLaptka-V27q3-N8yO9fu_14rP0lXesSK0iG6-RJPhYrsjQG_Pgc0NqGVTvvGz-dYlXFqW2fevaQgrVhRvWn6N9BnVbx58Uz1UF5eiUvFivqc3JLtjZJXdD4EoMOeGsETMOZCwuHApNswPzpHYVJ1xhoWa_QiONRxfT7ELQWAT1OApQalgq32vlzCwDjtiQ8DH8ZfwobM7WLZELFZzSaJbPTMKpIiPrg9ZiVH4UmOpeJIWAuLALx_0M1o5UCaSlaoYz-ciq73sEOqHqiba1IK6_zJOgwdxm3EUv8YlepLPQHxbaPpsfx_VMfkim4asmkxJPd_WSL068Yi7EAmDUdjbz6f1TpY4MkyBsw4R15RB0nDCynw5erMscFOTuJ35NfBWmPAktbgG2gnCJX5cKOrrs73XVze1qdim8yPp_VwlxO8Bd8SXYpTAy1S5mBMvXXrx4oveiVX2AbgysXcNB0LwE4jeVAYro54VZC5K5Zsh6AZufqNmjPQNExm2daSrVGWjSUPXP8Yucvyi_wNqwODYr9BuFDDDLDoc2X_smlF5SGyaEtOEBCNocDMadyoGm2UI6M5_qPGPc__4m2hYqWlycAk_eA0UGkyzsmWFf1eQUqtEvUyqxDSLR5v-YuPzxQexZmQGY6NooFAseAeF4bEqhfS16d1pnJIBcYbkSZ48FKPKVuMJdABnxeuo6Izvyoyp88X8F1bALMIYAiY8XALWj1kP1ulc0UTX1FINDm9e8OwFRcu0eburQ7C4T-tC-8dlhiMyyLgPWYLF2ouzYq46YaK4iXZwvwq612IgZ3SUAIzPLgdxLxuhd1AqDdzA9EHFTrxlO2RYSa4tLRIKS4_r4fZXMupSTP58MlEhfFm-PFgS0gG-LAuHlpwRw7TpJAUM8vyT2pV0e0FYj59Uk6QF_haqfOS54z9xTo_QPk8LvOFbYVAG1QEfVhhtIvTUkJp3m4-he3150Hyf0NWBvphZEz8gANilf0_yz4EN68ZOSNzbntrD2Cs17vqKL6EZ9UQCkavbAfUcZhh0owfZUvZ_vOkUCGB0k__xdZBr-RnyQnMoOPpAuQpvhCmNSzdvdADzBHNr1frsCnmQPn8xXL3pEd3G78jgorTvYl3BgsGQLQE6hw5edGiR-3tjwqNknz2uWHeciv1uHEKtVBgy2hKC-_F3VEQaHTohEc4pfZ-QS7uC52wq5oi4om918xsaNKwa9BycgHAUvUKFLckyNQEdR1EpYYTC4nnGJUyxsNzJn8pUheaRrfitNqBZGhrf-gm0IelettQS9zFMcgocy_nocvEDOfU4gVFcJrD6gsGlVxUo_y4V2xSRs2T0vLZFJj1ZBN6MMgE_pA6kq-MEVCULcWd52i3IbNjUVheICmQdr1KFOuVcL2Eo0zmuMx6VWX230t_K4dVdf3aI-ZoKMRcI6EE-ycubCQlTPc47ykILhhpehg1wn8ayJrWBtF7DhvOG2SZz9tzS_3HiaOuRJMQ5-M3fmimdb6qWAvxPEcPkOT-QrqXtzNAgfE4JR2W0NDeg5sbvzObfknzDkCturYH356SSgZ8i3U7BU1Ov1x789ZID4xt9HVnD6QzB6OlId-m2t56flYB3Z2iK0y4XwSAGROkuIWWUFfJOkXhqd7GhDc234rU-FG5k5WeZhA0kh3CCIM1LpWBsFBHcFEhWh3CxJsPlq6f7Wnum5UiQ6ZlH2hHKZqYT7u62-Fpu-ascXtYJlnkiRPQz83smXHA8qP2PEmH3BOo1evOP4k3crefpQbrwrXVpGalLoJwZ9EmY9fO_Zs07zjw1hmd3MHdl9HqMVEeQw5ceVA9-U5E40OFDQltJE2EFB67v8emo79qZFku7CxSpl5nNBVpwTeR6ZC0asWZ3un_QASVffqlmvjzvbrzO8NGptKr56afiPJC5Cd0teODQSoHqpc0ZehkeCti1RfA6lK8yHP-Ei0GTh3OAg9D7CvM1Hzy63y5mfauUQczf9uyxyDy1y0MaS36NK4ns1smIoGWtvO4KCJ4Lf6-FD65pHXCPW4EODM9UR1jHWk3HFgfwtob6iBcq4bWt48jYfl_TLpDKV8F9yWukoPvbNw3HTtD_5l_Nlu3zhWOU3BJ_WamrgKfNtekbYli0sadoaJfsxMck8aHYTb4EPFSRkkHdpscY1wHx5hw5A-WOJ0fQSbGqpVaY3ZJbVqNylL-6c2y1FU3cnZ_0yVqN4gbb33cIiwD-qqprv57J1AAXTpv8TcAhsbD7FEDe56YZa6uVMpq92xAvx0Ha3kK8k4YPV6taaBEYULw4z-ruoDCrOO6ntkh_hADGenu58ZScp4Di1nZ18MxzIZ0nYB1zmwmb5YR0k23GtjORYO0_XIISjm4VK1lDqUg2tkfIMhiYC5QzwDm6ceirOwontnT9gnvSQVmxwzQcCHZXObcHoUTErDomyX-qlppCD6ip5aO7GgqjmEuPQTERCC6af38yKemLmDfLMs8mpjryVgIwQ_k3DLBXDUW_SQYvUDGGtsCxRyp3QkGkRNG6iiSUtmAfKFibbmuHzPb_rhkLNsVWda84KrHm8Kffh2Y2k3HEyNbw5T5fSIVvJj6QctxrB-dHA0uGgqv3yNpqJDA1bzrJZdi57JmnoO_UjY1zCPayf_dl6FDAaDw33vVBLq_jM3C25kkrphlvBO4kU8E5GlD7f5n9-WcuVKPPktpJonuAsIIY_GnOTdntJXq_a1UOqWI4hEos1zh7RbRPGX9o-jWcgy0Jmc1ENOS9w7Z3WWuNsxgtSHwaUtz2gE5Dd2Kymqi5P1xs_-uGOP8GeU1dGx5oNd1kcEOhDTLNqqCGU-uIuJGzpEu22p6kZtf6Dy1OENyKuDyT4huUHU4zSFa7XwJztSj6St7O-Zhz2dN9SzfhfQ4a8iNS8_W5i5HXU2FZWdBzk3beTyoULL7uSN8wijbNzEeO4MSdLPvDHXmmVtSQ7o2JALQSrXky9LvQiwdLnOcljDMhv2xRQq3EfPn1gFGe_0D5_xPrS603tibJKzKDmJjjTt8UQjW5PDwi0AFhTkHXSuHYmyj4v8ohETpFTfJIUIr2_swJrOp35rVmL0kL29coadIVJTsjYl2HGQ-bLTdpEo4vphC7iUayx77Nlc8470dyEMgfW_KRk3JGi2lydpakLaHIobONK0hHCqGEfIIJ12aYeX_SfyENzZDSyI_-xxV_KyeA-OQg1-nZ124b2AgMrKj0CtPqCUzpzLvZ4kcTxm5_gyioAqkZG-K1xZJLBV4glmBGVeuSdN7t6y15l2jCEl1pItD-pqzbqV_elPwfPTL2dG0igzu5bCS5EWy9KnIzWMOQPIiRekkOYzc6YWYe6r8BprfifWCoHK0y9EguqNCdCFPwo9CFG2tvc14jm5vlKLrJdWP9vaRy4AogictrQLH_Xvt_xHoU3FS8dfP6MtkL0-YqkU4EKXuHPsdpBNFlxKWyN6zvoNYsBHik0PGEj9yMc-UyyM1hSGbwNLqVr60ponMIU21KagGunqck__4_iWqZntwj7cPOIE8QUNHok91Y95hYH8Z1D3dxQcoNfn_ftfFc5WsqaMMZZvLeo32kcQ_TBcHlpucyxnFztGfXp6Frrc6PuzSaFBOMSQTciWLpGDHzh8gpRssRSk0vTkEPRLCKdl2_GPUK173ytnILJZCaZkM_BlRekNITWRoY_NcLZtRU4lLXyHQ-J9zANsikg3XAi6bfs5UlOlzP5S4_BeUfQ_-FP3-1_fxCr8Wepa2ukzxEu6dMyWMAN5kZrJk0yN7lASJ7HcfRkTM4twAClk69FjAw-zXDvfOnVB2owjmFz3dCm_rvtC1PHVUybE_neg3u6UV6Hcx2GLHmIe_N0slFARbZpTnIZh88O_lTuG2VkNCbXhXDaft7IpNlR2jgaQqsf_5h7xVazOdOKvJdAKu1ZoA3d4e6-loxMi_f9dt0wpd7IRqDz-e6ePXihpPVng7fmiXgE6OncgommFwcvfPkcmzoxJpeYhgFBaCs=","summary":[{"type":"summary_text","text":"**Inserting test helpers and verifying session behavior**"},{"type":"summary_text","text":"**Refining onRun argument filtering and bind logic**"},{"type":"summary_text","text":"**Updating startup argument handling and version probing**"}]},{"id":"rs_020671dfcc618bf6016a5898013674819b938e507eaf70fa83","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJgJ0tpbe-3UcS7g3IiZeX98HHeCnZPAYK0wUmiYWmVWiACI319-cFFbXbmU2iJc6FvXhS5yMtKZZJ7f7_4IRqZempZ3EAAb2sTdDBU_mZozjmvsNl8oUAJE0MeG9nfv_RTcSI4xUEdpl3TGX7hbTzpcwk7Ch6bV-rdn-hNiONd8MqY1yWrfbj5yYAhww5TjVi6X5T7g5vW3Br1QAe8_1etRFQp4diJAVlb3jwfXOcsSoZ28AZxUzKBdXGjr5932yEX8SxqyvMHYFv6JjeZZbtVKsFd4hV7y_61s-PubmnEYuh0raxV2zSvXljpExJI_4UKN0hzLIHfdpME72uyxX_tUNN0yihAMr5q0RMEGnEY6nrQYqY73zWf4a6Asvl-nS-WHF2RApdQiqXbR4br1HYlQfoLqiqhj0FJHAxLl5NRyZ3yUD_c371-vEhC7W2Dd7lAILOIWwFcPYWQ1WEYweO0kCN7YONhWhwOZfGEgsPDjQlDIYLS5agXG0UOyiepSFTcjFuYBu0e7EMfeEzdeiq3alLADO5LpTtD1hR8In2vQxgygWobcFkZZfAuAjT2LFsbx0K3-8uMEU_vT_bZwGgldBeK1oN-c5wI8QzGwsLH1ULuM3uzPJu52Ct1SXU6TCyBPx_VV5FkZt7nFqlam1dyZMdkA65yXKbPlTuafk8e7AY4aPQO1Hw2wgYYE4YaJE1Zi8-4nk295FbFLNcObXrupAVRkPVfJpv1X-Ur5C9ZlDO4cmyWpfxHIcLW8rSUPcPJmXy0_7jGaMlQHURjgF8OEdsRs42we6Bk3JKx40O8sK0CBNIkdFAEJEbfKqoxBy5Xf9uLfYW18fWFSPkZeMnkYugGMYV-GaKHJkxVP0GEnEzJgOEdyp1Jo-dZ5RjKtX99VDposd7GBOgfsX61uIqxmY3EdoHiRA6khJ8GsGFF3PBRHtWvDiLmxKLtSh3_u9lZQB1g3s_C82Czo9c6rtrVMB-fucYwDpzGKv8zNK6snVeIpFV2BLiUxsG50DTZbhgB4FrIpFs3WJBW89rVaTgrZXtxUa6b-RAg-eljF-uqtulFzE3Y2HWzXjy6ttSLBZQkNCL2RAbPqRrR9BjhHtJ589IyBBYVQUSi3J2VnynFvBoqyPl3XF_pRuFKHhDrkkITA-vhIoQQ9WF5i1SqmVfhRuYWbHZGotk-FvBcYtIulPdj3dYPmRUydGKTqAnHSyzBRdMJlLFw203MWI3LPjONPggiFckDsM7evSQDHrEXamswNmSm2pJNVXe2Eaqrgfml1sR6ZI47IgsChVRWVnye-IPcNaZVyueRLJ3b08FMtuHzozc6QqYPwWicr3Gzwr1o___Bg0uCUcIltP8nZE0AmszqHzvkwkcFfE6og80O1OG-5QKp9IutejHC3w6_2PsA-e_tVqEQD_f17JwRXhoTB0okjs0V9WgnNI5elLNr6Lg3-8Ai7d470bvqX6qG4beepr33ztgocBjXzsbhK7wwoMsbmMcDP3K-SgKctVLQxsU4kpKo8bmq5slNq1cXQRHvPj7Zjw-WzIYNJ3MA3tLb36DTAuxUHvzeOdr31gjdSVeTPNSOsHMxfsE4HRHdScdv4bH00TEebEAJih_-56cI1ct8U-_c5Neg0ToHVGQ7-Np3i4wA32-LPeXkqvi8yxQxdSPgiQCCk3GDdEyNal0akin4ZJFZhNKvBy7t8MonJMWQm0HXnydEAqh67DJPtu9u8jO2mtvAhuUGab73-ZzKaPera6qV48ps7P0bc8F6eS0TqALN05iu2SJDKnBznZrHMj-poxfORqW3vd-gSpPo1GjNql7niCNVQ_R9rMS8UtPehvPyaMJtiJBoBGm2S07sDcIl1xeOUEqcTgpASa3J_3Sf5MKjFx_GxfUjHe6qYYaeRnl78r5H3SzzSBWgbtLKZ97P_mv_ZpJ69XzdW8pwi4770CgSJcmuxOU3axaOORCA4Z08f2SEYr7Rp0nDJNlx8ygTjXIRfta_POzNmFJJcZxD4cDTth7NPs-VFDqLsXxboSbnK8o7rVCmFz2jRaKsx2k7XS7P2qHUNkhvt-5_H8JYAkl71NdCEmZnP4Qkwbh4ZcPPdvKrVAp_t5ZWw_VkDqDV8moBnzcJgND4ZdCq4GkXLEhvJ0Jzi31MIblPPwAip4pJ_cEsnqolmx3TUj7lUuRhntuhV3ZwWGqViSnz0RrsigltMVbnb77fAElvB8DprW50zZHKX-vQx4cdzSzyBUeqiq5RJcE95A6scbk1513cS1ksHYafBZDn-ynceaqvOhC32oKxXngU2OvOu0uRbQS0dz8AYsk04rgBATc8QMfmvI020a9nsaDjsgPvaW8OOSVsMx56EuJF6XCYLhIJ0q6ACiit_yvozOkFa8LgjP4cFv5S-A-BxClitPixSCOAWI4OiQmUExuK3JSW9HqvhsAlIztTEq60UzlwYR1-3MjGuwKYWCNRQPzAMuhGl3ecyAajrLC2iePHXuqJkkfNCqXdqRgBUPG58EOyw16ykfsd6Bj6YtC5jcOG61hMcuquFGfXNXhjVBqsxmgqRKujwL2rheMG5XzEYMkrQyghnnLnUqqM2iW99k8rmwB9d8NrPihESWAu1g_y2KORo9ECyI_QX_IAYfrf7r9kuQUWhuxVxeBZGnzlIj6-JjK8wbyuAzJ9g2euGBH02_y4ePkDT5xg8ll7zJIU2wR8DjMqefYVtxkUw7DBvrENpvsRr9rthmhyt24IBGNY-HkeSf1iIMqgDc5SWn-56bEm3S4LaDbk9V_gPTSICCCe-bKvqiIjeZJbpT7ucnDzS2DSETrkNjHkrRo9sLV1F0ium75YHoY4m5eUO1_krq5kHSZILE2ap8ExRDuRmx0JNMDqkZ1SDz-E4kBTAO7Us2_a4QW_sJtaLBaR650mcvws5O4dztqvqYLi-YiZLL6caFtCVILeVbsJKG-Y1hY344GK9c637Pr31hD3nec8g3-4K65I_-ry9CqghqvCu0RTzI0GKMwt_QVbdeU5vZcNs7ADQJlXQGE4uZ6xthESE6KRGKeWjmCGcWrbhare4--R5O8x3a-O0eP4FvioT0uXWlt1Th9hIO0emyNWFoADSwMj4sJhW8mdBi8SKXdKwYNYA4saAv0_ZawzF58nEGUwqeh3Lg-dWjkMuyJU3DM_RSA_EVz-XixudYj9MnpXmU0nb39WP2M8SuouGPQjgee0t6pkbOiRnHEergowjGmWPT0ZNLmpJX7ZnSlFv2lRTnjYEvcTcEzeEYEUwBHRTtNW3dQOdK6fKZJ_SgDwY_dAHu70lxKK5_4HGF721ISQ6md5ba61z3oYrCQ3LFv9mYLbpJlk1xmPIpLwL0nVrkm_q5KXzyKGh4dfNULaauiWsIAvW-SLvmqWoF1xkn4FShNoLWF51aeaLNB9Hfae9I23yawB4hEbtasa8jWNBqUq9FXJEG0egzdRjohFx6qmS0GSjy8MRWDnjXQOcpTj9xTrs2L6Br2lWcHIREfjznVFWrZiBRHWoC-cqiFR1wwWxiAlmxPSEVYx6TZrP3gamXQbfU0700wdIfMdb3gndTOJCg7Dk0DfI5jzumvJcN34iEiulOh8QHQ8rYvjt-cGaa87WUVLethvUPj6YAs8RFdzEL6KKL-JgOqObrT_pngcToVaiAM7HZSN5S4-641BuzGvxlAk40X9dc2mdXzHQmhebQS-aLTj4ea50ptREOzKxPHpMVwn_FR_NOSPphiwFT3gYWHYb33nuVOQToRmTkIeHJhKJ9u5RvfZByHEpO4w80S_wainwMKXyEasNAa-HBTjKSXO0CW6zQGW4iWjumQflmCWbfgUe1kHb_eb9WpIH-YikX3bPeV575SGPnAsikb5NlKSzFyjlpWx1U146bhDndrqWrDEr9a5Jb0BoBXI8bx5WyRNyJncaTyka43ZU51n3d75b7haz4qUdckVSyur1l5JJspNum_D0R9PWVGh4D0qlDh_arWYAKIsNQxx3yqChBKO6w-Bdmh_yh-n_9X8oTvwGO4WPBAETyMmWkhm67Gj3TxaDLbUsQk6SXhw5Rl6npQ6DmNAC1vitysZtU0gcWCz2FH5AoV8czTAvH27RETeLMXiqoQRkUuCNcRr42Tf81wEa3iM3lfYywP-7zgxWCzQRj7fYpD6g10qxDroz6Kf3H4lPXh0-ug==","summary":[{"type":"summary_text","text":"**Tracing agent shutdown sequence**"},{"type":"summary_text","text":"**Differentiating shutdown event modes**"},{"type":"summary_text","text":"**Testing argument completion fallback**"}]},{"id":"rs_020671dfcc618bf6016a5898096594819bb2e1e61decac480a","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJgJcFQErFCF7brywQ4ZwO0p7xcy9u4de5Ow3DP4WuDLQl8lSISR0ljixdQa4B15qMR3rVW9uCy6eHi9Kw_heHVDThKl1ChozD1V6H26XhXRgCbDNDRV35qiZNh4p_m-DfreTFFGibwjPxK-mQztkkCxBYoDmpx4jto3sAMONI_vBloVL3HSW4BnGe4FLmrN3MPKMkoSWQihzgCVV3vHrsX-8nr0uoJXVeWSG1SpjTuPdgG0mdcJU2RUZcCRZfnljhezxBVztnMUh4cpCpqhrBmvES3WZNk4r7i7GWIhMy1cyi_M1eJqAfwcf4OpGj6OEyKsrCDCaEN9AX6x4gtOJW-UptLSPaN2i9PKWsHXUx5ihDzRNGss_gM20TQYLOHIZJh4L6B1fd4Wqhcs4WkghUg7W0_nbVHcaNI1zLIWdn1ZOAfJMdsDXpgJz8BwDCvy4X1FE2N9udP22swtlG0FeYXpLzUqGBduJHoGonJxEfSBqtDH4YhjECoNcgIwkN6AAmZMdymewGp6H65oEvnVV1sNYpabsWigdbSd_cwud3SpZn7Thtf7U0ZUYW6gzaS3Bu3VbKMfwdyssbj7NRbPQjpqoGvgenhu_njRRelgRGGKd4N87Gu2iDTMMt7p0W_PzhYgqMeeDeFrjVFraqXW4Uz9kPjp5V5zBO1G9ngONOaJk2Vs6myYqqudpi0R4nyHODHRCfGMCOmC-drFyi1iJO0Q2D9boEraGwioilf1EhN5HKZQ_sanKoMdY-dHInxsvuDL10ofdYlvb88qFkT-WO1u4alhpVzsM0Z1AGb3nMU70ZGkBPkqktDos0rvg52BUbdS3gEWbAi-epvHglnfRMY6VbmOToNQJwwE0BurqQUkAimp5VDk7j_wQFi4A4ojdWVXGbVelAB1D3DLgyR5KMrZNeBuGJFOF_zaQBzEwrKeO8Kz0iHnBrX42XMKPy9ZGIwZFVaQjSpn6RY1HlUDaAAVXo54w5sdTwqeQf638g1Q9jWasjq4GqT0rsU0LKCV5wKBpccssypsKXMXsPSIMG_bHA==","summary":[{"type":"summary_text","text":"**Adding comprehensive tests**"}]},{"id":"ctc_020671dfcc618bf6016a589809d9e4819b9cba3e688007e39a","type":"custom_tool_call","status":"completed","call_id":"call_skhLfO53mQthFB8WP2EIwWGy","input":"*** Begin Patch\n[tests/omp-extension.mjs#3EE9]\nINS.PRE 1422:\n+// [unit->REQ-PARITY-READY-ACTIVATION]\n+// [unit->REQ-PARITY-LIVE-ACTIVATION]\n+async function testNativeActivationCommandsAndErrors() {\n+\tconst inert = createHarness({ id: null });\n+\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\n+\tassert.ok(inert.tools.has(\"spt_checkpoint\"));\n+\tawait inert.emit(\"session_start\");\n+\tassert.deepEqual(inert.calls, [], \"an ordinary OMP session must remain lifecycle-inert\");\n+\tassert.equal(\n+\t\tawait inert.emit(\"session_before_switch\", { reason: \"new\" }),\n+\t\tundefined,\n+\t\t\"an unbound extension must not block native session changes\",\n+\t);\n+\n+\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\n+\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");\n+\tassert.deepEqual(readyBind.args, [\n+\t\t\"api\",\n+\t\t\"--adapter\",\n+\t\t\"omp-spt\",\n+\t\t\"bind\",\n+\t\t\"ready-one\",\n+\t\t\"--set-session-id\",\n+\t\t\"session-1\",\n+\t\t\"--type\",\n+\t\t\"ready_agent\",\n+\t]);\n+\tassert.deepEqual(inert.children[0].args, [\n+\t\t\"api\",\n+\t\t\"--adapter\",\n+\t\t\"omp-spt\",\n+\t\t\"listen\",\n+\t\t\"ready-one\",\n+\t\t\"--session-id\",\n+\t\t\"session-1\",\n+\t]);\n+\tassert.ok(\n+\t\tinert.notifications.some(({ message, type }) =>\n+\t\t\ttype === \"info\" && message.includes(\"ready endpoint ready-one\"),\n+\t\t),\n+\t);\n+\tawait inert.commands.get(\"live\").handler(\"other-id\", inert.ctx);\n+\tassert.equal(inert.calls.filter((call) => call.args[3] === \"bind\").length, 1);\n+\tassert.ok(\n+\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\n+\t);\n+\tawait inert.emit(\"session_shutdown\");\n+\n+\tlet bindAttempts = 0;\n+\tconst retryable = createHarness({\n+\t\tid: null,\n+\t\tonRun(call) {\n+\t\t\tif (call.args[3] === \"bind\") {\n+\t\t\t\tbindAttempts += 1;\n+\t\t\t\tif (bindAttempts === 1) throw new Error(\"identity already active\");\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait retryable.emit(\"session_start\");\n+\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n+\tassert.equal(retryable.children.length, 0);\n+\tassert.equal(retryable.shutdowns, 0, \"a pre-token command error must keep ordinary OMP usable\");\n+\tassert.ok(\n+\t\tretryable.notifications.some(({ message }) => message.includes(\"identity already active\")),\n+\t);\n+\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n+\tassert.equal(retryable.children.length, 1, \"a corrected activation may retry after a bind error\");\n+\tassert.ok(\n+\t\tretryable.calls\n+\t\t\t.findLast((call) => call.args[3] === \"bind\")\n+\t\t\t.args.includes(\"live_agent\"),\n+\t);\n+\tawait retryable.emit(\"session_shutdown\");\n+\n+\tconst headless = createHarness({ id: null, hasUI: false });\n+\tawait headless.emit(\"session_start\");\n+\tawait headless.commands.get(\"ready\").handler(\"\", headless.ctx);\n+\tassert.deepEqual(headless.calls, []);\n+\tassert.ok(\n+\t\theadless.notifications.some(({ message }) => message.includes(\"requires an endpoint id\")),\n+\t\t\"ordinary activation must never guess an identity when native selection is unavailable\",\n+\t);\n+\tawait headless.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-READY-ACTIVATION]\n+async function testNativeActivationSelectionAndCompletion() {\n+\tconst harness = createHarness({\n+\t\tid: null,\n+\t\tselectResults: [\"ready-old\"],\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tlocal: [\n+\t\t\t\t\t\t{ id: \"ready-old\", state: \"ready_agent\", alive: false },\n+\t\t\t\t\t\t{ id: \"ready-busy\", state: \"ready_agent\", alive: true },\n+\t\t\t\t\t\t{ id: \"live-old\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tid: call.args[3],\n+\t\t\t\t\tadapter: \"omp-spt\",\n+\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+\t\t\t\t});\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\n+\tassert.deepEqual(harness.selections[0].values, [\n+\t\t\"ready-old\",\n+\t\t\"Create a new endpoint id\",\n+\t]);\n+\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], \"ready-old\");\n+\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\n+\t\t{ value: \"ready-old\", label: \"ready-old\" },\n+\t]);\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n+\t\t\"selection and activation must not start an agent-managed background poll\",\n+\t);\n+\tawait harness.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n+async function testExplicitLiveAutoResume() {\n+\tconst activity = {\n+\t\told: \"2026-07-10T00:00:00.000Z\",\n+\t\tnewest: \"2026-07-15T00:00:00.000Z\",\n+\t};\n+\tconst harness = createHarness({\n+\t\tid: null,\n+\t\tconfirmResults: [true],\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tlocal: [\n+\t\t\t\t\t\t{ id: \"old\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t\t{ id: \"newest\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t\t{ id: \"active\", state: \"live_agent\", alive: true },\n+\t\t\t\t\t\t{ id: \"foreign\", state: \"live_agent\", alive: false },\n+\t\t\t\t\t],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tid: call.args[3],\n+\t\t\t\t\tadapter: call.args[3] === \"foreign\" ? \"claude-spt\" : \"omp-spt\",\n+\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n+\t\t\t\tconst id = call.args[3];\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: activity[id], text: id } }] }],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tassert.deepEqual(harness.commands.get(\"live\").getArgumentCompletions(\"--\"), [\n+\t\t{ value: \"--auto\", label: \"--auto\" },\n+\t]);\n+\tawait harness.commands.get(\"live\").handler(\"--auto\", harness.ctx);\n+\tassert.match(harness.confirmations[0].message, /newest.*most recently active/s);\n+\tconst bind = harness.calls.find((call) => call.args[3] === \"bind\");\n+\tassert.equal(bind.args[4], \"newest\");\n+\tassert.ok(bind.args.includes(\"live_agent\"));\n+\tassert.ok(\n+\t\t!harness.calls.some(\n+\t\t\t(call) => call.args[2] === \"digest\" && [\"active\", \"foreign\"].includes(call.args[3]),\n+\t\t),\n+\t\t\"auto-resume must inspect only inactive compatible identities\",\n+\t);\n+\tawait harness.emit(\"session_shutdown\");\n+\n+\tconst declined = createHarness({\n+\t\tid: null,\n+\t\tconfirmResults: [false],\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tlocal: [{ id: \"prior\", state: \"live_agent\", alive: false }],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tid: \"prior\",\n+\t\t\t\t\tadapter: \"omp-spt\",\n+\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: \"2026-07-15T01:00:00.000Z\" } }] }],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait declined.emit(\"session_start\");\n+\tawait declined.commands.get(\"live\").handler(\"--auto\", declined.ctx);\n+\tassert.equal(declined.calls.filter((call) => call.args[3] === \"bind\").length, 0);\n+\tawait declined.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-STARTUP-BRIEF]\n+// [unit->REQ-PARITY-TARGETED-HINTS]\n+// [unit->REQ-PARITY-UPDATE-NOTICE]\n+async function testStartupBriefHintsAndUpdateNotices() {\n+\tconst harness = createHarness({\n+\t\tcheckUpdates: true,\n+\t\tfetchLatestAdapterVersion: async () => \"v0.3.0\",\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--version\") return \"spt 1.0.0\";\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\n+\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\tnotifs: [\n+\t\t\t\t\t\t{\n+\t\t\t\t\t\t\tfrom_id: \"spt-update\",\n+\t\t\t\t\t\t\tkind: \"consent\",\n+\t\t\t\t\t\t\tstate: \"seen:1\",\n+\t\t\t\t\t\t\thead: \"An spt-core update v1.2.0 is available.\",\n+\t\t\t\t\t\t},\n+\t\t\t\t\t\t{\n+\t\t\t\t\t\t\tfrom_id: \"spt-update\",\n+\t\t\t\t\t\t\tkind: \"consent\",\n+\t\t\t\t\t\t\tstate: \"dismissed\",\n+\t\t\t\t\t\t\thead: \"An spt-core update v9.0.0 is available.\",\n+\t\t\t\t\t\t},\n+\t\t\t\t\t],\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") return \"0.2.1\";\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tconst first = await harness.emit(\"before_agent_start\", {\n+\t\tprompt:\n+\t\t\t\"Go live, show my endpoint identity, send a message to an agent, join two machines, and create a checkpoint.\",\n+\t\tsystemPrompt: [\"base\"],\n+\t});\n+\tassert.equal(first.systemPrompt[0], \"base\");\n+\tconst injected = first.systemPrompt.at(-1);\n+\tfor (const expected of [\n+\t\t\"spt whoami --json\",\n+\t\t\"spt endpoint list\",\n+\t\t\"spt how-to send\",\n+\t\t\"commune (checkpoint mode), signoff, and role\",\n+\t\t\"/ready\",\n+\t\t\"/live\",\n+\t\t\"spt how-to subnet\",\n+\t\t\"spt --version\",\n+\t\t\"spt adapter version omp-spt\",\n+\t\t\"spt update\",\n+\t\t\"Use extension-native `/live`\",\n+\t\t\"omp-spt v0.3.0 is available\",\n+\t\t\"spt adapter update omp-spt\",\n+\t\t\"spt-core v1.2.0 is available\",\n+\t]) {\n+\t\tassert.match(injected, new RegExp(expected.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\n+\t}\n+\tconst quiet = await harness.emit(\"before_agent_start\", {\n+\t\tprompt: \"Review live reload, identity matrices, message queues, subnet masks, and checkpoint files.\",\n+\t\tsystemPrompt: [\"base\"],\n+\t});\n+\tassert.equal(quiet, undefined, \"related technical nouns without clear SPT intent must not hint\");\n+\tawait harness.emit(\"session_shutdown\");\n+\n+\tconst unavailable = createHarness({\n+\t\tcheckUpdates: true,\n+\t\tfetchLatestAdapterVersion: async () => {\n+\t\t\tthrow new Error(\"network down\");\n+\t\t},\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--version\") throw new Error(\"version unavailable\");\n+\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\n+\t\t\t\tthrow new Error(\"notification store unavailable\");\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") {\n+\t\t\t\tthrow new Error(\"adapter version unavailable\");\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait unavailable.emit(\"session_start\");\n+\tconst noClaim = await unavailable.emit(\"before_agent_start\", {\n+\t\tprompt: \"Continue the task.\",\n+\t\tsystemPrompt: [],\n+\t});\n+\tassert.ok(noClaim.systemPrompt.at(-1).includes(\"OMP SPT endpoint\"));\n+\tassert.ok(!noClaim.systemPrompt.at(-1).includes(\"OMP SPT updates:\"));\n+\tawait unavailable.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n+// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+async function testActiveTurnBoundaryDeliveryAndFallback() {\n+\tconst harness = createHarness();\n+\tawait harness.emit(\"session_start\");\n+\tawait harness.emit(\"agent_start\");\n+\tconst firstEnvelope = '<EVENT type=\"msg\" from=\"first\">one</EVENT>';\n+\tconst secondEnvelope = '<EVENT type=\"msg\" from=\"second\">two</EVENT>';\n+\tharness.children[0].stdout.emit(\"data\", `${firstEnvelope}${secondEnvelope}`);\n+\tawait flush();\n+\tassert.deepEqual(harness.submitted, []);\n+\n+\tconst boundary = await harness.emit(\"context\", {\n+\t\tmessages: [{ role: \"user\", content: \"operator prompt\" }],\n+\t});\n+\tassert.equal(\n+\t\tboundary.messages.at(-1).content,\n+\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\n+\t\t\"the first accepted message must enter at the next model boundary\",\n+\t);\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [...boundary.messages, { role: \"assistant\", content: \"first outcome\" }],\n+\t});\n+\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");\n+\tassert.equal(commandCalls(harness, \"send\")[0].input, \"first outcome\");\n+\tassert.deepEqual(harness.clock.delays(), [0]);\n+\tawait harness.clock.runNext(0);\n+\tassert.deepEqual(\n+\t\tharness.submitted,\n+\t\t['<msg from=\"second\"/>'],\n+\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\n+\t);\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n+\t\t\"active-turn delivery must use the extension listener, never a background poll\",\n+\t);\n+\tawait harness.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+async function testAbnormalTurnsRestoreReceivability() {\n+\tfor (const [label, completionEvent] of [\n+\t\t[\"cancelled\", \"session_stop\"],\n+\t\t[\"interrupted\", \"session_stop\"],\n+\t\t[\"failed\", \"agent_end\"],\n+\t]) {\n+\t\tconst harness = createHarness();\n+\t\tawait harness.emit(\"session_start\");\n+\t\tawait harness.emit(\"agent_start\");\n+\t\tharness.children[0].stdout.emit(\n+\t\t\t\"data\",\n+\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\n+\t\t);\n+\t\tawait flush();\n+\t\tconst boundary = await harness.emit(\"context\", {\n+\t\t\tmessages: [{ role: \"user\", content: \"active work\" }],\n+\t\t});\n+\t\tawait harness.emit(completionEvent, { messages: boundary.messages });\n+\t\tconst outcome = commandCalls(harness, \"send\")[0];\n+\t\tassert.equal(outcome.args[1], label);\n+\t\tassert.match(outcome.input, /turn ended without an assistant response/);\n+\t\tassert.equal(stateCalls(harness).at(-1).args[4], \"idle\");\n+\n+\t\tharness.children[0].stdout.emit(\n+\t\t\t\"data\",\n+\t\t\t`<EVENT type=\"msg\" from=\"${label}-next\">next</EVENT>`,\n+\t\t);\n+\t\tawait flush();\n+\t\tassert.deepEqual(harness.submitted, [`<msg from=\"${label}-next\"/>`]);\n+\t\tawait harness.emit(\"session_shutdown\");\n+\t}\n+}\n+\n+// [unit->REQ-PARITY-PEER-SHORTFORM]\n+async function testPeerShortformParsingAndDispatch() {\n+\tassert.deepEqual(\n+\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\n+\t\t\t({ targets, body }) => ({ targets, body }),\n+\t\t),\n+\t\t[\n+\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\n+\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\n+\t\t],\n+\t);\n+\tassert.deepEqual(\n+\t\tparsePeerShortforms(\n+\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\n+\t\t),\n+\t\t[],\n+\t);\n+\n+\tconst harness = createHarness({\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\n+\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\n+\t\t\t}\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tawait harness.emit(\"agent_start\");\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n+\t\t\t},\n+\t\t],\n+\t});\n+\tassert.deepEqual(\n+\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\n+\t\t[\n+\t\t\t[\"alpha\", \"ship the patch\"],\n+\t\t\t[\"beta\", \"ship the patch\"],\n+\t\t\t[\"gamma\", \"inspect release\"],\n+\t\t],\n+\t);\n+\tassert.equal(harness.sentMessages.length, 1);\n+\tassert.deepEqual(harness.sentMessages[0].delivery, {\n+\t\tdeliverAs: \"nextTurn\",\n+\t\ttriggerTurn: true,\n+\t});\n+\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\n+\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\n+\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\n+\n+\tawait harness.emit(\"agent_start\");\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n+\t\t\t},\n+\t\t],\n+\t});\n+\tassert.equal(commandCalls(harness, \"send\").length, 3);\n+\tassert.equal(harness.sentMessages.length, 1);\n+\tawait harness.emit(\"session_shutdown\");\n+}\n+\n+// [unit->REQ-PARITY-CHECKPOINT]\n+async function testNativeCheckpointTool() {\n+\tconst harness = createHarness();\n+\tawait harness.emit(\"session_start\");\n+\tconst tool = harness.tools.get(\"spt_checkpoint\");\n+\tconst result = await tool.execute(\n+\t\t\"tool-1\",\n+\t\t{ wake: \"Continue release preparation.\" },\n+\t\tundefined,\n+\t\tundefined,\n+\t\tharness.ctx,\n+\t);\n+\tassert.equal(result.details.ok, true);\n+\tassert.equal(harness.compactions.length, 1);\n+\tassert.deepEqual(harness.sentMessages[0], {\n+\t\tmessage: {\n+\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n+\t\t\tcontent: \"Continue release preparation.\",\n+\t\t\tdisplay: true,\n+\t\t\tattribution: \"user\",\n+\t\t},\n+\t\tdelivery: { deliverAs: \"nextTurn\", triggerTurn: true },\n+\t});\n+\tawait harness.emit(\"session_shutdown\");\n+\n+\tconst ready = createHarness({ id: null });\n+\tawait ready.emit(\"session_start\");\n+\tawait ready.commands.get(\"ready\").handler(\"plain-ready\", ready.ctx);\n+\tconst refused = await ready.tools\n+\t\t.get(\"spt_checkpoint\")\n+\t\t.execute(\"tool-2\", {}, undefined, undefined, ready.ctx);\n+\tassert.equal(refused.isError, true);\n+\tassert.equal(refused.details.reason, \"not-live\");\n+\tassert.deepEqual(ready.compactions, []);\n+\tawait ready.emit(\"session_shutdown\");\n+\n+\tconst failed = createHarness({\n+\t\tonCompact() {\n+\t\t\tthrow new Error(\"native compaction cancelled\");\n+\t\t},\n+\t});\n+\tawait failed.emit(\"session_start\");\n+\tconst failure = await failed.tools\n+\t\t.get(\"spt_checkpoint\")\n+\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\n+\tassert.equal(failure.isError, true);\n+\tassert.match(failure.content[0].text, /native compaction cancelled/);\n+\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\n+\tawait failed.emit(\"session_shutdown\");\n+}\n+\n*** End Patch\n","name":"edit"}]},"duration":114713.27859999985,"ttft":5141.593400000129,"contextSnapshot":{"promptTokens":194605,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_skhLfO53mQthFB8WP2EIwWGy|ctc_020671dfcc618bf6016a589809d9e4819b9cba3e688007e39a","toolName":"edit","startedAt":"2026-07-16T08:37:56.142Z"},"id":"18dbdc0b","parentId":"532b47ed","timestamp":"2026-07-16T08:37:56.142Z"}
{"type":"message","id":"7ccddb70","parentId":"18dbdc0b","timestamp":"2026-07-16T08:37:56.181Z","message":{"role":"toolResult","toolCallId":"call_skhLfO53mQthFB8WP2EIwWGy|ctc_020671dfcc618bf6016a589809d9e4819b9cba3e688007e39a","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#9217]\n1227:async function testShutdownFallbackStaysBelowHostCap() {\n\n1420:}\n1421:\n1422:// [unit->REQ-PARITY-READY-ACTIVATION]\n1423:// [unit->REQ-PARITY-LIVE-ACTIVATION]\n…\n1907:}\n1908:\n1909:await testParsingAndReplies();\n1910:await testRunSptRejectsStdinErrorsAndHungCommands();"}],"details":{"diff":" 1227|async function testShutdownFallbackStaysBelowHostCap() {\n\n 1420|}\n 1421|\n+1422|// [unit->REQ-PARITY-READY-ACTIVATION]\n+1423|// [unit->REQ-PARITY-LIVE-ACTIVATION]\n+1424|async function testNativeActivationCommandsAndErrors() {\n+1425|\tconst inert = createHarness({ id: null });\n+1426|\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\n+1427|\tassert.ok(inert.tools.has(\"spt_checkpoint\"));\n+1428|\tawait inert.emit(\"session_start\");\n+1429|\tassert.deepEqual(inert.calls, [], \"an ordinary OMP session must remain lifecycle-inert\");\n+1430|\tassert.equal(\n+1431|\t\tawait inert.emit(\"session_before_switch\", { reason: \"new\" }),\n+1432|\t\tundefined,\n+1433|\t\t\"an unbound extension must not block native session changes\",\n+1434|\t);\n+1435|\n+1436|\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\n+1437|\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");\n+1438|\tassert.deepEqual(readyBind.args, [\n+1439|\t\t\"api\",\n+1440|\t\t\"--adapter\",\n+1441|\t\t\"omp-spt\",\n+1442|\t\t\"bind\",\n+1443|\t\t\"ready-one\",\n+1444|\t\t\"--set-session-id\",\n+1445|\t\t\"session-1\",\n+1446|\t\t\"--type\",\n+1447|\t\t\"ready_agent\",\n+1448|\t]);\n+1449|\tassert.deepEqual(inert.children[0].args, [\n+1450|\t\t\"api\",\n+1451|\t\t\"--adapter\",\n+1452|\t\t\"omp-spt\",\n+1453|\t\t\"listen\",\n+1454|\t\t\"ready-one\",\n+1455|\t\t\"--session-id\",\n+1456|\t\t\"session-1\",\n+1457|\t]);\n+1458|\tassert.ok(\n+1459|\t\tinert.notifications.some(({ message, type }) =>\n+1460|\t\t\ttype === \"info\" && message.includes(\"ready endpoint ready-one\"),\n+1461|\t\t),\n+1462|\t);\n+1463|\tawait inert.commands.get(\"live\").handler(\"other-id\", inert.ctx);\n+1464|\tassert.equal(inert.calls.filter((call) => call.args[3] === \"bind\").length, 1);\n+1465|\tassert.ok(\n+1466|\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\n+1467|\t);\n+1468|\tawait inert.emit(\"session_shutdown\");\n+1469|\n+1470|\tlet bindAttempts = 0;\n+1471|\tconst retryable = createHarness({\n+1472|\t\tid: null,\n+1473|\t\tonRun(call) {\n+1474|\t\t\tif (call.args[3] === \"bind\") {\n+1475|\t\t\t\tbindAttempts += 1;\n+1476|\t\t\t\tif (bindAttempts === 1) throw new Error(\"identity already active\");\n+1477|\t\t\t}\n+1478|\t\t},\n+1479|\t});\n+1480|\tawait retryable.emit(\"session_start\");\n+1481|\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n+1482|\tassert.equal(retryable.children.length, 0);\n+1483|\tassert.equal(retryable.shutdowns, 0, \"a pre-token command error must keep ordinary OMP usable\");\n+1484|\tassert.ok(\n+1485|\t\tretryable.notifications.some(({ message }) => message.includes(\"identity already active\")),\n+1486|\t);\n+1487|\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n+1488|\tassert.equal(retryable.children.length, 1, \"a corrected activation may retry after a bind error\");\n+1489|\tassert.ok(\n+1490|\t\tretryable.calls\n+1491|\t\t\t.findLast((call) => call.args[3] === \"bind\")\n+1492|\t\t\t.args.includes(\"live_agent\"),\n+1493|\t);\n+1494|\tawait retryable.emit(\"session_shutdown\");\n+1495|\n+1496|\tconst headless = createHarness({ id: null, hasUI: false });\n+1497|\tawait headless.emit(\"session_start\");\n+1498|\tawait headless.commands.get(\"ready\").handler(\"\", headless.ctx);\n+1499|\tassert.deepEqual(headless.calls, []);\n+1500|\tassert.ok(\n+1501|\t\theadless.notifications.some(({ message }) => message.includes(\"requires an endpoint id\")),\n+1502|\t\t\"ordinary activation must never guess an identity when native selection is unavailable\",\n+1503|\t);\n+1504|\tawait headless.emit(\"session_shutdown\");\n+1505|}\n+1506|\n+1507|// [unit->REQ-PARITY-READY-ACTIVATION]\n+1508|async function testNativeActivationSelectionAndCompletion() {\n+1509|\tconst harness = createHarness({\n+1510|\t\tid: null,\n+1511|\t\tselectResults: [\"ready-old\"],\n+1512|\t\tonRun(call) {\n+1513|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\n+1514|\t\t\t\treturn JSON.stringify({\n+1515|\t\t\t\t\tlocal: [\n+1516|\t\t\t\t\t\t{ id: \"ready-old\", state: \"ready_agent\", alive: false },\n+1517|\t\t\t\t\t\t{ id: \"ready-busy\", state: \"ready_agent\", alive: true },\n+1518|\t\t\t\t\t\t{ id: \"live-old\", state: \"live_agent\", alive: false },\n+1519|\t\t\t\t\t],\n+1520|\t\t\t\t});\n+1521|\t\t\t}\n+1522|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+1523|\t\t\t\treturn JSON.stringify({\n+1524|\t\t\t\t\tid: call.args[3],\n+1525|\t\t\t\t\tadapter: \"omp-spt\",\n+1526|\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+1527|\t\t\t\t});\n+1528|\t\t\t}\n+1529|\t\t},\n+1530|\t});\n+1531|\tawait harness.emit(\"session_start\");\n+1532|\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\n+1533|\tassert.deepEqual(harness.selections[0].values, [\n+1534|\t\t\"ready-old\",\n+1535|\t\t\"Create a new endpoint id\",\n+1536|\t]);\n+1537|\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], \"ready-old\");\n+1538|\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\n+1539|\t\t{ value: \"ready-old\", label: \"ready-old\" },\n+1540|\t]);\n+1541|\tassert.ok(\n+1542|\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n+1543|\t\t\"selection and activation must not start an agent-managed background poll\",\n+1544|\t);\n+1545|\tawait harness.emit(\"session_shutdown\");\n+1546|}\n+1547|\n+1548|// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n+1549|async function testExplicitLiveAutoResume() {\n+1550|\tconst activity = {\n+1551|\t\told: \"2026-07-10T00:00:00.000Z\",\n+1552|\t\tnewest: \"2026-07-15T00:00:00.000Z\",\n+1553|\t};\n+1554|\tconst harness = createHarness({\n+1555|\t\tid: null,\n+1556|\t\tconfirmResults: [true],\n+1557|\t\tonRun(call) {\n+1558|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n+1559|\t\t\t\treturn JSON.stringify({\n+1560|\t\t\t\t\tlocal: [\n+1561|\t\t\t\t\t\t{ id: \"old\", state: \"live_agent\", alive: false },\n+1562|\t\t\t\t\t\t{ id: \"newest\", state: \"live_agent\", alive: false },\n+1563|\t\t\t\t\t\t{ id: \"active\", state: \"live_agent\", alive: true },\n+1564|\t\t\t\t\t\t{ id: \"foreign\", state: \"live_agent\", alive: false },\n+1565|\t\t\t\t\t],\n+1566|\t\t\t\t});\n+1567|\t\t\t}\n+1568|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+1569|\t\t\t\treturn JSON.stringify({\n+1570|\t\t\t\t\tid: call.args[3],\n+1571|\t\t\t\t\tadapter: call.args[3] === \"foreign\" ? \"claude-spt\" : \"omp-spt\",\n+1572|\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+1573|\t\t\t\t});\n+1574|\t\t\t}\n+1575|\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n+1576|\t\t\t\tconst id = call.args[3];\n+1577|\t\t\t\treturn JSON.stringify({\n+1578|\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: activity[id], text: id } }] }],\n+1579|\t\t\t\t});\n+1580|\t\t\t}\n+1581|\t\t},\n+1582|\t});\n+1583|\tawait harness.emit(\"session_start\");\n+1584|\tassert.deepEqual(harness.commands.get(\"live\").getArgumentCompletions(\"--\"), [\n+1585|\t\t{ value: \"--auto\", label: \"--auto\" },\n+1586|\t]);\n+1587|\tawait harness.commands.get(\"live\").handler(\"--auto\", harness.ctx);\n+1588|\tassert.match(harness.confirmations[0].message, /newest.*most recently active/s);\n+1589|\tconst bind = harness.calls.find((call) => call.args[3] === \"bind\");\n+1590|\tassert.equal(bind.args[4], \"newest\");\n+1591|\tassert.ok(bind.args.includes(\"live_agent\"));\n+1592|\tassert.ok(\n+1593|\t\t!harness.calls.some(\n+1594|\t\t\t(call) => call.args[2] === \"digest\" && [\"active\", \"foreign\"].includes(call.args[3]),\n+1595|\t\t),\n+1596|\t\t\"auto-resume must inspect only inactive compatible identities\",\n+1597|\t);\n+1598|\tawait harness.emit(\"session_shutdown\");\n+1599|\n+1600|\tconst declined = createHarness({\n+1601|\t\tid: null,\n+1602|\t\tconfirmResults: [false],\n+1603|\t\tonRun(call) {\n+1604|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n+1605|\t\t\t\treturn JSON.stringify({\n+1606|\t\t\t\t\tlocal: [{ id: \"prior\", state: \"live_agent\", alive: false }],\n+1607|\t\t\t\t});\n+1608|\t\t\t}\n+1609|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+1610|\t\t\t\treturn JSON.stringify({\n+1611|\t\t\t\t\tid: \"prior\",\n+1612|\t\t\t\t\tadapter: \"omp-spt\",\n+1613|\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n+1614|\t\t\t\t});\n+1615|\t\t\t}\n+1616|\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n+1617|\t\t\t\treturn JSON.stringify({\n+1618|\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: \"2026-07-15T01:00:00.000Z\" } }] }],\n+1619|\t\t\t\t});\n+1620|\t\t\t}\n+1621|\t\t},\n+1622|\t});\n+1623|\tawait declined.emit(\"session_start\");\n+1624|\tawait declined.commands.get(\"live\").handler(\"--auto\", declined.ctx);\n+1625|\tassert.equal(declined.calls.filter((call) => call.args[3] === \"bind\").length, 0);\n+1626|\tawait declined.emit(\"session_shutdown\");\n+1627|}\n+1628|\n+1629|// [unit->REQ-PARITY-STARTUP-BRIEF]\n+1630|// [unit->REQ-PARITY-TARGETED-HINTS]\n+1631|// [unit->REQ-PARITY-UPDATE-NOTICE]\n+1632|async function testStartupBriefHintsAndUpdateNotices() {\n+1633|\tconst harness = createHarness({\n+1634|\t\tcheckUpdates: true,\n+1635|\t\tfetchLatestAdapterVersion: async () => \"v0.3.0\",\n+1636|\t\tonRun(call) {\n+1637|\t\t\tif (call.args[0] === \"--version\") return \"spt 1.0.0\";\n+1638|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\n+1639|\t\t\t\treturn JSON.stringify({\n+1640|\t\t\t\t\tnotifs: [\n+1641|\t\t\t\t\t\t{\n+1642|\t\t\t\t\t\t\tfrom_id: \"spt-update\",\n+1643|\t\t\t\t\t\t\tkind: \"consent\",\n+1644|\t\t\t\t\t\t\tstate: \"seen:1\",\n+1645|\t\t\t\t\t\t\thead: \"An spt-core update v1.2.0 is available.\",\n+1646|\t\t\t\t\t\t},\n+1647|\t\t\t\t\t\t{\n+1648|\t\t\t\t\t\t\tfrom_id: \"spt-update\",\n+1649|\t\t\t\t\t\t\tkind: \"consent\",\n+1650|\t\t\t\t\t\t\tstate: \"dismissed\",\n+1651|\t\t\t\t\t\t\thead: \"An spt-core update v9.0.0 is available.\",\n+1652|\t\t\t\t\t\t},\n+1653|\t\t\t\t\t],\n+1654|\t\t\t\t});\n+1655|\t\t\t}\n+1656|\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") return \"0.2.1\";\n+1657|\t\t},\n+1658|\t});\n+1659|\tawait harness.emit(\"session_start\");\n+1660|\tconst first = await harness.emit(\"before_agent_start\", {\n+1661|\t\tprompt:\n+1662|\t\t\t\"Go live, show my endpoint identity, send a message to an agent, join two machines, and create a checkpoint.\",\n+1663|\t\tsystemPrompt: [\"base\"],\n+1664|\t});\n+1665|\tassert.equal(first.systemPrompt[0], \"base\");\n+1666|\tconst injected = first.systemPrompt.at(-1);\n+1667|\tfor (const expected of [\n+1668|\t\t\"spt whoami --json\",\n+1669|\t\t\"spt endpoint list\",\n+1670|\t\t\"spt how-to send\",\n+1671|\t\t\"commune (checkpoint mode), signoff, and role\",\n+1672|\t\t\"/ready\",\n+1673|\t\t\"/live\",\n+1674|\t\t\"spt how-to subnet\",\n+1675|\t\t\"spt --version\",\n+1676|\t\t\"spt adapter version omp-spt\",\n+1677|\t\t\"spt update\",\n+1678|\t\t\"Use extension-native `/live`\",\n+1679|\t\t\"omp-spt v0.3.0 is available\",\n+1680|\t\t\"spt adapter update omp-spt\",\n+1681|\t\t\"spt-core v1.2.0 is available\",\n+1682|\t]) {\n+1683|\t\tassert.match(injected, new RegExp(expected.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\n+1684|\t}\n+1685|\tconst quiet = await harness.emit(\"before_agent_start\", {\n+1686|\t\tprompt: \"Review live reload, identity matrices, message queues, subnet masks, and checkpoint files.\",\n+1687|\t\tsystemPrompt: [\"base\"],\n+1688|\t});\n+1689|\tassert.equal(quiet, undefined, \"related technical nouns without clear SPT intent must not hint\");\n+1690|\tawait harness.emit(\"session_shutdown\");\n+1691|\n+1692|\tconst unavailable = createHarness({\n+1693|\t\tcheckUpdates: true,\n+1694|\t\tfetchLatestAdapterVersion: async () => {\n+1695|\t\t\tthrow new Error(\"network down\");\n+1696|\t\t},\n+1697|\t\tonRun(call) {\n+1698|\t\t\tif (call.args[0] === \"--version\") throw new Error(\"version unavailable\");\n+1699|\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\n+1700|\t\t\t\tthrow new Error(\"notification store unavailable\");\n+1701|\t\t\t}\n+1702|\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") {\n+1703|\t\t\t\tthrow new Error(\"adapter version unavailable\");\n+1704|\t\t\t}\n+1705|\t\t},\n+1706|\t});\n+1707|\tawait unavailable.emit(\"session_start\");\n+1708|\tconst noClaim = await unavailable.emit(\"before_agent_start\", {\n+1709|\t\tprompt: \"Continue the task.\",\n+1710|\t\tsystemPrompt: [],\n+1711|\t});\n+1712|\tassert.ok(noClaim.systemPrompt.at(-1).includes(\"OMP SPT endpoint\"));\n+1713|\tassert.ok(!noClaim.systemPrompt.at(-1).includes(\"OMP SPT updates:\"));\n+1714|\tawait unavailable.emit(\"session_shutdown\");\n+1715|}\n+1716|\n+1717|// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n+1718|// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+1719|async function testActiveTurnBoundaryDeliveryAndFallback() {\n+1720|\tconst harness = createHarness();\n+1721|\tawait harness.emit(\"session_start\");\n+1722|\tawait harness.emit(\"agent_start\");\n+1723|\tconst firstEnvelope = '<EVENT type=\"msg\" from=\"first\">one</EVENT>';\n+1724|\tconst secondEnvelope = '<EVENT type=\"msg\" from=\"second\">two</EVENT>';\n+1725|\tharness.children[0].stdout.emit(\"data\", `${firstEnvelope}${secondEnvelope}`);\n+1726|\tawait flush();\n+1727|\tassert.deepEqual(harness.submitted, []);\n+1728|\n+1729|\tconst boundary = await harness.emit(\"context\", {\n+1730|\t\tmessages: [{ role: \"user\", content: \"operator prompt\" }],\n+1731|\t});\n+1732|\tassert.equal(\n+1733|\t\tboundary.messages.at(-1).content,\n+1734|\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\n+1735|\t\t\"the first accepted message must enter at the next model boundary\",\n+1736|\t);\n+1737|\tawait harness.emit(\"agent_end\", {\n+1738|\t\tmessages: [...boundary.messages, { role: \"assistant\", content: \"first outcome\" }],\n+1739|\t});\n+1740|\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");\n+1741|\tassert.equal(commandCalls(harness, \"send\")[0].input, \"first outcome\");\n+1742|\tassert.deepEqual(harness.clock.delays(), [0]);\n+1743|\tawait harness.clock.runNext(0);\n+1744|\tassert.deepEqual(\n+1745|\t\tharness.submitted,\n+1746|\t\t['<msg from=\"second\"/>'],\n+1747|\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\n+1748|\t);\n+1749|\tassert.ok(\n+1750|\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n+1751|\t\t\"active-turn delivery must use the extension listener, never a background poll\",\n+1752|\t);\n+1753|\tawait harness.emit(\"session_shutdown\");\n+1754|}\n+1755|\n+1756|// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+1757|async function testAbnormalTurnsRestoreReceivability() {\n+1758|\tfor (const [label, completionEvent] of [\n+1759|\t\t[\"cancelled\", \"session_stop\"],\n+1760|\t\t[\"interrupted\", \"session_stop\"],\n+1761|\t\t[\"failed\", \"agent_end\"],\n+1762|\t]) {\n+1763|\t\tconst harness = createHarness();\n+1764|\t\tawait harness.emit(\"session_start\");\n+1765|\t\tawait harness.emit(\"agent_start\");\n+1766|\t\tharness.children[0].stdout.emit(\n+1767|\t\t\t\"data\",\n+1768|\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\n+1769|\t\t);\n+1770|\t\tawait flush();\n+1771|\t\tconst boundary = await harness.emit(\"context\", {\n+1772|\t\t\tmessages: [{ role: \"user\", content: \"active work\" }],\n+1773|\t\t});\n+1774|\t\tawait harness.emit(completionEvent, { messages: boundary.messages });\n+1775|\t\tconst outcome = commandCalls(harness, \"send\")[0];\n+1776|\t\tassert.equal(outcome.args[1], label);\n+1777|\t\tassert.match(outcome.input, /turn ended without an assistant response/);\n+1778|\t\tassert.equal(stateCalls(harness).at(-1).args[4], \"idle\");\n+1779|\n+1780|\t\tharness.children[0].stdout.emit(\n+1781|\t\t\t\"data\",\n+1782|\t\t\t`<EVENT type=\"msg\" from=\"${label}-next\">next</EVENT>`,\n+1783|\t\t);\n+1784|\t\tawait flush();\n+1785|\t\tassert.deepEqual(harness.submitted, [`<msg from=\"${label}-next\"/>`]);\n+1786|\t\tawait harness.emit(\"session_shutdown\");\n+1787|\t}\n+1788|}\n+1789|\n+1790|// [unit->REQ-PARITY-PEER-SHORTFORM]\n+1791|async function testPeerShortformParsingAndDispatch() {\n+1792|\tassert.deepEqual(\n+1793|\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\n+1794|\t\t\t({ targets, body }) => ({ targets, body }),\n+1795|\t\t),\n+1796|\t\t[\n+1797|\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\n+1798|\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\n+1799|\t\t],\n+1800|\t);\n+1801|\tassert.deepEqual(\n+1802|\t\tparsePeerShortforms(\n+1803|\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\n+1804|\t\t),\n+1805|\t\t[],\n+1806|\t);\n+1807|\n+1808|\tconst harness = createHarness({\n+1809|\t\tonRun(call) {\n+1810|\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\n+1811|\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\n+1812|\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\n+1813|\t\t\t}\n+1814|\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\n+1815|\t\t},\n+1816|\t});\n+1817|\tawait harness.emit(\"session_start\");\n+1818|\tawait harness.emit(\"agent_start\");\n+1819|\tawait harness.emit(\"agent_end\", {\n+1820|\t\tmessages: [\n+1821|\t\t\t{\n+1822|\t\t\t\trole: \"assistant\",\n+1823|\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n+1824|\t\t\t},\n+1825|\t\t],\n+1826|\t});\n+1827|\tassert.deepEqual(\n+1828|\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\n+1829|\t\t[\n+1830|\t\t\t[\"alpha\", \"ship the patch\"],\n+1831|\t\t\t[\"beta\", \"ship the patch\"],\n+1832|\t\t\t[\"gamma\", \"inspect release\"],\n+1833|\t\t],\n+1834|\t);\n+1835|\tassert.equal(harness.sentMessages.length, 1);\n+1836|\tassert.deepEqual(harness.sentMessages[0].delivery, {\n+1837|\t\tdeliverAs: \"nextTurn\",\n+1838|\t\ttriggerTurn: true,\n+1839|\t});\n+1840|\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\n+1841|\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\n+1842|\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\n+1843|\n+1844|\tawait harness.emit(\"agent_start\");\n+1845|\tawait harness.emit(\"agent_end\", {\n+1846|\t\tmessages: [\n+1847|\t\t\t{\n+1848|\t\t\t\trole: \"assistant\",\n+1849|\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n+1850|\t\t\t},\n+1851|\t\t],\n+1852|\t});\n+1853|\tassert.equal(commandCalls(harness, \"send\").length, 3);\n+1854|\tassert.equal(harness.sentMessages.length, 1);\n+1855|\tawait harness.emit(\"session_shutdown\");\n+1856|}\n+1857|\n+1858|// [unit->REQ-PARITY-CHECKPOINT]\n+1859|async function testNativeCheckpointTool() {\n+1860|\tconst harness = createHarness();\n+1861|\tawait harness.emit(\"session_start\");\n+1862|\tconst tool = harness.tools.get(\"spt_checkpoint\");\n+1863|\tconst result = await tool.execute(\n+1864|\t\t\"tool-1\",\n+1865|\t\t{ wake: \"Continue release preparation.\" },\n+1866|\t\tundefined,\n+1867|\t\tundefined,\n+1868|\t\tharness.ctx,\n+1869|\t);\n+1870|\tassert.equal(result.details.ok, true);\n+1871|\tassert.equal(harness.compactions.length, 1);\n+1872|\tassert.deepEqual(harness.sentMessages[0], {\n+1873|\t\tmessage: {\n+1874|\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n+1875|\t\t\tcontent: \"Continue release preparation.\",\n+1876|\t\t\tdisplay: true,\n+1877|\t\t\tattribution: \"user\",\n+1878|\t\t},\n+1879|\t\tdelivery: { deliverAs: \"nextTurn\", triggerTurn: true },\n+1880|\t});\n+1881|\tawait harness.emit(\"session_shutdown\");\n+1882|\n+1883|\tconst ready = createHarness({ id: null });\n+1884|\tawait ready.emit(\"session_start\");\n+1885|\tawait ready.commands.get(\"ready\").handler(\"plain-ready\", ready.ctx);\n+1886|\tconst refused = await ready.tools\n+1887|\t\t.get(\"spt_checkpoint\")\n+1888|\t\t.execute(\"tool-2\", {}, undefined, undefined, ready.ctx);\n+1889|\tassert.equal(refused.isError, true);\n+1890|\tassert.equal(refused.details.reason, \"not-live\");\n+1891|\tassert.deepEqual(ready.compactions, []);\n+1892|\tawait ready.emit(\"session_shutdown\");\n+1893|\n+1894|\tconst failed = createHarness({\n+1895|\t\tonCompact() {\n+1896|\t\t\tthrow new Error(\"native compaction cancelled\");\n+1897|\t\t},\n+1898|\t});\n+1899|\tawait failed.emit(\"session_start\");\n+1900|\tconst failure = await failed.tools\n+1901|\t\t.get(\"spt_checkpoint\")\n+1902|\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\n+1903|\tassert.equal(failure.isError, true);\n+1904|\tassert.match(failure.content[0].text, /native compaction cancelled/);\n+1905|\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\n+1906|\tawait failed.emit(\"session_shutdown\");\n+1907|}\n+1908|\n 1422|await testParsingAndReplies();\n 1423|await testRunSptRejectsStdinErrorsAndHungCommands();","firstChangedLine":1422,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784191076180}}
{"type":"message","id":"7b18e231","parentId":"7ccddb70","timestamp":"2026-07-16T08:37:59.434Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding runner calls before existing code**"},{"type":"toolCall","id":"call_J3yXsKWL5xl5Qxt2CzW5grgh|fc_01ca6a8b904ff92b016a5898671498819ab6f049fef1d86f67","name":"read","arguments":{"i":"Reading expanded test runner","path":"tests/omp-extension.mjs","selector":"1895-1945"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6726,"output":54,"cacheRead":194048,"cacheWrite":0,"totalTokens":200828,"reasoningTokens":15,"cost":{"input":0.03363,"output":0.0016200000000000001,"cacheRead":0.097024,"cacheWrite":0,"total":0.132274}},"stopReason":"toolUse","timestamp":1784191076237,"responseId":"resp_01ca6a8b904ff92b016a589864a940819a92b27b9ea7005e46","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_01ca6a8b904ff92b016a5898664f64819aa1e840a46a474851","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJhnhJipC9gsfb3JWZS9c1fCrH_vLoopOmz87u2AGqXmcd3fidGLsOAZxRnVGYpXz9g5tmAvNSPzOjtnIJhPXS-bidZ2fvy9ksGZ7oeFZaZZBMjD6X8WmTAfGVu2LayJ0mxtwfUt0nlS_HS6Lb7BwrTom3ChwSzLk0uNP6AXn-JmYfIBIehibD2YTEQU0JJChnkQnxMyqe1LK_MgHYVCeKreV3mmqX377voCN4rk6F1lCKSUvjrToc29cGqDhfhARgdoMOQqaynn1WlpC_ls1tPkoqUxL7VEHKnr06yn_NiXFRQS5TK9fC8hMyQeq_rtAN104cEPj51dcnJ9leZguXU1F4nndXAOgWHiiHNb0q1hj30zUlccVeqTgxEVQZTWmlIC0-D3D6FvD1MqZ6J8L-Rx75D-tpRgO4MSxLh3jt-mHnyYQeow9sIHgYe6PtGB5yUiAAuo4WoOQuFWba5no3aKQ8RjgaTTv2_jbrHm3YOjWzpOZ5fAc6q_4b6uiIiHiTVofllkl06Rgqbcbwp6qX1pN2d6VpAdIraIf0SS4Xr3ZMfapawQ6wXA2wnwxT-weVvoVuxu9s8KHWxETIFpBlFpwpAf9oQv12xu-4jx_pydanFFmljadUcqkJrgd7UbojlTSR-GflPqXPXjunOzBcTa0dVD8C6SIz5vqFXb4AXvgwNm9vyNftbnJjXDi9Z6VUUbWd6TkANLQ3s6QIjeAHUW23G07BeVKWMw2-IbsHEUoZaZCQQm5S88QzrrsFAWQj1dJqJ4ryod55ISz-ey3XEMfp6yRP4y0aH9wOX88um62_UOiYHcyeDWBHNhSPTqNLX2G4hd32LDz_bAKz-brzxid5bB5XBA8bw2SXdD-I8QJCxnDy6mO6gtEFG4XiGGQrL1wUvXBB3XUtZTIvXODrUeHTxgPxjSLSqYORwMUgKAF_75NiRwT9yo2pn25Hl5g9AUMvMjDiA-gb1APEhbAE0HEgZaUp_thl64VRgQCy-n_nw=","summary":[{"type":"summary_text","text":"**Adding runner calls before existing code**"}]},{"id":"fc_01ca6a8b904ff92b016a5898671498819ab6f049fef1d86f67","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading expanded test runner\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1895-1945\"}","call_id":"call_J3yXsKWL5xl5Qxt2CzW5grgh","name":"read"}]},"duration":3196.157000000123,"ttft":2057.3716000001878,"contextSnapshot":{"promptTokens":200774,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_J3yXsKWL5xl5Qxt2CzW5grgh|fc_01ca6a8b904ff92b016a5898671498819ab6f049fef1d86f67","toolName":"read","startedAt":"2026-07-16T08:37:59.434Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading expanded test runner"},"id":"2eecd6a0","parentId":"7b18e231","timestamp":"2026-07-16T08:37:59.434Z"}
{"type":"message","id":"ea891655","parentId":"2eecd6a0","timestamp":"2026-07-16T08:37:59.461Z","message":{"role":"toolResult","toolCallId":"call_J3yXsKWL5xl5Qxt2CzW5grgh|fc_01ca6a8b904ff92b016a5898671498819ab6f049fef1d86f67","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#9217]\n1859:async function testNativeCheckpointTool() {\n…\n1894:\tconst failed = createHarness({\n1895:\t\tonCompact() {\n1896:\t\t\tthrow new Error(\"native compaction cancelled\");\n1897:\t\t},\n1898:\t});\n1899:\tawait failed.emit(\"session_start\");\n1900:\tconst failure = await failed.tools\n1901:\t\t.get(\"spt_checkpoint\")\n1902:\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\n1903:\tassert.equal(failure.isError, true);\n1904:\tassert.match(failure.content[0].text, /native compaction cancelled/);\n1905:\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\n1906:\tawait failed.emit(\"session_shutdown\");\n1907:}\n1908:\n1909:await testParsingAndReplies();\n1910:await testRunSptRejectsStdinErrorsAndHungCommands();\n1911:await testLifecycleCustodyAndContext();\n1912:await testDeferredBindLifecycleSerialization();\n1913:await testOutcomeSendRetriesAndExhaustion();\n1914:await testSubmissionFailureAdvancesQueue();\n1915:await testFailedIdleRecoveryFailsClosed();\n1916:await testListenerRestartExhaustion();\n1917:await testListenerStableIntervalResetsRetries();\n1918:await testFatalTeardownAwaitsInFlightOutcome();\n1919:await testSessionEndRetriesAfterTransientFailure();\n1920:await testHumanBusyFailureFailsClosed();\n1921:await testShutdownReapsAndFailsQueuedCustody();\n1922:await testListenerTerminationEscalatesAndReaps();\n1923:await testProtocolCorruptionFailsClosed();\n1924:await testInboundQueueOverflowReturnsAcceptedCustody();\n1925:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n1926:await testShutdownFallbackStaysBelowHostCap();\n1927:\n1928:console.log(\"OMP-EXTENSION OK\");\n1929:"}],"details":{"displayContent":{"text":"async function testNativeCheckpointTool() {\n…\n\tconst failed = createHarness({\r\n\t\tonCompact() {\r\n\t\t\tthrow new Error(\"native compaction cancelled\");\r\n\t\t},\r\n\t});\r\n\tawait failed.emit(\"session_start\");\r\n\tconst failure = await failed.tools\r\n\t\t.get(\"spt_checkpoint\")\r\n\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\r\n\tassert.equal(failure.isError, true);\r\n\tassert.match(failure.content[0].text, /native compaction cancelled/);\r\n\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\r\n\tawait failed.emit(\"session_shutdown\");\r\n}\r\n\r\nawait testParsingAndReplies();\r\nawait testRunSptRejectsStdinErrorsAndHungCommands();\r\nawait testLifecycleCustodyAndContext();\r\nawait testDeferredBindLifecycleSerialization();\r\nawait testOutcomeSendRetriesAndExhaustion();\r\nawait testSubmissionFailureAdvancesQueue();\r\nawait testFailedIdleRecoveryFailsClosed();\r\nawait testListenerRestartExhaustion();\r\nawait testListenerStableIntervalResetsRetries();\r\nawait testFatalTeardownAwaitsInFlightOutcome();\r\nawait testSessionEndRetriesAfterTransientFailure();\r\nawait testHumanBusyFailureFailsClosed();\r\nawait testShutdownReapsAndFailsQueuedCustody();\r\nawait testListenerTerminationEscalatesAndReaps();\r\nawait testProtocolCorruptionFailsClosed();\r\nawait testInboundQueueOverflowReturnsAcceptedCustody();\r\nawait testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\r\nawait testShutdownFallbackStaysBelowHostCap();\r\n\r\nconsole.log(\"OMP-EXTENSION OK\");\r\n","startLine":1859,"lineNumbers":[1859,null,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"}}},"isError":false,"timestamp":1784191079460}}
{"type":"message","id":"443926d3","parentId":"ea891655","timestamp":"2026-07-16T08:38:04.576Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning insertion of calls post-parsing**"},{"type":"toolCall","id":"call_Hh4Yk5UUIu7uk3vZxUlNZyiZ|ctc_0e693d04e6232e51016a58986ad1fc819995016f708a79b7a7","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#9217]\nINS.POST 1926:\n+await testNativeActivationCommandsAndErrors();\n+await testNativeActivationSelectionAndCompletion();\n+await testExplicitLiveAutoResume();\n+await testStartupBriefHintsAndUpdateNotices();\n+await testActiveTurnBoundaryDeliveryAndFallback();\n+await testAbnormalTurnsRestoreReceivability();\n+await testPeerShortformParsingAndDispatch();\n+await testNativeCheckpointTool();\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1069,"output":122,"cacheRead":200192,"cacheWrite":0,"totalTokens":201383,"reasoningTokens":10,"cost":{"input":0.005345000000000001,"output":0.00366,"cacheRead":0.10009599999999999,"cacheWrite":0,"total":0.10910099999999999}},"stopReason":"toolUse","timestamp":1784191079523,"responseId":"resp_0e693d04e6232e51016a589868772c8199a8778c59ae5c75f9","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0e693d04e6232e51016a58986a214c8199b6f97525e6b9c359","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJhqWKAcveqvdVxU1WLL8rBsX_MKQt8AAEqZwR3ei6s8SWAMrm4b6-pUp9pwGr8r2-kD8GCV0BjthfWEiwOamv51DblUYS2b825YYZiERjsuaXupBG68njUlWzFPDbwW3dGqCoP-E01qxTe4FYucALxGDDBRbm_nHtQUaK30QIuCBZboLC0EwbcOTmsPhhrK0iKrJN88FoKQWaoBQoyeM-LFRmyyeFsEoQnHT65LDFndYxDRMiz9Z5bjtbPOVwIqAedMCDGB2dIk20fKQWcXE_ga_5Moqc7qmc2LuXHBAcZVPR3m-4c5TJ6IOF8RiBT3_hQp5jKlYQQheg232BrCgSl9xAUNchGNkkJG0l8tVEEmlsQkcV5l0GUixKuIvut8EU-OhsK3W0vj1RObZSrov-tcTQJFrLKHtasfBwTLuIa8bpQFihA7ctJAzIEvZZ3ChkDjAGQEqz5m0xYf_mtgvPeE3XCfMt6YJ-tTIep4IWvjHzepEagalz30LBeKeJGlzz_0LlLhh2yZAO3ILljhk3an94pnEr7RYkAXIFhL8MHQqZU4Z2h99kSUHDCAY5xMWM_qh8gBv-IlzICsVWWNW9RzgAv19F53YTjQDn5JxuRcFwBoJ5LQQxQ5-a_hlqUPRiKj_PTkQwUhZcaGmUHTJUP9mweBcEwwHk6Fnp1XFe6eZjPoI_FwDBOD6k3eU1bwdeWa31qGgAwHAoc__zLb5Pfy3Pf_hxe7oQ-sQRYydEl6vWEf1Ard6H63rCAtskueTyV9FR5l1-iJUGlA0Nox11WbKJvN1_zv9mV4T1XhqFT2NTMycUaLEpim0XdKDFo4GwaJMtRbPCmUnGJtAdzsJ6BEejAo_phTMIvHUwJd5teba9KNRWNRgxpMcMqSuJrPrLGmuHeIquBF7MsPePgN_vy7Bo1Z-sbjK_eO3x4UT73ebW_XDo5tHJi_Kvhgg639MRTTYwDE9zRMZXxef2z4nFzv4g==","summary":[{"type":"summary_text","text":"**Planning insertion of calls post-parsing**"}]},{"id":"ctc_0e693d04e6232e51016a58986ad1fc819995016f708a79b7a7","type":"custom_tool_call","status":"completed","call_id":"call_Hh4Yk5UUIu7uk3vZxUlNZyiZ","input":"*** Begin Patch\n[tests/omp-extension.mjs#9217]\nINS.POST 1926:\n+await testNativeActivationCommandsAndErrors();\n+await testNativeActivationSelectionAndCompletion();\n+await testExplicitLiveAutoResume();\n+await testStartupBriefHintsAndUpdateNotices();\n+await testActiveTurnBoundaryDeliveryAndFallback();\n+await testAbnormalTurnsRestoreReceivability();\n+await testPeerShortformParsingAndDispatch();\n+await testNativeCheckpointTool();\n*** End Patch\n","name":"edit"}]},"duration":5053.471000000369,"ttft":2588.597500000149,"contextSnapshot":{"promptTokens":201261,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Hh4Yk5UUIu7uk3vZxUlNZyiZ|ctc_0e693d04e6232e51016a58986ad1fc819995016f708a79b7a7","toolName":"edit","startedAt":"2026-07-16T08:38:04.577Z"},"id":"f75bb230","parentId":"443926d3","timestamp":"2026-07-16T08:38:04.577Z"}
{"type":"message","id":"f64ca7ee","parentId":"f75bb230","timestamp":"2026-07-16T08:38:04.610Z","message":{"role":"toolResult","toolCallId":"call_Hh4Yk5UUIu7uk3vZxUlNZyiZ|ctc_0e693d04e6232e51016a58986ad1fc819995016f708a79b7a7","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#00DB]\n1925:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n1926:await testShutdownFallbackStaysBelowHostCap();\n1927:await testNativeActivationCommandsAndErrors();\n1928:await testNativeActivationSelectionAndCompletion();\n…\n1933:await testPeerShortformParsingAndDispatch();\n1934:await testNativeCheckpointTool();\n1935:\n1936:console.log(\"OMP-EXTENSION OK\");"}],"details":{"diff":" 1925|await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n 1926|await testShutdownFallbackStaysBelowHostCap();\n+1927|await testNativeActivationCommandsAndErrors();\n+1928|await testNativeActivationSelectionAndCompletion();\n+1929|await testExplicitLiveAutoResume();\n+1930|await testStartupBriefHintsAndUpdateNotices();\n+1931|await testActiveTurnBoundaryDeliveryAndFallback();\n+1932|await testAbnormalTurnsRestoreReceivability();\n+1933|await testPeerShortformParsingAndDispatch();\n+1934|await testNativeCheckpointTool();\n 1927|\n 1928|console.log(\"OMP-EXTENSION OK\");","firstChangedLine":1926,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784191084609}}
{"type":"message","id":"8d08c3ad","parentId":"f64ca7ee","timestamp":"2026-07-16T08:38:08.404Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Running test suite**"},{"type":"toolCall","id":"call_5AaS7SQcl2RGtryLiUwAj9fU|fc_0496e334b7a6b34c016a58986fd6588198b22fd3780a122c01","name":"bash","arguments":{"i":"Running expanded extension tests","command":"node tests/omp-extension.mjs","cwd":".","timeout":180}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1298,"output":48,"cacheRead":200192,"cacheWrite":0,"totalTokens":201538,"reasoningTokens":7,"cost":{"input":0.00649,"output":0.00144,"cacheRead":0.10009599999999999,"cacheWrite":0,"total":0.10802599999999998}},"stopReason":"toolUse","timestamp":1784191084661,"responseId":"resp_0496e334b7a6b34c016a58986d2e1081988bd9099a8798aa48","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0496e334b7a6b34c016a58986f31f481988a40691333333127","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJhvxhziPMBEKZq2MAagpfrD8HtGGnblenSOrAEF-pZIn8XBsyiIHXn0wlzOECNQpZADzlUTrBi7kJ971TxmBLUm3tj1zrCCHfCmPMgMWPXAPSMxm4kREXkZBJQB3yXYIPBs9hBAhVUFbv3wShoGf_tgN7G3BeoYreA1ppUxIgDfaM-lU3jdLwiY78oiyrFwZ79QOgty-B_J_BPdaAIQg6jIBDvrHuHxCqoym6QfDFtboF30F08d7llm1slumaQy3a_rvdXcWhuy-5OS-fGE3Pd_IgDXEwqZ9GYhTztFnqdJzK_T11lqSEQQuvpMpviB5WqYdZYRXaAxdyFFIBa_FyyXa1XP5QlaDTi7RUExq8OYsUPYbiWth_rsZqWQvre0wsG6KFLHSFOG18hmt8VGmYN-GxnQALipTRtiCzkuMM2qHwtP2FUfMZnqiFUplLegS2A3Hu9W7Nx8jGMkHI7iaT2DQEBs6VycgWYbagwxgUJUEyUjQEshkvPGJn42EezMogaNfj_-5gPd_vNb3NnDFKtsCBbJXCDisb1Kdb0P6q_mt8HGzyi_v2vylA128uXPqLxAUVb0EE6XHUarSGrgU5eKgtvROLtL71tT6XIE5FlDiE3Y_5eJQSppu7iKDE1Y0WqIqZGZ9xjdWn3qZADYh4MZp3MGtvnW68oKuybVucRmsTcWECa9IMZ04KDu9pL4KmMBya2yth_s0vQRGY1Tc55sKVAuMiBz8gudkf5anPIdOHU_gCMHDTTwCbE3Cc-hETy2G0kpnSNcN7guG4Eu4BiP1ms_MDymkSPS2yU6oD_mCe1gKnRULYUBFbS-cIQ-LFCwoepkw19cHa2ICySW1vZ79vpJOhyDMobYjWlrHG4UTDOktIWURLNCcXRUvKedWKLyCwUap5V086rF_A29VM3UkADKXGPj50zE3HPD-hNDkiQ=","summary":[{"type":"summary_text","text":"**Running test suite**"}]},{"id":"fc_0496e334b7a6b34c016a58986fd6588198b22fd3780a122c01","type":"function_call","status":"completed","arguments":"{\"i\":\"Running expanded extension tests\",\"command\":\"node tests/omp-extension.mjs\",\"cwd\":\".\",\"timeout\":180}","call_id":"call_5AaS7SQcl2RGtryLiUwAj9fU","name":"bash"}]},"duration":3742.3759999996983,"ttft":2519.641399999615,"contextSnapshot":{"promptTokens":201490,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_5AaS7SQcl2RGtryLiUwAj9fU|fc_0496e334b7a6b34c016a58986fd6588198b22fd3780a122c01","toolName":"bash","startedAt":"2026-07-16T08:38:08.404Z","args":{"command":"node tests/omp-extension.mjs"},"intent":"Running expanded extension tests"},"id":"cf3137ad","parentId":"8d08c3ad","timestamp":"2026-07-16T08:38:08.404Z"}
{"type":"message","id":"6b0c1316","parentId":"cf3137ad","timestamp":"2026-07-16T08:38:08.515Z","message":{"role":"toolResult","toolCallId":"call_5AaS7SQcl2RGtryLiUwAj9fU|fc_0496e334b7a6b34c016a58986fd6588198b22fd3780a122c01","toolName":"bash","content":[{"type":"text","text":"OMP-EXTENSION OK\n\n\nWall time: 0.11 seconds"}],"details":{"timeoutSeconds":180,"wallTimeMs":109.54190000006929},"isError":false,"timestamp":1784191088514}}
{"type":"message","id":"74ad8e4e","parentId":"6b0c1316","timestamp":"2026-07-16T08:38:35.007Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Verifying test coverage completeness**\n\n**Analyzing event boundary handling for tool calls**\n\n**Exploring message injection timing during tool calls**"},{"type":"thinking","thinking":"**Clarifying tool_call event handler sequencing**\n\n**Optimizing concurrent command dispatching**\n\n**Implementing concurrent queue dispatching**"},{"type":"thinking","thinking":"**Assessing GitHub release access and checkpointing**\n\n**Sending final contract**"},{"type":"toolCall","id":"call_Ua4etfcXZAMGMCxQsI285FsA|fc_0ff2ef0eedd80baf016a589888e41c8199950f81d379e131d6","name":"irc","arguments":{"i":"Confirming checkpoint wake contract","op":"send","to":"AgentSurface","message":"Checkpoint seam landed as tool `spt_checkpoint({wake?})`: requires active live endpoint, calls `ctx.compact(...)`, then `pi.sendMessage` with `{deliverAs:'nextTurn', triggerTurn:true}` (not followUp—the public OMP docs guarantee hidden post-teardown continuation for nextTurn). It returns observable ok/error and never wakes after compaction failure. Please align skill wording/tests.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":347,"output":1331,"cacheRead":201216,"cacheWrite":0,"totalTokens":202894,"reasoningTokens":1192,"cost":{"input":0.0017350000000000002,"output":0.03993,"cacheRead":0.10060799999999999,"cacheWrite":0,"total":0.14227299999999998}},"stopReason":"toolUse","timestamp":1784191088552,"responseId":"resp_0ff2ef0eedd80baf016a58987106508199a715fca24b90b3de","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0ff2ef0eedd80baf016a589872ec5c8199be7af686a3fbca72","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJh8SyTMkXGbgQGUnp5qlHA5Jp_-Ntt3qCIw_qu2x46k9Yss4GSpmsRNYBHNmSgzN5Wxn4EkQomsghod0QvWweSfeKc5uksp7avmH79AG7BZT8nxhb4NluiLktUdd6YiLc_du3qLk-wNG_G8XZyzgu6TE_pIyOMeiQeIoxFwS-cLkGwLiu7DQWQUiHvRwFawpJe8NModfzP9bBKjVLex1e91inqM8Cm2L0f8CAMYuSYw7NLKvGVczMvKAyZjLJv5A7fwGshrm7SKFT9dTk5I4yqIdz4SZDA1y5eKufKY5fXwJB_nVmMzgiwiAMDBK3crZ0yRgdU50jZJtjsIqL9EFuVF9dnYx3M9uzUJYSsMFEkErDVpTGskoK8_vn_4uy8_UUA5SVgEeYobRbJ0v3zeLJrPfvZDuR0bMGwfcPN_yMF7FJP_lQ9m6L_noNhL33-8aeo3RXxuI9xW0Yfj87Lq4QzEzO6Xz72xQ1rsshDrLYhNAdaWL1SgIs3uNEdPOvqqFB0h7onmTVHb26P6dm1okBh4QuUwOwKe_xO7iEHKp5XIcNB-YiWDz0itprjD0dV_qhW-2NpfX6ZVMuSbi0FXg3CdMSyWI7R9jg2fA6uje7elGi1YOXtJl_Rq0f6usUu3edpl6PpdTuSEgs9s8i-VuF35BM9aqJ9QRn60QbCaL_I_xi8RC5CL_p-hbDfwlr7qgdKeLK02lx3HyuwUAp3_aidjCJbI3ZNBxNmJfij1aN295F0WWUHfJ98plcuoAExHT0l8vIDPqilPb5sOuVpntE1quJNrhbFmPI0fwDh7mDMzA_l0RZFHBpSwiYLk6FeG86APlGXJM9ikPVhFyX4SnmgrxcdxmdVvy5el1AcMWyYTGmveO98ETut66F3w4zDoIJB190qdEnK2bgL6AvKbceu4V6oHC7WM4tXViydWJsIBl1RvngJ9yRs9vdINNGFzOSIUQFe6rnVcnaQuWxl0Xc4h9oYVAhpVwQKVv5yh7y0Zs9c4bh0zcJ4zLgI6bSQlgP5L44IkyDmwdoK4zYljzmg-EDONmn6Wbc0mJFgrbXf8RbBX_Og2aRh8QlTQt63zNKWKrPc45TMhuiro_pZz0m9pUveZzHkX1T1xbzle2gLNN4MNe2_lDNOlZ-Ncb_stOYd0QkXI7SJR10GpVA6Pqs8wZbXfzKQ_jQPlzot-qqM4Pcucqby32M11srmmOII2Qh4WBXrqjdYFLytsATDV8KdRhDvcs3OT3dZBzEm7RdPh8pHozG64am422uZvrMjuyJ2BiHVKjjDElaTXsXOxBtte0XZ1O6rGlYKbA0epj3AlP2MC6AfEIuXLM9usDPCSHh6I6Vrjh-S074Zyg5c8Eb8Wz548Ng8dkFkXgJZhvERIfU-P7zL64oGZ-EXRQJqsjMznSvrF552SKLKv6zKS1Rg30CbnqTy0TnCG9tliGe71Fq3yKyX6P9Ns9TptpxUqvNrdNTE2vFU3eUmSJZktOxKQRMQVW0Sb1fOqOn5XR17Eihzx1rDh2FrIKgAVNgl6I8GjHX5VfKMk5bgAPOD4FqsYQIVMkwVLLp9CkYZnNDczLjnjqWT5nODav6r0Qb4W1KxBvF1w289ho0R4LHjwBCWyNkZtG5dGWKPhinJE9cYz-xNqGR4L5a8K9B6OohiIddXL6AAT97u3ruDBMKlzxswlQl1xjJUMJjMNWlNYT6_il6yT_yBKjXlEedGyTzpuDqofJyzJKPcNN-dEN9HpKgZrnZ_A_n5BMUEEl5-3c7hFnIrmQgqCKfGzNW-3SdJNojpsyOo9Qm9UuBvN7EL-lCYb1ibSgR3bhjtqoBYVpKXQ-AuWHpkGHbHzrz6mR_vg32vljCrvN5HUh8IoJeJrczZKyQILD-39VQWSR5kF4VcYzkaZli9uYXXeXqtdqPSKtpWRBv-Zz4OLaIbVEpHpYXHjhX4a3YmP2fY122xbhB2UpYnpP5aesI_hGlydGPFvHnRPyZqRX70MvAQ-I2v27tW73HQPpl734gRNMfy2bu1eYwFaBMR_egljNl95WzKdPbvLdGckeLIvto86Nl2eq9ZyVGiZQ3iku_OPUsP9-2IqNjNzvnhn0uppbfyyYdWtLRwYDhI75ySMf2SvvHrDH7xRbGmkpmjuJFHSNiJpuVYhB0DXrWoGTnqbvtrH0yi7DN6cinfSLym98BE7T8kbXPaMf7Y5w7lGW1keUCPzaX2pXDwV44n1jsjR0hZhoQfM6ugwvLk1CwV6sQzrlwsPoJfDBibu_9XaTvwsxQ-ilO3TjMGQjPxkEvgRA90FTbbDFP_eKS6mOfAZL596pJhnPTiEbDyij0fQGfIeHFA5K8ZITANW5Qz8AArpJZYwhs1tA75KAZbQ9OTAkYylb0wABlqVqkQAtM3x45avW2ir0gTHGXZFmkwue2yxV1IwUS_6PgGcyb24iqFNG5lYlgYR5Rx61lAOg6Q8uzosOWkq44ajAy9hUmm1ITxq0FJ-0ZRib4fRdjOpxmbC1K-67i_lfpxakxGntozycYDvFa-ME7vvN7j5JrAHKP338FIAXUeLvrDfrS5_nYqFJX31t5tWYk2JH7dQ52yG0kE7KyO2B87u0tt_CryQpd79cwfmqxLWFxq66pqpq99TFW053XZcC-uy82GpFB5OASmkz1NlzN4rtzPVEITwn-WKQ7r-JoXyVullDKN3O0vrdHJOHUZuRtcdteLlsxfMQ9zrGqrM97Wm0vprh8gXrTF-gJ_gCclFvz11oglf6oNSk149wSk15ezeUminZ6rE2r-xrxhQzV2Tqs80KxkCUkCLJYC7sjF8YkkhpR1B9yGNhZITltmA8TYyQHtVnZxCFQhB4Pw6Lbl_CmYvDEbknCBy7GLLCPmcAeKkFZJH8jfhtLabX8fPWU8-AUk_ZYb-meRWdoep21mOEZQKuB7Vko1pIUkQXd-mDE2s7slhZo5q-aCmApBTTNPfJdaSLH3G5ZRIY0HoobX2nBnZuJqiE07h76k15kk4F_HIDP9jk6n1QpLb7x_bt7CXYX0Rc1cBEfjwQNWrt12zhxmoL0LSigsf7rjso5iX9efl3xWbDpnglZH58BI8bYxbwmYJ2KofbYbOxqQelP3S9Sdsmaln7Xx-CpUpqIxBmYX6JHribe993w4Ao6DDZ0X7A7PLkU7U3XoPxN-mSRQPnlXe4DZrCb5mZ1Ey3GqcAyFBahxGmCWwYed4KA92oTEP73JHGsaPkEj50RZ3lKSHWPDMHQkpSc7FeZGfGDx_hiZTGuUo5WgtrAvP_esYVn7Pnx7MUWRpYMh9olEjj_NDLnB9J8zMfOS2I1HiLQnGJbLntLUYRsVI0RtZRCbmYR2cqrXek1TagHnSo6DCmmOokk7X26Vg_2hsfXq645cxu-VAXGWNKYOpwf66P9swihIbB-Hx-gqLVt1VFiVylf9c4lV623M3CKWMtcyGBK3QHt2fDiuj9lx2ehmSSQ6nsbwTJeZ6octYWApkIYWcNDutqOV9l_cmhiq0ZdGz5tITDQ2HuuQrCm430KWmBptorygSCdiAPTK5_9KRq0BVO2YwdRHvFU2DaTL5ikxcJEq-GfS6PT0Az2Nj5QkkuObslLxJkMi6xwcLHiSJmmSNKsDGeejgAbDwnP1WzyJ7e6l-I57gSvqM3e-8lbxF2RO4j8eoeKZ8ZI_8R0o59jlGxQwGgx9Q0ZLoUGttTU8yOeobds3YMYfCaShbXrAwgirJ1er8HmMrGrqnRBJd3a3V_4aa4pBvhjqXZ6A6W298Q4tUjE1rns_5613Q3iP4Grd_cHNPwJYb8yHfmy0aNZuj6YVu8qgWyyUzEZa7eZo0Cp3NBGlD-h46METuz6llN-zPvCcLaHR4Yj5Az6uRxqkuHq3VW6A9NkD0ECpxMVZKl3Ck25TyHO7iG9oKS64uv8bS583J0ICgbRcNrNIUExjz0GbnHerGQxXSp4Q2fhZWMkANb04HVYKhbbLacf_6lJAS0lnERD1G1gjlxC1hLPDAklWWnswmsD2LfqGjICwaPSuYHTKyzuqQ567t5764nSpkH87jMkrOTMVt9K3qnWwxkOI9K1G6X09-1TLQXQ9Vpn3clvLh9zAGaqHEY6iMJmH4C47KEy0atji7bwN4rbAi2yKjtjZzsK7Ga-QameI5iB5nb6bdoiQjVT84HooW8BiCS8fu6wTJ9lyNUS1Z9-pWBt6LZGReIAAgERCy75le8OVjfJYdE1Ljy97IKFAMnz4Ipa_NvvBZgSXZY-9GyoMy4tR_xJjsl28eCQUhUeuTEc2BWYGr7GG9rmkeKr1DIS5nf0AuhZOH2gUiP6BOR4KG_f2IH7fXStDTxtR7_GaBnISNVM-wPvThDvmGg_wQrzXQcqt65Zh-70fy2d1XnSOPamaDxtCHhuCpd9WFxwauGRIYBeUCqA-g2ET5h-rqyCc_sqo-0ZMbbH_EvMa8pQ0Kq6AlOhqC0vd6ibjd-GRqrtCOmh32unwjAwotMDiDIu71mhs7xw==","summary":[{"type":"summary_text","text":"**Verifying test coverage completeness**"},{"type":"summary_text","text":"**Analyzing event boundary handling for tool calls**"},{"type":"summary_text","text":"**Exploring message injection timing during tool calls**"}]},{"id":"rs_0ff2ef0eedd80baf016a58987ccc908199b39c6dd488e44ac2","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJiGA6UdwYUM-37zxYygOpMhsSX_jKDic1pTpD76Eq6lbL-VM7DXa6gyMrlzS6RZNhAkFRh67XQ9UAoEHZkywFMYfTzZYqfi-1DeHq3iZsG26Lr1tvgGody2EWOycidaLzPQYb1Pw4QwmLSyyv-up-rKFWGuF4wHOXlTzCTVkoZpJDFO6ppuBBDgTNuAZildKs0XDwTttqemb0msuvjGn3dr2_t7-taKe--JKEErinF3tIb8zlDz1ErKz867VTDJ6AST4LWNklqxmJJno6XfD5u-jFdlWTDrMO4zZUc_RKe5NNHrMsGJ4PLDobvLh2V4KO_a7f_fPvn1vX411C5yqMSAuZ4tO2WZv3jPTwttq3PTJkpz9TJQ3y8r3HIFXN-_Vc2sTPJvQOLNzokgyC37q501EhMoNbfRAQTTigKnZloeT6MU-KRS8HUBPS0pFtf975iTnjAqdLV--2pUzX7aB51zB0pu3GrfxdJ5ky3JQwliwhy_uQVZH0dSnxJXENQOTQt0ZYRu8qm5HF7E7-Xo7CPoF_BQbX5P2C1kXJNHHhpPnT-1qVk5Uhh_zpWdfaiJSqjQJeZtJoXwvuci7hq5zRiEDYVw0vjxRa3YufSzp5Q2YCCSaQSxhu2RprFd-y5Aj-CNm8Cg9IiHeYJgR9CtfvIY_bsDvaM1C5TbOl_iIZZXT5uS8WbpYymD_BmcofZCvTklMAqNkiJeU6fq8cNvSodtP3IE5utE3q_mqJRfFQfW8KYaR9TY99mKfBp-Pax8xwF-4mM2FhUxbNHvH5H2jVIz3pHt_iKxS-npwD70-bK_V0Zo_0OUGMj9ceUp6DvgSOzZM79EtTn4VyLJye_i6euDuiWzj6T7bjLKf7HIlIp7JfoIEW4p9UqkQVqu0FvSxkBJYmpp9dEN6jJZ6TxAwRfKbaqstWC_9TIkhSDVmHkFjkAbduCBX66SjVIy1TSu9ZvND5MUJ_Y566iHOgr4AeT4r3PhyLREmgYm8YKutKdYS6jGzGqNxPc9yxYzOw-89KyjR9yGi2Y2-Jif6DxWLcuSUQDvQGSJpOFgGYSwgT9gYjC01SQLmKwwHD8PB-PgYFWuUwm0KegnrJLtGoql9BTirfRbIZWbIm5QmGaUzBHAkvYjGQGxOoAVxTRuHrwmpIsIBOePK_Ea5iGgujEpCoc5v6RwumSifuQwdiPqo0JxsaKBZT-k25w3XMC78gdl23CdtVSjB0Dc7mHJ_BHVJypc-hDrd89Qaqg_39QSE9T65ih3PlbdY0nstWr7kZYUoU2V8uKWsHfTYyyr9DifjGl4eG_begAgkpGXawq_zZAbG7GKLhywxkp3PX2LOTQ2nrjHnTqQcVPvNZTi7rr0-q6U5vCdOutGYdyOu6CJMHE_8-NNOtOextmYQjf1CJXoQtyVGDdmZnYBkLU9rOaPA7tIJzH5miipFR65D96VTpIgCjzMkRxIAhDHp1s3AxnG69XS3Zb_JCIMKJS84jDGhBfNXIqPY4ijUUR94yTvqDdzQNNnwN7pTAWxWHS8ub8g7eEH0LiXl2yue-tnsJB2zriz8NtmY_W-H981IFwpARRJh3UCYCOAPLBIZZWaPbLIn7nYAMSXZ9kQGpKkju7JPhdOYeR7hgSkwJ-c694RjE0vzC0LvPW2hBRgzhKu4_sqYKUdcQNnLj-6piD7fjfY9wbO5LuprE3mjar46sXFHiuDyk3SUpsM5tGm7-G8MC3nTIchybj8sG7rx9dfaUdDdIeVVZeKh-KIsn9aXxSjQwLiflHnQlSTLxJ_GLs6OBp9sCQzDGLfuZPikHR9rtw3OkaLADXRoS4zphbOLx1A6R4vtapvZDM6USb9tSPuoI7_9w8LngUw0egv7_GZV7T-WQlPBYa-TfB_eah2gg-2MzBVP5m_iZlki90FYyoeO-q5BkrPPBo3OiCSs1c2rSsXfxW9GlscA9aDuhmWKyVlVzm7rOmptHS09TsMhiz8VRAqWDKiJ6mBs8rSFYMyRaWx95-_6-6vlnssnG_oVRRJx86ctHPkHIl0d-KB0RkglKENEVbQsiiO3T7JtV4YOUmN7u55dVBDB3JTdQ3bAjXs2DsBIAgtCnxehJwRfd1T3rAZBYoIiK8iNrFPTjU8zY6Zq_sNVmbLqJ5sXJ3eWxXNkVLwg77cbGT9dpMEndXQ_tve-ZM0tBARoX4ulsohofWJykGi56d3q8c0us1MKgYW9W2xk3vuj8OpNQuwBXQBg0B0EmsTON6ir4Pjd4YSRGTgZdzwBbIUOvjmnEpPEVRZomuat5d-zrYH2Z0rNaKfMpQlFaAfqohyrb0hxvHjbqHt3vAHSoG2zWKGUKL2fjJlwfJZYhkB9om9nUNfBo-riasSgO2e1o4TOJ9jzxdYYauVX_fUyBhHowWaLLSsbC3rBXGkKKEKJtvxHNhemOjizgkmiATP1IdPeDrzDJUjYXLnfsB31R5V_c2FY91bc6ldZ9wtVHUo3VtbpFls7RU_kFgTRBzreaKuLnygYxbSuVUefHCojfGSpuQTOiytapFmhwg-PqwFWl0icfX-obOAJo6h1rSaVZw8P3VIqKWMQNTYd4gXNR1TzGOisKnPJlUlcRun-MbvXolpIxf_n6HPdLQ6sv3LkLyiU3cPWF6t6NWHbWxu1G-_yu4O8Lvmuf_pJZiPXa2K48IxbaQHTexSo6xYDbcHyMDQJ3-tcE614_HjZPdzA-bRwHzLrBdUT6EhZnKgfQdPALb12vd6ze3-XTAUNnH0OYfsvpM15Mi--SuAOuGB9Yb3_heaYI0RvfmAr1tOEtAHD_U7cCJU6q2cQv0TarRF-uokKKnxGcsn9iLTsaJ_i1wr4EUzqBHQAFM_rfjEgCTOg9Y9NLiX0pxb9TYru_cQ4MNnJ7RTj2o4-YJHyyFVKMkGmZtu5q1yMZXlN8iWUNZqhGiiJvJzmP76vvp7gECFv_NDJBJ3uzURd5TxALiaqS6rlYjpCPi_KkXjrKuNd0x34fOb0kxASTemDCZu8_BzQN_MvWizZpwSq5v1f7PVtEKal3puFBXPrionusZt5bIaXY0673WofX174XXYpLyVBJFjSj43zseVezx3HxmdWMm_KK59dJyHscxRu6UMPwoJFUpIMPu5AHHBitsFYFzvpEDXy3Cnr08ghhJ6Bw1VchjKaeRKUQMjxhu6Gh2_MzJhJzlGgi8I_Xfiw3bt1_JAvVeziySYhpxOl3nTxkLgRcyEKEjQSnOxiILCt4Q07roufuv1fGAujrBdiugFP4_oS7FY2iSMy-6mhfKDsaHdqt2ot96-GQXTnr8VZB0L8Go2Oc0ua8rw7Jw0CqIVbPdg7qiHUzfkxO-3zVDT4818zK6D8kTQXPlzPg9Ndd0yCdlIJ64V6zJqSYZvISfztr2npbDSRjiuedr3VMeiVSP1JCbBOJmgiLUkKcZju5w7FF13y1WKTapM_1UDBTcLN8WFevpxPtgrUIGeGW8fboLRtupTHEB2dr8QuXxD6GmE6YR33y0ZdG-fcRtrfYhzSZVNjw8vPDr4tPEQyqF4_yNRUkYwc2kBgtdJCFVesWt3M6dAUBYhBPM_giHcSErCJYaUuPPuQJJK6z9ck0LY-EcLAUFwEqxHJFufNlTKx3m3N7-ashdB70Yj37f06a0omGrs5fOLbIr7J6wncZSOHxKEmYScXnasHX3UZ2TgZw3MDj_Tcl10KBRBHUogeDN5Me4bTx0X_vnKxeApHc60WkXjUpr3Ry_pwu25Kl6vU0PEEw6FUe2OonbiU2VUGPuju6cKiDsHRX29dpEWkKKvw9yW9CFjFN-FfoQP_NXhoKXj-K-hYQANrRgY5uVlQLxxiDWm7rW5mfkJwLNJSAdwYFJ46pfiKJppSvckxqhXELpPJP7it7ARJLkcnEH8yv6iNUcl_j_88IeefvX-TSO57w5faAUUI515fynlb0iRQsQfA1EBFXvGyfei2cm4_nmo4GZSWc734b9b2HaUh5fMsOSfRoz39cnx8bIVvRPCNkHjhXwV3tMahn64-XRyBEfM1lJ0Jr8ZVvN2Z__QfHVulq3WGv_qAkx37nlnzVEvCDeelp9l4xK7Ip2Q6rCC8kt4oNnqy863QUnw9Kne3iMkOwsdPcwijAY9tDIY-duPSgwAOwLYu7sdSf3gz2lvDcleYe2_7OZPp8aE5WN2GDBLNHswJ0tj-mN6v2g_T5N14tsw2u5coxc2VoaTHppZedh0H-a154ZxvmEKWjkWM6lmSM2JJIULs-ZmKSzxGnU6dY7xHdJajzd-ieqHCI2q0gTfXwfcyxYaFMO0gQ-xGub9rHjR3pP2lSGBX5PQGDFfbhPBWGtiCj8JLnQiyg2c5072m5ze24B8ncNpEyX7evB_nywojCAXLXn2fL57TsK1pJvd-w54N2J-MIEYm_GN0maOUM9Nn1IUBuHZt_fh_qFgedVYCs_T3ofNkJdVUdAN4sGBf3ts6xsemOsNN_0huoPGBDBvaJXVSlIwUizFezwZL4Kqsh_hIkV1RIeADcpUTDq4mXsQAjWuqgmg0k9J7cZVC5Cjl_GZXW-nLKjAUps4dcNvW7KnCJWWFqbsg9jkGdHUKcZNfCTb9veWd0hyLCZr1iH-l3vgOpFCMnnzpnLM-GT8WNCfe-uOrtX8ckLwrcIT9ze-HJIqmAkCQEaKQRdGRHmI7afa6dUVUJC6Hx5qQolxvQ==","summary":[{"type":"summary_text","text":"**Clarifying tool_call event handler sequencing**"},{"type":"summary_text","text":"**Optimizing concurrent command dispatching**"},{"type":"summary_text","text":"**Implementing concurrent queue dispatching**"}]},{"id":"rs_0ff2ef0eedd80baf016a5898864dfc8199b74647c8b5ffcde3","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJiIGgB46fa-KDe9486jOtQTo3EIcdmSKhtG0s60daJXzKMC4yl9yYEVCvmM5sHelvDdH7mLvpMgjzSe-bCObiwT84a8n4ETbS7uPJ2ygAwwWz-6RW67qE9QECzbe8cnt6WSiuWsYy7jvteq-xH0UQ_HW-yIpLzYMO7CkWYTCOF0sT2dPIiQ9Xg1DWewfny-ZMgux6T7d2EiD64oETuodRPe4Ajl-AId2G6ZB8CZo-SUDIZn2reRdvIPr2X-eijtaHE4uJWKrSL6nm0TMu59JgHAX028g8TJnCjGtVVvtyxU3HbCLif1peaCI-dLDQZNhK5xjaMvmLaRPIo2ui47c7em9a0RRYWzM_tULvUWnGFma2HwfNdiu9gpzwpWW25wzzZ3gqaLRwwCxP_kBgYPxKDxeWHjiqs5mO_c9AZmqu7nX9Fi1Sm6JJXjd1nBoU1UQ-zqFRgrnYKRBD0JfD9DdlNY9CHiFq5veeTOORZDhLcfwdd1OdP4Wh7OGMXZ_rreTEFfa5Dm2ecLwpDDaulhpPxxzIIRkU7ioLMdoL62IaZtFiBt7Plpa4l2qhEHm__ZmLqDGxeKtkWVlovLLypUf4VfKZag1dtsEgjQEY5R2kYUh8dq_eddkM7GrD0E2f3toDrZlGO2cGc1YLdCJNu6PU7Ls63eJOAb11ThZf7zxLvD5fd563cbzcWc3iONLtLZP8USdaiYeIoxlxprscKHXlzy2dg-3vq_iG_61IGuQjn6ru0_P6Ivyw_THse320OR87_qbRj-Y-tYLjyqs5snxBNDNiOgbTV8BusW8wD3U-PHW80UR4yCU-G-8k8tl0K_iRIyurBwSGZHQkjffPie9plztEHGXFzZNmpa-VvRlMRF3734FQ86wSUMF_V8LLYzyFt3jpZKW2mMqYnQuGiGf_Iwl15diOB-CJLxPJX5_YD-n1nYAugrp88cQLpfWFZ4reBMEC8Y8clOSeUc1z8-cYs1VKGdQ2WoICr2fIVi90Qxd5A3eTflOn2RYELCKpfLPMSqOpqW9lTcyrDyUGqoXrbap3gw_Xz9dSLKC96XFaKMXdTFnf8wW_voQfWfvbDfW5wEKYFL9WC6fwinMzg5Xloorr6JMGvtbYXSn3-juBC2FuQ5MalepruZXpVoIDIh-_AJCFAFbUqiWybTtkcbiZgXEWkLdMKvNu30dhND8H8zmVm15--it-HgdR-YEN5XPpM3gyOx3fsQpe-6zQxIF6PK3s5-AZ-bPmPc50L13Y-mZPHgh44RnI4w4U9eYvfQQJ8nUyiTb9tbLQ3iz4Z5EW9LGaa9acANX52s5ULVJK22elCfoSR-xelh-BbgtnfHPojuRe9phRWZZfd7vJnMNwZskkB_jXmYwU_MysKWi9bkUIquMuCrzu3ypYw5V6no4cj-nwjoiq1jKS11qi6saP8OBD67QIZ84VQqjAAT02S7I9cDsIRmkBK7GUM80yGK8HPLHzQhEwc98HA8OljBqY0bw1cD0448s-Jf0PwkCZ2rt8jY5su7J3PNwAWS_e7prAQDFrXf2Srp5Fc1rQ7hpCUjup3EP87lnzzYGPijC7yxj9CVsOmou0AskWiEZO01CHwW9nV4uNyPL0YqLFo59kjj442MB-F3Buf4TYCex1A98dglZweeodgWh0rwlAgx-6IF0oJkNKwJdodd-60VixbZvRjnN8AtG6nHqzuhzRol39SdvBTqLVEN-N6C6BAmtQRtPoITaaVDhMwYyQ7jwBdy_EM9r9lpfhSipNO0R9G08n4WgQ0s1FmScSyU_CIRuJTAeDXkiGN5nkhN0kMj2lLOh1ysJ9UtLRMc-Gvvc0-DO1Hf--zyYiXddeRrpBXakz0L6VrhzPlPI0vHfvGr8cBgHghSubJ9mZl4PzAfCrf7NmYfGzlbvCO6zvsLp_9guYur","summary":[{"type":"summary_text","text":"**Assessing GitHub release access and checkpointing**"},{"type":"summary_text","text":"**Sending final contract**"}]},{"id":"fc_0ff2ef0eedd80baf016a589888e41c8199950f81d379e131d6","type":"function_call","status":"completed","arguments":"{\"i\":\"Confirming checkpoint wake contract\",\"op\":\"send\",\"to\":\"AgentSurface\",\"message\":\"Checkpoint seam landed as tool `spt_checkpoint({wake?})`: requires active live endpoint, calls `ctx.compact(...)`, then `pi.sendMessage` with `{deliverAs:'nextTurn', triggerTurn:true}` (not followUp—the public OMP docs guarantee hidden post-teardown continuation for nextTurn). It returns observable ok/error and never wakes after compaction failure. Please align skill wording/tests.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_Ua4etfcXZAMGMCxQsI285FsA","name":"irc"}]},"duration":26454.378800000064,"ttft":2354.50260000024,"contextSnapshot":{"promptTokens":201563,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Ua4etfcXZAMGMCxQsI285FsA|fc_0ff2ef0eedd80baf016a589888e41c8199950f81d379e131d6","toolName":"irc","startedAt":"2026-07-16T08:38:35.007Z","intent":"Confirming checkpoint wake contract"},"id":"760847a6","parentId":"74ad8e4e","timestamp":"2026-07-16T08:38:35.007Z"}
{"type":"message","id":"d6363982","parentId":"760847a6","timestamp":"2026-07-16T08:38:35.008Z","message":{"role":"toolResult","toolCallId":"call_Ua4etfcXZAMGMCxQsI285FsA|fc_0ff2ef0eedd80baf016a589888e41c8199950f81d379e131d6","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- AgentSurface: injected"}],"details":{"op":"send","from":"NativeExtension","to":"AgentSurface","receipts":[{"to":"AgentSurface","outcome":"injected"}]},"isError":false,"timestamp":1784191115007}}
{"type":"message","id":"ec11d9f7","parentId":"d6363982","timestamp":"2026-07-16T08:38:46.001Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning manual code review with subagent**\n\n**Assigning focused code reviewer**"},{"type":"toolCall","id":"call_IrslB5ZJK76RA1yEoQVJsCXd|fc_08956093e7495cc1016a589892301c819b8f77379e64faabdd","name":"task","arguments":{"i":"Reviewing extension changes","context":"# Goal\nReview the omp-spt native extension capability-parity implementation for correctness against focused acceptance.\n# Constraints\nRead-only review. Public OMP/SPT surfaces only; never inspect spt-core source. Do not run formatters, project-wide tests, or edit files.\n# Contract\nNative /ready and /live own bind/listener; immutable binding; explicit confirmed live auto-resume; active-turn context boundary injection with ordered fallback; abnormal turns settle custody and restore idle; exact plain @<target[,target] body @> dispatch; no background poll; startup/hints/update injection; checkpoint tool compact+wake.","tasks":[{"assignment":"# Target\nReview only adapter/strings/omp-spt.mjs and tests/omp-extension.mjs, focusing on the newly added parity behavior and interactions with pre-existing custody/shutdown paths.\n# Change\nIdentify concrete correctness bugs, race/deadlock risks, public OMP API misuse, requirement gaps, or tests that pass without proving their stated behavior. Rank findings by severity with exact file locations and recommended fixes. Do not edit.\n# Acceptance\nReturn only actionable findings; state PASS if no findings. Do not run project-wide commands.","id":"ExtensionReview","description":"Review native extension parity","role":"Native OMP Extension Reviewer"}],"agent":"reviewer"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1701,"output":450,"cacheRead":201216,"cacheWrite":0,"totalTokens":203367,"reasoningTokens":156,"cost":{"input":0.008505,"output":0.0135,"cacheRead":0.10060799999999999,"cacheWrite":0,"total":0.12261299999999999}},"stopReason":"toolUse","timestamp":1784191115024,"responseId":"resp_08956093e7495cc1016a58988b6718819bb605140d2a87247b","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_08956093e7495cc1016a58988d597c819ba0146cadcc0f76d8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJiS7WgAvqGL0FDWl7V6BACuoFwvum8GFMaHgbm4205l6L33Fw2a5sZaY7VEHywXnHlaw5LEGRu228YQG-UnXZW7xuRVW9JShDemaNRqBk9zkluFuVcNAEzn43UNPxVKRLYvqRZqQ0lQWjOiaPndLcmFPmFZQveQq_qBLBXZJhasT0uFl86iOYSwHCgINpthA71_c0MX3fpldo5s2GJc7s29KGb8J8XvzUzTEZ6tsLEjMJ_MsMAwAk8jIx715cMK717zDbnSSe_OmkMOE-TDGe9qZyx13dY2rzpwjZcPD7z3qRRUXBqcSw6Oj2JNulYth5lsUKrjUd1andvFwd3sFxTrCVPT6TPZVW2ahhdeu-vMsqizw3Q49i37pQzNgtZM0MoTD99PwcIPku5EQFED2xKx5g8hPmkk9MpGVRCkGHSJgNlCREmgHHHKTQT3eIDQK6KFtrK7I-5LSiTAWuJoSG1bh1iyJPGkWZjxZHSOaTQDoE8oFPK-zEdIhDseTlaF5sU3ZsFp0Np9OmYP2Agr7GGXJfVxaBvh12MOpVOjd1k2GkfDse6IugQMaLuPOE5sN6HAaC3mplInOweL9w0JDE6Ul-xBQR2XAN2xfTHYw0TEdsHkFCKSR13mS3Hmv15nENm5LQrY5E9f6HRyKz37kjJ-ztsRd1bXwUUxcJDwK1pumdcjgz_enmK694igindeVil7E13oFF4PChB7hmWeBX337v7X4qhRtH9vzbOZDZNaAqgyJDIwD5uab317ZfVCVtRXBoqsYeYZUJ82Z0aI2CGvvaVoECJb1_BpGl9NpC9XFLnsdlbFjfdjf7C9Fp-YAeBYpAfc6_iaBDssDTpNQsBtrUbM6vm-vjsBTGW1cn8w-SNxAAC0DewrFu0-kKSrqWTE7q_o3Fq-4OErJ_V_WIxAz2JGap7o-falC2NQcEzCvfVkqcWsvGVBDhWYQxIC16zll_Pp3Gvcd4xV_ScMf_mKkqmoHcEl_eVoyOhR2nvGMVXsWZvty8lOaY8kfpBG1D0V2xQx1QwsliWNkzymttucYH3gnbk6OptBqV5SKexqN2cZuV5OaJs0H5ZH5FUfQLFIsrahTbta2aQGdbuzmfFOrTY3MyPXPGeBTYARYHjqA9kRJhZyyGDMrTzzYdPuHRDw1m8tp138Vf4SIdMRqDuYQlumHFzzyBox-MLrR1JhPoIrHzj8IsZ8gUBuRJCNChXDU8HlrEg-C2SitTRQJhDqp8c2gtKZEeUBT5H5UGkS3U0Pytwkpn84q9zNVdaVnbWZHCK9OFUGtrDqvncLkGMd838QewNCuhH1RE5yeEffQeOGKgiwHgDgqUSSbU2Vj715o5xYSNQQAafdpq9eJ8BGXAi8j0GPAGbZPmsT-2D79Vf9epCkGAdlsU3WwA5BGnSqaaxK6uqatu94_QOdXfnFZVnc6Qe5ZOz5HMtCU2uCerGrGbK8g9DAxzfXWUXBGQYcn6_j_jjOJfinwt5mHX6nSojtPuv15QOEy6TuMoAyPi3LtxiEwjEKQlkyfSsoEhVqbq4XMW1GL8M1KlfcKkq4OwtD4b0Q31S2F2yV1yIslmDrcMcJ9VeBFmlzkRWAkuXdcn0PZhF0fD08OLnJgS3o_I_vYeb1Upw4S2qQtcSUizE4Pew_P2Qltk9dDKo5D5oolYuUtj_60j25LN0sF9DxBoQz3AVsiSUrNz1G_FbNSx2vp5VN2fyopfnChpQI5oN1JkeQYRRiGrBd4yt_nbDHCbXntI-bdOJ2D7lcc6riHWA0jTayplmfZuEarYJl_lb1_wVuqaEUZSsPSAKgOh8W7dt1A5dPrk8XBgmZPnrT8bceMBfgakuY0fO7forKmfHzepHE76TvHR4Pguu3DG32yQeKOF4SHVoEq90w5zG1Zg3M1tFNtsLyvk7cD2k9SGCEEhq1-qkAsqcB2o0floRn_kNqQHU0KfEfkBEqDdKhQRt29xupJsXfVUp-StGXLxF8","summary":[{"type":"summary_text","text":"**Planning manual code review with subagent**"},{"type":"summary_text","text":"**Assigning focused code reviewer**"}]},{"id":"fc_08956093e7495cc1016a589892301c819b8f77379e64faabdd","type":"function_call","status":"completed","arguments":"{\"i\":\"Reviewing extension changes\",\"context\":\"# Goal\\nReview the omp-spt native extension capability-parity implementation for correctness against focused acceptance.\\n# Constraints\\nRead-only review. Public OMP/SPT surfaces only; never inspect spt-core source. Do not run formatters, project-wide tests, or edit files.\\n# Contract\\nNative /ready and /live own bind/listener; immutable binding; explicit confirmed live auto-resume; active-turn context boundary injection with ordered fallback; abnormal turns settle custody and restore idle; exact plain @<target[,target] body @> dispatch; no background poll; startup/hints/update injection; checkpoint tool compact+wake.\",\"tasks\":[{\"assignment\":\"# Target\\nReview only adapter/strings/omp-spt.mjs and tests/omp-extension.mjs, focusing on the newly added parity behavior and interactions with pre-existing custody/shutdown paths.\\n# Change\\nIdentify concrete correctness bugs, race/deadlock risks, public OMP API misuse, requirement gaps, or tests that pass without proving their stated behavior. Rank findings by severity with exact file locations and recommended fixes. Do not edit.\\n# Acceptance\\nReturn only actionable findings; state PASS if no findings. Do not run project-wide commands.\",\"id\":\"ExtensionReview\",\"description\":\"Review native extension parity\",\"role\":\"Native OMP Extension Reviewer\"}],\"agent\":\"reviewer\"}","call_id":"call_IrslB5ZJK76RA1yEoQVJsCXd","name":"task"}]},"duration":10976.558500000276,"ttft":2317.216000000015,"contextSnapshot":{"promptTokens":202917,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_IrslB5ZJK76RA1yEoQVJsCXd|fc_08956093e7495cc1016a589892301c819b8f77379e64faabdd","toolName":"task","startedAt":"2026-07-16T08:38:46.003Z","intent":"Reviewing extension changes"},"id":"c89af404","parentId":"ec11d9f7","timestamp":"2026-07-16T08:38:46.003Z"}
{"type":"message","id":"120e4335","parentId":"c89af404","timestamp":"2026-07-16T08:59:12.385Z","message":{"role":"toolResult","toolCallId":"call_IrslB5ZJK76RA1yEoQVJsCXd|fc_08956093e7495cc1016a589892301c819b8f77379e64faabdd","toolName":"task","content":[{"type":"text","text":"<task-result id=\"NativeExtension.ExtensionReview\" agent=\"reviewer\" status=\"completed\" duration=\"20m26s\">\n<meta lines=\"97\" size=\"8.3KB\" />\n<preview full-output=\"agent://NativeExtension.ExtensionReview\">\n{\n  \"findings\": [\n    {\n      \"title\": \"Correlate replies without the ephemeral context stub\",\n      \"body\": \"OMP's public `context` contract modifies only the provider-bound message clone; it does not persist the synthetic `<msg ...>` user message into `session_stop.messages` or `agent_end.messages`. For every item accepted by the new active-turn branch, `completed.stub` is therefore absent here, so `extractReply` returns empty and the sender receives \\\"turn ended without an assistant response\\\" even when the model produced a reply. `tests/omp-extension.mjs:1739` hides this by constructing `agent_end` from `boundary.messages`, which real OMP does not do. Record an assistant-message baseline when accepting the item and correlate the later assistant independently of the synthetic stub, then make the test pass realistic persisted messages.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1767,\n      \"line_end\": 1772\n    },\n    {\n      \"title\": \"Re-inject active-turn messages on every provider context\",\n      \"body\": \"Setting `activeInjected` makes all later `context` events skip the item. Because OMP does not persist a `context` replacement, the envelope is present for only the first provider call; if that response calls a tool, the following model continuation is rebuilt without the accepted peer request and can answer or act without the message it owns. Keep the active item injected at a stable position on every provider context until it settles, and add a test that emits a second `context` event after a tool boundary.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1696,\n      \"line_end\": 1698\n    },\n    {\n      \"title\": \"Bound shortform dispatch below OMP's handler deadline\",\n      \"body\": \"Targets are sent sequentially inside `completeTurn`, while each production `runCommand` can consume the 15-second default timeout and OMP stops awaiting an extension handler after 30 seconds. Three nonresponsive targets therefore leave this promise running after OMP has timed out the stop/end handler; a new turn can start, then the stale completion resumes and publishes `idle` or queues its status turn over the newer turn. Dispatch with a bounded aggregate deadline below OMP's handler cap, preferably in parallel with cancellation, and finish custody/state transitions before work that can outlive the lifecycle callback.\",\n      \"priority\": 1,\n      \"confidence\": 0.97,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1730,\n      \"line_end\": 1738\n    },\n    {\n      \"title\": \"Dispatch shortforms only from the current turn\",\n      \"body\": \"When there is no inbound `completed` item, `completed?.stub` is `undefined`, so `extractReply` searches the entire transcript and returns the latest assistant entry regardless of which turn produced it. If a later turn fails or is aborted before producing a new assistant message, the previous turn's already-dispatched `@<... @>` output is selected and sent again. Capture the assistant baseline at `agent_start` or use a verified current-turn assistant entry, and mark processed output so an abnormal empty turn cannot replay prior peer commands.\",\n      \"priority\": 1,\n      \"confidence\": 0.94,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1783,\n      \"line_end\": 1783\n    },\n    {\n      \"title\": \"Stop peer-status wakeups once shutdown begins\",\n      \"body\": \"If `session_shutdown` starts while a shortform `send` is in flight, teardown sets `stopping` and aborts the command, but this function catches that rejection, finishes the loops, and still calls `sendMessage` with `nextTurn` plus `triggerTurn`. OMP's public delivery contract schedules an internal continuation in that case, so shutdown can create a new agent turn after listener/custody teardown has begun. Re-check `stopping` after each awaited send and immediately before status injection, and suppress the status wake during teardown.\",\n      \"priority\": 1,\n      \"confidence\": 0.96,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1745,\n      \"line_end\": 1753\n    },\n    {\n      \"title\": \"Preserve Linux path identity during auto-resume\",\n      \"body\": \"`normalizePath` lowercases every path and strips every trailing slash. On supported Linux hosts, `/work/Foo` and `/work/foo` are different projects but compare equal, while the root path `/` normalizes to an empty string and disables the CWD filter entirely. `/live --auto` can consequently rank and confirm the most recent identity from another project as \\\"compatible.\\\" Resolve and compare paths with platform-appropriate case semantics, and preserve filesystem roots when removing trailing separators.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 614,\n      \"line_end\": 618\n    },\n    {\n</preview>\n</task-result>"}],"details":{"projectAgentsDir":null,"results":[{"index":0,"id":"NativeExtension.ExtensionReview","agent":"reviewer","agentSource":"bundled","task":"Complete the assignment below, thoroughly:\n\n# Target\nReview only adapter/strings/omp-spt.mjs and tests/omp-extension.mjs, focusing on the newly added parity behavior and interactions with pre-existing custody/shutdown paths.\n# Change\nIdentify concrete correctness bugs, race/deadlock risks, public OMP API misuse, requirement gaps, or tests that pass without proving their stated behavior. Rank findings by severity with exact file locations and recommended fixes. Do not edit.\n# Acceptance\nReturn only actionable findings; state PASS if no findings. Do not run project-wide commands.","assignment":"# Target\nReview only adapter/strings/omp-spt.mjs and tests/omp-extension.mjs, focusing on the newly added parity behavior and interactions with pre-existing custody/shutdown paths.\n# Change\nIdentify concrete correctness bugs, race/deadlock risks, public OMP API misuse, requirement gaps, or tests that pass without proving their stated behavior. Rank findings by severity with exact file locations and recommended fixes. Do not edit.\n# Acceptance\nReturn only actionable findings; state PASS if no findings. Do not run project-wide commands.","description":"Review native extension parity","lastIntent":"Locating checkpoint ordering test","exitCode":0,"output":"{\n  \"findings\": [\n    {\n      \"title\": \"Correlate replies without the ephemeral context stub\",\n      \"body\": \"OMP's public `context` contract modifies only the provider-bound message clone; it does not persist the synthetic `<msg ...>` user message into `session_stop.messages` or `agent_end.messages`. For every item accepted by the new active-turn branch, `completed.stub` is therefore absent here, so `extractReply` returns empty and the sender receives \\\"turn ended without an assistant response\\\" even when the model produced a reply. `tests/omp-extension.mjs:1739` hides this by constructing `agent_end` from `boundary.messages`, which real OMP does not do. Record an assistant-message baseline when accepting the item and correlate the later assistant independently of the synthetic stub, then make the test pass realistic persisted messages.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1767,\n      \"line_end\": 1772\n    },\n    {\n      \"title\": \"Re-inject active-turn messages on every provider context\",\n      \"body\": \"Setting `activeInjected` makes all later `context` events skip the item. Because OMP does not persist a `context` replacement, the envelope is present for only the first provider call; if that response calls a tool, the following model continuation is rebuilt without the accepted peer request and can answer or act without the message it owns. Keep the active item injected at a stable position on every provider context until it settles, and add a test that emits a second `context` event after a tool boundary.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1696,\n      \"line_end\": 1698\n    },\n    {\n      \"title\": \"Bound shortform dispatch below OMP's handler deadline\",\n      \"body\": \"Targets are sent sequentially inside `completeTurn`, while each production `runCommand` can consume the 15-second default timeout and OMP stops awaiting an extension handler after 30 seconds. Three nonresponsive targets therefore leave this promise running after OMP has timed out the stop/end handler; a new turn can start, then the stale completion resumes and publishes `idle` or queues its status turn over the newer turn. Dispatch with a bounded aggregate deadline below OMP's handler cap, preferably in parallel with cancellation, and finish custody/state transitions before work that can outlive the lifecycle callback.\",\n      \"priority\": 1,\n      \"confidence\": 0.97,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1730,\n      \"line_end\": 1738\n    },\n    {\n      \"title\": \"Dispatch shortforms only from the current turn\",\n      \"body\": \"When there is no inbound `completed` item, `completed?.stub` is `undefined`, so `extractReply` searches the entire transcript and returns the latest assistant entry regardless of which turn produced it. If a later turn fails or is aborted before producing a new assistant message, the previous turn's already-dispatched `@<... @>` output is selected and sent again. Capture the assistant baseline at `agent_start` or use a verified current-turn assistant entry, and mark processed output so an abnormal empty turn cannot replay prior peer commands.\",\n      \"priority\": 1,\n      \"confidence\": 0.94,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1783,\n      \"line_end\": 1783\n    },\n    {\n      \"title\": \"Stop peer-status wakeups once shutdown begins\",\n      \"body\": \"If `session_shutdown` starts while a shortform `send` is in flight, teardown sets `stopping` and aborts the command, but this function catches that rejection, finishes the loops, and still calls `sendMessage` with `nextTurn` plus `triggerTurn`. OMP's public delivery contract schedules an internal continuation in that case, so shutdown can create a new agent turn after listener/custody teardown has begun. Re-check `stopping` after each awaited send and immediately before status injection, and suppress the status wake during teardown.\",\n      \"priority\": 1,\n      \"confidence\": 0.96,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1745,\n      \"line_end\": 1753\n    },\n    {\n      \"title\": \"Preserve Linux path identity during auto-resume\",\n      \"body\": \"`normalizePath` lowercases every path and strips every trailing slash. On supported Linux hosts, `/work/Foo` and `/work/foo` are different projects but compare equal, while the root path `/` normalizes to an empty string and disables the CWD filter entirely. `/live --auto` can consequently rank and confirm the most recent identity from another project as \\\"compatible.\\\" Resolve and compare paths with platform-appropriate case semantics, and preserve filesystem roots when removing trailing separators.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 614,\n      \"line_end\": 618\n    },\n    {\n      \"title\": \"Determine launch-time endpoint type before checkpointing\",\n      \"body\": \"The normal `SPT_ENDPOINT_ID` startup path calls `activateEndpoint(initialId, undefined, ...)`, so `activationType` remains undefined even though the documented launch surface hosts both ReadyAgent and LiveAgent identities. This guard rejects only endpoints activated explicitly through `/ready`; a normally launched ReadyAgent can call `spt_checkpoint`, compact its context, and queue a live-only continuation. Populate the type from the public endpoint-info/identity response during launch and require `live_agent` explicitly before compacting; add a launch-time ReadyAgent case to the test.\",\n      \"priority\": 2,\n      \"confidence\": 0.98,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1101,\n      \"line_end\": 1110\n    },\n    {\n      \"title\": \"Exclude all Markdown code spans from shortform dispatch\",\n      \"body\": \"The mask is line-oriented and recognizes only fenced blocks and backtick spans whose opener and closer are on the same line. A literal example in a four-space indented code block, or inside a valid backtick code span that crosses a newline, remains visible to `parsePeerShortforms` and is sent as a real peer message despite the new tests' stated no-side-effect rule for quoted code. Use a CommonMark-aware code-span/block scanner, or at minimum carry inline-span state across lines and mask indented code blocks, with regression cases for both forms.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 179,\n      \"line_end\": 185\n    },\n    {\n      \"title\": \"Check every public poll command shape\",\n      \"body\": \"Both new \\\"no background poll\\\" assertions inspect only `call.args[3]`, which catches an `spt api ... poll` shape but not the public top-level `spt poll` shape (`args[0] === \\\"poll\\\"`) or a poll started through `spawnProcess`. A regression that adds the forbidden background poll can therefore leave both acceptance tests green. Assert that neither recorded command arguments nor spawned child arguments select `poll`, while still allowing the one authenticated `listen` child.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"tests/omp-extension.mjs\",\n      \"line_start\": 1542,\n      \"line_end\": 1544\n    },\n    {\n      \"title\": \"Prove checkpoint waits for compaction before waking\",\n      \"body\": \"The fake `compact` records its invocation synchronously and resolves immediately, so these final-state assertions also pass if production code starts compaction without awaiting it and sends the wake first. That means the test tagged for the ordered compact-plus-wake requirement does not prove its defining ordering. Return a deferred promise from `onCompact`, start `tool.execute` without awaiting it, assert `sentMessages` is empty while compaction is pending, then resolve the gate and verify exactly one wake.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"tests/omp-extension.mjs\",\n      \"line_start\": 1863,\n      \"line_end\": 1872\n    }\n  ],\n  \"overall_correctness\": \"incorrect\",\n  \"explanation\": \"The patch does not satisfy active-turn delivery and custody: OMP context replacements are nonpersistent, so accepted messages disappear after the first provider call and their replies are miscorrelated. Peer shortform completion also introduces handler-timeout and shutdown races, with additional auto-resume, checkpoint-role, Markdown parsing, and acceptance-test gaps.\",\n  \"confidence\": 0.99\n}","stderr":"","truncated":false,"durationMs":1226379,"tokens":430608,"requests":49,"contextTokens":189888,"contextWindow":272000,"modelOverride":["openai-codex/gpt-5.6-sol:high"],"resolvedModel":"openai-codex/gpt-5.6-sol:high","aborted":false,"usage":{"input":397086,"output":33522,"cacheRead":6826496,"cacheWrite":0,"totalTokens":7257104,"reasoningTokens":26006,"cost":{"input":1.9854299999999998,"output":1.0056600000000002,"cacheRead":3.413248,"cacheWrite":0,"total":6.404337999999997}},"outputPath":"C:\\Users\\decid\\.omp\\agent\\sessions\\-Documents-projects-omp-spt\\2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7\\NativeExtension\\NativeExtension.ExtensionReview.md","extractedToolData":{"yield":[{"data":{"title":"Correlate replies without the ephemeral context stub","body":"OMP's public `context` contract modifies only the provider-bound message clone; it does not persist the synthetic `<msg ...>` user message into `session_stop.messages` or `agent_end.messages`. For every item accepted by the new active-turn branch, `completed.stub` is therefore absent here, so `extractReply` returns empty and the sender receives \"turn ended without an assistant response\" even when the model produced a reply. `tests/omp-extension.mjs:1739` hides this by constructing `agent_end` from `boundary.messages`, which real OMP does not do. Record an assistant-message baseline when accepting the item and correlate the later assistant independently of the synthetic stub, then make the test pass realistic persisted messages.","priority":1,"confidence":0.99,"file_path":"adapter/strings/omp-spt.mjs","line_start":1767,"line_end":1772},"status":"success","type":["findings"]},{"data":{"title":"Re-inject active-turn messages on every provider context","body":"Setting `activeInjected` makes all later `context` events skip the item. Because OMP does not persist a `context` replacement, the envelope is present for only the first provider call; if that response calls a tool, the following model continuation is rebuilt without the accepted peer request and can answer or act without the message it owns. Keep the active item injected at a stable position on every provider context until it settles, and add a test that emits a second `context` event after a tool boundary.","priority":1,"confidence":0.99,"file_path":"adapter/strings/omp-spt.mjs","line_start":1696,"line_end":1698},"status":"success","type":["findings"]},{"data":{"title":"Bound shortform dispatch below OMP's handler deadline","body":"Targets are sent sequentially inside `completeTurn`, while each production `runCommand` can consume the 15-second default timeout and OMP stops awaiting an extension handler after 30 seconds. Three nonresponsive targets therefore leave this promise running after OMP has timed out the stop/end handler; a new turn can start, then the stale completion resumes and publishes `idle` or queues its status turn over the newer turn. Dispatch with a bounded aggregate deadline below OMP's handler cap, preferably in parallel with cancellation, and finish custody/state transitions before work that can outlive the lifecycle callback.","priority":1,"confidence":0.97,"file_path":"adapter/strings/omp-spt.mjs","line_start":1730,"line_end":1738},"status":"success","type":["findings"]},{"data":{"title":"Dispatch shortforms only from the current turn","body":"When there is no inbound `completed` item, `completed?.stub` is `undefined`, so `extractReply` searches the entire transcript and returns the latest assistant entry regardless of which turn produced it. If a later turn fails or is aborted before producing a new assistant message, the previous turn's already-dispatched `@<... @>` output is selected and sent again. Capture the assistant baseline at `agent_start` or use a verified current-turn assistant entry, and mark processed output so an abnormal empty turn cannot replay prior peer commands.","priority":1,"confidence":0.94,"file_path":"adapter/strings/omp-spt.mjs","line_start":1783,"line_end":1783},"status":"success","type":["findings"]},{"data":{"title":"Stop peer-status wakeups once shutdown begins","body":"If `session_shutdown` starts while a shortform `send` is in flight, teardown sets `stopping` and aborts the command, but this function catches that rejection, finishes the loops, and still calls `sendMessage` with `nextTurn` plus `triggerTurn`. OMP's public delivery contract schedules an internal continuation in that case, so shutdown can create a new agent turn after listener/custody teardown has begun. Re-check `stopping` after each awaited send and immediately before status injection, and suppress the status wake during teardown.","priority":1,"confidence":0.96,"file_path":"adapter/strings/omp-spt.mjs","line_start":1745,"line_end":1753},"status":"success","type":["findings"]},{"data":{"title":"Preserve Linux path identity during auto-resume","body":"`normalizePath` lowercases every path and strips every trailing slash. On supported Linux hosts, `/work/Foo` and `/work/foo` are different projects but compare equal, while the root path `/` normalizes to an empty string and disables the CWD filter entirely. `/live --auto` can consequently rank and confirm the most recent identity from another project as \"compatible.\" Resolve and compare paths with platform-appropriate case semantics, and preserve filesystem roots when removing trailing separators.","priority":2,"confidence":0.99,"file_path":"adapter/strings/omp-spt.mjs","line_start":614,"line_end":618},"status":"success","type":["findings"]},{"data":{"title":"Determine launch-time endpoint type before checkpointing","body":"The normal `SPT_ENDPOINT_ID` startup path calls `activateEndpoint(initialId, undefined, ...)`, so `activationType` remains undefined even though the documented launch surface hosts both ReadyAgent and LiveAgent identities. This guard rejects only endpoints activated explicitly through `/ready`; a normally launched ReadyAgent can call `spt_checkpoint`, compact its context, and queue a live-only continuation. Populate the type from the public endpoint-info/identity response during launch and require `live_agent` explicitly before compacting; add a launch-time ReadyAgent case to the test.","priority":2,"confidence":0.98,"file_path":"adapter/strings/omp-spt.mjs","line_start":1101,"line_end":1110},"status":"success","type":["findings"]},{"data":{"title":"Exclude all Markdown code spans from shortform dispatch","body":"The mask is line-oriented and recognizes only fenced blocks and backtick spans whose opener and closer are on the same line. A literal example in a four-space indented code block, or inside a valid backtick code span that crosses a newline, remains visible to `parsePeerShortforms` and is sent as a real peer message despite the new tests' stated no-side-effect rule for quoted code. Use a CommonMark-aware code-span/block scanner, or at minimum carry inline-span state across lines and mask indented code blocks, with regression cases for both forms.","priority":2,"confidence":0.99,"file_path":"adapter/strings/omp-spt.mjs","line_start":179,"line_end":185},"status":"success","type":["findings"]},{"data":{"title":"Check every public poll command shape","body":"Both new \"no background poll\" assertions inspect only `call.args[3]`, which catches an `spt api ... poll` shape but not the public top-level `spt poll` shape (`args[0] === \"poll\"`) or a poll started through `spawnProcess`. A regression that adds the forbidden background poll can therefore leave both acceptance tests green. Assert that neither recorded command arguments nor spawned child arguments select `poll`, while still allowing the one authenticated `listen` child.","priority":2,"confidence":0.99,"file_path":"tests/omp-extension.mjs","line_start":1542,"line_end":1544},"status":"success","type":["findings"]},{"data":{"title":"Prove checkpoint waits for compaction before waking","body":"The fake `compact` records its invocation synchronously and resolves immediately, so these final-state assertions also pass if production code starts compaction without awaiting it and sends the wake first. That means the test tagged for the ordered compact-plus-wake requirement does not prove its defining ordering. Return a deferred promise from `onCompact`, start `tool.execute` without awaiting it, assert `sentMessages` is empty while compaction is pending, then resolve the gate and verify exactly one wake.","priority":2,"confidence":0.99,"file_path":"tests/omp-extension.mjs","line_start":1863,"line_end":1872},"status":"success","type":["findings"]},{"data":"incorrect","status":"success","type":["overall_correctness"]},{"data":"The patch does not satisfy active-turn delivery and custody: OMP context replacements are nonpersistent, so accepted messages disappear after the first provider call and their replies are miscorrelated. Peer shortform completion also introduces handler-timeout and shutdown races, with additional auto-resume, checkpoint-role, Markdown parsing, and acceptance-test gaps.","status":"success","type":["explanation"]},{"data":0.99,"status":"success","type":["confidence"]}]},"outputMeta":{"lineCount":97,"charCount":8522}}],"totalDurationMs":1226382,"usage":{"input":397086,"output":33522,"cacheRead":6826496,"cacheWrite":0,"totalTokens":7257104,"reasoningTokens":26006,"cost":{"input":1.9854299999999998,"output":1.0056600000000002,"cacheRead":3.413248,"cacheWrite":0,"total":6.404337999999997}},"outputPaths":["C:\\Users\\decid\\.omp\\agent\\sessions\\-Documents-projects-omp-spt\\2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7\\NativeExtension\\NativeExtension.ExtensionReview.md"]},"isError":false,"timestamp":1784192352385}}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `AgentSurface`:\n\nAligned commune SKILL/test: checkpoint requires `.self.status == live_agent`; write precedes tool; documents native compaction then `nextTurn`+`triggerTurn`; asserts no wake after failed reset and observable failure. Focused package suite passes.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"AgentSurface\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531d34e14db7992","from":"AgentSurface","message":"Aligned commune SKILL/test: checkpoint requires `.self.status == live_agent`; write precedes tool; documents native compaction then `nextTurn`+`triggerTurn`; asserts no wake after failed reset and observable failure. Focused package suite passes."},"attribution":"agent","id":"50e609fc","parentId":"120e4335","timestamp":"2026-07-16T08:59:12.386Z"}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `TruthGates`:\n\nYour nine extension requirements are now active at doc+impl+unit; traceable-reqs check is green: 34 complete, 0 incomplete, 0 findings. ADR 0015/0017 roots are included.\n\nAn agent sent this while you were waiting or working. Any active interruptible wait was stopped early so you can read it now.\n\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"TruthGates\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531d3d3345b7998","from":"TruthGates","message":"Your nine extension requirements are now active at doc+impl+unit; traceable-reqs check is green: 34 complete, 0 incomplete, 0 findings. ADR 0015/0017 roots are included."},"attribution":"agent","id":"2d9167ad","parentId":"50e609fc","timestamp":"2026-07-16T08:59:12.386Z"}
{"type":"message","id":"c4793464","parentId":"2d9167ad","timestamp":"2026-07-16T08:59:17.618Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Fetching full reviewer output**"},{"type":"toolCall","id":"call_BF3O4Xv5XTAdwR2jUFxCgdBd|fc_070ee041ae4bc3b4016a589d6531d8819b85819e456adf8ee0","name":"read","arguments":{"i":"Reading full extension review","path":"agent://NativeExtension.ExtensionReview","selector":"1-220"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2606,"output":50,"cacheRead":202240,"cacheWrite":0,"totalTokens":204896,"reasoningTokens":13,"cost":{"input":0.013030000000000002,"output":0.0015,"cacheRead":0.10112,"cacheWrite":0,"total":0.11565}},"stopReason":"toolUse","timestamp":1784192352410,"responseId":"resp_070ee041ae4bc3b4016a589d60d164819b8372ac7bb6e7b64d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_070ee041ae4bc3b4016a589d648d4c819bb05f0d8d43d57664","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ1lvx2V2vWedBYeFlr0aK_0EtcvxMl22y8M-X23dXr8cKJkuuwTPVN14NwPKLVE0Q4Ty6NktFYfus57Y3qOGH1GLK5tAmaY1cpCmWxdVER48l_0OXvMXGpF3beCNhQEWCs6m0l2FVcIYMV-2NRfEMkk5da5OISzf1y1mvcyaSJOLER0edq8fnzlPUMwj2sScwiiPyzeCSiJepBmuv73bSr_XFu2x-UQnh00XNv86ozLdvA--RgpkyPjqMm5qXKc28QG3EQJsBRf8vpxPSMYEXDOITB9f8UE0IqZJEb7k8ltswLxIIBh6ti20hiCgtYF0ENctw9HNUpj2leV2qZoi8GJBHyw022AwZoeAwrRkTG5rWDMCgXpAwIYE50nFExCju7xFNjQhJ7bVamZ8icJIC8XJU9qcvm-eOwBnd_A2hnNB5ObMU7eS9ca5BoK6JSPSBBRcZlnPSKkH7HdifACEg37PCxO_GEaHmPWnartVi3RT7IDS3RNzbkC-AtI11msQx3zn1X1yQfOecIFAK-TlcwjQ3SCcd0c__h8vn0IxLHf-tQb7F16rh7Gr0BVL4r0KxDPyv-4OEwTP3vpQT4ycqg8qie2783svStXyeY3n9psZTQO-PrvcDGJ518HtDL5RrPSgPV_xWtz5DdfwM3YOsSPLllmxQ9x2D7E61zog0jusUqhhuj_fvLK2yQBkrE0NyTVuOrC_zMPJC-Jt1MwDPxIsm3T7cM-cuZbPfj3PK0459Z5S7DH0zJoBH72g8Qalw5rkHFENfNoq31A3qN8StJkzkjL3bgF5XTAvnOVY49xlEgBMzu5YZ1AG7O1GpNPnSOqk-MQrS7Z-zHDZpb06OQzFAUYloa31b3B430jgZrnaNp7nD6LmAf6OGJLCje7LbvqBOOUg2Sr9vC7xXn7Ii5fJqNGQ-kY4328pO3GU_lKsdMu1Uq8oKl3z_eEziUYDhv3SbdkUgEsj0mu5bxl3Ajg7A==","summary":[{"type":"summary_text","text":"**Fetching full reviewer output**"}]},{"id":"fc_070ee041ae4bc3b4016a589d6531d8819b85819e456adf8ee0","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading full extension review\",\"path\":\"agent://NativeExtension.ExtensionReview\",\"selector\":\"1-220\"}","call_id":"call_BF3O4Xv5XTAdwR2jUFxCgdBd","name":"read"}]},"duration":5206.254600000102,"ttft":4126.907500000205,"contextSnapshot":{"promptTokens":204846,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_BF3O4Xv5XTAdwR2jUFxCgdBd|fc_070ee041ae4bc3b4016a589d6531d8819b85819e456adf8ee0","toolName":"read","startedAt":"2026-07-16T08:59:17.618Z","args":{"path":"agent://NativeExtension.ExtensionReview"},"intent":"Reading full extension review"},"id":"62a0d300","parentId":"c4793464","timestamp":"2026-07-16T08:59:17.618Z"}
{"type":"message","id":"ab4ae12f","parentId":"62a0d300","timestamp":"2026-07-16T08:59:17.620Z","message":{"role":"toolResult","toolCallId":"call_BF3O4Xv5XTAdwR2jUFxCgdBd|fc_070ee041ae4bc3b4016a589d6531d8819b85819e456adf8ee0","toolName":"read","content":[{"type":"text","text":"{\n  \"findings\": [\n    {\n      \"title\": \"Correlate replies without the ephemeral context stub\",\n      \"body\": \"OMP's public `context` contract modifies only the provider-bound message clone; it does not persist the synthetic `<msg ...>` user message into `session_stop.messages` or `agent_end.messages`. For every item accepted by the new active-turn branch, `completed.stub` is therefore absent here, so `extractReply` returns empty and the sender receives \\\"turn ended without an assistant response\\\" even when the model produced a reply. `tests/omp-extension.mjs:1739` hides this by constructing `agent_end` from `boundary.messages`, which real OMP does not do. Record an assistant-message baseline when accepting the item and correlate the later assistant independently of the synthetic stub, then make the test pass realistic persisted messages.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1767,\n      \"line_end\": 1772\n    },\n    {\n      \"title\": \"Re-inject active-turn messages on every provider context\",\n      \"body\": \"Setting `activeInjected` makes all later `context` events skip the item. Because OMP does not persist a `context` replacement, the envelope is present for only the first provider call; if that response calls a tool, the following model continuation is rebuilt without the accepted peer request and can answer or act without the message it owns. Keep the active item injected at a stable position on every provider context until it settles, and add a test that emits a second `context` event after a tool boundary.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1696,\n      \"line_end\": 1698\n    },\n    {\n      \"title\": \"Bound shortform dispatch below OMP's handler deadline\",\n      \"body\": \"Targets are sent sequentially inside `completeTurn`, while each production `runCommand` can consume the 15-second default timeout and OMP stops awaiting an extension handler after 30 seconds. Three nonresponsive targets therefore leave this promise running after OMP has timed out the stop/end handler; a new turn can start, then the stale completion resumes and publishes `idle` or queues its status turn over the newer turn. Dispatch with a bounded aggregate deadline below OMP's handler cap, preferably in parallel with cancellation, and finish custody/state transitions before work that can outlive the lifecycle callback.\",\n      \"priority\": 1,\n      \"confidence\": 0.97,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1730,\n      \"line_end\": 1738\n    },\n    {\n      \"title\": \"Dispatch shortforms only from the current turn\",\n      \"body\": \"When there is no inbound `completed` item, `completed?.stub` is `undefined`, so `extractReply` searches the entire transcript and returns the latest assistant entry regardless of which turn produced it. If a later turn fails or is aborted before producing a new assistant message, the previous turn's already-dispatched `@<... @>` output is selected and sent again. Capture the assistant baseline at `agent_start` or use a verified current-turn assistant entry, and mark processed output so an abnormal empty turn cannot replay prior peer commands.\",\n      \"priority\": 1,\n      \"confidence\": 0.94,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1783,\n      \"line_end\": 1783\n    },\n    {\n      \"title\": \"Stop peer-status wakeups once shutdown begins\",\n      \"body\": \"If `session_shutdown` starts while a shortform `send` is in flight, teardown sets `stopping` and aborts the command, but this function catches that rejection, finishes the loops, and still calls `sendMessage` with `nextTurn` plus `triggerTurn`. OMP's public delivery contract schedules an internal continuation in that case, so shutdown can create a new agent turn after listener/custody teardown has begun. Re-check `stopping` after each awaited send and immediately before status injection, and suppress the status wake during teardown.\",\n      \"priority\": 1,\n      \"confidence\": 0.96,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1745,\n      \"line_end\": 1753\n    },\n    {\n      \"title\": \"Preserve Linux path identity during auto-resume\",\n      \"body\": \"`normalizePath` lowercases every path and strips every trailing slash. On supported Linux hosts, `/work/Foo` and `/work/foo` are different projects but compare equal, while the root path `/` normalizes to an empty string and disables the CWD filter entirely. `/live --auto` can consequently rank and confirm the most recent identity from another project as \\\"compatible.\\\" Resolve and compare paths with platform-appropriate case semantics, and preserve filesystem roots when removing trailing separators.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 614,\n      \"line_end\": 618\n    },\n    {\n      \"title\": \"Determine launch-time endpoint type before checkpointing\",\n      \"body\": \"The normal `SPT_ENDPOINT_ID` startup path calls `activateEndpoint(initialId, undefined, ...)`, so `activationType` remains undefined even though the documented launch surface hosts both ReadyAgent and LiveAgent identities. This guard rejects only endpoints activated explicitly through `/ready`; a normally launched ReadyAgent can call `spt_checkpoint`, compact its context, and queue a live-only continuation. Populate the type from the public endpoint-info/identity response during launch and require `live_agent` explicitly before compacting; add a launch-time ReadyAgent case to the test.\",\n      \"priority\": 2,\n      \"confidence\": 0.98,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1101,\n      \"line_end\": 1110\n    },\n    {\n      \"title\": \"Exclude all Markdown code spans from shortform dispatch\",\n      \"body\": \"The mask is line-oriented and recognizes only fenced blocks and backtick spans whose opener and closer are on the same line. A literal example in a four-space indented code block, or inside a valid backtick code span that crosses a newline, remains visible to `parsePeerShortforms` and is sent as a real peer message despite the new tests' stated no-side-effect rule for quoted code. Use a CommonMark-aware code-span/block scanner, or at minimum carry inline-span state across lines and mask indented code blocks, with regression cases for both forms.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 179,\n      \"line_end\": 185\n    },\n    {\n      \"title\": \"Check every public poll command shape\",\n      \"body\": \"Both new \\\"no background poll\\\" assertions inspect only `call.args[3]`, which catches an `spt api ... poll` shape but not the public top-level `spt poll` shape (`args[0] === \\\"poll\\\"`) or a poll started through `spawnProcess`. A regression that adds the forbidden background poll can therefore leave both acceptance tests green. Assert that neither recorded command arguments nor spawned child arguments select `poll`, while still allowing the one authenticated `listen` child.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"tests/omp-extension.mjs\",\n      \"line_start\": 1542,\n      \"line_end\": 1544\n    },\n    {\n      \"title\": \"Prove checkpoint waits for compaction before waking\",\n      \"body\": \"The fake `compact` records its invocation synchronously and resolves immediately, so these final-state assertions also pass if production code starts compaction without awaiting it and sends the wake first. That means the test tagged for the ordered compact-plus-wake requirement does not prove its defining ordering. Return a deferred promise from `onCompact`, start `tool.execute` without awaiting it, assert `sentMessages` is empty while compaction is pending, then resolve the gate and verify exactly one wake.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"tests/omp-extension.mjs\",\n      \"line_start\": 1863,\n      \"line_end\": 1872\n    }\n  ],\n  \"overall_correctness\": \"incorrect\",\n  \"explanation\": \"The patch does not satisfy active-turn delivery and custody: OMP context replacements are nonpersistent, so accepted messages disappear after the first provider call and their replies are miscorrelated. Peer shortform completion also introduces handler-timeout and shutdown races, with additional auto-resume, checkpoint-role, Markdown parsing, and acceptance-test gaps.\",\n  \"confidence\": 0.99\n}"}],"details":{"resolvedPath":"C:\\Users\\decid\\.omp\\agent\\sessions\\-Documents-projects-omp-spt\\2026-07-15T11-14-59-465Z_019f657c-b509-7000-86f2-0cc67e63a2b7\\NativeExtension\\NativeExtension.ExtensionReview.md","contentType":"text/markdown","displayContent":{"text":"{\n  \"findings\": [\n    {\n      \"title\": \"Correlate replies without the ephemeral context stub\",\n      \"body\": \"OMP's public `context` contract modifies only the provider-bound message clone; it does not persist the synthetic `<msg ...>` user message into `session_stop.messages` or `agent_end.messages`. For every item accepted by the new active-turn branch, `completed.stub` is therefore absent here, so `extractReply` returns empty and the sender receives \\\"turn ended without an assistant response\\\" even when the model produced a reply. `tests/omp-extension.mjs:1739` hides this by constructing `agent_end` from `boundary.messages`, which real OMP does not do. Record an assistant-message baseline when accepting the item and correlate the later assistant independently of the synthetic stub, then make the test pass realistic persisted messages.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1767,\n      \"line_end\": 1772\n    },\n    {\n      \"title\": \"Re-inject active-turn messages on every provider context\",\n      \"body\": \"Setting `activeInjected` makes all later `context` events skip the item. Because OMP does not persist a `context` replacement, the envelope is present for only the first provider call; if that response calls a tool, the following model continuation is rebuilt without the accepted peer request and can answer or act without the message it owns. Keep the active item injected at a stable position on every provider context until it settles, and add a test that emits a second `context` event after a tool boundary.\",\n      \"priority\": 1,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1696,\n      \"line_end\": 1698\n    },\n    {\n      \"title\": \"Bound shortform dispatch below OMP's handler deadline\",\n      \"body\": \"Targets are sent sequentially inside `completeTurn`, while each production `runCommand` can consume the 15-second default timeout and OMP stops awaiting an extension handler after 30 seconds. Three nonresponsive targets therefore leave this promise running after OMP has timed out the stop/end handler; a new turn can start, then the stale completion resumes and publishes `idle` or queues its status turn over the newer turn. Dispatch with a bounded aggregate deadline below OMP's handler cap, preferably in parallel with cancellation, and finish custody/state transitions before work that can outlive the lifecycle callback.\",\n      \"priority\": 1,\n      \"confidence\": 0.97,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1730,\n      \"line_end\": 1738\n    },\n    {\n      \"title\": \"Dispatch shortforms only from the current turn\",\n      \"body\": \"When there is no inbound `completed` item, `completed?.stub` is `undefined`, so `extractReply` searches the entire transcript and returns the latest assistant entry regardless of which turn produced it. If a later turn fails or is aborted before producing a new assistant message, the previous turn's already-dispatched `@<... @>` output is selected and sent again. Capture the assistant baseline at `agent_start` or use a verified current-turn assistant entry, and mark processed output so an abnormal empty turn cannot replay prior peer commands.\",\n      \"priority\": 1,\n      \"confidence\": 0.94,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1783,\n      \"line_end\": 1783\n    },\n    {\n      \"title\": \"Stop peer-status wakeups once shutdown begins\",\n      \"body\": \"If `session_shutdown` starts while a shortform `send` is in flight, teardown sets `stopping` and aborts the command, but this function catches that rejection, finishes the loops, and still calls `sendMessage` with `nextTurn` plus `triggerTurn`. OMP's public delivery contract schedules an internal continuation in that case, so shutdown can create a new agent turn after listener/custody teardown has begun. Re-check `stopping` after each awaited send and immediately before status injection, and suppress the status wake during teardown.\",\n      \"priority\": 1,\n      \"confidence\": 0.96,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1745,\n      \"line_end\": 1753\n    },\n    {\n      \"title\": \"Preserve Linux path identity during auto-resume\",\n      \"body\": \"`normalizePath` lowercases every path and strips every trailing slash. On supported Linux hosts, `/work/Foo` and `/work/foo` are different projects but compare equal, while the root path `/` normalizes to an empty string and disables the CWD filter entirely. `/live --auto` can consequently rank and confirm the most recent identity from another project as \\\"compatible.\\\" Resolve and compare paths with platform-appropriate case semantics, and preserve filesystem roots when removing trailing separators.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 614,\n      \"line_end\": 618\n    },\n    {\n      \"title\": \"Determine launch-time endpoint type before checkpointing\",\n      \"body\": \"The normal `SPT_ENDPOINT_ID` startup path calls `activateEndpoint(initialId, undefined, ...)`, so `activationType` remains undefined even though the documented launch surface hosts both ReadyAgent and LiveAgent identities. This guard rejects only endpoints activated explicitly through `/ready`; a normally launched ReadyAgent can call `spt_checkpoint`, compact its context, and queue a live-only continuation. Populate the type from the public endpoint-info/identity response during launch and require `live_agent` explicitly before compacting; add a launch-time ReadyAgent case to the test.\",\n      \"priority\": 2,\n      \"confidence\": 0.98,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 1101,\n      \"line_end\": 1110\n    },\n    {\n      \"title\": \"Exclude all Markdown code spans from shortform dispatch\",\n      \"body\": \"The mask is line-oriented and recognizes only fenced blocks and backtick spans whose opener and closer are on the same line. A literal example in a four-space indented code block, or inside a valid backtick code span that crosses a newline, remains visible to `parsePeerShortforms` and is sent as a real peer message despite the new tests' stated no-side-effect rule for quoted code. Use a CommonMark-aware code-span/block scanner, or at minimum carry inline-span state across lines and mask indented code blocks, with regression cases for both forms.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"adapter/strings/omp-spt.mjs\",\n      \"line_start\": 179,\n      \"line_end\": 185\n    },\n    {\n      \"title\": \"Check every public poll command shape\",\n      \"body\": \"Both new \\\"no background poll\\\" assertions inspect only `call.args[3]`, which catches an `spt api ... poll` shape but not the public top-level `spt poll` shape (`args[0] === \\\"poll\\\"`) or a poll started through `spawnProcess`. A regression that adds the forbidden background poll can therefore leave both acceptance tests green. Assert that neither recorded command arguments nor spawned child arguments select `poll`, while still allowing the one authenticated `listen` child.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"tests/omp-extension.mjs\",\n      \"line_start\": 1542,\n      \"line_end\": 1544\n    },\n    {\n      \"title\": \"Prove checkpoint waits for compaction before waking\",\n      \"body\": \"The fake `compact` records its invocation synchronously and resolves immediately, so these final-state assertions also pass if production code starts compaction without awaiting it and sends the wake first. That means the test tagged for the ordered compact-plus-wake requirement does not prove its defining ordering. Return a deferred promise from `onCompact`, start `tool.execute` without awaiting it, assert `sentMessages` is empty while compaction is pending, then resolve the gate and verify exactly one wake.\",\n      \"priority\": 2,\n      \"confidence\": 0.99,\n      \"file_path\": \"tests/omp-extension.mjs\",\n      \"line_start\": 1863,\n      \"line_end\": 1872\n    }\n  ],\n  \"overall_correctness\": \"incorrect\",\n  \"explanation\": \"The patch does not satisfy active-turn delivery and custody: OMP context replacements are nonpersistent, so accepted messages disappear after the first provider call and their replies are miscorrelated. Peer shortform completion also introduces handler-timeout and shutdown races, with additional auto-resume, checkpoint-role, Markdown parsing, and acceptance-test gaps.\",\n  \"confidence\": 0.99\n}","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97]},"meta":{"source":{"type":"internal","value":"agent://NativeExtension.ExtensionReview"}}},"isError":false,"timestamp":1784192357620}}
{"type":"message","id":"a533ee16","parentId":"ab4ae12f","timestamp":"2026-07-16T09:00:10.911Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning assistant baseline capture**\n\n**Designing assistant reply extraction helper**\n\n**Implementing assistant count baseline reset and tracking**"},{"type":"thinking","thinking":"**Clarifying reply handling logic**\n\n**Refining baseline reset order**\n\n**Reordering dispatch and timeout handling**"},{"type":"thinking","thinking":"**Enforcing consistent command timeouts**\n\n**Designing cross-platform path normalization**"},{"type":"thinking","thinking":"**Implementing activation type resolution and masking logic**\n\n**Designing comprehensive Markdown code masking**\n\n**Refining backtick span masking with exact run matching**"},{"type":"thinking","thinking":"**Defining poll detection logic**\n\n**Enhancing poll detection and shutdown tests**\n\n**Planning deferred implementation for parallelism**"},{"type":"thinking","thinking":"**Reading lines for mask function**"},{"type":"toolCall","id":"call_OyGCGaGfPVvKnUgE9u4EHQNx|fc_0c2eea7faf3a6210016a589d9a729c8191981f369ce667dd99","name":"read","arguments":{"i":"Reading shortform parser implementation","path":"adapter/strings/omp-spt.mjs","selector":"160-245"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2550,"output":2641,"cacheRead":204288,"cacheWrite":0,"totalTokens":209479,"reasoningTokens":2600,"cost":{"input":0.012750000000000001,"output":0.07923000000000001,"cacheRead":0.102144,"cacheWrite":0,"total":0.19412400000000002}},"stopReason":"toolUse","timestamp":1784192357628,"responseId":"resp_0c2eea7faf3a6210016a589d67384c819193b5ee0c64ee1609","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0c2eea7faf3a6210016a589d69ae548191a0252ef19801544d","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ1zpp_UfMXz8l3j_Cfbv1Mn5DxxmaFAR72fJyQIyvumWci6e2Inj3Xg1UWwJAz3_LBeAAPwV8Mlt2itQNPXQOSZdBl6rwycQWRl_-R3Pla_IsrgYw9NKGFte0pIRVC1o3R89hC-C6a7ySrHBudp5rMoAdaCqCVI7HzlRRp-urQX6P2hwCFEpr7l2pNosFrQ_U3TfeSBokQDJX8oCkvWSMlOfLmNa3zNUHx6sZzTepPLyuHdc1blzcfcN4gzvjtl-7HzwOq2hGaBA7qlFRexAopVPmhZ5B175k9Xe2mQigKaa22ztq17TXxQbz-oZXkQJMs09_2HZKzAeuNSgYSjEfb7OxlqM4Dl7EuDM4-OwgjTTFOYOYS9kvmg-ZtbfiFZGbDMkDKV3UXwFx9wEygCEGefQxqLMeKeQCOZ1In2WgYgMACvZZ1S_RdOkAbmTL1GSi27_oK6chg_SJM5CFGLZgBuF5S4AYxA_08CZwoJbdv2lnjOpYZhgwdSn9lWttP8iQ9QG_oQcpBrhCxF6emYxurb-slwttwI_C-Weh51DC0ZQ-yqJRr-xUs7H1QvJSxMGA0_cscDh8IS_ZHcMvJNCnHlL8qAA4rQOf7HLiln5CL96mI_y7A9tj0McZcCyThcpUrAyRM013JXlM9ZFlXF15m34MY-QB_3TdhLqhew8dSuxggoYJtkDSwCS08FCqvzs-DQLUqLV46M0ZsTX_GSj8QO_ZA-L9OC44yXnWtg71qgzwOPsKGLi4bh5Fmbn17wwiG5tzuzG7P0rBv8MK6yCc-n1tBZh5pH2KlqhmeDOLR0x9q_5VHBGVBNRcoEKx0sOfS-0ha9VaSu-tTGm4gtYc4zYJNHIvchua9NfOfpfa8b1s1UtM43sAaUS7YFYzdxKajZBgRNAhvbNtN4BMKdbt5r0daJ9lvKSYoJz4j3qr9m82hQUgCDW7pSTpvnxEk_dfHaxRKN_18RZv9TX4mA6c5Df0u8VDZ52hUa1OlxecIWNNuGGJrwglV6PH8jOAORnQg3v6fIbHW8I3H_e-BwZ4QET6jsHLicyGCZMkV8YyZHEKsQ1H7AaYv5b0OvtOqcysor9FfXdYMfaFO7QJkOAU8coMxurKKCVelBKScOxYGl318e5mUSo-77TJH4ANTzuQYXoC0FKcLedML5er2GPZ8U-V3K6Im6yQ--9Znp6h6La2kMi31yhUal-YUhAQyswfCTehAHIv9gCnqxUt8Cf9M72x3nzWhHRYsJD3AeKtpYD4PR7t_XQtMQbvl5pgg9_fzF-naoxtMo5vZg9IGtrPMKh54PSNu7JACGbwAG1hTpC0IrlLDXsTQ4CvArC_OY6hlrnTfIGxhnaruGdExA1NqqdZmNTy2TnEekb5A8oF28bU-nG21H3tSeZGwpYXCXSTB_q_Xxws6ZPKJMfov-fxYNPhN6lhb_2qzDitwaKxeKB8VlMe9p6mA06L093C064RvREAH2NLHbBT61D2mTXfsrXY4agv8BbwF9bF1g6tBCamCrkyUAUSPta96ehayZCClF13XZxApi5G8HWbVbCVoONZnTzuoSkxPhJKyDmRO3vQpFZ1zmupsL0tFtm4eKMDF5fl19j8dvDOQxM8yVVG1zWONzGir2Eof5nVBoStx6kdzj9pZ275in8bDjNID8U4Fq377mfzitN4moztypnrqM07UkWzANFtSzd5qqAcJGfzOXR83ZFKa9JxPohl6NVi3ssD-I4pkam2LakZ5pGFYTl9fGP_RRrdd59FrrZJ7rcgWR-w5c3FV_WKPhoqYzHKhEcaveV_lvXEYbUV8zb4i4D2IMb3JXRPBP83Y7gYs2Sb_wA2kaEtAiSMl3xjuePiaSEgmA9yqXpPLCzNWU8wdLtsrjl603H1lP2dRZI3p8OFfL0ZwmixsdGVCzysc4B1i7MAjYE4z92G8NdSgmbMl9TIZh9TkCYvWkhljFPINN3CZH1pPzTDE83Ailm0dPPhPmNKQqMK7F5L4iH_OSsYSrcotsqGYGIKAmJOr4B1beTsvAJj3cldjahFzcJQnfPGFOFL4XsdjMUC_fYgrZlvusoQx8uj4vCBko20y1O0IRVQa8WxLBQ2rVX0Pz8rJzffgnSTdSa3hOetPzceBIr_TjhHeG10b58bc_hYXp8jyC3GNeLpTTdcDNJevZ2N3fBFkUgw7MinnqQ_qYLUZvmVFf_jfgypueN44K33DFXYhkbaSX9ylysNiKZYh2-VhQCn5SPvdZVUXFw_eyfivl9NQUfQ8ArMcIHJRhjPwWtJTqQpreviQ96XySJ3KNd2FSRYAQ8-I0-dUpY45WtfJR5hu6y27L-OtE01j2tp3FuWy4FkOSRqfa5Vs_pxB8r0LnwfcTi3uqYAKrecj1LfHI0pFJ8D9mOq27rQNdbJWopd8LTpe5bWbLoXFarCRRbzPYIUsylMKjv7LZJQkAxP4jtsliXRBmcNnyfy-LW90FMq1HhGsDH0S6URKihi-QQgu3lLxn7XNyaTedmYD2zPAON8S7mwn4AAJFbyw9QnKsI8563YBAhyemv-hqovqY-jm9LOWePsjFoQ5LdeV8Wj1u9JmZ-3p-ZOGqahy7J_FwQyzZ9x82Ub2pcgAS-wKwInJmQcXlL8HzbGudPDRvrq-5-QGiwJlGcczYlyfn9iNdcqYg0zt7l4EIkRorieSgehwNiRhuYpQY2lph7Jz4ik91oYGHUMmNK_-WHCIMQAxHmWThpKoGWRTk4LLtBnfd-RpibwyVc7D1zhtJ3u-MzMTSHx1beLKePr4U0QdN_1pVytEUkX30l20xzlrkR03xWTzT4mOPTwlpLWm3gHq3a2GIn8gBVf2WBgl4iDfxzeWPL5_sjJ_LqXRsuSuisggOgu-m-BkVnCcADYXUVsuDJpQBRXKUkAInfKu8m_zkEHc7TJgqimjKsgij85pt28QLomVkO4u_WGcXQ-rcqmMKUJp1t6m1RZoipvyXhjOcxazImT88qBNBtgqj7e_jWeCx89OBWmeewrCfMLnIePS9pI4EKl3SgJefKycxYjRCgxsBabt-yf7VX9XE6TOYLSHRS6hBDA7uhFrvjgwIbXptYm85QMFzt1RaL1BlvVlYtXYhtE4JLKbSFvRYalgUWn74efrkTyAW1veM84ZkpLgjMKKADGQv8a6s6BCBylu-Ep6sTQdGBX9fU1n1TthfLCGOwdYbjxRGNTbJR5zWx1b9NdRG45dGmmoKJZ3XbPC4b8DRq4khkjdYdSpQI1TJWNHVd45OlQ_IyTzGwEW9lJAiJEd9WiYIkhTjMRJ-yKXNC6A5yx0RgJ481qpNd2z4VhYPN9nQQifnfBX45_-pldqOA1nFbWB0SOSkz8Hfx1RB07o6xL5PVB8DvTtGY2Fexn1K1vT0dK1OWFgx8rjQTyPfim-YDZeurucPudtlVl_PaYs1UdSe9nwz8pNqGtQNJOLYrYz9EGuN6p4U-cmw6fUi3iK-w3FbDKNjFeodYxK9jkVxSG5Zl-7LZOj70grPbLKRQBs0szgegBIF46O1VDgqtPA4RwT9jRQ3TBTNKMTdD8KiywrewTnTtmaNJCFAYJyoKCTqrBn0sjaPO2GCL9Ll6EFffmpn0gUeKwyY78bAjKryqJdePNeVfCOnIw_d0VwyKk-oOaBoVCjXqTmifrcECCxk4CkojZ_MZp-NqjWpdR_F3nPe7_O4-_YsKR3BVscyUXz3fAqdFd_YETmBv3ft93jDYs43NLhOnpcjJrB8SpQyFdQs5mJxGfaUDWSftD7kC9eIFDUAT1Pl1VfaJxX6qwyiA9beI0MWxW8iewV5f2DUe0Olqz9SdzaEOaaDLmqK_VHZ4zvHUVS_VtW7QBO_cdw4IIl74E_qsHJfMdkSERc3rSmznjRL44Tkw0JaAYgEtzTXKTmim98oFkYvC3z_ZVfGXOyx0n-FuV3etLhCrYuB7EOLzH47UQ56mosF3LiXgyhOsEQ2UFG1EB21EEYRwJ4MSxlCKf_RN3dgWtW1_w7NUBzBn2k3TJaJhlqRWX7EVguNBRx8wyA12HdyfwovL5hGa1ief3kKBhEztfWVUNHQUh-kPoCQ2i-bF76ji9kcHtpqgxJNrZuUDJ38pE9-_jqfaA-GeTvwvNin-oteY0HJGTWUTCUcjfKEjLxH9upptvHClEv94urIMWIcLDiWIP5KtPcPtt_S50nt_PDuconpgFt086THHSsJLA3ybtBG55bqXsj0gAd0mT893k50zS6ZWhcdTAWIUcib6eHqPosvUJ1KigzDSXWDHh1YXrpZh4MTon539ftf9VsC7ntAIbk5DGBx2p_4oA3O8BBSAuudtY855amCNf92umG-PemlLbxCkGp0RFD1YzIPU9A_GCdJxIeo3FH44Cl1E29wSmgO8lTB-J3ph3BRKbkE42Dl1pMI0RH5wE5rOk1Hn8ockIWvsn3Fsa3ApI05KJpNR15JQ5ZCULvyzJM7ooGePx2nfOJhGtx2tD2Fy4MrcbvTyTTR42JcYqkHZZJ8V9H_efQah5mp-81EPotvNCnKcG1VYovjWoEtAXzHCL2sJ7jynSnRBEzJzw==","summary":[{"type":"summary_text","text":"**Planning assistant baseline capture**"},{"type":"summary_text","text":"**Designing assistant reply extraction helper**"},{"type":"summary_text","text":"**Implementing assistant count baseline reset and tracking**"}]},{"id":"rs_0c2eea7faf3a6210016a589d7363b08191a781f00ae65be7aa","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ196A_dHCfHxB3gsgRY8VDroRv_sHxGOFttTg8-3iuGBe0hfyggd_2IKjbePBOoD9rFfuXucd6Vmcj0egLi745N1xJVhe9U_UEWcpJQisCOhQel3ZEldROpDa_XbgCgd92VV9eGckyuilMMg8bblQFASMYWWUyazv1s8OrPDoRS7dS_Q-D5qcxbpwP0h4GNxiU6BA3Y_lpW48_bs9rlsRSc0ywMrKg5XD-UTvJfdnkq_SX6KHoRaQEgLKS4Os8y1fXs8wOUazpH08abWXAeqE92yF80Mn21d2lhTPFKxRF-iAOUWesm3ULDICjKhh8RPCrRMH3QgdTtUwLOsQGNihc9Z-SUVr6WkONdZS7WaERFlXTE9jhGDjegBdWiUOOIfHrECnIaFEFOA2ZMRp_ZlBJzHJVpnSnXnFOivvsRJ3a7DY7qIB6EFvOVi68nDOu6QmIqCJyxAQ6Shql4v7HqtSZL4wNTR398AH4P9qQ5Ac0XlOAnejnV8cDrTsB-njZn8Hls5XrE-SgYaoKeVZzIm_yPKrB9glGvTnxt36xP1o4STazw_hiyJbUdgstjSqKavwxmkoh5uSYSLuu2fHpDg9od_zuxKF2jS7wikzyTVXcgpjmTDA96NsBWbvjb9bQJlzRArxzxhVIucwfOl4xnDNN2qkHm7gQQb_1bKEiV_RVKEngw1PxGAio4CYnwXLFB_SjFpa-HZDuMJkfAc3ZYXIwEyfXBrGFw7JJWE-Qvm4Rg32MNL2N7O4k85ZrvUgs1BvVvdlRj73YeevuO9rZ9oUzgjDzbycqBuHq39ChbBVh-jeThYIVJkzoYhVnS7iX27PhlO-Z5xOJkATO3EMSfwe6Zf8Rs7oBQyknC_EXkw41arQRMHWPOSlu6dXTrBhKajatbN1W4Vkil48mmwNtOqSBf3b_jlQd5ZmW4phfqPEubuCqokZSvAZr9CAbjfVT13oErFWC1pzZ8lFremYmKAXDauoSB1gZG4Wm5TMz5gOGbiVadN8IuOfGfj1Gbey2rEjRFLdiCA2I8pahLfnjkQo4AG8bRn1GSo54OPeSmAAQtp2vL7A1Rs0RiyqwFU2i5M8SPLnXY4M0e_VfVxzTSj6OCuvI3Ral7DO9utCs0ujF8Tz30m4bTpjslTZdYyUKC2OSAONPckjfKnHn5udbDUgvvWIQK0R6DraZSiyexpkwM1TSnf65w3ym90WMiXMXD9bFqg9kiVqTcsb5f_BHDrvq9UL7_N0UKTzAiYOuz6md6niGEGYyAvOS0YX3SEL9TYVa4DirgxZDj36m0kwCRq6dOokqz7r1S_HbyielNMGnmKlFkQi_94AhlY1e8KotloTri5kBcZwKM-8V_k2KrqYtWHgW8by6zROJE-ixjNV0cJQksCzFQ4sZXW7nm9LpdxK92XArvSn7_WMgYFsVBlUEDiplLhlabuvKpkaPNvzmSkSwB_SGCMVJlqrmZUX5GSc5rm5ahswBj4C_2Nqzhv7DPPXHyOFcKtMyCbiAqETosn5CFJW7sH0O-TDraFyHfXa0tkQJVQbytq-BGCRferiwri2zt0CLfmZXKDrWwiDxuUXkpoX61zcBTOU8F6KDWDmUYh79oyPoFCP2Lbm5ugatQcSzYpxiOVJsMZrs52SZD9N2wOhHiznoj4FGa4ue5W74M19alI-wym2CpLFdStbdCHKdtWzz8dr_FDkAvp4lnzJkcmfrI3BWLDvkOqavg6K6DEvd_KE-CWNboao1v-PocpFixO28hqt1YLlbuhzE6Wf2GbfxWGaV7YyIc7SMSdphTetqAb3wk9NW_5fQH7gro3y9uDBEoQ2DPrVumiuiKwCsuDN21Ib90bNnLwOxWbHc2NG3I_u7QlO7obwJgECeyVZAIZ_tnLRKu4IZgEInswhthF_NGWrCYzKnyys0Rkd4mY1j2a-gAwi9fJwkYev6XM9VBLickNBJYzhujXvKwXduFnWka39WgdrbSYYWSSINVu7dZaiNZ-9I8XMOHLY7DPZkMST0zjn-sfwPGmyXm9HdWzpExWK2q9MwnuH-J_T-UPsnbDz9qZ-i9KkDISUje64C-h9iPJ1EOp3rwu_DpNLPnaBfgR_ueWl7NrOp4mrd-Xwu3fmC5m7V4QG-kSb_lBB54-YkfQUv03R9qfC67Vu_89RgR_rtiI0deXcW_-ptKQ-eeBKW1ZIiCnqygktxBJOedJgNBgF4UqlWhTFUDpmIzlXvQ6Hv808pmiy4pNcPaVcc8OnvhNEcESH153YZ2o_J5lxe-izGStd4p690DRy-Mgm5z9h0YmQG3emewSiMVNu24TSpi3BGmoTJF0gXUhvzChG8Ai62ZKtep86ljdOhK3RVpPuI0ZoYKDuTMv0bZrefhW-dYjC08YJR-NiIYMPoao6zstBBpRMlWGsM5SUg-pTiiUNyWrlz3Hucfg5NL0ueJ1zvorkDmZPlgo84XpGVUECqP7NAKJVjYWY05jvgeT2MnxE0kerOoGqCrv_5eyqZsvpl7N-_sNMN9aU7tw64EKSyuO5A6J9EmuPZwnh7bOhnzRXAj8IbpWRvyiXbg8i5BZRB0JHOPmY7sd_QJoefYAszaodP0UQV5EWgo1IJwlfuV9OfxfE45wYVVE22VKdimV21e7ufhARRMb4WGSub79FhtHcPw5jghTtd44Okj_c98FU6yvlUHzzCPIx0au-Q1zaDg8yZF90kezRgXAJKBl3J1P_584W21XYmycWmxhDE9lD7ssP6ncihZnzUFemznxLF4rRhxvf1wQtVpxDi5Yj3VUgUbN24-hXyxuKRHJMPJQrHNW7UrrMMI4CBVNdSzpKC_sBSDAmLj6uQbVSG9thc3X4rWmb940rNOuMGEcVIYErtd57Jep1yumLX6P0mpK-2XslxHYm6gQTK8n07AlJtsmdxTXUWDN4k59HGgXDvQW5bLuEr6NuWwtofQZcyvS3WwWbh2IiVbDdlqXNRHHiIhEsT42Qanx1Y48K3iXq7VLwYWdwG0gR7zGg_JvDz6Iw56hVm_UCsVk0Jw6j-OqaCHomEAG8iUW6qmNxxstcfMU1NR5SogGh87u5O_Iwbkl735LsvHO6sKfbizwdIQ31tUvsKR6We_KI5tVQpxP819mAD4mB1Apzx5OIRzqm0J8EkwhHhohY6DQzHAf4EbVtSBfMpJybNNZ2Z10rDYcAfV0S4LDvMDVlCqY5Y9oF1dMwuvBryJ1BZHvPQG_AVQno826htXBU5j3j5ji27Cclq8wsQofQ7OqW9bGFMbVSmfo3wS3LQjsMsmm3LmH5DhRdWSJ34TUUK81EJoFN0BvPs6sy6gqwss2QWKHD8UO9UlyaXIgdhAFbpaWRa3pDCzhMBxMAr18HFNEAcW6stL4F4lqSQMvToy7SX_tzFNca4p8KgNrHvpZgKebQfGBBNAbBjQJtoD4p0dKVBV4ZzTVYX_Dn23-oTvxt1uKPgyr85ygtoQoGE3Y_71JnoRgTOu1phJZNdYIm7MOCtFFusn6lwwkONGSCVNDKo3ONpOQLusRCamQn50SXZBGpauVr8VQrPytcmBNNlNnfvVY784yPGS-JEBCxrdsPOWTCT1aZhcKA3_n_fDy5BDkDLOHcqdWYR56Ft0yue9S8r2wFer5e-GqCMjrxvxELNtD-j6BN1HBCvCYue6BUzy4hkv4_GF4-0mEtLfDwI5_h773u9EndnmFVrM3HQVY8JFy2RDXfUQfG4YwMxPYUW_rZHBJ6tFt2t_uPN5dfzwdf5k1e4yrEgSeTf7u85min5r2QnmAC_jZovB15KqUm8a1O9VlSA79fb6ro2lF5QGvH2WqHs7khoyCL61OiBfEDUjtnt-BVwc2x7m9lLb40J1OyjG9fngqyFxXP1gkfLpdGVTUuoNOWA2zz9YEwyS5oX9-h1c4xla-NEyhpn-939WaiQAFrOo7e9TXfVAMZIUjknp71uk9i2Xus0RguLsXyTjTUhmznyMVA-92PMypemoaXeWrrrWslqs4j9A24BiW_N78FIb0ZPNWduGRtmWKzIDNy9si_tAi_0WZIsXnCe70XwpLp6-7uKWzgojWAnvlh4la8HxBXzCQW0u6HCaV7Go3iyV0vuVD-vp0Yr_OsCbBZegjYLRBrj7qXzx9uYilQqURTB5-z5IM-GYixZx1nme2Kd7N_wBCcpud88kDaZGzMLtz_YLE5f6-F8hO_GwUQIMEP4po7Bl7z78qlZ6p8BbIPey7m4qn4Uo5M9tRWBXfL8dCXavVQ6isJjzDPUTjK3snNgjpJ0ODcrQVjN7odjkKs7XKGxg7i1oo783GANack68lO5HnLX9y_dYwnqLe0atOOEYzzR8OOhsVo-OMvhnr-ueJHh9OCH9ooWJdixdUDRVptok-BOOMkJxZlfIAwRGJSJEhHtvguG5N_ENFBmrX5MR3uYRXWlhymqOuGVvprxCi2MtsZK__xyqDyjXXY1Pu3A=","summary":[{"type":"summary_text","text":"**Clarifying reply handling logic**"},{"type":"summary_text","text":"**Refining baseline reset order**"},{"type":"summary_text","text":"**Reordering dispatch and timeout handling**"}]},{"id":"rs_0c2eea7faf3a6210016a589d7db7248191a194159580873861","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ2FH7IquU4o8QzAEfz8thluaEjZQLgUE4p4Dj5zMJYrKe4RNR13fTfvf2tNAp3UGxtTckScIe0qXg1ds6V3tfPswDYlsSJigjxXCLjM5d9On01oshWp8_i89DU9299barcav59aFDoOjnSloptQd5A9vv6Q2tSo-o8ZVdUqLMGzxjEqaTOJTt1qiPB7EY32D39FmanRrVhllqjdvC_6VX9GM9juHXFKmhpwTnwKjy7dTF5jo5_jYivhANsdfmSghB43Ol0Gc1kBRyPfPeSNGijYhstPPDTqYQEro9VUrOW9vCijgPKdx5NC4U6Dja8yjFoaMgvr3vs4AexyZuHLmqFbgyOWvQM99y89m4v27qJYYnr6wAvyRFPd-1jYLBg3H1wmIKZIvrpPEr_lqHFdptTtI_zVuMGzMgwQQ96ppk5_mTLb2iTA3g2xM5g2P4y2YPitvw2R_mdAD1Yf7sdsULK_IozAAxqXS2vMJgROr_A_7RsnnpYIfjSPHAELHku6adZoUbXp5e2rRXzMSi-Do3AutaYGv9HUHZmzmmF4JQMuENKFjVi9brmG6xT-9FobjxIRRFTlLZQHGuEBPxQ4I-3IcqQ1PN7K689d7OG5qmNu5TAKhiHSj_2FGN9cWE_uJexJBvatJYs2uz61Rhydtw7zdUM28QeiNOiOJqORnYDLGXStd5CFQH4s9oaljs1hqV2u7VYU5lpjhHajZiNhJ79qm5krtduNJZfemikmn21Z88-7dHHT5JZlOnVmNWDOw4BFppYIlrhgDALhYd1pocUNBYTy4_CpI2I3oGPxXxS0QaA4c-68cIpGJEHe1_Nl5MG937WH3_V9m-YbaDz4NWH2sqW-SVBxy0YomAOLJEqQWBEGA7mNE7ymGpqDTWm1cbYdwOSby7YW9k4RWlBrwD95v0us41h800ncxDZmlYOdLviDg4P_mmZzS5YrgbbLWRsNAvr8iNReowaTAZTqHyDGwDSEgYQRUwo036ExB-QZKd2FFN-H2xmbAD1bFzKenfXxNQWr6wUWvm7gqJ72QejTwoXfDpk2ZM_doTtDKPRBgFYc7amkfOyQJBh5eJM1QszOo8qWR1XDnsVbB-1Son6UmE-jYoxTk8iJNk4byaqDk6kdTSdN8rzMC1LD0O1FiEzmlKwma-p7oHygRC29oT0fnxKNdMYlymT9DdQhFl27pRxWQP5rhyVr99JdGgT7V-Hhq5Oi4C7F4aXStP4sDg3t_7STEO0S4IfHJpjvGT7CIZV1pg28dNsHdrcu8dWb0m20fovv9P86Esp7z2mpRcLM5SGNSl7NMnA7R73YocqozvoaRJ-C1y7jG8LkLoLBCVNnTxcNCausG7EgmO7qPhiGGL5VtCsjtsXvV7PtPou7V-wgIIbo--34QR_YGfJq7pUhcam9cbtKlRtn1D7nF04-T8utS33Xwt9NY9VyiDCwLaYhgUxJ3tLGdS2V6vBCBPLFZpXQS8JGW8OZE_Jtz4Ai9dYaZYy7yvpBBU8gKAGtvYTHdtZZxh5bJwfA2oAZ-PRaVp5p-ozyIz8C3IXJWn8uKJvTF9vz7ELbUKSWFlWZgLDgo2ryx-Y5dm3t-s8z7PLi2LDa4gLO5mEQMqkm7QiCkAARrPKa3bRTZJHiYwb1LhapIheGhiDSbL-VTlDww18nMwU9Plouae1X1ulP97VeEsCjHQimRcmDojRTRHdLDxMv-HdCp0sf9Vs6g0qQVJJrkCe2xhNGoZJ5WGsYFtE2TSQGAeFWpdR-F6LCXrlRaF5e2_mcjikCFDDS4jPAHpm_PISjsS6M_aeF5PRBQ7KAHPZ0BRP1dph17vmXEc3mZw83X5mMoUxXHUlOEUmh7Bchs4SfL8vfpF9h8uQ7Sv8Dgt9xvPBY5BpgmabH_P3Uog76_Ppf9wH34D3JtBUETS9_lFGN1OVkCpbinU3e19wsAdD9F9wiNzdv7CQslGQZohLKj8yonO5UURNIt3ZgFrB0UWF1ylDXMcO7cvrSqkpm8_kDDMimh4gt-B9lpeVJrjQ2Eoz_CWxzsyV2HAASObOE_vDQLkA0-j4cmHVMjqSfYD6nt4TyV-nN-BSh3MDA2TGLv-0zkOrHgCEQzGE7aT29TJcBvhoMasozxdNFF1DS8LFyHFGtMb6ufyuCx9No3DEfPSZiQIWv-peuQPZlJl5LjUr7lY2lgkRr1dnGrMyPuovqDwiTAHpxVA1txuOEY3zbDMtpACT2OkjOofHYKKgCiEjM1UXro0r1uVeeZwE3aXgWOBs1U_Kw5v4FxeuMl71oYjv7547GoX0c79ZWGDf872sUpm_LQE-Qc4na6fHYsHhhECrOIengFTjrbdJur9OSqxeovSlOi-vEMvy2IfOjvAGnr5MoGJsonlrXbIzVXT6ZMDDL_NM9zxl3aZKCSYOyUJNWGNo0Z_qb4tVQ1fOQQpyMqjaMPlniB6_Mk06jxqSGX1aKTClXtEzeDQ_-bKNIaBQMaTZ07bi7i6RCR6WE-5BhlBLNJD7k3JTkLv0L4nsxN0-wKs27gF8tNuocfYKsmkW--_3b6TBvDAJdjqBPyiCIwG3JA5pyuqN5vvCYeFAmFE3PC49Hf2bz2Uq6hKmgVrHBIDYATyAN5pMcNRsCdIS7cVvbb6mU4zB4V3UZRrtr9Fs4KyLdg7nXwufh4EPAkZCT-HQ-1ta23gZs_hCKfAelUHhq0tCnLtHDVUsBcyILI477JvcR-01nHXuKY9gJRclFSZHUuo-HnCJsytK1PE30QgVI8L6bxZG5tOIjXHxWGafVEcdoiP4Ok4LYuEBw36vNQ706gtJAnnyoHZOlaT6887g2Tv2zwzKgo75xHlv7NWAtlP7BicI9s4_S2JplVl6Rimxwo4zSCPq-coQz6WbCyViJwBcCeQR0cWd4HXN_cSf-Mx-y_ToauObT9D6QJq7G2mfo9pqLQa7zmyiuJYlDxKscjDBZDlssYpbAGjU_a7s3UYw2p36SlPOVWpf-0V2RdExc2HK2Ykdll-JT60EqzeM1x9fvKbwFxA8bkjLGlJasYuWDu5dLMwHTZgd9yhkSsS24fXwH49bZAAkIVTUzNmUWsP7RBUH75msIbji5A5TXaPkWOHriXZ_0y8uWNNrewlmp8DD_72qt4eTPWEaMXgLGou6FRw8hlpnGQ7RcWwtbDT30eI0OFjoQvyOINy2bhywpOEV5gd5c9UHnR5-17ccy5qlX0yKzcf7ncNXwRAr9ZeQ2vwAoMvnNK_y6TIw2Ye3MjoiNBJnCj--SNAI01ASYbcwHMd2FkKMDvGaXg33NKR5Vr0zF3YgpPXbbEF6h_wuMhJHFdHokVMh-5XFXIAfMdnrV6GfBTu597dH02Ss2kWSEnGeo5xzm7Q2W9EWDmva5-Rj8gvU2HMIbAjrIaBuDKxgaOpqZkL4wEoip8aWtS6tia1X9e0cWs3xpdGRKUQFH7ahZXPyiW7owUH6VhlNY-moh0Cippoqc5J-7yiV3l8xbYFStL-n17nIHVVhfOuSqf2vKAGxUGTtIzN7eQRkeD9Bs02__rrhIeXF-FX_wWxaQWp0z7-55cN-ZRVLGxHmrSwJ389Tg1MaQDNC1vOpruJjL6XLT2bBkeD7iXdVEEJIyFTDcDA1N1NiEI2MPH6kmcBqvLGnF4kSkl1SJn4xUZMKd5QLTJ6Nsvr6JCwM1N_Xr-E3xFl5-kgrMTCv-2jLEqNv5bFVjC8MAbYPN7TNRleqDna579vGEHgpd_MM0perEKBqnytToF0o6CQrx9PvqQqmVt1G64kJJSKoIhP9rSSQhjIayXTqozu-2KbBPz5njO1jlZcBHCLr5hx_pv0BfXrtD6glVquUh3cJnDve1-rHS1Wv5Xp6Gyc77P9rhgymQDy-P2vcLq96RtdNJapccm-vgf07Oq9SkN_zfAUNfVOR_fYet8Y3GbIElJ-qRUTIZjek8YyyA36QgHEx9bX7H7Pc2a2HEVHfcvN-RfZHjMHVAZj7a3uLMFOIoo36DDiMJSqscrKiQDRJ8bj3NEGXUZq3ltBfLHu4HQ6foyFXx6GTWDaTKJDZJXGbdt5vlbdmod37SNtLb_l0=","summary":[{"type":"summary_text","text":"**Enforcing consistent command timeouts**"},{"type":"summary_text","text":"**Designing cross-platform path normalization**"}]},{"id":"rs_0c2eea7faf3a6210016a589d85e8ac819190a707b9ff3161ad","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ2QPokZxIgk59GpHR1VZcXxRSs3dLcF4QPaW2TORj1EYMVSh6dj2I9Tl8aZTCwjT_ilDiFJLXv_jdP6sv1z6GfpjxhretHGUG4FNljwSRm3ZNkHTiNyQBeIiSCeJV_vqkuCBofY2Aa6ul1v0M02WUo8c9EINcyHJoesXzfgIB9x1yirpCkcXoU1LysS_Kp7H2NLiqXsFbtlX2PYYeIHNCZ_87Tk-yzbUzvqjfMlkB8hIKuNR9xEbJ7eziT3b0MbDIzdBOB_5k2QO5gwAfP4R0knIx0tknmei5mpEhJcPxrWXGjnAWJRsW1hxvwi7wms4Z53lTRrUgjEaqvzL7_worDeLKHF40QTqu9P3Ai5txVegTM9MGvX45PFR5_wDK5kIe3pQtBD7y0NxTmdMFks5RHelrrw6jLV893-nQ-caMPUBYpg12BU0ultEqoRaYF7VrFrwUUBF51WbOvh_mJj_ASw8BWiHW3O1oDPEa5Brns1KiKJNlhv6FRqAtI2fY4iXJDkk30GQOzTcRLwJPeMMhaazpcfDj28EBH_6YMLsbA7Ifh3KFRpiBqYusyVAIfFbjSF248vASfbS9r0lz2pZ0vuTN-MTi9UAsGHCZ1ioH1osV_Ctbc1zCqpmdqShQ4ZaLGS03xb_Qm97yqprRiXuPhkfxFH5idwBDfisCIHA0m2-Y729gSFGkE5lntsW11yz6XPUV0g45PyxAp_C5cAuRTWwtimMHTl1pbfx88P2cfTZMvHVCjdE0gOKBzq1MstZla7zqk9R5DdB5GA2DBYiwojF1SRKnVl0otCTnGJWHCLbS38R3iNecjOcQEGbSnhJIXUTml2paKXeR0fK8YcVJ2IRmJQ4KFZq42649ZZFq5Afwcj_FLpzcDT_dQF_25lY1OnmBeSqie9CO3KiTTjL56X53ZnukEbeZiKM2hWbRccrp997CAFOU1V9Fl3l2P3ELMnXDMH2IGTZ8SQDfjYXrGjUV5VLx359_N_195g3HmTYzND9fvkYy0BsuFoBLaszIwz4qTKk1s8MVDD3a4f6--x10sibgrC0Rz4akVbBPPs9MDZC8dLJgdDPQgPybpfL0kL2If6MzpfiLADflrU5QSx7oXzgBW2u75C6bP0mT2Ll6u0wWPF6Z3stUQo7yb58pmzZdCVynI9Y8C7DAKKTUTsM1Ysf6IPWIf5wl695MCKeR0kRVhP6xgq71Y1_mF3hN7tDiXJbv4QIbtmI9oHIw-jAz1hruaCZ2QJ8cq2Y9N7mgzodU2siDNACfqntAoyF7Odajrea35_7eYS-E923mbuUQTY31LUviiRwrovTfl_QQW_j4N6m4fRPG3I1UhXJ3JXkURq6-rmboWHO5HsoeVBmOXrNaTWrGZBWFlHSFw_kVGOvZXr9vjaeU_6bZPM9YNhtN4G4oS2JbhTlCQ4DXSgO5rZYX65nyGAAbdbOpBAuTXIu74kLpjPM-Id-THIp4dGVRQ0UbFp1hMbKSex0a8YTHJD5eWD3VazHiWU1X6CDRRV7VkMfoMiJLA1Wld8KcSMaQ8AHGFRH0utA3ru2ILhlqL0tYywg9reWetTfJEPl5uUVgUx_AJwzLy7_n0aayZ8C6Lq4OdSUO4ER3Il5vPXPYBinthAFEAhB-BUcqhYhFV1pPhbW37wKZ01o5XM2yLil8telLy0L4AkorlYlzEMY55YjaV20VQcY7ZK_XNybSoRZwnaZu6VDmS0iVN7t-qdmYTvD3abbXysmgsD7G-7fZBYqDkeoA9kzj98Yo0U_lWYmYwqvx6qdhtVxMPRyR2UJ2tEHjfT1NdiPtpOWzoz7DeFMG3xenD8vItZIQZYD9E7FyGkoCdzWOC7a8RXq1PdK7-Eph4zDR3kKIigl_Ik4aR_Ij3BBM6jdnxWRj9u03qts8oDzY1-_LyDQpSTZ3gPfAwqeQes_OT0d7HluxKFUQhBmCPVfhiXs_OrMAwR_wwrhWCDAh_KvSHOapxyBRmHPruyMZODhU6WD8OiAAye-VzJs25Ul6wJ_edmYiTilcfqNxymwAFAplNeX04QnTnW26Wx0cBraDZ4FVd2ar2Hwp9wnD9XECpCfgcj_eXZ0nOBhxAYfnHQMFm9QIEdU-Y6IRFgfeAI2Bxt04f3TwFaA4QgTvu7sQNfaiesxxp1CER6RZVop82MUAd-YXLFoCzQ2PWJnRZkcZEFgPPxxgifP3IleDVTPZI0c5ug3MgSKGF7XZIIXO5aq2iamRMCnb6c6oh_NLjytAMJpyxm6ogF4TlYaE4j7V1iVPtyEL3GTevLfZxyjzU6KDt7Q6ODEXFdaySwnYNaETGhjckZ8e5u5c9OAJ8rsDx9UwN5BtLt-BKYcmuz9Lye5biCbZCGRZtCzOj0Grsm5JMLFzyMC7Gn5Y28z4DCzV4Xm6JR1_21bcWYNTuDNH32hD0BqXl4cnnwxVtnJlikL3pKIpJdiSjW8wxcJArH0L6H9knoa6qfg83awYGHyYW_BjdQlkC5vosooyRhBD5K-UdY-xf6lQW2XpnoJp5s5pIIUpfZOGwqiFiHGqDZe0a6ccIfquBLMkOu17IofrfWuXpks57QlFmN05JWvY4Ho6cSAaiQlfPOQv5_2l7etDNhB7JtzPfY016h9yr86cI28O-jUWFC2cNgvP7WU2e6j3I33fXDMVA1Z2N8bPYEGn0c4ii9w_4_DD-GmjYDPV4zLWdV4in-vFI7edX4ldKlwdnaPlnio0fc5kpsGox6m_Sg8hpVdvjagA-CTbQqsbW9hzJTaiF0-NxpWd6x8wAj6WYduMrLBSrM7ngQ-ekH0rqXX4oQp9iL8cu1qaJ7k1KSoyV_ZJ0kWBDik-2lz4rogw6yY0Hp9dgtP-_CWzCWxj3XwKQrBTyHUVoJV-5ekpfBc5IsI6Akz22BWbaa965jKmoFGjHhN8-St-DXVJVFL2lcyLu3ncQO8TLp--jXnXxhdYMXlOZjNu9Nf3TFSNKI63TaYuDAwOK0MG5ZLvSzIq3kFEiusceurG-vyL_Df_CC4L3nEkcAxJ7Jn83GEtnH3vKQLn4EgsmjxIRNtvlhGbHwKzkby3XcKONC69VntcJWlnGGpSnETeJccbFf276d5zvm8P2U-MnE2mVJAZnPPobC2KvTztU879BQCVsf_Ye-yvBWoJ78I3k-IzWP7OqGiiRizBvWYAO4AM1oXEgCoZCqip_3_ZEsVemID9maccoPAneltfCrhPIksjuapUwnKqc4_34y9pTOIxU-nCZ42LjzwnY6k6UG-wqYYDs1VELWzE6ZirX9ZALm3nW5us9wmSb0hHwV8-XslGfWQxmhapgj2pjN__OYcstj_lL8V3GbixPf-hRHj-hjfXfhno0uI9ZWoiOZhubA15rFV-NWv-M-sRqN6HTOIngSraE25IePOUf6klwk-1eOXUBczLVRzwuTZoWzD9x1yK17OF7i-gejBmZPYzUuLx3QNgFHz9GtoaKQvfNqB0rifxcFuYecmLiitMCFOYIKcNaRpJUjz3BoL2WwldsqdtrgApe7PDJoBBMMW00qi7oOd0o-760NIVspdHgOo4hpr04g0x_MfigPFpaos5odc-axhBociTkoex98heisA1toFZkNYJgackGXNL87KqJZi0xUxKjPx11_KTL3NIXvo1-AAUTSiz5VW3IvaZdof58BNXYC55Ep3Q8yqJJbOq5ZAKhJuI0Hj7nDGtlY4X8D8wqvoSCmurVo3gtzMVZBK3x6zwHBXbynPPCBvgtpCRUsRqFAIz5OQAmkE4kcBPiwM8uACZkR6ZkOsgaTx7-wloexHCgK5HkbhGcUXfR6qD6VeFmWaYBCzeB2LnlFx5O8D32ETq2tGnRF8sdTQL8DZaVNg5TpcPI8Snviy1w5nZcXGd52vRNiUDxL5lfm14V2K9sJ_K_viuRDLNZ4SpNeFR2Z9Apz7XGl_CxPdSnGSFwldFnXGqMKP9qJWxX3WhhtZd24OGnS0TEmZj96rhS_K1FfDKTZvsYSNmdIklH9CN_4mzY68JGQW20ppeR04Ys0UoJiiDQzIEhWdx4Mxo0D6V_a5tIa47DaSwe3Pts9PLeMc1D2r3Jk08WqtRkSB1kIL54jnXTkKs4wwVJ-R7p-GdVXYQ78JWp_5MVO18RXaMl3cK1HmetpAc65uhpJcEbh9DXraDnDXyxdGOUG-l_ODB1EhQ==","summary":[{"type":"summary_text","text":"**Implementing activation type resolution and masking logic**"},{"type":"summary_text","text":"**Designing comprehensive Markdown code masking**"},{"type":"summary_text","text":"**Refining backtick span masking with exact run matching**"}]},{"id":"rs_0c2eea7faf3a6210016a589d9043648191a42851187122990b","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ2ZoaCtfSfvuv75AZY2lGvHtMttEx5zODi5PkWRBM79N8Y4r6f_C7Y0Eh8P5Bcr-mPcYxaEtgMB-48x2_uOn7bEU429WOsrhIYDgdZUqGYVieKCblxjz0xR7CspubqKF7TfHkxtKyuqwb4t0SMbtD1lTMHOSqY1-xyLClWaaIcOS-Lw0YACr3vRYhrc__ohjdX0tg45vRt9yuo8PmVcE_nB_Xh4KDwPr_2DfeMM8nTrBNSBuLLpuHka5CFxxpSgGnhiInv_imZUZbMyjtJFSTUxI75dldLmVIdvl1Ce36vi5RByixXTL_gIRuzR6-n8B0NXFrKixQ1Lyf4KO5xKVtEfVbgo0Uh6W3MepKqDYXUKP-SoNk3bcvicW5-qnS545_8FZVHZvNQ80F-nnm4D3AGDK10EIvCajPoqcHhoxPbsaXR4W2E9l11gvYx8DN1dVi4QvaD6JiDxW20X7v9vEYghqdNqHHKlykVculv45MsI0VZhqsgvkrbC6CKmgb-nJayUyfFWiT9gYZal1wQaFa56Ud1rdta8_ijQAy1Bzkw8Cm_0uuZ6biSHLlRm5zzogNpKwKDyPYz4N1NKaZewNgu-JUrDBmsopgAt4coHPuU0C_pLBWOp77gelFYFep_HV3wra-DQk7LlYbcMEoyLDjwBs4QjTMWOnj5Zwmcuzv0-AChzv8NkTQIXZM5fWTrrUNaU8ZI8_lrEpu-lRcRCHJPiWYdoqWvfgBMuYnfBW_j_klHgq6ZB4OeCsF-LMZlj5la6mArRGpeh1JoEUr8WcCi2o08Rr7qI8NAWYFb1CKeLxiKI3pTsE1Y92AXXs29q0wHxB1iC92fiwBLL4PzOToUEDHWF1_8G-5MMas4gyLT0nLLvIetPchYc-aQM_xAU-DdWFSanAvop9a4SrRlpL83LrnLLUnCOOEeXryZM3vA2h88ojmYtPzjT7s8HJtDu4AhwvLgydnX2SUqKxA6i_07fc0osLzJzwdbLzBNv0DLyXUCRVLT_hNp-LZDIQtWQdB0b1EYrm2A-LRfk90eRJ6nPvINQeMYGPMdkiEz7TwhyKBxfaUo3G6fmPNxOaU0Xz55eRYk1s4257ICY28pmq2tZ1-h52o_Th-5N1kFGE5bdMlHTTtvLVeS7DMhkkK878zeKuHtySBhrnJ8rwQIIDI5X1cussAzUIjbpdGJYRQThc9Ze5i3FIC3A9d6Z7Ap6KA5szh2oDvju8HxHhB7lkFeNCn3Y_0_WcXLRUj_cr7tT2c3oHgVJ-oKyDoFPyPhmZ39md1EZAHId72KhSOfiqhbp1ycuwNPq9Sd6SrbPfqSPdAoAev7fCoSdko38lL7iRZI3r6oLrnXXTJHn_CCAb3ecvdqIVSXiwKHAfzNS-h4g8nc_PbPwk_BRoxOGPZaJvLJevVH3oZ0AY23ix4bUnAshop1qP_2Fesqxk7lrCJkO-WRl2415FBZ2TwVjFWJzRqFh8Sfmv11Fs6xW1N-zS_WfEPfuVmUGTv-20UXNH_LsNieBwxLM-rg4xX8J03PzImhj89pC831r6T7QD_EEYeeHvhNLyH9R42cD5BcU_Hwr3iSzHqOPdogPVIPU6QjxCfhSwSvZU4RnewgMOZ0Oc4Awm7U6bf5A8ZM2jxs3U4JqRCY-ECVjrUrFMHThKN_aTWdSfjkPfDMH1rCr5ztKnENO12iYzpP4BA8q1M0m9lUczwN-HfiLrdcVSyHWmdbJMwKWmN4NdC8pMY2vQUodVAFFmfVcXOf_pDK8OcFMmTFPSeqQZSxK2dBmIXMC3HB0nF3wrHAqUfJCy-MTI1sg59O_waAcbqzkTZae33HcJhsjG2F7KH-KbrJQeYMKYHoXK3bg7Jy4ZScCBGjYMS-SflAPV2OsoW1-ROxAUekxB7Olu8q2hd0OPfOrVt3EmWEBLj3Y5yczmatc1KU3IxLWbX7PIiU0hu39mpu0ytwPSKLr8YuKixm19LU6_Fd28m_CHlBwqR-ht1vxkNwDoGpQ0Jt2eSjWFYCOh0Bp-C0EldtfssqsBiIdE3U0P5n53VEeR2sWxbUPw4d4Co4bq02UxkrL5yjbsHYzDuHBPCnvN1jienNLeLtsEyV--fr2JylKbvSTsJ1TJIeuVfRQfKQwWbtwP-uiZ9GGrCZqGm--mZg61_MqaqhNFQukEOlgofpFS9T0bX-mvkDwyRYh9Uws233--MxcjpGcgrHPhZBob603uVhA0xJL6-qR7Z_Zkbn69C34SGvJSPzvqGpvEOnuHfQm4k1lCaWPFrsEZI_KUypU1l22ggmRqaiZ39SD5tfYYy9INyv-rhSGyYAun84hpc09gJ4rhGgiZal3wqQKAwM7e-DGhRqfu2QwWFensqZYXbdDkHLQkPjS85vmeLaKAhPpKccqu8fwNfM773DN_2AWwKcMltNKnqRXeQJw0Mg6B1pe7slIDpLxSAZmBb0HXW3DuUuYUZH-V3YkKK-3vQiqNl64qaoH9on7x6xMCImVDWtAVMRDZP4Or56EDGh85-Lqu2H3sfFzdI0FSmapL1Sscg09gmPDarXF5nbmdCVW1nvm1B_9zvZD74NHJLsGxixisvGEEG9WxoBhffWkGWfd2shm5VE68Fx2ueqf0g1mwc3I00CpH-u05GVfDZjADXXcXHGWSmLKuG3RWkEhrdXvuJwIdrXx63a1PgwUQB3bvofLimeZciGaIIii6pBgWye78_Tw6KF-6HnHzYMNgPpqikDc0pYDnbE27ArLkbmKb7AExcCaVd_qa3LJs4WneCpWdKgHjS6XUt00Z6RiiKpiO9sgeMQagaWPkf7j6QlJ_cmbH5KSH6plu-QTbLXSUoabWY-vejnJtQOliJ4XxdLfJWWoetf5tgYKz7Lq7mXA7fH34ot_yYrjq8aG0xJBQOCs6N9wzw4pc3TAxGNVgYNtqsHiRFgmjt1VJruhBDD44r5O0hOKXMeFNyWGX4wpFFNwtMpKGN-Fe1R9o-cueD_ltTeLgD-N2MrShzjIMvrzA170U_MIJ5kesMplseGff2b26se2QM3v1MovmvDFoUeELJXaYPGj-uGpXQdBMIjJHuNUgBhYRIG7kdt-b_0qu2hrSYbiDlrq04z55Rf22GGUGMnzvBGRbuWhEVrsz0TPujg3uMsFal2seImuGP3JYHs_bm0EIK8g7nWXrxwxh_Mt4vkpqtFALChTg4oD_snBO37-V7_35-7DHerqI5U1dy1Wiey0xMPwTp-4uM5mk1xtKAkvYI2fxLhGuHbp71qBxBLrxiaVHOoTnj7IeHcwzgXl_SqCYse5kXqS8VHPJ07A6KT4AqD4Y-HW9-voRMtRMkkBzyFkfHzIPp04ZrLoAoufQqKJRisJeMgNvWAyBjXIvSzCNTtyFJfK1OcQPRxpckSTq72Arv-wX63T-8FzNzL1_h5Mdx7n0zltD-d3DSix6OE-OQfsjvjGPCtw8KWBNonwWOpnFP2cE-nI-O_iMybMfG3F6nLPDDxBJsvGLXSA0vGMAOLnbJXeZBsFxHb8KQg2ow6pLW1u_TpSdSVtR1yBnrELKVbxUx7PafNbdmQCGqMksyWJGPa9eqqZiDySSLFqeutWfi4XE7PZ-QTD5WTAj5hLZDXHK_arfF_NIHSlVp-HqUcX_Uir6aIQvCiIn3kAKkVxhQasmb1PIuTSBjWnF3BOR61zeU9uLlEa-cxfpz0TfQvkMQtvayq1tmyB_0xfruyfZsuj6Q8v2wPqhzk3UMGjEkdiZNNb5_Krea9yms0htUG7BOkteE6ogQNwFdXDjYBob2f-aNDsKEhnXji3nCieHezkIunkeCJt7TwIcOLDvizrW8BLXJGFDbIV5xw6_y5T8yJyTkt-9GrLOFxiL9TdI0pm5aN1iC59_YU1F8ONsbqluzvfxmKT2W5ezuQ-bKlirp5C3DCpDMdZ438kZQCmD-u2xTIq5ZJQkl8GFfmstjZC2H0n8A_g4FN04g85_iDcNlZ9bjb7Vkt1IysxeLSBiFemM_nz_LIHWnvLNldBDQOpASf0FK9V2ohExXAwY8hpeep2PpXd3k9NGW7kppfTB8GJoNi-K1-n5Flkhv0MThj4zMCN1D8NYv-wYf9MQP39Ng9fDpsH3AJ8x1RrMzQshgnee4qqHvMKZliQX_zhSyNNxKmMcauStgChd1kNENsJ2aw1-gS0NLhbNlPICoqUd1M5MSQ7zRWDXD4g4YBuzuZ3td2K1ZGeHjoQ5Y7g","summary":[{"type":"summary_text","text":"**Defining poll detection logic**"},{"type":"summary_text","text":"**Enhancing poll detection and shutdown tests**"},{"type":"summary_text","text":"**Planning deferred implementation for parallelism**"}]},{"id":"rs_0c2eea7faf3a6210016a589d99e74081919c4be4b306e62274","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ2aniyCtUg-GtzHsYrJ2IPQrpDM9ni4G4TcIjlRH5ZS-afjWnFQT0Y5TQTsCiMawegI3qVkak-lLu62rL2vPWG8JQK2EtBAbFNNTckp4cPaV09fhm6dSjNRy7J0Ihx-udxHX8VRFnNLxc8H2AQXyhfEmdufZGngcZN5oTf1vKZZJ8Eu1BvDbAGzX-fUbsMuBhYJqhbkTD4cxCC4EUUfX1a0NuDMz4SBsow3go6JkAqARZtWG7Bj07AgNg9XItd5V2aO9Yngbi2j5fC4p4ilQdtt5IlXYO38sgNDjZNRecCOaVUFg-KY9D0t53E9WHTJVKMUXPKLsALpvd0QEhff-s90a7G9eE-FojaBaqqwXAxWqvP7A21lrMFGBnJS4LbEt48Q6WfXE-qNHJKPAbu5ZbHNE7pAwBDgR3zh5A0u0pAvGMOvOFALOhSSVDNQrW1RiasDUSrF429-J9YRNmQg8WXM9cGGOwxpbOLz-KMNcnTts25Jl-nWlHmz2NFtgY540dBu1HKtRSnpp8P1Se7L61CcEEFJVplFaxq8v3DKA4hJmwOTcvEvkjI0LLrKbl8y9N-E3l3b_RNelf3G4DiTcOFq0eS0PQHps7RPTVoZrtmjPd24SeuKZ0GvqV_oUgENCUHImQOKh0Kv94zgpQ_s9qDYqf-5ALV4j9bXDLqXrOwG25LGnRd2qQYbqzVk9uCJ2WXQWOkhnnxJDFX7VmgFULtH4n7nyRJm5bGzkKPeHXtfqMakn6sn9gPHSrdkSvnFOaO5oXsabINIF_ZXdc0X6dkd3vtjq0rgZVA8wkvyMLbyYte4FE5Ps3IkD7uAcMhaIYXrJmPBmugx8ZYGrnqdrLt1K3gcYiPYlqPVapzIwujnbw9UtYI0FxMU6abeclCMmvOHB6P-lM5Np1kwCAnVYE5tFoWwyETtxx8UolIqXigzCXPv3kwUoUKDICOs3MIzgtMc","summary":[{"type":"summary_text","text":"**Reading lines for mask function**"}]},{"id":"fc_0c2eea7faf3a6210016a589d9a729c8191981f369ce667dd99","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading shortform parser implementation\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"160-245\"}","call_id":"call_OyGCGaGfPVvKnUgE9u4EHQNx","name":"read"}]},"duration":53282.42659999989,"ttft":4129.963999999687,"contextSnapshot":{"promptTokens":206838,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_OyGCGaGfPVvKnUgE9u4EHQNx|fc_0c2eea7faf3a6210016a589d9a729c8191981f369ce667dd99","toolName":"read","startedAt":"2026-07-16T09:00:10.911Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading shortform parser implementation"},"id":"292527bb","parentId":"a533ee16","timestamp":"2026-07-16T09:00:10.911Z"}
{"type":"message","id":"1e3dfcc0","parentId":"292527bb","timestamp":"2026-07-16T09:00:10.925Z","message":{"role":"toolResult","toolCallId":"call_OyGCGaGfPVvKnUgE9u4EHQNx|fc_0c2eea7faf3a6210016a589d9a729c8191981f369ce667dd99","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#F43A]\n154:function senderStub(sender) {\n155:\tconst escaped = sender\n…\n159:\t\t.replaceAll(\">\", \"&gt;\");\n160:\treturn `<msg from=\"${escaped}\"/>`;\n161:}\n162:\n163:function injectEnvelope(messages, item) {\n164:\tconst index = messages.findLastIndex(\n165:\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\n166:\t);\n167:\tif (index < 0) return messages;\n168:\tconst original = messages[index];\n169:\tconst content =\n170:\t\ttypeof original.content === \"string\"\n171:\t\t\t? `${original.content}\\n\\n${item.envelope}`\n172:\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\n173:\tconst injected = [...messages];\n174:\tinjected[index] = { ...original, content };\n175:\treturn injected;\n176:}\n177:\n178:function maskMarkdownCode(text) {\n179:\tconst lines = String(text).split(/(\\r?\\n)/);\n180:\tlet fenceCharacter;\n181:\tlet fenceLength = 0;\n182:\treturn lines\n183:\t\t.map((line) => {\n184:\t\t\tif (/^\\r?\\n$/.test(line)) return line;\n185:\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n186:\t\t\tif (fence) {\n187:\t\t\t\tconst character = fence[1][0];\n188:\t\t\t\tif (!fenceCharacter) {\n189:\t\t\t\t\tfenceCharacter = character;\n190:\t\t\t\t\tfenceLength = fence[1].length;\n191:\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n192:\t\t\t\t\tfenceCharacter = undefined;\n193:\t\t\t\t\tfenceLength = 0;\n194:\t\t\t\t}\n195:\t\t\t\treturn \" \".repeat(line.length);\n196:\t\t\t}\n197:\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\n198:\n199:\t\t\tconst masked = [...line];\n200:\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\n201:\t\t\t\tif (line[cursor] !== \"`\") continue;\n202:\t\t\t\tlet runLength = 1;\n203:\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\n204:\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\n205:\t\t\t\tif (closing < 0) {\n206:\t\t\t\t\tcursor += runLength - 1;\n207:\t\t\t\t\tcontinue;\n208:\t\t\t\t}\n209:\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\n210:\t\t\t\tcursor = closing + runLength - 1;\n211:\t\t\t}\n212:\t\t\treturn masked.join(\"\");\n213:\t\t})\n214:\t\t.join(\"\");\n215:}\n216:\n217:// [impl->REQ-PARITY-PEER-SHORTFORM]\n218:export function parsePeerShortforms(text) {\n219:\tconst source = String(text ?? \"\");\n220:\tconst prose = maskMarkdownCode(source);\n221:\tconst shortforms = [];\n222:\tconst pattern = /@<([\\s\\S]*?)@>/g;\n223:\tfor (const match of prose.matchAll(pattern)) {\n224:\t\tconst inner = match[1];\n225:\t\tconst separator = inner.search(/\\s/);\n226:\t\tif (separator <= 0) continue;\n227:\t\tconst targetList = inner.slice(0, separator);\n228:\t\tconst body = inner.slice(separator).trim();\n229:\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\n230:\t\tshortforms.push({\n231:\t\t\ttargets: targetList.split(\",\"),\n232:\t\t\tbody,\n233:\t\t\tindex: match.index,\n234:\t\t\traw: match[0],\n235:\t\t});\n236:\t}\n237:\treturn shortforms;\n238:}\n239:\n240:function parseJson(raw, label) {\n241:\ttry {\n242:\t\treturn JSON.parse(raw);\n243:\t} catch (error) {\n244:\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\n245:\t}\n246:}\n247:\n248:function parseVersion(raw) {\n…\n251:}\n\n[Showing lines 159-248 of 1830. Use :249 to continue]"}],"details":{"truncation":{"content":"\t\t.replaceAll(\">\", \"&gt;\");\r\n\treturn `<msg from=\"${escaped}\"/>`;\r\n}\r\n\r\nfunction injectEnvelope(messages, item) {\r\n\tconst index = messages.findLastIndex(\r\n\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\r\n\t);\r\n\tif (index < 0) return messages;\r\n\tconst original = messages[index];\r\n\tconst content =\r\n\t\ttypeof original.content === \"string\"\r\n\t\t\t? `${original.content}\\n\\n${item.envelope}`\r\n\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\r\n\tconst injected = [...messages];\r\n\tinjected[index] = { ...original, content };\r\n\treturn injected;\r\n}\r\n\r\nfunction maskMarkdownCode(text) {\r\n\tconst lines = String(text).split(/(\\r?\\n)/);\r\n\tlet fenceCharacter;\r\n\tlet fenceLength = 0;\r\n\treturn lines\r\n\t\t.map((line) => {\r\n\t\t\tif (/^\\r?\\n$/.test(line)) return line;\r\n\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\r\n\t\t\tif (fence) {\r\n\t\t\t\tconst character = fence[1][0];\r\n\t\t\t\tif (!fenceCharacter) {\r\n\t\t\t\t\tfenceCharacter = character;\r\n\t\t\t\t\tfenceLength = fence[1].length;\r\n\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\r\n\t\t\t\t\tfenceCharacter = undefined;\r\n\t\t\t\t\tfenceLength = 0;\r\n\t\t\t\t}\r\n\t\t\t\treturn \" \".repeat(line.length);\r\n\t\t\t}\r\n\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\r\n\r\n\t\t\tconst masked = [...line];\r\n\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\r\n\t\t\t\tif (line[cursor] !== \"`\") continue;\r\n\t\t\t\tlet runLength = 1;\r\n\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\r\n\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\r\n\t\t\t\tif (closing < 0) {\r\n\t\t\t\t\tcursor += runLength - 1;\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\r\n\t\t\t\tcursor = closing + runLength - 1;\r\n\t\t\t}\r\n\t\t\treturn masked.join(\"\");\r\n\t\t})\r\n\t\t.join(\"\");\r\n}\r\n\r\n// [impl->REQ-PARITY-PEER-SHORTFORM]\r\nexport function parsePeerShortforms(text) {\r\n\tconst source = String(text ?? \"\");\r\n\tconst prose = maskMarkdownCode(source);\r\n\tconst shortforms = [];\r\n\tconst pattern = /@<([\\s\\S]*?)@>/g;\r\n\tfor (const match of prose.matchAll(pattern)) {\r\n\t\tconst inner = match[1];\r\n\t\tconst separator = inner.search(/\\s/);\r\n\t\tif (separator <= 0) continue;\r\n\t\tconst targetList = inner.slice(0, separator);\r\n\t\tconst body = inner.slice(separator).trim();\r\n\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\r\n\t\tshortforms.push({\r\n\t\t\ttargets: targetList.split(\",\"),\r\n\t\t\tbody,\r\n\t\t\tindex: match.index,\r\n\t\t\traw: match[0],\r\n\t\t});\r\n\t}\r\n\treturn shortforms;\r\n}\r\n\r\nfunction parseJson(raw, label) {\r\n\ttry {\r\n\t\treturn JSON.parse(raw);\r\n\t} catch (error) {\r\n\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\r\n\t}\r\n}\r\n\r\nfunction parseVersion(raw) {\r","truncated":true,"truncatedBy":"lines","totalLines":1672,"totalBytes":2732,"outputLines":90,"outputBytes":2732,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"function senderStub(sender) {\n\tconst escaped = sender\n…\n\t\t.replaceAll(\">\", \"&gt;\");\r\n\treturn `<msg from=\"${escaped}\"/>`;\r\n}\r\n\r\nfunction injectEnvelope(messages, item) {\r\n\tconst index = messages.findLastIndex(\r\n\t\t(message) => message?.role === \"user\" && messageText(message) === item.stub,\r\n\t);\r\n\tif (index < 0) return messages;\r\n\tconst original = messages[index];\r\n\tconst content =\r\n\t\ttypeof original.content === \"string\"\r\n\t\t\t? `${original.content}\\n\\n${item.envelope}`\r\n\t\t\t: [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];\r\n\tconst injected = [...messages];\r\n\tinjected[index] = { ...original, content };\r\n\treturn injected;\r\n}\r\n\r\nfunction maskMarkdownCode(text) {\r\n\tconst lines = String(text).split(/(\\r?\\n)/);\r\n\tlet fenceCharacter;\r\n\tlet fenceLength = 0;\r\n\treturn lines\r\n\t\t.map((line) => {\r\n\t\t\tif (/^\\r?\\n$/.test(line)) return line;\r\n\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\r\n\t\t\tif (fence) {\r\n\t\t\t\tconst character = fence[1][0];\r\n\t\t\t\tif (!fenceCharacter) {\r\n\t\t\t\t\tfenceCharacter = character;\r\n\t\t\t\t\tfenceLength = fence[1].length;\r\n\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\r\n\t\t\t\t\tfenceCharacter = undefined;\r\n\t\t\t\t\tfenceLength = 0;\r\n\t\t\t\t}\r\n\t\t\t\treturn \" \".repeat(line.length);\r\n\t\t\t}\r\n\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\r\n\r\n\t\t\tconst masked = [...line];\r\n\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\r\n\t\t\t\tif (line[cursor] !== \"`\") continue;\r\n\t\t\t\tlet runLength = 1;\r\n\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\r\n\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\r\n\t\t\t\tif (closing < 0) {\r\n\t\t\t\t\tcursor += runLength - 1;\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\r\n\t\t\t\tcursor = closing + runLength - 1;\r\n\t\t\t}\r\n\t\t\treturn masked.join(\"\");\r\n\t\t})\r\n\t\t.join(\"\");\r\n}\r\n\r\n// [impl->REQ-PARITY-PEER-SHORTFORM]\r\nexport function parsePeerShortforms(text) {\r\n\tconst source = String(text ?? \"\");\r\n\tconst prose = maskMarkdownCode(source);\r\n\tconst shortforms = [];\r\n\tconst pattern = /@<([\\s\\S]*?)@>/g;\r\n\tfor (const match of prose.matchAll(pattern)) {\r\n\t\tconst inner = match[1];\r\n\t\tconst separator = inner.search(/\\s/);\r\n\t\tif (separator <= 0) continue;\r\n\t\tconst targetList = inner.slice(0, separator);\r\n\t\tconst body = inner.slice(separator).trim();\r\n\t\tif (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;\r\n\t\tshortforms.push({\r\n\t\t\ttargets: targetList.split(\",\"),\r\n\t\t\tbody,\r\n\t\t\tindex: match.index,\r\n\t\t\traw: match[0],\r\n\t\t});\r\n\t}\r\n\treturn shortforms;\r\n}\r\n\r\nfunction parseJson(raw, label) {\r\n\ttry {\r\n\t\treturn JSON.parse(raw);\r\n\t} catch (error) {\r\n\t\tthrow new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);\r\n\t}\r\n}\r\n\r\nfunction parseVersion(raw) {\r\n…\n}","startLine":154,"lineNumbers":[154,155,null,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,null,251]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1830,"totalBytes":2732,"outputLines":90,"outputBytes":2732,"shownRange":{"start":159,"end":248},"nextOffset":249}}},"isError":false,"timestamp":1784192410925}}
{"type":"message","id":"7270a654","parentId":"1e3dfcc0","timestamp":"2026-07-16T09:00:25.275Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Replacing code block**"},{"type":"toolCall","id":"call_XNcwF5ndSGq0v8frdHFKX7Ax|ctc_03b6862392617389016a589da0921c8199af1f4372e361fc25","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#F43A]\nSWAP.BLK 178:\n+function maskMarkdownCode(text) {\n+\tconst source = String(text);\n+\tconst masked = source.split(\"\");\n+\tlet fenceCharacter;\n+\tlet fenceLength = 0;\n+\tlet lineStart = 0;\n+\twhile (lineStart < source.length) {\n+\t\tconst newline = source.indexOf(\"\\n\", lineStart);\n+\t\tconst lineEnd = newline < 0 ? source.length : newline + 1;\n+\t\tconst line = source.slice(lineStart, newline < 0 ? lineEnd : newline).replace(/\\r$/, \"\");\n+\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+\t\tconst indentedCode = !fenceCharacter && /^(?: {4}|\\t)/.test(line);\n+\t\tlet maskLine = Boolean(fenceCharacter || fence || indentedCode);\n+\t\tif (fence) {\n+\t\t\tconst character = fence[1][0];\n+\t\t\tif (!fenceCharacter) {\n+\t\t\t\tfenceCharacter = character;\n+\t\t\t\tfenceLength = fence[1].length;\n+\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+\t\t\t\tfenceCharacter = undefined;\n+\t\t\t\tfenceLength = 0;\n+\t\t\t} else {\n+\t\t\t\tmaskLine = true;\n+\t\t\t}\n+\t\t}\n+\t\tif (maskLine) {\n+\t\t\tfor (let index = lineStart; index < lineEnd; index += 1) {\n+\t\t\t\tif (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";\n+\t\t\t}\n+\t\t}\n+\t\tlineStart = lineEnd;\n+\t}\n+\n+\tfor (let cursor = 0; cursor < source.length; cursor += 1) {\n+\t\tif (masked[cursor] !== \"`\") continue;\n+\t\tlet runLength = 1;\n+\t\twhile (masked[cursor + runLength] === \"`\") runLength += 1;\n+\t\tconst delimiter = \"`\".repeat(runLength);\n+\t\tlet closing = source.indexOf(delimiter, cursor + runLength);\n+\t\twhile (\n+\t\t\tclosing >= 0 &&\n+\t\t\t(source[closing - 1] === \"`\" || source[closing + runLength] === \"`\")\n+\t\t) {\n+\t\t\tclosing = source.indexOf(delimiter, closing + runLength);\n+\t\t}\n+\t\tif (closing < 0) {\n+\t\t\tcursor += runLength - 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tfor (let index = cursor; index < closing + runLength; index += 1) {\n+\t\t\tif (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";\n+\t\t}\n+\t\tcursor = closing + runLength - 1;\n+\t}\n+\treturn masked.join(\"\");\n+}\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":4119,"output":658,"cacheRead":206336,"cacheWrite":0,"totalTokens":211113,"reasoningTokens":7,"cost":{"input":0.020595000000000002,"output":0.01974,"cacheRead":0.103168,"cacheWrite":0,"total":0.143503}},"stopReason":"toolUse","timestamp":1784192410970,"responseId":"resp_03b6862392617389016a589d9b52dc8199a0af00ee3ca60e29","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03b6862392617389016a589d9d15448199b8e7eae4e6173bc8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ2g8xq4ALFQ7UKJ__MJ6aOa-eiJuBONpPtZZ5M5zAix7z3Dygiyp-wE5NvSkfolfwf_nVljpU604j-oj6W5ReZ8RrZaE9oeDT-t9Ao7lLwQHPrBjXCv0PTYoqAsd-xnff1_vfTf9HRUXP-isSXJEkC1PZG4Bo-0C-G3ff2lv-g9Prx3JweBsqZCbiB4rX1Bs1TG5DFKqYBNZrHCkjAjerqRZXUwIEocvR4j9b3gL4M9IOkcQ3soh3FYuqeLFGdoIxJ0w35-R-9cz-yDI0_KhbbL5mcmMWjC6q6fy8C_UaLSj76vqmwMMgIy17WWc9E3IHtfUK7aw_KlS36pkX5LYRryItA5TgmQvlHgvUT3K_uk-Ux_fljf3zRo_DFaEbNkW2JxwRu0kIdQQtX1knfNqDdJlD54V7gt4Hnw5KhLW72_PdKhwfGeHttuBDI916tQecLHvGP4QmlV42-nMKUS61tXLt8r4h8tUW1rnuFd2VxFxVf8LSGs9ydua8xn6fRWFkSqLO2mMbkrJT8TZERdirkZY6ExIDOnlro2q3CAA9f-h3yxj7qt8rgj2BTF8hOlhSB9CCk6PHUUpFkyCDKvkVGjWF1obN0lfk1bBmMYkS_kFjBh3HBPC0ewsfsr4V0CCh1-5rwv0aA8HE8xj0URw14N5kuEwF90383C-6Eq59URFS5rr3Pvcoh7piQYM8osYOj6p0TYTJTp0kK8vAanYWFDHE2hx9-001X_X8vbpe3GsgiSd3uyZwvL4m9GLBCd6IXlSgzUVOybxQYMBzvSX1w2WD3--9RWFPNZllbM7kK-pV6GC_PWzA2kjizQh2nOdT-peG-1dKh0cgHhjXZaChMLtWrPw6XwaTfF0QNIwcFYPXXaHx0Es7SD-9S2e52puCKtUUBOLz4qMtYLcz2TSPuqwKmvtBfUZk-aIGlRK1YYcFLld_wXNSl473yydz2eHKsj","summary":[{"type":"summary_text","text":"**Replacing code block**"}]},{"id":"ctc_03b6862392617389016a589da0921c8199af1f4372e361fc25","type":"custom_tool_call","status":"completed","call_id":"call_XNcwF5ndSGq0v8frdHFKX7Ax","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#F43A]\nSWAP.BLK 178:\n+function maskMarkdownCode(text) {\n+\tconst source = String(text);\n+\tconst masked = source.split(\"\");\n+\tlet fenceCharacter;\n+\tlet fenceLength = 0;\n+\tlet lineStart = 0;\n+\twhile (lineStart < source.length) {\n+\t\tconst newline = source.indexOf(\"\\n\", lineStart);\n+\t\tconst lineEnd = newline < 0 ? source.length : newline + 1;\n+\t\tconst line = source.slice(lineStart, newline < 0 ? lineEnd : newline).replace(/\\r$/, \"\");\n+\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+\t\tconst indentedCode = !fenceCharacter && /^(?: {4}|\\t)/.test(line);\n+\t\tlet maskLine = Boolean(fenceCharacter || fence || indentedCode);\n+\t\tif (fence) {\n+\t\t\tconst character = fence[1][0];\n+\t\t\tif (!fenceCharacter) {\n+\t\t\t\tfenceCharacter = character;\n+\t\t\t\tfenceLength = fence[1].length;\n+\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+\t\t\t\tfenceCharacter = undefined;\n+\t\t\t\tfenceLength = 0;\n+\t\t\t} else {\n+\t\t\t\tmaskLine = true;\n+\t\t\t}\n+\t\t}\n+\t\tif (maskLine) {\n+\t\t\tfor (let index = lineStart; index < lineEnd; index += 1) {\n+\t\t\t\tif (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";\n+\t\t\t}\n+\t\t}\n+\t\tlineStart = lineEnd;\n+\t}\n+\n+\tfor (let cursor = 0; cursor < source.length; cursor += 1) {\n+\t\tif (masked[cursor] !== \"`\") continue;\n+\t\tlet runLength = 1;\n+\t\twhile (masked[cursor + runLength] === \"`\") runLength += 1;\n+\t\tconst delimiter = \"`\".repeat(runLength);\n+\t\tlet closing = source.indexOf(delimiter, cursor + runLength);\n+\t\twhile (\n+\t\t\tclosing >= 0 &&\n+\t\t\t(source[closing - 1] === \"`\" || source[closing + runLength] === \"`\")\n+\t\t) {\n+\t\t\tclosing = source.indexOf(delimiter, closing + runLength);\n+\t\t}\n+\t\tif (closing < 0) {\n+\t\t\tcursor += runLength - 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tfor (let index = cursor; index < closing + runLength; index += 1) {\n+\t\t\tif (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";\n+\t\t}\n+\t\tcursor = closing + runLength - 1;\n+\t}\n+\treturn masked.join(\"\");\n+}\n*** End Patch\n","name":"edit"}]},"duration":14304.11540000001,"ttft":2092.066399999894,"contextSnapshot":{"promptTokens":210455,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_XNcwF5ndSGq0v8frdHFKX7Ax|ctc_03b6862392617389016a589da0921c8199af1f4372e361fc25","toolName":"edit","startedAt":"2026-07-16T09:00:25.277Z"},"id":"ef8e6e03","parentId":"7270a654","timestamp":"2026-07-16T09:00:25.277Z"}
{"type":"message","id":"3fb376ff","parentId":"ef8e6e03","timestamp":"2026-07-16T09:00:25.371Z","message":{"role":"toolResult","toolCallId":"call_XNcwF5ndSGq0v8frdHFKX7Ax|ctc_03b6862392617389016a589da0921c8199af1f4372e361fc25","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#9F38]\nSWAP.BLK 178 → resolved lines 178-215 (38 lines)\n177:\n178:function maskMarkdownCode(text) {\n179:\tconst source = String(text);\n180:\tconst masked = source.split(\"\");\n181:\tlet fenceCharacter;\n182:\tlet fenceLength = 0;\n183:\tlet lineStart = 0;\n184:\twhile (lineStart < source.length) {\n…\n199:\t\t\t} else {\n200:\t\t\t\tmaskLine = true;\n201:\t\t\t}\n202:\t\t}\n203:\t\tif (maskLine) {\n204:\t\t\tfor (let index = lineStart; index < lineEnd; index += 1) {\n205:\t\t\t\tif (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";\n206:\t\t\t}\n207:\t\t}\n208:\t\tlineStart = lineEnd;\n…\n231:\t}\n232:\treturn masked.join(\"\");\n233:}\n234:"}],"details":{"diff":" 177|\n 178|function maskMarkdownCode(text) {\n-179|\tconst lines = String(text).split(/(\\r?\\n)/);\n+179|\tconst source = String(text);\n+180|\tconst masked = source.split(\"\");\n 180|\tlet fenceCharacter;\n 181|\tlet fenceLength = 0;\n-182|\treturn lines\n-183|\t\t.map((line) => {\n-184|\t\t\tif (/^\\r?\\n$/.test(line)) return line;\n-185|\t\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n-186|\t\t\tif (fence) {\n-187|\t\t\t\tconst character = fence[1][0];\n-188|\t\t\t\tif (!fenceCharacter) {\n-189|\t\t\t\t\tfenceCharacter = character;\n-190|\t\t\t\t\tfenceLength = fence[1].length;\n-191|\t\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n-192|\t\t\t\t\tfenceCharacter = undefined;\n-193|\t\t\t\t\tfenceLength = 0;\n-194|\t\t\t\t}\n-195|\t\t\t\treturn \" \".repeat(line.length);\n+183|\tlet lineStart = 0;\n+184|\twhile (lineStart < source.length) {\n+185|\t\tconst newline = source.indexOf(\"\\n\", lineStart);\n+186|\t\tconst lineEnd = newline < 0 ? source.length : newline + 1;\n+187|\t\tconst line = source.slice(lineStart, newline < 0 ? lineEnd : newline).replace(/\\r$/, \"\");\n+188|\t\tconst fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);\n+189|\t\tconst indentedCode = !fenceCharacter && /^(?: {4}|\\t)/.test(line);\n+190|\t\tlet maskLine = Boolean(fenceCharacter || fence || indentedCode);\n+191|\t\tif (fence) {\n+192|\t\t\tconst character = fence[1][0];\n+193|\t\t\tif (!fenceCharacter) {\n+194|\t\t\t\tfenceCharacter = character;\n+195|\t\t\t\tfenceLength = fence[1].length;\n+196|\t\t\t} else if (character === fenceCharacter && fence[1].length >= fenceLength) {\n+197|\t\t\t\tfenceCharacter = undefined;\n+198|\t\t\t\tfenceLength = 0;\n+199|\t\t\t} else {\n+200|\t\t\t\tmaskLine = true;\n 196|\t\t\t}\n-197|\t\t\tif (fenceCharacter) return \" \".repeat(line.length);\n-198|\n-199|\t\t\tconst masked = [...line];\n-200|\t\t\tfor (let cursor = 0; cursor < line.length; cursor += 1) {\n-201|\t\t\t\tif (line[cursor] !== \"`\") continue;\n-202|\t\t\t\tlet runLength = 1;\n-203|\t\t\t\twhile (line[cursor + runLength] === \"`\") runLength += 1;\n-204|\t\t\t\tconst closing = line.indexOf(\"`\".repeat(runLength), cursor + runLength);\n-205|\t\t\t\tif (closing < 0) {\n-206|\t\t\t\t\tcursor += runLength - 1;\n-207|\t\t\t\t\tcontinue;\n-208|\t\t\t\t}\n-209|\t\t\t\tfor (let index = cursor; index < closing + runLength; index += 1) masked[index] = \" \";\n-210|\t\t\t\tcursor = closing + runLength - 1;\n+202|\t\t}\n+203|\t\tif (maskLine) {\n+204|\t\t\tfor (let index = lineStart; index < lineEnd; index += 1) {\n+205|\t\t\t\tif (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";\n 211|\t\t\t}\n-212|\t\t\treturn masked.join(\"\");\n-213|\t\t})\n-214|\t\t.join(\"\");\n+207|\t\t}\n+208|\t\tlineStart = lineEnd;\n+209|\t}\n+210|\n+211|\tfor (let cursor = 0; cursor < source.length; cursor += 1) {\n+212|\t\tif (masked[cursor] !== \"`\") continue;\n+213|\t\tlet runLength = 1;\n+214|\t\twhile (masked[cursor + runLength] === \"`\") runLength += 1;\n+215|\t\tconst delimiter = \"`\".repeat(runLength);\n+216|\t\tlet closing = source.indexOf(delimiter, cursor + runLength);\n+217|\t\twhile (\n+218|\t\t\tclosing >= 0 &&\n+219|\t\t\t(source[closing - 1] === \"`\" || source[closing + runLength] === \"`\")\n+220|\t\t) {\n+221|\t\t\tclosing = source.indexOf(delimiter, closing + runLength);\n+222|\t\t}\n+223|\t\tif (closing < 0) {\n+224|\t\t\tcursor += runLength - 1;\n+225|\t\t\tcontinue;\n+226|\t\t}\n+227|\t\tfor (let index = cursor; index < closing + runLength; index += 1) {\n+228|\t\t\tif (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";\n+229|\t\t}\n+230|\t\tcursor = closing + runLength - 1;\n+231|\t}\n+232|\treturn masked.join(\"\");\n 215|}\n 216|","firstChangedLine":178,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192425371}}
{"type":"message","id":"dbfdcfd0","parentId":"3fb376ff","timestamp":"2026-07-16T09:00:30.325Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Refining fence detection and tag masking**"},{"type":"toolCall","id":"call_g9b9Drxa7lq9W351kxtfNerd|fc_043cba0642e3df48016a589dad8d78819b827a8582682ae8fa","name":"grep","arguments":{"i":"Locating path normalization","pattern":"function normalizePath","path":"adapter/strings/omp-spt.mjs","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1926,"output":137,"cacheRead":209408,"cacheWrite":0,"totalTokens":211471,"reasoningTokens":79,"cost":{"input":0.009630000000000001,"output":0.00411,"cacheRead":0.10470399999999999,"cacheWrite":0,"total":0.118444}},"stopReason":"toolUse","timestamp":1784192425486,"responseId":"resp_043cba0642e3df48016a589da9e8e4819ba5eef0fa12491290","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_043cba0642e3df48016a589dab9eb8819b9ab1263000ead474","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ2tLyq811dVDxAMbqJJSFzp3nc4tH0mcB3xO4i-NPPtJ7MLh6DTG62W4l0szk1mQusyDIfMG--Bp1YrKdwczy4gbBmIEzDLj0ujBHtz90C6_pQpbld8k_boghUq0RHevLS_nxATABEvYpkJfMwmiEssbH6W4fZp1uMqn9W0AJhYuDR9_bmkvZd5A7fy2cCBYuOqVt84ZD8ZKQ3OTWmk1sng8p9pfyDzT1uvjYc-W8IvSmwN3cVDinxmgg2XNFLTycVLQwX8AILVnMvWAnaGc5SwF4xSuKq9NXioTBx_kGygC_2vAVRzKZuJ_7VWZOmj8imB8f5yFZF0tiz0yCBoeyPRLyVDRMSr7NdthBfEcX1kJwkN4CObD8tgOEy7uxelc_4hN-ZDLrihGSr2PjonbFw8ngFS2OhnJrcyn47HsGiE2MABFNMEGe9pu1ZxHxd5l1gaJxlarWqBm-JCfojAvZzEhwMq-JmajqbisrctZC7pip5QqL9Uw8GlGUOE6zxqSKqdXKydKJaIxr4nVpxTs-nNnE76yNJ2ENjyB_x9Ch3ErJjNSSPdzjYe4MGG4wDD-2j2tAOlFPM72ollkAlm0L5nY937uHaYq1Pb66voN6l0pjv2wI54k4ucz9zvMQ4rgrADMu9gJZcKA1IE8-Yxm3QhWJymtnQowlbrebLv3M_8joyjQ4YCJxbQ0kM7jixCiKw4dPn0GDs7BjNPy2dBj7D2ZCtWDnosG_jstInNWfO_0J5FYK25jn3HUOdKGjv2lg1dZN3xAfT8r3C4Q9BfSjG4HyYQXHwI_I-OWVSEIj3YRv--QOfyUAkKEgeCgbA2ZlbR7VZuZgxCP4PylTZ0L9q91gykTY1LYfK_rZZ52kfp5i8r8MaGSJN4ik3972IvACvOxeKXJKW-PwJ5NcDBTduH7cl1Cbzb8dGr5j594bZ0IqSOCbjxtZxbbNDHJy0hwygZaSahl6DSJGgkRuPO2x99j1bltKH3y-4HtbxRlyx_6hd4h2FDnJOO7E8SGV1ZYX5RNVqcctBswIiFnKZIFZR8ZnXLcnQCpg2RnxAoDvOkbuYtrMUNTqTvycTx_HAay7sI3oPOJnnPMFLle3wDRIKNvRZc1RaZYFUDZjKr0HITow10q6FDSw5tKnCZT8jKAMRl9V9Wi3gq6EkXR20v6AEAMGFUdJpIK-APtgkzuVRBy_nvwr9DMp5iiwzON2oOzSCz1Ot1cY5JCyyHP863Ozjm4kKwfujUTA2VNLoOyzkvice4rZcKGtuBYnSVeJUvBZXJIY-NooJeg6KJjp5QFAs_ULOslVN66N4kl3ksun3IV19a6UPzkuf8oLpzjaJPPnQXF_iqElR2K5hJdtPe_BkASZqExm59V_8m_FRVhkg88fPPx7muoqapiExo-sp5nVit","summary":[{"type":"summary_text","text":"**Refining fence detection and tag masking**"}]},{"id":"fc_043cba0642e3df48016a589dad8d78819b827a8582682ae8fa","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating path normalization\",\"pattern\":\"function normalizePath\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_g9b9Drxa7lq9W351kxtfNerd","name":"grep"}]},"duration":4837.910600000061,"ttft":2117.657600000035,"contextSnapshot":{"promptTokens":211334,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_g9b9Drxa7lq9W351kxtfNerd|fc_043cba0642e3df48016a589dad8d78819b827a8582682ae8fa","toolName":"grep","startedAt":"2026-07-16T09:00:30.325Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Locating path normalization"},"id":"eb6c66a9","parentId":"dbfdcfd0","timestamp":"2026-07-16T09:00:30.325Z"}
{"type":"message","id":"5fc8c39d","parentId":"eb6c66a9","timestamp":"2026-07-16T09:00:30.351Z","message":{"role":"toolResult","toolCallId":"call_g9b9Drxa7lq9W351kxtfNerd|fc_043cba0642e3df48016a589dad8d78819b827a8582682ae8fa","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#9F38]\n 631:\n*632:\tfunction normalizePath(value) {\n 633:\t\treturn String(value ?? \"\")\n 634:\t\t\t.replaceAll(\"\\\\\", \"/\")\n 635:\t\t\t.replace(/\\/+$/, \"\")"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":1,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":1}],"truncated":false,"displayContent":" 631│\n*632│\tfunction normalizePath(value) {\n 633│\t\treturn String(value ?? \"\")\n 634│\t\t\t.replaceAll(\"\\\\\", \"/\")\n 635│\t\t\t.replace(/\\/+$/, \"\")"},"isError":false,"timestamp":1784192430350}}
{"type":"message","id":"b0741894","parentId":"5fc8c39d","timestamp":"2026-07-16T09:00:36.161Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_qUE1wRQy5XDIzOTNkwHtEcaY|fc_0b0ac7d6e7a0bb63016a589db37f688199950dcde3762cabd7","name":"read","arguments":{"i":"Reading path helper","path":"adapter/strings/omp-spt.mjs","selector":"628-645"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1108,"output":49,"cacheRead":210432,"cacheWrite":0,"totalTokens":211589,"reasoningTokens":10,"cost":{"input":0.005540000000000001,"output":0.00147,"cacheRead":0.10521599999999999,"cacheWrite":0,"total":0.11222599999999999}},"stopReason":"toolUse","timestamp":1784192430376,"responseId":"resp_0b0ac7d6e7a0bb63016a589daf079c8199bda6db52ccba660d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0b0ac7d6e7a0bb63016a589db2ffa08199a4ca1f6759d71b91","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ2zySD4uegwamA_TRGPlliZFmVB1T2gLHdm1NBwx5_RgyhvqmXRv58-Yl6I2to0XcgvAB6McPDt4lL3cdqsamuDNfxk1KTN-o5onnAjnaijW2s1YLkNBn6RC_qMMtUH4Juy3UENEhR7jIvsrxePXb5Es4vponXCLLP-jwjdnzCgv0s4LFG1ukGIEjw1RNypWMG3HgqS97PDQG3H21oJ2YwaAEiR-c_53MkY8CgdnZXCjwRv8-Tak9UqXzX74Mj5fCo7jNwyIOAEm1vJ-4bkxvZxc4blegKdlentkYnk3ByUW1tyB2Wv8GtHI9H4VGD2fFugA5Zdwjm_47EEccRni9rh8bGoFLhRZGjVPKLuL34MN0AhrD-D1d-wsnkrKg7qusN72_fljVla0ZlOy02YOfSW6tKHYnonrj_iu0u0TeA9VLy_fnW83zcC5l1ktmJvAHmZP7k2llxNEj4yWj4hyEULeIMx50mLBoMN0twJef0ujVkYBjN9WJL5e23mypV2YOZWgL0BLc8s255G_87oZ2Sws55l1T2PWEXL3bNvZoi5mAw37CZ5FzMwERYjMf0NE5XCmJvYrlyz7IjO4M2vWtTJrBirCd-zZMjB68Py26nQ0G_S4T_EUJEV72WJ0M-qieEYzi1tl4LnlWNF0BYZnjMTh-IJg4s7vuJ3JFQBkdeyzTjyFiZ385OVBtKZpjxrqP43vXv47Gj6-qvL0UkfeJvYpSu73Oxv9GJSU9fKmp240A3FdseYnq1RECX8lAgD8ge05b5s-3rFepiHaInYZyYleuh6-TynFMrL8mLfGcHlZVziJGnf-sK9OvcBwHSwmD0p7oyfRZ7VofWYErab0qvMItDW8UutwhpMa_omeBCdWYnt7a0ZI7Z2J_nyEjkju5GXnleRrca5eUjhms6tbqcIdn13ouCmwTu9gML9eJP7sEZ5oI2K9aggLLttcXvpYtMi","summary":[]},{"id":"fc_0b0ac7d6e7a0bb63016a589db37f688199950dcde3762cabd7","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading path helper\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"628-645\"}","call_id":"call_qUE1wRQy5XDIzOTNkwHtEcaY","name":"read"}]},"duration":5750.601499999873,"ttft":4678.247500000056,"contextSnapshot":{"promptTokens":211540,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_qUE1wRQy5XDIzOTNkwHtEcaY|fc_0b0ac7d6e7a0bb63016a589db37f688199950dcde3762cabd7","toolName":"read","startedAt":"2026-07-16T09:00:36.161Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading path helper"},"id":"ddbf93aa","parentId":"b0741894","timestamp":"2026-07-16T09:00:36.161Z"}
{"type":"message","id":"a836f8e6","parentId":"ddbf93aa","timestamp":"2026-07-16T09:00:36.253Z","message":{"role":"toolResult","toolCallId":"call_qUE1wRQy5XDIzOTNkwHtEcaY|fc_0b0ac7d6e7a0bb63016a589db37f688199950dcde3762cabd7","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#9F38]\n624:\tconst commandCompletions = (cachedIds, includeAuto) => (prefix) => {\n…\n626:\t\tconst matches = values\n627:\t\t\t.filter((value) => value.startsWith(prefix.trim()))\n628:\t\t\t.map((value) => ({ value, label: value }));\n629:\t\treturn matches.length > 0 ? matches : null;\n630:\t};\n631:\n632:\tfunction normalizePath(value) {\n633:\t\treturn String(value ?? \"\")\n634:\t\t\t.replaceAll(\"\\\\\", \"/\")\n635:\t\t\t.replace(/\\/+$/, \"\")\n636:\t\t\t.toLowerCase();\n637:\t}\n638:\n639:\tfunction latestDigestTimestamp(digest) {\n640:\t\tlet latest = Number.NEGATIVE_INFINITY;\n641:\t\tfor (const turn of digest?.turns ?? []) {\n642:\t\t\tfor (const entry of turn?.entries ?? []) {\n643:\t\t\t\tfor (const value of Object.values(entry ?? {})) {\n644:\t\t\t\t\tconst parsed = Date.parse(value?.ts ?? \"\");\n645:\t\t\t\t\tif (Number.isFinite(parsed)) latest = Math.max(latest, parsed);\n646:\t\t\t\t}\n647:\t\t\t}\n648:\t\t}\n…\n650:\t}\n\n[Showing lines 627-648 of 1848. Use :649 to continue]"}],"details":{"truncation":{"content":"\t\t\t.filter((value) => value.startsWith(prefix.trim()))\r\n\t\t\t.map((value) => ({ value, label: value }));\r\n\t\treturn matches.length > 0 ? matches : null;\r\n\t};\r\n\r\n\tfunction normalizePath(value) {\r\n\t\treturn String(value ?? \"\")\r\n\t\t\t.replaceAll(\"\\\\\", \"/\")\r\n\t\t\t.replace(/\\/+$/, \"\")\r\n\t\t\t.toLowerCase();\r\n\t}\r\n\r\n\tfunction latestDigestTimestamp(digest) {\r\n\t\tlet latest = Number.NEGATIVE_INFINITY;\r\n\t\tfor (const turn of digest?.turns ?? []) {\r\n\t\t\tfor (const entry of turn?.entries ?? []) {\r\n\t\t\t\tfor (const value of Object.values(entry ?? {})) {\r\n\t\t\t\t\tconst parsed = Date.parse(value?.ts ?? \"\");\r\n\t\t\t\t\tif (Number.isFinite(parsed)) latest = Math.max(latest, parsed);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r","truncated":true,"truncatedBy":"lines","totalLines":1222,"totalBytes":669,"outputLines":22,"outputBytes":669,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\tconst commandCompletions = (cachedIds, includeAuto) => (prefix) => {\n…\n\t\tconst matches = values\n\t\t\t.filter((value) => value.startsWith(prefix.trim()))\r\n\t\t\t.map((value) => ({ value, label: value }));\r\n\t\treturn matches.length > 0 ? matches : null;\r\n\t};\r\n\r\n\tfunction normalizePath(value) {\r\n\t\treturn String(value ?? \"\")\r\n\t\t\t.replaceAll(\"\\\\\", \"/\")\r\n\t\t\t.replace(/\\/+$/, \"\")\r\n\t\t\t.toLowerCase();\r\n\t}\r\n\r\n\tfunction latestDigestTimestamp(digest) {\r\n\t\tlet latest = Number.NEGATIVE_INFINITY;\r\n\t\tfor (const turn of digest?.turns ?? []) {\r\n\t\t\tfor (const entry of turn?.entries ?? []) {\r\n\t\t\t\tfor (const value of Object.values(entry ?? {})) {\r\n\t\t\t\t\tconst parsed = Date.parse(value?.ts ?? \"\");\r\n\t\t\t\t\tif (Number.isFinite(parsed)) latest = Math.max(latest, parsed);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n…\n\t}","startLine":624,"lineNumbers":[624,null,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,null,650]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1848,"totalBytes":669,"outputLines":22,"outputBytes":669,"shownRange":{"start":627,"end":648},"nextOffset":649}}},"isError":false,"timestamp":1784192436252}}
{"type":"message","id":"46a312df","parentId":"a836f8e6","timestamp":"2026-07-16T09:00:44.253Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Refining path normalization logic**"},{"type":"toolCall","id":"call_kCiGOW26oiW06FvxYabD6W5U|ctc_0db2c790d331edea016a589db9e4708199903a40933299e402","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#9F38]\nSWAP.BLK 632:\n+\tfunction normalizePath(value) {\n+\t\tlet normalized = String(value ?? \"\").replaceAll(\"\\\\\", \"/\");\n+\t\twhile (\n+\t\t\tnormalized.endsWith(\"/\") &&\n+\t\t\tnormalized.length > 1 &&\n+\t\t\t!/^[A-Za-z]:\\/$/.test(normalized)\n+\t\t) {\n+\t\t\tnormalized = normalized.slice(0, -1);\n+\t\t}\n+\t\treturn process.platform === \"win32\" ? normalized.toLowerCase() : normalized;\n+\t}\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":421,"output":199,"cacheRead":211456,"cacheWrite":0,"totalTokens":212076,"reasoningTokens":54,"cost":{"input":0.002105,"output":0.0059700000000000005,"cacheRead":0.10572799999999999,"cacheWrite":0,"total":0.11380299999999999}},"stopReason":"toolUse","timestamp":1784192436318,"responseId":"resp_0db2c790d331edea016a589db4b88c8199b900cbfdce7a8580","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0db2c790d331edea016a589db851a48199bd682643e0f77c1e","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ25MzvrVjdflwcaMpk6liNWAw_F6_0ieIjBBdRLqHaBaeILyYJCtSUzyUsbWMi3qqoDJkqRlyamT3WkcdAan-xCkfoLomKJvD40QCjT8qUlmanxCOw_4xCz0s9jRpRnnWIyxJM0xmT47An6PUGkWr802FluZ7f5CNePA_8rkCVTw9I0qx524zjN9h7XVt_xLBJh2io19IkQj7mHBgbYfpMWKTOPqQ-W9bgkEU22rtfbrw06cRjlPpSAtJ7ufUSG58Nq86l337Yox8yDnaCRN04AuWA40CTzPZMMALrGdnORwSw3-fRrvaA2zBgUgk41kzgLEDRDOJBaFYkKNLTNOyBFy3ZYjr3zPZDuGSObzWKZ14Ka72nd2suPvoQ1H5Ya7NUhv8Eft1w7g57U6ylLb15goFMzumLPWYw7c7NbTAN_ORpHvq6NbofTHTqt-DOyMaURZwqKU8n1JHuj8lcDTT6a7RpvHL6Q3WTo51mkJEhLNrrwsJpICp2qN6SUt3Hu_sjGi-Mf1qPMVYnTk8ijhbn0avjf0MTzjbH0fo3TwUyos2oFIQJPp_pe5g2-UI624tGBxJcyynli5Anv_0gUt9ygIzHTzpmKNn39u2owcNGzxXmCrbIa3elcDH07pz2kydH_Rki8QAqenVX97TC63WjgEuKWwxw7vqmuyVJJSDqT8DRYaJSKJU4V4VGUVUjaN8vwtdgRkbkHXqh29k2KW6yLUb4FYg-oaMPzlK8llpfARJ2actqLOJw-Xhno3ipxlCWyyzlDHAalqjvRIySVxoAmVZuw0o_9Z70PEnnRJwfZFcHKbzW2UvVEluUxzBKSwRYiRUiTxueRzq4hlvWp7DaiMby2e_0pUXIUYmBwI3RR2Mv0YroKq9bex5GK5odSThGbBJ84K1lR6hduGMgQa7IdRfSl697qaukOupbYp6_kzq0vuk4L5VNYLCn2kxTp0uKxCowEAPAeWq5s1vT8ctzzajNA1m_6d2aTqjfWNnjwZCGwHGCAUYM8US9N3lSpWO3L9OsGndtrZHXBeko_26KI1GRzVwFpAPEaeoseHYHoBNHypmb7Zgp1N6rS1li-HAbY2BiraLvVA2izUfUOfaK2f4HXlltQhWd2YxKJhlxBO0pUFRjmM_jXXZgvZo32YYj15a5UxvRHQggAOu9YXI7O93PJqus1CUyll5OtIVtsCaKrCqM873VDuvIOINuflf8v","summary":[{"type":"summary_text","text":"**Refining path normalization logic**"}]},{"id":"ctc_0db2c790d331edea016a589db9e4708199903a40933299e402","type":"custom_tool_call","status":"completed","call_id":"call_kCiGOW26oiW06FvxYabD6W5U","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#9F38]\nSWAP.BLK 632:\n+\tfunction normalizePath(value) {\n+\t\tlet normalized = String(value ?? \"\").replaceAll(\"\\\\\", \"/\");\n+\t\twhile (\n+\t\t\tnormalized.endsWith(\"/\") &&\n+\t\t\tnormalized.length > 1 &&\n+\t\t\t!/^[A-Za-z]:\\/$/.test(normalized)\n+\t\t) {\n+\t\t\tnormalized = normalized.slice(0, -1);\n+\t\t}\n+\t\treturn process.platform === \"win32\" ? normalized.toLowerCase() : normalized;\n+\t}\n*** End Patch\n","name":"edit"}]},"duration":7935.041200000327,"ttft":3989.129399999976,"contextSnapshot":{"promptTokens":211877,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_kCiGOW26oiW06FvxYabD6W5U|ctc_0db2c790d331edea016a589db9e4708199903a40933299e402","toolName":"edit","startedAt":"2026-07-16T09:00:44.254Z"},"id":"21535c8c","parentId":"46a312df","timestamp":"2026-07-16T09:00:44.254Z"}
{"type":"message","id":"aa30fd6d","parentId":"21535c8c","timestamp":"2026-07-16T09:00:44.308Z","message":{"role":"toolResult","toolCallId":"call_kCiGOW26oiW06FvxYabD6W5U|ctc_0db2c790d331edea016a589db9e4708199903a40933299e402","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#5F60]\nSWAP.BLK 632 → resolved lines 632-637 (6 lines)\n631:\n632:\tfunction normalizePath(value) {\n633:\t\tlet normalized = String(value ?? \"\").replaceAll(\"\\\\\", \"/\");\n634:\t\twhile (\n…\n640:\t\t}\n641:\t\treturn process.platform === \"win32\" ? normalized.toLowerCase() : normalized;\n642:\t}\n643:"}],"details":{"diff":" 631|\n 632|\tfunction normalizePath(value) {\n-633|\t\treturn String(value ?? \"\")\n-634|\t\t\t.replaceAll(\"\\\\\", \"/\")\n-635|\t\t\t.replace(/\\/+$/, \"\")\n-636|\t\t\t.toLowerCase();\n+633|\t\tlet normalized = String(value ?? \"\").replaceAll(\"\\\\\", \"/\");\n+634|\t\twhile (\n+635|\t\t\tnormalized.endsWith(\"/\") &&\n+636|\t\t\tnormalized.length > 1 &&\n+637|\t\t\t!/^[A-Za-z]:\\/$/.test(normalized)\n+638|\t\t) {\n+639|\t\t\tnormalized = normalized.slice(0, -1);\n+640|\t\t}\n+641|\t\treturn process.platform === \"win32\" ? normalized.toLowerCase() : normalized;\n 637|\t}\n 638|","firstChangedLine":632,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192444307}}
{"type":"message","id":"e9fdae2a","parentId":"aa30fd6d","timestamp":"2026-07-16T09:00:50.869Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding platform override for Linux testing**"},{"type":"toolCall","id":"call_Fm2gt04FeZ7TnxLjkY5KeeHQ|fc_0d1376f44e634588016a589dc241f4819aa5052f078b2858a7","name":"read","arguments":{"i":"Reading constructor platform location","path":"adapter/strings/omp-spt.mjs","selector":"535-555"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":725,"output":103,"cacheRead":211456,"cacheWrite":0,"totalTokens":212284,"reasoningTokens":63,"cost":{"input":0.003625,"output":0.00309,"cacheRead":0.10572799999999999,"cacheWrite":0,"total":0.11244299999999999}},"stopReason":"toolUse","timestamp":1784192444377,"responseId":"resp_0d1376f44e634588016a589dbceba8819a8f1ae4a3194e0aec","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0d1376f44e634588016a589dc09784819a867418ee23482968","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ3Cx1fJPF-k1kfLC_ZgWXwNOyjFF4j1g3T5q9cLvFQbYIFc86ZhFxWtm1MTJWjnrYnoWRggh4eSfTS-ES7z_L0GBEuZmGE_s0PBeMDptVQHt5mrhNDssuRsqRwFGWZBxVwa0fD7563ZaXjhWENcY7N5gwEGqcD39oUr-58qMDmaSZZ-OoDF7MbjneZeJYVnDv-KES1tJOquBgAdgeQF9gnbJcthyNUzxunXM4F5a5hY37vPVKvjnsvJElKnqieVvtUi5rND-HnkRDbNhutEwXXH_Tmq-FK9EqixZFK2-BUo53UahdpXe44KS4HlUrj83g-Jx3U4fvnO0MxSkzQ4o-OQjpz3VyYEZCzYut5PNEnzjgmmswDtMmaceUOtMHU0_fkvN6AUTZ0XaOjt_lO1Tt9GC5xWT0I7QLSYMT4P_h7T_XLa7hmb8NAus8PyHVk1oR4t2zY9Ch4yse7WPoLJxVakxEKaMJBNENn9mnGlG2uTCPc3UsJEHRUzocU3g1WTWhvsqVmqTPLlo_L9X8i7t0V0wnTuzKjOJ3xSG-Y72Htudg2ycoLA6k2TXTulHguHAFH__aZbtaV0LN7Hw7b8dhAkgEcnv1-korbTsELvYgtRt96HXJwMU0227Buueo0MDpvDc3D0lc929416wF8hMrAsXGgf2PsIQWh5zkK0iv7izNg85JkxO7z5uJBjZgPP4oMlKNfheroADAhlc6ZUk0CYj57XfyHKhpbe4eybauQwhSiDpKJzF7qDRtkYbLx6eMtK8d0Wpc9yVZtapApctt9DgFUY8F8o-Z5Cn1FH70Irpd_my8apbe4bs-DNFvd6rt-X9pAO20M_QBytku567DSTAoX0imSn2Sd9_jMKXaV8ieWBWYmYcDc_9FVIibfb5vNZBHYmjP3hmUeJzOFi8wWIkS5aJcgs_kDgYZgI7DnBjqtngISswfm69AgR8DYGu2o3dpcMOYPg_7NWIseRlF25N2GTazmgIPz0WnlJS_hwl1UHwbhTqx_RkKk9oCzWg3_EdldyVRkSAUaTQonLEIJAiFyRQ5lTCFUiEv_nc29XNj0BUzc_Lq2n4-o4PJwNgZ8q8DWrD4W3FR2258y015z5C99V2C4-KbxjAfNO34Pwyf8yRfspkz2mZZRWjrP3xHlob0fEYUCa4HlkLLyR5xbP91BgFVjiI1R_ClHtvHrhpnPmZbpDoPwa2d-dpZmpiOX_5zx8PzpkL-ZaxHyLooUnkWyqQ4w3mE2sGrW0ElRQWlNHFBUuAbQYEMzL7KOs3idUuucSQyAvn9dTD-8L9w3ZjTmph20sJPwtPtift0p4UYnUH574fN-lscDGNdZCmesr","summary":[{"type":"summary_text","text":"**Adding platform override for Linux testing**"}]},{"id":"fc_0d1376f44e634588016a589dc241f4819aa5052f078b2858a7","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading constructor platform location\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"535-555\"}","call_id":"call_Fm2gt04FeZ7TnxLjkY5KeeHQ","name":"read"}]},"duration":6491.2675000000745,"ttft":4208.980800000019,"contextSnapshot":{"promptTokens":212181,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Fm2gt04FeZ7TnxLjkY5KeeHQ|fc_0d1376f44e634588016a589dc241f4819aa5052f078b2858a7","toolName":"read","startedAt":"2026-07-16T09:00:50.884Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading constructor platform location"},"id":"834125ee","parentId":"e9fdae2a","timestamp":"2026-07-16T09:00:50.884Z"}
{"type":"message","id":"6170e281","parentId":"834125ee","timestamp":"2026-07-16T09:00:50.908Z","message":{"role":"toolResult","toolCallId":"call_Fm2gt04FeZ7TnxLjkY5KeeHQ|fc_0d1376f44e634588016a589dc241f4819aa5052f078b2858a7","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#5F60]\n409:export function runSpt(args, input, overrides = {}) {\n…\n425:\treturn new Promise((resolve, reject) => {\n…\n534:\t});\n535:}\n536:\n537:export function createOmpSpt(overrides = {}) {\n538:\tconst spawnProcess = overrides.spawnProcess ?? spawn;\n539:\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\n540:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n541:\tconst env = overrides.env ?? process.env;\n542:\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n543:\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n544:\tconst customRunSptCommand = overrides.runSptCommand;\n545:\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n546:\tconst runSptCommand =\n547:\t\tcustomRunSptCommand ??\n548:\t\t((args, input, options = {}) =>\n549:\t\t\trunSpt(args, input, {\n550:\t\t\t\tclearTimeout: clearTimer,\n551:\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\n552:\t\t\t\tenv,\n553:\t\t\t\tkillForceMs,\n554:\t\t\t\tkillGraceMs,\n555:\t\t\t\tsetTimeout: setTimer,\n556:\t\t\t\tsignal: options.signal,\n557:\t\t\t\tspawnProcess,\n558:\t\t\t}));\n…\n1850:}\n\n[Showing lines 534-558 of 1853. Use :559 to continue]"}],"details":{"truncation":{"content":"\t});\r\n}\r\n\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r","truncated":true,"truncatedBy":"lines","totalLines":1320,"totalBytes":910,"outputLines":25,"outputBytes":910,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"export function runSpt(args, input, overrides = {}) {\n…\n\treturn new Promise((resolve, reject) => {\n…\n\t});\r\n}\r\n\r\nexport function createOmpSpt(overrides = {}) {\r\n\tconst spawnProcess = overrides.spawnProcess ?? spawn;\r\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\r\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\r\n\tconst env = overrides.env ?? process.env;\r\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\r\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\r\n\tconst customRunSptCommand = overrides.runSptCommand;\r\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\r\n\tconst runSptCommand =\r\n\t\tcustomRunSptCommand ??\r\n\t\t((args, input, options = {}) =>\r\n\t\t\trunSpt(args, input, {\r\n\t\t\t\tclearTimeout: clearTimer,\r\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\r\n\t\t\t\tenv,\r\n\t\t\t\tkillForceMs,\r\n\t\t\t\tkillGraceMs,\r\n\t\t\t\tsetTimeout: setTimer,\r\n\t\t\t\tsignal: options.signal,\r\n\t\t\t\tspawnProcess,\r\n\t\t\t}));\r\n…\n}","startLine":409,"lineNumbers":[409,null,425,null,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,null,1850]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1853,"totalBytes":910,"outputLines":25,"outputBytes":910,"shownRange":{"start":534,"end":558},"nextOffset":559}}},"isError":false,"timestamp":1784192450908}}
{"type":"message","id":"7d420702","parentId":"6170e281","timestamp":"2026-07-16T09:01:02.083Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding platform swap functionality**"},{"type":"toolCall","id":"call_j63uj7aPGnL1BgexBQ7q7XEz|ctc_0194aba5493bea63016a589dcc9e308198b40f7168cd6d2651","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#5F60]\nINS.POST 541:\n+\tconst platform = overrides.platform ?? process.platform;\nSWAP 641.=641:\n+\t\treturn platform === \"win32\" ? normalized.toLowerCase() : normalized;\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1162,"output":85,"cacheRead":211456,"cacheWrite":0,"totalTokens":212703,"reasoningTokens":10,"cost":{"input":0.00581,"output":0.00255,"cacheRead":0.10572799999999999,"cacheWrite":0,"total":0.114088}},"stopReason":"toolUse","timestamp":1784192450922,"responseId":"resp_0194aba5493bea63016a589dc35c4c8198af4371aa392abd24","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0194aba5493bea63016a589dcc06188198875fc79a9d2cd886","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ3MWiJLebqzR72m6FVlaR2u_Ad0ozBs7tsK5RtoYZnKdty6HnZUuaYgFNZQaDMPQDtwROa3HjdnAqxYGcL2DRYm1C_dShJ-23fcY-TMysq4ZrwcJUMBZIVMSzOTBi82iLJTplqWSxHqZO_egbIMe9S418gSzg4XECI8F3K4t6KizRWthhKaaZlp2SNTBK3n_jiF80biWEmWntzpxqKqlT_j-TQ4K1obiqFlceQZF7oxEJ06FT9k2sK0qn4RqWN7HyZGDwASPIKuQuo13nyLXi3yAsBM4K8M1pHQMDA6ASwn5ggcOtww5QUNALRa6qfsrzHsMtO5r15XeO5Kr3bABinCblmz5Ut6EOuR2y6tUKIEb43ECGK8vXEuE6yVahC9RGDoAiYAz2SY-MwemNSyQqdX4FI0uh5zAxzhPC34nsdKgjdde-p3148tpQt8PUM1Ylw0mpnSC49CfSSVhoD-5vSaNNn6tNPGjE837wSHJv2F-0008Pybdk4AgrmKx5rgDeEJzi97Ge004oIqjvDJ1Mwm1qcruTbgyuSU5eG716TZu0i5wqCHCDhNvV4xWnSuS2hjwM6I1o1gSqQExSRS4P4nlY14dDEaPKAb4H3GE0noVBmipm9V9Ck4SjoFgQiNq0tMRzegksqNp63Bh2HcnS4OmPZWnIIu-acRVYeYPgclWnC-ArT22OLjz8VDxy8dmMemx87fD1H7jRvFfWM22Ufln9yS_UFrXHlZN-jL6397MgbGbjDWVdCm5SQ6mYB84d_-MKhLYoaNg-i1KO_Ai1_QyYow2P0HSzlprpJWkbtbOcM_x_HVDX_ugyGFHSBfMiilWitUaumkxheRZFSJBUqPb-bXPTTstw_DO64LHDBug6j3qK9J6o4BeI5HKN_RYPke3BZ0_qDXBg2_lfZ2KKSApW6-CE4yb9a4zo8SKMdqcv9L3rk37tZt1vbetp-neENz","summary":[{"type":"summary_text","text":"**Adding platform swap functionality**"}]},{"id":"ctc_0194aba5493bea63016a589dcc9e308198b40f7168cd6d2651","type":"custom_tool_call","status":"completed","call_id":"call_j63uj7aPGnL1BgexBQ7q7XEz","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#5F60]\nINS.POST 541:\n+\tconst platform = overrides.platform ?? process.platform;\nSWAP 641.=641:\n+\t\treturn platform === \"win32\" ? normalized.toLowerCase() : normalized;\n*** End Patch\n","name":"edit"}]},"duration":11159.939300000202,"ttft":9125.364700000267,"contextSnapshot":{"promptTokens":212618,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_j63uj7aPGnL1BgexBQ7q7XEz|ctc_0194aba5493bea63016a589dcc9e308198b40f7168cd6d2651","toolName":"edit","startedAt":"2026-07-16T09:01:02.083Z"},"id":"97e34751","parentId":"7d420702","timestamp":"2026-07-16T09:01:02.083Z"}
{"type":"message","id":"68e7f9d1","parentId":"97e34751","timestamp":"2026-07-16T09:01:02.084Z","message":{"role":"toolResult","toolCallId":"call_j63uj7aPGnL1BgexBQ7q7XEz|ctc_0194aba5493bea63016a589dcc9e308198b40f7168cd6d2651","toolName":"edit","content":[{"type":"text","text":"This edit anchors to lines 641 of adapter/strings/omp-spt.mjs that [adapter/strings/omp-spt.mjs#5F60] never displayed (it showed a partial range, a search hit, or a folded summary). Actual file content at those lines:\n  641:\t\treturn process.platform === \"win32\" ? normalized.toLowerCase() : normalized;\nVerify the content matches what you intend to touch, then re-issue the edit with the same [path#tag] header — a straight retry now succeeds without a re-read. If the content does NOT match, fix your line numbers."}],"details":{},"isError":true,"timestamp":1784192462084}}
{"type":"message","id":"cc1b09f2","parentId":"68e7f9d1","timestamp":"2026-07-16T09:01:06.193Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_OL5k8wBJKZwNT3Mto7hDV50S|ctc_0dda0def12937f8f016a589dd0d678819899bbdd0dc744ee66","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#5F60]\nINS.POST 541:\n+\tconst platform = overrides.platform ?? process.platform;\nSWAP 641.=641:\n+\t\treturn platform === \"win32\" ? normalized.toLowerCase() : normalized;\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":361,"output":81,"cacheRead":212480,"cacheWrite":0,"totalTokens":212922,"reasoningTokens":6,"cost":{"input":0.0018050000000000002,"output":0.00243,"cacheRead":0.10624,"cacheWrite":0,"total":0.110475}},"stopReason":"toolUse","timestamp":1784192462094,"responseId":"resp_0dda0def12937f8f016a589dce7f48819893062b20c8bc7320","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0dda0def12937f8f016a589dd049b0819888601b9c5fee40fe","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ3Q3h8uXM5WQspohIq6gHZny7zsQJ41k1brT1MhHf8zUisi4t9mkTr1KxxpVqsQ5-3X-z0lpufhZnrZN7i5vv343U2RlSXDfcJ4_AH3MlUkJC3Ojo4I1xBv2erzP8kAt_yn6wtM4QSt9Oyjt8cCzo0TXVtaz9xTujgVSMIJT4CVyBrgYXCcJ5kTdTc4c6VWuFwLJ2TpEUGsWBKGQDF3RSjjzqb2SVwaG6bmWaxInSm_WQG9htakm1_iflzhfLKxgCQzf8zLOLPyt98gmLe3uBDhH5MvF9-rdKvi1jyJKnWk3xzVNn1bK4EwVrlHwBtXJl34CiyiogJjqxhvRxMSimpJ9z5lgqd2Uv-HSedpmUed1ZxrN_Ghke7J0l6PQ4LZQVyv3ZkZkdc74MoykksPu3NenCGtVNUNRO_Ery1d9bJe0um28p98IC7SGeid6RFh4oytEbcSp-0H_pX2jbHTN_1kUKdEZicrc_kDowWCJdt3eWJQ9eOf5YM5_4o9GpjUPqIrfpL85o_81QYAr5mM22qjIdJEw6LwR5X1pJnz2qDzuN7SqMFXUJVlnrW65Ho3rGtjX0FY_84nmsrh3-Eh4h0vcE6ZGKzQhgzSml0yZhFnkMRSAM5PvD9sJ2BymV-Vg6JtPeW2XiQI1d8LyD73sRuxNj8dpQCaMSbMaOzyapWokPxcQulDUD72drb5tdsaT7plrRV-45eOPchUbHulQYFB1gvMsuGeHw91jtu1ErAFlNaDLin_s9ZWZNEsRngkm8ihQTLKBweCCs4cAPs1OCjsrbL5Q1LLo28b5adSCjLl3CwwuFLW2aGZr-MXmq-ReLWybXwBWRdYzVwJWwV9c0A_2Y55VyzHq6nkK9X2pfiv3DoYa6S3NrYhOKhkXTwVQf-PfPUbAVMA1uPXyrx2w_QNJkxS2Wxp9ZgwyOZTLKTZ7XU=","summary":[]},{"id":"ctc_0dda0def12937f8f016a589dd0d678819899bbdd0dc744ee66","type":"custom_tool_call","status":"completed","call_id":"call_OL5k8wBJKZwNT3Mto7hDV50S","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#5F60]\nINS.POST 541:\n+\tconst platform = overrides.platform ?? process.platform;\nSWAP 641.=641:\n+\t\treturn platform === \"win32\" ? normalized.toLowerCase() : normalized;\n*** End Patch\n","name":"edit"}]},"duration":4099.18870000029,"ttft":2254.9936000001617,"contextSnapshot":{"promptTokens":212841,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_OL5k8wBJKZwNT3Mto7hDV50S|ctc_0dda0def12937f8f016a589dd0d678819899bbdd0dc744ee66","toolName":"edit","startedAt":"2026-07-16T09:01:06.195Z"},"id":"89e58b63","parentId":"cc1b09f2","timestamp":"2026-07-16T09:01:06.195Z"}
{"type":"message","id":"450233fe","parentId":"89e58b63","timestamp":"2026-07-16T09:01:06.232Z","message":{"role":"toolResult","toolCallId":"call_OL5k8wBJKZwNT3Mto7hDV50S|ctc_0dda0def12937f8f016a589dd0d678819899bbdd0dc744ee66","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#0778]\n540:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n541:\tconst env = overrides.env ?? process.env;\n542:\tconst platform = overrides.platform ?? process.platform;\n543:\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n544:\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n\n633:\tfunction normalizePath(value) {\n\n635:\t\twhile (\n\n639:\t\t) {\n640:\t\t\tnormalized = normalized.slice(0, -1);\n641:\t\t}\n642:\t\treturn platform === \"win32\" ? normalized.toLowerCase() : normalized;\n643:\t}\n644:"}],"details":{"diff":" 540|\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n 541|\tconst env = overrides.env ?? process.env;\n+542|\tconst platform = overrides.platform ?? process.platform;\n 542|\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n 543|\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n\n 632|\tfunction normalizePath(value) {\n\n 634|\t\twhile (\n\n 638|\t\t) {\n 639|\t\t\tnormalized = normalized.slice(0, -1);\n 640|\t\t}\n-641|\t\treturn process.platform === \"win32\" ? normalized.toLowerCase() : normalized;\n+642|\t\treturn platform === \"win32\" ? normalized.toLowerCase() : normalized;\n 642|\t}\n 643|","firstChangedLine":541,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192466232}}
{"type":"message","id":"8b212a4b","parentId":"450233fe","timestamp":"2026-07-16T09:01:11.038Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding assistant count functions**"},{"type":"toolCall","id":"call_vljtPPKONGw1L74225UJg8So|fc_0ef39ab23dd1a135016a589dd683d8819b8008232d953a53ac","name":"read","arguments":{"i":"Reading reply extraction helpers","path":"adapter/strings/omp-spt.mjs","selector":"110-150"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":603,"output":95,"cacheRead":212480,"cacheWrite":0,"totalTokens":213178,"reasoningTokens":55,"cost":{"input":0.0030150000000000003,"output":0.00285,"cacheRead":0.10624,"cacheWrite":0,"total":0.112105}},"stopReason":"toolUse","timestamp":1784192466291,"responseId":"resp_0ef39ab23dd1a135016a589dd2a9ac819bbad6bbcceecf0ea9","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0ef39ab23dd1a135016a589dd50fb4819b9fa22f22206f60a9","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ3WCFK0zCIjXu8G5XwUvY5JTg6ocnis9CsomvUmw8DpDZ0zUpSPYwIJ28P2LZQ_-FSoLfghrO09c-EEEQlWMNsIiYU_PSXP5X9qT6ZdruJe4AvtSn98ScQIDDJEQJXLr8nI6wz35SvYxut4bW95ZTQuTx-RzZLoEqMgNo1pSR-O3p_obtmOxUXGHjmq8l9L_XAHqdBC4t9qreDRr8WU4YEp06fk96JNPrOBi9YJ8QrUi87-CYuuyOmCJ3y_YhEIEB-_DYDaEdB7mj7Z6mHJk0x3xQF30Wuzmgu6eIKf_BlmXf3Q9T5erarwZU_0EMW0sj3AI80bN_TbwGHTfOXAtTltHmlNMY_D17dYajLCCTvOokMlrqGMF0eh4m9flUbt9OHLBbQcL4RZGbJYmw00Cpj_nkZYShW-XJu68nyPZWDU6BfzTR4D_T0j53abrdBEwg6tXHMh9tA-2prJGe7tQ_1Y6B6BFSquzBh9-0PF4QEG755NXk7j6WEnHhJgvmLmslQFH6txkscnm81ZX8oC010Lx-aaO65ixRc3b76Rs4hN-nkORpbDS-TwlkYBMRalbTfTM4T2JZZ4E5aUEeKhY-frOaspF4LtgCnb7G6-mtvS55K3KRAdyvrGfNajeGzp_jcTtyKdZblX2CH7wJjfSFZT_NC8PPhQjFM5ZM2sWUUAFvT1PIi5qlgUqcx039Z8j3ffkNo8uwpQqfH4LjI35w9BaCX31Q_KylQy-qXa4kO-TXhmdsR0LY5rp8_bUO9uph2Z9EueBvpkQX0Wh8YUEUiUdEJ61XSi3P00iN9LELuMq_UNVwbFtRMUd35KOEJ2JtOC_w6Kt1kspCmRcvkCVgJKaXD0k82Mw_MYTuVFjfdJeRRbg0PKHe0UUvFvWaq7RXWVAdXuuDycEzJDpfIWtVySm3J-659ojKddvdE4ZfI5wjtHj-LzWPY15cDr1Zwk14BmtzeBdnNBf8dsxnOvsvIM4WxYF5RBq48VMUNGePk_C2frmF_DoHDmmTjVg65ipHjeaQOkHnwHHfcn0pqwKQC7YWVHYFxzQlaWwDUNxMhFeoCiuvvCtqOUPylBu_zkqkltxEv_o8z983qUG5K6_iAltDyH1Bcjf2UCCSlJS4SiqJ-OMsRxzPLu-V10raVBpZPUlOClRnlTLe-nMXxkyYMH6IwyYEVeflJXSpsmPDDcHoi9uZgvvzBWlsk3mldbK0bkipa_Cq2_n36Jmds0iXdGduLZxBWe9TUBxqZjM1GLmt3ie6b7fEFeSl6nUtCqlTbs","summary":[{"type":"summary_text","text":"**Adding assistant count functions**"}]},{"id":"fc_0ef39ab23dd1a135016a589dd683d8819b8008232d953a53ac","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading reply extraction helpers\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"110-150\"}","call_id":"call_vljtPPKONGw1L74225UJg8So","name":"read"}]},"duration":4746.128500000108,"ttft":2749.3345000003465,"contextSnapshot":{"promptTokens":213083,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_vljtPPKONGw1L74225UJg8So|fc_0ef39ab23dd1a135016a589dd683d8819b8008232d953a53ac","toolName":"read","startedAt":"2026-07-16T09:01:11.038Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading reply extraction helpers"},"id":"2775fd2c","parentId":"8b212a4b","timestamp":"2026-07-16T09:01:11.038Z"}
{"type":"message","id":"fbd4e3b2","parentId":"2775fd2c","timestamp":"2026-07-16T09:01:11.055Z","message":{"role":"toolResult","toolCallId":"call_vljtPPKONGw1L74225UJg8So|fc_0ef39ab23dd1a135016a589dd683d8819b8008232d953a53ac","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#0778]\n46:export function drainEvents(raw, options = {}) {\n…\n51:\twhile (true) {\n…\n109:\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\n110:\t}\n111:}\n112:\n113:function messageText(message) {\n114:\tif (typeof message?.content === \"string\") return message.content;\n115:\treturn (message?.content ?? [])\n116:\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\n117:\t\t.map((part) => part.text)\n118:\t\t.join(\"\");\n119:}\n120:\n121:export function extractReply(messages, afterUserMessage) {\n122:\tconst allMessages = messages ?? [];\n123:\tlet start = 0;\n124:\tif (afterUserMessage !== undefined) {\n125:\t\tconst userIndex = allMessages.findLastIndex((message) => {\n126:\t\t\tif (message?.role !== \"user\") return false;\n127:\t\t\tconst text = messageText(message);\n128:\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\n129:\t\t});\n130:\t\tif (userIndex < 0) return \"\";\n131:\t\tstart = userIndex + 1;\n132:\t}\n133:\tconst assistant = allMessages\n134:\t\t.slice(start)\n135:\t\t.reverse()\n136:\t\t.find((message) => message?.role === \"assistant\");\n137:\treturn assistant ? messageText(assistant) : \"\";\n138:}\n139:\n140:function firstLine(text) {\n141:\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\n142:}\n143:\n144:function errorSummary(error) {\n145:\tconst detail = error instanceof Error ? error.message : String(error);\n146:\treturn firstLine(detail).trim() || \"unknown error\";\n147:}\n148:\n149:function failureMessage(reason, error) {\n150:\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\n151:\treturn `[omp-spt] ${reason}${detail}`;\n152:}\n153:\n\n[Showing lines 109-153 of 1854. Use :154 to continue]"}],"details":{"truncation":{"content":"\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\r\n\t}\r\n}\r\n\r\nfunction messageText(message) {\r\n\tif (typeof message?.content === \"string\") return message.content;\r\n\treturn (message?.content ?? [])\r\n\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\r\n\t\t.map((part) => part.text)\r\n\t\t.join(\"\");\r\n}\r\n\r\nexport function extractReply(messages, afterUserMessage) {\r\n\tconst allMessages = messages ?? [];\r\n\tlet start = 0;\r\n\tif (afterUserMessage !== undefined) {\r\n\t\tconst userIndex = allMessages.findLastIndex((message) => {\r\n\t\t\tif (message?.role !== \"user\") return false;\r\n\t\t\tconst text = messageText(message);\r\n\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\r\n\t\t});\r\n\t\tif (userIndex < 0) return \"\";\r\n\t\tstart = userIndex + 1;\r\n\t}\r\n\tconst assistant = allMessages\r\n\t\t.slice(start)\r\n\t\t.reverse()\r\n\t\t.find((message) => message?.role === \"assistant\");\r\n\treturn assistant ? messageText(assistant) : \"\";\r\n}\r\n\r\nfunction firstLine(text) {\r\n\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\r\n}\r\n\r\nfunction errorSummary(error) {\r\n\tconst detail = error instanceof Error ? error.message : String(error);\r\n\treturn firstLine(detail).trim() || \"unknown error\";\r\n}\r\n\r\nfunction failureMessage(reason, error) {\r\n\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\r\n\treturn `[omp-spt] ${reason}${detail}`;\r\n}\r\n\r","truncated":true,"truncatedBy":"lines","totalLines":1746,"totalBytes":1404,"outputLines":45,"outputBytes":1404,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"export function drainEvents(raw, options = {}) {\n…\n\twhile (true) {\n…\n\t\tif (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };\r\n\t}\r\n}\r\n\r\nfunction messageText(message) {\r\n\tif (typeof message?.content === \"string\") return message.content;\r\n\treturn (message?.content ?? [])\r\n\t\t.filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\r\n\t\t.map((part) => part.text)\r\n\t\t.join(\"\");\r\n}\r\n\r\nexport function extractReply(messages, afterUserMessage) {\r\n\tconst allMessages = messages ?? [];\r\n\tlet start = 0;\r\n\tif (afterUserMessage !== undefined) {\r\n\t\tconst userIndex = allMessages.findLastIndex((message) => {\r\n\t\t\tif (message?.role !== \"user\") return false;\r\n\t\t\tconst text = messageText(message);\r\n\t\t\treturn text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);\r\n\t\t});\r\n\t\tif (userIndex < 0) return \"\";\r\n\t\tstart = userIndex + 1;\r\n\t}\r\n\tconst assistant = allMessages\r\n\t\t.slice(start)\r\n\t\t.reverse()\r\n\t\t.find((message) => message?.role === \"assistant\");\r\n\treturn assistant ? messageText(assistant) : \"\";\r\n}\r\n\r\nfunction firstLine(text) {\r\n\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\r\n}\r\n\r\nfunction errorSummary(error) {\r\n\tconst detail = error instanceof Error ? error.message : String(error);\r\n\treturn firstLine(detail).trim() || \"unknown error\";\r\n}\r\n\r\nfunction failureMessage(reason, error) {\r\n\tconst detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;\r\n\treturn `[omp-spt] ${reason}${detail}`;\r\n}\r\n\r","startLine":46,"lineNumbers":[46,null,51,null,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1854,"totalBytes":1404,"outputLines":45,"outputBytes":1404,"shownRange":{"start":109,"end":153},"nextOffset":154}}},"isError":false,"timestamp":1784192471054}}
{"type":"message","id":"5cb6d1f8","parentId":"fbd4e3b2","timestamp":"2026-07-16T09:01:16.375Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_NLS5uOy3hwL1bAylGz0U08Su|ctc_096856baa6338c13016a589dd9d9148198a2e12bd78724d81b","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#0778]\nINS.POST 138:\n+function assistantMessageCount(messages) {\n+\treturn (messages ?? []).reduce(\n+\t\t(count, message) => count + (message?.role === \"assistant\" ? 1 : 0),\n+\t\t0,\n+\t);\n+}\n+\n+function extractReplyAfterAssistantCount(messages, baseline) {\n+\tconst assistants = (messages ?? []).filter((message) => message?.role === \"assistant\");\n+\tif (assistants.length <= baseline) return \"\";\n+\treturn messageText(assistants.at(-1));\n+}\n+\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1180,"output":154,"cacheRead":212480,"cacheWrite":0,"totalTokens":213814,"reasoningTokens":6,"cost":{"input":0.005900000000000001,"output":0.00462,"cacheRead":0.10624,"cacheWrite":0,"total":0.11676}},"stopReason":"toolUse","timestamp":1784192471064,"responseId":"resp_096856baa6338c13016a589dd765088198a7d049014e3e9359","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_096856baa6338c13016a589dd93fb081989d4f76573558834f","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ3Z89uuGQ4v4mI7PD-9op9MVV48bUXxEbqseKdMy6VnZHLi5XhX_cqDErdf53FyUk96p3B2sqxsHyStPNCByxXa20QUiqd2B7TbaUkKzeYgxzqCD4AoZQ3zQYD6lwb6IiSJc_97ELituY_a0kWLuqflLnJbg9waT9-5cLZd87NI-N-9houTsUajJnHGB2wro0BPRnAJQQqKX6v6Vp8wISCS8swzAgnJjFa8HfSLSdDT5i9dPu1mUFN2QKoU1FkxvmydIvQO3iqrjIivoAkxRvwwzcfsG4cOPD6fpM9DLz2F9RsJ31eYW8giESiptXrWvPnfD3UqyjWaL0qhTisvTZ_jMDAXlB37_XtpuMDpcn2CFzP6pgRlhRWaeQpWMzYVqNysDatwluIh4AWTa9iuBs1uUj3xxQMjtigedK1OvdddhjF2Qwjocw9pcncGbVk6bG7zt__JRfuyMcQHFZUy0h9z2COjENZLtSqTF_kq87TO-UIbxWT_xE3Q6m1ftChWEfNxvga8lbMP0njfZlUw3hzYPEl7qb00bi8z0GtWu2-TO6HQ9WNY0F9sCiufgybpXOeav1ZkzcqCD6h2uU34I8tJo54FdchOPMK0oTwQhx_hCN1dc1B49ZAFaYJuMXRV4rvC3ocwwn--1nhEdN4HPpK8xjLWh82lAG15OfjpmhIUOMhUI7PDEFRG3461pUbp4thKBYwvLPofryFpcrfuywF3tpdXoqdwwYB53VP8miltPwgzWCbf1FUwrbxwTLn9bc0areSGImX6Btzt6YXdjHhppRQ1yYda0e4WVVeHwzuxX_qVTTE7e4AT84yXh6KkrosjtJxYOXB5Msd63JsrXwXw5vMiQdRDchLZj9j8B_oYrhGVzKpFZ8INIvNpb0VgNCRgQ9WZcehWwkJJ52tvQx9mZZeBFLXrN6XJxJgitKmbEUA=","summary":[]},{"id":"ctc_096856baa6338c13016a589dd9d9148198a2e12bd78724d81b","type":"custom_tool_call","status":"completed","call_id":"call_NLS5uOy3hwL1bAylGz0U08Su","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#0778]\nINS.POST 138:\n+function assistantMessageCount(messages) {\n+\treturn (messages ?? []).reduce(\n+\t\t(count, message) => count + (message?.role === \"assistant\" ? 1 : 0),\n+\t\t0,\n+\t);\n+}\n+\n+function extractReplyAfterAssistantCount(messages, baseline) {\n+\tconst assistants = (messages ?? []).filter((message) => message?.role === \"assistant\");\n+\tif (assistants.length <= baseline) return \"\";\n+\treturn messageText(assistants.at(-1));\n+}\n+\n*** End Patch\n","name":"edit"}]},"duration":5311.115799999796,"ttft":2168.0712999999523,"contextSnapshot":{"promptTokens":213660,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_NLS5uOy3hwL1bAylGz0U08Su|ctc_096856baa6338c13016a589dd9d9148198a2e12bd78724d81b","toolName":"edit","startedAt":"2026-07-16T09:01:16.376Z"},"id":"043de371","parentId":"5cb6d1f8","timestamp":"2026-07-16T09:01:16.376Z"}
{"type":"message","id":"669c5d1c","parentId":"043de371","timestamp":"2026-07-16T09:01:16.403Z","message":{"role":"toolResult","toolCallId":"call_NLS5uOy3hwL1bAylGz0U08Su|ctc_096856baa6338c13016a589dd9d9148198a2e12bd78724d81b","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#31C9]\n121:export function extractReply(messages, afterUserMessage) {\n\n137:\treturn assistant ? messageText(assistant) : \"\";\n138:}\n139:function assistantMessageCount(messages) {\n140:\treturn (messages ?? []).reduce(\n…\n143:\t);\n144:}\n145:\n146:function extractReplyAfterAssistantCount(messages, baseline) {\n147:\tconst assistants = (messages ?? []).filter((message) => message?.role === \"assistant\");\n…\n151:\n152:\n153:function firstLine(text) {\n154:\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\n155:}"}],"details":{"diff":" 121|export function extractReply(messages, afterUserMessage) {\n\n 137|\treturn assistant ? messageText(assistant) : \"\";\n 138|}\n+139|function assistantMessageCount(messages) {\n+140|\treturn (messages ?? []).reduce(\n+141|\t\t(count, message) => count + (message?.role === \"assistant\" ? 1 : 0),\n+142|\t\t0,\n+143|\t);\n+144|}\n 139|\n+146|function extractReplyAfterAssistantCount(messages, baseline) {\n+147|\tconst assistants = (messages ?? []).filter((message) => message?.role === \"assistant\");\n+148|\tif (assistants.length <= baseline) return \"\";\n+149|\treturn messageText(assistants.at(-1));\n+150|}\n+151|\n+152|\n 140|function firstLine(text) {\n 141|\treturn text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";\n 142|}","firstChangedLine":138,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192476402}}
{"type":"message","id":"a4007505","parentId":"669c5d1c","timestamp":"2026-07-16T09:01:24.303Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding need state variables**"},{"type":"toolCall","id":"call_ArRlezrnNxV1YbHGVlRr8PE9|fc_01ca06fa5e7736fc016a589de361b8819abd527d55cdda00f6","name":"grep","arguments":{"i":"Locating turn state","pattern":"turnCompletionPromise","path":"adapter/strings/omp-spt.mjs","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":459,"output":84,"cacheRead":213504,"cacheWrite":0,"totalTokens":214047,"reasoningTokens":26,"cost":{"input":0.002295,"output":0.00252,"cacheRead":0.106752,"cacheWrite":0,"total":0.111567}},"stopReason":"toolUse","timestamp":1784192476422,"responseId":"resp_01ca06fa5e7736fc016a589ddcd8cc819a8cdf714fd4caa543","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_01ca06fa5e7736fc016a589de26c94819a854ed41cc2091efd","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ3jMcucoumGNx4OZ9V2Zm0WwbyFYV19TGB8TsTszti9tupfVqfjyxPhP5PqV92Ho_mcqIH6bnY-60oYUz9BeVjIShiKYer70M52kkEzXBZzzNeYJOrrGcfXAd4YC6FAzaSmw6gt8BpaAaqT3nbss57xPHjXiIxb-rQgww2tQzq82rClxUjGQ-Iiqx-wlMuNZMWcsteE7NNez_QXKlm3ZNnnYnTuPaqZsryOSAPS0DVhnItZzrkBJSnp5YSVt-dtMWWY_lm_oz4t5AUvwrSN3zUCBQNAYStMadKLCNngOnp0hIwds3-lj0CWlGCtc7WqJG39aHl4rj0DKsrdqW64RETGiEeEcOGXeqy1dP0JpCfMbJruwstS8Cz7zDwytX4Tk-GDwEqaY4L8ebH_KjSO7K2A0ax0yh0PDHySgZDWpe72uaFwyS4WE5epGySOEvIcvw0uW1q0a2n6IqQgChTeZvZt9PPMIWeVxi24xu1Gu21X4RkYK69JsX3Y_9EaQ58C0mmVMi3YxIK4Srkenp5Q4ouBq5L7QGHtaLvgNjwTjQ7FIxxC0zc3RAc5xYzEmvQjuge038QQfcoxYAEs4tipSqyk7kw-OeWJnPdC28NMqdc9bGv8xg79VksDPRNezjGKg-qzJ5O2Rah5EuNAEs3Eexo_9M4WGYKVJntYHIO6DeW8x24wTT9dFlmn5tAnWPh6cx4uBnBAlLx53UTLh9Tj7K3H6RU5tLWmz-sW7N24dbyHd2h5NhVU-a608XGBX24dKSjBegLVC-fkTuQ1aY0KCVYXQLzOdXLhbXM21ocVkRQRXqww4dfCE6aNOu59BblztLPl3NMOFSiR-9ADLufIzPDe7OlkMKrNoWYJBweMWUefX9pL0YwKukiQa0b28xFHs5C8ZSmvlYFRrlDZDezZ7SuYF0RTC9sbT2vj8owqlL7qFQlNBPSRYI-wCLISpQhKFJ-54GGAPlqLPyDl-mm_Wa3NOX4ow_KxRMVV6zffMBi74nJLEV6t1V93A4u8vIwM2NEtSN0rdbSQVX19mmu7i0vJaWZu3-2t5zUVQWWVjKm8U30=","summary":[{"type":"summary_text","text":"**Adding need state variables**"}]},{"id":"fc_01ca06fa5e7736fc016a589de361b8819abd527d55cdda00f6","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating turn state\",\"pattern\":\"turnCompletionPromise\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_ArRlezrnNxV1YbHGVlRr8PE9","name":"grep"}]},"duration":7879.412100000307,"ttft":6019.13450000016,"contextSnapshot":{"promptTokens":213963,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ArRlezrnNxV1YbHGVlRr8PE9|fc_01ca06fa5e7736fc016a589de361b8819abd527d55cdda00f6","toolName":"grep","startedAt":"2026-07-16T09:01:24.303Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Locating turn state"},"id":"8a84a537","parentId":"a4007505","timestamp":"2026-07-16T09:01:24.303Z"}
{"type":"message","id":"3a5a6cc6","parentId":"8a84a537","timestamp":"2026-07-16T09:01:24.306Z","message":{"role":"toolResult","toolCallId":"call_ArRlezrnNxV1YbHGVlRr8PE9|fc_01ca06fa5e7736fc016a589de361b8819abd527d55cdda00f6","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#31C9]\n 713:\t\tlet dispatching = false;\n*714:\t\tlet turnCompletionPromise;\n 715:\t\tlet listenerTerminationPromise;\n 716:\t\tlet shutdownMode = false;\n 717:\t\tlet shutdownDeadlineExpired = false;\n...\n 1836:\t\t\tif (stopping) return;\n*1837:\t\t\tturnCompletionPromise = undefined;\n 1838:\t\t\tagentActive = true;\n 1839:\t\t\tdesiredState = \"busy\";\n 1840:\t\t\ttry {\n...\n 1848:\t\tpi.on(\"agent_end\", (event) => {\n*1849:\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1850:\t\t\treturn turnCompletionPromise;\n 1851:\t\t});\n 1852:\n 1853:\t\tpi.on(\"session_stop\", async (event) => {\n*1854:\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1855:\t\t\tawait turnCompletionPromise;\n 1856:\t\t});\n 1857:\n 1858:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":6,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":6}],"truncated":false,"displayContent":"  713│\t\tlet dispatching = false;\n *714│\t\tlet turnCompletionPromise;\n  715│\t\tlet listenerTerminationPromise;\n  716│\t\tlet shutdownMode = false;\n  717│\t\tlet shutdownDeadlineExpired = false;\n     │...\n 1836│\t\t\tif (stopping) return;\n*1837│\t\t\tturnCompletionPromise = undefined;\n 1838│\t\t\tagentActive = true;\n 1839│\t\t\tdesiredState = \"busy\";\n 1840│\t\t\ttry {\n     │...\n 1848│\t\tpi.on(\"agent_end\", (event) => {\n*1849│\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1850│\t\t\treturn turnCompletionPromise;\n 1851│\t\t});\n 1852│\n 1853│\t\tpi.on(\"session_stop\", async (event) => {\n*1854│\t\t\tturnCompletionPromise ??= completeTurn(event);\n*1855│\t\t\tawait turnCompletionPromise;\n 1856│\t\t});\n 1857│\n 1858│\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {"},"isError":false,"timestamp":1784192484306}}
{"type":"message","id":"55c98a2a","parentId":"3a5a6cc6","timestamp":"2026-07-16T09:01:39.259Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding state management**"},{"type":"toolCall","id":"call_6CE8iUMAanMPYRVikkamZVAy|ctc_0160ea93e37d7f17016a589df24424819aa18fd42f7eb83b69","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#31C9]\nINS.POST 714:\n+\t\tlet turnAssistantBaseline;\n+\t\tlet knownAssistantCount = 0;\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":801,"output":64,"cacheRead":213504,"cacheWrite":0,"totalTokens":214369,"reasoningTokens":7,"cost":{"input":0.004005000000000001,"output":0.00192,"cacheRead":0.106752,"cacheWrite":0,"total":0.112677}},"stopReason":"toolUse","timestamp":1784192484326,"responseId":"resp_0160ea93e37d7f17016a589de50d88819abd9f1306674a5506","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0160ea93e37d7f17016a589df1c7f4819a9d54a5aae2efe2ee","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ3yjl2j35O1yjSu620YqPV0RGX-yn4OTZ70PBa3WhCW4ZTWy6EBH8l8Zxh6ynivZ7XNQzTX0BIq1Zq_MIiPlq-k0U52AGN9ueAx9YHS5rpNFv92iffCqiOBY1UYH2t5EJ6b0zq6aEawjEgX83FZE00OL2ER91-pLRa8v3W2iRvLrLAU6NuXnGwDghESnmmQb5Xf-MaeFemxWpjt45ufpNKbflAGvZzPpEQuid4UvzxZENoWm6wKhOtB_jYEL1QmTOCybliGui8wz3_-k_CkUWvyCtsqj19FZIl5zOXa_1D76SFxGEi529aTFTv5QNpi7M3ssUw5abVKSuk0T41k2mtoc2cLmyhnu79napK8lyDR7LV7xYVU-FKwHrX4M5-dZfJKsGl8x4vsPZQUk0SM9V2k0Y9eRx91Sx44T-FsJ2bJvZieY-PhjF2d_uNzc_wPbQGyyoakkx8wA0UHBvVxfPEFY_HUFLtvKtaa7UctP4aotGHdhGA87WPYWyLcBO4nFd6rvrbMj2VxalgE5XQ714xOi28bQkOUtgG1Tsyh8H0MGTMvCE3wg83EHdqRrDZXVAVrfOVk_3BkGssINoaQJDal2GP-AQ4ld-vCivUAm4Z0zs1hKNsrWejcBt9k1LGwhKjLccvxJcXZJG4DY42U0IbDf37zmfLDnI4wtYAnBlFerQp6fl5axPshopUyGC4GOb1Lx_mXOG-_sFBmPG5xzco2eKIwuxxSMAyt0R1-1yVbJUZhNj8PlsdNXNlTAYR_o4Ig66d4RkFsYRgkkEfdtRPP_u1nQ8gbZYDYBMCghyrOxeHDkGir3iK8rhyORyVoSOXRKtCCwgEmv-G0Dp7RF_nway3UDMpv8-ZlE61Xee7m3DM9VYeiuzgnNuh27tq1cZlo7ujnilJ9yb6KRPd7BL2EudPp70aRzmH_St92DkkuUhg=","summary":[{"type":"summary_text","text":"**Adding state management**"}]},{"id":"ctc_0160ea93e37d7f17016a589df24424819aa18fd42f7eb83b69","type":"custom_tool_call","status":"completed","call_id":"call_6CE8iUMAanMPYRVikkamZVAy","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#31C9]\nINS.POST 714:\n+\t\tlet turnAssistantBaseline;\n+\t\tlet knownAssistantCount = 0;\n*** End Patch\n","name":"edit"}]},"duration":14908.762099999934,"ttft":13443.580099999905,"contextSnapshot":{"promptTokens":214305,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_6CE8iUMAanMPYRVikkamZVAy|ctc_0160ea93e37d7f17016a589df24424819aa18fd42f7eb83b69","toolName":"edit","startedAt":"2026-07-16T09:01:39.260Z"},"id":"b0d50f87","parentId":"55c98a2a","timestamp":"2026-07-16T09:01:39.260Z"}
{"type":"message","id":"2b78555e","parentId":"b0d50f87","timestamp":"2026-07-16T09:01:39.387Z","message":{"role":"toolResult","toolCallId":"call_6CE8iUMAanMPYRVikkamZVAy|ctc_0160ea93e37d7f17016a589df24424819aa18fd42f7eb83b69","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#0137]\n713:\t\tlet dispatching = false;\n714:\t\tlet turnCompletionPromise;\n715:\t\tlet turnAssistantBaseline;\n716:\t\tlet knownAssistantCount = 0;\n717:\t\tlet listenerTerminationPromise;\n718:\t\tlet shutdownMode = false;"}],"details":{"diff":" 713|\t\tlet dispatching = false;\n 714|\t\tlet turnCompletionPromise;\n+715|\t\tlet turnAssistantBaseline;\n+716|\t\tlet knownAssistantCount = 0;\n 715|\t\tlet listenerTerminationPromise;\n 716|\t\tlet shutdownMode = false;","firstChangedLine":714,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192499387}}
{"type":"message","id":"be72f740","parentId":"2b78555e","timestamp":"2026-07-16T09:01:42.898Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_wxyax1yJb2N9TXPo7VFR0xuj|fc_0fa44fb110bb7485016a589df63060819bbe3bd0468b15d9d7","name":"read","arguments":{"i":"Reading active context and completion","path":"adapter/strings/omp-spt.mjs","selector":"1720-1865"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":942,"output":56,"cacheRead":213504,"cacheWrite":0,"totalTokens":214502,"reasoningTokens":13,"cost":{"input":0.004710000000000001,"output":0.00168,"cacheRead":0.106752,"cacheWrite":0,"total":0.113142}},"stopReason":"toolUse","timestamp":1784192499525,"responseId":"resp_0fa44fb110bb7485016a589df3f020819b83ae72beabec5e85","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0fa44fb110bb7485016a589df59524819b9c48c427a75ce362","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ32LL0360VDmQPnJF7ntCW2rXLnTryLeV3KIAdsvo2tNt95WNjU05z709HjmkFr9gtEuK97VeqKyBRlCI35LUoZRUTuBg97BIfOu79Is31Fkej6BMI_6CZ7WR9wCaeJ0sqoqXWUvnyxqK8FZBZN2QIABeiGZ9fqac71agJSIdkIbSBwGXczf2kxMOVBzcVY6NCSyGGNRlwIa6kweZwadLF6bfZ0yV8objyWYH9neBGcg6-BzqhLoDFFSZ-b7GEDpGNl1c-JuY992EuJxmCTbUEo7gJU7QkC3aRwnhejgytbiEk1SjkdgYl36TiesKeOtSlMMhv_n0RhvOVZ7TuQhWq5wHCRwgGQBgKp-0Wm49hM_YQLw95Vjs0RVIicS942SO7tA35s9Wy7h0ROvHXrXGy63fa8ImRLDRHjipU1Zlhm8JC9zx58lD68Szk_XlVAbbc8f1tbHQcJqkyEL-jUjY9T-uPiuhbWNcS4Eq3PTnxVkaP_XOWqjkSHJKmXzOFQAHutIKNJRiWQmESAh3G5D97DNqtMvv7Q5nl4KvPNMg5Slb0dsI4lmGabj6ic-XtLaIamuj1Gn6xCEeEnvWmZ6hqafK3flhl9vcGFpFfM8eYGUt7pC5rbYffXVpBpo_80waIgEYAj4FrMkRf38ZtjG4HI9iyvOjBy35s-DetaGZiPW2IMO5rcBrO0Gm5_BpsOedwTaHkivUljluVuCOracWn8Hze9Wv_L0wWvAjNmHofvIHWO349hfrlVm360RYdd5esxvO32OSX1OcKmgoZlHmxgKDVtgvi3tIQs5OFqBfBvI8f710F942hTJr4-Nus5-CRK4JS-l8PYQEc73D6jQhI73rY3dsQzI16k5ZErnz1K0hc498N0a01JKf_QKgotPlizCLiw5uhDbrqs_TI3_-SS5uUILAvehhH3xk4vCO6rFUNBVQvwfoupVWRe4zXyfLOP9wqwkc3LNTy611VTO6QzsGCrl8_2lGcwyw7Wl3KbZto=","summary":[]},{"id":"fc_0fa44fb110bb7485016a589df63060819bbe3bd0468b15d9d7","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading active context and completion\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1720-1865\"}","call_id":"call_wxyax1yJb2N9TXPo7VFR0xuj","name":"read"}]},"duration":3345.746400000062,"ttft":2156.840499999933,"contextSnapshot":{"promptTokens":214446,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_wxyax1yJb2N9TXPo7VFR0xuj|fc_0fa44fb110bb7485016a589df63060819bbe3bd0468b15d9d7","toolName":"read","startedAt":"2026-07-16T09:01:42.899Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading active context and completion"},"id":"bfa7e63b","parentId":"be72f740","timestamp":"2026-07-16T09:01:42.899Z"}
{"type":"message","id":"48f0ce52","parentId":"bfa7e63b","timestamp":"2026-07-16T09:01:42.979Z","message":{"role":"toolResult","toolCallId":"call_wxyax1yJb2N9TXPo7VFR0xuj|fc_0fa44fb110bb7485016a589df63060819bbe3bd0468b15d9d7","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#0137]\n550:export function createOmpSpt(overrides = {}) {\n…\n690:\treturn function ompSpt(pi) {\n…\n1714:\t\tpi.on(\"context\", (event) => {\n…\n1716:\t\t\tif (\n1717:\t\t\t\tagentActive &&\n…\n1719:\t\t\t\t!dispatching &&\n1720:\t\t\t\tqueue.length > 0\n1721:\t\t\t) {\n1722:\t\t\t\tconst item = queue.shift();\n1723:\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n1724:\t\t\t\titem.submitted = true;\n1725:\t\t\t\titem.activeInjected = true;\n1726:\t\t\t\tcurrent = item;\n1727:\t\t\t\tmessages = [\n1728:\t\t\t\t\t...messages,\n1729:\t\t\t\t\t{\n1730:\t\t\t\t\t\trole: \"user\",\n1731:\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n1732:\t\t\t\t\t},\n1733:\t\t\t\t];\n1734:\t\t\t}\n1735:\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n1736:\t\t\t\tmessages = injectEnvelope(messages, current);\n1737:\t\t\t}\n1738:\t\t\tif (messages !== event.messages) return { messages };\n1739:\t\t});\n1740:\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n1741:\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n1742:\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n1743:\t\tpi.on(\"before_agent_start\", async (event) => {\n1744:\t\t\tif (!activated || !id || stopping) return;\n1745:\t\t\tconst additions = [];\n1746:\t\t\tif (startupBriefPending) {\n1747:\t\t\t\tstartupBriefPending = false;\n1748:\t\t\t\tadditions.push(startupBrief(id));\n1749:\t\t\t}\n1750:\t\t\tconst hints = promptHints(event.prompt);\n1751:\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\n1752:\t\t\tif (updateNoticesPending) {\n1753:\t\t\t\tupdateNoticesPending = false;\n1754:\t\t\t\tconst notices = await updateNoticesPromise;\n1755:\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\n1756:\t\t\t}\n1757:\t\t\tif (additions.length === 0) return;\n1758:\t\t\treturn {\n1759:\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\n1760:\t\t\t};\n1761:\t\t});\n1762:\n1763:\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n1764:\t\tasync function dispatchShortforms(messages, afterUserMessage) {\n1765:\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\n1766:\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n1767:\t\t\tif (shortforms.length === 0) return;\n1768:\t\t\tconst statuses = [];\n1769:\t\t\tfor (const shortform of shortforms) {\n1770:\t\t\t\tfor (const target of shortform.targets) {\n1771:\t\t\t\t\tif (!id) {\n1772:\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\n1773:\t\t\t\t\t\tcontinue;\n1774:\t\t\t\t\t}\n1775:\t\t\t\t\ttry {\n1776:\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\n1777:\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\n1778:\t\t\t\t\t} catch (error) {\n1779:\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\n1780:\t\t\t\t\t}\n1781:\t\t\t\t}\n1782:\t\t\t}\n1783:\t\t\ttry {\n1784:\t\t\t\tpi.sendMessage(\n1785:\t\t\t\t\t{\n1786:\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n1787:\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n1788:\t\t\t\t\t\tdisplay: true,\n1789:\t\t\t\t\t\tattribution: \"user\",\n1790:\t\t\t\t\t},\n1791:\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n1792:\t\t\t\t);\n1793:\t\t\t} catch (error) {\n1794:\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\n1795:\t\t\t}\n1796:\t\t}\n1797:\n1798:\n1799:\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n1800:\t\tasync function completeTurn(event) {\n1801:\t\t\tagentActive = false;\n1802:\t\t\tdesiredState = \"idle\";\n1803:\t\t\tif (stopping) return;\n1804:\t\t\tconst messages = event.messages ?? [];\n1805:\t\t\tconst completed = current;\n1806:\t\t\tif (completed?.submitted && !completed.settled) {\n1807:\t\t\t\tconst reply = extractReply(messages, completed.stub);\n1808:\t\t\t\ttry {\n1809:\t\t\t\t\tawait settleItem(\n1810:\t\t\t\t\t\tcompleted,\n1811:\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n1812:\t\t\t\t\t);\n1813:\t\t\t\t} catch (error) {\n1814:\t\t\t\t\tif (stopping) return;\n1815:\t\t\t\t\tawait failClosed(\n1816:\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n1817:\t\t\t\t\t\terror,\n1818:\t\t\t\t\t);\n1819:\t\t\t\t\treturn;\n1820:\t\t\t\t}\n1821:\t\t\t}\n1822:\t\t\tawait dispatchShortforms(messages, completed?.stub);\n1823:\t\t\tif (current === completed) {\n1824:\t\t\t\tcurrent = undefined;\n1825:\t\t\t\treleaseItem(completed);\n1826:\t\t\t}\n1827:\t\t\ttry {\n1828:\t\t\t\tawait setState(\"idle\");\n1829:\t\t\t} catch (error) {\n1830:\t\t\t\tif (stopping) return;\n1831:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n1832:\t\t\t\treturn;\n1833:\t\t\t}\n1834:\t\t\tscheduleDispatch();\n1835:\t\t}\n1836:\n1837:\t\tpi.on(\"agent_start\", async () => {\n1838:\t\t\tif (stopping) return;\n1839:\t\t\tturnCompletionPromise = undefined;\n1840:\t\t\tagentActive = true;\n1841:\t\t\tdesiredState = \"busy\";\n1842:\t\t\ttry {\n1843:\t\t\t\tawait syncDesiredState();\n1844:\t\t\t} catch (error) {\n1845:\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\n1846:\t\t\t}\n1847:\t\t});\n1848:\n1849:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1850:\t\tpi.on(\"agent_end\", (event) => {\n1851:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1852:\t\t\treturn turnCompletionPromise;\n1853:\t\t});\n1854:\n1855:\t\tpi.on(\"session_stop\", async (event) => {\n1856:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1857:\t\t\tawait turnCompletionPromise;\n1858:\t\t});\n1859:\n1860:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n1861:\t\t\truntimeCtx ??= ctx;\n1862:\t\t\tui?.setStatus(\"omp-spt\", undefined);\n1863:\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\n1864:\t\t});\n1865:\t};\n1866:}\n1867:\n1868:export default createOmpSpt();\n\n[Showing lines 1719-1868 of 1869. Use :1869 to continue]"}],"details":{"truncation":{"content":"\t\t\t\t!dispatching &&\r\n\t\t\t\tqueue.length > 0\r\n\t\t\t) {\r\n\t\t\t\tconst item = queue.shift();\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\titem.activeInjected = true;\r\n\t\t\t\tcurrent = item;\r\n\t\t\t\tmessages = [\r\n\t\t\t\t\t...messages,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\trole: \"user\",\r\n\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}\r\n\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\r\n\t\t\t\tmessages = injectEnvelope(messages, current);\r\n\t\t\t}\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\r\n\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\r\n\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\r\n\t\tpi.on(\"before_agent_start\", async (event) => {\r\n\t\t\tif (!activated || !id || stopping) return;\r\n\t\t\tconst additions = [];\r\n\t\t\tif (startupBriefPending) {\r\n\t\t\t\tstartupBriefPending = false;\r\n\t\t\t\tadditions.push(startupBrief(id));\r\n\t\t\t}\r\n\t\t\tconst hints = promptHints(event.prompt);\r\n\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\r\n\t\t\tif (updateNoticesPending) {\r\n\t\t\t\tupdateNoticesPending = false;\r\n\t\t\t\tconst notices = await updateNoticesPromise;\r\n\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\r\n\t\t\t}\r\n\t\t\tif (additions.length === 0) return;\r\n\t\t\treturn {\r\n\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\r\n\t\tasync function dispatchShortforms(messages, afterUserMessage) {\r\n\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\r\n\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\r\n\t\t\tif (shortforms.length === 0) return;\r\n\t\t\tconst statuses = [];\r\n\t\t\tfor (const shortform of shortforms) {\r\n\t\t\t\tfor (const target of shortform.targets) {\r\n\t\t\t\t\tif (!id) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\r\n\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tpi.sendMessage(\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\r\n\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\r\n\t\t\t\t\t\tdisplay: true,\r\n\t\t\t\t\t\tattribution: \"user\",\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst messages = event.messages ?? [];\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tawait dispatchShortforms(messages, completed?.stub);\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\tawait turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\r\n\t\t\truntimeCtx ??= ctx;\r\n\t\t\tui?.setStatus(\"omp-spt\", undefined);\r\n\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\r\n\t\t});\r\n\t};\r\n}\r\n\r\nexport default createOmpSpt();\r","truncated":true,"truncatedBy":"lines","totalLines":151,"totalBytes":4535,"outputLines":150,"outputBytes":4535,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"export function createOmpSpt(overrides = {}) {\n…\n\treturn function ompSpt(pi) {\n…\n\t\tpi.on(\"context\", (event) => {\n…\n\t\t\tif (\n\t\t\t\tagentActive &&\n…\n\t\t\t\t!dispatching &&\r\n\t\t\t\tqueue.length > 0\r\n\t\t\t) {\r\n\t\t\t\tconst item = queue.shift();\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\titem.activeInjected = true;\r\n\t\t\t\tcurrent = item;\r\n\t\t\t\tmessages = [\r\n\t\t\t\t\t...messages,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\trole: \"user\",\r\n\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}\r\n\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\r\n\t\t\t\tmessages = injectEnvelope(messages, current);\r\n\t\t\t}\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\r\n\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\r\n\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\r\n\t\tpi.on(\"before_agent_start\", async (event) => {\r\n\t\t\tif (!activated || !id || stopping) return;\r\n\t\t\tconst additions = [];\r\n\t\t\tif (startupBriefPending) {\r\n\t\t\t\tstartupBriefPending = false;\r\n\t\t\t\tadditions.push(startupBrief(id));\r\n\t\t\t}\r\n\t\t\tconst hints = promptHints(event.prompt);\r\n\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\r\n\t\t\tif (updateNoticesPending) {\r\n\t\t\t\tupdateNoticesPending = false;\r\n\t\t\t\tconst notices = await updateNoticesPromise;\r\n\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\r\n\t\t\t}\r\n\t\t\tif (additions.length === 0) return;\r\n\t\t\treturn {\r\n\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\r\n\t\tasync function dispatchShortforms(messages, afterUserMessage) {\r\n\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\r\n\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\r\n\t\t\tif (shortforms.length === 0) return;\r\n\t\t\tconst statuses = [];\r\n\t\t\tfor (const shortform of shortforms) {\r\n\t\t\t\tfor (const target of shortform.targets) {\r\n\t\t\t\t\tif (!id) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\r\n\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tpi.sendMessage(\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\r\n\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\r\n\t\t\t\t\t\tdisplay: true,\r\n\t\t\t\t\t\tattribution: \"user\",\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst messages = event.messages ?? [];\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tawait dispatchShortforms(messages, completed?.stub);\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\tawait turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\r\n\t\t\truntimeCtx ??= ctx;\r\n\t\t\tui?.setStatus(\"omp-spt\", undefined);\r\n\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\r\n\t\t});\r\n\t};\r\n}\r\n\r\nexport default createOmpSpt();\r","startLine":550,"lineNumbers":[550,null,690,null,1714,null,1716,1717,null,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1869,"totalBytes":4535,"outputLines":150,"outputBytes":4535,"shownRange":{"start":1719,"end":1868},"nextOffset":1869}}},"isError":false,"timestamp":1784192502978}}
{"type":"message","id":"6b890305","parentId":"48f0ce52","timestamp":"2026-07-16T09:01:47.435Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Reviewing code at line 1708**"},{"type":"toolCall","id":"call_9PvsCZHzNn0qsoKgmRiU35rZ|fc_09c9a387c759df58016a589dfb2884819a96be2cbe50dd1d63","name":"read","arguments":{"i":"Reading context handler start","path":"adapter/strings/omp-spt.mjs","selector":"1704-1742"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2746,"output":57,"cacheRead":213504,"cacheWrite":0,"totalTokens":216307,"reasoningTokens":15,"cost":{"input":0.013730000000000001,"output":0.0017100000000000001,"cacheRead":0.106752,"cacheWrite":0,"total":0.122192}},"stopReason":"toolUse","timestamp":1784192503032,"responseId":"resp_09c9a387c759df58016a589df79c94819ab517598cc3fcdbe6","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09c9a387c759df58016a589dfa1db4819abeeebb4277ae10e8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ37C_Y5M-rXRuJVPlF31C1JPfOPRbbHHtZ3R69S1b-O-favWDF5e6w-Z86gcjSU2aWzoYvWyNjUXYmKk5Vl0-Z4kBHA0qNQ5jlPzNZficNNoCyo0D-n6nv01IpGk4yBJ5x87DeOHZ3BSz6XlTarAafUOU5WHBFdVxTwpRqnTjblVNZLdBQkz32oOVOwRp6G_KKDkMLa8VYI8AeBWvoJ4LKVvF0EglefrDwKElRkiBvuLvhG35NQerXJ5Oyc9joIkF-pk20NvHssXPQthz00ueIgg2lLjo3Rx9gqXG8yJOcQ8xfk4GbmSUHz3sDaILuaCvnaKp882ncmEXoMEki6yvJYwnGHiJSuYze5p8HxemUx4_o_lodKzwENJdKWsBv91jUM5jozrMqUwfiQWq8J3_2013rOgYuk6vypntp_CYbmGS-gSJGKJWxxR27BlllvgOD11YhRW3q68jmv2NFZMpRcUVh17oi8rNNvPj0arXfyc8o9dBMwMSvKPP_z8k6Bfyi6eScZwsGOL8Ein9_PFBLUK-smJY05Ymk3uV7o_A1hDnHII3NiAi_0979T6BUIkLuEEzsyHPozbUIjXnQO6DzRLsXjPvLZVY5T-PbkwxExQ-UlY5qVYT8JiIQIlWH9CXJO3zlVIVYFFBMaI0tqSQkwdLplOwW9vvc8d1LMpSgIM_yNPhUyrelcNhkpsSAAP6wRSLj_bzijOj0E5DCNOuuduYUmIf82qwQ6B637jIZJo3ZBA00O_Baer3q09lsrx4F0fHjxpHpaS-dZrtqs7208hvVzkzxXb5os338FLoWHh-KuL3SZDHN1Pvu-zh21iPojqVbQqlOuWDTkg59KNm4Ryk3c906V-5WfwoisvXzhdxzUKbIJi7CLvAMW0MSjifjuDnz2aX9n88YwHMKlyNJoHfVt4YsMEUve9PtO6LVOpkz4Y9233EVSM9ZebjpVAkjHFXkqigZrg-0c4glBzY5aFg==","summary":[{"type":"summary_text","text":"**Reviewing code at line 1708**"}]},{"id":"fc_09c9a387c759df58016a589dfb2884819a96be2cbe50dd1d63","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading context handler start\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1704-1742\"}","call_id":"call_9PvsCZHzNn0qsoKgmRiU35rZ","name":"read"}]},"duration":4402.439100000076,"ttft":3153.6857000002638,"contextSnapshot":{"promptTokens":216250,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_9PvsCZHzNn0qsoKgmRiU35rZ|fc_09c9a387c759df58016a589dfb2884819a96be2cbe50dd1d63","toolName":"read","startedAt":"2026-07-16T09:01:47.456Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading context handler start"},"id":"079a96ec","parentId":"6b890305","timestamp":"2026-07-16T09:01:47.457Z"}
{"type":"message","id":"0b8d2cac","parentId":"079a96ec","timestamp":"2026-07-16T09:01:47.518Z","message":{"role":"toolResult","toolCallId":"call_9PvsCZHzNn0qsoKgmRiU35rZ|fc_09c9a387c759df58016a589dfb2884819a96be2cbe50dd1d63","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#0137]\n1696:\t\tconst blockSessionChange = (description, ctx) => {\n…\n1703:\t\t};\n1704:\n1705:\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n1706:\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\n1707:\t\t);\n1708:\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\n1709:\t\t\tblockSessionChange(\"session branch\", ctx),\n1710:\t\t);\n1711:\n1712:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n1713:\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n1714:\t\tpi.on(\"context\", (event) => {\n1715:\t\t\tlet messages = event.messages;\n1716:\t\t\tif (\n1717:\t\t\t\tagentActive &&\n1718:\t\t\t\t!current &&\n1719:\t\t\t\t!dispatching &&\n1720:\t\t\t\tqueue.length > 0\n1721:\t\t\t) {\n1722:\t\t\t\tconst item = queue.shift();\n1723:\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n1724:\t\t\t\titem.submitted = true;\n1725:\t\t\t\titem.activeInjected = true;\n1726:\t\t\t\tcurrent = item;\n1727:\t\t\t\tmessages = [\n1728:\t\t\t\t\t...messages,\n1729:\t\t\t\t\t{\n1730:\t\t\t\t\t\trole: \"user\",\n1731:\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n1732:\t\t\t\t\t},\n1733:\t\t\t\t];\n1734:\t\t\t}\n1735:\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n1736:\t\t\t\tmessages = injectEnvelope(messages, current);\n1737:\t\t\t}\n1738:\t\t\tif (messages !== event.messages) return { messages };\n1739:\t\t});\n1740:\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n1741:\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n1742:\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n1743:\t\tpi.on(\"before_agent_start\", async (event) => {\n1744:\t\t\tif (!activated || !id || stopping) return;\n1745:\t\t\tconst additions = [];\n…\n1761:\t\t});\n\n[Showing lines 1703-1745 of 1869. Use :1746 to continue]"}],"details":{"truncation":{"content":"\t\t};\r\n\r\n\t\tpi.on(\"session_before_switch\", (event, ctx) =>\r\n\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tlet messages = event.messages;\r\n\t\t\tif (\r\n\t\t\t\tagentActive &&\r\n\t\t\t\t!current &&\r\n\t\t\t\t!dispatching &&\r\n\t\t\t\tqueue.length > 0\r\n\t\t\t) {\r\n\t\t\t\tconst item = queue.shift();\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\titem.activeInjected = true;\r\n\t\t\t\tcurrent = item;\r\n\t\t\t\tmessages = [\r\n\t\t\t\t\t...messages,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\trole: \"user\",\r\n\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}\r\n\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\r\n\t\t\t\tmessages = injectEnvelope(messages, current);\r\n\t\t\t}\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\r\n\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\r\n\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\r\n\t\tpi.on(\"before_agent_start\", async (event) => {\r\n\t\t\tif (!activated || !id || stopping) return;\r\n\t\t\tconst additions = [];\r","truncated":true,"truncatedBy":"lines","totalLines":167,"totalBytes":1233,"outputLines":43,"outputBytes":1233,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\t\tconst blockSessionChange = (description, ctx) => {\n…\n\t\t};\r\n\r\n\t\tpi.on(\"session_before_switch\", (event, ctx) =>\r\n\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tlet messages = event.messages;\r\n\t\t\tif (\r\n\t\t\t\tagentActive &&\r\n\t\t\t\t!current &&\r\n\t\t\t\t!dispatching &&\r\n\t\t\t\tqueue.length > 0\r\n\t\t\t) {\r\n\t\t\t\tconst item = queue.shift();\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\titem.activeInjected = true;\r\n\t\t\t\tcurrent = item;\r\n\t\t\t\tmessages = [\r\n\t\t\t\t\t...messages,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\trole: \"user\",\r\n\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}\r\n\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\r\n\t\t\t\tmessages = injectEnvelope(messages, current);\r\n\t\t\t}\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\r\n\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\r\n\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\r\n\t\tpi.on(\"before_agent_start\", async (event) => {\r\n\t\t\tif (!activated || !id || stopping) return;\r\n\t\t\tconst additions = [];\r\n…\n\t\t});","startLine":1696,"lineNumbers":[1696,null,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,null,1761]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1869,"totalBytes":1233,"outputLines":43,"outputBytes":1233,"shownRange":{"start":1703,"end":1745},"nextOffset":1746}}},"isError":false,"timestamp":1784192507517}}
{"type":"message","id":"1ae2d052","parentId":"0b8d2cac","timestamp":"2026-07-16T09:01:58.054Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Refining context injection logic**\n\n**Adjusting turnAssistantBaseline handling**"},{"type":"toolCall","id":"call_FEO8jRZyVxQbj98g5agoVNEl|fc_016f4a4b78abb480016a589e050410819b9ce8873b72e6775b","name":"grep","arguments":{"i":"Locating timeout constants","pattern":"DEFAULT_COMMAND_TIMEOUT_MS|commandTimeoutMs =","path":"adapter/strings/omp-spt.mjs","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1303,"output":404,"cacheRead":215552,"cacheWrite":0,"totalTokens":217259,"reasoningTokens":340,"cost":{"input":0.006515000000000001,"output":0.01212,"cacheRead":0.107776,"cacheWrite":0,"total":0.126411}},"stopReason":"toolUse","timestamp":1784192507667,"responseId":"resp_016f4a4b78abb480016a589dfc12e0819b85a0efa2934fc1ff","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_016f4a4b78abb480016a589dfe7508819ba704aa7564a3f116","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ4Fob9vzAL2flbXw2gTeqJFMODE7XHdtfMUn65vzhbbMfPyGGK2hzVafY_ALeKF615DkeqlGwTW0t9M3cEVcyJu0ebPnz1B-mPe4WdBSNgAyKy8eCNujrEE_tBnBxW6q1s5B8hV5IAZAeImMW8N6E-sDFlZ5cS_iM3GFAYCgA72tZeyKux1p1PaIjj6egjsEC-7PAsiXPSAzEQtVwD9jV-skAMo8jU2zfan0fSurRlHE5sf6rXJoDoePDstgv_gg7kcEnsAhd4NxnSe_9VcUAKH08Q1Ib9XNFIiOkXzGtunS_k8SfJ_H9J3-ZKUXb7yFqO7PNXRv27Pz7OcL42BZh-blKxZQE-sjvtIPCz2oPZJA9qQKvWs9ab69nzEwILUC1m9owXdFZMNDjZu62ly4SfM5KVgAUhSffJFG_oYUQvUtwdS_YTJegFoxLxQtYIOJMQ_kMruqP3bzGPSY5M8CPOSglpR5T9I76Q3kVh6tOeqcWNm-xQO5NBrYw1HUNQaETIcA0wxZNCMxPIR-QC2nSNH3wOZS8MGmzd3KSxSKtVcLNM8LmhqbSotNAd217IPGPkMJFCSt20t8KJg-nSpiO-_8DpKeL2j3zhM8CVQ4NGnXd4imo9ou4Cnk4H2paNaQ6pb0GnPU2N6uNFuusdZ00koYGZq1YYRZUdP8_w7YnydZ71k9w05zKrtpEoK-2I0oez7MadgtGFay2GaQNgIPzrTtRSXwB1uUZ1yLyHFR-KAqEeSIRfnGd6dbpp1wu2MG_rYHh3dgP-7s-QogqjHgEE9Sl1DVvuMGzpsxBWmcGlmpF-3U5fSo1wyxM5FUwCp2N4A3LdzJY3u7xrNKbTqKc5Ymz5O3HWbaTGkM2QS1zlgBVA6DxaARowUx7ceZXwlTgfeB634SMtbgo0M1oRUu0F4AbPT2NhFSeC4hLMkUKuFK6hbl9OHUlWxVSRAUovoj6zAxZv7penCrX7WZYWE5HjoIrs44GNXtZ3JEdaTkgn3-NOlO50ZfXNIm1NwLhyE4Wo4cd2zN9WOjv81ObBhFTlKqxVVRe9H4d6dadEM63vp3gIngQUPq7Ry2x5Ffh5WqespusmNz61deyg3ibMSZhi9_zP13zvAA-QCiYOtEfZKy5ZNKWblEvDiJmjQwiAN09lBcNFZPr0t6W_7SxiAq8U7T0ZJ6iYrpi_ePvRcsey2g-nGuKH0vLF6hiw85jrSXhG132O-PRO7KPyZHKvRGZ3JDj-KEVejQ1ei-v3A8URcCx4-c4sF6tqypnfIB3VESZ6t2q7zCWXwo_zNqFzjKn2UfElN_PElLytzoUqt9xB5YA7ZJ8YZlHyL1u9ek7yeL2zEaOkX_QBXxx_6D24DRj5L4u5OBTLzmUCGUvrHrwV6AAZ7zdkAh9vAVFgOZ-yzUmbmhb9bkXE61NdEOUtaoV8B30hxuNzm-ORi5dwtqvanlldBsbgD0Z3eScYlXCNtkQSh73XcsznoyannZEOZSihdncsc5c6AFyGuEXV_325n_olwjD_7zdaG8xfkmVSQRy83F9baGqwxADewAuPWjavBJdlkm0SGOcRfeFwGl4BAyPcWF1vr3qKGwxb7rcdjZN75zRAPyD8jxRF5AwkBhK9pTvcg71C4zDgScCafnXjbzpI14ikLAayyPkIR3iLJ4tkWaNUrl57kvWimwBx0KDZ6XqAxFF8n7qcnSaOQ0e1JQ976kmhSJfNJfYq_vtenpHXPXlHOgcv1grZ0itperEBKnn0UsEWNg4wqyYVEHtfsmn7ZUoew0LYGuGes9r_jfLfAxzh2ulyChX1FSZMYE9mwReAqNfS0VsU_wqvBlU0-0j8DPsQYAinjYSu8Jp3T2-tt6jYK-4tpKseY2IIg2slwCxtBPsP5VYCxw8qg3lpvOE1JEv81LiCrcNEPW4BuQbkTDOx6OHd4esCss4VZUy9ukiTKLhp9hnasevmXaBRGqZPPxa712SnAGwlzatQE_fOqmZBASiV2hOyi7Q17HgSL13ymP417QDykXvtSc303czhdfGrSKVJeo2AOFOnEY4_KjPZuPpxlTT793egZkE1mnmKp_rQfI-vXkeZHQzW2JWuwcxIXXfXWUYfgGCsgMrlX1emuQDxSfNijkQknBsJ7-HTdEgAtDw_AetwxyB1xtyZvyKHChcnc5SGkwhuEZHprw6eWTa8fcmGa1ybgBi6KJdvLGRccTPWxruKQwD9wRFYzjUzhEMr5jUYRBq-7JI5qeGgkewsSfo3myEGSfSqh3piP-Bg2XnJFwOJZsz7RmoGwujJJmBwVT3jycZ07tITP6QsGjnhsogLQ5qTS__3vcrrw-6akD6bOFBSuMoOuO1Yuzw-xBVA4JDl9WI3onUpspsHEPbIviv68sYRroNgclMESooph_eYvu9jdjQeMfiQGxVpQ3k2OyImXDL7a04YxFR8PMjL-mpmg7qRjsH1yg5OQyVkfBy243CRWkbsNNE8zpLJMYnmpUy50Pw5fG354J_JB27L55o7XlslfNaNbBQoRhUshpH2Y97dW4hxDplS_WLbzQ6O5uUO4oPngrpWYo6kF8ncNdJ3h_YjP2-x6IpKb1fvlfHgEqItmf8acLIIJan8ePmzg-y_48zIbTfi2cvknJe9fLaMUJBhRwki9CGeOKEgrb97tpi-kbr5NLfuTSD14QlVlP6WE6ocN5x64TMRcrN_LGawiX8iK6JptjRvrDaJ5Y1ocmra7RQNDhrlqcKCzb_zqIfmbVYK3MkHqNqw1oCmcsQu-Bg37pZ2i0PJr6-khxt0cqPG9tCH6qFMI5Tk0bHebgHO0s5K_37HRL2IonaD7iK3fnMZxU0YiWM9jN-e6gAKWRANMeA02grh6pHJkA0FiDaAgFNacQ8sp0MLvfbP_fwkcaz2jyB_Lu3A0_PITrMSmn_mInJEDEg3QzHl9LUwbwLQ8S-49TbUcaYk1u9xY1CBcFMqnUH4yhr-DPN_yhrs_D96kwepTEEZMn8HQ3tQVciM7YOB8HJJyM_2-xtzzQLa8mKz6K-6rNgbNDaEvE9TQkPyHXdZIvhD1lZzcSXRCixyArYyjqRkKlmVF_b67L37yq1QvatsUh7qXUABqeZKDycvxvFbHKhXZvYGVioBsJp0eWYphSaGDocRYDcQbBbL_Jzwd4j_djIaRufeHkC3ik9TyaMppPPYO2D1VLMeLmPUYD68I6p8q","summary":[{"type":"summary_text","text":"**Refining context injection logic**"},{"type":"summary_text","text":"**Adjusting turnAssistantBaseline handling**"}]},{"id":"fc_016f4a4b78abb480016a589e050410819b9ce8873b72e6775b","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating timeout constants\",\"pattern\":\"DEFAULT_COMMAND_TIMEOUT_MS|commandTimeoutMs =\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_FEO8jRZyVxQbj98g5agoVNEl","name":"grep"}]},"duration":10386.251000000164,"ttft":2799.13440000033,"contextSnapshot":{"promptTokens":216855,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_FEO8jRZyVxQbj98g5agoVNEl|fc_016f4a4b78abb480016a589e050410819b9ce8873b72e6775b","toolName":"grep","startedAt":"2026-07-16T09:01:58.054Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Locating timeout constants"},"id":"e715b93e","parentId":"1ae2d052","timestamp":"2026-07-16T09:01:58.054Z"}
{"type":"message","id":"f7a31a37","parentId":"e715b93e","timestamp":"2026-07-16T09:01:58.465Z","message":{"role":"toolResult","toolCallId":"call_FEO8jRZyVxQbj98g5agoVNEl|fc_016f4a4b78abb480016a589e050410819b9ce8873b72e6775b","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#0137]\n 351:\n*352:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n 353:const DEFAULT_KILL_GRACE_MS = 100;\n 354:const DEFAULT_KILL_FORCE_MS = 100;\n 355:const DEFAULT_LISTENER_BUFFER_LIMIT = 256 * 1024;\n...\n 425:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n*426:\tconst timeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n 427:\tconst graceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n 428:\tconst forceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n 429:\tconst env = overrides.env ?? process.env;\n...\n 558:\tconst customRunSptCommand = overrides.runSptCommand;\n*559:\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n 560:\tconst runSptCommand =\n 561:\t\tcustomRunSptCommand ??\n 562:\t\t((args, input, options = {}) =>"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":3,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":3}],"truncated":false,"displayContent":" 351│\n*352│const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n 353│const DEFAULT_KILL_GRACE_MS = 100;\n 354│const DEFAULT_KILL_FORCE_MS = 100;\n 355│const DEFAULT_LISTENER_BUFFER_LIMIT = 256 * 1024;\n    │...\n 425│\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n*426│\tconst timeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n 427│\tconst graceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n 428│\tconst forceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n 429│\tconst env = overrides.env ?? process.env;\n    │...\n 558│\tconst customRunSptCommand = overrides.runSptCommand;\n*559│\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n 560│\tconst runSptCommand =\n 561│\t\tcustomRunSptCommand ??\n 562│\t\t((args, input, options = {}) =>"},"isError":false,"timestamp":1784192518463}}
{"type":"message","id":"0d27b176","parentId":"f7a31a37","timestamp":"2026-07-16T09:02:02.133Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding const and option keywords**"},{"type":"toolCall","id":"call_u95QWCWdWllOZzukZuh6VQss|fc_0476ae2807d52a85016a589e09ae3c819aa22736594f3e8f4a","name":"read","arguments":{"i":"Reading constants and constructor timeout","path":"adapter/strings/omp-spt.mjs","selector":"345-365,552-570"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":920,"output":54,"cacheRead":216576,"cacheWrite":0,"totalTokens":217550,"reasoningTokens":9,"cost":{"input":0.004600000000000001,"output":0.0016200000000000001,"cacheRead":0.108288,"cacheWrite":0,"total":0.114508}},"stopReason":"toolUse","timestamp":1784192518754,"responseId":"resp_0476ae2807d52a85016a589e0727b0819a8e13b710e1d194e0","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0476ae2807d52a85016a589e08ed04819a916ac018043808f0","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ4JvosrqEYpWRHmjAL7YbgRj0bJUGEgbyeb8z6oMiEWwYpuVHNfPdXJULkgFO6JOyHJW4VQ9XJGCpNHo1I9NHyVHxr3CHK7swmUuaNjSUR06rqhfObuWLExNLcfR7p2yvHC0CgacZGVt5aSb68lkHgsLntwOVCy29mgq4I4aetP-v5cCzMnvAInsmG22CTtYGlKn-cC7_GmeGyq2aq0_TC1h0NOp1COod-q4EZEMK8yJbzjv1McZ0qpnMjaDy56qy-GBh95iGm_nxF0_OyJb2Wxxk_9Kl-S9HPsZR1vtcPOFBP4ecjye7bgDwPZZW7GzyQfhYKhndY0J1oXki5ju5DMMMdv6w4CJt7iOIrMBUjNGDYmYUnX6tllc0vCwmItAUC4-1-i_8a7p5zh-789FyV5GJas3yPjzcRuFbV36KN1ahf7LVZ-lFtW8Uf5LKN2ZZu40hBRTle-0Ojk1O473OimXrwKfC1wCRkv26jrOkGN_vmNkj1FlZBhpDyBpke5ZyWiOUszWheKyZ0d0VEKkaLDWFinrobQ2NacY9ZZ3LQXS8runP-xxPmR0hpHyti61b3DMA4P9iq4xkyzZ1Nl1Y5aBZMgotw8ZUeT6JZzGFeI9r5soQ05EAEY_I9NxO8i6fsFu9BShyWr8WejyRvMOxJBeyVnod-UiFOMPYPA6V6xKo0e6Z4z2L5rECF9sGX6-ksa9-dIposYnXMJ5O76DGv_gdJAB9oEjKZsrJ2A-dlCDJ_T7e1AiME0_gfGQiOtIm_iFqmAPDiGKHaBsT9DOpDjgQorLX1oy8V9463iM1jKObK3yiW-HuADVTvKP8qYSsE22MV_LBJMHgoCpJl9yGM2acOt0a7Feuia01MBikUnQvhGYa6a1JS8DNMqmoVtNZmDIGT3tj9loirfVfvIFtsUPqPcoCCcVrvGjjBM4dDLjJFNEFmOknu1UjaTt0x5BKLN","summary":[{"type":"summary_text","text":"**Adding const and option keywords**"}]},{"id":"fc_0476ae2807d52a85016a589e09ae3c819aa22736594f3e8f4a","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading constants and constructor timeout\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"345-365,552-570\"}","call_id":"call_u95QWCWdWllOZzukZuh6VQss","name":"read"}]},"duration":3378.1743000000715,"ttft":2168.9457000000402,"contextSnapshot":{"promptTokens":217496,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_u95QWCWdWllOZzukZuh6VQss|fc_0476ae2807d52a85016a589e09ae3c819aa22736594f3e8f4a","toolName":"read","startedAt":"2026-07-16T09:02:02.133Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading constants and constructor timeout"},"id":"30bb11e6","parentId":"0d27b176","timestamp":"2026-07-16T09:02:02.133Z"}
{"type":"message","id":"3b16f148","parentId":"30bb11e6","timestamp":"2026-07-16T09:02:02.213Z","message":{"role":"toolResult","toolCallId":"call_u95QWCWdWllOZzukZuh6VQss|fc_0476ae2807d52a85016a589e09ae3c819aa22736594f3e8f4a","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#0137]\n340:function startupBrief(id) {\n341:\treturn [\n…\n345:\t\t\"- Continuity/lifecycle: use the packaged commune (checkpoint mode), signoff, and role skills.\",\n346:\t\t\"- Activation/setup: `/ready`, `/live`, and the packaged setup skill.\",\n347:\t\t\"- Subnets: `spt how-to subnet`.\",\n348:\t\t\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\",\n349:\t].join(\"\\n\");\n350:}\n351:\n352:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n353:const DEFAULT_KILL_GRACE_MS = 100;\n354:const DEFAULT_KILL_FORCE_MS = 100;\n355:const DEFAULT_LISTENER_BUFFER_LIMIT = 256 * 1024;\n356:const DEFAULT_ACCEPTED_QUEUE_LIMIT = 128;\n357:const DEFAULT_ACCEPTED_BYTES_LIMIT = 1024 * 1024;\n358:const DEFAULT_SHUTDOWN_BUDGET_MS = 1_800;\n359:const DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS = 300;\n360:\n361:function childExited(child) {\n362:\treturn (\n363:\t\t(child.exitCode !== undefined && child.exitCode !== null) ||\n364:\t\t(child.signalCode !== undefined && child.signalCode !== null)\n365:\t);\n366:}\n…\n552:\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\n553:\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n554:\tconst env = overrides.env ?? process.env;\n555:\tconst platform = overrides.platform ?? process.platform;\n556:\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n557:\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n558:\tconst customRunSptCommand = overrides.runSptCommand;\n559:\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n560:\tconst runSptCommand =\n561:\t\tcustomRunSptCommand ??\n562:\t\t((args, input, options = {}) =>\n563:\t\t\trunSpt(args, input, {\n564:\t\t\t\tclearTimeout: clearTimer,\n565:\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\n566:\t\t\t\tenv,\n567:\t\t\t\tkillForceMs,\n568:\t\t\t\tkillGraceMs,\n569:\t\t\t\tsetTimeout: setTimer,\n570:\t\t\t\tsignal: options.signal,\n…\n572:\t\t\t}));"}],"details":{"displayContent":{"text":"function startupBrief(id) {\n\treturn [\n…\n\t\t\"- Continuity/lifecycle: use the packaged commune (checkpoint mode), signoff, and role skills.\",\n\t\t\"- Activation/setup: `/ready`, `/live`, and the packaged setup skill.\",\n\t\t\"- Subnets: `spt how-to subnet`.\",\n\t\t\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\",\n\t].join(\"\\n\");\n}\n\nconst DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\nconst DEFAULT_KILL_GRACE_MS = 100;\nconst DEFAULT_KILL_FORCE_MS = 100;\nconst DEFAULT_LISTENER_BUFFER_LIMIT = 256 * 1024;\nconst DEFAULT_ACCEPTED_QUEUE_LIMIT = 128;\nconst DEFAULT_ACCEPTED_BYTES_LIMIT = 1024 * 1024;\nconst DEFAULT_SHUTDOWN_BUDGET_MS = 1_800;\nconst DEFAULT_SHUTDOWN_COMMAND_TIMEOUT_MS = 300;\n\nfunction childExited(child) {\n\treturn (\n\t\t(child.exitCode !== undefined && child.exitCode !== null) ||\n\t\t(child.signalCode !== undefined && child.signalCode !== null)\n\t);\n}\n…\n\tconst setTimer = overrides.setTimeout ?? globalThis.setTimeout;\n\tconst clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;\n\tconst env = overrides.env ?? process.env;\n\tconst platform = overrides.platform ?? process.platform;\n\tconst killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;\n\tconst killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;\n\tconst customRunSptCommand = overrides.runSptCommand;\n\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n\tconst runSptCommand =\n\t\tcustomRunSptCommand ??\n\t\t((args, input, options = {}) =>\n\t\t\trunSpt(args, input, {\n\t\t\t\tclearTimeout: clearTimer,\n\t\t\t\tcommandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,\n\t\t\t\tenv,\n\t\t\t\tkillForceMs,\n\t\t\t\tkillGraceMs,\n\t\t\t\tsetTimeout: setTimer,\n\t\t\t\tsignal: options.signal,\n…\n\t\t\t}));","startLine":340,"lineNumbers":[340,341,null,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,null,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,null,572]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"}}},"isError":false,"timestamp":1784192522212}}
{"type":"message","id":"25334a52","parentId":"3b16f148","timestamp":"2026-07-16T09:02:08.433Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_1DmtRLiLLRHDaxIwKxCAN0RN|ctc_092d31e15e465348016a589e0ed854819bb979ec442537955b","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#0137]\nINS.POST 352:\n+const DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS = 5_000;\nINS.POST 559:\n+\tconst shortformCommandTimeoutMs =\n+\t\toverrides.shortformCommandTimeoutMs ?? DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS;\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1510,"output":90,"cacheRead":216576,"cacheWrite":0,"totalTokens":218176,"reasoningTokens":6,"cost":{"input":0.00755,"output":0.0027,"cacheRead":0.108288,"cacheWrite":0,"total":0.11853799999999999}},"stopReason":"toolUse","timestamp":1784192522353,"responseId":"resp_092d31e15e465348016a589e0ac49c819b84225e3e5235fb66","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_092d31e15e465348016a589e0e78b0819bbe58e0913517d8c8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ4Oy5izZw8134tfxJKJOJSJD2SS70bGGwxS2evnrjxpg5793vmbZnh8QjWjS9KgjZPvp4mDYHiwcjF3qcwWHWHwQZtiqk7zgdoSPsGEoWmVRl3H_QhnIJ9TPNzv-imXXW3AMHTDcTMTlbrTV7Ub5n0mzjFXcvNDHLp85xpf89ZuRyWaS3biZakh9tALOBJcXWZgqJTaZKH25hGyVp4Jp79fdkXsXUo18ewJswGKRNsjd0zxsVK4o0c9MU7TpfDouaxmtugbXd9oKJK8PQA5OE78iAJcCT_oGsPMgple_2p8zwHUCL8Kg4qfXOiWeMCBwoGL4T2xY8_bhM0wojmgRzD9RWmEJps6ev4M3yPuTUrFNMxEmTTFUt3Ndu2ds-85jlVEAEUDwpxaKpffaz0-p0kUR2AXHjTYDeprrwtFoUp9Jtg5tmsT_XDrDA31t5gqwnnGGbhTVjCD4IyUUM0zK2d_3H9jvp6O1Kz-mMOI3fILbnMWhWzTxl9_QduZg9ldkrSmRDKCZqg06MjevrjX92P25yXlnoqpgFl8sRPMVtIUjo6m7b_QXg9UAZKqIOFxMN9iPfQ5hb_-G1uy62gwT9WGlBdlIc5x5oO1CLICn32WZG0aWXwS7AqYpR2Tej22oE6LJwFgwgffZ1xAx8k2mI8tanJpcsOMBEiO874Wos74GF9Q_JNiUEwFYuxfKGhhfVMxHbV_dql6hMUgh9NQgixh9twkRco9mIjZXl7aXaEZxHClxQurhxba4iWa3vLT_8K_DfH4KlN0C4aElK5g9WPv5BaN5Vqyb4xQKyYWUI2x0SMbgJo6xkvRXZMrADZCwytt7G_cHZ5yd2l081h7jLpAtqIt0vAvg4IsSWTZxD9iUcE_rkGYSFhB-IQGw4tMCYfSBPrweY2Gekp8oqtxETNzmypXBAXvh9LLcEtPM6zukmw=","summary":[]},{"id":"ctc_092d31e15e465348016a589e0ed854819bb979ec442537955b","type":"custom_tool_call","status":"completed","call_id":"call_1DmtRLiLLRHDaxIwKxCAN0RN","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#0137]\nINS.POST 352:\n+const DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS = 5_000;\nINS.POST 559:\n+\tconst shortformCommandTimeoutMs =\n+\t\toverrides.shortformCommandTimeoutMs ?? DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS;\n*** End Patch\n","name":"edit"}]},"duration":6014.101199999917,"ttft":4121.111699999776,"contextSnapshot":{"promptTokens":218086,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_1DmtRLiLLRHDaxIwKxCAN0RN|ctc_092d31e15e465348016a589e0ed854819bb979ec442537955b","toolName":"edit","startedAt":"2026-07-16T09:02:08.434Z"},"id":"936161df","parentId":"25334a52","timestamp":"2026-07-16T09:02:08.434Z"}
{"type":"message","id":"c62d2d5d","parentId":"936161df","timestamp":"2026-07-16T09:02:08.840Z","message":{"role":"toolResult","toolCallId":"call_1DmtRLiLLRHDaxIwKxCAN0RN|ctc_092d31e15e465348016a589e0ed854819bb979ec442537955b","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#EB19]\n351:\n352:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n353:const DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS = 5_000;\n354:const DEFAULT_KILL_GRACE_MS = 100;\n355:const DEFAULT_KILL_FORCE_MS = 100;\n559:\tconst customRunSptCommand = overrides.runSptCommand;\n560:\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n561:\tconst shortformCommandTimeoutMs =\n562:\t\toverrides.shortformCommandTimeoutMs ?? DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS;\n563:\tconst runSptCommand =\n564:\t\tcustomRunSptCommand ??\n\n575:\t\t\t}));"}],"details":{"diff":" 351|\n 352|const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;\n+353|const DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS = 5_000;\n 353|const DEFAULT_KILL_GRACE_MS = 100;\n 354|const DEFAULT_KILL_FORCE_MS = 100;\n 558|\tconst customRunSptCommand = overrides.runSptCommand;\n 559|\tconst commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n+561|\tconst shortformCommandTimeoutMs =\n+562|\t\toverrides.shortformCommandTimeoutMs ?? DEFAULT_SHORTFORM_COMMAND_TIMEOUT_MS;\n 560|\tconst runSptCommand =\n 561|\t\tcustomRunSptCommand ??\n\n 572|\t\t\t}));","firstChangedLine":352,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192528839}}
{"type":"message","id":"9a75ccdb","parentId":"c62d2d5d","timestamp":"2026-07-16T09:02:38.438Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Implementing dispatchShortforms with ordering**\n\n**Refining shortform dispatch sequencing and shutdown handling**"},{"type":"toolCall","id":"call_PLuNaft8SrjMteR5yANjOsOo|ctc_0dcdb11c56b27b75016a589e1c384081999f77c41d9a8b7399","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#EB19]\nSWAP.BLK 1714:\n+\t\tpi.on(\"context\", (event) => {\n+\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n+\t\t\tturnAssistantBaseline ??= assistantBaseline;\n+\t\t\tlet messages = event.messages;\n+\t\t\tif (\n+\t\t\t\tagentActive &&\n+\t\t\t\t!current &&\n+\t\t\t\t!dispatching &&\n+\t\t\t\tqueue.length > 0\n+\t\t\t) {\n+\t\t\t\tconst item = queue.shift();\n+\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n+\t\t\t\titem.submitted = true;\n+\t\t\t\titem.activeInjected = true;\n+\t\t\t\titem.assistantBaseline = assistantBaseline;\n+\t\t\t\tcurrent = item;\n+\t\t\t}\n+\t\t\tif (current?.submitted && !current.settling) {\n+\t\t\t\tif (current.activeInjected) {\n+\t\t\t\t\tconst content = `${current.stub}\\n\\n${current.envelope}`;\n+\t\t\t\t\tif (\n+\t\t\t\t\t\t!messages.some(\n+\t\t\t\t\t\t\t(message) => message?.role === \"user\" && messageText(message) === content,\n+\t\t\t\t\t\t)\n+\t\t\t\t\t) {\n+\t\t\t\t\t\tmessages = [...messages, { role: \"user\", content }];\n+\t\t\t\t\t}\n+\t\t\t\t} else {\n+\t\t\t\t\tcurrent.assistantBaseline ??= assistantBaseline;\n+\t\t\t\t\tmessages = injectEnvelope(messages, current);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (messages !== event.messages) return { messages };\n+\t\t});\nSWAP.BLK 1764:\n+\t\tasync function dispatchShortforms(assistantOutput) {\n+\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n+\t\t\tif (shortforms.length === 0 || stopping) return;\n+\t\t\tconst deliveries = shortforms.flatMap((shortform) =>\n+\t\t\t\tshortform.targets.map((target) => ({ target, body: shortform.body })),\n+\t\t\t);\n+\t\t\tconst statuses = await Promise.all(\n+\t\t\t\tdeliveries.map(async ({ target, body }) => {\n+\t\t\t\t\tif (!id) return `${target}: failed (activate this OMP session first)`;\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], body, {\n+\t\t\t\t\t\t\ttimeoutMs: shortformCommandTimeoutMs,\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn `${target}: ${firstLine(result) || \"sent\"}`;\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\treturn `${target}: failed (${errorSummary(error)})`;\n+\t\t\t\t\t}\n+\t\t\t\t}),\n+\t\t\t);\n+\t\t\tif (stopping) return;\n+\t\t\ttry {\n+\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t{\n+\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n+\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n+\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t},\n+\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t);\n+\t\t\t} catch (error) {\n+\t\t\t\tif (!stopping) logError(\"omp-spt could not inject peer-message results\", error);\n+\t\t\t}\n+\t\t}\nSWAP.BLK 1800:\n+\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+\t\tasync function completeTurn(event) {\n+\t\t\tagentActive = false;\n+\t\t\tdesiredState = \"idle\";\n+\t\t\tif (stopping) return;\n+\t\t\tconst messages = event.messages ?? [];\n+\t\t\tconst completed = current;\n+\t\t\tconst turnBaseline = turnAssistantBaseline ?? knownAssistantCount;\n+\t\t\tconst completedBaseline = completed?.assistantBaseline ?? turnBaseline;\n+\t\t\tconst currentTurnReply = extractReplyAfterAssistantCount(messages, turnBaseline);\n+\t\t\tif (completed?.submitted && !completed.settled) {\n+\t\t\t\tconst reply = extractReplyAfterAssistantCount(messages, completedBaseline);\n+\t\t\t\ttry {\n+\t\t\t\t\tawait settleItem(\n+\t\t\t\t\t\tcompleted,\n+\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n+\t\t\t\t\t);\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tif (stopping) return;\n+\t\t\t\t\tawait failClosed(\n+\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n+\t\t\t\t\t\terror,\n+\t\t\t\t\t);\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (current === completed) {\n+\t\t\t\tcurrent = undefined;\n+\t\t\t\treleaseItem(completed);\n+\t\t\t}\n+\t\t\tknownAssistantCount = assistantMessageCount(messages);\n+\t\t\ttry {\n+\t\t\t\tawait setState(\"idle\");\n+\t\t\t} catch (error) {\n+\t\t\t\tif (stopping) return;\n+\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t\tawait dispatchShortforms(currentTurnReply);\n+\t\t\tif (!stopping) scheduleDispatch();\n+\t\t}\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":738,"output":1494,"cacheRead":217600,"cacheWrite":0,"totalTokens":219832,"reasoningTokens":432,"cost":{"input":0.00369,"output":0.04482,"cacheRead":0.1088,"cacheWrite":0,"total":0.15731}},"stopReason":"toolUse","timestamp":1784192528914,"responseId":"resp_0dcdb11c56b27b75016a589e1157488199b1bf1ec65344dc8d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0dcdb11c56b27b75016a589e1369948199b17cb1de36441303","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ4cYl7rflVkcE5auqCTZNexu__8laGevySP1B4IvO4PcT5YMSOcPUYJUmcCqwwATayPh2pKawYw62IALcdwuGdLcK9gkYtb4X1kPZszu7NRY_Lh3yDq5hsJeoEw7ZkBqAAXpEmt4EAK20dFeN1xmwn-LqRuX67fp-mHXJwwhKBR6TFi76uPitfPSd3YhxXcy958Y_YHtsyJrpnKu3lUc2fAofD_JX4dv7msQD9loIO_DT-MF4x0Cm_xxBRiQYvDAqC8fDPSZnUd4QvBdiK3CAnYiKyhGkbWNRkJA3AU7VrmBKHAXCtp_FjNYYK73k2KhW8NXcFaL7WkJ7frUL5XIixyjJw_tE4l4A7wfqGs10iCpe3TF5trmlphiWaooIjNsRcVx1rLaSf184Ai0SqCVHQsew7VKhXL8hj4hcCSIoW7g_bEE15WaYxcgq0SPmC_GykULMzQFxldLat4r9LA4VeoCWihdLbsH9WIafW1D-kkjAmZdjpimoN-FL1IYd44tKv47OVmwJ7Da6l5bQvB4f_tzRt5AvLGcM6Rq45K0-th755hCGL9PHe6xwoCUzCl7dnv3i4Z-cIX70oNqYFzJMFAlLhAluJOU2RAHse2YGYwppSmV3EjifPOaKxnFviYNY4UoWJ0gGbgc-eOMOERmEF-hp6zgzmpctvZHbIc0Wh3452whmzHOPFUlGaa4M6F_4IwRyQ1ACCmgBS_hz80wT7hY1SfzzTnPHObkfSoYmEPOfgkFSScZtjI6hsGJp0NPqkvKBV3ynGOa_2Pe5lOc2_lGoftWsOwZPUQU5Yt6jAarqpAqoFDCyV1VarmhyZ7vTEgNfg96J2fDH4O1wPvvR4japJbzhLCs_CkApbAxfd0Y5IpPBOPmPNe2jBvlCHpb1o02fiIKSwnIfg-6JeeqptZ6afWJ7TpcJ7iFgZfUmGwn6P1bS7ugjCfInHoc4ATPAABv1FvVaqE27vXBMGlEutms8_5bMNx6eTvZG0AzFn7ndivF5exVegi996DSDjabqPkEbyGNrNCMFPQLbIKyjBLWABxiI1WmKqQ89MiXDOQQOYER1rZLz_M_0lHWSs0b6Y6BFKVrgbhhUDzWeH0rN1p4MV5CZX-6K-2gm01sH8zKOcgs43_05vr3KWVejAxm1NB3DVQ_lWpPA65AQ8tMNglLkDGLORjAdaPCEtWxFqhrD923u8N6I2aRPanQbOUQTfophPwhBHGEcobVzqssOXQm0FCryIQNzoBUTH7liDRwmeAaW3FQg-51GnAswRKK4Z931twLpvb0UjteT01sl7jQYPMCY6gua0wsjThx6Cc6_DnO2_w6W7r31dAf3iLrzv9xm-8d_gWLektsE5vMo-qQj3UDTuRw59Hbd1B50xHeR_Gal9ujInuVX5Wxuk5poXBTHmQEvYmEwPPbgIHRK_POGQC-i9H5hJFUQqoRGF1KjJRHSLaBhxnD-Kv0u3lf9paGqnLG4Pb5Y1FEAtmP9PQCut-SPlZxPZQQsYefEgsgLRODHN0jJbyJFASXl9D4Oqy1wstTi7TRf_eP7gLsbJS8TvzW09_wpEJTC5TarIJ42QxAgvvslquo-k-ZFki0yS3uwTTB2QBWjY08xZNxd2mdIcZiGZSiGsMZs__ARWsGUPftZLhfVm2je658W0bcE1ULu5Pf4aVAl3a8g2vS76ASMMWXwU6xX1z84-OKF5xTM735_966TWnw9BC9iQvdNgW3WlQcZbBdK84ksOCEEUj5GY-RQ9tA8lL0by4N2ECaHsxTFh6n6Rye_o8tG1mZbCTSNqWNF9miPXEtD1NGZMhp__wbLh5p6X1H-G7mKS-dFFf1iCJ6BOFmOkeaJFd5GF7wFLQsGDILD9csMvboDkjMIxNR-G81yomoN8W1-YqkWPpAKNkHls2j1X93_bqZFEt8nxOL1Q00oFd2Lq829LOoN3BFNURhMzvjuY_19ETwNbycWjGuoMEWOIoeoYUisSP_xdmStM2m_m4LpSqBuG2vFOA0o8K16rBvS9R3c8voYLpDz2itG_QZ7u01GTrA-JlMZC1nvVNFwfy2dNYmTqFeIn9HIWdT3ClHpESi4f_M_LQHPw84ACWCxSQ81HvVAy_I3mIRQiHn1X2-1AYckDPkxG95HOMJG4lAa3Sqskg2RU9b7Bh_PNNy4jDvSDhH8DaMmPXyCvMQj5-YSpWZqRBOJY2qHqztJgyFPgPggqyvhLcldjMSP4A_VTemiCuR7nMzv2iilPgoPn6exQsMqhTctd7vuhaUaTTZPn72Mr4jtqavTEUagMZ44VL5OVjsIdFkX2TNq26yBvNqvoyBvic4-lIV5RV5P01CvMMORqslVQiWO2pKiomxdHwWxIkAsB0F7uQLZ_DPjzvvJPw3WfiLVYrbO8o-sZPQ-JgknKJeI4ur0IFZQEdTSZkrChUdpbmRMJbQ4wykVLEfxlrP4krRPsONHANrLoJGPG2y0SuYaoQHANAqq3-btIog_g_Ey-uOnZmYXhQP0URmtapWiTgedqKJISBgQADGPrbxI5D_Hi6FZQLDMJx9WJeFf_kAEFigVgMp5v_5lcehbCiQ8pBV-mOYlS7cpAcMHcX8j8vz-h2tiZLacMKpuvo9Wb_pRNOzY9i80nFTDewXuudJ2sD7P35ZjMAHDje3xXBxWUqs5QuHfnO87GWG_3yfhXE5dD_zEnv5X6mENCGvPgI_z8KLCkWB5I6AeEX_fYpLqOxAP4Q5Tvgti6iIz7nEgRPlNNT8LcL6SBJpQIUI4tLyrbIuizrshJmY2autE-WdK3rj-6YfXWYOwvNkslzjRT5s7JUC2bfxctgK6uZ_sv4xzvjZ21U5Jf8JiWV4fY6cn0kmJLjyXphn95PHEwz_NEdybPS7r0XKTuN4W8zVo5FN4AYXktj0M8R7M8ctFXOGnyEbJh6nUCUY40-iNJ9HUgjZ_CJ84h7LMofOXVwfE52LTeNWWjbHpGjcnnsXsQczFQAdHo33rlH_vG8TZxVq72tIzhFKaEjWVsI_o_bhyCkRk9jTIatuTKtzt_Q3FoVzQquOZEz5xYgJb_1kTzWRjTakiZiJJizRV27oicNQN-qlNXBXRuBis5Ilur8_Ri4wXIoaoccd0OdGbVV1vzf4GhCHb9TnbZBNVYW1PrUlq2ezNObHNl-D8tqiTGIFzov7mH4KrKTDK5yRMIyFxr6p99ssrJTWOkYUJ2qr3q4pp6vgms2SCkyhAmt_sKZtHCTjwp363vKmtKVR9gwhZlQ5Rvx9i5AauJ6-aYUCHfy6ufKX9Dn9Lo_nwDBk3if7kkiY9M24_EE37ipQ97YUuYLABi99HyOyevQ72fC0ow_VINzsYYAol-6h_UWDEdBwyUPOa3d80k85E01XhQU7gNnfoNHxOjemeEpYS-kotvP7S8xE_hmGM3gsDal4xLLBmv6C_wx9YFUCcE_TrwkWmLT53xpG3CSNyvJ886ArnZF6uMwhV1BRlf_NnuUw_Ua-HQL3r2cHb3NEP1r7k39KnxnDpIQs62IVNDfDhPzTWKtonJlfJrjiPda-flWOr3Ceq5J6-WysbyRpZdxK_tl7SUfLJ55FSRSQnC4oM1YwSruBlZOFu4efEBQszrHjsxjp8mKO87mCMwuk0CrXc573beBD2dDUbCmlT4rpUh71dhDl3RKgV_SYXv8SQPYVR5YFbWwnr_do37_D-HWjnQJTiS_tYi1YmlYwXE9FU-6cH5tIkhQ_z9BP2v1D9MweIsvfVwyyc1ZGXs26CN_aSeO0ezf-LcloACoEW6xR2BpSsH80MH1kXbfj8laE7Cl0axz9Rkrji3eIO7pcQTRm2oQxdEZO5QhbKRMeykW8Yd0kCQPdQ1mOjbhfWm1b5Qj9Lgn6Az04VxuS5peAxGhGKB_UVXWngWEag7vQOnhr32h7iMwAwoi9XCOqg==","summary":[{"type":"summary_text","text":"**Implementing dispatchShortforms with ordering**"},{"type":"summary_text","text":"**Refining shortform dispatch sequencing and shutdown handling**"}]},{"id":"ctc_0dcdb11c56b27b75016a589e1c384081999f77c41d9a8b7399","type":"custom_tool_call","status":"completed","call_id":"call_PLuNaft8SrjMteR5yANjOsOo","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#EB19]\nSWAP.BLK 1714:\n+\t\tpi.on(\"context\", (event) => {\n+\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n+\t\t\tturnAssistantBaseline ??= assistantBaseline;\n+\t\t\tlet messages = event.messages;\n+\t\t\tif (\n+\t\t\t\tagentActive &&\n+\t\t\t\t!current &&\n+\t\t\t\t!dispatching &&\n+\t\t\t\tqueue.length > 0\n+\t\t\t) {\n+\t\t\t\tconst item = queue.shift();\n+\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n+\t\t\t\titem.submitted = true;\n+\t\t\t\titem.activeInjected = true;\n+\t\t\t\titem.assistantBaseline = assistantBaseline;\n+\t\t\t\tcurrent = item;\n+\t\t\t}\n+\t\t\tif (current?.submitted && !current.settling) {\n+\t\t\t\tif (current.activeInjected) {\n+\t\t\t\t\tconst content = `${current.stub}\\n\\n${current.envelope}`;\n+\t\t\t\t\tif (\n+\t\t\t\t\t\t!messages.some(\n+\t\t\t\t\t\t\t(message) => message?.role === \"user\" && messageText(message) === content,\n+\t\t\t\t\t\t)\n+\t\t\t\t\t) {\n+\t\t\t\t\t\tmessages = [...messages, { role: \"user\", content }];\n+\t\t\t\t\t}\n+\t\t\t\t} else {\n+\t\t\t\t\tcurrent.assistantBaseline ??= assistantBaseline;\n+\t\t\t\t\tmessages = injectEnvelope(messages, current);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (messages !== event.messages) return { messages };\n+\t\t});\nSWAP.BLK 1764:\n+\t\tasync function dispatchShortforms(assistantOutput) {\n+\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n+\t\t\tif (shortforms.length === 0 || stopping) return;\n+\t\t\tconst deliveries = shortforms.flatMap((shortform) =>\n+\t\t\t\tshortform.targets.map((target) => ({ target, body: shortform.body })),\n+\t\t\t);\n+\t\t\tconst statuses = await Promise.all(\n+\t\t\t\tdeliveries.map(async ({ target, body }) => {\n+\t\t\t\t\tif (!id) return `${target}: failed (activate this OMP session first)`;\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], body, {\n+\t\t\t\t\t\t\ttimeoutMs: shortformCommandTimeoutMs,\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn `${target}: ${firstLine(result) || \"sent\"}`;\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\treturn `${target}: failed (${errorSummary(error)})`;\n+\t\t\t\t\t}\n+\t\t\t\t}),\n+\t\t\t);\n+\t\t\tif (stopping) return;\n+\t\t\ttry {\n+\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t{\n+\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n+\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n+\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t},\n+\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t);\n+\t\t\t} catch (error) {\n+\t\t\t\tif (!stopping) logError(\"omp-spt could not inject peer-message results\", error);\n+\t\t\t}\n+\t\t}\nSWAP.BLK 1800:\n+\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+\t\tasync function completeTurn(event) {\n+\t\t\tagentActive = false;\n+\t\t\tdesiredState = \"idle\";\n+\t\t\tif (stopping) return;\n+\t\t\tconst messages = event.messages ?? [];\n+\t\t\tconst completed = current;\n+\t\t\tconst turnBaseline = turnAssistantBaseline ?? knownAssistantCount;\n+\t\t\tconst completedBaseline = completed?.assistantBaseline ?? turnBaseline;\n+\t\t\tconst currentTurnReply = extractReplyAfterAssistantCount(messages, turnBaseline);\n+\t\t\tif (completed?.submitted && !completed.settled) {\n+\t\t\t\tconst reply = extractReplyAfterAssistantCount(messages, completedBaseline);\n+\t\t\t\ttry {\n+\t\t\t\t\tawait settleItem(\n+\t\t\t\t\t\tcompleted,\n+\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n+\t\t\t\t\t);\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tif (stopping) return;\n+\t\t\t\t\tawait failClosed(\n+\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n+\t\t\t\t\t\terror,\n+\t\t\t\t\t);\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (current === completed) {\n+\t\t\t\tcurrent = undefined;\n+\t\t\t\treleaseItem(completed);\n+\t\t\t}\n+\t\t\tknownAssistantCount = assistantMessageCount(messages);\n+\t\t\ttry {\n+\t\t\t\tawait setState(\"idle\");\n+\t\t\t} catch (error) {\n+\t\t\t\tif (stopping) return;\n+\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t\tawait dispatchShortforms(currentTurnReply);\n+\t\t\tif (!stopping) scheduleDispatch();\n+\t\t}\n*** End Patch\n","name":"edit"}]},"duration":29523.233899999876,"ttft":2488.839699999895,"contextSnapshot":{"promptTokens":218338,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_PLuNaft8SrjMteR5yANjOsOo|ctc_0dcdb11c56b27b75016a589e1c384081999f77c41d9a8b7399","toolName":"edit","startedAt":"2026-07-16T09:02:38.441Z"},"id":"8aa5d7ab","parentId":"9a75ccdb","timestamp":"2026-07-16T09:02:38.441Z"}
{"type":"message","id":"1225a59a","parentId":"8aa5d7ab","timestamp":"2026-07-16T09:02:38.532Z","message":{"role":"toolResult","toolCallId":"call_PLuNaft8SrjMteR5yANjOsOo|ctc_0dcdb11c56b27b75016a589e1c384081999f77c41d9a8b7399","toolName":"edit","content":[{"type":"text","text":"line 1: `SWAP.BLK 1714:` could not resolve a syntactic block beginning on line 1714 (unsupported language, blank/closer line, or parse error). Use `SWAP 1714.=M:` with explicit lines.\n\n 1712:\t\t\tblockSessionChange(\"session branch\", ctx),\n 1713:\t\t);\n*1714:\n 1715:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n 1716:\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]"}],"details":{},"isError":true,"timestamp":1784192558531}}
{"type":"message","id":"eefcae0a","parentId":"1225a59a","timestamp":"2026-07-16T09:02:45.670Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Reevaluating anchor due to line shifts**"},{"type":"toolCall","id":"call_cM31QAR9RCFPCFC8QDou6XEX|fc_0a86a86f2fd87987016a589e3563548199a8e495ba2e00e3a0","name":"read","arguments":{"i":"Regrounding lifecycle blocks","path":"adapter/strings/omp-spt.mjs","selector":"1710-1855"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2363,"output":65,"cacheRead":217600,"cacheWrite":0,"totalTokens":220028,"reasoningTokens":22,"cost":{"input":0.011815,"output":0.0019500000000000001,"cacheRead":0.1088,"cacheWrite":0,"total":0.122565}},"stopReason":"toolUse","timestamp":1784192558608,"responseId":"resp_0a86a86f2fd87987016a589e2f53a88199951d2b446fffb201","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0a86a86f2fd87987016a589e316630819997e8dcd659cf578d","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ41cTlbfVMOq53FATEph_pQ4Ij6ioIGG0ZAaDay4LGTN6Nwgs4Cp2wUrgp0wIIgJtw1G73Q_33tSWItJwxN9rWTrEmjI-v7OrxnDLn5RPCcidrqlmaM6rycFRCcg6bzvNe-65Ai_IpkeX1pUWc0ANjq2I__IIcUwvR8Ogo32hd-Fyt_fpN_1mcNtD7sySfBNYdG-mHnq4cuPpw-1Z-MrLEbI-b7pa0J6ZPGqMEiUQglx6QhxvHFBkZZkmRJeL8Cy4gaZhcmuV_lLDZ7tbM5L6xlthx0PJrlAI-7H_pMt23ESe0kBTD1fTIeAbspyyqCWbbboDCdcmOhM6-JbrNnLYU1LtIZtXUVFfvyJh5ZA_tJjoXDHDnt-wwqnnnYzVaBXdYyWJv7vP7lHrEfzywjfVkNLEbKvTyimvhvux5MdFZKGcIjtZYtb1gRhi8rXOFn09cHkRJIS10bSTFy6WWOOXKT0XyZu1GG3TOwwVb2EMRPMjGQaCGVMm7jFXw6nMdXQWP49_einrEJ97Z10IkfONg_Gu1ZPbWCk8i5AYf3OIQYACU7vGigv3VAUCSf_yS6lPuH7CQydzWaHuvbGCYIH4WS2RANMjaPvxBBwHwn8wPQs6iMShYOvygeNU2ZHV0MCBtwu3GOfcpOKTN94uCJo7X6QFMb9V73gep-Yd0Wa6a6AcG4LziGweC0AWscp0GzG0me6MvXYru5T1WyuFcy8XnLR5-00Iba816gpv7EV83sEIWCzRkwxCwc-r4SuBQzOM23ITAroRYEJk2KGsGytMpsLZ026e5gosegGsY0DlETaJ_cdPkleOHWb-MFLnJEpAD2dC3FIq1rm4S9tFkuDr99bqFaacHV7aQMFkGO3KYIj59L9TGCrPFHah3xqoqttCCShE2TSSAOQGxiNlcSVVxNRsQxTrjwciOfYcw9yIQCrZRL3qvSSd49ZIISYNJcdj-vm3NHx93NhMKYbjvB-ZWuvubJZK7OZtIG0SFVj2TFWDhjLo4wFToielyYkLjLydVL-rZAX6Bt7oYjwHh596OPgg==","summary":[{"type":"summary_text","text":"**Reevaluating anchor due to line shifts**"}]},{"id":"fc_0a86a86f2fd87987016a589e3563548199a8e495ba2e00e3a0","type":"function_call","status":"completed","arguments":"{\"i\":\"Regrounding lifecycle blocks\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1710-1855\"}","call_id":"call_cM31QAR9RCFPCFC8QDou6XEX","name":"read"}]},"duration":7060.903299999889,"ttft":2769.2305999998935,"contextSnapshot":{"promptTokens":219963,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_cM31QAR9RCFPCFC8QDou6XEX|fc_0a86a86f2fd87987016a589e3563548199a8e495ba2e00e3a0","toolName":"read","startedAt":"2026-07-16T09:02:45.670Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Regrounding lifecycle blocks"},"id":"f4adaa13","parentId":"eefcae0a","timestamp":"2026-07-16T09:02:45.670Z"}
{"type":"message","id":"a34ca695","parentId":"f4adaa13","timestamp":"2026-07-16T09:02:45.687Z","message":{"role":"toolResult","toolCallId":"call_cM31QAR9RCFPCFC8QDou6XEX|fc_0a86a86f2fd87987016a589e3563548199a8e495ba2e00e3a0","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#EB19]\n1708:\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n1709:\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\n1710:\t\t);\n1711:\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\n1712:\t\t\tblockSessionChange(\"session branch\", ctx),\n1713:\t\t);\n1714:\n1715:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n1716:\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n1717:\t\tpi.on(\"context\", (event) => {\n1718:\t\t\tlet messages = event.messages;\n1719:\t\t\tif (\n1720:\t\t\t\tagentActive &&\n1721:\t\t\t\t!current &&\n1722:\t\t\t\t!dispatching &&\n1723:\t\t\t\tqueue.length > 0\n1724:\t\t\t) {\n1725:\t\t\t\tconst item = queue.shift();\n1726:\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n1727:\t\t\t\titem.submitted = true;\n1728:\t\t\t\titem.activeInjected = true;\n1729:\t\t\t\tcurrent = item;\n1730:\t\t\t\tmessages = [\n1731:\t\t\t\t\t...messages,\n1732:\t\t\t\t\t{\n1733:\t\t\t\t\t\trole: \"user\",\n1734:\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n1735:\t\t\t\t\t},\n1736:\t\t\t\t];\n1737:\t\t\t}\n1738:\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n1739:\t\t\t\tmessages = injectEnvelope(messages, current);\n1740:\t\t\t}\n1741:\t\t\tif (messages !== event.messages) return { messages };\n1742:\t\t});\n1743:\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n1744:\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n1745:\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n1746:\t\tpi.on(\"before_agent_start\", async (event) => {\n1747:\t\t\tif (!activated || !id || stopping) return;\n1748:\t\t\tconst additions = [];\n1749:\t\t\tif (startupBriefPending) {\n1750:\t\t\t\tstartupBriefPending = false;\n1751:\t\t\t\tadditions.push(startupBrief(id));\n1752:\t\t\t}\n1753:\t\t\tconst hints = promptHints(event.prompt);\n1754:\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\n1755:\t\t\tif (updateNoticesPending) {\n1756:\t\t\t\tupdateNoticesPending = false;\n1757:\t\t\t\tconst notices = await updateNoticesPromise;\n1758:\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\n1759:\t\t\t}\n1760:\t\t\tif (additions.length === 0) return;\n1761:\t\t\treturn {\n1762:\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\n1763:\t\t\t};\n1764:\t\t});\n1765:\n1766:\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n1767:\t\tasync function dispatchShortforms(messages, afterUserMessage) {\n1768:\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\n1769:\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n1770:\t\t\tif (shortforms.length === 0) return;\n1771:\t\t\tconst statuses = [];\n1772:\t\t\tfor (const shortform of shortforms) {\n1773:\t\t\t\tfor (const target of shortform.targets) {\n1774:\t\t\t\t\tif (!id) {\n1775:\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\n1776:\t\t\t\t\t\tcontinue;\n1777:\t\t\t\t\t}\n1778:\t\t\t\t\ttry {\n1779:\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\n1780:\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\n1781:\t\t\t\t\t} catch (error) {\n1782:\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\n1783:\t\t\t\t\t}\n1784:\t\t\t\t}\n1785:\t\t\t}\n1786:\t\t\ttry {\n1787:\t\t\t\tpi.sendMessage(\n1788:\t\t\t\t\t{\n1789:\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n1790:\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n1791:\t\t\t\t\t\tdisplay: true,\n1792:\t\t\t\t\t\tattribution: \"user\",\n1793:\t\t\t\t\t},\n1794:\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n1795:\t\t\t\t);\n1796:\t\t\t} catch (error) {\n1797:\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\n1798:\t\t\t}\n1799:\t\t}\n1800:\n1801:\n1802:\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n1803:\t\tasync function completeTurn(event) {\n1804:\t\t\tagentActive = false;\n1805:\t\t\tdesiredState = \"idle\";\n1806:\t\t\tif (stopping) return;\n1807:\t\t\tconst messages = event.messages ?? [];\n1808:\t\t\tconst completed = current;\n1809:\t\t\tif (completed?.submitted && !completed.settled) {\n1810:\t\t\t\tconst reply = extractReply(messages, completed.stub);\n1811:\t\t\t\ttry {\n1812:\t\t\t\t\tawait settleItem(\n1813:\t\t\t\t\t\tcompleted,\n1814:\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n1815:\t\t\t\t\t);\n1816:\t\t\t\t} catch (error) {\n1817:\t\t\t\t\tif (stopping) return;\n1818:\t\t\t\t\tawait failClosed(\n1819:\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n1820:\t\t\t\t\t\terror,\n1821:\t\t\t\t\t);\n1822:\t\t\t\t\treturn;\n1823:\t\t\t\t}\n1824:\t\t\t}\n1825:\t\t\tawait dispatchShortforms(messages, completed?.stub);\n1826:\t\t\tif (current === completed) {\n1827:\t\t\t\tcurrent = undefined;\n1828:\t\t\t\treleaseItem(completed);\n1829:\t\t\t}\n1830:\t\t\ttry {\n1831:\t\t\t\tawait setState(\"idle\");\n1832:\t\t\t} catch (error) {\n1833:\t\t\t\tif (stopping) return;\n1834:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n1835:\t\t\t\treturn;\n1836:\t\t\t}\n1837:\t\t\tscheduleDispatch();\n1838:\t\t}\n1839:\n1840:\t\tpi.on(\"agent_start\", async () => {\n1841:\t\t\tif (stopping) return;\n1842:\t\t\tturnCompletionPromise = undefined;\n1843:\t\t\tagentActive = true;\n1844:\t\t\tdesiredState = \"busy\";\n1845:\t\t\ttry {\n1846:\t\t\t\tawait syncDesiredState();\n1847:\t\t\t} catch (error) {\n1848:\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\n1849:\t\t\t}\n1850:\t\t});\n1851:\n1852:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1853:\t\tpi.on(\"agent_end\", (event) => {\n1854:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1855:\t\t\treturn turnCompletionPromise;\n1856:\t\t});\n1857:\n1858:\t\tpi.on(\"session_stop\", async (event) => {\n…\n1861:\t\t});\n\n[Showing lines 1709-1858 of 1872. Use :1859 to continue]"}],"details":{"truncation":{"content":"\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tlet messages = event.messages;\r\n\t\t\tif (\r\n\t\t\t\tagentActive &&\r\n\t\t\t\t!current &&\r\n\t\t\t\t!dispatching &&\r\n\t\t\t\tqueue.length > 0\r\n\t\t\t) {\r\n\t\t\t\tconst item = queue.shift();\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\titem.activeInjected = true;\r\n\t\t\t\tcurrent = item;\r\n\t\t\t\tmessages = [\r\n\t\t\t\t\t...messages,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\trole: \"user\",\r\n\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}\r\n\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\r\n\t\t\t\tmessages = injectEnvelope(messages, current);\r\n\t\t\t}\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\r\n\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\r\n\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\r\n\t\tpi.on(\"before_agent_start\", async (event) => {\r\n\t\t\tif (!activated || !id || stopping) return;\r\n\t\t\tconst additions = [];\r\n\t\t\tif (startupBriefPending) {\r\n\t\t\t\tstartupBriefPending = false;\r\n\t\t\t\tadditions.push(startupBrief(id));\r\n\t\t\t}\r\n\t\t\tconst hints = promptHints(event.prompt);\r\n\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\r\n\t\t\tif (updateNoticesPending) {\r\n\t\t\t\tupdateNoticesPending = false;\r\n\t\t\t\tconst notices = await updateNoticesPromise;\r\n\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\r\n\t\t\t}\r\n\t\t\tif (additions.length === 0) return;\r\n\t\t\treturn {\r\n\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\r\n\t\tasync function dispatchShortforms(messages, afterUserMessage) {\r\n\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\r\n\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\r\n\t\t\tif (shortforms.length === 0) return;\r\n\t\t\tconst statuses = [];\r\n\t\t\tfor (const shortform of shortforms) {\r\n\t\t\t\tfor (const target of shortform.targets) {\r\n\t\t\t\t\tif (!id) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\r\n\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tpi.sendMessage(\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\r\n\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\r\n\t\t\t\t\t\tdisplay: true,\r\n\t\t\t\t\t\tattribution: \"user\",\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst messages = event.messages ?? [];\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tawait dispatchShortforms(messages, completed?.stub);\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r","truncated":true,"truncatedBy":"lines","totalLines":164,"totalBytes":4557,"outputLines":150,"outputBytes":4557,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\t\tpi.on(\"session_before_switch\", (event, ctx) =>\n\t\t\tblockSessionChange(`${event.reason} session switch`, ctx),\r\n\t\t);\r\n\t\tpi.on(\"session_before_branch\", (_event, ctx) =>\r\n\t\t\tblockSessionChange(\"session branch\", ctx),\r\n\t\t);\r\n\r\n\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\r\n\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\r\n\t\tpi.on(\"context\", (event) => {\r\n\t\t\tlet messages = event.messages;\r\n\t\t\tif (\r\n\t\t\t\tagentActive &&\r\n\t\t\t\t!current &&\r\n\t\t\t\t!dispatching &&\r\n\t\t\t\tqueue.length > 0\r\n\t\t\t) {\r\n\t\t\t\tconst item = queue.shift();\r\n\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\r\n\t\t\t\titem.submitted = true;\r\n\t\t\t\titem.activeInjected = true;\r\n\t\t\t\tcurrent = item;\r\n\t\t\t\tmessages = [\r\n\t\t\t\t\t...messages,\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\trole: \"user\",\r\n\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\r\n\t\t\t\t\t},\r\n\t\t\t\t];\r\n\t\t\t}\r\n\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\r\n\t\t\t\tmessages = injectEnvelope(messages, current);\r\n\t\t\t}\r\n\t\t\tif (messages !== event.messages) return { messages };\r\n\t\t});\r\n\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\r\n\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\r\n\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\r\n\t\tpi.on(\"before_agent_start\", async (event) => {\r\n\t\t\tif (!activated || !id || stopping) return;\r\n\t\t\tconst additions = [];\r\n\t\t\tif (startupBriefPending) {\r\n\t\t\t\tstartupBriefPending = false;\r\n\t\t\t\tadditions.push(startupBrief(id));\r\n\t\t\t}\r\n\t\t\tconst hints = promptHints(event.prompt);\r\n\t\t\tif (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);\r\n\t\t\tif (updateNoticesPending) {\r\n\t\t\t\tupdateNoticesPending = false;\r\n\t\t\t\tconst notices = await updateNoticesPromise;\r\n\t\t\t\tif (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);\r\n\t\t\t}\r\n\t\t\tif (additions.length === 0) return;\r\n\t\t\treturn {\r\n\t\t\t\tsystemPrompt: [...(event.systemPrompt ?? []), additions.join(\"\\n\\n\")],\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\r\n\t\tasync function dispatchShortforms(messages, afterUserMessage) {\r\n\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\r\n\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\r\n\t\t\tif (shortforms.length === 0) return;\r\n\t\t\tconst statuses = [];\r\n\t\t\tfor (const shortform of shortforms) {\r\n\t\t\t\tfor (const target of shortform.targets) {\r\n\t\t\t\t\tif (!id) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\r\n\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tpi.sendMessage(\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\r\n\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\r\n\t\t\t\t\t\tdisplay: true,\r\n\t\t\t\t\t\tattribution: \"user\",\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t\t\t\t);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\n\t\tasync function completeTurn(event) {\r\n\t\t\tagentActive = false;\r\n\t\t\tdesiredState = \"idle\";\r\n\t\t\tif (stopping) return;\r\n\t\t\tconst messages = event.messages ?? [];\r\n\t\t\tconst completed = current;\r\n\t\t\tif (completed?.submitted && !completed.settled) {\r\n\t\t\t\tconst reply = extractReply(messages, completed.stub);\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait settleItem(\r\n\t\t\t\t\t\tcompleted,\r\n\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\r\n\t\t\t\t\t);\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tif (stopping) return;\r\n\t\t\t\t\tawait failClosed(\r\n\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\r\n\t\t\t\t\t\terror,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tawait dispatchShortforms(messages, completed?.stub);\r\n\t\t\tif (current === completed) {\r\n\t\t\t\tcurrent = undefined;\r\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tscheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n…\n\t\t});","startLine":1708,"lineNumbers":[1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,null,1861]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1872,"totalBytes":4557,"outputLines":150,"outputBytes":4557,"shownRange":{"start":1709,"end":1858},"nextOffset":1859}}},"isError":false,"timestamp":1784192565686}}
{"type":"message","id":"bacdbc12","parentId":"a34ca695","timestamp":"2026-07-16T09:03:08.298Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Editing specific blocks 1717, 1767, 1803**"},{"type":"toolCall","id":"call_aiJEDA3UUcLuarVJD70gVt6R|ctc_031fe690f59c47e9016a589e39a70c81999ec80aca02e634cc","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#EB19]\nSWAP.BLK 1717:\n+\t\tpi.on(\"context\", (event) => {\n+\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n+\t\t\tturnAssistantBaseline ??= assistantBaseline;\n+\t\t\tlet messages = event.messages;\n+\t\t\tif (\n+\t\t\t\tagentActive &&\n+\t\t\t\t!current &&\n+\t\t\t\t!dispatching &&\n+\t\t\t\tqueue.length > 0\n+\t\t\t) {\n+\t\t\t\tconst item = queue.shift();\n+\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n+\t\t\t\titem.submitted = true;\n+\t\t\t\titem.activeInjected = true;\n+\t\t\t\titem.assistantBaseline = assistantBaseline;\n+\t\t\t\tcurrent = item;\n+\t\t\t}\n+\t\t\tif (current?.submitted && !current.settling) {\n+\t\t\t\tif (current.activeInjected) {\n+\t\t\t\t\tconst content = `${current.stub}\\n\\n${current.envelope}`;\n+\t\t\t\t\tif (\n+\t\t\t\t\t\t!messages.some(\n+\t\t\t\t\t\t\t(message) => message?.role === \"user\" && messageText(message) === content,\n+\t\t\t\t\t\t)\n+\t\t\t\t\t) {\n+\t\t\t\t\t\tmessages = [...messages, { role: \"user\", content }];\n+\t\t\t\t\t}\n+\t\t\t\t} else {\n+\t\t\t\t\tcurrent.assistantBaseline ??= assistantBaseline;\n+\t\t\t\t\tmessages = injectEnvelope(messages, current);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (messages !== event.messages) return { messages };\n+\t\t});\nSWAP.BLK 1767:\n+\t\tasync function dispatchShortforms(assistantOutput) {\n+\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n+\t\t\tif (shortforms.length === 0 || stopping) return;\n+\t\t\tconst deliveries = shortforms.flatMap((shortform) =>\n+\t\t\t\tshortform.targets.map((target) => ({ target, body: shortform.body })),\n+\t\t\t);\n+\t\t\tconst statuses = await Promise.all(\n+\t\t\t\tdeliveries.map(async ({ target, body }) => {\n+\t\t\t\t\tif (!id) return `${target}: failed (activate this OMP session first)`;\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], body, {\n+\t\t\t\t\t\t\ttimeoutMs: shortformCommandTimeoutMs,\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn `${target}: ${firstLine(result) || \"sent\"}`;\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\treturn `${target}: failed (${errorSummary(error)})`;\n+\t\t\t\t\t}\n+\t\t\t\t}),\n+\t\t\t);\n+\t\t\tif (stopping) return;\n+\t\t\ttry {\n+\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t{\n+\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n+\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n+\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t},\n+\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t);\n+\t\t\t} catch (error) {\n+\t\t\t\tif (!stopping) logError(\"omp-spt could not inject peer-message results\", error);\n+\t\t\t}\n+\t\t}\nSWAP.BLK 1803:\n+\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+\t\tasync function completeTurn(event) {\n+\t\t\tagentActive = false;\n+\t\t\tdesiredState = \"idle\";\n+\t\t\tif (stopping) return;\n+\t\t\tconst messages = event.messages ?? [];\n+\t\t\tconst completed = current;\n+\t\t\tconst turnBaseline = turnAssistantBaseline ?? knownAssistantCount;\n+\t\t\tconst completedBaseline = completed?.assistantBaseline ?? turnBaseline;\n+\t\t\tconst currentTurnReply = extractReplyAfterAssistantCount(messages, turnBaseline);\n+\t\t\tif (completed?.submitted && !completed.settled) {\n+\t\t\t\tconst reply = extractReplyAfterAssistantCount(messages, completedBaseline);\n+\t\t\t\ttry {\n+\t\t\t\t\tawait settleItem(\n+\t\t\t\t\t\tcompleted,\n+\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n+\t\t\t\t\t);\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tif (stopping) return;\n+\t\t\t\t\tawait failClosed(\n+\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n+\t\t\t\t\t\terror,\n+\t\t\t\t\t);\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (current === completed) {\n+\t\t\t\tcurrent = undefined;\n+\t\t\t\treleaseItem(completed);\n+\t\t\t}\n+\t\t\tknownAssistantCount = assistantMessageCount(messages);\n+\t\t\ttry {\n+\t\t\t\tawait setState(\"idle\");\n+\t\t\t} catch (error) {\n+\t\t\t\tif (stopping) return;\n+\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t\tawait dispatchShortforms(currentTurnReply);\n+\t\t\tif (!stopping) scheduleDispatch();\n+\t\t}\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":2120,"output":1082,"cacheRead":219648,"cacheWrite":0,"totalTokens":222850,"reasoningTokens":20,"cost":{"input":0.0106,"output":0.03246,"cacheRead":0.10982399999999999,"cacheWrite":0,"total":0.152884}},"stopReason":"toolUse","timestamp":1784192565742,"responseId":"resp_031fe690f59c47e9016a589e3626a8819983351e7e5a37a0c3","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_031fe690f59c47e9016a589e3878348199b49f7799bdec211f","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ45hPKUthbz_NLj9o4xm-_EWRPu7paqJ-0wDOSL3ZLjl1BHV3dprukHH-uraRdq7rKCbS30UV8k2iu-pklnF8lAbfliJzbPUyoDdQjOux-kPf6Fu_E6wHlrVLxui6C9S62S4JuWb8MIj7E2epzVXQ2uYgHjoiDYTQi0tUFD8daQxZ-3BPJ14mIUZ4C2esXTRaEhtkFlAy-T4BhvrtLz-SzcKKvGV467CKMy1kVv8PCvgfGdkGxiftGoSGjZY1QrdEr8leofxNd7eu1BLz05WFySiYsH1dHOsCPLzXjm0muyEjQyks529IN-9gDEiI59bMpfbU1CW2FVXuG4AkP6aMoSEW3a6Sj9NiPr2mhYZ9m9sR1lpq-7bZTO1XkGNUp80-i3SNtAN9VraM74SR-3oGXSvwNDOz81N7FgFCRrFJdU79_yzi7irzSPaaUM6wJjlTX_dulZwN7UsjbEEY3M4abTldqrJ2VoaI79MvQbzFevKrTf3t-w81BFFndB2IZqaTNhrmDClFUKNgxZ2AJ-ucpQtMeegRPw2q_lz0JN5TmWxT-eLmFOmjtMUcWA8Jb8wP52l4XJFAy37jmABZUxhYfU7CSG6vIV-rIY_3JAk448LH8B3Rb2RJPJo9EeSI6orvD5AFGCfO6A9ja7eMF2AlBHZH1Tea2qpfyxEErmetDPkEsmc1f6JWFMAkoMLcDSX3WnIlyRNyTcXy2VtqyEpjSdzdppFux86fwp-zydNsVMn67ilqt6GT70NgKB2s2cbO1ztkdjsL9AieO8tliWhikiYS1goshxZ_gWbo72dapdOCPEOytdku3t7nIlUemeAY-TTuRb2-3huqtDbWZMBeTzguEsH8j1yx-_T1YJiz2FCUVJufluMipHSXgOkMtdzEmVuVfjEwoVESePAvHWl7PVGjMKZEhAGpo2_WdHn_EO22tdNWZjqJXL9Zj6QkJL4cs86Dsd-3L3pbWL9cz2CWbDXQ==","summary":[{"type":"summary_text","text":"**Editing specific blocks 1717, 1767, 1803**"}]},{"id":"ctc_031fe690f59c47e9016a589e39a70c81999ec80aca02e634cc","type":"custom_tool_call","status":"completed","call_id":"call_aiJEDA3UUcLuarVJD70gVt6R","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#EB19]\nSWAP.BLK 1717:\n+\t\tpi.on(\"context\", (event) => {\n+\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n+\t\t\tturnAssistantBaseline ??= assistantBaseline;\n+\t\t\tlet messages = event.messages;\n+\t\t\tif (\n+\t\t\t\tagentActive &&\n+\t\t\t\t!current &&\n+\t\t\t\t!dispatching &&\n+\t\t\t\tqueue.length > 0\n+\t\t\t) {\n+\t\t\t\tconst item = queue.shift();\n+\t\t\t\titem.stub = senderStub(item.from ?? \"unknown\");\n+\t\t\t\titem.submitted = true;\n+\t\t\t\titem.activeInjected = true;\n+\t\t\t\titem.assistantBaseline = assistantBaseline;\n+\t\t\t\tcurrent = item;\n+\t\t\t}\n+\t\t\tif (current?.submitted && !current.settling) {\n+\t\t\t\tif (current.activeInjected) {\n+\t\t\t\t\tconst content = `${current.stub}\\n\\n${current.envelope}`;\n+\t\t\t\t\tif (\n+\t\t\t\t\t\t!messages.some(\n+\t\t\t\t\t\t\t(message) => message?.role === \"user\" && messageText(message) === content,\n+\t\t\t\t\t\t)\n+\t\t\t\t\t) {\n+\t\t\t\t\t\tmessages = [...messages, { role: \"user\", content }];\n+\t\t\t\t\t}\n+\t\t\t\t} else {\n+\t\t\t\t\tcurrent.assistantBaseline ??= assistantBaseline;\n+\t\t\t\t\tmessages = injectEnvelope(messages, current);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (messages !== event.messages) return { messages };\n+\t\t});\nSWAP.BLK 1767:\n+\t\tasync function dispatchShortforms(assistantOutput) {\n+\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n+\t\t\tif (shortforms.length === 0 || stopping) return;\n+\t\t\tconst deliveries = shortforms.flatMap((shortform) =>\n+\t\t\t\tshortform.targets.map((target) => ({ target, body: shortform.body })),\n+\t\t\t);\n+\t\t\tconst statuses = await Promise.all(\n+\t\t\t\tdeliveries.map(async ({ target, body }) => {\n+\t\t\t\t\tif (!id) return `${target}: failed (activate this OMP session first)`;\n+\t\t\t\t\ttry {\n+\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], body, {\n+\t\t\t\t\t\t\ttimeoutMs: shortformCommandTimeoutMs,\n+\t\t\t\t\t\t});\n+\t\t\t\t\t\treturn `${target}: ${firstLine(result) || \"sent\"}`;\n+\t\t\t\t\t} catch (error) {\n+\t\t\t\t\t\treturn `${target}: failed (${errorSummary(error)})`;\n+\t\t\t\t\t}\n+\t\t\t\t}),\n+\t\t\t);\n+\t\t\tif (stopping) return;\n+\t\t\ttry {\n+\t\t\t\tpi.sendMessage(\n+\t\t\t\t\t{\n+\t\t\t\t\t\tcustomType: \"omp-spt-peer-status\",\n+\t\t\t\t\t\tcontent: `OMP SPT peer-message results:\\n- ${statuses.join(\"\\n- \")}`,\n+\t\t\t\t\t\tdisplay: true,\n+\t\t\t\t\t\tattribution: \"user\",\n+\t\t\t\t\t},\n+\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n+\t\t\t\t);\n+\t\t\t} catch (error) {\n+\t\t\t\tif (!stopping) logError(\"omp-spt could not inject peer-message results\", error);\n+\t\t\t}\n+\t\t}\nSWAP.BLK 1803:\n+\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n+\t\tasync function completeTurn(event) {\n+\t\t\tagentActive = false;\n+\t\t\tdesiredState = \"idle\";\n+\t\t\tif (stopping) return;\n+\t\t\tconst messages = event.messages ?? [];\n+\t\t\tconst completed = current;\n+\t\t\tconst turnBaseline = turnAssistantBaseline ?? knownAssistantCount;\n+\t\t\tconst completedBaseline = completed?.assistantBaseline ?? turnBaseline;\n+\t\t\tconst currentTurnReply = extractReplyAfterAssistantCount(messages, turnBaseline);\n+\t\t\tif (completed?.submitted && !completed.settled) {\n+\t\t\t\tconst reply = extractReplyAfterAssistantCount(messages, completedBaseline);\n+\t\t\t\ttry {\n+\t\t\t\t\tawait settleItem(\n+\t\t\t\t\t\tcompleted,\n+\t\t\t\t\t\treply || failureMessage(\"turn ended without an assistant response\"),\n+\t\t\t\t\t);\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\tif (stopping) return;\n+\t\t\t\t\tawait failClosed(\n+\t\t\t\t\t\t`omp-spt could not send the outcome to ${completed.from ?? \"unknown\"}`,\n+\t\t\t\t\t\terror,\n+\t\t\t\t\t);\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (current === completed) {\n+\t\t\t\tcurrent = undefined;\n+\t\t\t\treleaseItem(completed);\n+\t\t\t}\n+\t\t\tknownAssistantCount = assistantMessageCount(messages);\n+\t\t\ttry {\n+\t\t\t\tawait setState(\"idle\");\n+\t\t\t} catch (error) {\n+\t\t\t\tif (stopping) return;\n+\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t\tawait dispatchShortforms(currentTurnReply);\n+\t\t\tif (!stopping) scheduleDispatch();\n+\t\t}\n*** End Patch\n","name":"edit"}]},"duration":22554.851199999917,"ttft":2714.618599999696,"contextSnapshot":{"promptTokens":221768,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_aiJEDA3UUcLuarVJD70gVt6R|ctc_031fe690f59c47e9016a589e39a70c81999ec80aca02e634cc","toolName":"edit","startedAt":"2026-07-16T09:03:08.299Z"},"id":"080b0259","parentId":"bacdbc12","timestamp":"2026-07-16T09:03:08.299Z"}
{"type":"message","id":"5ec2e27c","parentId":"080b0259","timestamp":"2026-07-16T09:03:08.345Z","message":{"role":"toolResult","toolCallId":"call_aiJEDA3UUcLuarVJD70gVt6R|ctc_031fe690f59c47e9016a589e39a70c81999ec80aca02e634cc","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#6778]\nSWAP.BLK 1717 → resolved lines 1717-1742 (26 lines)\nSWAP.BLK 1767 → resolved lines 1767-1799 (33 lines)\nSWAP.BLK 1803 → resolved lines 1803-1838 (36 lines)\n1716:\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n1717:\t\tpi.on(\"context\", (event) => {\n1718:\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n1719:\t\t\tturnAssistantBaseline ??= assistantBaseline;\n1720:\t\t\tlet messages = event.messages;\n1721:\t\t\tif (\n\n1726:\t\t\t) {\n\n1729:\t\t\t\titem.submitted = true;\n1730:\t\t\t\titem.activeInjected = true;\n1731:\t\t\t\titem.assistantBaseline = assistantBaseline;\n1732:\t\t\t\tcurrent = item;\n1733:\t\t\t}\n1734:\t\t\tif (current?.submitted && !current.settling) {\n1735:\t\t\t\tif (current.activeInjected) {\n…\n1746:\t\t\t\t\tmessages = injectEnvelope(messages, current);\n1747:\t\t\t\t}\n1748:\t\t\t}\n1749:\t\t\tif (messages !== event.messages) return { messages };\n1750:\t\t});\n\n1773:\n1774:\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n1775:\t\tasync function dispatchShortforms(assistantOutput) {\n1776:\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n1777:\t\t\tif (shortforms.length === 0 || stopping) return;\n1778:\t\t\tconst deliveries = shortforms.flatMap((shortform) =>\n…\n1782:\t\t\t\tdeliveries.map(async ({ target, body }) => {\n1783:\t\t\t\t\tif (!id) return `${target}: failed (activate this OMP session first)`;\n1784:\t\t\t\t\ttry {\n1785:\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], body, {\n1786:\t\t\t\t\t\t\ttimeoutMs: shortformCommandTimeoutMs,\n1787:\t\t\t\t\t\t});\n1788:\t\t\t\t\t\treturn `${target}: ${firstLine(result) || \"sent\"}`;\n1789:\t\t\t\t\t} catch (error) {\n1790:\t\t\t\t\t\treturn `${target}: failed (${errorSummary(error)})`;\n1791:\t\t\t\t\t}\n1792:\t\t\t\t}),\n1793:\t\t\t);\n1794:\t\t\tif (stopping) return;\n1795:\t\t\ttry {\n1796:\t\t\t\tpi.sendMessage(\n1804:\t\t\t\t);\n1805:\t\t\t} catch (error) {\n1806:\t\t\t\tif (!stopping) logError(\"omp-spt could not inject peer-message results\", error);\n1807:\t\t\t}\n1808:\t\t}\n\n1812:\t\tasync function completeTurn(event) {\n\n1816:\t\t\tconst messages = event.messages ?? [];\n1817:\t\t\tconst completed = current;\n1818:\t\t\tconst turnBaseline = turnAssistantBaseline ?? knownAssistantCount;\n1819:\t\t\tconst completedBaseline = completed?.assistantBaseline ?? turnBaseline;\n1820:\t\t\tconst currentTurnReply = extractReplyAfterAssistantCount(messages, turnBaseline);\n1821:\t\t\tif (completed?.submitted && !completed.settled) {\n1822:\t\t\t\tconst reply = extractReplyAfterAssistantCount(messages, completedBaseline);\n1823:\t\t\t\ttry {\n1824:\t\t\t\t\tawait settleItem(\n\n1827:\t\t\t\t\t);\n1828:\t\t\t\t} catch (error) {\n\n1835:\t\t\t\t}\n1836:\t\t\t}\n1837:\t\t\tif (current === completed) {\n1838:\t\t\t\tcurrent = undefined;\n1839:\t\t\t\treleaseItem(completed);\n1840:\t\t\t}\n1841:\t\t\tknownAssistantCount = assistantMessageCount(messages);\n1842:\t\t\ttry {\n1843:\t\t\t\tawait setState(\"idle\");\n1844:\t\t\t} catch (error) {\n\n1847:\t\t\t\treturn;\n1848:\t\t\t}\n1849:\t\t\tawait dispatchShortforms(currentTurnReply);\n1850:\t\t\tif (!stopping) scheduleDispatch();\n1851:\t\t}\n1852:\n\nWarnings:\nAuto-repaired a replacement boundary echo at line 1803: dropped 1 leading payload line(s) identical to the surviving line(s) just above the range. The range was one line short of the content you retyped — issue the payload as the final content for the selected range only, and widen the range to consume any keeper you restate."}],"details":{"diff":" 1716|\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n 1717|\t\tpi.on(\"context\", (event) => {\n+1718|\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n+1719|\t\t\tturnAssistantBaseline ??= assistantBaseline;\n 1718|\t\t\tlet messages = event.messages;\n 1719|\t\t\tif (\n\n 1724|\t\t\t) {\n\n 1727|\t\t\t\titem.submitted = true;\n 1728|\t\t\t\titem.activeInjected = true;\n+1731|\t\t\t\titem.assistantBaseline = assistantBaseline;\n 1729|\t\t\t\tcurrent = item;\n-1730|\t\t\t\tmessages = [\n-1731|\t\t\t\t\t...messages,\n-1732|\t\t\t\t\t{\n-1733|\t\t\t\t\t\trole: \"user\",\n-1734|\t\t\t\t\t\tcontent: `${item.stub}\\n\\n${item.envelope}`,\n-1735|\t\t\t\t\t},\n-1736|\t\t\t\t];\n 1737|\t\t\t}\n-1738|\t\t\tif (current?.submitted && !current.settling && !current.activeInjected) {\n-1739|\t\t\t\tmessages = injectEnvelope(messages, current);\n+1734|\t\t\tif (current?.submitted && !current.settling) {\n+1735|\t\t\t\tif (current.activeInjected) {\n+1736|\t\t\t\t\tconst content = `${current.stub}\\n\\n${current.envelope}`;\n+1737|\t\t\t\t\tif (\n+1738|\t\t\t\t\t\t!messages.some(\n+1739|\t\t\t\t\t\t\t(message) => message?.role === \"user\" && messageText(message) === content,\n+1740|\t\t\t\t\t\t)\n+1741|\t\t\t\t\t) {\n+1742|\t\t\t\t\t\tmessages = [...messages, { role: \"user\", content }];\n+1743|\t\t\t\t\t}\n+1744|\t\t\t\t} else {\n+1745|\t\t\t\t\tcurrent.assistantBaseline ??= assistantBaseline;\n+1746|\t\t\t\t\tmessages = injectEnvelope(messages, current);\n+1747|\t\t\t\t}\n 1740|\t\t\t}\n 1741|\t\t\tif (messages !== event.messages) return { messages };\n 1742|\t\t});\n\n 1765|\n 1766|\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n-1767|\t\tasync function dispatchShortforms(messages, afterUserMessage) {\n-1768|\t\t\tconst assistantOutput = extractReply(messages, afterUserMessage);\n+1775|\t\tasync function dispatchShortforms(assistantOutput) {\n 1769|\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n-1770|\t\t\tif (shortforms.length === 0) return;\n-1771|\t\t\tconst statuses = [];\n-1772|\t\t\tfor (const shortform of shortforms) {\n-1773|\t\t\t\tfor (const target of shortform.targets) {\n-1774|\t\t\t\t\tif (!id) {\n-1775|\t\t\t\t\t\tstatuses.push(`${target}: failed (activate this OMP session first)`);\n-1776|\t\t\t\t\t\tcontinue;\n-1777|\t\t\t\t\t}\n+1777|\t\t\tif (shortforms.length === 0 || stopping) return;\n+1778|\t\t\tconst deliveries = shortforms.flatMap((shortform) =>\n+1779|\t\t\t\tshortform.targets.map((target) => ({ target, body: shortform.body })),\n+1780|\t\t\t);\n+1781|\t\t\tconst statuses = await Promise.all(\n+1782|\t\t\t\tdeliveries.map(async ({ target, body }) => {\n+1783|\t\t\t\t\tif (!id) return `${target}: failed (activate this OMP session first)`;\n 1778|\t\t\t\t\ttry {\n-1779|\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], shortform.body);\n-1780|\t\t\t\t\t\tstatuses.push(`${target}: ${firstLine(result) || \"sent\"}`);\n+1785|\t\t\t\t\t\tconst result = await runCommand([\"send\", target, \"--from\", id], body, {\n+1786|\t\t\t\t\t\t\ttimeoutMs: shortformCommandTimeoutMs,\n+1787|\t\t\t\t\t\t});\n+1788|\t\t\t\t\t\treturn `${target}: ${firstLine(result) || \"sent\"}`;\n 1781|\t\t\t\t\t} catch (error) {\n-1782|\t\t\t\t\t\tstatuses.push(`${target}: failed (${errorSummary(error)})`);\n+1790|\t\t\t\t\t\treturn `${target}: failed (${errorSummary(error)})`;\n 1783|\t\t\t\t\t}\n-1784|\t\t\t\t}\n-1785|\t\t\t}\n+1792|\t\t\t\t}),\n+1793|\t\t\t);\n+1794|\t\t\tif (stopping) return;\n 1786|\t\t\ttry {\n 1787|\t\t\t\tpi.sendMessage(\n 1795|\t\t\t\t);\n 1796|\t\t\t} catch (error) {\n-1797|\t\t\t\tlogError(\"omp-spt could not inject peer-message results\", error);\n+1806|\t\t\t\tif (!stopping) logError(\"omp-spt could not inject peer-message results\", error);\n 1798|\t\t\t}\n 1799|\t\t}\n\n 1803|\t\tasync function completeTurn(event) {\n\n 1807|\t\t\tconst messages = event.messages ?? [];\n 1808|\t\t\tconst completed = current;\n+1818|\t\t\tconst turnBaseline = turnAssistantBaseline ?? knownAssistantCount;\n+1819|\t\t\tconst completedBaseline = completed?.assistantBaseline ?? turnBaseline;\n+1820|\t\t\tconst currentTurnReply = extractReplyAfterAssistantCount(messages, turnBaseline);\n 1809|\t\t\tif (completed?.submitted && !completed.settled) {\n-1810|\t\t\t\tconst reply = extractReply(messages, completed.stub);\n+1822|\t\t\t\tconst reply = extractReplyAfterAssistantCount(messages, completedBaseline);\n 1811|\t\t\t\ttry {\n 1812|\t\t\t\t\tawait settleItem(\n\n 1815|\t\t\t\t\t);\n 1816|\t\t\t\t} catch (error) {\n\n 1823|\t\t\t\t}\n 1824|\t\t\t}\n-1825|\t\t\tawait dispatchShortforms(messages, completed?.stub);\n 1826|\t\t\tif (current === completed) {\n 1827|\t\t\t\tcurrent = undefined;\n 1828|\t\t\t\treleaseItem(completed);\n 1829|\t\t\t}\n+1841|\t\t\tknownAssistantCount = assistantMessageCount(messages);\n 1830|\t\t\ttry {\n 1831|\t\t\t\tawait setState(\"idle\");\n 1832|\t\t\t} catch (error) {\n\n 1835|\t\t\t\treturn;\n 1836|\t\t\t}\n-1837|\t\t\tscheduleDispatch();\n+1849|\t\t\tawait dispatchShortforms(currentTurnReply);\n+1850|\t\t\tif (!stopping) scheduleDispatch();\n 1838|\t\t}\n 1839|","firstChangedLine":1717,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192588345}}
{"type":"message","id":"cd87be24","parentId":"5ec2e27c","timestamp":"2026-07-16T09:03:15.534Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Resetting agent baseline and editing turnCompletion**"},{"type":"toolCall","id":"call_lZyCryBZAC33MHwcSJSGMA0D|fc_0b2296ee8253e204016a589e53048c819b94989617bb3f34fb","name":"read","arguments":{"i":"Reading agent lifecycle after correlation fix","path":"adapter/strings/omp-spt.mjs","selector":"1840-1885"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":3138,"output":78,"cacheRead":220672,"cacheWrite":0,"totalTokens":223888,"reasoningTokens":34,"cost":{"input":0.015690000000000003,"output":0.00234,"cacheRead":0.11033599999999999,"cacheWrite":0,"total":0.12836599999999998}},"stopReason":"toolUse","timestamp":1784192588909,"responseId":"resp_0b2296ee8253e204016a589e4d7b44819b9d2db173dd8dd46d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0b2296ee8253e204016a589e51df24819b9106e4cc2470d1f2","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ5TEDF-GUGiNXoLq3LkCHn-kFs0y58JAmWNt1VfHo2owFIX1TqjOATkyydZIWNeEDJXblsU_Vi-EQWXzvKhbQ_GFrlBIAWQZKFTXu9VJx4z3RSqHp_npLktTxT-jrHnXKnzr6z9SPt2f-xyca9IlOvwSJaA4H2WfDqxyyX7W0tfGxdh4c0b4ys-l8JaHX2_MBCnGjlCSHqwKmPc7_PnzAnRPty18GEAD56dRmL6xMcDuUQ2DT9alcDwBkxOWfoJHl6tlVKu7WAvuWEOB7EDOQq6PqaIcf1wIRntcHX0brazCkZNCJZm-nOhHUloFHtGJIUOwsCTIbiTVDokNM3v4yLlAW2w6OkxSup3rSh1Q68chAy-ARj3jezUG2QfJ9hAEHGyVqE1Uy1IBfSS6J0Uqu7RfTyssj4GIkVwKTtiHnthNywj4cTCbvJZBlTRjCgJazyxQ8xl1eDoydRqPTBqSjgRRJOcqCQc2oCgYS7U0t0uydIpvk6bjhRW7Ln7h4XYt182PndJbEs_izv-MoeSbk71GGu11l7jIVAojqtRyy-0EU3lJHL82hhZ61HdNh-t11c4MU7szPU6_mLoojO3XPJOL3GgA6oCZjf4NKrNr13hRqySXIh1iGoQ2hyN4cwWBXXyg6wf0SecMS_4x1jpbUOv6_2Ir5804CR8EGAX3vpKxcu2nubcz25A9gtc1TCDu1AAsDNl8yu5VaNI7Mu8vIkNModx4CKvx8Z2yPTJ9cpVqwmdSCZKz3bfsPJYHyZARdA2Z2Ac_9PND-kaUI6QrT5mqvSuk4yo-DBNQ2VI-O7dERsexi548mvjtC4oGmWa7KL8wJneryVnyPSH1xbuV86TG-o505MP8TdmUzHdUX3LCItpfK0tMyEjwHcRxNpxbPh9fQ0dXvSyJsv36abC-XyXgj00q9JmfTKXmg23342D_pjKRQqx-8nVp8JRxw8i6cxX6gR63RG65gunW69lqDI0MvDnVfFhRAPHgp1ZOKahRHUiz4ELCSGjThOtYVCAPc1-kZTUlhVI6zyDwL1wsfnqfpunSn4cb_3XWWQ7nTYaOt4XW-fAx56oc6AN1fOupS8pVHE95kNuawVbngjjK3N_P1YwhVPg3tx44S7iq91_-n4=","summary":[{"type":"summary_text","text":"**Resetting agent baseline and editing turnCompletion**"}]},{"id":"fc_0b2296ee8253e204016a589e53048c819b94989617bb3f34fb","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading agent lifecycle after correlation fix\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1840-1885\"}","call_id":"call_lZyCryBZAC33MHwcSJSGMA0D","name":"read"}]},"duration":6623.343400000129,"ttft":4957.066800000146,"contextSnapshot":{"promptTokens":223810,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_lZyCryBZAC33MHwcSJSGMA0D|fc_0b2296ee8253e204016a589e53048c819b94989617bb3f34fb","toolName":"read","startedAt":"2026-07-16T09:03:15.534Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading agent lifecycle after correlation fix"},"id":"70037655","parentId":"cd87be24","timestamp":"2026-07-16T09:03:15.534Z"}
{"type":"message","id":"5be28e64","parentId":"70037655","timestamp":"2026-07-16T09:03:15.549Z","message":{"role":"toolResult","toolCallId":"call_lZyCryBZAC33MHwcSJSGMA0D|fc_0b2296ee8253e204016a589e53048c819b94989617bb3f34fb","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#6778]\n551:export function createOmpSpt(overrides = {}) {\n…\n693:\treturn function ompSpt(pi) {\n…\n1812:\t\tasync function completeTurn(event) {\n…\n1837:\t\t\tif (current === completed) {\n…\n1839:\t\t\t\treleaseItem(completed);\n1840:\t\t\t}\n1841:\t\t\tknownAssistantCount = assistantMessageCount(messages);\n1842:\t\t\ttry {\n1843:\t\t\t\tawait setState(\"idle\");\n1844:\t\t\t} catch (error) {\n1845:\t\t\t\tif (stopping) return;\n1846:\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\n1847:\t\t\t\treturn;\n1848:\t\t\t}\n1849:\t\t\tawait dispatchShortforms(currentTurnReply);\n1850:\t\t\tif (!stopping) scheduleDispatch();\n1851:\t\t}\n1852:\n1853:\t\tpi.on(\"agent_start\", async () => {\n1854:\t\t\tif (stopping) return;\n1855:\t\t\tturnCompletionPromise = undefined;\n1856:\t\t\tagentActive = true;\n1857:\t\t\tdesiredState = \"busy\";\n1858:\t\t\ttry {\n1859:\t\t\t\tawait syncDesiredState();\n1860:\t\t\t} catch (error) {\n1861:\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\n1862:\t\t\t}\n1863:\t\t});\n1864:\n1865:\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\n1866:\t\tpi.on(\"agent_end\", (event) => {\n1867:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1868:\t\t\treturn turnCompletionPromise;\n1869:\t\t});\n1870:\n1871:\t\tpi.on(\"session_stop\", async (event) => {\n1872:\t\t\tturnCompletionPromise ??= completeTurn(event);\n1873:\t\t\tawait turnCompletionPromise;\n1874:\t\t});\n1875:\n1876:\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n1877:\t\t\truntimeCtx ??= ctx;\n1878:\t\t\tui?.setStatus(\"omp-spt\", undefined);\n1879:\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\n1880:\t\t});\n1881:\t};\n1882:}\n1883:\n1884:export default createOmpSpt();\n1885:"}],"details":{"displayContent":{"text":"export function createOmpSpt(overrides = {}) {\n…\n\treturn function ompSpt(pi) {\n…\n\t\tasync function completeTurn(event) {\n…\n\t\t\tif (current === completed) {\n…\n\t\t\t\treleaseItem(completed);\r\n\t\t\t}\r\n\t\t\tknownAssistantCount = assistantMessageCount(messages);\r\n\t\t\ttry {\r\n\t\t\t\tawait setState(\"idle\");\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (stopping) return;\r\n\t\t\t\tawait failClosed(\"omp-spt could not mark the endpoint idle\", error);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tawait dispatchShortforms(currentTurnReply);\r\n\t\t\tif (!stopping) scheduleDispatch();\r\n\t\t}\r\n\r\n\t\tpi.on(\"agent_start\", async () => {\r\n\t\t\tif (stopping) return;\r\n\t\t\tturnCompletionPromise = undefined;\r\n\t\t\tagentActive = true;\r\n\t\t\tdesiredState = \"busy\";\r\n\t\t\ttry {\r\n\t\t\t\tawait syncDesiredState();\r\n\t\t\t} catch (error) {\r\n\t\t\t\tif (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-OMP-EXTENSION-CUSTODY]\r\n\t\tpi.on(\"agent_end\", (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\treturn turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_stop\", async (event) => {\r\n\t\t\tturnCompletionPromise ??= completeTurn(event);\r\n\t\t\tawait turnCompletionPromise;\r\n\t\t});\r\n\r\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\r\n\t\t\truntimeCtx ??= ctx;\r\n\t\t\tui?.setStatus(\"omp-spt\", undefined);\r\n\t\t\tawait shutdownWithinBudget(\"OMP session shut down before your message could complete\");\r\n\t\t});\r\n\t};\r\n}\r\n\r\nexport default createOmpSpt();\r\n","startLine":551,"lineNumbers":[551,null,693,null,1812,null,1837,null,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"}}},"isError":false,"timestamp":1784192595549}}
{"type":"message","id":"d8b6812a","parentId":"5be28e64","timestamp":"2026-07-16T09:03:20.300Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding reset functionality**"},{"type":"toolCall","id":"call_as1ey93pGrDaxT6hPktzLQIE|ctc_0daf1680e8a9ad75016a589e57eeb48199acf59ee68e058ba0","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#6778]\nINS.POST 1855:\n+\t\t\tturnAssistantBaseline = undefined;\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1707,"output":56,"cacheRead":222720,"cacheWrite":0,"totalTokens":224483,"reasoningTokens":7,"cost":{"input":0.008535000000000001,"output":0.00168,"cacheRead":0.11136,"cacheWrite":0,"total":0.121575}},"stopReason":"toolUse","timestamp":1784192595567,"responseId":"resp_0daf1680e8a9ad75016a589e5400a8819982fdcaa3545b7738","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0daf1680e8a9ad75016a589e5628288199b3d0983d1f9b0888","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ5XsVCEX6puYeE7frOpUao2Qhxv79KMI4CwSZPMOajfoo7ukqKF2moO4HhJO2R5ladX6m7cn2nPO7wMBnqMx8U89R6eOIYYTS9Wy3xg8Zt76P5TM64IeZLeUO3sBXbBgu-mhONWVd0n6IqdhFNQcDeXH-_ZcIkDz4rxvs80vYkQba4tuyVxZsl5X-kjY40BGM-2SY9uXCFcWhSUbiCteEZ-qW3tlotqsUivZC6GVzm-1KgWZ3aSO8TVGLux4CV0CJuBh_NY_B8zqQQg7yA4zMn4WfWyQIun6mILQEa8Oj1RNxoqoxp44hj9BJkOht9eQxcomy8Rlma5MZ1GE9Mx-IpyWcZxBSCOcOle81LbE1QlOQkmJiIrjO4QXqcNmWNJWYP-4icLiwCX0i9nnWikgj4eXc-8wttKCU0sk-FZj_uysKh2LxNIyZXWIHXiRyhf3VoqQthC2q7jhn-B3QLhcof0Xu-zxE0dloOsVGMFg9Hqs6r64_fyoM7MwqR_4poRW-BvugzfLoucowt3_-OVeYZ6QnqntkzrsXWqtNa2yflifx7yPUbHAfQFeC-ngZsJ0FuKbTjMrYJVINdBOnduKgMfHyoR5lmDu92x_mpMKovG6cG9D-OVQKpcr901B2fXkU_OfQgf7q-pXq2wbP5nGDEOxSaLeTMbO1Je5YmFOIP72NnfIad40qaxoIqa5aP9HayvjFV04LgiDbUYWbHgoBBxQs_obyyhaQzj4EhiycXGidY7xyMlyXLD_xNMWaEMxQE07IfAG40ohY6bJdQqhB48IBvip0F5JN14BQ58eG3K4WJKwXbCgH1Qk5m8sTmE8b5G0pUv1XYptQCJ7BBp_CcZ1pxFcscYP1E3Rg84QHRzC5WY4ucUvIBB2g7LEwjwVMEgVhtywumMxjSlTIMrcboxRms5XsW26Zoqm-XNuK9zlpU=","summary":[{"type":"summary_text","text":"**Adding reset functionality**"}]},{"id":"ctc_0daf1680e8a9ad75016a589e57eeb48199acf59ee68e058ba0","type":"custom_tool_call","status":"completed","call_id":"call_as1ey93pGrDaxT6hPktzLQIE","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#6778]\nINS.POST 1855:\n+\t\t\tturnAssistantBaseline = undefined;\n*** End Patch\n","name":"edit"}]},"duration":4732.115900000092,"ttft":2569.2058999999426,"contextSnapshot":{"promptTokens":224427,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_as1ey93pGrDaxT6hPktzLQIE|ctc_0daf1680e8a9ad75016a589e57eeb48199acf59ee68e058ba0","toolName":"edit","startedAt":"2026-07-16T09:03:20.301Z"},"id":"84d60ab7","parentId":"d8b6812a","timestamp":"2026-07-16T09:03:20.301Z"}
{"type":"message","id":"94322cf8","parentId":"84d60ab7","timestamp":"2026-07-16T09:03:20.335Z","message":{"role":"toolResult","toolCallId":"call_as1ey93pGrDaxT6hPktzLQIE|ctc_0daf1680e8a9ad75016a589e57eeb48199acf59ee68e058ba0","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#6AFA]\n1854:\t\t\tif (stopping) return;\n1855:\t\t\tturnCompletionPromise = undefined;\n1856:\t\t\tturnAssistantBaseline = undefined;\n1857:\t\t\tagentActive = true;\n1858:\t\t\tdesiredState = \"busy\";"}],"details":{"diff":" 1854|\t\t\tif (stopping) return;\n 1855|\t\t\tturnCompletionPromise = undefined;\n+1856|\t\t\tturnAssistantBaseline = undefined;\n 1856|\t\t\tagentActive = true;\n 1857|\t\t\tdesiredState = \"busy\";","firstChangedLine":1855,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192600334}}
{"type":"message","id":"27128b43","parentId":"94322cf8","timestamp":"2026-07-16T09:03:29.219Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Identifying type resolution blockage**"},{"type":"toolCall","id":"call_FhRJokbAwfouIjqJiKf5E0Ut|fc_086adf3d72b97917016a589e60eec8819a9ae2e443326ae3ac","name":"read","arguments":{"i":"Reading checkpoint tool implementation","path":"adapter/strings/omp-spt.mjs","selector":"1120-1205"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":818,"output":55,"cacheRead":223744,"cacheWrite":0,"totalTokens":224617,"reasoningTokens":13,"cost":{"input":0.004090000000000001,"output":0.00165,"cacheRead":0.111872,"cacheWrite":0,"total":0.117612}},"stopReason":"toolUse","timestamp":1784192600351,"responseId":"resp_086adf3d72b97917016a589e58bb68819aa2e2729eda0d3781","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_086adf3d72b97917016a589e5f5aa8819a80cbeb6bc39af9ae","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ5gdTQNq4rdRCXHAwcmGhyfi4AdUieJyL5CNQzEzuuGQ-mJLZp4ZLFYvmpMJSh2j_HhrMq8ntD1cC5r4sS3htg-BZPZ84sA4mgG6jf8FY__RzixVA7zqKIPEneFRl8xkURlswL0L0esKB9XPvzEC75i8hDvgquhP-ssIaq27s9W3vN3Gsyn3HKpRea-E2tsc-CIqZpt36bBslH639tiYm-ooD6Q-lohjrohtd6-qo5KpWG85OLS9O2pPgAHFkO1w05lbRHW6FfVd9ezTNAS49iTGn4459VdVjv1iV8CRIRIrmVpF8V596wNhF9gH_NWbHMdfgxiwLBC1qFZov-FeSlFBrcJJeSxA3kvXBZJysazyxFMDYh9_fWGBfI4M8fIiJpye325EWb9i1Z5D3VVH67mhgxFszqpnrqbK7HO-VI0rhD-QnoaBxFOqT0zu1JndaIJMAhbwhxY70vNsUFIKll59BoB1Kj-dvAjowDfFNUbGxba8YUCQ6UYdH29S84d_OTs1kQEw34cdLOSSvCIaKgm5VdHkeAWkcAJMP9xejmT1uZW1m51USsney-zizDoK_2tUAFYlKmalu54d6ZCgVIZkWusIOwxeR5eYJ2V1VUylmsCZpiUVr1E9Ydkgs5yF_6oRpq2S5tQvLbE2cDzWl13FWVn16D409tP9hoKFvAeEb4G7NeIBIPAZuURGLFeKXFIPesfoAIXHznNvvN-Cg-bo0znySv76YnJWNOZX1YviZK2VQa5HkWRBie4ugpduZy2xRuN7CuAdeRPYyJLmbqhiZL0quirbsojLzGOhQFGSqJZQo8UVAxq7ld9uh-F60ORPmmDdnQ-khMY8OHU2i0qB3ZYZCyrL529tjmxDMg80UF95gIQyYGAJyr5r1BKumDEKD4n3kJQ12hXP8ZgK6N58rvLj8vFgcFEskIy0F0oB9LwtQ28o3TRb-GgmsRFA7BwshPFkRe6YGycseudQO0B0nTvYIUQN6SayNbQWm0mfcI=","summary":[{"type":"summary_text","text":"**Identifying type resolution blockage**"}]},{"id":"fc_086adf3d72b97917016a589e60eec8819a9ae2e443326ae3ac","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading checkpoint tool implementation\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1120-1205\"}","call_id":"call_FhRJokbAwfouIjqJiKf5E0Ut","name":"read"}]},"duration":8867.658999999985,"ttft":6982.812200000044,"contextSnapshot":{"promptTokens":224562,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_FhRJokbAwfouIjqJiKf5E0Ut|fc_086adf3d72b97917016a589e60eec8819a9ae2e443326ae3ac","toolName":"read","startedAt":"2026-07-16T09:03:29.220Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading checkpoint tool implementation"},"id":"4973ca8c","parentId":"27128b43","timestamp":"2026-07-16T09:03:29.220Z"}
{"type":"message","id":"a9d27833","parentId":"4973ca8c","timestamp":"2026-07-16T09:03:29.235Z","message":{"role":"toolResult","toolCallId":"call_FhRJokbAwfouIjqJiKf5E0Ut|fc_086adf3d72b97917016a589e60eec8819a9ae2e443326ae3ac","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#6AFA]\n1116:\t\tpi.registerCommand(\"ready\", {\n…\n1119:\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n1120:\t\t});\n1121:\n1122:\t\tpi.registerCommand(\"live\", {\n1123:\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\n1124:\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\n1125:\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n1126:\t\t});\n1127:\n1128:\t\t// [impl->REQ-PARITY-CHECKPOINT]\n1129:\t\tpi.registerTool({\n1130:\t\t\tname: \"spt_checkpoint\",\n1131:\t\t\tlabel: \"SPT Checkpoint\",\n1132:\t\t\tdescription:\n1133:\t\t\t\t\"After the commune skill has saved this live endpoint's continuity drop, compact native OMP context and wake the same endpoint.\",\n1134:\t\t\tparameters: checkpointParameters(pi),\n1135:\t\t\tasync execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {\n1136:\t\t\t\tif (!activated || !id) {\n1137:\t\t\t\t\treturn {\n1138:\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"SPT checkpoint failed: no active endpoint.\" }],\n1139:\t\t\t\t\t\tdetails: { ok: false, reason: \"not-activated\" },\n1140:\t\t\t\t\t\tisError: true,\n1141:\t\t\t\t\t};\n1142:\t\t\t\t}\n1143:\t\t\t\tif (activationType === \"ready_agent\") {\n1144:\t\t\t\t\treturn {\n1145:\t\t\t\t\t\tcontent: [\n1146:\t\t\t\t\t\t\t{\n1147:\t\t\t\t\t\t\t\ttype: \"text\",\n1148:\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n1149:\t\t\t\t\t\t\t},\n1150:\t\t\t\t\t\t],\n1151:\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\n1152:\t\t\t\t\t\tisError: true,\n1153:\t\t\t\t\t};\n1154:\t\t\t\t}\n1155:\t\t\t\tconst wake =\n1156:\t\t\t\t\tparameters.wake?.trim() ||\n1157:\t\t\t\t\t\"Resume from the saved commune context and continue the prior work.\";\n1158:\t\t\t\ttry {\n1159:\t\t\t\t\tawait ctx.compact({\n1160:\t\t\t\t\t\tinternalGuidance:\n1161:\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n1162:\t\t\t\t\t});\n1163:\t\t\t\t\tpi.sendMessage(\n1164:\t\t\t\t\t\t{\n1165:\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n1166:\t\t\t\t\t\t\tcontent: wake,\n1167:\t\t\t\t\t\t\tdisplay: true,\n1168:\t\t\t\t\t\t\tattribution: \"user\",\n1169:\t\t\t\t\t\t},\n1170:\t\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\n1171:\t\t\t\t\t);\n1172:\t\t\t\t\treturn {\n1173:\t\t\t\t\t\tcontent: [\n1174:\t\t\t\t\t\t\t{\n1175:\t\t\t\t\t\t\t\ttype: \"text\",\n1176:\t\t\t\t\t\t\t\ttext: `SPT checkpoint complete for ${id}; native continuation queued.`,\n1177:\t\t\t\t\t\t\t},\n1178:\t\t\t\t\t\t],\n1179:\t\t\t\t\t\tdetails: { ok: true, endpoint: id },\n1180:\t\t\t\t\t};\n1181:\t\t\t\t} catch (error) {\n1182:\t\t\t\t\treturn {\n1183:\t\t\t\t\t\tcontent: [\n1184:\t\t\t\t\t\t\t{\n1185:\t\t\t\t\t\t\t\ttype: \"text\",\n1186:\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: ${errorSummary(error)}`,\n1187:\t\t\t\t\t\t\t},\n1188:\t\t\t\t\t\t],\n1189:\t\t\t\t\t\tdetails: { ok: false, reason: errorSummary(error) },\n1190:\t\t\t\t\t\tisError: true,\n1191:\t\t\t\t\t};\n1192:\t\t\t\t}\n1193:\t\t\t},\n1194:\t\t});\n1195:\n1196:\n1197:\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\n1198:\t\t\tfor (const [controller, active] of activeCommands) {\n1199:\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\n1200:\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\n1201:\t\t\t\t\tactive.abortTimer = setTimer(\n1202:\t\t\t\t\t\t() => controller.abort(reason),\n1203:\t\t\t\t\t\tshutdownCommandTimeoutMs,\n1204:\t\t\t\t\t);\n1205:\t\t\t\t\tactive.abortTimer?.unref?.();\n1206:\t\t\t\t\tcontinue;\n1207:\t\t\t\t}\n1208:\t\t\t\tcontroller.abort(reason);\n1209:\t\t\t}\n1210:\t\t}\n\n[Showing lines 1119-1208 of 1886. Use :1209 to continue]"}],"details":{"truncation":{"content":"\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\r\n\t\t});\r\n\r\n\t\tpi.registerCommand(\"live\", {\r\n\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\r\n\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\r\n\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-PARITY-CHECKPOINT]\r\n\t\tpi.registerTool({\r\n\t\t\tname: \"spt_checkpoint\",\r\n\t\t\tlabel: \"SPT Checkpoint\",\r\n\t\t\tdescription:\r\n\t\t\t\t\"After the commune skill has saved this live endpoint's continuity drop, compact native OMP context and wake the same endpoint.\",\r\n\t\t\tparameters: checkpointParameters(pi),\r\n\t\t\tasync execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {\r\n\t\t\t\tif (!activated || !id) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"SPT checkpoint failed: no active endpoint.\" }],\r\n\t\t\t\t\t\tdetails: { ok: false, reason: \"not-activated\" },\r\n\t\t\t\t\t\tisError: true,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t\tif (activationType === \"ready_agent\") {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\ttype: \"text\",\r\n\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t],\r\n\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\r\n\t\t\t\t\t\tisError: true,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t\tconst wake =\r\n\t\t\t\t\tparameters.wake?.trim() ||\r\n\t\t\t\t\t\"Resume from the saved commune context and continue the prior work.\";\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait ctx.compact({\r\n\t\t\t\t\t\tinternalGuidance:\r\n\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\r\n\t\t\t\t\t});\r\n\t\t\t\t\tpi.sendMessage(\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\r\n\t\t\t\t\t\t\tcontent: wake,\r\n\t\t\t\t\t\t\tdisplay: true,\r\n\t\t\t\t\t\t\tattribution: \"user\",\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\ttype: \"text\",\r\n\t\t\t\t\t\t\t\ttext: `SPT checkpoint complete for ${id}; native continuation queued.`,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t],\r\n\t\t\t\t\t\tdetails: { ok: true, endpoint: id },\r\n\t\t\t\t\t};\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\ttype: \"text\",\r\n\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: ${errorSummary(error)}`,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t],\r\n\t\t\t\t\t\tdetails: { ok: false, reason: errorSummary(error) },\r\n\t\t\t\t\t\tisError: true,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t});\r\n\r\n\r\n\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\r\n\t\t\tfor (const [controller, active] of activeCommands) {\r\n\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\r\n\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\r\n\t\t\t\t\tactive.abortTimer = setTimer(\r\n\t\t\t\t\t\t() => controller.abort(reason),\r\n\t\t\t\t\t\tshutdownCommandTimeoutMs,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tactive.abortTimer?.unref?.();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tcontroller.abort(reason);\r","truncated":true,"truncatedBy":"lines","totalLines":768,"totalBytes":2766,"outputLines":90,"outputBytes":2766,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\t\tpi.registerCommand(\"ready\", {\n…\n\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\r\n\t\t});\r\n\r\n\t\tpi.registerCommand(\"live\", {\r\n\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\r\n\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\r\n\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\r\n\t\t});\r\n\r\n\t\t// [impl->REQ-PARITY-CHECKPOINT]\r\n\t\tpi.registerTool({\r\n\t\t\tname: \"spt_checkpoint\",\r\n\t\t\tlabel: \"SPT Checkpoint\",\r\n\t\t\tdescription:\r\n\t\t\t\t\"After the commune skill has saved this live endpoint's continuity drop, compact native OMP context and wake the same endpoint.\",\r\n\t\t\tparameters: checkpointParameters(pi),\r\n\t\t\tasync execute(_toolCallId, parameters, _signal, _onUpdate, ctx) {\r\n\t\t\t\tif (!activated || !id) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"SPT checkpoint failed: no active endpoint.\" }],\r\n\t\t\t\t\t\tdetails: { ok: false, reason: \"not-activated\" },\r\n\t\t\t\t\t\tisError: true,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t\tif (activationType === \"ready_agent\") {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\ttype: \"text\",\r\n\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t],\r\n\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\r\n\t\t\t\t\t\tisError: true,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t\tconst wake =\r\n\t\t\t\t\tparameters.wake?.trim() ||\r\n\t\t\t\t\t\"Resume from the saved commune context and continue the prior work.\";\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait ctx.compact({\r\n\t\t\t\t\t\tinternalGuidance:\r\n\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\r\n\t\t\t\t\t});\r\n\t\t\t\t\tpi.sendMessage(\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\r\n\t\t\t\t\t\t\tcontent: wake,\r\n\t\t\t\t\t\t\tdisplay: true,\r\n\t\t\t\t\t\t\tattribution: \"user\",\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{ deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\ttype: \"text\",\r\n\t\t\t\t\t\t\t\ttext: `SPT checkpoint complete for ${id}; native continuation queued.`,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t],\r\n\t\t\t\t\t\tdetails: { ok: true, endpoint: id },\r\n\t\t\t\t\t};\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tcontent: [\r\n\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\ttype: \"text\",\r\n\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: ${errorSummary(error)}`,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t],\r\n\t\t\t\t\t\tdetails: { ok: false, reason: errorSummary(error) },\r\n\t\t\t\t\t\tisError: true,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t});\r\n\r\n\r\n\t\tfunction abortActiveCommands(reason, allowBindGrace = false) {\r\n\t\t\tfor (const [controller, active] of activeCommands) {\r\n\t\t\t\tconst isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";\r\n\t\t\t\tif (allowBindGrace && isBind && active.abortTimer === undefined) {\r\n\t\t\t\t\tactive.abortTimer = setTimer(\r\n\t\t\t\t\t\t() => controller.abort(reason),\r\n\t\t\t\t\t\tshutdownCommandTimeoutMs,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tactive.abortTimer?.unref?.();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tcontroller.abort(reason);\r\n\t\t\t}\n\t\t}","startLine":1116,"lineNumbers":[1116,null,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1886,"totalBytes":2766,"outputLines":90,"outputBytes":2766,"shownRange":{"start":1119,"end":1208},"nextOffset":1209}}},"isError":false,"timestamp":1784192609234}}
{"type":"message","id":"3dc25f37","parentId":"a9d27833","timestamp":"2026-07-16T09:03:41.052Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding endpoint type resolver helper**"},{"type":"toolCall","id":"call_F8bXYMtJMyZ4DJqb2ww8zE3G|ctc_0a6972aff60cbcce016a589e66a928819ab9dabf22b1d59649","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#6AFA]\nINS.POST 1126:\n+\t\tasync function resolveActivationType() {\n+\t\t\tif (activationType) return activationType;\n+\t\t\tconst info = parseJson(\n+\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", id]),\n+\t\t\t\t`spt api endpoint-info ${id}`,\n+\t\t\t);\n+\t\t\tif (![\"live_agent\", \"ready_agent\"].includes(info.endpoint_type)) {\n+\t\t\t\tthrow new Error(\"endpoint-info did not report live_agent or ready_agent\");\n+\t\t\t}\n+\t\t\tactivationType = info.endpoint_type;\n+\t\t\treturn activationType;\n+\t\t}\n+\nSWAP 1143.=1154:\n+\t\t\t\tlet resolvedType;\n+\t\t\t\ttry {\n+\t\t\t\t\tresolvedType = await resolveActivationType();\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: could not verify a live endpoint: ${errorSummary(error)}`,\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"type-unverified\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t\tif (resolvedType !== \"live_agent\") {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1906,"output":480,"cacheRead":223744,"cacheWrite":0,"totalTokens":226130,"reasoningTokens":106,"cost":{"input":0.00953,"output":0.0144,"cacheRead":0.111872,"cacheWrite":0,"total":0.135802}},"stopReason":"toolUse","timestamp":1784192609257,"responseId":"resp_0a6972aff60cbcce016a589e61ac90819aba88c8751cee9aaf","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0a6972aff60cbcce016a589e640da0819ab2d24c38a402e2d9","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ5mNVgwcSyofkLsA7jagK2K5CTtGZCFknVGcZIVycB4Yn9iiGFIQ61TQKfPEyxEG29-M5uW2SBdOep3soYBoPXzfkrZxM7a5GG51RI6bZzkJGPYXBZ91239NqfY4MpopbcIJlBBj7utrEO0lKAdJ6fCkCjiUM5Sx9YX8YBOFV6b0MVtrJ--4z9kn_RAk7XQxOKl9YWrEyGq3lXQETRDobjlBaVpBb9vfIJMzdhMuWQgNjFApk33Ugm7Ylkj2HDIejyoAOK-1VLeoJTB6jR0M95_wcQkc5IIB3bhJ3UIIytzqVbdouRZuvHKh6wMTZlsSQl8kcwoXm9oT2T2kB524wKUx2wowVfSrMD0rf-qwtelr638stWbJe2RJqrofRiwr8rsmMTX9In5I3mPKTB_Qdae7Gm-aceFHjzMLFWo6q-Rf_YrQuvenkMW6z1zcQ9fcYhR6hKhGjIMvwLKfTu4t8EeCUSBLdYjsuC9FsNb6LzLwT4sUqagTzO--B0httrTzjj35KF0ieGDCiXft_f5i8Cnm9UQAN9Dee9qVoBBmif-SAHflfLGgok-X0kmugh7R4Za7O7JIyinZ5_yP3rvig0P3jaf_vl7QEaCcDwFVLCY-nPZNTDa-9uzTvliqPPRYaRmSQ6SHyFxVntU2LX88WdazPSdvkC3ZV-YTcYLcaaoJXod0oXqdteJAQqM1CI8uxZaiZzCzJpG5VV5UXWUj1zAJpzxENT2wz8-GQFRtXOq_IM2MVsCEJp5Uo1IFFFmOLG6CnLlpvyLwmlzdBEBJ4vm5D9bRRo4RgBnYJ_mAmEFoDn3fUmpwCXPYWmpBqPRb1n_YnyDV3GZZddAX3_gMqMGTdq-2K5JeC3CRmhqWCO9T3k_JC5EJ04yzZ5wBnykZcUE8U6FwCn7G_F3D27oxX_LLPtwR23df7eUNNFRksb-IucTdErD8Mb5KT0A_CJcOraBiYeLMoL4mjAPb5PqFSS7Xt2WRLkzfEfngrSUgO3mhRn_h48z4zGX84i03VvWXtmj851yFPT7lmqbvIh4knfkQY-igAAoJIm5wxmxfFpuH-PCPPZcxVuEqqgc2cUxRVJxxVP988pMg8IL4QgGpEi98EkgB_vsB4DRC9Ulov5mk8iDELy0PU4_tPdQIWjE5YOUyrV3ktFOoA-IEgEx5sAR0qqa0V38Ws_qAKs_yVW2mF128uloOpmeFPhhjAKlGn7n_1Xsex_gqQ94eJbYfZkxsP1QSITfKxT4G7x5EUG4z0eHdRrhEVnMCQsxwswoXFzjopYUNtAk5mROngv8UDjTD1f1fJG5eQHR7wpjHPRNDgxKVvgjKC-aeqRVVcJ2PvD-Q7G9inthw-KBS5wlSbO3AzRwphMde20gquM_qLmO5jHHIzvXXfy8U0wSAmjMyyZRS3BqH1FC_1UMzV7b3FxIyzh64mUO34C07FQl2P4Tt4vCDjSMK005VOKrTykilE_pGj_MUwHoVpuOBXxicLOOnGIxKPkNYLyoLmr8ov1Hvlp6ko5yqOVQh5weizvvNcZG9yPLSFsICZsM3HK1Cv5MXA==","summary":[{"type":"summary_text","text":"**Adding endpoint type resolver helper**"}]},{"id":"ctc_0a6972aff60cbcce016a589e66a928819ab9dabf22b1d59649","type":"custom_tool_call","status":"completed","call_id":"call_F8bXYMtJMyZ4DJqb2ww8zE3G","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#6AFA]\nINS.POST 1126:\n+\t\tasync function resolveActivationType() {\n+\t\t\tif (activationType) return activationType;\n+\t\t\tconst info = parseJson(\n+\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", id]),\n+\t\t\t\t`spt api endpoint-info ${id}`,\n+\t\t\t);\n+\t\t\tif (![\"live_agent\", \"ready_agent\"].includes(info.endpoint_type)) {\n+\t\t\t\tthrow new Error(\"endpoint-info did not report live_agent or ready_agent\");\n+\t\t\t}\n+\t\t\tactivationType = info.endpoint_type;\n+\t\t\treturn activationType;\n+\t\t}\n+\nSWAP 1143.=1154:\n+\t\t\t\tlet resolvedType;\n+\t\t\t\ttry {\n+\t\t\t\t\tresolvedType = await resolveActivationType();\n+\t\t\t\t} catch (error) {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: could not verify a live endpoint: ${errorSummary(error)}`,\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"type-unverified\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n+\t\t\t\tif (resolvedType !== \"live_agent\") {\n+\t\t\t\t\treturn {\n+\t\t\t\t\t\tcontent: [\n+\t\t\t\t\t\t\t{\n+\t\t\t\t\t\t\t\ttype: \"text\",\n+\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n+\t\t\t\t\t\t\t},\n+\t\t\t\t\t\t],\n+\t\t\t\t\t\tdetails: { ok: false, reason: \"not-live\" },\n+\t\t\t\t\t\tisError: true,\n+\t\t\t\t\t};\n+\t\t\t\t}\n*** End Patch\n","name":"edit"}]},"duration":11764.534899999853,"ttft":2774.1745000001974,"contextSnapshot":{"promptTokens":225650,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_F8bXYMtJMyZ4DJqb2ww8zE3G|ctc_0a6972aff60cbcce016a589e66a928819ab9dabf22b1d59649","toolName":"edit","startedAt":"2026-07-16T09:03:41.053Z"},"id":"3d38e9a8","parentId":"3dc25f37","timestamp":"2026-07-16T09:03:41.053Z"}
{"type":"message","id":"1ddf7b7b","parentId":"3d38e9a8","timestamp":"2026-07-16T09:03:41.101Z","message":{"role":"toolResult","toolCallId":"call_F8bXYMtJMyZ4DJqb2ww8zE3G|ctc_0a6972aff60cbcce016a589e66a928819ab9dabf22b1d59649","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#8D63]\n1122:\t\tpi.registerCommand(\"live\", {\n\n1125:\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n1126:\t\t});\n1127:\t\tasync function resolveActivationType() {\n1128:\t\t\tif (activationType) return activationType;\n…\n1137:\t\t\treturn activationType;\n1138:\t\t}\n1139:\n1140:\n1141:\t\t// [impl->REQ-PARITY-CHECKPOINT]\n1142:\t\tpi.registerTool({\n\n1149:\t\t\t\tif (!activated || !id) {\n1150:\t\t\t\t\treturn {\n\n1154:\t\t\t\t\t};\n1155:\t\t\t\t}\n1156:\t\t\t\tlet resolvedType;\n1157:\t\t\t\ttry {\n1158:\t\t\t\t\tresolvedType = await resolveActivationType();\n1159:\t\t\t\t} catch (error) {\n1160:\t\t\t\t\treturn {\n1161:\t\t\t\t\t\tcontent: [\n1162:\t\t\t\t\t\t\t{\n1163:\t\t\t\t\t\t\t\ttype: \"text\",\n1164:\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: could not verify a live endpoint: ${errorSummary(error)}`,\n1165:\t\t\t\t\t\t\t},\n…\n1174:\t\t\t\t\t\t\t{\n1175:\t\t\t\t\t\t\t\ttype: \"text\",\n1176:\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n1177:\t\t\t\t\t\t\t},\n1178:\t\t\t\t\t\t],\n\n1181:\t\t\t\t\t};\n1182:\t\t\t\t}\n\n1222:\t\t});"}],"details":{"diff":" 1122|\t\tpi.registerCommand(\"live\", {\n\n 1125|\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n 1126|\t\t});\n+1127|\t\tasync function resolveActivationType() {\n+1128|\t\t\tif (activationType) return activationType;\n+1129|\t\t\tconst info = parseJson(\n+1130|\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", id]),\n+1131|\t\t\t\t`spt api endpoint-info ${id}`,\n+1132|\t\t\t);\n+1133|\t\t\tif (![\"live_agent\", \"ready_agent\"].includes(info.endpoint_type)) {\n+1134|\t\t\t\tthrow new Error(\"endpoint-info did not report live_agent or ready_agent\");\n+1135|\t\t\t}\n+1136|\t\t\tactivationType = info.endpoint_type;\n+1137|\t\t\treturn activationType;\n+1138|\t\t}\n 1127|\n+1140|\n 1128|\t\t// [impl->REQ-PARITY-CHECKPOINT]\n 1129|\t\tpi.registerTool({\n\n 1136|\t\t\t\tif (!activated || !id) {\n 1137|\t\t\t\t\treturn {\n\n 1141|\t\t\t\t\t};\n 1142|\t\t\t\t}\n-1143|\t\t\t\tif (activationType === \"ready_agent\") {\n+1156|\t\t\t\tlet resolvedType;\n+1157|\t\t\t\ttry {\n+1158|\t\t\t\t\tresolvedType = await resolveActivationType();\n+1159|\t\t\t\t} catch (error) {\n 1144|\t\t\t\t\treturn {\n 1145|\t\t\t\t\t\tcontent: [\n 1146|\t\t\t\t\t\t\t{\n 1147|\t\t\t\t\t\t\t\ttype: \"text\",\n+1164|\t\t\t\t\t\t\t\ttext: `SPT checkpoint failed: could not verify a live endpoint: ${errorSummary(error)}`,\n+1165|\t\t\t\t\t\t\t},\n+1166|\t\t\t\t\t\t],\n+1167|\t\t\t\t\t\tdetails: { ok: false, reason: \"type-unverified\" },\n+1168|\t\t\t\t\t\tisError: true,\n+1169|\t\t\t\t\t};\n+1170|\t\t\t\t}\n+1171|\t\t\t\tif (resolvedType !== \"live_agent\") {\n+1172|\t\t\t\t\treturn {\n+1173|\t\t\t\t\t\tcontent: [\n+1174|\t\t\t\t\t\t\t{\n+1175|\t\t\t\t\t\t\t\ttype: \"text\",\n 1148|\t\t\t\t\t\t\t\ttext: \"SPT checkpoint failed: continuity checkpoints require a live endpoint.\",\n 1149|\t\t\t\t\t\t\t},\n 1150|\t\t\t\t\t\t],\n\n 1153|\t\t\t\t\t};\n 1154|\t\t\t\t}\n\n 1194|\t\t});","firstChangedLine":1126,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192621100}}
{"type":"message","id":"1f34a16c","parentId":"1ddf7b7b","timestamp":"2026-07-16T09:03:53.308Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding shutdown check after compact operation**"},{"type":"toolCall","id":"call_CoKnVBNUi76nhwnJBh0Gmo4i|fc_0b39f972955f1aca016a589e75442c819a92c76db32c596283","name":"grep","arguments":{"i":"Locating checkpoint wake call","pattern":"await ctx\\.compact|pi\\.sendMessage","path":"adapter/strings/omp-spt.mjs","selector":"1180-1220","case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1691,"output":150,"cacheRead":224768,"cacheWrite":0,"totalTokens":226609,"reasoningTokens":81,"cost":{"input":0.008455,"output":0.0045000000000000005,"cacheRead":0.112384,"cacheWrite":0,"total":0.125339}},"stopReason":"toolUse","timestamp":1784192621156,"responseId":"resp_0b39f972955f1aca016a589e6d9578819aaf4c74e087bd38f0","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0b39f972955f1aca016a589e733d6c819aa5eb3614607bae95","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ518aF9iQhlKYMMxmGeZMTFRmLwE8uYn3ub9e0iVY1JMbVK7ltnjSaWpCh4byjXLKM9MG749dK_E9IUgG0uATwXvq-tZyGnq0xM3kejmdtq66XgsFkGoYL_6B-38WdE70fpkUYGXRDQkHrGZVnP91LUl8E3xPGBlobMy0n1VVYpylrqttuiYnlSbCE5B5AYk16A6G2AFGjnGAVcR7xcpSFAK3N30rU-D81pT-YPYT-Yn5Rsqt1y1gN0e25ipM5-AV6l7gN0APF7Dn-SXhuuTAmDb3hvL5NWULoInhduE1-KifJy8l9kwL9kwN6YErgv4tVSNcRb-0RN7W-ssEeoJj8vrTopdnDu_PL80REjmKVPtlhICl8NsUj4Cg9D7RxKnmgh044odMSDyqO7Z_UsjNCos2dK6MSvnDtXTCZe8Q2QPYdDl6VMhRuDKl4_zlb8IfyWtrPM5HqI3hPaRf9GYjjFeMRXh6Eu-Yc6iKtmPhx0bZWAJ669-n3UGGtUH6FkzoXqO7Nv0OfKpMkS4tmyjfvgsAG3i028lBo9j4hqCcybw1cvdyNPlA30o1Af10MYtpJQwLzCyi6UWZZwbZDO0gEQy-xN5Ir8x-HQs7NDhr9v69t2ifN4389x0l3dWBYS9Q1Lx-qRAwM4ZQutHoLV5zQvw6to7IFucusFmqPJPnOauXXFk92ECKmr73O9J8BJt2UeoWJlNTCFePJkwglO_-7QlllcB9pyd0mieZZbPhBKO6RR0Zef5hDgI87umHbLnv_Jp-LR5i8yAm6fl3a8F6XdYsHcmqFWofLp-Q_4_zqnk2XOMk-TK27MlnxkNPI0tckDpgJXuA4k86OHN3zkQlqM1iPDZJAxFuGDW1NgBilC4orGY8FQKkDcZikENivorXv8llUYczzXT9ISg540TgmbOXLPBV8w6bnyKyUdRRbCt4MxznPgZZy9q16QaBWKIs5RNAOeTAvw6aqCDGBsfg9Wefjt79y4MnGPGVKm7H9QHduAid5QRBEbktjrSUHKYwgFpJ3ME6-bhL8EABoJ-7nEvBOjTOjnPOH63KeyqiA_1nqHEEQifGlmhMp4IYWTIEYd5ai2-OjVMQglrEgN-0QZEVe74CQpQWMcLGqP6lgmD3C6JiH2PfoQNar_q40n1vrR2KwF5Sw7es7lLDt_TJkScaVjg6xzwXiJCPlqGMPHP_Qw-rAaonhD4jdxqQSsI-Fh3amDuHB9kTSoq82Z-bBEMLw6cW8t4hKAPrkT7egXsaQGqNC3AOPgRoN5XuCX4dPHyjYqv1-Nt7NBt3xAKg4QdTWY4f1Krm6VsSYcdMhu-l9PQg5QWmOdpQfd-1howTXAFoxSqxc2KaaqhJZjPfb0cbuwLfd2w-j_O7Sa6jzz3Og-prqqp4C4PNPDlK0VGoSvTwETcWzIR9v3iB0AkHuGLw==","summary":[{"type":"summary_text","text":"**Adding shutdown check after compact operation**"}]},{"id":"fc_0b39f972955f1aca016a589e75442c819a92c76db32c596283","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating checkpoint wake call\",\"pattern\":\"await ctx\\\\.compact|pi\\\\.sendMessage\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"1180-1220\",\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_CoKnVBNUi76nhwnJBh0Gmo4i","name":"grep"}]},"duration":11995.585999999661,"ttft":6360.835299999919,"contextSnapshot":{"promptTokens":226459,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_CoKnVBNUi76nhwnJBh0Gmo4i|fc_0b39f972955f1aca016a589e75442c819a92c76db32c596283","toolName":"grep","startedAt":"2026-07-16T09:03:53.308Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Locating checkpoint wake call"},"id":"fe5d527b","parentId":"1f34a16c","timestamp":"2026-07-16T09:03:53.308Z"}
{"type":"message","id":"79956da5","parentId":"fe5d527b","timestamp":"2026-07-16T09:03:53.313Z","message":{"role":"toolResult","toolCallId":"call_CoKnVBNUi76nhwnJBh0Gmo4i|fc_0b39f972955f1aca016a589e75442c819a92c76db32c596283","toolName":"grep","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#8D63]\n 1186:\t\t\t\ttry {\n*1187:\t\t\t\t\tawait ctx.compact({\n 1188:\t\t\t\t\t\tinternalGuidance:\n 1189:\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n 1190:\t\t\t\t\t});\n*1191:\t\t\t\t\tpi.sendMessage(\n 1192:\t\t\t\t\t\t{\n 1193:\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n 1194:\t\t\t\t\t\t\tcontent: wake,"}],"details":{"scopePath":"adapter/strings/omp-spt.mjs","searchPath":"C:/Users/decid/Documents/projects/omp-spt/adapter/strings/omp-spt.mjs","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":2,"fileCount":1,"files":["adapter/strings/omp-spt.mjs"],"fileMatches":[{"path":"adapter/strings/omp-spt.mjs","count":2}],"truncated":false,"displayContent":" 1186│\t\t\t\ttry {\n*1187│\t\t\t\t\tawait ctx.compact({\n 1188│\t\t\t\t\t\tinternalGuidance:\n 1189│\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n 1190│\t\t\t\t\t});\n*1191│\t\t\t\t\tpi.sendMessage(\n 1192│\t\t\t\t\t\t{\n 1193│\t\t\t\t\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n 1194│\t\t\t\t\t\t\tcontent: wake,"},"isError":false,"timestamp":1784192633312}}
{"type":"message","id":"20cea695","parentId":"79956da5","timestamp":"2026-07-16T09:03:58.476Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Editing code at line 1190**"},{"type":"toolCall","id":"call_rV5EsRTCx0AvEMD7gBe026sH|ctc_0ce796cb86d01cc0016a589e7cac80819aa613b32b68f27bb9","name":"edit","arguments":{"input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#8D63]\nINS.POST 1190:\n+\t\t\t\t\tif (stopping) throw new Error(\"OMP session began shutting down during checkpoint\");\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":944,"output":71,"cacheRead":225792,"cacheWrite":0,"totalTokens":226807,"reasoningTokens":11,"cost":{"input":0.00472,"output":0.00213,"cacheRead":0.112896,"cacheWrite":0,"total":0.11974599999999999}},"stopReason":"toolUse","timestamp":1784192633332,"responseId":"resp_0ce796cb86d01cc0016a589e79de98819aa2ad9a89507b3f14","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0ce796cb86d01cc0016a589e7c0024819a906a30b9c6b44e55","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ580z7txuDT8fTnIuDzw7FZw3QoSmXfXFDjNmjA1L_pa0diYxePZYoWtB1yKZZfh0IlADSejgED3OS_U2dTESo3cNwzzS-mNuBqw8nHQscFp83I8S7ImNH8JK20vVqvig9DOV9DUmKacqNbxUNr--PXOFyy-GgdKvhwi_G3uI9Bvi7xJT82enwRHhTvdSjMNls49GsMnZBdMCQsGgtWVCK5ECECEExAt7U2lPHs1uNDeaOl2seQqclHGyLjMO_gO5JDCFz1GWJb_W1OmnGy_cU93Sld56348MmSILkOD0XOnsRLZVTVMYntMMRDrnRD2hFL9CuCw2F_O1CrkBjXplsyisHzDfvdvV30Z2Lb14CyU-Rf5bjkih-rKY3xTG1cjm_HWokPU3IGDAHbANHlu-N1xcqozCT5IetrlCX-6SezbzzTMIaEjl_kBMGW-Obs4wTsmjW-0U2NtHHYB6JDw3snwHTaIiSRzVAcsKLwn7qXMwGK1y_YhcNYumrWYuo3tMwvBiI8-dbdmLNpClXHKaXc_1mtjSlvGoBcnlQJJV3-yhy_shjBT2lQEsQB3z5DGciug6ZozU4zSuLYbxIRP8_1P3CMqk3t0QKUGibHo2R4cpveY21VH1Qq-UowLafChT-SsJ55lrUrq6PmoEgZlBqNJttKkkCnKtFs3494ih1965Ge0DfvFkPLMScmLdhn4TnmL79FzpkYVYwJ8txxySFpbPLdClz9Il4yRAEtL0p0CZguiYBEPJdR6ZPMSUjeRg-RoujHGHVSBs3SdvXttBNjdswH1N15zhUzYZmhODCQ_GWF7609CgoQ4W8FKHcoYjCqoOhdEJWEfjEvOtkSnXGrnfx1DL8Y4T1Y5wiNV75qog1zLWlGfPFw9wt3QCzhFQQVEhXQxyNRpCjurQwAC0SNUnb2tdqJWQsv4ZX_rwpmmX3kvAy_8lpFewu3YWTierhL","summary":[{"type":"summary_text","text":"**Editing code at line 1190**"}]},{"id":"ctc_0ce796cb86d01cc0016a589e7cac80819aa613b32b68f27bb9","type":"custom_tool_call","status":"completed","call_id":"call_rV5EsRTCx0AvEMD7gBe026sH","input":"*** Begin Patch\n[adapter/strings/omp-spt.mjs#8D63]\nINS.POST 1190:\n+\t\t\t\t\tif (stopping) throw new Error(\"OMP session began shutting down during checkpoint\");\n*** End Patch\n","name":"edit"}]},"duration":4998.724200000055,"ttft":2646.8004000000656,"contextSnapshot":{"promptTokens":226736,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_rV5EsRTCx0AvEMD7gBe026sH|ctc_0ce796cb86d01cc0016a589e7cac80819aa613b32b68f27bb9","toolName":"edit","startedAt":"2026-07-16T09:03:58.871Z"},"id":"c61187f2","parentId":"20cea695","timestamp":"2026-07-16T09:03:58.871Z"}
{"type":"message","id":"f8b29405","parentId":"c61187f2","timestamp":"2026-07-16T09:03:58.927Z","message":{"role":"toolResult","toolCallId":"call_rV5EsRTCx0AvEMD7gBe026sH|ctc_0ce796cb86d01cc0016a589e7cac80819aa613b32b68f27bb9","toolName":"edit","content":[{"type":"text","text":"[adapter/strings/omp-spt.mjs#9CB1]\n1187:\t\t\t\t\tawait ctx.compact({\n1188:\t\t\t\t\t\tinternalGuidance:\n1189:\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n1190:\t\t\t\t\t});\n1191:\t\t\t\t\tif (stopping) throw new Error(\"OMP session began shutting down during checkpoint\");\n1192:\t\t\t\t\tpi.sendMessage(\n1193:\t\t\t\t\t\t{\n\n1198:\t\t\t\t\t\t},\n\n1200:\t\t\t\t\t);"}],"details":{"diff":" 1187|\t\t\t\t\tawait ctx.compact({\n 1188|\t\t\t\t\t\tinternalGuidance:\n 1189|\t\t\t\t\t\t\t\"Preserve only the durable state needed to continue from the just-saved SPT commune.\",\n 1190|\t\t\t\t\t});\n+1191|\t\t\t\t\tif (stopping) throw new Error(\"OMP session began shutting down during checkpoint\");\n 1191|\t\t\t\t\tpi.sendMessage(\n 1192|\t\t\t\t\t\t{\n\n 1197|\t\t\t\t\t\t},\n\n 1199|\t\t\t\t\t);","firstChangedLine":1190,"op":"update","path":"adapter/strings/omp-spt.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192638927}}
{"type":"message","id":"49d190ff","parentId":"f8b29405","timestamp":"2026-07-16T09:04:03.302Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Updating test harness to accept runOptions**"},{"type":"toolCall","id":"call_pN7xTFXjg5tY2GVosITXfLO1|fc_04107e0fc1bfb5f6016a589e82c188819b9e3f8de4953d8b22","name":"read","arguments":{"i":"Reading harness command adapter","path":"tests/omp-extension.mjs","selector":"180-240"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1135,"output":66,"cacheRead":225792,"cacheWrite":0,"totalTokens":226993,"reasoningTokens":29,"cost":{"input":0.005675,"output":0.00198,"cacheRead":0.112896,"cacheWrite":0,"total":0.12055099999999999}},"stopReason":"toolUse","timestamp":1784192638978,"responseId":"resp_04107e0fc1bfb5f6016a589e7fafe0819b9482b3a73ac40a0a","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_04107e0fc1bfb5f6016a589e81b618819b98b6bf94f02a5304","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ6C5bNlnR_uuRTd7uMedF4zp0s0YPBAt7AYdWgrVHZcDEfUCd9gDC5kkkXt8YukJNkCRAWFlBgMFLfms3rVAb7nEa2iYbCVZnZqsgdJhdyDeKcIi15ulzQHD562OuJy6xj5eJOAQsjdR_8PhxgSUZ3wUlR-7xvpvoGv-QkCOza31UGiX3zCuigTphy3gWRemmL52MvqOnvI5vV55qZrA3aAIHmy8TpPeLU9dpoxUBZkuKwjKBC4vpxoyBSC8KZlzOCFNI0HkPhLP3U-99RmVf5hgui3g8CZOTsLTNPOqlSXmtasI6vrq7y9ygCt_1zvYyvXItdEqBiiHv_hudoJYhOWiFEKRf3CPFhpqhnE_FFjWwAfU6L-O3EW-a9GU4AEtnLhjVtGkdTO04-Emp_hW7NSNRS3b7nmBwWWCksKQyq8rJ3CjVYwMD5q4QSNw5z4zkXaMfz7KFqDuevePNA8puWfzOkrhDU5GZ1xODnW7qdgAAS6iP5N3Z-WubWJPVgL8OpfpQn-EmDI-eMUZmmxdNlHFUFi-T5A-yy4X_DksV4KrpjMbz0bFTNEzx5G4tpEAR5KHQfkQJgkSsAnz-gLqKWjG9z4cn0B1VDA4Ed4MJ4yIKWzZYKlMrIqKMxnUguyy5DgEJlkVeOGhfqpCmZAo7gamqR-_Tjaja2jxxghzU9UGRGXRoCmFjt-cYNToIERR2spCsY0jdfUc19E5fuDDauN0wCM4ugL5oegLPQXVAO8cpG8Z_HJg5JK5jghsIHuhArYvLD455UY0lLi3sZ0HBb91M3WbvMZkic8EcJ2z1aKjtG_NBvsW-jLvhsl5Arc_p4upFnp0k_XvW5kok5w4IJsWFRZfOSJcR8JCoLFgMiYQDkpO2Ph3eySBJoUSef8P5BpS98BRF5DQFPmBUmEZY6RHuIt9DWVNGNmXbdyIKpD-0UitlUIY8Ci-nRlsq0s7-8cLDo_wluROgHqJhPHiY0XyIT_6twiSTw5ICQYpZoY1_6J48qEwMiXcG429YXHEhRh36WFyrJwAxSyEjBkdnxyhO4ZTdPsOmuGsRyQhPtP3HPV_aAr7acYxU_MBOC2Nosx","summary":[{"type":"summary_text","text":"**Updating test harness to accept runOptions**"}]},{"id":"fc_04107e0fc1bfb5f6016a589e82c188819b9e3f8de4953d8b22","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading harness command adapter\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"180-240\"}","call_id":"call_pN7xTFXjg5tY2GVosITXfLO1","name":"read"}]},"duration":4323.19840000011,"ttft":2711.9582000002265,"contextSnapshot":{"promptTokens":226927,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_pN7xTFXjg5tY2GVosITXfLO1|fc_04107e0fc1bfb5f6016a589e82c188819b9e3f8de4953d8b22","toolName":"read","startedAt":"2026-07-16T09:04:03.302Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading harness command adapter"},"id":"5da6c632","parentId":"49d190ff","timestamp":"2026-07-16T09:04:03.302Z"}
{"type":"message","id":"8420a0c1","parentId":"5da6c632","timestamp":"2026-07-16T09:04:03.320Z","message":{"role":"toolResult","toolCallId":"call_pN7xTFXjg5tY2GVosITXfLO1|fc_04107e0fc1bfb5f6016a589e82c188819b9e3f8de4953d8b22","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#00DB]\n164:\tconst pi = {\n…\n179:\t\tregisterCommand(name, command) {\n180:\t\t\tcommands.set(name, command);\n181:\t\t},\n182:\t\tregisterTool(tool) {\n183:\t\t\ttools.set(tool.name, tool);\n184:\t\t},\n185:\t\tsendMessage(message, delivery) {\n186:\t\t\tsentMessages.push({ message, delivery });\n187:\t\t\toptions.onSendMessage?.(message, delivery);\n188:\t\t},\n189:\t\tsendUserMessage(content) {\n190:\t\t\tsubmitted.push(content);\n191:\t\t\toptions.onSubmit?.(content);\n192:\t\t},\n193:\t};\n194:\tconst runSptCommand = async (args, input) => {\n195:\t\tconst call = { args: [...args], input };\n196:\t\tcalls.push(call);\n197:\t\tconst overridden = await options.onRun?.(call);\n198:\t\tif (overridden !== undefined) return overridden;\n199:\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\n200:\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\n201:\t\t}\n202:\t\treturn \"\";\n203:\t};\n204:\tconst spawnProcess = (binary, args, spawnOptions) => {\n205:\t\tconst child = new FakeChild();\n206:\t\tchild.binary = binary;\n207:\t\tchild.args = [...args];\n208:\t\tchild.spawnOptions = spawnOptions;\n209:\t\toptions.onSpawn?.(child);\n210:\t\tchildren.push(child);\n211:\t\treturn child;\n212:\t};\n213:\tconst extension = createOmpSpt({\n214:\t\tenv: {\n215:\t\t\tSPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",\n216:\t\t\tOMP_SPT_SUBNET: options.subnet,\n217:\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\n218:\t\t},\n219:\t\tcheckUpdates: options.checkUpdates ?? false,\n220:\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\n221:\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n222:\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n223:\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\n224:\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\n225:\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\n226:\t\tshutdownBudgetMs: options.shutdownBudgetMs,\n227:\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\n228:\t\tlistenerStableMs: options.listenerStableMs ?? false,\n229:\t\tkillForceMs: options.killForceMs ?? 4,\n230:\t\tkillGraceMs: options.killGraceMs ?? 3,\n231:\t\tlistenerBufferLimit: options.listenerBufferLimit,\n232:\t\trunSptCommand,\n233:\t\tspawnProcess,\n234:\t\tsetTimeout: clock.setTimeout.bind(clock),\n235:\t\tclearTimeout: clock.clearTimeout.bind(clock),\n236:\t});\n237:\textension(pi);\n238:\n239:\tasync function emit(name, event = {}) {\n240:\t\tlet result;\n241:\t\tfor (const handler of handlers.get(name) ?? []) {\n242:\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\n243:\t\t\tif (returned !== undefined) result = returned;\n244:\t\t}\n…\n246:\t}\n\n[Showing lines 179-243 of 1937. Use :244 to continue]"}],"details":{"truncation":{"content":"\t\tregisterCommand(name, command) {\r\n\t\t\tcommands.set(name, command);\r\n\t\t},\r\n\t\tregisterTool(tool) {\r\n\t\t\ttools.set(tool.name, tool);\r\n\t\t},\r\n\t\tsendMessage(message, delivery) {\r\n\t\t\tsentMessages.push({ message, delivery });\r\n\t\t\toptions.onSendMessage?.(message, delivery);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tcheckUpdates: options.checkUpdates ?? false,\r\n\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r","truncated":true,"truncatedBy":"lines","totalLines":1759,"totalBytes":2273,"outputLines":65,"outputBytes":2273,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\tconst pi = {\n…\n\t\tregisterCommand(name, command) {\r\n\t\t\tcommands.set(name, command);\r\n\t\t},\r\n\t\tregisterTool(tool) {\r\n\t\t\ttools.set(tool.name, tool);\r\n\t\t},\r\n\t\tsendMessage(message, delivery) {\r\n\t\t\tsentMessages.push({ message, delivery });\r\n\t\t\toptions.onSendMessage?.(message, delivery);\r\n\t\t},\r\n\t\tsendUserMessage(content) {\r\n\t\t\tsubmitted.push(content);\r\n\t\t\toptions.onSubmit?.(content);\r\n\t\t},\r\n\t};\r\n\tconst runSptCommand = async (args, input) => {\r\n\t\tconst call = { args: [...args], input };\r\n\t\tcalls.push(call);\r\n\t\tconst overridden = await options.onRun?.(call);\r\n\t\tif (overridden !== undefined) return overridden;\r\n\t\tif (args[0] === \"api\" && args[3] === \"bind\") {\r\n\t\t\treturn options.bindOutput ?? \"BOUND endpoint token=token-123\";\r\n\t\t}\r\n\t\treturn \"\";\r\n\t};\r\n\tconst spawnProcess = (binary, args, spawnOptions) => {\r\n\t\tconst child = new FakeChild();\r\n\t\tchild.binary = binary;\r\n\t\tchild.args = [...args];\r\n\t\tchild.spawnOptions = spawnOptions;\r\n\t\toptions.onSpawn?.(child);\r\n\t\tchildren.push(child);\r\n\t\treturn child;\r\n\t};\r\n\tconst extension = createOmpSpt({\r\n\t\tenv: {\r\n\t\t\tSPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",\r\n\t\t\tOMP_SPT_SUBNET: options.subnet,\r\n\t\t\tOMP_SPT_SPT_BIN: \"spt-test\",\r\n\t\t},\r\n\t\tcheckUpdates: options.checkUpdates ?? false,\r\n\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\r\n\t\tacceptedBytesLimit: options.acceptedBytesLimit,\r\n\t\tacceptedQueueLimit: options.acceptedQueueLimit,\r\n\t\trestartDelaysMs: options.restartDelaysMs ?? [5, 10],\r\n\t\toutcomeRetryDelaysMs: options.outcomeRetryDelaysMs ?? [],\r\n\t\tsessionEndRetryDelaysMs: options.sessionEndRetryDelaysMs ?? [],\r\n\t\tshutdownBudgetMs: options.shutdownBudgetMs,\r\n\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\r\n\t\tlistenerStableMs: options.listenerStableMs ?? false,\r\n\t\tkillForceMs: options.killForceMs ?? 4,\r\n\t\tkillGraceMs: options.killGraceMs ?? 3,\r\n\t\tlistenerBufferLimit: options.listenerBufferLimit,\r\n\t\trunSptCommand,\r\n\t\tspawnProcess,\r\n\t\tsetTimeout: clock.setTimeout.bind(clock),\r\n\t\tclearTimeout: clock.clearTimeout.bind(clock),\r\n\t});\r\n\textension(pi);\r\n\r\n\tasync function emit(name, event = {}) {\r\n\t\tlet result;\r\n\t\tfor (const handler of handlers.get(name) ?? []) {\r\n\t\t\tconst returned = await handler({ type: name, ...event }, ctx);\r\n\t\t\tif (returned !== undefined) result = returned;\r\n\t\t}\n…\n\t}","startLine":164,"lineNumbers":[164,null,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,null,246]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1937,"totalBytes":2273,"outputLines":65,"outputBytes":2273,"shownRange":{"start":179,"end":243},"nextOffset":244}}},"isError":false,"timestamp":1784192643320}}
{"type":"message","id":"72cd257f","parentId":"8420a0c1","timestamp":"2026-07-16T09:04:10.087Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adjusting run configurations**"},{"type":"toolCall","id":"call_qVHAqsJaPYDJfmgOfRZjBk4b|ctc_0debd03d866fa141016a589e864d808198b29fc448471b1c36","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#00DB]\nSWAP 194.=195:\n+\tconst runSptCommand = async (args, input, runOptions) => {\n+\t\tconst call = { args: [...args], input, options: runOptions };\nINS.POST 220:\n+\t\tplatform: options.platform,\nINS.POST 227:\n+\t\tshortformCommandTimeoutMs: options.shortformCommandTimeoutMs,\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":948,"output":121,"cacheRead":226816,"cacheWrite":0,"totalTokens":227885,"reasoningTokens":14,"cost":{"input":0.00474,"output":0.00363,"cacheRead":0.113408,"cacheWrite":0,"total":0.121778}},"stopReason":"toolUse","timestamp":1784192643368,"responseId":"resp_0debd03d866fa141016a589e83f8808198bf4bf9252f4104b4","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0debd03d866fa141016a589e85ad7081989dbe87448d510df5","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ6Gk3w_kniy-EwBei4iC-5JDzi1Dbh7NW4Q0ovmCM3k_uWRIWtKliISZzAi17Bsj0VPI3pBC7Gq5LYm72Qs4O5Aa62UxeVs_qcceVn4_mAsWAKGhEuMwlH53roa57nfKrMEg-IYAK3Q4qkK5FWl9YnJIJUUPjOoY6teV4zpC5CTndW8PexKashjchTGZAXUt23dkqBA74jY6yT7qbdUHLt7Fn0c0Pj8p8R5NgkWCq7BuyiDfSHX1JjVUuXfRho-MP9xhIbGZqQ_Fe0L1NmgSTnWzGU5bLUMY_HyOS4cV_v-k5wDQc3Iq-r5VrLa0dedTuWtzYTXB7QEdBX3T0U8Pe31Hjz9oXVqVc-crwNVoV-e_u9TwCquQdlC88ZmxDIPyVGcGHUroo_kLHOXAYx_Ks_6dVNpBvnCTVud_EDAQCAIoJ507gf4-2hiEcsJVgkzJDgB7-vCy5x4QEV4XoQM2VrxA_GJWu-EEZhrENoCQZ6ZYdUh-LOETQt3JD0vY46UPhtt1ccw1-jjoOZIz69NG11DCWoit-tT9xtU9QKvUS2QY96ok6Dno_V0h7vhEEf2yjxrF1khMtLGAoUGbSe9LomA1yzZzzvtp62g3Nz8X2eMrpXMQ23IL2x4vbp3-HRnl8_uOcHUTDVrHOOa-zZhXMCWkqCwuKp9O--uLMN2-a6-ASmy7J8EK8Z-x2LRh-I3vClHLuxaiH-V0pbpXyA43qRZGmUsCAs99-CNwyD80U0koTUTkIKWXPAgo3OKF4aRhMMVtsVAxe_l3Kq9GZMf2TWNK8MAjx2oyMc1-l9Ve2Q63V-S-5t_E9tA--itIOSXc0Qa9IaGx0mC2cbCkTgmNrTnLYV9domELSIvL62mU-FNQF5poN2cPKqT8UOkypKow9KylirbBkYx9i29Pz5niw2ZQPQaV3D4pUGdIiYG7-8I8UMhEvJqYaVFvENCM0sb6-WBbu0eH_vgXNDc9OoQ9pGOUVOndBDT5atrP9XOvOBRmp8=","summary":[{"type":"summary_text","text":"**Adjusting run configurations**"}]},{"id":"ctc_0debd03d866fa141016a589e864d808198b29fc448471b1c36","type":"custom_tool_call","status":"completed","call_id":"call_qVHAqsJaPYDJfmgOfRZjBk4b","input":"*** Begin Patch\n[tests/omp-extension.mjs#00DB]\nSWAP 194.=195:\n+\tconst runSptCommand = async (args, input, runOptions) => {\n+\t\tconst call = { args: [...args], input, options: runOptions };\nINS.POST 220:\n+\t\tplatform: options.platform,\nINS.POST 227:\n+\t\tshortformCommandTimeoutMs: options.shortformCommandTimeoutMs,\n*** End Patch\n","name":"edit"}]},"duration":6577.815599999856,"ttft":2296.7349000000395,"contextSnapshot":{"promptTokens":227764,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_qVHAqsJaPYDJfmgOfRZjBk4b|ctc_0debd03d866fa141016a589e864d808198b29fc448471b1c36","toolName":"edit","startedAt":"2026-07-16T09:04:10.088Z"},"id":"20df09ec","parentId":"72cd257f","timestamp":"2026-07-16T09:04:10.088Z"}
{"type":"message","id":"eb25d55a","parentId":"20df09ec","timestamp":"2026-07-16T09:04:10.132Z","message":{"role":"toolResult","toolCallId":"call_qVHAqsJaPYDJfmgOfRZjBk4b|ctc_0debd03d866fa141016a589e864d808198b29fc448471b1c36","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#6916]\n164:\tconst pi = {\n\n189:\t\tsendUserMessage(content) {\n\n192:\t\t},\n193:\t};\n194:\tconst runSptCommand = async (args, input, runOptions) => {\n195:\t\tconst call = { args: [...args], input, options: runOptions };\n196:\t\tcalls.push(call);\n197:\t\tconst overridden = await options.onRun?.(call);\n\n203:\t};\n\n219:\t\tcheckUpdates: options.checkUpdates ?? false,\n220:\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\n221:\t\tplatform: options.platform,\n222:\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n223:\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n227:\t\tshutdownBudgetMs: options.shutdownBudgetMs,\n228:\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\n229:\t\tshortformCommandTimeoutMs: options.shortformCommandTimeoutMs,\n230:\t\tlistenerStableMs: options.listenerStableMs ?? false,\n231:\t\tkillForceMs: options.killForceMs ?? 4,"}],"details":{"diff":" 164|\tconst pi = {\n\n 189|\t\tsendUserMessage(content) {\n\n 192|\t\t},\n 193|\t};\n-194|\tconst runSptCommand = async (args, input) => {\n-195|\t\tconst call = { args: [...args], input };\n+194|\tconst runSptCommand = async (args, input, runOptions) => {\n+195|\t\tconst call = { args: [...args], input, options: runOptions };\n 196|\t\tcalls.push(call);\n 197|\t\tconst overridden = await options.onRun?.(call);\n\n 203|\t};\n\n 219|\t\tcheckUpdates: options.checkUpdates ?? false,\n 220|\t\tfetchLatestAdapterVersion: options.fetchLatestAdapterVersion,\n+221|\t\tplatform: options.platform,\n 221|\t\tacceptedBytesLimit: options.acceptedBytesLimit,\n 222|\t\tacceptedQueueLimit: options.acceptedQueueLimit,\n 226|\t\tshutdownBudgetMs: options.shutdownBudgetMs,\n 227|\t\tshutdownCommandTimeoutMs: options.shutdownCommandTimeoutMs,\n+229|\t\tshortformCommandTimeoutMs: options.shortformCommandTimeoutMs,\n 228|\t\tlistenerStableMs: options.listenerStableMs ?? false,\n 229|\t\tkillForceMs: options.killForceMs ?? 4,","firstChangedLine":194,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192650132}}
{"type":"message","id":"21e60b1d","parentId":"eb25d55a","timestamp":"2026-07-16T09:04:18.034Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Hiding options in call objects**"},{"type":"toolCall","id":"call_l8zfbGXhVaudkNBBjSOqH80R|ctc_01d5553e22e4ced1016a589e90f3f0819999130043dc8c8a76","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#6916]\nSWAP 195.=195:\n+\t\tconst call = { args: [...args], input };\n+\t\tObject.defineProperty(call, \"options\", { value: runOptions });\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1317,"output":163,"cacheRead":226816,"cacheWrite":0,"totalTokens":228296,"reasoningTokens":96,"cost":{"input":0.006585000000000001,"output":0.00489,"cacheRead":0.113408,"cacheWrite":0,"total":0.124883}},"stopReason":"toolUse","timestamp":1784192650195,"responseId":"resp_01d5553e22e4ced1016a589e8a9f248199a787ee0aff5358a6","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_01d5553e22e4ced1016a589e8ecb888199b5b2e48ba9da7508","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ6QnLnAGhd14GIFpZSHOQFoMAnjLdswuZNJ_1ab5bIRiqSyi4zUzl1Dn_Ei1MlRitnKw9osHdFk4YzS_j8cNLdQ6dkW7FUCRYusU5FM5whbsgS1LvQzCs_ziawNnmhia2aRb0mf4Og0ojTExlZDOgdDBwrwMNbgdCv9QOP-Km4loVWyofqbuorNc97-PKAuskpwMXlpEkV_cnf00ggbjmYBns4LidKqp9LmouK9SreDswIgYpo7j70HgUIZUNUR10ezNXfMCaddIEETdGZ0cEKEeRnvl2jSurEovcBSM0OYr8vh4Wpghc7Ho3l4aDv5k2ERS5a5kw7RWodsm6dZb8G-FGmc7k5xX9Xoaxw3un-etAWr6BUC7E6bPo-SEz5Xj4UZ1J309LsEZ1SfSE6G9zhirpDDWEBfduQ2-BuAshwXfJ9zM0MFLXwP4RHQrWKZXVdyobNqlUzU-9i6Mp8Y8QDVEWfjfv3uIwZfi5uu-ihjhHVcHn4_PJhSMvfj5J5woE7jt3WRNolNTjSQnCobqIyh-XCAqtu1cQHBZ2PfjJRzgt7jC767H1tyROQ_UU8nTU-ZjIya7jPSjI1K8XG3cavvwQ7sVqua58kiZyYL1XFlmdu3DSk7LtYCcyXzWhW64EZ3UggM3GeFqgbmdzkyK8TNHOXFXSDcxsZ2fjmYrbZUHQk0cZN85wxBcGK9RmFxmGv0EI3vakV9tKUc6HqA82wwyRt9P1BriER4tVKFbTTY4R8Hx6m4lA2VYD2UPtrOv7t0c5XHYtjv3ZdrRaSpnzs7KDZEJ4PNYYJRlOYJwUbJpzfXu_kpJ8xRlmyYWLX712fnFdAKQaJTcshGV3Bo9nH3WaErqnOeVgsk6DeWio1DRkhKw13f6w8p--4bniAEeG7uJKBl2FqCYVamVYBQs0BO-ZPY8BcdX9NP7lILjCUxFEWsEth-9p05Nh7kFtX74fIfFww5kPS-cNycYZAuGaHF01Jq7smoJ3CzXrkUWzo-RxPBkYLQ26VB_rrVXTqSMOHi5rL9cm1i-e5yD-EtufHnaHzUlzDsh21DymyafdwgBAXLnWFXP62mQBbdaPtIJg8ht2Fo2GX5Hf1ZNuXIa3IgHJgNa2NXzagv2ieS3qcTimYtoGqX5OfitHReDzbYme4vAtWVA2dnnI6IOg1jrd6gsasmf7OW6FnhKA6GC3C5zjbEAdPtFPy9MEWSJcZlpUqTueX7nGQ_YQw08K0x7VKLJfj-NfILdaDM1pFwUoT2gBj1ox7i7Sctjrtapxm2yXMmF3-rgnZcrO_-aajepNxXwi02PyrPaeI0JBFipYHaONtCyuJm5zEMWsCDb_zRhbW4zKXoV08nVIsyG6ammYla6XKsOlNhdXjNBQpE9IT0wY5Lu0xXulZZxBiyoH0ZWz3dkawD5TGkUcADJjaJGF5-VYLh9GfwTaJKClSvq-8ulvsBxaJjKKMXoWe6p-oAgvuU0BjRUzoiYX3efRF751-5GyP1PaCnDF-MhbS2ihvV_UI=","summary":[{"type":"summary_text","text":"**Hiding options in call objects**"}]},{"id":"ctc_01d5553e22e4ced1016a589e90f3f0819999130043dc8c8a76","type":"custom_tool_call","status":"completed","call_id":"call_l8zfbGXhVaudkNBBjSOqH80R","input":"*** Begin Patch\n[tests/omp-extension.mjs#6916]\nSWAP 195.=195:\n+\t\tconst call = { args: [...args], input };\n+\t\tObject.defineProperty(call, \"options\", { value: runOptions });\n*** End Patch\n","name":"edit"}]},"duration":7839.06110000005,"ttft":4733.638799999841,"contextSnapshot":{"promptTokens":228133,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_l8zfbGXhVaudkNBBjSOqH80R|ctc_01d5553e22e4ced1016a589e90f3f0819999130043dc8c8a76","toolName":"edit","startedAt":"2026-07-16T09:04:18.035Z"},"id":"ba8f672f","parentId":"21e60b1d","timestamp":"2026-07-16T09:04:18.035Z"}
{"type":"message","id":"2b1a2aab","parentId":"ba8f672f","timestamp":"2026-07-16T09:04:18.079Z","message":{"role":"toolResult","toolCallId":"call_l8zfbGXhVaudkNBBjSOqH80R|ctc_01d5553e22e4ced1016a589e90f3f0819999130043dc8c8a76","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#9031]\n164:\tconst pi = {\n\n193:\t};\n194:\tconst runSptCommand = async (args, input, runOptions) => {\n195:\t\tconst call = { args: [...args], input };\n196:\t\tObject.defineProperty(call, \"options\", { value: runOptions });\n197:\t\tcalls.push(call);\n198:\t\tconst overridden = await options.onRun?.(call);\n\n204:\t};"}],"details":{"diff":" 164|\tconst pi = {\n\n 193|\t};\n 194|\tconst runSptCommand = async (args, input, runOptions) => {\n-195|\t\tconst call = { args: [...args], input, options: runOptions };\n+195|\t\tconst call = { args: [...args], input };\n+196|\t\tObject.defineProperty(call, \"options\", { value: runOptions });\n 196|\t\tcalls.push(call);\n 197|\t\tconst overridden = await options.onRun?.(call);\n\n 203|\t};","firstChangedLine":195,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192658079}}
{"type":"message","id":"52a7ee52","parentId":"2b1a2aab","timestamp":"2026-07-16T09:04:24.393Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Running tests after updating checkpoint type**"},{"type":"toolCall","id":"call_vNQeiVMZc8uvBuqf9cbA5rZY|fc_03748aded66d4379016a589e96ab60819ba4ecbde5261b06e7","name":"bash","arguments":{"i":"Running tests after review fixes","command":"node tests/omp-extension.mjs","cwd":".","timeout":180}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":563,"output":59,"cacheRead":227840,"cacheWrite":0,"totalTokens":228462,"reasoningTokens":17,"cost":{"input":0.0028150000000000002,"output":0.00177,"cacheRead":0.11392,"cacheWrite":0,"total":0.118505}},"stopReason":"toolUse","timestamp":1784192658125,"responseId":"resp_03748aded66d4379016a589e92b738819b99f1d405b49a499d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_03748aded66d4379016a589e95bd30819b9c94f1e149553a1f","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ6WGpXoqvDjLHbsA9YoOYD_pmwpshw3PZ8Xnoi8qbvCQw1Zvj03XvJQ_HVBEwSxIuZfXiM3WZTmEZoE7J5uEnicSg-QlYrWQspx487G2UzgApeSM2WxEBUQOEmMI9WtvYdZxtBrSxJw_eutr0bVyOfW7ubxcSdCR3W_A8Li0NU1h7vBDDj_veN8Eov1NHKy_aCKBAjdUFJf1pO6-60KGRyyGI7JK920lCkHxIopslu8UQ_dPYGJJkje6mnJTSDQ7YzbeeRBNyF1zWicbtZLHDtKzOGj0-DRzPwxcX9FKPJVyxvLEKWqrv5jtnAlY2EuXOCj2lcO9adYmoiZSultf26qFHccpna4-yzeAtgd0yB7JZMlxGm7wr89Vzjk2FBovf1SNjR7Jccs20EJd6HNsbn46L8zPYb40VX2m_AUna9HqTGScxqNxUGAGk7gJkouDbqP2d03qjFlm5C8r8pKXPghWL8WpWXdVBaznvxE6oKCudcxhCsrN0R-X7ky4IuPdiJO1oLroH5DZ1pLK43wEqSFeMeTIBMiXuPL7yjf1DcB824i9jjo9uYkG1ukvY5x2heDCHneFAeGPs-O-K1uPdlvSX9YmYzQMd1dp1nKEjDG9wsKF7fBtPOZzydbFLmYWtwL-4pYi7ZmEs7BEDcPLmupsgzyHCijBtq9DsZ4WfSVyPfRCPz81TUVp6gi8fTD9xku2nrso7rEMbesDx8WR0KuKW-4TgVuvn9JbiZXLVT0LK2MRjnIVowRFkSoA9yWYK1Kr2kyIhP5lo4ULhr1qZP7gM3U4J1HuF4yKaHlUJLQGbWAw8bFHLC7zip6qHiCcwJzv0LanXiH86X2u1MPptkK0WIy29kaChckzlhc49IANtxxpZUiedDQmsyITd3KM8hAOoJIrhBRbyqRJ8hyLjQjxfQ3YXBLPeD02DK5dYk8zManTMB84TRoEIsXaN0TNfAGrI62sKW-GetUC_p1qLrysIxMdZk8Bqs2yMU9xisR-lwFC5KMm3N_HfhaXxkRCBaC","summary":[{"type":"summary_text","text":"**Running tests after updating checkpoint type**"}]},{"id":"fc_03748aded66d4379016a589e96ab60819ba4ecbde5261b06e7","type":"function_call","status":"completed","arguments":"{\"i\":\"Running tests after review fixes\",\"command\":\"node tests/omp-extension.mjs\",\"cwd\":\".\",\"timeout\":180}","call_id":"call_vNQeiVMZc8uvBuqf9cbA5rZY","name":"bash"}]},"duration":6233.100899999961,"ttft":6231.832200000063,"contextSnapshot":{"promptTokens":228403,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_vNQeiVMZc8uvBuqf9cbA5rZY|fc_03748aded66d4379016a589e96ab60819ba4ecbde5261b06e7","toolName":"bash","startedAt":"2026-07-16T09:04:24.393Z","args":{"command":"node tests/omp-extension.mjs"},"intent":"Running tests after review fixes"},"id":"7d859790","parentId":"52a7ee52","timestamp":"2026-07-16T09:04:24.393Z"}
{"type":"message","id":"6ca14035","parentId":"7d859790","timestamp":"2026-07-16T09:04:24.609Z","message":{"role":"toolResult","toolCallId":"call_vNQeiVMZc8uvBuqf9cbA5rZY|fc_03748aded66d4379016a589e96ab60819ba4ecbde5261b06e7","toolName":"bash","content":[{"type":"text","text":"node:internal/modules/run_main:107\n    triggerUncaughtException(\n    ^\n\nAssertionError [ERR_ASSERTION]: Expected values to be strictly equal:\n\nfalse !== true\n\n    at testNativeCheckpointTool (file:///C:/Users/decid/Documents/projects/omp-spt/tests/omp-extension.mjs:1873:9)\n    at async file:///C:/Users/decid/Documents/projects/omp-spt/tests/omp-extension.mjs:1937:1 {\n  generatedMessage: true,\n  code: 'ERR_ASSERTION',\n  actual: false,\n  expected: true,\n  operator: 'strictEqual',\n  diff: 'simple'\n}\n\nNode.js v25.8.2\n\n\nWall time: 0.21 seconds\n\nCommand exited with code 1"}],"details":{"timeoutSeconds":180,"wallTimeMs":214.58179999981076,"exitCode":1},"isError":true,"timestamp":1784192664608}}
{"type":"message","id":"3aab9a57","parentId":"6ca14035","timestamp":"2026-07-16T09:04:29.342Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Modifying test harness and ordering**"},{"type":"toolCall","id":"call_YcUldN0mfE11x1r5K296muRF|fc_025de11d6579bf41016a589e9d05d88199be941a0e17247ac1","name":"read","arguments":{"i":"Reading checkpoint regression test","path":"tests/omp-extension.mjs","selector":"1855-1915"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":793,"output":91,"cacheRead":227840,"cacheWrite":0,"totalTokens":228724,"reasoningTokens":52,"cost":{"input":0.003965000000000001,"output":0.0027300000000000002,"cacheRead":0.11392,"cacheWrite":0,"total":0.120615}},"stopReason":"toolUse","timestamp":1784192664664,"responseId":"resp_025de11d6579bf41016a589e9921648199ab243b6bb0a286a6","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_025de11d6579bf41016a589e9b3ea881999976099f63d01021","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ6dIRgH3Eb4gdsHrXvIoCWuVkfSnYQv1hM5NGfNwPRvJdAs8_toASE2uPEN5jE7_jxeE7B52qqyGOB7IFUrRbRZsLQtMjJLQRrbRkLq-RIcbLRBzA23gJ0J38nZuFLGoLNDSC1tsttnq_rRTyDWz08uBHJoZj6L7-9eQM5kSpEN81jtaoUYVDGlEVhYDPGF4htPa9HQLMLKK-xMdXkxL4Asj1PJy7WxyPsGxW7nA9tVbLivtTFaOqj2UvoczRCwyC-wbxByLD3ywclLlSgpnh-_iM_BnzmSV2R-07Kgagdq4W4kaviulO-gLK-M7-mU-nRuG_SP0IypCttVM0cu8joL-er6ms2kh_OuEhGlyUQy0ubTGXdmu4A2Rlw86dKWdZglpSg71P3YwgRZVKSZaow0fsZsUJbM1fldY3G-LP2duwH9jA-iNkW4C39DbJ6C7XjCMQ2Q6rnq0MLgwOr7tiArQscxHVaBvTK7AiWky-bZkrdy1fY7iF34LRDr1INDsbFVzjngQYbmaNuxzy9rzmCcybi6CRicRyqxZ2D8sKtTP0V4T1n39csXkoVbA4-WQTBcWyf0AyiwEysK_5DmIoEjIne9TpLzkMI6UTqpB1fVCNLPKLWXKY1s01xTqbtjzdpCifDldQmt7msecO59a_djl-umWRLDd42ryIOlKO-FAFBzVyYJw5HoAQJBclfFQCP-UixhH5XFOGe-4gsMqKtgKrDiCWzmbLlXHUGdcts09xwJdd04tJ63HBrzXKLtWTmvkNqqsi5l69O1ctz3Ab2apnzI9kVBSelx8CuTb_L_Q2mxHd88rTvI4TCeiZlVMX7jzz2etufgG0dnZpzOrZRh05o6js7gm0I-aQktuZ7bmo-DUJmUly4Efpk3TsNG_d1uF4PXkvxWUplTx601YmbsisWlqmKZ-UPPZCUd1yaAVDDp4Bs21ZUknUztG1RCUjE1YZBZ9OhBfwjqKeJPB5NsnthyO3uWyKMCCYqy8abU8tvfVkVQ_AM_wYjmSbn-XS6976p8BXZuswSs2IqoH5m9F8npx5uYIDl_TzMKOpI-Ta51guZcTcNW3abJNBamCpWxCCje3sdU4eNYrXFYGtmXnGIaQtzuZvyPhSmOw433ENQ5tW9oJ9qeUhc-2OzWxW1ch_zyufg_eDDrw2NlXd1ERM59hPH_slXwsUSQpGGJxEQuUaklIULT8oFBhIwydmkvmKplJ_sVibmsK5FOseqgdrHOvkcjosoWm7Bt4-3IBXf-yg1S6CWipBEePfGiZ094","summary":[{"type":"summary_text","text":"**Modifying test harness and ordering**"}]},{"id":"fc_025de11d6579bf41016a589e9d05d88199be941a0e17247ac1","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading checkpoint regression test\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1855-1915\"}","call_id":"call_YcUldN0mfE11x1r5K296muRF","name":"read"}]},"duration":4678.201899999753,"ttft":2576.537299999967,"contextSnapshot":{"promptTokens":228633,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_YcUldN0mfE11x1r5K296muRF|fc_025de11d6579bf41016a589e9d05d88199be941a0e17247ac1","toolName":"read","startedAt":"2026-07-16T09:04:29.343Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading checkpoint regression test"},"id":"535c388a","parentId":"3aab9a57","timestamp":"2026-07-16T09:04:29.343Z"}
{"type":"message","id":"fcd36e5d","parentId":"535c388a","timestamp":"2026-07-16T09:04:29.360Z","message":{"role":"toolResult","toolCallId":"call_YcUldN0mfE11x1r5K296muRF|fc_025de11d6579bf41016a589e9d05d88199be941a0e17247ac1","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#9031]\n1794:async function testPeerShortformParsingAndDispatch() {\n…\n1848:\tawait harness.emit(\"agent_end\", {\n1849:\t\tmessages: [\n…\n1854:\t\t],\n1855:\t});\n1856:\tassert.equal(commandCalls(harness, \"send\").length, 3);\n1857:\tassert.equal(harness.sentMessages.length, 1);\n1858:\tawait harness.emit(\"session_shutdown\");\n1859:}\n1860:\n1861:// [unit->REQ-PARITY-CHECKPOINT]\n1862:async function testNativeCheckpointTool() {\n1863:\tconst harness = createHarness();\n1864:\tawait harness.emit(\"session_start\");\n1865:\tconst tool = harness.tools.get(\"spt_checkpoint\");\n1866:\tconst result = await tool.execute(\n1867:\t\t\"tool-1\",\n1868:\t\t{ wake: \"Continue release preparation.\" },\n1869:\t\tundefined,\n1870:\t\tundefined,\n1871:\t\tharness.ctx,\n1872:\t);\n1873:\tassert.equal(result.details.ok, true);\n1874:\tassert.equal(harness.compactions.length, 1);\n1875:\tassert.deepEqual(harness.sentMessages[0], {\n1876:\t\tmessage: {\n1877:\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\n1878:\t\t\tcontent: \"Continue release preparation.\",\n1879:\t\t\tdisplay: true,\n1880:\t\t\tattribution: \"user\",\n1881:\t\t},\n1882:\t\tdelivery: { deliverAs: \"nextTurn\", triggerTurn: true },\n1883:\t});\n1884:\tawait harness.emit(\"session_shutdown\");\n1885:\n1886:\tconst ready = createHarness({ id: null });\n1887:\tawait ready.emit(\"session_start\");\n1888:\tawait ready.commands.get(\"ready\").handler(\"plain-ready\", ready.ctx);\n1889:\tconst refused = await ready.tools\n1890:\t\t.get(\"spt_checkpoint\")\n1891:\t\t.execute(\"tool-2\", {}, undefined, undefined, ready.ctx);\n1892:\tassert.equal(refused.isError, true);\n1893:\tassert.equal(refused.details.reason, \"not-live\");\n1894:\tassert.deepEqual(ready.compactions, []);\n1895:\tawait ready.emit(\"session_shutdown\");\n1896:\n1897:\tconst failed = createHarness({\n1898:\t\tonCompact() {\n1899:\t\t\tthrow new Error(\"native compaction cancelled\");\n1900:\t\t},\n1901:\t});\n1902:\tawait failed.emit(\"session_start\");\n1903:\tconst failure = await failed.tools\n1904:\t\t.get(\"spt_checkpoint\")\n1905:\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\n1906:\tassert.equal(failure.isError, true);\n1907:\tassert.match(failure.content[0].text, /native compaction cancelled/);\n1908:\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\n1909:\tawait failed.emit(\"session_shutdown\");\n1910:}\n1911:\n1912:await testParsingAndReplies();\n1913:await testRunSptRejectsStdinErrorsAndHungCommands();\n1914:await testLifecycleCustodyAndContext();\n1915:await testDeferredBindLifecycleSerialization();\n1916:await testOutcomeSendRetriesAndExhaustion();\n1917:await testSubmissionFailureAdvancesQueue();\n1918:await testFailedIdleRecoveryFailsClosed();\n\n[Showing lines 1854-1918 of 1940. Use :1919 to continue]"}],"details":{"truncation":{"content":"\t\t],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\").length, 3);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-CHECKPOINT]\r\nasync function testNativeCheckpointTool() {\r\n\tconst harness = createHarness();\r\n\tawait harness.emit(\"session_start\");\r\n\tconst tool = harness.tools.get(\"spt_checkpoint\");\r\n\tconst result = await tool.execute(\r\n\t\t\"tool-1\",\r\n\t\t{ wake: \"Continue release preparation.\" },\r\n\t\tundefined,\r\n\t\tundefined,\r\n\t\tharness.ctx,\r\n\t);\r\n\tassert.equal(result.details.ok, true);\r\n\tassert.equal(harness.compactions.length, 1);\r\n\tassert.deepEqual(harness.sentMessages[0], {\r\n\t\tmessage: {\r\n\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\r\n\t\t\tcontent: \"Continue release preparation.\",\r\n\t\t\tdisplay: true,\r\n\t\t\tattribution: \"user\",\r\n\t\t},\r\n\t\tdelivery: { deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t});\r\n\tawait harness.emit(\"session_shutdown\");\r\n\r\n\tconst ready = createHarness({ id: null });\r\n\tawait ready.emit(\"session_start\");\r\n\tawait ready.commands.get(\"ready\").handler(\"plain-ready\", ready.ctx);\r\n\tconst refused = await ready.tools\r\n\t\t.get(\"spt_checkpoint\")\r\n\t\t.execute(\"tool-2\", {}, undefined, undefined, ready.ctx);\r\n\tassert.equal(refused.isError, true);\r\n\tassert.equal(refused.details.reason, \"not-live\");\r\n\tassert.deepEqual(ready.compactions, []);\r\n\tawait ready.emit(\"session_shutdown\");\r\n\r\n\tconst failed = createHarness({\r\n\t\tonCompact() {\r\n\t\t\tthrow new Error(\"native compaction cancelled\");\r\n\t\t},\r\n\t});\r\n\tawait failed.emit(\"session_start\");\r\n\tconst failure = await failed.tools\r\n\t\t.get(\"spt_checkpoint\")\r\n\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\r\n\tassert.equal(failure.isError, true);\r\n\tassert.match(failure.content[0].text, /native compaction cancelled/);\r\n\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\r\n\tawait failed.emit(\"session_shutdown\");\r\n}\r\n\r\nawait testParsingAndReplies();\r\nawait testRunSptRejectsStdinErrorsAndHungCommands();\r\nawait testLifecycleCustodyAndContext();\r\nawait testDeferredBindLifecycleSerialization();\r\nawait testOutcomeSendRetriesAndExhaustion();\r\nawait testSubmissionFailureAdvancesQueue();\r\nawait testFailedIdleRecoveryFailsClosed();\r","truncated":true,"truncatedBy":"lines","totalLines":87,"totalBytes":2197,"outputLines":65,"outputBytes":2197,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"async function testPeerShortformParsingAndDispatch() {\n…\n\tawait harness.emit(\"agent_end\", {\n\t\tmessages: [\n…\n\t\t],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\").length, 3);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-CHECKPOINT]\r\nasync function testNativeCheckpointTool() {\r\n\tconst harness = createHarness();\r\n\tawait harness.emit(\"session_start\");\r\n\tconst tool = harness.tools.get(\"spt_checkpoint\");\r\n\tconst result = await tool.execute(\r\n\t\t\"tool-1\",\r\n\t\t{ wake: \"Continue release preparation.\" },\r\n\t\tundefined,\r\n\t\tundefined,\r\n\t\tharness.ctx,\r\n\t);\r\n\tassert.equal(result.details.ok, true);\r\n\tassert.equal(harness.compactions.length, 1);\r\n\tassert.deepEqual(harness.sentMessages[0], {\r\n\t\tmessage: {\r\n\t\t\tcustomType: \"omp-spt-checkpoint-wake\",\r\n\t\t\tcontent: \"Continue release preparation.\",\r\n\t\t\tdisplay: true,\r\n\t\t\tattribution: \"user\",\r\n\t\t},\r\n\t\tdelivery: { deliverAs: \"nextTurn\", triggerTurn: true },\r\n\t});\r\n\tawait harness.emit(\"session_shutdown\");\r\n\r\n\tconst ready = createHarness({ id: null });\r\n\tawait ready.emit(\"session_start\");\r\n\tawait ready.commands.get(\"ready\").handler(\"plain-ready\", ready.ctx);\r\n\tconst refused = await ready.tools\r\n\t\t.get(\"spt_checkpoint\")\r\n\t\t.execute(\"tool-2\", {}, undefined, undefined, ready.ctx);\r\n\tassert.equal(refused.isError, true);\r\n\tassert.equal(refused.details.reason, \"not-live\");\r\n\tassert.deepEqual(ready.compactions, []);\r\n\tawait ready.emit(\"session_shutdown\");\r\n\r\n\tconst failed = createHarness({\r\n\t\tonCompact() {\r\n\t\t\tthrow new Error(\"native compaction cancelled\");\r\n\t\t},\r\n\t});\r\n\tawait failed.emit(\"session_start\");\r\n\tconst failure = await failed.tools\r\n\t\t.get(\"spt_checkpoint\")\r\n\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\r\n\tassert.equal(failure.isError, true);\r\n\tassert.match(failure.content[0].text, /native compaction cancelled/);\r\n\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\r\n\tawait failed.emit(\"session_shutdown\");\r\n}\r\n\r\nawait testParsingAndReplies();\r\nawait testRunSptRejectsStdinErrorsAndHungCommands();\r\nawait testLifecycleCustodyAndContext();\r\nawait testDeferredBindLifecycleSerialization();\r\nawait testOutcomeSendRetriesAndExhaustion();\r\nawait testSubmissionFailureAdvancesQueue();\r\nawait testFailedIdleRecoveryFailsClosed();\r","startLine":1794,"lineNumbers":[1794,null,1848,1849,null,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1940,"totalBytes":2197,"outputLines":65,"outputBytes":2197,"shownRange":{"start":1854,"end":1918},"nextOffset":1919}}},"isError":false,"timestamp":1784192669359}}
{"type":"message","id":"008eccde","parentId":"fcd36e5d","timestamp":"2026-07-16T09:04:43.689Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding launch-time readiness handling**"},{"type":"toolCall","id":"call_16wyOlWG1a7RhYZSx4DVS3IV|ctc_07335332475c63f9016a589ea31b6c8199a060f7a6b6911610","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#9031]\nSWAP 1863.=1872:\n+\tconst compactGate = deferred();\n+\tconst harness = createHarness({\n+\t\tonCompact() {\n+\t\t\treturn compactGate.promise;\n+\t\t},\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tconst tool = harness.tools.get(\"spt_checkpoint\");\n+\tconst checkpoint = tool.execute(\n+\t\t\"tool-1\",\n+\t\t{ wake: \"Continue release preparation.\" },\n+\t\tundefined,\n+\t\tundefined,\n+\t\tharness.ctx,\n+\t);\n+\tawait flush();\n+\tassert.deepEqual(harness.sentMessages, [], \"checkpoint wake must wait for native compaction\");\n+\tcompactGate.resolve();\n+\tconst result = await checkpoint;\nINS.POST 1895:\n+\tconst launchedReady = createHarness({\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+\t\t\t\treturn JSON.stringify({ endpoint_type: \"ready_agent\" });\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait launchedReady.emit(\"session_start\");\n+\tconst launchedRefusal = await launchedReady.tools\n+\t\t.get(\"spt_checkpoint\")\n+\t\t.execute(\"tool-launch-ready\", {}, undefined, undefined, launchedReady.ctx);\n+\tassert.equal(launchedRefusal.details.reason, \"not-live\");\n+\tassert.deepEqual(launchedReady.compactions, []);\n+\tawait launchedReady.emit(\"session_shutdown\");\n+\nINS.POST 1900:\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n+\t\t\t}\n+\t\t},\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1650,"output":593,"cacheRead":227840,"cacheWrite":0,"totalTokens":230083,"reasoningTokens":147,"cost":{"input":0.00825,"output":0.01779,"cacheRead":0.11392,"cacheWrite":0,"total":0.13996}},"stopReason":"toolUse","timestamp":1784192669404,"responseId":"resp_07335332475c63f9016a589e9dc87c81999c88319e08afc3c7","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_07335332475c63f9016a589ea004588199ab4fd2f9511b539f","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ6jl_-QBc0VYIdGrllvtYh1TqMAbbwOIkKUlFTlbljv4zyzu80o2-E_c4seKyJhVRyBM8RB3gNSeBitTpWRe51Rv2BiMq-CkAQeX5V1q9MZ8pvYD1pSlpkG4nsnQDcAIzzPCfke1fteopGnkdyIdV-c7CtRV9Ja4bNJ0IiMgC8ELi_R8b-HPJLrQzg_7dUKol9ja1Riiw_1RArjxwoUB4z7RPUQCVd0l3rRwbL8qej3wV5FaGDzW_oos4dcG36po4Bt_IdfH0AtAAf7V7Qo53aFjdx9dUikvcorIoAYmiVCCkDAqp6MM4NDA6-bpF5dO9HBuZOyE0jchhGZKc0Am8QZ0tnnKFp6a8WtWJRHJw-HfviK_ZPoJabzNirEPNjS1xsCjub3Kb7y0rQkZO3zwbhL8dJQkVmwN8Zxc0W34OFQpcqtc58z2FlwaQH-F2nddLeLTV0ENRPODS61jgt9bx4nn68LYCBgZt4e4EpXOjHJJW2q2WrPY8Cke1G4vQgt1PYQj5d3a5b_zkqHnf01JvFf9FbzDGEN7XDiZNdJxcVIvmRj5QwI8Yk81xG3Wr4P5pnNGFiKycULit97ynsrDG9dTGYqL3AVbWFb9Z1-KmuXHCPBnjgVICKV29eieh-mzonvYDv6Uvx8I20m7aiInh-6vjx4D35O4rmqflgdyefg__THKIUI-RC8RYd9WZdgta-BDBk5w3B_iFUYdCGbhuMgdyQ9LMzv1rrCSESzBt6AQ8tjqfRahO1l3wFbUb1jP0zg8DNUbq2saBXKYXrUwx1fCahddCyoECRDaHDuuim2eUBsX9ydHc_YLqJjmdleS7nkxXD66J29Elkl-w_fV0M3aS8yZVGkN4ZmEPe2SVyO1pATWFTmbyPMbti_T3FlXziVk3ITFTRsEGBSBKkb6xoxPEN4j98hMZZYXtbCtOvWWsW4IuNqSgXVgTAiucw1iIXk0XDBar0QNpz4VO3XLEB-CyiM6SyWIcwgeqhgJ7Bo1UE1gRxMklXJJQ5SGn8shZYitBOH1EYGRrNJP8RZr1c5asMi5HgGGtocw8dKs2AuRobwUvcPQ5oFQJ-AzgMTr8LYM1yv9GfTWlFFoU05zn5BUZWbeeEth72kZOCZ-T9AdkBlCpBEL6w1FutJgtKs-L6W_Pvs3snPdxv8bJQE0w9mhhOwfsyFsSMPiuwM47bTuC9Azn5ra8xwoc6TwIiTC7i97EtCX_Uktyhit2y8IY-lkyBrwqu-TYHbFHZCb_RI5r3DZz_qcR-jzcnxYFA9p4YLojRgWDzcZhFyO-l6rD7J4e8wxS3cdKCQB6JEk8R0TsJq_qxYjIgSjwl0RLhirWRO1dSaGCnpTLP3JRz9W2NTw1UcsbcIlC0-_kN7dyAJPPyt4MOFeWZkuMtjQHYoLP7GHEPdZx-Dn3NJen_v00NlJuO5oVpTYJTjeiQIy2_WMQ7YneMvsCdtEsedYSIHUx0iRvl9xFH7Q-OOCPfHMiTZ4uDnINyJzXzkHYhbloWvvB7s0OcED9bBMjlP5U-nqog0wPZYZQmGCYIDsZ1rEM7snFpXwE3PtxTWzVgXsDGAuwGaIjUeapKUYAdnuXQTdoRPgLA7bjkoZ7bjjdRtj-gi2gx9YuEsX2Dq8I5G1tbEz6hysgz_jtNj1M4sdsB8BNg84LABznfoqQ89yI6RTKB03pSSyrxyyOMe78uZIwcOQPYAEFMbvdIh_JCYqYdDBounfaqC754qiIH6DzfBIgkUNUi75RM8oCyZ9Hhdl9WSkhGaz3pjtxQxyQQWacnlgGCpniZz5MkI3dw5JXrWbeSoyQ==","summary":[{"type":"summary_text","text":"**Adding launch-time readiness handling**"}]},{"id":"ctc_07335332475c63f9016a589ea31b6c8199a060f7a6b6911610","type":"custom_tool_call","status":"completed","call_id":"call_16wyOlWG1a7RhYZSx4DVS3IV","input":"*** Begin Patch\n[tests/omp-extension.mjs#9031]\nSWAP 1863.=1872:\n+\tconst compactGate = deferred();\n+\tconst harness = createHarness({\n+\t\tonCompact() {\n+\t\t\treturn compactGate.promise;\n+\t\t},\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait harness.emit(\"session_start\");\n+\tconst tool = harness.tools.get(\"spt_checkpoint\");\n+\tconst checkpoint = tool.execute(\n+\t\t\"tool-1\",\n+\t\t{ wake: \"Continue release preparation.\" },\n+\t\tundefined,\n+\t\tundefined,\n+\t\tharness.ctx,\n+\t);\n+\tawait flush();\n+\tassert.deepEqual(harness.sentMessages, [], \"checkpoint wake must wait for native compaction\");\n+\tcompactGate.resolve();\n+\tconst result = await checkpoint;\nINS.POST 1895:\n+\tconst launchedReady = createHarness({\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+\t\t\t\treturn JSON.stringify({ endpoint_type: \"ready_agent\" });\n+\t\t\t}\n+\t\t},\n+\t});\n+\tawait launchedReady.emit(\"session_start\");\n+\tconst launchedRefusal = await launchedReady.tools\n+\t\t.get(\"spt_checkpoint\")\n+\t\t.execute(\"tool-launch-ready\", {}, undefined, undefined, launchedReady.ctx);\n+\tassert.equal(launchedRefusal.details.reason, \"not-live\");\n+\tassert.deepEqual(launchedReady.compactions, []);\n+\tawait launchedReady.emit(\"session_shutdown\");\n+\nINS.POST 1900:\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n+\t\t\t}\n+\t\t},\n*** End Patch\n","name":"edit"}]},"duration":14250.14400000032,"ttft":2590.25530000031,"contextSnapshot":{"promptTokens":229490,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_16wyOlWG1a7RhYZSx4DVS3IV|ctc_07335332475c63f9016a589ea31b6c8199a060f7a6b6911610","toolName":"edit","startedAt":"2026-07-16T09:04:43.690Z"},"id":"09958120","parentId":"008eccde","timestamp":"2026-07-16T09:04:43.690Z"}
{"type":"message","id":"e6cc2025","parentId":"09958120","timestamp":"2026-07-16T09:04:43.731Z","message":{"role":"toolResult","toolCallId":"call_16wyOlWG1a7RhYZSx4DVS3IV|ctc_07335332475c63f9016a589ea31b6c8199a060f7a6b6911610","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#5A93]\n1861:// [unit->REQ-PARITY-CHECKPOINT]\n1862:async function testNativeCheckpointTool() {\n1863:\tconst compactGate = deferred();\n1864:\tconst harness = createHarness({\n…\n1872:\t\t},\n1873:\t});\n1874:\tawait harness.emit(\"session_start\");\n1875:\tconst tool = harness.tools.get(\"spt_checkpoint\");\n1876:\tconst checkpoint = tool.execute(\n1877:\t\t\"tool-1\",\n1878:\t\t{ wake: \"Continue release preparation.\" },\n1881:\t\tharness.ctx,\n1882:\t);\n1883:\tawait flush();\n1884:\tassert.deepEqual(harness.sentMessages, [], \"checkpoint wake must wait for native compaction\");\n1885:\tcompactGate.resolve();\n1886:\tconst result = await checkpoint;\n1887:\tassert.equal(result.details.ok, true);\n1888:\tassert.equal(harness.compactions.length, 1);\n1908:\tassert.deepEqual(ready.compactions, []);\n1909:\tawait ready.emit(\"session_shutdown\");\n1910:\tconst launchedReady = createHarness({\n1911:\t\tonRun(call) {\n…\n1922:\tassert.deepEqual(launchedReady.compactions, []);\n1923:\tawait launchedReady.emit(\"session_shutdown\");\n1924:\n1925:\n1926:\tconst failed = createHarness({\n1927:\t\tonCompact() {\n1928:\t\t\tthrow new Error(\"native compaction cancelled\");\n1929:\t\t},\n1930:\t\tonRun(call) {\n1931:\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n1932:\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n1933:\t\t\t}\n1934:\t\t},\n1935:\t});\n1936:\tawait failed.emit(\"session_start\");\n\n1944:}"}],"details":{"diff":" 1861|// [unit->REQ-PARITY-CHECKPOINT]\n 1862|async function testNativeCheckpointTool() {\n-1863|\tconst harness = createHarness();\n+1863|\tconst compactGate = deferred();\n+1864|\tconst harness = createHarness({\n+1865|\t\tonCompact() {\n+1866|\t\t\treturn compactGate.promise;\n+1867|\t\t},\n+1868|\t\tonRun(call) {\n+1869|\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+1870|\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n+1871|\t\t\t}\n+1872|\t\t},\n+1873|\t});\n 1864|\tawait harness.emit(\"session_start\");\n 1865|\tconst tool = harness.tools.get(\"spt_checkpoint\");\n-1866|\tconst result = await tool.execute(\n+1876|\tconst checkpoint = tool.execute(\n 1867|\t\t\"tool-1\",\n 1868|\t\t{ wake: \"Continue release preparation.\" },\n 1871|\t\tharness.ctx,\n 1872|\t);\n+1883|\tawait flush();\n+1884|\tassert.deepEqual(harness.sentMessages, [], \"checkpoint wake must wait for native compaction\");\n+1885|\tcompactGate.resolve();\n+1886|\tconst result = await checkpoint;\n 1873|\tassert.equal(result.details.ok, true);\n 1874|\tassert.equal(harness.compactions.length, 1);\n 1894|\tassert.deepEqual(ready.compactions, []);\n 1895|\tawait ready.emit(\"session_shutdown\");\n+1910|\tconst launchedReady = createHarness({\n+1911|\t\tonRun(call) {\n+1912|\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+1913|\t\t\t\treturn JSON.stringify({ endpoint_type: \"ready_agent\" });\n+1914|\t\t\t}\n+1915|\t\t},\n+1916|\t});\n+1917|\tawait launchedReady.emit(\"session_start\");\n+1918|\tconst launchedRefusal = await launchedReady.tools\n+1919|\t\t.get(\"spt_checkpoint\")\n+1920|\t\t.execute(\"tool-launch-ready\", {}, undefined, undefined, launchedReady.ctx);\n+1921|\tassert.equal(launchedRefusal.details.reason, \"not-live\");\n+1922|\tassert.deepEqual(launchedReady.compactions, []);\n+1923|\tawait launchedReady.emit(\"session_shutdown\");\n 1896|\n+1925|\n 1897|\tconst failed = createHarness({\n 1898|\t\tonCompact() {\n 1899|\t\t\tthrow new Error(\"native compaction cancelled\");\n 1900|\t\t},\n+1930|\t\tonRun(call) {\n+1931|\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n+1932|\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n+1933|\t\t\t}\n+1934|\t\t},\n 1901|\t});\n 1902|\tawait failed.emit(\"session_start\");\n\n 1910|}","firstChangedLine":1863,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192683730}}
{"type":"message","id":"e1cefb0b","parentId":"e6cc2025","timestamp":"2026-07-16T09:04:48.078Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Reviewing boundary test case at 1670**"},{"type":"toolCall","id":"call_Hm83m9u1JqhGhnRSqq3qvdU9|fc_043a62843ef7c8a3016a589eaf97c0819bacf360cb9c7f5643","name":"read","arguments":{"i":"Reading active-boundary test","path":"tests/omp-extension.mjs","selector":"1680-1770"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1628,"output":58,"cacheRead":228864,"cacheWrite":0,"totalTokens":230550,"reasoningTokens":18,"cost":{"input":0.008140000000000001,"output":0.00174,"cacheRead":0.11443199999999999,"cacheWrite":0,"total":0.12431199999999999}},"stopReason":"toolUse","timestamp":1784192683784,"responseId":"resp_043a62843ef7c8a3016a589eac79a8819baaa0a9a220eb0071","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_043a62843ef7c8a3016a589eaeac04819ba9906bd9e4f2f145","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ6v6wN15Qzw2s0mCE1xBgRxgOhFgXfb28TjWB-4s6pKFrmBRudobhUGFqHz8rw3WuarKwrKRIP1sNb5BO5-NM9tOE8jhH8l_TwOSdBjfsLgl9jZxR_Ourz7WB_m7Rxup8f-YpkEUZJzR92d9HuYfoCJxgHeTw7C0Z2mc2a2TOtJiLs1vsvM47nYnNmUGsMXmd2Wzl30kRn0OBfiaobYg-gse5UjIIWTWhjUE8IOjNXIWT4iTjkl9iuJks18puiuW1Gy1MvANPc-AaT8OnakljiYEpuFQY62aSlZ_bN00CYhP3EvEiH9mRwp9JalxFFNxtDISrovMRx6hZQY25iRrmwdNWml0bTGqJMDa1AChD1RCEJYdyLG0ozhp-RzHn3TYkcFyzygpkU67WogbOF5FSmQZK67TIePX2HTFKYT6s3VAmCv9a5paxtCvoI5EptQX9hrqd0tiGzZ86Dkj6j7dxpD-uaA7YFAJPInnFeaIQK-91q_6qS_JGcoA_8-xqhP5YtjTTcVUE7eKMl8Wz8ldicrWNG0Ito-E5xcgb5YaKojvIZSv_ZFH_xpYRMYI_fqyxRCfxo_IS1PvtcMZW8Qobr88tZXM35uNcyoz8pxXGXAVOAt_yM_cg2L1L_-Vp56byxZEil1_RSpk2YsLAQUle543x5KnEqDciBcAk0e-WsBYK3y1Fb3uzA6jGkud65bNx05W4fY9GrqiFObk_g2NgQQbXhFnMCEHUnqdGiPMk8RkMaA6Kdf2fnC3jEgjfun7B-Y23ytj_FsJmcZVF4haawUpEMomFkL5Dy4o6UoNOnMQV1Lj3OLa8Fstpi2wFfR78SsQEzUH3aK4CceVWx_tRCOlRA0FVTyThBrOP-9lCNGngdHp2SsdgRLIU_z7E3HVh4L4zhY5gB595-pVWJh1SsPoGK5BHwyxdNkyEbh4F9LkaNia4VnY4Jyvgf7iLIndsajmSKc0hKYPusVQmY27XK0i_qel9txu4KI2lel9U0Y3gFL901M-j7TU60cQAiIo3MH","summary":[{"type":"summary_text","text":"**Reviewing boundary test case at 1670**"}]},{"id":"fc_043a62843ef7c8a3016a589eaf97c0819bacf360cb9c7f5643","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading active-boundary test\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1680-1770\"}","call_id":"call_Hm83m9u1JqhGhnRSqq3qvdU9","name":"read"}]},"duration":4293.795900000259,"ttft":2870.277400000021,"contextSnapshot":{"promptTokens":230492,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Hm83m9u1JqhGhnRSqq3qvdU9|fc_043a62843ef7c8a3016a589eaf97c0819bacf360cb9c7f5643","toolName":"read","startedAt":"2026-07-16T09:04:48.078Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading active-boundary test"},"id":"91df9586","parentId":"e1cefb0b","timestamp":"2026-07-16T09:04:48.078Z"}
{"type":"message","id":"b76c1108","parentId":"91df9586","timestamp":"2026-07-16T09:04:48.094Z","message":{"role":"toolResult","toolCallId":"call_Hm83m9u1JqhGhnRSqq3qvdU9|fc_043a62843ef7c8a3016a589eaf97c0819bacf360cb9c7f5643","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#5A93]\n1635:async function testStartupBriefHintsAndUpdateNotices() {\n…\n1670:\tfor (const expected of [\n…\n1679:\t\t\"spt adapter version omp-spt\",\n1680:\t\t\"spt update\",\n1681:\t\t\"Use extension-native `/live`\",\n1682:\t\t\"omp-spt v0.3.0 is available\",\n1683:\t\t\"spt adapter update omp-spt\",\n1684:\t\t\"spt-core v1.2.0 is available\",\n1685:\t]) {\n1686:\t\tassert.match(injected, new RegExp(expected.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\n1687:\t}\n1688:\tconst quiet = await harness.emit(\"before_agent_start\", {\n1689:\t\tprompt: \"Review live reload, identity matrices, message queues, subnet masks, and checkpoint files.\",\n1690:\t\tsystemPrompt: [\"base\"],\n1691:\t});\n1692:\tassert.equal(quiet, undefined, \"related technical nouns without clear SPT intent must not hint\");\n1693:\tawait harness.emit(\"session_shutdown\");\n1694:\n1695:\tconst unavailable = createHarness({\n1696:\t\tcheckUpdates: true,\n1697:\t\tfetchLatestAdapterVersion: async () => {\n1698:\t\t\tthrow new Error(\"network down\");\n1699:\t\t},\n1700:\t\tonRun(call) {\n1701:\t\t\tif (call.args[0] === \"--version\") throw new Error(\"version unavailable\");\n1702:\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\n1703:\t\t\t\tthrow new Error(\"notification store unavailable\");\n1704:\t\t\t}\n1705:\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") {\n1706:\t\t\t\tthrow new Error(\"adapter version unavailable\");\n1707:\t\t\t}\n1708:\t\t},\n1709:\t});\n1710:\tawait unavailable.emit(\"session_start\");\n1711:\tconst noClaim = await unavailable.emit(\"before_agent_start\", {\n1712:\t\tprompt: \"Continue the task.\",\n1713:\t\tsystemPrompt: [],\n1714:\t});\n1715:\tassert.ok(noClaim.systemPrompt.at(-1).includes(\"OMP SPT endpoint\"));\n1716:\tassert.ok(!noClaim.systemPrompt.at(-1).includes(\"OMP SPT updates:\"));\n1717:\tawait unavailable.emit(\"session_shutdown\");\n1718:}\n1719:\n1720:// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n1721:// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n1722:async function testActiveTurnBoundaryDeliveryAndFallback() {\n1723:\tconst harness = createHarness();\n1724:\tawait harness.emit(\"session_start\");\n1725:\tawait harness.emit(\"agent_start\");\n1726:\tconst firstEnvelope = '<EVENT type=\"msg\" from=\"first\">one</EVENT>';\n1727:\tconst secondEnvelope = '<EVENT type=\"msg\" from=\"second\">two</EVENT>';\n1728:\tharness.children[0].stdout.emit(\"data\", `${firstEnvelope}${secondEnvelope}`);\n1729:\tawait flush();\n1730:\tassert.deepEqual(harness.submitted, []);\n1731:\n1732:\tconst boundary = await harness.emit(\"context\", {\n1733:\t\tmessages: [{ role: \"user\", content: \"operator prompt\" }],\n1734:\t});\n1735:\tassert.equal(\n1736:\t\tboundary.messages.at(-1).content,\n1737:\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\n1738:\t\t\"the first accepted message must enter at the next model boundary\",\n1739:\t);\n1740:\tawait harness.emit(\"agent_end\", {\n1741:\t\tmessages: [...boundary.messages, { role: \"assistant\", content: \"first outcome\" }],\n1742:\t});\n1743:\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");\n1744:\tassert.equal(commandCalls(harness, \"send\")[0].input, \"first outcome\");\n1745:\tassert.deepEqual(harness.clock.delays(), [0]);\n1746:\tawait harness.clock.runNext(0);\n1747:\tassert.deepEqual(\n1748:\t\tharness.submitted,\n1749:\t\t['<msg from=\"second\"/>'],\n1750:\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\n1751:\t);\n1752:\tassert.ok(\n1753:\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n1754:\t\t\"active-turn delivery must use the extension listener, never a background poll\",\n1755:\t);\n1756:\tawait harness.emit(\"session_shutdown\");\n1757:}\n1758:\n1759:// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n1760:async function testAbnormalTurnsRestoreReceivability() {\n1761:\tfor (const [label, completionEvent] of [\n1762:\t\t[\"cancelled\", \"session_stop\"],\n1763:\t\t[\"interrupted\", \"session_stop\"],\n1764:\t\t[\"failed\", \"agent_end\"],\n1765:\t]) {\n1766:\t\tconst harness = createHarness();\n1767:\t\tawait harness.emit(\"session_start\");\n1768:\t\tawait harness.emit(\"agent_start\");\n1769:\t\tharness.children[0].stdout.emit(\n1770:\t\t\t\"data\",\n1771:\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\n1772:\t\t);\n1773:\t\tawait flush();\n…\n1790:\t}\n1791:}\n\n[Showing lines 1679-1773 of 1974. Use :1774 to continue]"}],"details":{"truncation":{"content":"\t\t\"spt adapter version omp-spt\",\r\n\t\t\"spt update\",\r\n\t\t\"Use extension-native `/live`\",\r\n\t\t\"omp-spt v0.3.0 is available\",\r\n\t\t\"spt adapter update omp-spt\",\r\n\t\t\"spt-core v1.2.0 is available\",\r\n\t]) {\r\n\t\tassert.match(injected, new RegExp(expected.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\r\n\t}\r\n\tconst quiet = await harness.emit(\"before_agent_start\", {\r\n\t\tprompt: \"Review live reload, identity matrices, message queues, subnet masks, and checkpoint files.\",\r\n\t\tsystemPrompt: [\"base\"],\r\n\t});\r\n\tassert.equal(quiet, undefined, \"related technical nouns without clear SPT intent must not hint\");\r\n\tawait harness.emit(\"session_shutdown\");\r\n\r\n\tconst unavailable = createHarness({\r\n\t\tcheckUpdates: true,\r\n\t\tfetchLatestAdapterVersion: async () => {\r\n\t\t\tthrow new Error(\"network down\");\r\n\t\t},\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--version\") throw new Error(\"version unavailable\");\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\r\n\t\t\t\tthrow new Error(\"notification store unavailable\");\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") {\r\n\t\t\t\tthrow new Error(\"adapter version unavailable\");\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait unavailable.emit(\"session_start\");\r\n\tconst noClaim = await unavailable.emit(\"before_agent_start\", {\r\n\t\tprompt: \"Continue the task.\",\r\n\t\tsystemPrompt: [],\r\n\t});\r\n\tassert.ok(noClaim.systemPrompt.at(-1).includes(\"OMP SPT endpoint\"));\r\n\tassert.ok(!noClaim.systemPrompt.at(-1).includes(\"OMP SPT updates:\"));\r\n\tawait unavailable.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\r\n// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\nasync function testActiveTurnBoundaryDeliveryAndFallback() {\r\n\tconst harness = createHarness();\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.emit(\"agent_start\");\r\n\tconst firstEnvelope = '<EVENT type=\"msg\" from=\"first\">one</EVENT>';\r\n\tconst secondEnvelope = '<EVENT type=\"msg\" from=\"second\">two</EVENT>';\r\n\tharness.children[0].stdout.emit(\"data\", `${firstEnvelope}${secondEnvelope}`);\r\n\tawait flush();\r\n\tassert.deepEqual(harness.submitted, []);\r\n\r\n\tconst boundary = await harness.emit(\"context\", {\r\n\t\tmessages: [{ role: \"user\", content: \"operator prompt\" }],\r\n\t});\r\n\tassert.equal(\r\n\t\tboundary.messages.at(-1).content,\r\n\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\r\n\t\t\"the first accepted message must enter at the next model boundary\",\r\n\t);\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [...boundary.messages, { role: \"assistant\", content: \"first outcome\" }],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");\r\n\tassert.equal(commandCalls(harness, \"send\")[0].input, \"first outcome\");\r\n\tassert.deepEqual(harness.clock.delays(), [0]);\r\n\tawait harness.clock.runNext(0);\r\n\tassert.deepEqual(\r\n\t\tharness.submitted,\r\n\t\t['<msg from=\"second\"/>'],\r\n\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\r\n\t);\r\n\tassert.ok(\r\n\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\r\n\t\t\"active-turn delivery must use the extension listener, never a background poll\",\r\n\t);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\nasync function testAbnormalTurnsRestoreReceivability() {\r\n\tfor (const [label, completionEvent] of [\r\n\t\t[\"cancelled\", \"session_stop\"],\r\n\t\t[\"interrupted\", \"session_stop\"],\r\n\t\t[\"failed\", \"agent_end\"],\r\n\t]) {\r\n\t\tconst harness = createHarness();\r\n\t\tawait harness.emit(\"session_start\");\r\n\t\tawait harness.emit(\"agent_start\");\r\n\t\tharness.children[0].stdout.emit(\r\n\t\t\t\"data\",\r\n\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\r\n\t\t);\r\n\t\tawait flush();\r","truncated":true,"truncatedBy":"lines","totalLines":296,"totalBytes":3567,"outputLines":95,"outputBytes":3567,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"async function testStartupBriefHintsAndUpdateNotices() {\n…\n\tfor (const expected of [\n…\n\t\t\"spt adapter version omp-spt\",\r\n\t\t\"spt update\",\r\n\t\t\"Use extension-native `/live`\",\r\n\t\t\"omp-spt v0.3.0 is available\",\r\n\t\t\"spt adapter update omp-spt\",\r\n\t\t\"spt-core v1.2.0 is available\",\r\n\t]) {\r\n\t\tassert.match(injected, new RegExp(expected.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\r\n\t}\r\n\tconst quiet = await harness.emit(\"before_agent_start\", {\r\n\t\tprompt: \"Review live reload, identity matrices, message queues, subnet masks, and checkpoint files.\",\r\n\t\tsystemPrompt: [\"base\"],\r\n\t});\r\n\tassert.equal(quiet, undefined, \"related technical nouns without clear SPT intent must not hint\");\r\n\tawait harness.emit(\"session_shutdown\");\r\n\r\n\tconst unavailable = createHarness({\r\n\t\tcheckUpdates: true,\r\n\t\tfetchLatestAdapterVersion: async () => {\r\n\t\t\tthrow new Error(\"network down\");\r\n\t\t},\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--version\") throw new Error(\"version unavailable\");\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"notif\") {\r\n\t\t\t\tthrow new Error(\"notification store unavailable\");\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"adapter\" && call.args[1] === \"version\") {\r\n\t\t\t\tthrow new Error(\"adapter version unavailable\");\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait unavailable.emit(\"session_start\");\r\n\tconst noClaim = await unavailable.emit(\"before_agent_start\", {\r\n\t\tprompt: \"Continue the task.\",\r\n\t\tsystemPrompt: [],\r\n\t});\r\n\tassert.ok(noClaim.systemPrompt.at(-1).includes(\"OMP SPT endpoint\"));\r\n\tassert.ok(!noClaim.systemPrompt.at(-1).includes(\"OMP SPT updates:\"));\r\n\tawait unavailable.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\r\n// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\nasync function testActiveTurnBoundaryDeliveryAndFallback() {\r\n\tconst harness = createHarness();\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.emit(\"agent_start\");\r\n\tconst firstEnvelope = '<EVENT type=\"msg\" from=\"first\">one</EVENT>';\r\n\tconst secondEnvelope = '<EVENT type=\"msg\" from=\"second\">two</EVENT>';\r\n\tharness.children[0].stdout.emit(\"data\", `${firstEnvelope}${secondEnvelope}`);\r\n\tawait flush();\r\n\tassert.deepEqual(harness.submitted, []);\r\n\r\n\tconst boundary = await harness.emit(\"context\", {\r\n\t\tmessages: [{ role: \"user\", content: \"operator prompt\" }],\r\n\t});\r\n\tassert.equal(\r\n\t\tboundary.messages.at(-1).content,\r\n\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\r\n\t\t\"the first accepted message must enter at the next model boundary\",\r\n\t);\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [...boundary.messages, { role: \"assistant\", content: \"first outcome\" }],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");\r\n\tassert.equal(commandCalls(harness, \"send\")[0].input, \"first outcome\");\r\n\tassert.deepEqual(harness.clock.delays(), [0]);\r\n\tawait harness.clock.runNext(0);\r\n\tassert.deepEqual(\r\n\t\tharness.submitted,\r\n\t\t['<msg from=\"second\"/>'],\r\n\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\r\n\t);\r\n\tassert.ok(\r\n\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\r\n\t\t\"active-turn delivery must use the extension listener, never a background poll\",\r\n\t);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\nasync function testAbnormalTurnsRestoreReceivability() {\r\n\tfor (const [label, completionEvent] of [\r\n\t\t[\"cancelled\", \"session_stop\"],\r\n\t\t[\"interrupted\", \"session_stop\"],\r\n\t\t[\"failed\", \"agent_end\"],\r\n\t]) {\r\n\t\tconst harness = createHarness();\r\n\t\tawait harness.emit(\"session_start\");\r\n\t\tawait harness.emit(\"agent_start\");\r\n\t\tharness.children[0].stdout.emit(\r\n\t\t\t\"data\",\r\n\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\r\n\t\t);\r\n\t\tawait flush();\r\n…\n\t}\n}","startLine":1635,"lineNumbers":[1635,null,1670,null,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,null,1790,1791]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1974,"totalBytes":3567,"outputLines":95,"outputBytes":3567,"shownRange":{"start":1679,"end":1773},"nextOffset":1774}}},"isError":false,"timestamp":1784192688094}}
{"type":"message","id":"77b015b5","parentId":"b76c1108","timestamp":"2026-07-16T09:05:01.086Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Modifying second context with persistent messages**"},{"type":"toolCall","id":"call_adMjPYWRI9bhmlHeWchmaeNZ|ctc_081052c4e6a28a51016a589eb87b3c81998c4dc77ad4186abf","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#5A93]\nSWAP 1740.=1742:\n+\tconst afterToolBoundary = await harness.emit(\"context\", {\n+\t\tmessages: [\n+\t\t\t{ role: \"user\", content: \"operator prompt\" },\n+\t\t\t{ role: \"assistant\", content: \"\", toolCalls: [{ name: \"read\" }] },\n+\t\t\t{ role: \"toolResult\", content: \"tool output\" },\n+\t\t],\n+\t});\n+\tassert.equal(\n+\t\tafterToolBoundary.messages.at(-1).content,\n+\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\n+\t\t\"ephemeral context must be re-injected before every later model continuation\",\n+\t);\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [\n+\t\t\t{ role: \"user\", content: \"operator prompt\" },\n+\t\t\t{ role: \"assistant\", content: \"\", toolCalls: [{ name: \"read\" }] },\n+\t\t\t{ role: \"toolResult\", content: \"tool output\" },\n+\t\t\t{ role: \"assistant\", content: \"first outcome\" },\n+\t\t],\n+\t});\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":1931,"output":413,"cacheRead":229888,"cacheWrite":0,"totalTokens":232232,"reasoningTokens":141,"cost":{"input":0.009655,"output":0.01239,"cacheRead":0.11494399999999999,"cacheWrite":0,"total":0.136989}},"stopReason":"toolUse","timestamp":1784192688102,"responseId":"resp_081052c4e6a28a51016a589eb08c1c8199861e6b38a90dfecb","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_081052c4e6a28a51016a589eb57e908199946bbf858f4830fb","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ649TuCLzK8KAqPhvzwd9dwXws4zFQl34afoqfp67gBnCItbcolk13Drwm7vzuMImPgpFuaUCe6ZeFjzq63RSsd-keH-VW-10NAn4MTgKg3RcZvrZyWQsXvQvgh-I5LqcW7pfGEK9MoyQ0uG0O7elSkctulmjrKr-fQ78H1Rm3uZXfirkqoSShFAqRiilLYys-pPgoNvot0HiXYIBzD6THwWu31M9j3HLHS8UJllICdDOhQcdWxq1RQHax2pehzkmnt2C-yisUU7nxVUnbXET8t_NK8bq7XgjRhrIB00Q7zTm2DCKnZMeCBx-q1ZQGivYxkKCeDtt0PB9T3K1uTNdMKDD5U985Zslx3sixPSRKqtXwzc15CchwJkdhHFJ_C0OKNFA40-I8JBq_uyQoVztjKRgMVtrlXNoLzCJm7PwcqSCK9hpIBKIrAF9GqrvooGRC5XGZgjjyGWCZk6a00sUk4Tbwe0TlnSxiTAgxlxmZ3nxB_zcM4hr_1sgtHDqS8gUmXBCXqngt84ZzZMk64s39y3eC67QP9L5y2E3eoHlKn2zjlbd9Gy2ohSoNGIbFmYJJIdIDzuEqGdY2jTXiKO-K4iOGQ098Pq42RaLeR63ruh-hk_xyc3awgilrk6YoSm4QVWDULzmA9XMqBXXSOLqJ57q7fVeU76qH_I1M1JgnZ6FgmFSNwikO8g-mE087S6jdN4U5yArb9Lv3ZW6uPwRwvuDfg3hrYsiwQY1oGDh-6MSekYhzKe4BJdwTm-C048PerjpqPDJCcmlkhobzFdMtnQILQ_FpTqWn2qV3_Of7jHo8Xq7ZDsj6Tf3AWvR9eKWnBzR8weWjEDzRwUO05g-_keljbve2IiuM98hxNUXy0YiGKSRQW-cOR7HQvqfaB9q4lMmjg74m_l-gUJEkox5DHYZOp6IxzN1FYOABCbymmx7u4Bl0XxdBGbCZdRVlGMchskU0mND9tYuLLIxbBQakz1ooTdVzVMRtNN5Il4TrFKAdL6ASw68mWY7MDfmLBrunEcAzCo3S3ikmw3GHi0khtmIxjmuf7ooWUxzgha_Kohi45Cb5jerZdRFghNHLKSNL0DIStMks_GkavsFMJKeRWELCr46vqsEkb5RZo35BTenIHy33cDJG41rOLY_A_qWV0kt3_Q0yw-DK27ChbxUI4pl01qDQzNoYiRtdAyDQgvm1f9r8HXFXX_4uzjZgrdwA1QLiQi7cI1ECn0mQgJJBoD6QxDBrQYbp5SI-WvYZIHtKp8yuSgLtp5Unn8vl6pThs9RoLlMx0L_kbWq-9uv3dJP61kXw2phjvPQnPKsm6Cr72HE9Np8NnJ85iRW9iiWrHAwvA7Eycb0rsYvhGwuAlSB4RJfv97waj9uQ9Q_jlqljP3OZys9V4Oz9n-DfhUa-UhtJ7_qt_c38-x2bUYakZjxBfDdOAeD-ZOWUnVClC13w6tKy_eRiIELXX09xkBF8UB5QtYuJAzRZLvBBxa04gBqn9ZLudI6gbEqDEPcCLdoN_vkKlRkkxOjU2KuFvo0_vyRe5Qi_-MDVFT5LwfufXoqVcSUOVvWOteV8PVU2ZMLWUC1nCrIVvX2WTU1G7kc3pIJy_N8YiMTQjVTn3wENphTFUtH3y5I9PO4FL2RG8SzQqm-9r3rJ7qHS4l3-0gV02MXsPcUnHTlxVVKoYv5qmccIVJ8Cijf5sEvVZ_r-c_0Wv9WMWd15HscJowean30OOwK5u4u0UJATcpvgM64qcASh7uujCb-TT2PgFR1wBDNT0bTRVa2GadrLFvbZZ48hDF9sENvTT7DIpI1Od1a50O-CQu-5n9IIM4Ky2aGtkjOMKQ0L41pxko4mftH3Sp357HAt0hZXahblgkAq-CPpykQ==","summary":[{"type":"summary_text","text":"**Modifying second context with persistent messages**"}]},{"id":"ctc_081052c4e6a28a51016a589eb87b3c81998c4dc77ad4186abf","type":"custom_tool_call","status":"completed","call_id":"call_adMjPYWRI9bhmlHeWchmaeNZ","input":"*** Begin Patch\n[tests/omp-extension.mjs#5A93]\nSWAP 1740.=1742:\n+\tconst afterToolBoundary = await harness.emit(\"context\", {\n+\t\tmessages: [\n+\t\t\t{ role: \"user\", content: \"operator prompt\" },\n+\t\t\t{ role: \"assistant\", content: \"\", toolCalls: [{ name: \"read\" }] },\n+\t\t\t{ role: \"toolResult\", content: \"tool output\" },\n+\t\t],\n+\t});\n+\tassert.equal(\n+\t\tafterToolBoundary.messages.at(-1).content,\n+\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\n+\t\t\"ephemeral context must be re-injected before every later model continuation\",\n+\t);\n+\tawait harness.emit(\"agent_end\", {\n+\t\tmessages: [\n+\t\t\t{ role: \"user\", content: \"operator prompt\" },\n+\t\t\t{ role: \"assistant\", content: \"\", toolCalls: [{ name: \"read\" }] },\n+\t\t\t{ role: \"toolResult\", content: \"tool output\" },\n+\t\t\t{ role: \"assistant\", content: \"first outcome\" },\n+\t\t],\n+\t});\n*** End Patch\n","name":"edit"}]},"duration":12982.945299999788,"ttft":5372.090100000147,"contextSnapshot":{"promptTokens":231819,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_adMjPYWRI9bhmlHeWchmaeNZ|ctc_081052c4e6a28a51016a589eb87b3c81998c4dc77ad4186abf","toolName":"edit","startedAt":"2026-07-16T09:05:01.088Z"},"id":"12651884","parentId":"77b015b5","timestamp":"2026-07-16T09:05:01.088Z"}
{"type":"message","id":"17662184","parentId":"12651884","timestamp":"2026-07-16T09:05:01.174Z","message":{"role":"toolResult","toolCallId":"call_adMjPYWRI9bhmlHeWchmaeNZ|ctc_081052c4e6a28a51016a589eb87b3c81998c4dc77ad4186abf","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#9A9B]\n1735:\tassert.equal(\n\n1738:\t\t\"the first accepted message must enter at the next model boundary\",\n1739:\t);\n1740:\tconst afterToolBoundary = await harness.emit(\"context\", {\n1741:\t\tmessages: [\n…\n1750:\t\t\"ephemeral context must be re-injected before every later model continuation\",\n1751:\t);\n1752:\tawait harness.emit(\"agent_end\", {\n1753:\t\tmessages: [\n1754:\t\t\t{ role: \"user\", content: \"operator prompt\" },\n…\n1757:\t\t\t{ role: \"assistant\", content: \"first outcome\" },\n1758:\t\t],\n1759:\t});\n1760:\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");"}],"details":{"diff":" 1735|\tassert.equal(\n\n 1738|\t\t\"the first accepted message must enter at the next model boundary\",\n 1739|\t);\n+1740|\tconst afterToolBoundary = await harness.emit(\"context\", {\n+1741|\t\tmessages: [\n+1742|\t\t\t{ role: \"user\", content: \"operator prompt\" },\n+1743|\t\t\t{ role: \"assistant\", content: \"\", toolCalls: [{ name: \"read\" }] },\n+1744|\t\t\t{ role: \"toolResult\", content: \"tool output\" },\n+1745|\t\t],\n+1746|\t});\n+1747|\tassert.equal(\n+1748|\t\tafterToolBoundary.messages.at(-1).content,\n+1749|\t\t`<msg from=\"first\"/>\\n\\n${firstEnvelope}`,\n+1750|\t\t\"ephemeral context must be re-injected before every later model continuation\",\n+1751|\t);\n 1740|\tawait harness.emit(\"agent_end\", {\n-1741|\t\tmessages: [...boundary.messages, { role: \"assistant\", content: \"first outcome\" }],\n+1753|\t\tmessages: [\n+1754|\t\t\t{ role: \"user\", content: \"operator prompt\" },\n+1755|\t\t\t{ role: \"assistant\", content: \"\", toolCalls: [{ name: \"read\" }] },\n+1756|\t\t\t{ role: \"toolResult\", content: \"tool output\" },\n+1757|\t\t\t{ role: \"assistant\", content: \"first outcome\" },\n+1758|\t\t],\n 1742|\t});\n 1743|\tassert.equal(commandCalls(harness, \"send\")[0].args[1], \"first\");","firstChangedLine":1740,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192701173}}
{"type":"compaction","id":"6e4df01b","parentId":"17662184","timestamp":"2026-07-16T09:05:01.560Z","summary":"You are resuming a prior conversation. Its earlier turns were archived to reclaim context and are reproduced under HISTORY below, oldest to newest. Read HISTORY in full, then continue from the live conversation that follows it.\n\nThe archived transcript is compact: each turn opens with a heading — `# User ¶`, `# Assistant ¶`, or `# Tool call ¶` — assistant reasoning is wrapped in _italics_, and tool output sits inside `<out>…</out>`.\n\nReading HISTORY:\n- Plain-text sections are the verbatim transcript — rely on them exactly.\n- Some middle sections are attached as images instead of text. Each image is a page of that same transcript and belongs at its place in the reading order, between marked delimiters. Within an image, a solid black cell marks a newline and runs of spaces collapse to one.\n  - A frame is one grid 196 characters wide and up to 71 rows tall: read left to right, top to bottom — there is no word wrap, so a word may break across rows.\n  - Text inside `<out>` is dim gray — that gray is archived tool output, not conversation.\n- When an exact earlier detail matters and a section reads unclearly, re-derive it from the workspace (re-read files, re-run commands) rather than guessing.\n\nFILES\n===================\n. (Read)\nCONTEXT.md (Read)\ntraceable-reqs.toml (Read)\n# adapter/\nomp-spt.toml (Read)\n## strings/\nomp-spt.mjs (Read)\n# docs/\nKNOWN-HAZARDS.md (Read)\nPARITY.md (Read)\n## adr/\n0015-extension-owned-session-activation.md (Read)\n0017-active-turn-delivery-uses-safe-boundaries.md (Read)\n# tests/\nomp-extension.mjs (Read)\n\nHISTORY\n===================","shortSummary":"Archived 202,707 chars of history onto 13 snapcompact frames (+27,833 chars as text)","firstKeptEntryId":"1ae2d052","tokensBefore":232232,"details":{"readFiles":[".","CONTEXT.md","adapter/omp-spt.toml","adapter/strings/omp-spt.mjs","docs/KNOWN-HAZARDS.md","docs/PARITY.md","docs/adr/0015-extension-owned-session-activation.md","docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md","tests/omp-extension.mjs","traceable-reqs.toml"],"modifiedFiles":[]},"fromExtension":false,"preserveData":{"snapcompact":{"frames":[{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"iVBORw0KGgoAAAANSUhEUgAABiAAAAYaAgMAAAAgkEnVAAAACVBMVEX///8AAACAgIBJX6m2AAEKSklEQVR42uxdT47buNOtFtwAoZUDJHvCK8Gn6B+QA/Si+z5Cr3wMLY055aeqV0UWKcp/Op3EM5+UmcSWKLLIZ5G26uk9osb2/k4PvD12dF8a4QbE34sw8F99qqif1grG4t1xxC6/t/90ELF633+qm9IV6sa8p5vW24k3xtJsZBWI/p4ag/9X/upSRbmdrlldJ//Ppbi7Yyga6YpzfE1r0XdaMlZtds1+XwKC29DaotsXHECpnZDaDK6dzvWzuxGIUL16f+8a58bFvu4eIC7hugbEWsThyocsLgLt7gQiD2UMdbuhaqcNRKufnwHi8sg16uqn4zT/feqnfurmd4f5XwaC38sf2UfE+2PAcZ405n9pPnPk4Tra3hP/PddCMdr742TTHJfvpaaD1o1/+Qj/nWrhNk8HxDOStH/Efo1OYomIC/vGYHEhJgBxxhmE3nAdY+i1nRiPqU2rXaJN/eUz5/+lTzGiLYzD/OfE9fdyFNHhCGpiINIYaK8YCOyz3lu/MfZzwAxIHGKIYcYxhPlfBoLfY18Mw1xk0Pf8Lw/2EGxq4n+xN8YYjhN/jvkVv+dZgV8dJ50UpKbg6kJt/HeqhduMc5sBVwSXC3MNXBbRyXmR3+EohTHFpVep1PgxH+E49Vy5eC1aCVBeY+ZCRIFyf0PgXlpPBhQnjmCe9waczkcHzHxSK2YXTE16pkaGqQnlY9HvOBC/6wlhHM9csD/PXT7LFTH/OyMmhVFhz6+kJKrwQGAvmkYQeI/68vzdS1tB6p5bnOtDbT2mCaml14D7c6dXkn5Y9Mz3d4l2biHo0f78ETg+DwTX9DEfQZzcHpf+CIg2A8Fnox4egeD6q6+jxCzF+zOhrjPK9BKFDj8Z2P3ZgJAxCOiVAcHlMbLWb46AS0z6eUBB/gRjjZjmOW2iyQKbPxHT/DmQkiUQskbI3n40IMJo7/0SzLXKZ433TVFblVVlwqBIWZmS9AqV94MDgqPjctxC0KMxMBA0+cUaVwRqQXtrQOhAcjwNIObJcbIrAtdtxPmDDOEYqQYi6hWBMZCyabEOo47ghGilbpTQC1ynJm5vOTXx3wdeIU7+opJvIwBC90ZyQOD9EIItmx0u67mmXHsxNVkt3CaXGLBGxHn+xyQkQAQBIoTRuj1HNpxOVlNIE5oAMcQ09Fz8dOq0nSiny+vBao8yHdkHT0HB9CFrBA++1DXEoT/JqGnNiNPGMgGR6u0yEIt+c208NU1dWjDmpeoUZLFJS7UstkB+XlACFmySWXdeDSb8juh0L5ag43SUZR+LWZcWay4vCx/ZVwE+C2fIIp9q0TZPvHTy+yi/BLgsouNy3ELQo/MHJFpcHZcZAcQoH53jhPY6+WRzCWn31Fmbpy4t1p22jY/LMUU418NtnQixn+ZXwUZtHuZJpxgdy/d3PwZSx8iTJfahztxvrm3ld9vyC2JH0X0l/Oe88tU2XH5/0xfD4szYOKOObllfR1+3lZHU+9tHW+P3qa31TV0+EdPl8+rj7fLxhgjKM+8F4is3iyQ297d7uN1r+q9FuAGxAfGvj24DYgNiA2IDYgNiA2IDYgNiA+K/E+FDhvh7YnpwMDYgbtzi9WPljbzQKoPUYau2+c6pPzNcun+1PFvu9d609Xf0sBqy9cR6uGck+Q7stfP79ZYQZqej1DWOLYHoFmXW7li2gLjGFym28dZx6lYYE5ksEK4CEerzQ2s0u1UgbBRWKqRu/Z5szqaFxoivAUFfBMT1z+49QFzq4WeAoBUg6NNAGClJNzAdJIERwWkAPwOMBjARZFpwTI1+Smcx20JKeR5GDAXjY8psBmNggB2REi0X+CLgPMTILTIQRznbylnkmUuB1roVxkRmbVg9SIOhB+BncC2ZkZF4G5QZGxgBGyvH+kh/AISl1rT3p1QXynKUk/FUJK87zFkskizuoOlCySImJgJXlTgWwjnAWSSpUJTyPAywJhJ/IWQ2gzEwBkliptTjBb6IJTYlKy1XBCc5rZwmOR2XwpKQbcZEZm1YPZp6jSmFOXAtmZFhEXSSTh4S4+ND2CND8KwPnwblNcKYIVzPgN66vnWacFYmykfIjARLpQvf4hwSE0EvajA1hHPwEYoUe2RegitDnvHRn3syNgPyzeg28xnkirjIFwEDg4GY3xkQyPUG8DiOBZeiJ88kqRkTmbVh9fRCkJwjImaUICbPyLAIOjBdEo1BeCPnGDzZAKwUtDdf+8pVQT32UWWuCOgCHKPyO/hYHtISCP13zKsG2AiopARCSk2uDHnGB/gVOM8DEfUzepkvoowPviKoBGII4HFE5UboFDx5JknNmMisjVTPPDVx/QxEVPqDZ2RYBEYkyEAMjlyh3BSwUqS9uacyKhpjMCAieSAiLYEY+FJNQARMOmAiCBC53IDPA96FxE1wZcgzPkDGwrtMDmtPTUu+iJFf0tQUDAguh06i/cylyEySJlNkUP6GfvDqqalkZFgEnTJdjPHxIeyRDETJTekYiGjMEGXJFL0tpybuWwBrgbkE4DcE8C1OXWIiyApvHAvhHOSzpLQtkVqmZHyAo4B3WKx5mG2xvsYX0cX8xC3y74hOmCaA23gc4EZ0yvnwTJKaMZFZG1aPclZOebEuGRmUCJtchltBG2MQ9kgw1kf0XzvmJTgv1qiH26WCv3KUHmOxjnf9Rrlra1d9/ffmbXyR9tfb+KlIP0tGiBfedTf/sv5Kxklz+zy/IdJ1vsg9A3YvEDd/1C5Gs91repCYNiA2IDYgHr2nGxAbEBsQGxAbEBsQGxAP3tMNiA2E3xPPv4AuswHxxVu0F/Wj+GGNe9AvTvAKGPFK+FWdyOsto9FjsW7qxvtOcWU4y97GtajcmeW9sG7Cnd9FH9biiutRWZXrQIz2vs2PMJaE43SELODQAiK488FoSI1FefS+OLsGoiuy8u0OlwIS4SYgfKnLDA3fU3uWtYwzLO7J5rEMV2K/BkRcC68BBNFNQPizXVsVjDUQdAMQ9PuAqOoPSyGXcCGuNhDGtFgwKZRrcdDko1yOY69pIPAn+MFa8CU608wYcTay0QfH7sBDw+fE6UjsBkJGGakhrlfenRR6r9GhLAvoZCBF5dkjUOVY9uY4VVofEgWSVJkLAp6Fr6sje9Q3M0mUoSGKIQdNbQEI9NZYGb6uOp7O9fWYtDrwGWsxKYRrAXUOmwqQ3GM1ihCEpTAnWDvR3OhUM0PTmQE5suDYHXJBQyOAEutCeBCa7Jes7xBwXc0tx4o/klgW0Mngtkv2CP89NnoTKq0PRIG0bVA+SuJZUGaPdMpA8UwSMDSijAMrdQiJYYICyRAyK8PXVcdT9tW0OoSpsGRSWB6XOQ96RZxxIXWiRqH8iQAgWDdDOQ4juAoYTnsFBsfcwvlD9TaMJRETED04DsbBCHZFZI0OY1lknYyKPRKYX7LsjQFh9SAKaHoEJQxknkVmj3Syt2SSgKERjb8REU3QmMHKOFZ11fGgr2UZ0rRkxaRwXAvGjrk+JupAHTk2g1wRnKa3vR1lPl2XXoHBwQyLD9XbMIZQviJYLUNZFKOl1Ym8RoexLLJORizZI8IvWfYmA6H1SBRyRVBIdTqyAtlHLqX8M5MEU5N+vkE0yEBEXXPKuup45o/YFNzVqqsE5D1iRQ5JXIu5tLDfRi436tQE1RxhWwCIoSPTssgdN2GgEBJbYrCpSfU1hsPkpiYdDP7WhBbwnSQupyaZvFKHXYnTadmbUJcaMDWBB5K5JpkChj5wG0j5+6lJGBrG36AKiMTK8HXV8fCHmo/xGpH6DKZCyaTQ5Qlci5MSVCOXG3WZkb1gW5yEL3E6qioFOENYrKGCYewOsCVG1dtQfY1TJBAgj8J3UD4DcyNOMX1Lz0oftlhz3ca8cOwR5n7EZW+6SusDUWDJDWR8FPAsOsce4Tbw7SczScDQgCSY1Rekr8ekugElkUXkKR6K2lfXu5u2+CVU9fLra6y/On5i+zUSSv0l9NY2PEMjNonFN8d/b8gXEPurQNz8SfoFIFpt5J78WgS/0vdf6jg91Lbd9NuA2IDYgNiA2IDYgNiA2IDYgNiA2IDYgHjgT8i1yO6NvCx/6ey/MiYbEF8wJpf8T0LzZVyce1nNItZ7K47G8p6L3JddqW254exK/yOUkcVGO1GOS2p1MQrix5Iebc6RzPXt5j+y7bX29zf++1kLPcur5zeU/PG6GvaubrLkT1TH0pFmor4rgCilDvK5kSqth8TR6BY1agWeIxG6IqJanGJFdsIB4dJTK0DYGDjiAx+cIjWA2GMIGY/3992e6EkOPmmhJ3n1Yw8gnoqRf1oA8ZQR6S587G4DomsCQetAjOXwNoCgkg1RH7sPCLoZiNwryWLEJhAvMxQ6rFeA2NP+qR75xtsEhOdPVIoSYxYSP1Ssg8xykESJZ2WcoDSR97DKBx4KLjkalZPKydrmh9F5OFCbsSUwGSKNZHoWq/of2hoPNDxUysitN3J8AhCsPXJWHobk6NRFJalnnDiZNA/ty/Prfj9POi/v7z/eeOifX59fecjxbwLihV6e6Nu8j/9/fv3x+szvfnI5/lf2znt4+np+rfgTlaLEaGlP2A941kFmOUjqMOQcdBzAZnB7+NHyIYrviedoVE4qknMUcYgJQKA2Y0uYK4vGFMIF/Q9rjQcaHiol18N68/7+kZxbOK6PlOzMnhGp3oHTq3wl7Hf7/fw53tsVMb+XSWgvk5FAsmfI+M/3+Rj/v9/t8G7P5eZ/v3+Xs77vdjiz5E9UihIZiFCzDjzLQdQsQuJ1pPysOZ7YM/4foeRolE4qXGquT9QrAARqM7aEXyPAI1nX/7DWeKC7isXhuRt8nBkoGQhTx4AxjzmtoE+s2/E0TyUKRLoiEhDzIg0gnhgkAmjP8/8/3vZkEM7Xy9t+hz+8R4Co+ROlokQmAngezpLlwPyM7Hpi2ivJqaQCInM0SieVfrS2DYhIni3hgVAeybSu/9EGgo957gYfj+UVkVacGRJlhBgQotvxslcg8hqRgdjvMhDzOzlGr/NnnwyI5xeUw3VSAZH5E7WihDEg4LTiWQeZ5QC5g+x6wswMBSIRc4Jc2KdTydGonFQomN6FARHgq5IIJ+opp4oadFn/g1t7fzcPlVwyczd4Up1LDQpEyFNT4PajZ2BEnZpo/wIgdrslEPOEk4GYlwg99u1VpiYZ9j3KzSV5rwCxk6mp5E+UihIyWLr4CduBWiwHEdpJricyHASOQ97TQckilhyN2kklqCxXEFaInXt0PIfjpDoa6v1ySf+DW2NpEniolCVD+poRI7cg68/896g8jG6c/46egQH1EP5S+sKL8s+nV/sdgcUaS+7zzx/yyoD4MQ/2vLRjGX/FOy43//uT9/KeJyzWrR9Hl386VftAHbvJdvLydomTcRtfY1lqzZKEii/eyy/ta2yMz/2y3rv9+11r701DffkoSLlfAcQlRsRtbIllqctA/KlbHH7I82d/T1++bfeaHmRMNiAeZEw2IB5kTDYgHmRMNiAeZEw2IB5kTDYgHmRMNiAeZEw2IL58TP78kPoW/xagD/hB2oB4hG3HIeEOyL6+FTIf2y32lBsfZgaDK6dn7Zq3VX68Pb3swIvQ89/fJS1z0w2+vnqdlT/sCPZEvAmXgfjnHKt9+b3XFElboz49I+IpwZZbBHZd94UpgXhpA1HmvB0LQYB4ugCEZzGACLHbP4EXQcaKiKmTS25J6fDiE/6d5insiJb3siShWx9BYkf2dSBCWAOijFHPGEc1a7ASXfqA4FXJSQhfAwTdBQSVQOw5MSJJdjJWRCxiWzNvyd0LtByQcsjrK+ITQNClK2IJxDTE0DrtYECEZkXPr2/zH/AKnl/f38E4+PaKdEc+xtlZfoUESM1C4O2bcBi+vVq9LzuclaaiufSb1M4ciPnIy3xv/oWzwJkVEanFAunVB6XXd5K6UfYJhr7XhJaIq+vt8KAMEvk0nnpNOmXfFe9+0lFmeMRoaiRn0xSpHFzqGOHdclAvF+Qh9eFj8goc0FIwp5dSkWROVPxv/kPCK9jv3t+/z685n4okXz4mH+GdcQ5qFgLnpey9Xh+7Fz0rXwVP9D8kzSU7Mue4BIidY0UcxyYLhJOuqjZgehfGPrGpyVgcqhVC4HXM6VF0fjDfF+Nple4nnWN4gL0xpBw76jH2B79bxMi5YOWPcLpV8oCDxZIVOADEvEYoA8VzXxSIZ+EVPPPUNL9+liT4vjgmn3JNdS9ZCBj6eflNGai9DPoSCDkXB3Z2RWRWRKSaBQLvleTwIlwKG/zerxHGtkg+JTAjOep0YL4vpj8CBxVzP+kc+yOmXPVHMCURRHI8t5kqXDPcWUgpOSgdJcaswJGuiDM0Sjz3RQcbw0qvDAT/y0O0L47JJPOqV8SChQAg9uSuCAHCT016Reiwz0d2tkZkVsSSBSLvksMLuBQ2+DR5ICK0QZJPCc7RK2KuD8odyYmIvPtJ5/1iHBCRMhDZwaWOkb1bgjrH2GKNFjrKChxdWiMkLn7puC822N/3aWqS1zsZHncMQ/3tFZyDmoWgQOywRghlZPfzJ84SwtULf0lyU5PUYt+aMitCOlmxQJR1AVupxC4x9gnWi071MpjHYfQbBSIKc2/odADVd2Uo3U9qMRhy9B8DIju41DGyKEyS+zEgiqnJgOgwkQ1GUsrcF1lUeVllXoEu1j+ZZUB7XlbzMSzA82e+yUIAEPKe8GuCF2A96wV7mMUw1/YKDgSXsN8RmRXBF+mCBaL8js48V2SxTuwTwmss1hRUK0QXa5swoBXSpzOcg4poawh4E4ib/Uktp6Yx8VXwuTUHlzrGTo6oAJb+jrCvBlmBQ2LkyEdjoHjuy+KLHF3c9iuvy73lkSe6lChv/bKOK18k6y+ojbINK8J44Rhqu+2X9bWobtlucJ/8SiDu2T4DxPr2OSbInwPicp13h/SV23avaQPir7e7AfHXe70B8SC93oB4kF5vQDxIrzcgHqTXGxAP0usNiAfp9daNu3vxu3r3G+rdgPia9lZT49hi41h/U6ix8bq73K47FlciiM0Tuot9WOyvjvXUdJPQ3t3w2FhRAndd/znbvWJmbeA+7xjG0M23zI/jcaxcWUKbM3HJImOhXXE7EGEBxIoOSAOIbMbRNSBYA8IzPTwQPn78y70IrsfhAhDhYlv2xKplT+xpdX4EfxRj+TmPPlb1hja/4SoQZaifB4I+AcS9V8SamEf2NLkViO4iENQAgrN6CsT8bhqY4SEJpLHSYQ5U8hEOSXWiVLo4p/0iPm76HcK5ABDMfjD3lbMwIDLrgXkRB2VQGHvBt5uVOMTFRYXYhQtRnKvxND1gsA9qH0uexUFeWd3C6bD4xYSDHwRGG8fUc1PriJBmP2W3lPTocbMtD8ShAOJ0YobHIQHBo2QjSyUfISTViVLp4gP6FRFKA8aggErGnFebJN0X7awPSTMq+4LAixiCJRqXih2mxKEuLmpNEBfnIp6OWi4l2Dfq65pnMcgrqxsP0Wv8mgufP04YAdMaIVPrkOlFemf6IOhHiLHZlkhNTDo1nSAtAyA+JPkaTwYE9qiXS8lHCMpROFZKFx/Qr4jZ8aQnczXBFTEfUS4DSn8EYz30SmSxd0seBO9TmYgo7AfL41bnmt6BJDsrlxKpwwgwS56FZo6tbhc/GRBwiclaI8nGJrAHS1QZrcy86Ebes2wrKJdEBTJCCcRcfiiBUC+Xio9guhNUKl18yB7mQSQ+wmSuJgAiGpdhQOkPq0W8SKJ71+BBTEmJg68I+8QPi3MVCGFL1C4lUwZiybMYjHhABoTFr0AMPOB5GMsrgiZ1b5H4jXnRyZ4Gp8MDETwQvFjbAp6B0D0VH4FMdaJUuvhQCkgxNamniAIRwGXgOdhNTWTTS0wT1ZIHkZQ4Aq8INjX1p/JcYWYkAlntUoL/T6fYVAQ5TJ1zZNGpKWQXGF7p4hBcj+F40unUBLkVTE3MvOjc1LTgdBRA1N+awBPBtyYFAl4uJR9BNSpO/VQqXTAzwXxFMoPiqE4pWKzBZeCP7hiwbBrrgRczIUOmRbXkQSQljgl7sVhTKM8F55vn35ZLidYbdYmveBZRmYC2WPv4+V/iqenUuR7D8QSiYL25t4zGvOjHvFgveSdShtq/I2SC1N8R2GNeLnekwVs/bWSZu1Lm+tfbFscihkvl76s/Xu1ZWywiMzxi+toe6Q42xurWaO/2Slo8CLsiLpW5BQg7L36ipl8Hou5FPsv252ji1b58Eohf3bZ7TQ8yahsQGxAbEH8i1A2Iv1/lBsSDVLkB8SBVbkA8SJUbEA9S5f9XIP7GUD4GfA9G4NmAeBggMi9jLJ1P/L+yLRxYYtuvZFFLtTOHck2bIhZ1xZvb8GdH966X8syzGOdbfVmxQ+XZb665Lt2KjJNMY1jWtOJBww/zGQdhDQg7vnAfGUMTiDV/ldL8Q86L6y7QgQrywEUgcoRLYQYPRId65vwBA5EVO1q9uFRzTWWIDeQ4MwGrEOsApFGaQODxVns/DW0giLzTiWvuJiDqEC+bc38OiGbIF4HgNG9W7FgHol3zLUAMCoTrwBoQ9nirKVucTp6vseQolAwOkgRI6VRSakwsVCuEa8EZqoOqXghzQ2uL0VgYuZZDSgAhYWS6F/3UZlE4ZshkHjFgmCQfmBOACCMDYYodMb1a09zwNYP/scZUSa0rEFACkbMlRSWy9jHpjEhaSB/4toxryddYchRKBgdUiEzHoqUxUatWdJK7ZSCCql4cxxCsNuyhxMUIc9iaKiVLoZLqXsTQZlFkZghlj5gROhqaWx5Ed1+uy6zYcRyTdscKF8TXjERwm6lCSSgono7jh0xNcUB/8Gi+JEojct0DsvN9WiOgU1HyNZYchZLBoZ5WqmPR0pioVStYKeMDQJA+4x9zbZrqPCuDIz3p7z1f+jNa7JuMEEpWPVyPWZAcCTwQPk9z3gQgsmJHTK/61b7nmu3D0WSqnIVnchb9AVIghEGSgehldsDeaKwKXawnLNaer7HkKJQMDl0jko7FUmOiVq1gKYaPoEMQza3Fasu+Pq4W0d8wD5R0daiORitCGy5nyjOqjkaI1AKCr4OYX4W1vueacxxLpgpUOUyRw4CIlIAY2INm/uBN4KzEUE9Nkvj3fI0lR6FkcAgQOkkMoaUxUatWdMK1KICwK4JsjRDmT1kLJhhENGTXl3aEiRkyJLOemK8uTE0VEDEBEXP7l2pOMbWYKoO1zr06nWxqwriFIJwRiekwGbNEF2vjZdR8jSVHoWRwcAzGezhMLY2JWrVCuA0xyBBA9WJeI+iYnFDkm/5JuRhSCyiPnUbENQbd12ZROGbICWY9YFNgwNQHxgEBxQ7T2oDoVZsL4msG/8PqrZgqJ2tdpp4oBE72eAk8bh04I9ijrSy+Sra/UsaVL5frXzzj1bPX2rx+5rX27tmu/7L+bM0X6wxtsYtGOCWDYi2YdZ7FZ4BAbdfP/PcDkTkjV4H4/dt2r+lBwtmA2IDYgHiEIdiAeJAh2IB4kCHYgHiQIdiAeJAh2IB4kCF4aCAetYk/OUxf39Zf/qhtQHyyRjxIXm2Lm3l9Sh/HtdKak7VnTHkbw9V7Nc3bhr3rSqzK5ftbcp8zlY0Xa5TyF1v3w4Zn6NaDjkWDfbNfYQHEcbo4BjE0ol/oZHSJ4nEZiO4qEKUvypIl4YfMgPBCFfmOb3DC56ncKhDhil6HSUBYGyGEVVylT+MFgEXtowYihk8CQb8JiMstXQWiOPUrgKAlELLnjwPRJ+7BCnchMR8yY6PmIEiaQ+QO3t85tRSjPRQcY+ZTKBuDDisMEf4Xz0Qj7cPpE+ZVIK0CnY1IxuAIkgFH4tPKISmTFTk0ssQqWdfrgBYHzkGKCGccp6z1YTwV+KOou8vEQGReyUF6PPdPeCooA2cWHun8rh5tff4Yn6U2dyGnFzNjo+YgyCPhEU/Uj6xcMeIxeXtF6VHyzP9osySgEgDHE04oDvJcOScaVWeDpyQ8rTxlIKwcuZKkfyPSrAPS1uuA8gDUBnp5mht5Q9tHyVPF/FGickkYCOWKeAYMeCpc1jmz5Hf1aNOBzGdkjbsQyZ72z4yNmoMg/7Jaxdw8q0scCQoe9qo/Q+fD8z/aLAlVyjiz34lwHYKqdJi8g7irRALXJF0RWs77PigX5AxGiumArOl1cFumv0HygcEZtg+MEGlVx6J3bhbC/zj35BgwwlMRG4YznFkOxbt6tCkmn5E17kIGIjM2ag5CJKhV8Mz4AR4RgSOFV6r3UvA/2iyJpJtBIi4xLYBQ7oRIRgAIaHYsgDByARgpSQdkRa+D28qffgMi71N6BBkQ8xoxFVeE9I6PhzEqJcOUTeDMEsfiXRWFWSCFde5CnpoyY6PmIGS1ivf300mnKcqvuExIyhfORmbBklDdjMGmJhlg0atQnY0hGCNCgVDNjgCihi+pf1OpA9LW65CpSfQ3jLKDM9K+wTxV9KoZrf9YI0Ki2LAmCat9gCHCrxX6WLyrRjtxJNa5C7rECi2wSwoUJQfB1Cpkro3gOAjB8mTsDFKDssz/aLMkoJuB2oSYGFgjQ1oD+YyZItoWa2ocVbMD5bBYW8lsQ2Y9Wdfr4Lagv4EeB+WhpH0nW8TV/ySi//iiE7V3cp6MhvJUpJUxubXkd/VoX/rJcnWLja9nN5pihPWW8p5767r/+LKteKFUXD27ddbtv6zjpw6tlgKqtzV/SdniXiCuaXZcOv7wQHx+2+41/Y3oNyAeJPoNiAeJfgPiQaLfgHiQ6DcgHiT6DYgHiX4D4kGi34B4kOgfM4C/HMPDiMRsQPzCyci7ej6Cvr4mp7t43KoOZMld6G+o8coedyQ2S7H2fdHmFO/oe73xud2UeB3xUoQN9sb52jhGCyMUviT5765RQVfuQn4qRbOUN4gLtkB3AxCF6sWdQHQYjOBtNzSd1YTA/u4WUVpf+dxgtI4WbcC11SANtHtVlOjKwekWQa7YnTSviK8Egn4BCP1UFqdHunZFdM0gHBC5wvFSzJeAILrACslcDdKURk/GTehJkz5e+4KOnoUgpaFfYbbyprKBh1zBXTgn/gP8S8CIOE+Z5bHGIDHGR/ZryXwJqHfg4V3jhSBCllzvk929cT/GJOa+dGPpkIefUiJMsvJHbTGK/0Dmb1Tn+7ZM1j2NmLS94MXk4yJnb/oSJkLOCUcZqIBLUxKk6dHuTCAA/2AOUwwA8LS+EDXk0dUB6c1o3IVgviGqRmG2AJLTji1Og0VFmSWS/FocX2KQTHC2I1B+heQJObJoDJVe8sujKWQ03Fgk+x0zdaCTRGywXHU8TugJJTsCd75vi/00Qgz5kfzjuOyVP86sko6SGEpPDgjqzwoEeBASUK9l1AElZG8S0a/g/aLFgafqwWaQxOe8F74hpkYBKgFcV1BqjUHSZ5ZI8msRbkQSYzjKWd6FRYEQGSBjqKDrH8rGaLmxAAiNhUog0J+geh7d4vyiLb4iOD4ytZBIjV654x/Ie3eO4QB+RUdmWpEsMxDQhDJB2RAxeZOIosukYgqkVwT15jhCgdQ3xHQ3QCWAEo6yPFYYJEZWcH4two3IqhjMjRiyTocHok8MlQwEVD7iwo2FgUixQOBq7LRFA0J1N8b6fN+WWn9gVVpRCymPeyCCm5rUGydPTeavkrrpySpD0pWRqSII9wJzapZVESAGm1A6pRJgagpjvMQgGWzSyX4tmS8hR6Kk35NyCCLUqcnxN/gPq2IkhZHKjUWB0DZFM2OEbgamJgECH9lxcb5rS4AY/NQDXZNFr9JxZpV0pi+BBevoJKpgBaZmYabOIfu6pIFh3iTgIzDXopPFOoJroUsVn62+IapGATIrL57wYbnAIDkZSyT7tWS+hGpzzPVl5RBEyIv1UZfDpAqCLxWnthvLUb5GIBZwTTqCboapjEC1g4S/UZ3v2hKq2skvxkIrq3pVLOZscDUtv0rd7IiytpnV3QWljus/b+46c7nXfI/ol7db68jl2r+s470N/6qPSQZivabLbcS7o1vuNd8j+uXt1jpyuS8C4te37V7T3+//BsSD9H8D4kH6vwHxIP3fgHiQ/m9APEj/NyAepP8bEA/S/w2IB+n/w3wa/k12O78l1g2IX4o1MxhqBYqC24AEeGYzLB+/CjV7Im//nGNVk7bYLr5SS9SIYtHs8mS914Q+rDI4LkYUyhYXo3GL+sd0EYGQgYilSwr0LYqqPJsBf2U2Q2ImtIEonVe6RbcrZ5YSlpVaovOUbiTx0zkAQss2GBzImV6MKJQtFtE1gAgFIiofES6Mv7zoBIiQgVhWVTbtgGgQEtpAlB+Wrvn5CzddEd4f5RNA0K1A0FcDQdeAoAzEEUob6qdiTAVhYaQjYG4gpQIgDmo/DxYIPEs4fZKTIgflLPSJ+3BYc0CZjCkCvxVLzrRqkWewxbsEbArP6rCYoQii3ilTyeBQdY4Jaa+LEZ1Q30FryfVhunP6GyfPYTlPWfkDI2VeKyYqfzRWzAmjxxL5h0kSgNlPxZgKJsKPI0iiI8nImSx1ORmQYoSTiJwx5DRhUM5Cl7gVw4oDSnKFUAaJqGys1CKqBDEkNYwQj5OxOoQ5gvSj6mCYYIoxOHLaFJ/fixEN8gB9GEJmneCVZNOSVwtZKlc5LB8hK39wSTBavANMoGzCwC3yFTGAm5D9VEJyPmHWhgIha4TxJALlpD5zHhK5JJpWALMTlAehQxiTp0iTqUHgVUBJINJRVS9atYAvETTLPEc+msaHMkfktfq1hE7pjpk4EFJblHRF2hGhPmaRoBZXH3mvFnN/MQ7LRzDlj+wsEdQVBiom6uFytlFBrDJTZj8VDwRNHohISyAitYCIqkmRP8uZmNDiNDCTwVQsOp3R12rxQBBrf4ym8WFA8GuTX9B1qQIC9SoJYTWiPICdMv1SfVR4tSgPxDgsHyGSBwLEA7n28O0tlayBSBNQCCUQxdSUKFwOiCF6uRwRx3FTk6wKIRRArGh9JPWLMfMi2rXo1CRyQsymCDGzOmzgkiBJ6JwNjTA4EkUnJKLaakQD5InS1JSlYajwahl0XJTD8pF9VYKtEYFUtSSpe9hUr0DwkU4WGfNTMaYCOBd25Jj8TGyxBskR7AcWB+F3MfjFWtSOqEtMh47WFDhssQ7qt+IX67oWWbhPQQS2RA3DsTqMOQJFkKDLYsHgMPcT6Ws3XYzoBNUPMzzL9cnUlLxauJznsIwhK3+AdSsOMJQX625SVsyJ1Aqtm76C5lBsFQF5tVy8o857yrbj+F2t3F5v/NJYNyD+rUD8vW276bcBsQHxiHFsQGxA/Ic7twHx741jA2ID4j/cuQ2If28c/5FY/w3D+W+CfAPizk09U7BF7AlVCTyHPP9fMhrSu+A9GPw9lrbWRV2qbC11MkVxPON+8D/nr+78cWz2pxFtC4j+6tjC/+XqiHTW3TGsAKEZ8thhsEPXEoxwqhSx5HckrQtPJwiWcll8HtaA0Gdeg68r/13W3RJ1SFQJ7V4uEyO1+uP0M0KThOBpCq1xtQRGCF2lxdEcP1oDIhYdicKc4GGIazQY73BSAlGNaar+E0DQNSCWDIoWr8K/KzMCbRAvA9EGQ6sdw6JUVZ6TFefkcmKeKX3yBcmOJMyO6KDPMeIVtCsyv+EsZ6Ddg2NeKBeC0sPDk7itSFueTeG9T8AJMc+WXst4IMwH5ph4E0fzeAHvxLE2DppaSr4tyd0FZaDpgTZyfw6ZRVLEabwMOLFY+X60EUVdGAOcC70GqXV0I+IUTgjOJ8KxUM8UdSxR8f3sSAI2hzwEL3YBnT4hnPkNH+IkAiCGpFQBXxG13Eiy/2OAP0tmU3jvE2hwmCcJHkGHrkWnBCDS9Uj5E5yOnxA7ss+Z+RGDxY9mxLclWiJWHSN4jXBaH+ZkYSySGKhwkwnqrCK5QC3PMUGxA7ohIx6bN9mKSUcg5hEhp3Ciziedk09QxxICGyE7ksANRSobg9OuyPwGcUYQID406Z60M5SGAKYDFChykNE8RrL3yRlUhKAcC+Zd9Do1HXQC7M/mecKvgi5pfGZPBkQWlhC2ypjsQrglV0auCInN98egQtsWZyRT5oABSMnvAFDQHwnKf7E1S0qNeUTgDAMlEJn3MhA8xOpYAv8P70jCLISxUzZD1q7I/IaPtIyWQETSK0L5C1Cg8EBEKr1PYjAgVFLEFEC4lpGSnQwlVoQBIf2YWkAw5yMDEakCQsv4/gwJCG7bsT6U/eKBiG61gW6IARF1jTBGTB4RaHJACSRNTWAVsGeKOpYIK2N0jiQxjLJIs6fJ6LQrjN/QydTE8iCmL4FO8vGDXphgOkCBwlQ9EpvCe58M4ISExBdRCRSdEAWIIXmeDPA/SbEL76TgjYA7EZNvS3TuLqgtildLwdc4qBFPFWdS5oATi5W3NcJ0Q06nkJRLuLpM47MRMa6KAIGF86jOKOyZAscS8DRG50jST3xVMYuCvzxl7QrjN/QjK27oFCKrR2ZZRDqqxkeXFCiYGyJBGJvCe58oJ8Q8ScB7gNtKDCrrdUqeJyf4nyB2Pn6cOqe0YfFn3xb5KpLK8BAeR7BAPF8jUlCtEng1ZjcZKHPAiSX1P339gW4Iw2XKJSRr2FHdWWxEjKtywbWRVr/YrW/lF9eqjptqqFv6fb+s13413B91jvG2Pn6udPqC+8sd/1RLvw8Im0Z+PerPxhjpX7RtN/22Tv6nYtyA2IDYYtyA2IDYYtyA2IDYYtw6+fgxbsN3f+v/aW7TvxCIUjPC+Aa8FQoasuX3beYC34+8XsptpX5B1Vzp6xKv1ID2u+n6XUpo06L28s5nvHJmTH/3brzWzot1pBF57sZdtaUCR3AMjS5JIHS5pnQsv3LiB5rOWZZajlxwb0JD1qFbyDGsA5HICZJlaBUJLloAYVodmasRCsmHVlMZiNyiH5fuMhAjqYx7ySExIBZBN6VMVoEoVSi+Doh0drwIRCzrbul7hEWMJRBEDX2OW4G4cN5lIHIvZyCgwAF/E7LECJnqhCho4HFXKpkMxnTIXAUwJriTxwUfgrfMgTDNClP4OMjrrNiRPFwsjjH7uuDVef4DrYx0lKCnIUnTMXMpmFuCFo/OE8a4F6I7Eg5JhUMiN0aK/Tllz5eyZ9ZjNy6nnqzdrA5yNkeZE3gcDERWGOGUml4RYGJ86Mcm8Q0IjIcuPSNfMBl0f+YqIHF5nKAtsdSvyFwNaFZQeuwbmc4hmSJkJYAuTRy2T/Jr89kfUP9IRzvVDzmKvUz2YJH8eTSljOwvYdob6L2pcITU3w9jWKjniwkCDPrgvZ0Nik4al4hUrrJHVNHkwxxlBlAvGIisMIIH9F3S3fxGEt8AU5N4psBHxDEuHHPDuApGbkEWd6lfoe4lZwMCrAl0sj+bvob5pYC9ZDoYlPaCDAAgrBWCu4lSZHBFmAeLAZH5I2b0wRokahJSZJM79TmB4wm4JeSOm1ZIl4Qg3P4Ibgv0OSQijRa8FKlbgMgKI71fIwwIW0RsbVC+jkwanskAnY5I5LgKJRCRlvoVOfWuJh7K8xiCkQOY7RDJAxF1prW9JRB2lHkb/WhAgOwJLoUBkfkjBkQk/UwvgFCfE3E8AbfEDzjepbOL/exHE8Zovi0OCNPNgVJIviLEqUaACAUQQwIimdsUU5PTr8CezFVwQITM33D6FSHL7wgQgyl8HCa8ViBCVovR6Y+yCwpeJSDS0eRpYkAol0KBcPwRdVyR+mWNMCCKydSGLtvm4Pul7z9WmGK/clviYmpSb5gRExGvEcYh0akJChzwNyG1jlHGxajiPpO5rRRMBmM6JK4CdC4YCCtV6lckroZpVpxM4SMKI8NoJyqDFUwJBENt+/BqDObRYkeVjyGLNSJRDxbSlhJ/BI4rqB9XVEi+Mt1k/R1DXqr7tChbz/LZ5f5euS3KHoEcV472xPoh+B2RFUZ0sV7frhj3rW5/S37hHmERizH+Ur3xkzGUP3mpYSL4JdvfAuIetsk9QKzXGz8ZQw3Edq/pYVrfgNiA2IDYgNiA2IDYgNiA2IDYgNiAoIffHhyIfyNH598Vcyvaxr4NiIcB4lhpXMS6SMgeI90/vT6lVpcomQ1xJagY6nobbQa6dBstSDdifznmRnxrW1/VwkmGSzyUeGvFOdomEFXfLaW+NM4oB8xS+u6ZSHIsACqZDeXAdFeACA0gwlo30bWxVLmIVUvV2SteLfU5qIVF4GsNjaIPrtLONdGtRlu3Fxq3AJMTdWgi3gAiPbe/AILWgLh2RSyAiLcAQQ0g6AoQRJccZFALHlantfYrILqVWotoFzs9EMqbYCDOwskwFgP4DcZbMLUM5VYIEIcAdQtjSZiUu2c8xHiezKml1xQUkisH5y5ymEAzKNtjNRBwMKD8UbIi+ok/Y9kRRlklYIlgsinOXvdqKTknFgWuCKudXVZ65Xn06ZwxaNps5FRaqfGxjNbYJgfHKOF6JBuHSYa9PY4jFAE4VUiqGAFuRHIPSR4jUKuPJ3NLgQuC+a4UjIcIFoMm1wOA4BT7ELK7iDI/HAOElPegHIzoE6WkGh0AIjk/iAoIn/kRjLXkz3aGCJVXi0+TuiiicVoCzo35MXkuB6+Wo6gf6JVZaHy0okUCNThGCTvU6BUmjiScyaUMRC+8iS4xMo5n0blIHiOcY8wuCH0qsWQ8MBB6JHbiOoIhMo8I43J4ZQ6rLSS1jRihxuFZET0ZEL1OCMg192cDojx73aul5JxYFKRTTm+uGcIM6ZQPYgON8iDH9YXGRytaY5uYRodMTYnLOC2BAAOhy4wMchYwlIAwYsEUMs+iZjzED6MTiGdKDYSl50FdqNrLHiQRahwFK2JKi/XkgYjpiijPXvdqKTknwZmm5drlisAwU6otAZHN1pZA5Ggz2yRSAwgTIVEgVPLHuBpJumTgPzY1RfetKaYpJlkfFdoVH+q/As8U1uEogNCpSagLoWxvzG4lxdQEVgTHDCC4lKmA8BHuB7/3Z8v7plcLH/GaGhaFAQGOB68Rjo80IprTyaY1q7/UASmjzWyTzChJQECZgosdzzzj8a+AMUCR4+gYGczAyB4j/Wi/I1QfY8r+IhXj4QQWA6lnytzeiMUavAtbrMkpc1h7Y3YrOS04HLL8UTRHGFMBERURZmMQFWf3tObVAvJc1tSwKLBwm98MqSqIfi3RLxwsJ6EuKVp/qQNSRpvZJplR4oDIPy3+zNZd/0J74+ZjjitfLq+/jxdKrX3bjatfZi9He0FxxJQp/vbtgs+ofvxKzPHeE37ZCYijvUFxZLvX9Dei3YDYgNiA2IDYgNiA2IDYgNiA2IDYgNiA+AIgvrZj99ZUlr909q/E+KeA8+18qs0NiL8MRCTwFfj+4HIv3XRjhovgiU7cZ5en8hYsCE4/qpF73pDP3c1/ZNtr8O9v/PezFnqWV89vKPnjdSWMnX/z9PLjlUvutZ739722QPv6rN2+VZ2d6Y5q2Xb5H29PLzv0JvXljtuZNog4yXgLtpcW4gz1ZnLkBkSnQHQLtoRkXCaaGkDsETzj8f7O3XzCYNqgyqsfewDxVIziUwWEobHb76XkXutxQLy0gdil1jIQTxeA8G2j6d3+Cb1JfYlr3Ifi3wYQdDcQdAUIg0tFSGIXG0C8UOraFSD2tC+BoBUg9rvPAkE3A1E1LdBLb1Jf7gDC1CXwDLBpU2TNic6ZxUNnwtgJEIIwfxTURfJ8/Shy6jC46MELGfWheslE9ll3Q5Imc3dfnl/3+3kqeXl///HGA/D8+vzKw4B/ExAv9PJE3+Z9/P/zPPk887ufUu4n7/0hxzIQ3+T8b6/v7zjj2yvqfpv/SC0/uT2ciX9tQrQzdXp8fdmhbJqK5pJvUidHPh952e84fq7f+gLGyiE7qKgfy0GdXbQqzkGZugSvEVmbImtO2MPZABDpT9HTqPxRuDb5dwaCj+epydwlNM0ac7LUGA786dnzXDKPn10R6RMtk5FAsudO8p/v8zH+f7/b4d1ePrjfad67m8/YcUXzWsJnfZd6vu/e37/PNfF5qPt/8x8uP58lrfCZXMt3aZXXFzvTrrAXLeunxf9JFBI5Pb0CiJ3ry/HMIzVof6EnwiMM95pyalJ1Cc5bZ0mErDnBTIbjGc4n0Jn4UD0Nc6AITmPAgOjPHgjwIjIQfdbdEIbDE6Xg0xWRp5bnNwDxxCARQHvmgX7bk0HIS/m8942h+fG2k6VzTwByXkTnv+epaT7O5z3x/CZAcHkZQ+L9O0ItaY3QM22i+t9uv1sC8ePNgGCYcUXkvpjaCPQ9yKkkgPVRAAF1iRoI05xgFQl81TGdiQ/T0xhaQPAa8aEyDumKSEcBKWp0fIyXvQaf14gMxH6XgZjfyTHizysZEM8vmIrwucbKP79TIPaEK0IGXT61BgTOkenmFVfEXq8Icmd6IPzUpFeERj4f2dkakfuSSBL6NSUDoW4xOU1q6hIOiEJzgsakhTHkqYldSDjxn/1RPBCnExPEBIiQp6YQO/36mlU3lI+xf0F3drslEPOEkIGYlwg99u1VpiZMNFzuO//59rrb7XcVEDusETwNCRgvNjXJe52a+Eyu5dvrU7Hc8xoBoH/+RFmZJl/4S5KbmmQytG9NuS/iJVPpiYhjlLI+KHOdTV0CQJg2RdacoJgWmhN0JsBOAEc4+6MYEKIAE/uTMAmFLSHqFiP/jpj/FiBssU58jN2LLLbzLKu/I7CgYvmcl0h5ZUD8mCGYl0Ms4694N5f7yX/mwZ/3GhDyO2LH9XC932Q5n4HY85kvO15856M/sRTzmVwLzgIQOBO/JngB1rIv2MNtz3W8InIuYb8jcl+ijFQMfrHmEQ7K+qD6d1ps/gqMF7+2rv1YadXk9QEvl7/1l7X/TZXn7v3Kmfurv3L3KzXsF/ueLrTzy7c4PgPEGvfiz9zi8EPx/Eorw/g1QHy2N9u9pt/avw2IDYgNiA2IDYgNiA2IDYivD2UDYgPit/VvA+L/BxCP3sHHifEOasy/t5P/T4GI9iLLI0z5YCzLNLYgISzdVy62hXbcvli3fKXdrg7hKtHkVjYF0pf/nO15t+PILdjzcN2cEDiOsfZFCQUQYXkzNFZlG91ZAuGyd2MJRK1JYSoUeF6SLpS6DYjshxIa5cMqELkfWfKhuwGIlghEoKxMrtLq+uQtA8FS4/yAa1XbjUCE8q+Vx/JCI7wLQNBNQNB9QFTn3AoENYC4dEVc0s3wQAycVRsxDjFMwzRkz4dYRdB9GogOOhqHSd0/TuYDEhJnwzxOJMeszANuAo4n+qjvCCDM8WSlFJnGRslnoNSC+bkcnCw8Hj0+pHpLbxVzOmEnE4vxmATke/U8EV7KBCCS8ProazSJ9cPUV0AcFAg8H3068XPch6B2HFQqbbDYep8USWrmhjE2TK/kqEwOGflRMtLCLmCFCE2CBtbSSA+zK/dgJDLmgfcUMfEDBsLcVlZKCfzinpL4DJT8I7iFqH4uIT3yPh8fwXiwesGACOlc3jvvE80OxGjuKZQcHvAZJs0dwyMFfJLBzBag1CE6IyoAoRoc8YQPWvAqAvzMeGQgSqWNTlvAA/w1c2MoHu/XOEUTQVq1edDcGHoxIgC7AGoRWhFBxiTYAKkqgTzmrUBAv2K1lPA/aj4DHhtHC/g0wlXFgDgK0UAjw7CRKVnYuaQ+KEfK2hsWO86DoINcEckjJdd4PHcj+CkxAaE2IiIDk68IHvY5msGuiFJpg1voU7wL5kYwxRJEhTiTXEsNBPMzjF0QsUbkK4J0iAf7rEtHprRGqMNJuxQlaDyfAfu1hcmAiOSuiPmd8EimwQEhsU0eiDlynsun5J5iTkmTCDDYGpE8UnyNnbqmDEsgAoDAGsGLdTbfqJU2ZLFWZsqypyhjyiMWJ64IDXYwIGxqoqCaFQ6IqFUH8DYOkw6xzqYKRFgvlfgfFZ+B3EchAWFCQar4Ye5YwXUwn8s1S+vRaW8kF5goAgxu4hgi2dRkahyYmuJwmJZA1N+aEKva4xRKG+XUtMbcSFOTHOempdWjLmXq+CH8DJma1EmEoG2hyhJgHqiy3wSuh+hKjABC6ZjNUuB/LPkMRNYCFuuj6lTgHD0m3+4jXCMnU7Kw1rjmrH5h7inom5QK5luSPVKwWHONrClibi+R7OtANN2Qxe8ImUb1d0SptLFYrIue4lWXFutORpr/jonUdOcWw/Jr6PI35bLU57fyK/Rn4vUxZh1CTGB1O7dtyx5/1hklfta9RvC9Glar1N8Bwn4BW4z5F3FstvNZIOjTQHzhtt1repBR2IB4kFHYgHiQUdiAeJBR2IB4kFHYgHiQUdiAeJBR2IB4kFHYgHjYUXg0+5j/Tt82IP5Y31YFZvuiTGy9XtTFSRK/XVB1DWV9fZOV0YrHtRDN6SWSPsGX6jw2W46u7W66Z5hiUbvFDN3l/DqutrYctXpsVoHobgYiJcPVUMAZbIRbgeiIwsLSoxmPi2uMxR1VHqrO6gyLzlG655kcYKhRv/UmNIDoCiA6lbdwr6v7uq61BVGiHpsvA4IUCL8n0q8D0d0FBF0BgtzQXA1sAQS1gChet1rr2kDwXweniJFYEco/UIaC5K1cyiOqRXzyQTGPkKTgMSdZRKI/sRWQJAJf5Ow4GNmF5aD1ia/JqfRWOWgdHWXnE9VDSEfg9KJskDlFo24wJ0vJHLVfnMw5aJQH5wDj4kmOKMfke1JG4mu3EcLg59fmRpNGSMpzCsh6Zkm5I6h5IaQk3kBEiTExSCJQHscOzmZgMGaF90EZVJXDFDzmbN2AqQlpzUG9FJCU/fCaHloPmBApyz0UjixaN2Z7JGfJGSYMytjQ1OaI1L66wQxkzA/5lyMd5Yx8HA4wLp5gjijJXIDKSHLtqNMUFvrJXjNro0vjklvDFTEkngpe9WgfihhoDM4nR+ElsPcJO4iwogZR5icc5bj3QQFjAfwNUh8Gc/9JjinKY2AgsqZH4micc2a3I++tEiWGSFlHivVBEGeWaumS6YiwQZhjEbydBjxReoLbihEOvPGIxcNLrXfNABDgYVgkvvZeFUvM2MZeqxvF2fLrpWWI8VTUucXcsTIQFrp8dkU/I7mFZH4CMxoG74MyJGeUdEXYYp14C+q3IioekZKmh+M8LIGIUlukEohoRBd3RTDJAUAwGwRpfA+EOq5Mdp0vgbB4mHOxBIJ5GDkSX7u40VAGIpIHwtRKaiDw3Y5tUYS2lCxo8gkDQjtM0aYmwgXlpqaozIjkgzKXVsZCkPmwmJoKFkOempTpYHUOiftgU5Oex5EEyg4n6nwy9CcDAlohaWqK4FPo+yFJkFi/htPJJgtH9vLxZB8Zs2SqIilqDzFNTf61lQCfxd515FxjAtuiGB+FjF6JE+B8wt+HeYkb4f1xOhYLq3AegvdBmRfiU1D+Br+bF7cTKz+p00lyFzG3E6fpYYu1skig/iGDbI4sBNZGBkJLqO1Yr1ohBzVgg18JL6fi9HJCDVC84LIwqCHKx3WxzvEkRxRjgyijJEXia1emhyNvHvUrC0qAz2LvRI1Ee9YxvyTxUVZ/tFz5URP8q9ZXta/69RmvR9A4utb6tX7dFsl9ffO/ErrqSLy90faWMVyyNf4MEOtcjEcDYv3zrlfz7922e00Psm1AbEBsQGxAbEBsQGxAbEBsQGxA0L9n24DYgPgvDeMGxB/eIhnrAH7QecN9VNlUBR9v+urstVqNxREXZfuiYFyNrb8YuR49t1o56rvynppxNcTM2NURKUQvulCPxDKaSncklKWQWL1szhxbQ5b1u4vaQ8k9yI7nuf3o9oQFEDmJHoqmfco/NIDwth9l2r5bvO6o2crYAsK4Gu/vOfJOgehc40EzCiiRo+lc20sg4BqD/2NFfih7Ga4AUd2idcWvAEGrQNAXA0FNIOhWIGgJBLWAKEYiND8ELSAoA0FLILrLQGTWQRBOBHMgwOMI5JkOlB5U7VQfI7MRwFY4KscBfAekSvkIP/18nHzNHZmaRpfrcPyKo/BHwMo4OgcSYYek0vo4+9hqJXcadaLlQGCmcMrK2rdzGTpjkgTdbwwOa8/2EXndETwwLGkpAt8FQOSesYS96G04lREbDdtHmYHA6hPQqUBSkQPITAfjQkgaMVpGd3B6HQFMjMS8wNQ0iGaBJBhHzS6HLrEXulSH51cEeaJfVADyo+38EL3LMg/BBB6arUy2pkWpE31irxiuma8Ia9/OlWsoGOtD91u+WtuzfURZdySo6QLzVzrlLXWEJ8a1tDweD02DzN5Io2GlMutAPgdnAYJyQj2nvA/CcAAQx7OpuJjmBbQlIlLhmtdFzvpoJU2F4twl9kKX6vD8CuZpwG3CVDWi6lZ0hJYzxYCviGUr+YpA3p3ZF3wcEMvUpO3buXJFnO0D1mmfMhCmVgMVD3sVlaMC/kqnfJdEkFO2CgMRdXpP/BQdDdtHmXWg9h3jGhDM3SCRdAjyKrMROmVJQHwkotZEHnCf1YJYEm2NwCvHr+AZ9UM/85hpTd9DLvrJUww6arYylkBEWgJhqyPOzal/AwLXVQ2ErS2mOwJWB+LrlO+SgdCxaABho+GBcPYzcSiB8NwDTEgKROI4ZHZRgCaFTk1g+plCRnCyK6qboUofmeOR+RWYQMAFMUEg0a0gr/cBPmAComzFAXE6RTVUckCkyO1c6aEySQDEYTIGRwFEsO9FRsSJ2m+ZOAf3rSk50PAkExNJz8cJFzIFwlgHQbgXXSIgYrHO3ANbrI9KbcxsBCkj2hIoA24HWBzaYWVXeN0MKH10SbQq8ys6WbbBBelssRaFkGNS8JA1jEM8t1o5usVayD+TAcE1zx+RFLmdCx4HeBkB+8kYHNYe+ik8jKQ7IhyYE/grHO9xst8RqWcn7oUNuqmMIM6ebN+N2/1aEeIZdN8ZV9632vDv/jnf2tJtkcUvG4v18yL99k08g34zEHd8kr4QiH/dtt1r2rr7r41sA2IDYotsA2IDYots6+6DR7YBsQGxRfbAwf3+WB4Yig2Iv7xF/FPdorvtLo6eqwSDPu3sL5S96gUsOhqtcmP4bI204FmgBbBXROfYtlBF306ZFy4zsYg9Rxp9+yvKtTH/azwNDi1bYNiNYcSCe+xeDiFUQFiSkNRrod5Cc9hKQ5JMBqiBCA0g7qmRcnS6Fy0ohyOmUmrH0V0DYmwDYWeOoXPxeZZJLBy9QwkEtYCgpQ7FJSDoC4CgK0BMw2drpMIrZgFEddLSqeV+IKgAghwQ7T7EzNNgefHsRQJxdbM9YrWAPkme51KHCaocorlxQsq8U5aGcRzOJd8ju6GcSobGUZUrOlENaJU7nTJn4s4axXHlkNJaeDw36WcE831BHZ14aFhbc+ZpSgodp7bLjCmXdErjGUMv8RkQmWUCHopMikUf5rLG0+Bn6bMXST8huUhBc7GxS9YcudSgCT9JIg6daQPkPPecPvwo+B7mbsKGLuS0DsCBAKME8g3LcnAuoWRvcEeNEl3Qx/oBxOAeUofayIC0JnoTs8FA8odIyd7aZYZUucSA+AhgpyAD6Fkmxj0xCppjsFgqnwmS2YuElPfAviolEL4UZ17B60DaHLwIZjL0qusR5qA83wOqH/CFsFp6Mg4EGCUMRKscnEvMD+WuGiU6aI4YEF4tICizJHNauA3TEPlQTxS0DGZHdpkRYQBVLimByIQ8zzLpQG8lPyoyWhkI70VCynsA/4HpAp16pPhSknYXfx+VJMH8CXcTvXo+gud7RFPkoH7MviiZAxF1jWiVMy8T+KHcU6MBEUmBGKorgoycYxEwT8X0Pz7UE0VbnmjhMqN/0hrRAsJYJh2BG+JHRUbLeBoyNQXHmgDNbAA7QYBQiYZcClMTrw55apqDHBLHYQj0UfA9nL+IZ2gYByK5s7TKjeZcQvfWqFMT2V5eEeH1gm9NIUVvUxO4LOXUhJZbLjPGXjEe7ulk6h0OiGgCR25qcn1IPA1eIDvPmgB7gRcvmeeEzVA5lsD0i+dX8BfAy8ArLJ+BxlAwGqZsNebbAgcCjJKgXiV1OedccmeNYI4E7dVRGCb4OiKcixFqI2CYYG+X+BnSrluqWy4zsM5B7MLViDxaBoRnmfBalq3dHIMlfzu75bdmW5Xvglbf3XUtY1mWWzvz9jhkjfjimPNX2F/cbgGi/Xv7c1yKS2f5WJbl1s68PQ5mmMQvjvnLtu1e0/+bzm9AbEA8dG83IDYgNiA2IB6wtxsQGxAbEBsQD9jbf3GoXxfbvwCQDYg/vjWVOILxHOx9eU6kfDQW++oyi9ee4dBKMa/UEjVSZJzn9Py4uPMTFu/zHlFoRrzePSUDUUbUp3fHc7tHUtMtwxuzi0rvxpwy7yWLFjSUOIKl133RzISI7sxIpahBzVCokuY+se5rbQJRpNeT7gYDAU/24rQGECE1mfU1vHvKGhA5JrQbqJX6Xwci5L/HDERXQpgVPwog6DoQtqdWsmipS9wOBH0CiGmwJ54vAhHTgMirpXjLbUDQ7wEi63/I5d5Q4ugn5LCycwmruoPp4B1BVrQ2KoYClCjkglSti3Qs15rcVFTAPXmOeM0LM8t4f5dnp8k4JefEuOjl3dn8YUY8SDynfzj5k6QZzCumhzOKpGcyE2QM5s0Cgfe5JB2LWEx7AzfGjdFxLhkkaJfbPMUIpkeXysur0fgiNM7jY/4fXokDqVPvXMJJSDAdvCNIW2ujZCiYEgU+IkPwXim5Vn3QPLByhvE/ap5DzjG/v0NN4Aiuieh2ZAuBjwC+h6VHuYJO9TWiKnIQ9AiUzeGYIAO0O6QkdDlGZKDLHpl3TE54JjMGZZBEzZV2+sA7JfUQS5jqo/pisjDAnaRW4mD2AsskZOcSz3TwGhwtrY2KoeCUKLLWhXmlWK04E7oAYiOmfAzPc7BIe2Ig4MsDTgnUNsyyg4FASwHuK2OgoGoCqBPnMCODs+O9SjiYhshHMC8U1JiByD0y7xj0VDRK1CdGvSq0XWV8ROiUdKlP/EoVP4QvEkECrJU44BninUs808FrcLS0NkqGQq1EEQuVisQioQwEtDaCceMSzyGxJCZerG2/Kdlk15aPkNL9IDmKJpR2m7IQRJSaWHFDaQFUAmGUBA8EyvSjecdoT8n5xJiLCgEIIRrEYOohlIxIKPNF2L+GWkocOjU55xLxSxlM9GOpZOG1NtpKFJJUH/IUZCyPpMwxIESoccCfpeZq5KlpTPuZU/IB/xc3NaGlUc7n/8akOKNADDY1HVLy31gcHAE+gHBjESDKHjmHluRI46YmTO8qADLKCIiJTbbs4VejATG/mteIlhIHFmvvXCJ+KcJ08I4gba2NFSUKyloX+ViqVQWr1LxM/VlKnkN2LQEQ2N+JQ0ukvFiPwfgeo8bVTaPqa2Cx5lbBzQCbg0KfoxXtjiNYG/zF4jwG6HG4Hk3mHYP6sLCPwTNIrASzWtDPQ2ofXzFGMr7IeInP7r7Yhbt/xDR/13zdtvw9HD9dU6T7eSif4618cnRyZ/8Id+GvAnFvD79+RG4C4vG27abfBsQGxAbEBsQGxAbEBsQGxAbEBsQGxAbEA4e7bPPWKB5/cD8d4QbEwwBhd1eOZ/6TFQuSzoU9Lzby3zgWKbNAwJyIzdqrvXJ7P7g2F+GXt9xCNx7H+f/pH45tiih38bZcbrF3zIpGdFUtZURLxZGmD0s6x3gkx7ECIlSRYTy7JhBZQSGaTDoqV0HyVNmYk+yRHO+jIYqwCsRI+mRpGU8JhLPTlkSIJltCcEC00QiVaEN3BYhcSxnRcqS6SrWkPDvxSAoguhbpodzXtYCIklmK5HkctwBBSxbEbUDkaFaAsEdtFYjubiDoTiBa55Yj1pJmwd4lEKm4MBNUpUKSOs7tBOwJpE2t26w6Ebw3ChIlpwyEsR3AVsjuLJm7YVoX4HiABZG5F2A4MBDmUiIlNHznXyI1dFQCoUoeRRljbej06VQ8OvNOUQ7JQT1hSraGeZ+UEXXyKG/qB7gffJZwPqxNfuAXtSYeiUSIERBtDtEWwYPZMQv7d+oSoo4kAd4oSellEtWJCL6GqXBE9VyxK2JIriqqcBGQA1RGRgR3AUdiBI/Ccy8wnKanYQwOqO8Lt8J4EjlRGeRZ8HmloDgDVpUZlLWBPmVmCCmTYpB07yCuLUN6gL6uBVwSiyjRw7QfrAJgCgwwfECbUAQJGmHuG/gysDqIlhKnCJUKUs+SoHoRxrvwawRBHATElLO5jMRyalJGxDEpXHgWBIBQdxW4UhTcC2GBqDCKOUY4sSvocQhPAhe7OpoINeAAbZuqDLxajDyZ4hAGSc67cykcwxJe16J6DBbRGVMOuB7M2dCPZbL+QJvmxYEzhcehQBzP5ogB9RMBIlIGQl5NzmNkqIGAEAkpD8E4GB6ISKZrMRRA8P5+VO4C75w8EPpZHGnCGjGkbnM8quIUEnOIgl8jJPI4ZgGJXEa5GXmNSHwLA8IMNfTYZK4tRUvkIzL7HON6dONQAYE2cXVkIKJ+yKD2EbJLiwKhrIRgdjJGExwgDxGyc0maysqpSb9/jCXzAmuEApEIKtmTpZyadJIbMRHxrBtC7rYCMfCfw2QkCYklJiAif2uqy8QA1oZ9e0ltD6lXZK4tTtujqMWUnVJEQ5dcWDA1HaY0NYXcZhB1JwdESECYWY9NTVg4emUqHLGs6MLGbAjmwfJiKX+wkMU+iWgdoVFxwnH+HWFsB/Au5BqQxTozMo6Zyjkp7dJxL7h2/I6IGg98THRqOvGfKPwMU5Q6jgDiKGZT85lVGWF0JN8Sp+JxOk7mk4JSIfnG1C1hYXYRseLIqCMkvYnKEwHnw9rkyKOMsvFIjrJYgy8D7kz6rRHb3yvTlzYegq7xda3+Dn2bZ8htHIhsY7n4+kqXyQJWzsrc4rSyHlMsvprG5tfVyzF1iyOrv6wZ2fXtfm+Uy+HdxoGogaBPA3HLth5TvNKbW47dDMQtg/Knt+1e0wbEBsQGxAbEBsQGxJ84cQNiA2IDYgNiA+LvRfv44/kfDviW6Moy/1pvo/9XQDhliood0diXtuLeDB7dbZdzr2O7qkam3fgO1V2jUOpoFPWF1RuScvs1XowiXhibfuVYbA9rZTZSA3E8r7bslCnKVHmwDpbOKloBvM/dKfZsatUVV3ls7i9aTRmDLtltQFzCSAohtOtbAmHyFoQnOzMmDRZGq4c+jlw+NAa5W4xathDRMtGAiFSyPGJDZKMNRFw6qhgQVAFBdwBB7VbzR78CwnYHug8IagDR+OQ3eujjaNRa3Za/AgR5IApeiK/CeAglZwEPutLY01E9S4y/ACCgUHGcjMEBBoPnTYAlgaST506w1oUxJ6pWK74DXF6y60vW0Si5GPZorzExTCkDHInsgOLqUm8TnWLHwjtGShW8CzLNkMzo4Dyb+rukflsc3I6wRow4M0Ghg4EwZY+z7kM0RNCzaHAWJG0Z5ZFs9RxJ/AUBAs/jm7S/PfwetETIFJcYK1UNaF2AOVG2WvMdmI+BnC9cX6CjIeoEhaOKPexuTAxTypBHzIfsgJLromRqIMwORKLeMdx+xbtIjBQbHbBF8Ji/9dscWBCzpGZHZZ5EZL/nd0nZgzkr0UaCWS5BM8pL5sNRVDTgRAIXlWRZ44AwBgcYQvZe9SkC+Bpem8NJLMS61VDxHZiPgVisZZNv8CodTAKNalsGJoYpZXi3BmaC5H3oDSLTKyJ5x5hKiONdmICDY3TwIEtL0fptfUfMoiliV4T4zkCjPwPRn6NGk1gcxjqomA/CtYATScgOJfUVQRkIUcYwmQPRzwBfo9TmSKIjY91qrPgO6nu0CoTMsFO0GCZ8cgOZUoaJLoDpQZOvC3wV8Ucxvop6x0Ra8C70ioiO0dER1EqYk4J+W9+jXhHgouhSMC2BAHulYHFIgDXzgb1URtaLwB6W9HEOJQBCL0eRhUjUNKdPETJfI3MnktbFotWx4jswHwMEMRNncUCUjio6NR0mY2IEeYepySg3vi7/sUr91Xip5l0Q/FdUYyN9awpKGbL9GofE/OGYJ5iaHBA4PsQQnTGWcixq5gOMwEZxUpFl65T4CyOWXD7S6XJFunB36jOi+hTK16hUNWQWzkodudWRSr4D8zE6WSrh+qI6GtMYSkeVvFhHVfGADkYUjgQlBxRfl/AndLGO5L1jUI+Pw+zgoLER0u+IYEu8jRHikJiZwZE8JiMUOvh3hCl7jOINk0di8TPl+tZ96qzllpkTcaWm+39Zxytx3cLoaJ3Z6qER3lotWDsGxN39ifTntvw5+HNAfHYc1oG4zEnRMuNn+/Mg23bTbwNiA2IDYgNiA2IDYgNiA2IDYgNiA2ID4pH7868E4ZZo7+nB5nn0cECE7PjR/WNezcWGrMPEf0fKfy+3WPEyrFwsa7v0AFeQ0GLJoIiX+3LxgbBacYPvwfcXysdbK87RXgHCs2XYD4bvu3JKq5/+OccaCL2vGmPS/naB4M59KCUeXENXgAgNIAKt+ndwaGPJDIlVS9XZldVI14wuWZCMLd7JUg6ipA+sWHdItHV7JZWmU/4Jsmrwg4FQOx6QXwMi5aYXQNAaENeuiAUQ8RYgqAEEXQGCaJ1NYlHAdIHW2q+AWGN5FNEudpb7vMcK+8EMBoTUP5c9JBt5c/wAEAfJAit7I6VevKbGQV1E5Enq2GvCBo/1Hhyr4aDS7VmhQ/aPvT4Mq7LshR4HJ4W6xAyR6INpdmBKKc826XTjRXjGSXIwcbHjirDa2fOk5HXA20UF50ekwjyPZRltr/4wyi2ZzwQQWoYsicTtco7y4ICQ3LbobiiXQjO88hR1PBn7ISR3kVJTYxCpftWiEC4DgOAU+hAyq2EoWBzWHjLAfMXGaCnPrMfB2awuMUMAhJwvKVrA7c9W1klIXBDHODEHE3wiNYpoDA1Nk8boeB2ImXNp0ndcmUn+YViJFo/uh2DkOzA4PtRLBb4CuIolX30S7ZCRPyTQD2Eug3IpwFjgPCGGUFL8qcRCU0OA0CORz/1wdh3mzEJUuqhYbUHdUIJcTbUXSk8GRK8XNQQiWN9CNTCKs0k1NKLJuhQZ6dSzFAURudpNGSPzOmLIFAXmeDiWR1g6tyDaGK3Xfo340JEFrwVTnfjBDLgihBonV4R6gGTHDwXCLDkmK1Fraph5hQzz2InlRQmEsRrMpCPqLA3tDNIE/TwTTrUXCnud6GI9eSBiuiLKs0k1NDBYQwOItFKFvOhb7XJFkOd1eCCS5kYDiBwtiwZZr0sglERB0foyjlnWSE3QAEQAl8Kmpui+NcU0xZjBTcGfiOAiKBDhdOpKIHRqkrS/53cM7HYCN5QQyqkJehxCLhuNGcJz9AmuJwMDASJOPju5tWTtC51m+Ig5mMhrkwCizDvBGuF0Z0ZEczrZtGb158lrGW2XTW0wNYUExKBAKI+EvzVlINK3JnAP+I85fkBxAwssL7xdchcpNTVUbeKEhtUAbcRiHUNmNRwmcqwLa29UN5ROtShKPQ5RO4iJGUL4eMC35Cjv/dm9W6yZeeEUMyg7mPQudizcR2V2kLRovA4lqomtm7IzKLM8koZIFa1phgQ1f+t0sUaZI0ZDWxtVYSrydDV1a8zyX9m6619ob9wuCT7c/j5eKLX2bTeufpm9HG3dywe8xfEZB5Kv1f+4sv2yVQ1Hu6rK+Zt7+5u37abfBsQGxL8ktA2IDYgNiA2IDYgNiA2IBw9tA2ID4q8M+t8zsLmdBPOvZSptQKxuSERGtye9dndgLpsnO4ZCXH/+p6rT5cRLjVd+BSWO40SLvXTTraSoMUfNDIyhdE/RuEcpEusI53h28x/Z9jrYTy/LVp7f+Nhuv9v/eL19xPf4Z1eHnHgZlt4ugQgLIJYMCcdQGH3i/ToQndS2BAICEMYkCVTYgoyXO6pJmAREp0B0C36H5IgmmhpA7DFQjMf7+27Pwy1wpBHkv3/sOfKnl/lPOn1HT8W/5ag/CRBPXwVEe3Q/AwRdBYLuBoKuAEGpRwJ07FpXxAs+uDycAGK/Kwc1A/Hj7cfb02LIy3He3XJFcNqEmQnHSjOj0uaYwNsAQwL+JC2GAtgWh7Imx3ggxxsB2wHP5x/S59KcWKCXD06G92fpKHue4HFhq50Hdk7E0NH0MlDryEDAPQWeMaKDMeqHUHKn+pBw4mTMA/vy/LrnKefl/f3HGwPx/Dr/oefXH/O/3155MvJXxLe5NJf4wWV+4t9vr88/5wlMS/O/z3ME39IRnMGlsUaEIC4PgTzbYqHNAQZGRD4YJgBLhkKnbIuhUsvIjAdSXQykWOUpfFGsAOOCs2ame8F7jZPh/VmSeQJYU5Kw/VANDgaiI/SHa5N/5/o/kgOKRW9XRIww8TANBCQ++UqYp36+DPZ2RfAf3jvv233nv+l5b2vEE32fS3MJOXOe2Phf3sdnojSfxVcO/z0f+c5AzA3IeQRfEYPAsy1qbQ7V09DcLvxJ2gwFc1jJziWe8QC+BZfoKQNRPHWtTiz8nH7IlJfkz9Kp/gbHCE8W1I74PzQ/nCdeAAH3FAMCTI4MBNdoJArmZDzNM4cCoVfEj7f5kz4P7vN85PlN4KCnvX1rAmxcBkA8vxmUM1wAT86SNULgFIz3z7x3z/WrbkUJRKSGn8hUAsFlWgwF05gonUsc4wEOLASXFLdYez8zwhVRAmH+LOy4gq865snyoW4+fL0tgeD6cQ24KyIdBaSm6JEYJC97BcKtEa/0Og/kq0DUAGI3n8NHZ7Be9MrYPb/MB19xRez1ivBA0CuX2WNpFC6EUb8yR2PhSpKACHlqWjAURmVbVGoZzi8lqWcY28GAsMfCzYnFAVH4s5iyBpHWBiCGINpMzCQJoQZijkodUCx6eR07/fpqU1NikOxfAMRuR4upaZ5W5MASCAaIy9D++w7DLQP/7ZVL779/e7WpaZ+mprkusqnp1Mky15WaGbU2h1wRzEhgLgP8SRoMhQi2RazUMpxfinmWnIztEAyI4uuDaNOI44jqaiR/ForZ8wRfKlA7WM2ROXyTB0LMbiLcU+AZI04nI/+O6EcAYYt1YpDsXoiX0adX+x2BxZoX6qd5/wzJqwfixyuD9CxHf7ziTN73LIv0/IWV//25J160v+EIL+M/sVQ/X/8VEulPbKpYUbXc+tV6OZ41tkirps79fbn85V/W72/LvfmrLl7tyy+uq6UfBAj6ZSDW2CJ/+hZH/oTj1WUgnu/4Vf4XgNhu+m1AbED8rk5uQGxA/Lu2DYgNiA2IDYgNiA2IDYi/1KHf2+Jnovm7Pfiy1jcgfiMQT/5Ox4XbT3wXmG8I75DGoOfi6EoednelPbrcnoX+XrT4LK+EQTHnt9r8iZV45vr2dnxfR7rbX65lrzG4cnrWrnkTac5kv+zACNHzS15K3qLU5YPdPbWgwt9zZnbOXM1/7/3eFPLTBSA8o2G3a9XuT8ntkeYCyrae5JXki3dlxLuVePJ+B8RLG4h1vsVe964BUfQSXd0/gRFCxgeJpVlKAqKrxu7CFcFcBU4a/njbNwbw8hWxu62J4ji3dBWIOafy1Kx7v9L+7UC0r4jLQFSR7DlHIYwQMj7IGhBSgNkFyjH4KfyC+RXfIxeGgTIX5tySuyI45/SkrATwEb45zsLz69v8B/UZhwF18A3f3J6vXds3FoS2xwPHcGjKhUj/TUC8kPAn/LnLeHz77+8oifh9pNzOOt+C8O6VW9MJ8vVlh7PSR3Uu/Sa1M/tjPjJn7DjjzS0ZHwRJMdH/mKD3of4zyC1JIk9SgMwvIH61s+Qg0oPfd26NeJkLatLQmAqOmTAX+d/8hzkLeP9d87ffpdbcnq9d299RKmtrBK4IlJQkyg5AMIPiSa4Orvf7zhgUy3h8++/v3D9kj+tIL/Et5oF9/S4xfLfrY/eiZ/mJ8X/oleR6nl4BxM7xQYzvwv+yr8sofBdmwghbAantnaa1mYEgV0RiLiDVbUvnPHO+GLHEmAouIU7oHnMWDE4tt5OlzjgNVe1MrZv3GPthZ1MJrogExLxIAwhOU+5IU/Tz/zxlNuMp2p+npjmyZxyvIr3Et8DQM5EsvZNBXwLx482AYMBxRWQ+SCRzdukJyiLI6jeBkFeM9SuzEpi5sATiuwOCmQpLIPB5959I4UGk9uraeRj3GdwERHVFSEsGxF6WU653/rSSAVHFU7TPQPC/PERlpDLJrPItAMSe3BUhQPipSa8IHfb5yM7WiMwHiWTOLiT8rTUgvoNfMM/jP8vJowRit//26q4IKpgJesEz0wHvmcPwRAZMbq+sHR+ExH5YA0KmTwNiXiL0GK9qyqBYxOPb56lJItvJ8BSRXuJbKBA7rBGA+udPHJGJ8oW/JLmpCT3Sb02ZDxIT34VZjHE4nWKemp5f5XJ85eEHv0DGKy2nzErwQMjFx0vTfIYxFRwz4ZWXMV7I7D1zGFCHLdY7WtYu7Sv7wdqzFrGwYhnlGH+8ZiAQwT4xKJbx+PZlsf4p9e/rSC/xLQAEx2C/JngB1rNesIdbeQEx86fU8mq/IzIfJCa+Sz9FFWMhJZU2tzazIP8y3F8tu/gS+Int/e3WX9aX4tmvnHMp1v3FEuXRp4vl139Zx1uGoM0saANxjYXweSBuv8VxKZ6vB+KzPfgEEPcPy+/Ztpt+D9iNDYgH6cYGxIN0YwPiQbqxAfEg3diAeJBubEA8SDc2IB6kGxsQf6BL1wg1y+OPwyj6y5FsQHx9JM4r5dYtOl2AayWtDSQJ/zmbZvBx5P3H+V+uTXQxll1Mx6+pqh7PzXaLXv4ezxi+p9po86pnDJ/QL3eG6rTSvKKram0D0bLPUHuQ5Pre5QfWeejZ7iCKW3pc1sSy1HYcjyV2NRDRD7yPMtbPx/02zxgD4l7PmHmrPGOazIJ6cC8BcclxJF8RHoiBx31EKLCkjwtHlE5dVfLx4AalviJiFUFsXhG/wzNmFYh4CxDpzcF5pTjr+uQdckwOIeaHgv+NkSDi6CNYCWAn2EO9wk0gqGmIXr4D4qBA4B1rA4juxsk8WkQufYSHRD5ujiY4Jn1QBQ0eNPZa4QjOzlnFe7j8Ls+Y9/fPecaYg4V6xgzOK0W1LUxUP2SFDnua3zxDRBcA3ijRdC0GfTA+wONEVDqQBhySg4T5mEQOZCR9oJ0dRaTeCEcKKIDwp94fzz4pOCbPTceoyh/HEZoDUAiBh88gmvS/2zPm/f1znjEAInnGeIsOaFuwrkafLCsyEJDzZ2WOCKWM0LNiR8Qy2Wsdx3M3mpYHAPI1RW2ah6W8IqReAeKofitE5RXhHB7cGtEna40MRH+O2q73cPldnjH6kbzbM8aAUM8YD4RqW4iY1BII1s4YxFfEgCCehkadGSe9IqiTPVGviBUgAoDwa0BgTxK+IhDNRNUa4XxSJrdYT0sgoAbS1R4uv8kzRoD4hGdMWqwnqzR5pTiljDx8Zl4UkOZWpxT9HMyXGNkn33xMMDWxjodNTT7QtW9N2i3teNDpxx/PPil6rPj+o0AkhZDqA/AbPWN4avqMZ4wBoZ4x0MfQxfqUF2vzDukm08wQFxWCZwgDkZZqXaxFt2NMi/UpEgSvxJdFa47mvbL4HSFXhOhq9KK+oQuy+x3hfFLSYh1jcn85s9cK/woYRU9DHEsKD5ff5RnDi/VnPGM4fO8Zc9cW6+/xlL+NRyq1LeId9eqwhvJ7e/nLOjaOxXsa+ZKta8b+Gc8Y+uRYrQCRf/HGX6gcta3/eq6BSGeM9Ne3lpvKH27+d9e23fTbgNiA2IDYgNiA2IDYgNiA2IDYgNiA2IB4/Gbuau3fqwlzu9zKBsTfBCJePvXiDa2+qkVMAC6U922Fa0N8h6Du4rxwHPneKt/jne/0nvMdZY7gn3O8eG5z7ye2WL0rIg/5XSyLd41YPBC1I0l5DmphWkzJTfClvM2H32u1toBY+Le4Uq02OnX+QHJTTQkoZyjQcmz2Qs8N3SoQbUQ6x57JfQ+fBYKuANEKpAaCk4XdhZBLIGr+xy1XxBoQ1Xlj1Kw1dNijcDgsb9jRZ6+IdbZLWBS/Ewh4oDDDAFNKyT2YUzKn3vEijonfYS4nuAVsHAZcEcZNYF4GzoSsOs4Zg7JDRqSU+lQr0k0l12E+cjLOBPgkdtPcVC1K3kkvCa5OssyHBRAHzZVnt5fluXO7ekSjd04wtY6Gjh8ds/cMWQLK8zqM+3Jw3i3WD/apkYrkcxM+9IIsuQdz7mzQxKC6m3SJExT0cgf6ymGIxtRA8tWMDtQDRUqNorDPyVKQz2KqFQnYmuvAPi4xpKStMjiyqoXnnXDrSMweObkp2TXOBsrzzcIf4Y9f59xePGcF54KBIX+iJVLNCabW0eDxCwFTk9UxhNKdxnNfgqVZJcmq/YhDSraLLgSAKLkHPDTM68imGnlQQXoBi8M4DETkuAncCPMzOuGGAGYeaCUljNLe2eqGi8qS64Acc9Bpz6amPnm9lLwT812RNWJQmx6ZOzR7PqLM8bx2LveqBwVAoj+eDbSljgaPX9A1AuW6whoFbJDMfQnq3RLkHfqBjzwZr8CAKLkH8hkVbkegfEV4IKLNhyEv+sZNkCsCw0ywGfNA2BXYAiJzHTpmdyhnolisJ/N6iQXvRK/RMdMHCiBsjUC0zXOlzCTDNRprBZ/rpY6GByLSEohIJfclYJp0QLAnjNSkHigDA4HUeOYecJI+TU0ys9o0wyUVCLw2AyYythLPTRA5SHykEUCcTjatyZ4hT155aspch07pKYnYEyzDnb1WPGsD08vVb02LqSk2pqYZCOVqgMFS62hw/KeTABGCY4aU7jSe+xIoMUCG1A9MTfBAYb7CUZZrzz3o3WIts2NmUhD4CkJXpMxhwMJ9NIcV4SsEUlIjKQMikjq1SHsnLotasViXXAdjbgQyPklerLtpyTs5ytJ6+XeEfHxWz2X3FezvyLgaYLDUOhrSoxgkqs4xQ0p3Gs99CWSjmRdr/jKy8uVy5QvXiv3l6lfB6tteXP0yS+2vr1Yq3FJqbfvnTF+ytXoc7zzzy25xRLpzu/MXaTu0a89G/JktfnocfgMQv3vbbvptQGxAbEB84dD8nkAfI6YNiAeJaQPiQWLagHiQmDYgHiSmDYgHielBgPi9oTzqEP0/GI0NiGutynNhx5GTGOA4xJUbdl61g0uPa+IEunlOR1g2LY/z8p1SSc8GvkX3jzwPd5QoCr7FtTtXsY6vakr+5vuxKNMXQ9Kv1hnbDdFNt9LCHUDg8VJLDUbVtGgBgWcuPRCRSiASh2FMwDlegz375qtAJsyyAkjbjAHpoirNX7QQln0duxxfdVpmjfBN+KA1hXQcz3Q3xnCsKQDBjUZ3ffzLUWkCUZYdkTwZ9BHcC0C4vcMCCGoAQZeAmNsdUnomcSz0A9ECgi4A0f4IVkCEWurFgKBPANHdBARdB+KgzATNg8UDBmBECuesXAfmGVjJYIyH+f+DAgFWgjAUVHK80wRI5nTIWfpYLk9CyvqY2z0kIA4KBGfGIpV8i7qFXMdReRadMCiQQMoqHcZKgegE+iVpmtjRMZ3PQPSUVDNOpi3SJS6G35sYHcpDMaZGWWoZs0yIEx6k5ldIu0kUQ7Cn7XWNODH7gSHnufsjPfg9BCvJA6CnEJf+CNAZ4AfKozI9KD/WnvQmhOMwgrkQVFMDbAvmWkhea66v08mMn68u+RZ1C74OkpRoJ6WPUGJKKh2JlRIMCFHcCAxEzi2r3ITqiPC/1g/jYvi9xugwHgr2DFpv1iWpY2Yw8Mg9LpI5NRw1NjAMwHGTuXrIVwQDAa4D5nCUDE65g0t/BICWs7+ojxkS4F2A0yEch9EuRtSnV+KQRBsGA4JT7J5vsWwh1xFEE8RDTk6lw1gpc8nRvmDgDFMY8UCojkiEIojJwdR7E6NDauzPlD52vtQyZpkNzgZEf2YgNDZbFOcq9aS8RsgVwccmFU0gD4ReKwJEWl9yk6PwIChzOiJl6QZOnQ+oezTlCr9Yd0oIy3yLZQu5jqAEBih3GBCm0pFYKeRZI1GvCJo8EEF1RPoxpn5kZY68NyqjI686SYrCl1qOiq4vvX4k5qlpVH6KMRNa35rKqclKhlK5g5iTAR7IYdImlc5STE2FhkYIPHfqFIJvTQ0gFnyLooVcRxBNEA9E51U6jJUS9AMWwaEQIBLbIgERcJ2ncRmTMscQK+ZISDwUB0RdqhwVUpkYRDIIfUhiI2hRkPyOYEYcX4b4psJHRuM6SJdRMjjlDi7Nl5nwLE6R8FtA6ou2WCe9CSGVAIiO51Isqvo7Ip2bgMDviMy3qFvIdZjaBWtbqKbHmFU6EiuFl+iRf0eAQ8FcDWNb8LLJcXa6lOJc9KNL6iJ5L0TDusRDMX2OslRjVGSJFi0QXuRPwlo5ddMXKxfEG8pkDY+10pdYF+U5vo5ax6Ot0tFdjQvtt7U1Wnvj1VKxEYWR626VqPyNQDA36Fdb8HXUn6l7VTrK37jtT+htn9u6VLxQZqne+ce27V7Tg4zGBsQGxAbEgzS9AfEgTW9APEjTGxAP0vQGxIM0vQHxIE1vQPzlZv9629vV8CBt3x1RxD9hseeObemMEoumr9XY05XWi5tkvWoQ+zNbbIzjuJBbmGv65yxZyTNuHtpdn7io4/5RuH5evAxE57raUVj4lKyNiXuVWu8aQPhEfNv+w+tzLFxRTCsjRaV50oKT0WRjjDlNnyLQp06jl6jXUegKYkFcRtHYE6oehYW5SLgdiLL8sqrrQCxv664BQTcAcalRB0SCpmsO0woQkkaKwiLpqHxA0Qub3HpF1KNxJxBjyLZH5n7CF+m8X/gL2U3F1CdMV6LFowAQB6hYKCcCKZqDJl9MneLgPFusFuaKZPbHUcuARcJl5f2pT5ockqQ6FZyMEdnyBRsjsUesLsscHoRFIjn61LMeGXd74DedASYL98x8aLyWx7FyobG+HpOuiPE/TJcDk6v2dxT/EfALzP2E348B/IXsphJVfQJZ2CGUXAzwKJQ1FJARVrn+0TK3fEWYOkXIKc9UCydkM/sjULIZUE0MOWeISZMDeWvPyUj5vZqN4dgjHM8QzM1lEBaJ8vlEY2MINjUl9QA9YwjWswG9DZkcQE6lpFTikAFBD6jU5TBFEemROYZgELNjCWwxSjeVlMEOUJ1Y8ijAURDGRjROxFHYHFwrnruHOkWgJRsDNjlQxzBdA7QMTYygnI7erRElJ4MSEBXvwrFHjkkzw64I6HNEyr4rJRDHpMZhpAMoGvQSKbL8/TlULjTZYQXKJuDAeF0OfLXQ/n6o9ooHgpkNJRDiCJKAGEK0pmoehe0X4wvlRDCrga+tSQUQ5HNRAKG1AIgo6hhJrUNahiZGME7H5IEoOBkKxIKN4Wk8YySz0bB3WCNwZToghvIMqM7A0gNyFhwpgPByMaUSB8gW/QgyhNflkHBVDYSVOAbM7tn9hKth75DSTYU1NKIpUSj7oeRRdBmIoEAk/5IDBBCSOoUDItWiQITs5WJTEzQx5Jw8NQWbmjIno8tAlIwKA8KYKqH1rUkYF0OamrJPSsxRGxAC9OB4S0OoXGhC7seAoQ+VLgc+uNrfeek5UVqs4X6ChZM5Dlg9ukS8BCsikrmtlDwK/ZQIz4OXTnAiwHiIQjDM6hTQ54B/idXSC+MvUTUnvBMehjBH5JxTnzxebDl2nIwRrJGajWG/IzrV9YgqGFf+jhDGhfiuSB36GyWfEVPPPK9DtTxOXeVCY33lsQlJx8PrchSLdfsr560/VEoeRXflnMaPqkUtv7b5CEo2xm2/rOu41o/ePWZh+WV+UeheJkF0Z8Yba7kExOcYHbdsOabPAHGJj3HvmPnf7fdE9Fu27V7Tg0S0AbEBsQGxAbEB8TBtb0A8SNsbEA/S9gbEg7S9AfEgbf9bIroa3D0h39u922VKPjtw/0oJlw0I3uSOZKkaLPcy5d5+497KPbe94uLFwluhS0GXahqhYn9INPLqONFi7/u7PIC/4HKIncJY9ULcAGg3/5Ftr+2/v/Hfz1roWV49v6Hkj9dW954vArHX2mlfHJhb3eU9Cx+SQkcbT6N5jkNVvqql3OO0KkZDLqYxaAOxVNPoGkDkx2o7V2+XgOgW7i+i0x6re6YAYg8gGI/3dx6aJzn4pIWe5NWPPYB4KkayLLNrHnNAvLSB2DU+4WPpPpIfvIvtK+jqJXYvEMuKLwNBF4HIHwpL8jaAeKG9Dd0VIPa0L4GgVIYWQNB9QCx8SEr3EQj5jyZRXnuP3Mpr6Og8mR5Hv+I2otoUSzUNSepkGXP4uPB7YX9QVsfgvQxEPwEIbp/btYSVagM4TxNucR7El+fX/X6edF7e33+88bA+vz6/8uDi3wTEC7080bd5H////Prj9Znf/ZQzSN7PR/isb3IM5d7fUfrbK+p9m//IkZ/cFsoSUe1DUrmPAIiIZ4aX3iO38ho61icIIWWFW24jpM//L9Q0hIEB9xLOnJm2Bb8LSeXC9r6/f4hThE1NH+oYoaoAU05Ogq8yXwPzMO53+/38udzbFTG/l0loL5ORQLJnyPjP9/kY/7/f7fBuj6uG3/MRkr9RK5d7f5/3yTmo93/zH+Ij3+U6kbJECx+Syn0kXREU2t4jt/EaOmGLIHMLFsbSbYSvMgZioaYhV0SeVPSRfE1dJhMd3ctA9GcPBHxe3BWhnibgq/Dw7gyIdEUkIOZFGkA8MUiE4X2e///xtieDEEA8z+/nvQLEXoHgsvPUtHt+43OeeG4TIJ7f+BiW+X0LCFHkcO4j7uFssCcq75FbeQ00fqgnirEwlm4jPBmVQEBNQ9cIB0QkXBElENjLQMTyiqASCGiEmGMLTzh7BSKvERmI/S4DMb+TY/Q6f57JgHh+0XXkdSfl/RXBZRkI/nf+/8WA2MsfBp3rqoEYLn9ranmP3MprECCGkCaultuITU21moYBYY+wq7LT5IAIee/7O/NSFIiQp6bALI/oXVSiTk20fwEQu90SiHkCyUDMS4Qe+/Yqn3pMNpSmph0+53xcj+nUtP8uR15sapL3OjVxWTK/kuxDsv47ouU9ciuvgSJ7pBgjou02gsV6qaYRDIh0RYi2BRkXJKtj8F4R3jkdIXo1/81Ld4/fECN+R1iE4Kvwl9IXXkR/Pr3a7wgsqj9k2Z2XVHllQPyYIZiXdizjr3g3L+WyUD/N/zMQfPxJ9vBRWax/ypE9n/Wye9k9/5yP/JSpScpe+/551Y3EfwX9nKpErH785C+tWU1DGUAXzst7W79jO/f38ufW+rv1kv6X2X63LLu/sc667Kc3PxyfU5WIq53NahqtrsQ7gLi0/ToQz68PAMRXb9u9pg2IDYgNiA2IDYgNiA2IDYgNiA2IDYgNiIfQ2/jTIXx9e9c+GMvjD/P534D4xSaXPIS97nVMA82y7pq3R368Pb3swIrQ8y+qmjrXiUjCwICfSFHIv2tobcz3BftULtwsZ1syPHCv+J+z+Waz4woF3HWeb8uPTSDS8WvOwsfqtmlsjIP1AvfbFzyEvR5ZAyLzFPS8+Xb8E1gRZJyICwNTAdGpmMM6EF31LwnVoUvlumZ79Q577tQHYI/0aq6Ehz4iD/P+Xj7eF2yw0/EYSraIAhF9D7yayUJfJFT7ljyE60BQCcSekymSYifjRET6dSC6TwHRrQCRj7WAGNQ+BM9gL6EN2k55PLia6ysiVlG0r4gOLIJnqnkIvH0TBoO944QGeAdpKprPexN+AjMg5iMvnIPiHHDmRJi+RYzmzZISMydzHDEGBr9qcTt42LQEHp6lPh0x7Q7R3hh5WFC3iqAnZxMTemfWR+XxUgBxSD4uyNVzjRwj4j/IOf2oXhPpuLFVcEwGJ/m5ROaRCBXubNwRyn00tRDuo7ALah4CZ5y+S7rwu834c14Jyb18FTyRZl8lN/L0CiB2jhORnuaPH+pKklKVnJgVJoUxMMAiWXI7RPxEeSGWLTduSNLuGG1YYoACB5gb5myi1LIwZDV+83gBjWHSqekEA5yg7BWuUXQ0JP5Bk7isoJCPD4mtgmOSHUx+Luw4g6npQ1RPVO+ElUwQ66BRMZ/AgMg8BAz9vPym/NNeBn0JBJcHELSzKyJzIqJqe3BHoI5B6rSi7iNJ3aMr9Cs8twPzOXM0+nMGIhMbOFt+5OUOV4QqcGBRNmeTblRtjgRE8nhRGoMCMQ9LeUVIHBHxSxKXzKErQ28kid6tEebnEikD0Z/NJcMUS7L6B+3dFZF5CABiT+6KECD81KRXhA77fGRna0TmRETV9pBPFGk6VVkU3oXEA8HlPLcDQETyBB982tgsBEDEkfklMmNPUODABKFXxJyxjnqFpMV6svoLIAKA8GuA6GhI/ALrRNUaMWS2yuQW62kJRPaNidonxwLbf//26qam3X7ngNhhjWDCyH738yemJqFbvfCXJDc1CXfBvjVlTkTiS+jUlL1H5NWg/+apqcHtsAWVSygbUbQ9eLjS1BRtWISbYTTRuZTKEYG/MWA29h4vNRD1tyYlAUn8OKervjVZG94xxvm5AIggQAyeBxOgezJA/YOef+7px4KHACB48bZfE7wAK+/gBXuYpzAv4K9gQHAJ+x2RORG98TZO6s1yKhbrUwzmRgJWSIvbASC0hEpZqVZB1OVzgqUZ2lMmyQhFg078S4xjEgnGadnjBfFE6qj9O0I5JScIjHW2ILvfEZGMrZIX6+znchSXSeaZjMIagb9YP6FPrCEC9Q+6lrzeL0o8XTzna35Zx7X94VKJ7NZCxdfa6/Ve7k3t1lL+so6NY/HehohuAeL+0JevvwaI/Dv2EhDrpeKnerP+63mp26lnjPS3t+1eEz3GtgFBj7FtQNBjbBsQ9BjbBgQ9xrYBQY+xbUDQY2wbEPQY2wYEPdb2GAH92SgeksG0AfGJrfvH7hUWG+wxJv47Uv57uRVnhqzxGsvaLjEsVPThLieTi4yNPg0NauEUQH+hfLy14gsFVoGQ7OB8D3ac79nOaSB+IE7UlhcqJzHnvFw78k9wKf1yYLorQIQGEGGtF9g5lvyKWLVUnV0QBULFjjC/aItCRFGK2qs+uEq9mUi3Gm3dXlgAYaLxpnISoqWGVBC/UDkBEJq/pSUQtAbEtStiAUS8BQhqAEFXgCBq02Z8FJyc7JolW0Bc4oCsd6ENBJnKCRJi5t8SksoJisGiPqryBhgGR8ezkJxv4lYYm0FSH+KxAiCSF4myMmLw7ila24iaj1PyO5nO0zmpYlguGc4jnEjBmeep10j92flRYtPjMN2PzPkgylHgirDamZfRq2NLn84ZNe00Rzoa8Sxpjyyi7UXQvdf6makBIDIDRTVCKOcVGYiDA0JUToL0SMUWJlPeGII++a9JTBjIJG5F/BDPEQaiE48VfNrAYQiaAi3dU4ytoBoBIZjTSmBHCtQHq4Qu8SsAhJwfPoJp0fiz88P1psfRpas6Gx64KKIxNQLOjTG4B/Kl1KguMXplJlrAsBItO8Cg1zY1QSuElIHCT4EPiZ9ylOwc+7dAsMVUTpDoBSUwUsiJ+T7xC8h5noBbwUDoEfb0OX/oFaFDkpxHAETJVgjCnIC7iPikELoGLkevUwL4FbwhS9yfDYjybFJVjywDkQcVGW5uO0dBWj9qN48W+LdYHz7MhGOU9s5WN3LPy2jhKxF02gspn8dRqpOLffJF9+d4hn8LZJf8FTHXECkBYQobk/ELPBCRDAhNfTOPgWogEjtjyO4pia0A5oR8psUnRbtmqhhpsZ48EDFdEeXZanYwYbCGBhBppQp50bfa5YrAMFOqLQFhV2ALiBxtx+wO7bUHYkgjAdUcUzmJlX9LXiPE/yV7nmTOEKYYTE2BMrdCgRgSEOF06kogdGrqT9k9xdgKI5gTA4yP8sUOLoeZzYBfwXM0+7fwEQYCgiv5bHlvU5Mw/mya4SMKROBUvkVhQEC5g9cIx0fC53LujU1rVn+evJbRdvoBSwZAwdYIcVAJ5qCSVE6Sf0sCQr81if+LLDRj4hwIw6ADFyIt1olbEYTNcELDagw2YrEGj8IWawrZPcXYCiNJzafOFjtZHlEf9lBM/ArCxwP8iaO892f3brGW2TczKShxPiaRHdIoZC3T2rkInFj0a4l+4eCUfyc1Wv1ZTWQZ7XHKvYbDi0lVwEFFNUKSyklMNlkAIv+O6D6p2tD4mrj8QvtrvzLjp9/HYu/Fn1irtd1KMqh/At+uGXJN4+TLtn76szcX4sr+24D4fC8/C8Qf3LZ7TQ+ybUBsQGxAbEA8Qp83IDYgNiA2IB6wzxsQGxAbEF8U9CN04F85iBsQv29bmPy2jxfaBnC0piU7ItfSo8Tyzk5ANovvQC5zvfIUW1FXvMjAKLe+EUdrV3RlQ9tZWO4qz/dI53um/5x5f1y5Weg9YLj0GOpxawbUSLRbQqVZsmsBMVIw7xPTmrC/XYAosXS6DngCtJNM30I2IWqrDohLXtld812onm6T6MYcadSMYJJ1KHqIjJc9sRq1XAsIZGw8EJFKIBJ3ZKxiDCuf+LAO2RoQdBUIWrsi7FHXBhBheUV0zUG/BEvdmyUQeYhWgEBWTRQ6OuouAeH2DgsgaAEELYE4gMtwaruceB5CZmpAB0NN7ifJXk+WKsm1wA6E25pL6kO9yp2YOIOXHnMf7ZFBc1uJ4G+IIv5Bz+s06dSlkokfMvVkvBBJa+nt6aNzauGEkci2aypIvV0khy22ISmGGOESg9LIqh0ECOSXhVUy1SVD4nrMUSkQ4HtYT1Af+q4ONEmPRM4LSAcOpctJi4cg/AVla0iQg3A8xMYjpGf4cy0YaF4HwOCwyxyJWKwRSWiBSyW3FWlBXVMGUbCIo1mFHCdS3QtL4WKCy0oGmiPWOMDAENMCvUKR3oQCRqd7cgzMzEDWGcMra8TpyLyOCL7KR0ob55Ki8W9aIyfW39AoB3N60daRhI72iox5EuRPVocwtkaLhyD8BeuGnhNE+YI7Yy4puZZe9DOshl4/XUetWeQhyF8RIBigfa7XPFuYTXEkA8Jy5MYPidIK1DeiagiAtYE48NB5N2YgmLcRVJfDA4GFHvl7jhJro3x4hnxFMBDonS8ZNLvPWiNc+iMAtPzRyK1H/ehmxoucZ0BEKpQwGjyEGDwQwlwjM7YJySUl10JTXuI6KHAIXwE1ZyDSQ+KonyhZebhWk2dLIivoKoBaArQ2CENmczfihRZHXqyj8kEcEENaIyYlUticbhIWaY2QK2JRMiRfFyzWH8r7MM0aG7OAGDGHOJeXmK6IoXI5afAQsluKAjHIgKULjdzfeWoCecWmJuYrBKXbKBCxAAJnxqDnyIdiSC5G+XtJ5oeglVGvnpPxN/LElaYm4YkE09QY0tTEFiM5hjgE63nrW1M5NVnJBASUReh00igHZj0ad0SA4Bh1MjcdEjkvCAdNKY9ZCaPBQxD+gvIWuE1drE/sX9KpS4qvBYsiFmtlS8hCClYHgPC/I7LbCu/jc/ChMAULI0dmIaxA5t7SqSQXBeNvWBxgYETVw6DYIY4JChiyTvFCmWLg/WCy4HcEa3OokRRhsR6td65kUL4LlEXmSSdqlKcojBKMJIE1E7hvxnjRCE/NL4Dxwruv2j7zy/q6dGK89sN09azf9cs6rvxU+MTJ93XqdwJxnf3zOX4Q6Mq/pZu/BsSf2LZ7TRsQV+PZgHiQeDYgHiSeDYgHiWcD4kHi2YB4kHg2IB4kng2IB4nnXzNw/0+H4DGi3YD4I9F6jkQsDwULIF6u4nN3UEK4omCx5q+tTI9QMSiuxBcbJWN7HFr9ideA6JsjapuPlNasLbLqRCxLNYDoijN9uVIL4nqinxbUAUcSsIxA23E+dtpgcKHGFUZHVwERVoDoimFaxD+WjtutdjzJYaEyE8ItQNDNQKx/4sKVdq4DUVUwxpSFM8+IQsGi8DMJN18RtwFBF4Gg5jjSJSAuy4ecjYdBNTfhoJLnAOIwJQaDd0ZRRQokOeBfcphKHQvUBAaH6WAkqfbEn0j1oZQpWDggDvZI/ggtEPixBEJkytvwsVW1Qd3jMHmmCXqrGhtTR4WIPOo6GWukk4c0F3WfwNNAvMYo6fQRY/QNTA08TmxsDzyebNomJE/4R0xNNYthCPZwNwt+DClNqDyJxKAYkkOKPsAtGhpeHWNIDA55fjomO4PB8SdSon0QhxMoWHCGDLk9UwuBggXzKuDHAm+SD+WPuEx3qg2cE1P3GAqmCXr7EYw54m0VuiQHMJiIUshWDEmlI4KnAWqDMUo66IaoMkNQxaZAju0xkLY8hAqImpuABsGJQABgMHR4IPzcM6VSzjCHFBC3oL7hRRmQPtRaI7/qheXh+RNHq8+B3UHxSobIDc5ooizIXAfy8g39am0fwSI1pgmYFqwpAkZKR97xBXXZiMj783xFVHUDiOiAsLKqdJIYHpKWPie2R+jP3HJSRvBAlNwEYzB4ICLmv0lm6Yl9TESRgrJyh/E0SiAigcFB4k8SuYYpep7fhH3l0AmPIgNRrBFrQIi2RrM28zRx6iK4VvlIVuFIji+oC4obMgqjPMhf1d2PmbDQJUaJuhhRBoL/DhTJsT3QcgWEXZaOmxDT1OSASN1K/iCUHVJCMDIMvy6VLsDgEJqJm5pqDocbuuHatya06oAIsTE15dpU3aNgmhwm61cw3Zh6akqsEWaulFOTHTeOiQKhLYbUezA8grSb2B7sphIcEGMADwMLrecmQAvDFuvMYMAihMUmeYkIz6PTRakX1YysjmFUyIDF8JQXa8efmMrfC1CwWP8dIbohJwAB0atO2R5rtUHdIwbPNImJmQHmiF+sc12q5xGZfVLXjddRR8YYJUfohuhXIDA8gip9qLMMu6lMY2ioKV7a1r+2XasmXil/z2/Vr9ewiNdLhMvRJuZI+Fz9d27rw3Uvc+Kau+ef3eKd8S6jzWyrPxLwdq/pQaLdgNiA2IDYgNiA2IDYgNiA2IDYgNiAeISu/fui/f1B3NPCvdGU5S+d/bl+/kGINiD+2OjY/Vj+O6a9fd1UW2miUdWSy1AwGaLdA+VUjD1Nl9uNqYajO8v2vr/LY+WLNsSgYOoW0bDTNiW/evTlXRzrn7XQM5y731CSXb5Xt10LiL3WXVkez2V3+7Xz9659yuINnQLRVUIO3Y1A1KyJpYdJQWQY0/OnkqXoGkCYYHpOx9teANEt/FSQSepbQOwxAIzH+zsPzpMcfNJCT/Lqxx5APBXj9rQykPmIA+KlDcRuBYindSBqRY3PXhFLD5PilHGw1ArlbN0aEHQRiBwpajy0gHihvQ3eFSD2tH+6dAHslkd+EYiD06aYJ4ARQPTCc8DRzE1ISRFT5jhZiTZrgpKHSZ9qC2QcDtGmKIBA/lo5DWTOKOLfEg5J0cL2MhD9BCCYMcJ8COTDTETFosIjwu/vc4dfnl/3+3nSeXl///HGQ/D8+vzKA4F/ExAv9PJE3+Z9/P/z64/XZ373kwjvn3/ud3zONzmCUu/vOPbtFbW+zX/kyE9uCWXL83n7Ju1+e9WkoWQP+W8B4kOmJihhmNMJZ7dSmtCUOQZyuhtL1kQyCtC93NZxKkwSTshxzfm20RQxwGmAN0lURY7jFJKihe19f/+QXLZNTR8hM54Ok7dTwEPz8zUwD/R+t+cx2NsVMb+XSWgvk5FAsmfI+M/3+Rj/v9/t8G4+Y7fjkvvvUsl8FHVyqff373xkfo1a/zf/IT7yXT75UrY8/8cMzXdpfz4za1MI/ckBkQUKjJsABoMxNrK+wBprInuYGHfiqI4o8DExxQMK/orImS590DyQ803JexkI5l1kIIwzQWqoJDwRhYMtDJ7mGUGBSFdEAmJepAHEE4NEGODn+f8fb3syCHlO+fH2/MZnERlE/O8zT0275zc+44lnNgHCSvKCvAcQ7nwA9OONa6CsTRHSGtECgrkJYDBEl563EiscjORhkrgTBEeUCK6FLtYGhK4RDohIuCJKILCXgYjlFZHWk5KPAQ8UnnD2CkReIzIQ+10GYn4nx4g/sWRAPL/wQEod8jnPVwSXZCD43/n/FwNCSu4Ycq4JQOTzAcSe9IowbYogTA7uAPukhLAAopia4CxCzm+kZk0YvUSFgZJiRZ6aVr41CfNBgQi6RhgQIe99fz+dmHchQIQ8NYWYKTeZLSJEmP0LgNjtlkDMQ5OBmJcIPfbtVT73mG4wkDyxfOf1go/qEZ2aeMoRIHRqkvc6NXHZ8nwFYoc1gkybgjkGAaYu7FA1qczIlLkJxWJ9Aoci627UrImesocJ9kKxwjgcq78jQp+uCOFHkJLWTBtE984fi8i8C5Gkmv/mpVvAH/vRyJ8q1xWwWNPuhZfRn0+v9jsCyyovorz/h7wyIH7MEMxLO5bxV7zjgeSS8zDKYj1/mnm5lmOyWP/k17Tnc152LztelDHkKFueDyC4/f3yW+clBvd9vx3jjeU8M+N2K4y2W0p3oQ+f+2Xth2i/q1/v7xidcrD3u/VjV7e/c4sj3gHE7XV/Bojn1/r154F4fl0/9qBAfFU0202/DYgNiA2IDYgNiA2IDYgNiA2IDYg/ODobEA8yOiuN/Q1iyX9HQ+YXe7IB8dt64vgFmlvdNW98zOmLlx2YELLx/UvvfJK3SNccUGL7XViwPqLVE3G40WZZV6/1RD1m9VUqGI0zLYKbN1e2Zr1c28BBqVpbA8LzFkB92O2fwIQg40HEuA7EUhMjMw7WgahYH2N0viogDHi3lWVdXQVEKheWNIZYn7cKRI7JsSac5EXNelnf8t1hA6K7DgSVQOw5gSFpdTIexPrjexiCrvkRugwEXQOikrO4EYj0b9cEgi4CQVeBoBuBoAUQVI4TpzHANkhT0eszvQnjgFkP85EXzjxx3jfzIIyPcS78TaB3IQ4oY9LzcFyOpW9L5oSUrI+OtB7R8YAkSXZbKd1bDkkE3rgl3oeFeU5QGOGYLM7ak4VLnqf86DGiNP6Ie7B5gqw9J9AAhLFeZOJJzjDiOxAtQmlXNDs0yZbcVrrMXNnP2STLotpV8ESac5UcxtMrgNg5HsQRz+TrY/BQ4BC+RhiCpSslTRqNyxEK35aovi2UOCEl66NTbQ12VIHwAwNhbiux0tRIqdqh5cPS6cPmyvMImVeSPVn4zA8zOwjQ1BiC8UeyZ4zaNYSYJAOM9VI6w0j9cdC8PDLpg47G3JPBesIcFQNCBn0JxI83A4J2dkVkHgQzOyKZQgcUOCI8UEL2NTmK50qfdCiyb4twOshzQkrWR5ee6T/yAmdAqNtKT969xQbUfEpKH5ZAcH1Bfy3O2pMFMhHgo/RndWkJRlvInjG9OVcUQOTnrc0ZRspHRNpLlJ0anzAjJvfEiTQBCD816RWhwz4f2dkakXkQmvRXhY6g1jLpM5Zm8X40LocBwceGEAtfEQMisz5oNCDiSJOtEcltZfLuLemKaPqwAAiC80WKs/ZkUb0O6ITM5yHKxB+ZDAhzZLkEROp9RKQ4D/F0kl/MPVEgmCSy3/38ianpSfcwOyFNTcLhsW9NmQdhfIyP7G8C15XBTU1Kf8E0FKjwbYFqR8ickJL1wZRMnZoiiDPcZkgOLUtNjTw1lT4sQb2EgimDDC1PFj81sUkOogwpJkrclqD149tYZr0kIIJ9ADBG5rXSpdGQqSn5xgAIWaz3e2UbvGAPsxPmBfwVrAcuYb8jMg8CSkqm0BFUZYM5E1jcEIqxO0yHwvm2wD4tZE5IyfqgqPWoj0vPTMDktlK6t8TUji7WhQ8Lc0C4rU61MXC09mSBuFZeqhGl8UeyZwxYL9AbKVkvWKzhDIOpDD40qr6hmh0cFS/W2TcmYFry2xNdSmXf98s6qQR+kUpFd0kRZPWsNVvLa1u86WfaOuslXqz3r9ziaKtU3D4kt7QZ72z91qgjffVmaj9/AYiv27abfhsQGxBfGP4GxIOEvwHxIOFvQDxI+BsQDxL+BsSDhL8B8SDh/zeB+Pp68t5fo9XcTpz5/4rjBsR927qvyFqeutqgwyF3Nf85m1ay8C8ClIzf31kxozGA6fg/c8Km3sobbHo88JN9i3qKd8dKtjc24jXGR/dPPzW0iZHon/LZcaXrMdT1NtoMq9nxbu1dsD1hFYiwAkS2s9e0Dw99hLb3+3uIyzrmAUzHuwUTJDSAMCOB8qgCEdOHh2qrkq4BhO5zj+O73mniM5ME4sqItYEIDSACXeXvtHxFlkB0dwDB2TgBYuz0eeq4MBeRm9zpeLf4zIXVKyIWvird4oqIVZyxeUUkIJLrxQIIWgPi2hWxACIugPAsBktqmHH9IZnB98pfgFS7pk1GlDlO2fxeWRGnnP3q1AsFQHTq/6BsjFOMZ1UB4fp4+O04MxuSO8opt1OxP4hl07ku829BPdI15WowEHMrIjV0Np4JHTzz5GS8EwPiIJnpg6WadBx42DIHxWKHuwtk4vHwsUWIFBUedy7boxE1Hycbd/IsBsrvHLNizgdGy8nikXfS1CXYE+qNEB2TY0hmGZNOTSfQYYI6ooCNwZYecBQJeh3k411yR0Fr1k7J/uAH67muIfm3oB55+jpCh4Ozeh+aF/5Q/gZYIPBi4XiNd8JN8IcK3i1wltES0puCgxI/hK9iFgoAgikIFmHWKrGzrD3Nguvj/9Ivz2KwtDoYGMasmI+OnSogyRWRGA5gT8jnZC7jmBw5H6zXAHe1vCKgysGd4dCtdn9FJHeUMxgWIvdPJftDs78h24b0bo0At4OviAwE+Budsj8sXsc7ieTcI/pUwlwgMgeFY9cjwsv4MMsSlZkxPol3cLHawCjpVZlEJjDPYpB3gyS3yaltEIAgnZoyw4GEPQENpU72BGfrUQARAIRfI4J4q3yEmDgS1RoRzLmlH7WMvPfsDwNiyP4tk1uspyUQ4G9kUkH08hWUgDA9kclKeCB0dKKZcAThZdRAJD7JkM9K7SX9E1YmARCOxSCdPiVXkqS2IVNTsAE0hgOmpsME5xSdmsCQGMCu80DU35o0VO2M1V58a8pxUPZ4KdkfNjVZFDE4sxz9/pOAAFlm8JohFq/xTogKEaM0xeg4kOeNSOxDAiIwl6MAQqcmGYtQtjcqEySENDV5FoMsGsFsu4xZATZEp8tgZjhgsY7MbBhtsVYmx4nUaUSmuebvCLki5rJwFLHa3e8MSu4oJ3yz73Sx9uwPpj5yTJG67O2iizUIoQzE8TxKD+Aeg/6U8RrvhB2D+qQnAmcZ7RFVHJQgsZ8A2RG00BGLtXJOdLEm5+Bi7Y3KBOmU2NnIq1/6wZa/GObv2ZFaTIZrP/vMV6hde/2T7DIPo5Sfy/XE2Krrd27d9S+0t2+XOQ/WqVwqfqIWSr5C7drrwSvLXQMi1T626vrz229xWtnuNT3ItgGxAbEBsQGxAbEBsQGxAbEBsQGxAbEB8bsG+u9F+x+5GjYgHmGDx0Is9TDi1XPWt76qhW/D36rREW6L9ioQ3ouliutqE/2lUYjLl3J/mJNlaa9pgMSr/V12bSz1MFIjboBCY7xqX5PyHNQipjMLj5WlKEMo9ob2Xc2AjF7ZXlgSB8IyIq+8scpfoTXFD+WDjOWAIlehOci8N6wPeUjnrQJBDSDoChDUqLTuCCcLu2bJFhAXWCI52sXOy0DQAojl8F8DgtaBoAUQdDMQrKRxdq4jXdLDkNagfMEltLTnHlASXE96FeqoYr4nKGUcBlwRVjtzOHBmVq4AF0JSNKOpZuRaEYmPllkcxpkQv4jJbrAjbskoRpxbamEQlVoY62wWi/8wZUaL9KPQAQGxAA4vpgSCPab5cZgOWedjslpNTF50A8BGgLR/l/QwAISwD8JHMK8fzz3QdKokFDvKTArBO7NBMochGqsj4NyIM025gktxLk2YE7gyEy1g0ER8HS20LoImN4MyOEwPg99xCVpoYXD7XgvjAptF40cEYLRQ4oxYW6DawOHFlECQ5QsB2iBBY4opbSp7CdogCgSYFz0ZEKZagYxyfzYgSu4BGBW9s9nIgwqCTFKkCEZ7zLXzZ5X5GJ36q9hAq9CCXPrMuci1xka0yDEHnfZCyv1BD+P9/aBDW2th4EOVtTDW2SwWv2e0WEY764AAazi8mBKIOWZAGyToaJmfTNC9kvw9a9ec68hoehgZiJiuiJJ7AAsO9i0JlK8ID0S02TDkRd9qlysCw0yptgSEXYEtIHK0HTNBlDOxBEJy42NKzxdaGKoxk7Qw1tksFn/BaFETEjk+ZSAcxZT1QxwQSieAzkfS9dCjwuVC14bkOjKaHgbP0acTWBsMBFLjmXsg721qkpnRphlVoQhJkiTJ5mS1DawRjo80ItzTyaY1qz9PXjY15Wg7pacEzaKH4IAAgyMqEJUWhkxNTgtjjc2S4495akpuMHkaU17sgKkJSh0FEEPwDi+mIzIEo9zw8gg2grqOxKSHQSCXgGtxVBWLzD3o3WItehWZSYHLFHRFyhwGLHyonYvw2YGU1EjKgIhQvADljEt0yacFuh8+2mPW6ZDlr0uLNaihQoiDs1elhcF7vBbGGpslx48IovJBwAh0CzsWa3F4ORRaHzo1nWQqcou11HoCNwVmccXXveWXyfvfxwul6m+B6+UunOmijWG9ByvGIDexKmK4NYrfsv3KLYG7Q/4czaSK9tqzEcuzbmNV/BbuxZ8B4jGi3W76bUBsQGxAbEBsQGxAbEBsQGxAbEBsQPy/A+JXQr7l3H/TkNwf6zV60G9tfAPiNwERi/frbIv6iM8TuzrkfiXr6R/PrKtRZ49zSe92wqVHZ9LQPKF1tIorrpSNlwchfGoAQ6ieWopkrimeQxJzjPFCBLVQwjKh3qV/Sx5GtwACWVTT9I6asGkBYdyHDESkEojU1ljFEZbxZb5H2ZcWEF2jZyb0kPsTLvp7W6GuAUS2HbEexNzS+EtAlGFfBWJEymbQR3wvAOH2DgsgiJasiXUg6GYgVoZhAcQtV8RlIOg2IA7KJZizu5oawS3gLmlxwBVE9Ssq1xPhKIwpGRMPiZmgubN4ECCgvmHeK2XJkDgac1sKBNo2lgXqg7oFZ8sPSR3DzjuLe4olr3zth+SNgt6mGIzXIW1oW5o84geGbTRKXgp4J8ZA6ZOyBo9AckVRBouogIRD6oHtxdj2zmeFVT3mzyA4CO/vQ7AcKoXEUojCcIiD6VfE0vVEUoSjMSdQLiXSsUacjszHiPy0sxkclCWN6SA8ixPrZqhDygBlDWgbdJpajNFekTFG8CB7xNRUxzHgLCHp4N1H1hUgStyNQevEjK+8kIKXMuhUG/BYfExpzwEjgFI8EhY37w2pB7aXsgSAcktE1cNyztAUAL+iP6fCMXsgmDuJdz0RjxS7IrQcfFM6dDIiCY8rwrxXypKW1+VWufRHgLRIprQoENgbOyp1Lvi8DERdO2oxDkmOwXQ+enA7ovE0mFfB0zRUMzwdQkpErTXyKzAyoB3iM39cUsUpEr8l70XbxzP0ThDvAgjlVyTUvBmFpdK96wkaMlke/ZTYnG6fmLRGmPdKWTIn2LFYfyhfw7Rm9CodA7gVsSt8WMh8UBIQZe0WgwdCZ+uJ4MsyKRck+QdhAGNFEJIaR9TKKiJRGRkmOuGBiIQrogQCe2VspqhMEsSbgVCNF73whnRFUHVFUOl6glATcyIOqY7Wt6ZyanLcByWcIVjmceCSZ9UN43wIEEwEUMkiLa3RKhCqD+Jrj2lqckCkqSkpcyQpF+ZVmO0Mvy45JszxUAKMm5oMCHvEHnVCKSok1ortJc8AGYqpqRf2AzgGwio4UVLQMFeQrF/hXU+YoxCSjgAvecZoIKkNvyPMU8e8V8qSxnToT3b5KzPiFJV3AdZEALfidEw6F+bGAo2No/A96trBQrHFOsfgdT6SigfXeepksUYbnpdiJMxAJuZli3UwICi3wqwWneK0B7aXhAGii/WJVJEkfXtq/4ipGQ9tBsTv+mUdV75gfv1W9msZa7wyLjonVOc0OSSfG6iay9DmNvz7gSj7dT3Wy9yR3wDEbdt2r2m76bcBsQGxAbEBsQGxAbEBsQGxAfHXtg2IDYivCul2MsvvBv5PgPQH49iA+GtAREJm1W5eS+JywdyQR9enpR0G+13Pf2Tba6Dv4hv/rIWe4Z/9hpI/XlcD2fk3z9Vg7LWFyvF5Pme3v7WWve5xZ+j5u6aP9I83c/TO/XN3TZvck74xvDGN8+rWUSiA6LSpbqG0wYmJUDcDIPYIlPF4f+cuPcnBJy30JK9+7AHEUzFmT4shfNIXT/rqqQbipQ3E7mItGYinC0D4eNAl87jP/VsDwpgbi5Eb20YgDZuaS0AYXJpNo0MLiBdK3bgCxJ72T2sf3mosn4pd9wLRruU6EFUw+/3uCT1M/ZuG9SsiS7u4YV4HAsoWPLCjqEwYFwGZJAYC+hKSSoEjyWhASIZ4Smoc8sDt3LWX59f9fp50Xt7ff7xxZ59fn1+5y/g3AfFCL0/0bd7H/z+//nh95nc/uRz/K3vnPTx9PfGUlkq8v+OMb6+o+23+g3O4PX7F56zXgh5+k2i+6bvn15cdzk9T0Xzem7TDvZmPvOx33Cdu0/p3OlnPjVVSc0+U8ZIYMN5bJWt5zGU/RCUCQHTQh5BBR271/f0jQF8CF9hHMLsCEjGR/Gi5qWPwJ2W/mz888yfIroj5vUxCe5mMBJI9d4j/fJ+P8f/73Q7veOLnPd+/y1nfdzap5BLv79/nmrgU6v7f/IfkHPng7nDOei08yD9e7YheH7sXPd9Plf+TyKQ39PQKIHaufx9BnWESq6Tmnpg0hjFgsiOLjbu6xXyoSgSp2UXO7hoQ0JcwIMCHQFXgTBzPZobB6hhPlAJNV0QCYl6kAcQTg0QA7Xn+/8fbngxCXhb3GICdDdyTfJqtxDw17Z7f+Lwnnt8EiGc5B0uyDvZqLTb08/JL+7T0/m+33y2BkFpwYGdXRO7fB9xdoil1LLknYLxkBkx2ZOFxNy0P8B84UT60gOA14kMNm9IVkY6qXobwEZyWx8teA81rRAZiv8tAzO/kGPFnkwyI5xeUw3Xih5BerQQDwefxwBgQGHKZWl71ilitxYDYk7siBAg/NekVob2Zj+xsjcj9G4UrAseXFvfEGC/GgAEFIlJS55ARHMxjJEgSmx1BQqiBOJ2gL0HCkbCpKcQueapkNoNoeexfEPputwRivvgzEPMSoce+vcrUhIkG5eaSvFeGcJcmFS3BU9P+u4DxYlOTvNep6dsrn7NeSwJihzVCwN/9/InzZep84S9JbmqS+uxbU+7fmExsjFVSck+M8WIMmBkI5W8Mqs5hrjTCf4CNG7P6uskDISSYCH0JEqWNMWCx7sZ+zKJP8CBRLY/dCy+gP+cZVX9HYEHF8jkvh1g2FYgf8zDNSx+W8Ve843Lzvz/3srDOg/WKOT2XkMX6J5eiPZ/5suOFls/Bsjt/0i/WYkDIEcKvCV6A9fwX7OHW5npf0RsuYb8jcv9G807JRnEF98QYL8aAodhlo7hTMMplZsSv6VO0fjsWungXy9/6y9r/fsrz9H7lzP3u2i/a/crrtbJlmaeLZ7V+WccrqiKXx7g4Y0154s/c4vDdfn69NoR8RXwtEJ/t4dJf5hIQ6+oe8b5mfx8Q927bTb8NiA2Irzp3A+IXa/6qczcgfrHmrzp3A+IXa/6qczcgfrHmrzp3A+IXa/6qczcgfrHmrzr3XwrEf8Oh5z/hMrQB8We3sLaTn4+u98fG6+5KXflYbNbj98Tmqd2NUZf7YwVEx0/1jYtWki20ESIuKHuULcS1rva3xdqqOFME8h3WWiylDURYANG1224AkUkJZm0Rm84m3Y1RU5JyMDLE+7sjW8T09HgVc9lKdxWIhpxDLPvTXYh1hX/TkK34RSDobiDIAXHvFREa+9tAIIO2aOUTQNASiOqDdTnWBRBL7gHrXYi3yQggoEARlfNx9v4iTvUiuYu4urJzCZc083mVO3fneg7JUV1WctKpd6obHNdhakUN1QuvqWGuJRBzBz9lzocFCEJYK1mtwzRI5DFnykyLgz6Mm71cpAWnq6E3uUWr46jRdQTVkJVYMdIhj12DewDPEQPiOEKBQp/wDx+mwVFpasSGhobsi5IeTGoXQ0OPw3NIgtASsiEAEo9DsBZGfV1HDbUQr6lhXih8RZiixnz0FItWslpHVlwgSQObV8ug6c2Ss+F1NfSDHWHEAJcVNTBYidX7SujZS+4BPEc+3BVxTEwP3m86F6XqRd+oC9YHkjBPaheqoFGc66kLcJ4QpQw6mlaGnkNkygGNqIO5nJimhnmhAAhkyOajQ9lKVusQiwLJLjNzBY/fIyMND5SSs5F1NUwRhLuU3GLU0oPrbcWa9TlMh6TBPQjiOQIXFXl6XhQoVGoBLiuY2Ur1jalRF192YC7wFWGf82Fx7gIIwqVO0MrQYZwyEMuoh5C8TFRTw7xQqisilK04tY7JgIh2RZBpjvCxj4Kzofo2rKthji0s0DGVQMTmCCcgBlMMoRb3QIAIzOroDIgApoebmmiperGsC0MGIHgvpiaIPeRz4d1iHJJsE+U/RzG1cDq1WgLhLQn3wMpJvVBmIIIoJ42UNXfKVqqpiZkrWM2yD0qiHpFNTTE5q0BVQ6emUADRjNXGjMU1TP2kwT3ooMTB6hesRHRWBQrQMidYopkiRVa9SO4iri7sg65FJFusKZTnYgIzDkknriV+sc6OKljkzdukjDpCq8lpapgXyvu7KIekiYh/R+RWslqHaXTwe1lKNXaolKD3mbMBLxboaqiSSIQDjDmvHL3nShmrUywx9ZP1r2hUycTdLL9Q1rX0JlkofNBnt3hTLaaUEX+hdqLr4xDjvbU16ooXO4GvuZ/rQFKGoftr+logfqV2uiF6kwm6vbY7RmK717R1YuvDBsTWia0PGxBbJ7Y+bEBsndj6sAGxdWHrwQbEv2ELa+85JVP6IpTb9f2f4zFYLWuGKnK3cuVYvAmISOt91vehUdrt6y72KGo9Uf+K9wARisqDcBC6FSBCEWBHPlHu2REtHkMdf7fSm5rJEdOZQe7015SDupTF5IkDrVL2Mvh4LwDRLcZqsTfFLmeO4QoQxuwIrVGysG4Boj4WiyauAUH3A1HBFy7wQi4D0VVA0A1AUBOI8s19QOi58AY5qHdIZkD0CgQ4DBA2l4sXyhGE9JD4k1D2JzF2BHgWUKLIPAY4n/jHgiUvPXl2xsE5taQJo3Zg0dQVOBLHpGnhSxkTBQwOjaAqZbetOZ0jCSFTFzlZoqhPfJWah5El3vvJXFOMbSK5QmmlVt/oM59lSvwRME7YkYHTdSElCUnVI8z1gROaYzBPElWOoBH8oIDMtvmTGDsCTied2nnw6yGYvUDO2iI1GQp2RmZOAIilV8tx6vQsTa02eSHGREG+OvOZfKnO6h/kHFVYIE6cWuo0xBXOSDY9wAPtg3Nfkez5vHsIXn3DjB6U1RLEqyYgTg2MmQRBfT7AlshA9Oq5kKmI6OgH1DfOBgT8SSwpD16DKFGccSRlfZXnYJ4ineo+ZW8JY064K6JyYOnUXwVnmrpF5aSiTJQMRKuUTiXyzjRHECs4Kf0ZRIElD6PX83rKZh05R90pd8Wrb4hHi4w398/2cJw9HG7A0ZDPxxTV48Mt1hOAIJ2aVDlCgYjpilB/EgeEpc8zUwJAgOdgniIy208ZiMyccGtE5cCiV4SeaeoWVSllongglqUMiKhxZ1GLxElZUdnQXkk/oD7TBiKrb8haMRkQtqcfodbBbAfhaJh3iE5NoXOGNMacQNCiHEGnE0r7qYnPdewI0fDQi3yIfmoKxdQUPDsjMyfyd67agaXTs5R+E2LLp0WZKGBw5PZq9ojUP8g0p5ojMjENRvxZ52G4qUk8wUJim+jUpDY2wRF4dGoit8ccV/oTOBrwDrHFmt8d1QiMGQe8xKaFU77J84DCCwTURmMygB0BpxNRosCyd4rBnE+M59DrUttNnp2RmRMh5YBrBxaut5tQzpgadSljooDBoUyKackescW6m0xzRJZqW6xPxh+peRh+sRZuH3WJbSIL9ylAfCypbwTKDizoO/49qo/Nxe1TVhS/tMXqG/avbpd+WcdfiO2rRuVGbszfBeIrtq+8xfE7gLiRx7Hda9q6sfVgA2LrxtaDDYitG1sPNiC2bmw92ID4z3Xjazu4rO12eZV/39htQPw7gFj6pqxVBo2OG25XrbiL4J7jP2fzkT6OfJf3MhC1IkhstGXsie6fXu+DLqPBfc7YrsPqDnW9jTbDNc2RuQexvxxze+sadzvTcETUXmh0hIvjnrtOpbuI3Zm3py45F4favJCEthztXaSSMhAb1IS0L+Zsh4sLtAgn/xCr/l8GIjSACLSuJzP3YCwtUGLV0srZF4EoBroGorsIBFHtLuKB4IxcBiLXWF8RsWohNq+IBER6rnoBBK0Bce2KWAARbwGCGkBQC4iDPq4N3xRR4EjqFPxgLBgPZI/ZkvEreOh6KzdmdkdOwKy5i5RAHBIQmQfBNSoQypJgIJgvwmefHXPCsSNOqn8xGRCHQKqG4VNeoB/YmTGelaeR9EcIo5E0OJJ6SMXGONGImo+aNgOn5ezcZTrX55r3olyZdDblRCIGhjNu7PaBzO77+wCuRLSUoPErkERFOWR6jd0QYlt/wtxFNN0/6dTEubARbBGrn89hGgyTTJArZkUQaBOQeMBA62JIXAhmXlAwdQ1+9plrJlXDCKQlpF1yriYxcm3C0zD9EQJVwNgkWT3EszFIEqvgfgTS3KJk8FEfLBw61+ea90LV2YnMcjzjpA9cH2fmdvQy3FKC9ScopcftiiCUw1KsZJdzN7b1J8xdJOdqOzzDr2tE5kH0bo0Ai4SviAwEuBWdZ0ecJebQCTuCeQVZHaBPJbwwBFxNGAg9YvojlBUPAnn1kFC1F6Q34kcji3IkAGEsEAOiTyIXnvdC1dmqscGaEBkIRo4VJ9ghRTVm+GJPQKQ1YtJyMonoFcEaYXTJXaQCIhgQjgcxucV6WgJhahmZHeFApwSE6WVMVqJU6DAgdJiV9VEC4dVDQt2e9EZKReN8fARjt4i7zJj7XPNeqDqboLHByX0MzAlz4hD1k3iYFIiQnEGC43cMMTmrGI8hxDbvwdxFaiDsW1PmQWBq8t9/EhDqAeMVOgLYFgNPhMofcd+aYppijDpX8j4+VIcj648UQDj1kIKNMdc2guI2QDgoT01grIi7zGh9htpI5r1AFSSfPb+372D9BPcPljGIiZ8gkigEFge4Hcav4G/+tqRjsWYeA/usrOlPHBNfQb7lG88i/Y7IPIi8WKNd7tTxzKsXnw0mCLgiiQshzIsk1TXa74ij8TWkhC3WxqvgCLk2QIbeY4gQRSjUQ7qqvZHA/eimTNAcA+pTd5lofYbaSOa9COnOnd3bl7WlJwj22NfGWmWiK9xEMuW2/gK89gWx9TU5NuqPMR//M1t3/QvtHX1aG4fm+ySEVuzGHgNiqTKxdBOJrQ58Egir39r927c4PqMest1repBtA2IDYgNiA2IDYgNiA2ID4uuHZgNiA2IDYgPi4cO9pQtf1c1rH4H/NyBtQOTt4g2tzEOIKBypwfagqtQNFWuBy0C42uSO6HHk5Mw/57jwtYjNCK7HqW05NY45oTN6jkZsdOcOLY5mVOmWaRuIUlGiaDKlzucgqVv4pXSLBgOVCh3dKhB1e2EBBLI1eCITmQyxPFcVEE8HqM5ZpzWkUhmILHsR4joQ92pxhGL0bgSiFXINBB5SX/84lECsD8T6FbECxJhyfvbgsav7sh7H7UCQprwuXxH3aHHcAcSaogT4CsqLSBwGXBHGTTAlD9PcwDlj0Ad+R6SMHP+jwXXo1XPlkLQ59BZ4oa3RIUEZDwKE5PTmssbsuKzHkR4/bpTStpwah2TjNY3061ocx0IvxHRNrIc2WuCerChK+IfXHYchGv9C/Q9iTqFyOSh3HJFgHVXbwtXa4jrgEfSQtDnA4Ci1NfDs9bxGnI5ca8TUZHnsy3ocmSKxLKVtOTUOSQJrYvXXtTjMEyMzQEZJ/aKHNlpkrh4tRQmTcwBLwzgMRJ6PYUoeHcFzxAZaAxgFd8//aHIdYjTOhF8jStUMyKvMe4Z8RXggLulxZCCWpTQT6NQ4OC0b1bXl17U48t9HVSr5CH3uoY4WHFVWFCWSrobNciFSBkKdQ/iKQCDwQCmAMP5OC4jMdeBUunEmisW6VM0YydRd0hpRAhEX52RmxroehwGR1ThM9uJrtDjy35EMCJpSD4MRmGhNUYJndxM4kdfB4PF8DF4jHB9pRGdPJ5vWZM/gJ68l10Fn/5DUXEIaHKet0f7WZMyOy3ocnkZXl9K2nBqHn5p+XYsjBK8XElRzJPVQRwuOKk1FiV7nZSxhmcOAhTvpRwhfIZgPCSkDInJ5YUGQKV1kV5Sa62DMjUCmzWFLmdfWICF44ncEQ8cTyHEyZsdlPQ5E09bjyIu1qXEUi/Uva3GgZc8A4a836euIjpZzVKm/Tq3/GFn/XhhXv8yub0IbCNT8cnftvK/Y7vllfak313t6V/T3VUd3KleuhXT52YhPduXfDcSf37Z7TRsQGxAbEBsQGxAbEH+6jQ2IT/Z6A+I31fwnot+A+A293oD4TTV/IvrHweezsDz6R+v3n7oB8VXx9spbqNka1WYPycfl7vIFVfXEek/KBsd0JvQxemo/7nQpuths8/Pt000OKH31b3lGzQu5cTPeQncbEKO9zaocudmS24EUejkQXXMggp4dVoBYj+4yEPe3TzcZb3TVv6UyyCUgQvN1yEB4bfrbgKAGEERLtYx4wyfS+BNrQKxHdxmI+9v/PBC3XRE3AeG8T5RZoAwN5VuIBLsqURyhhHFiYGqGA25qi/IEOQ7EJBwGSKAr1wFS7irKzvllTZiMooVhrbej82W8D0v/S+1nBxSkg+w8c0NB7Z3yOxiIUhnkII8ii2fKydr20amXzMleExnjxAFhSUEwC5BQxLshmO1Ap0k/ZGnn3NK4ZDhE/WDh8XN4q4ScQhRLAPNOQbqRWQw8EMapGMHpGMHsaEfny3gfFkvofq797IASi/OSG0qAiggUExiIUhlE440YMaWfcMpUowMVAOOKK8IYJ2S8hU44BQWzQHhBnJoE48HILsxc0Cy1AFEzHLCEfaggA7xVwNCwAfUKF8afMCDs3PkM9UxpR+fLeB8WY5N8rv3sgFKeh+Q/1y1pY3nHnI9aGYTLMRCZSdKfoW0CXQ/sYeaLSaXEEgiZhaH5lZgFzHVghQ1Tnkj+IOq4wmQBLIcVw2GqB8IYGjYQXuHC+BNLIOIIz5R2dEUZ58MSf6l9Sg4oJhgRpXbdx3VPBkTUK8Irg7CyiQERyfhPQ9L1wJ5+jHQBCMdXALNALqHDpJobEraGaayMbAXjGA4xKU+kOoeQzG4wNSC8/qT8CaHlZP4Gnwv5HP2ENaLzZbwPS/yl9ik5oOAYzoMeif2hZIulQDhlEFY2USAGo+BB28TGDQI02dElsVSMt3A0O7LMLACHQRkMWKw5LlPlAPNiyXDok/JEYm6cwNCQPSdjRkDhQhfLEzMojFPBS3AgY3a0o/NlvA9L/0vtU3ZA8edlNxQlUEKHBDZwXhmEv4K9vxtDRUbnBG0TRCf8jxOUQrrEekl+Kp91HYnh0hfH69tS4eKzv6zjzTFfbv96367XuYw3rtQd7+nqpSA8++KeYFvnfyUQn2//1/tmnKVL0a22u91r+t19+P2nbkBsQGxAbEBsQGxAbEBsQGxAbEBsQDxmdA8ymu0Gvq7Ze2u6XTbl8zE+5IdgA+LPbGGhsVE9V19qs/Ir8C6Q8iv30k03aLgIMhrIRUiCdqH0IY/YT0vbjjme3fxHtr0O2fsb//2shZ7l1fMbSv54XQljdwmIvdZP+/qcnduzr87baxSujJ6x27fa+fFG3uaiawCR/VCWQGRDDytleynRDNa2jkIBRKdAdAtFEM71hMaHZI5nj0FkPN7fuYtPcvBJCz3Jqx97APFUjGMuY3U8OUR2+rcD4qUNxK4A4skB8XQBiNx+av4aEHQTEHQ3EHQFCINLH6SlQwuIF0rdugLEnvZPaxdBGolfB4JuBqJqfq8P8IJ10Dm1igUzY2QgoNHBG3Q6xOskHJJChe3NTAeTvGbvkrPyHCSdImwJq4tES2BUXxdJvYAfMRoQvNdSM6biMXf15fl1v58nnZf3d768n+j59fmVhwD/JiBe6OWJvs37+P/n1x+vz/zup0xfP3kv7/nxut/xmVzjN/n7/R3lv72i5rf5j9Txk1vDeXMQO5Saj+nofJPWv+lk+Pz6ssMZaSqaS77JOdzKfORFfT0GMdTonFrFgpkx8moAjQ7O6tkx3huSQoXtpWxJAJceMQj4CMaLGAPYEqhN/p3r/whQw8DU9BHMEAEyI9lOwFQ8+ErY7/Y8enu7Iub3MgntZTISSPYMGf/5Ph/j//e7Hd7hjO+8F1OTVCU1fpe/39+/z/XwcdT8v/kPcR3f5WMs5zEQXCvNxwT4GZzvEsV3W8F2L3qGnxr/J5FI9PT0qr4e8ProklpFg5kxlk9E64PnAcYGSSRF90LB5ngW5QtVv4ACB7LAkG5ImaoEBNQwDAhofxgRRpRrzmbawewODJ10JV0RCYh5kQYQTwwSAbTn+f8fb3syCHHGvGcBxF6BmM9547OeeHYTIJ7fuA18GdgLEBjS57f/pXWI63yiffoq8b/dfrcEgtsFEDw/ucR4l9QqlsyMjmogIuGKKIHAXlkjppgNECYAgUR9Cwiu/0NNQtIVkY4q109qdI4lL3sdsLxGZCD2uwzE/E6OEX9WyYB4ftEzKAHxvb4iZNB5ynoxIORzvJOJ5vW7A2K/80DsyV0RUsJPTXpFaFvzkZ36ekB9ovNqFRUzw4AwIwEAd5gcECHvZSBSXUOempjN0AsHo1OVCg/E6QQ1DGZ25akpiNiPn5qSY8n+BV3Z7ZZAzJNBBmJeIvTYPPfz1ISphmxqwp7djlcN1MhrxG7HUxOOz0Do1CTvdWr69spI/PwpQHwvgNhhjWCw97u5xHf7GsF7uLU0NclVqL4eUJ8wVYwWMyMYEOmKkGMEIEyhwvaSOF/pYq2qFlDgANU0surT5IEQmZMINQwSXYsxYLHuxn7sjaw4gQGhjiW7F15Cfz692u8ILKm8gPL+H/LKgOCleF4csYy/4p0sm/NiPQ/bvGeeqXeUauS/ZbGW47Tn8152vOzuBTBZ1nl2p/2e63r++ZJ+q/D7uQXCrwlekvWMF+zh1l74HGmLS1z8ghmrHzfLfbH52zNernWFO9GqqeKcXyh/6y9r/0Vzv/gpl/fsr9Za19Y+WpZ4unrOzUDQLwOxxmH4M7c4/DAsP4d5z1cB8Ru27V7Tg2wbEBsQGxAbEPR42wbEBsQGxAYEPd62AbEB8f8FCN/c1zT9ezvwq7U/rJHOBsQDAPH0sgMfQrZ9xcpYu2+0YjaMf4LndvRpX3pSTNKoo2Qb5ruqZ32AXv2nj6OWlju//5zl7uvEiSp+jeM5T762+ahR/z/n0j37MhAmR786CiH7pnT/mHt2XcL6HC+MZLoJuts/gQ9BxobwrIxQqExkCNaB6BSIrCNuYYVsHzOJeD+RPiabn//s4GCtItCWj8gP0+J4C4jQHDj0w1zpvZ98yRQxP3l7h54srTlKIHSf85N3kajxQzbxiCsfZe0LJzAkuU7GhvCsjPDpK6IBRCp3oASE/jGNAHWriFImp4Pm14MBEUoguotAUAUEP4+dgch11FdErOpsXxEJiOS4sQCC1oCgJRCc732izIbwrIyjuqXkpEzWtyCZYEolDCGInTBUplfBD+LyviDlztMaEIcMxLgE4lABgQdskTrKKhdIa4kOh7TVV0AcEhDZAYXrMBsBcEQYCPNqKbU2SLVIoKahbjMCxEHIcQedZtFjPOCb3VSYyYJRyl4vSKbN+wDEzrEhPCsjQL8iUJHXHky2P4xJ1SKE9JkesEak8hEPy3O9Ki4x8r+6RowKV4gnG2ghCkhWzoBgJ5USCHE7iQaVuZzwNAYdDj7+EWxqMheYeAIxCGcYa6VTDRBMMsJMGc2ZotTaQB9IOC82MpyLtOgHs19QVQOG0txUBkkXE0Yveb2AqDHvsysisyE8GQAOEmI+oEoUNpvjYe0Pp2cRKYY8VAcpDyCgbBHMxoK6aEAojQ9rxGBnC6EtkiobzGczd2OorgjVtMAXAkR7PHcj74FNSH/OQET1vOABBBDO9cKtEdD64DHIQHitDYIWyTmKI4y6zUSxGNHo+1SC3BhC0YOB0CPJ6yW5WtgakdkQSyBE3YIz0RNNyW9lykBkJQw3VGMU5Yy5O2Okm4BIZ8cCiBiKxdrWiAmaFphS9IqYv2FFMiBiaAARDAjngDK5xXpaAuG1NsgUP+xqpwSERT9ZCQ+EfjGJH2bokbxeEhD2rSmzITwrI9s9lZQbm5pY8cIrYWBqEnWPaOXDiM9LBoLtOOYzV781jYQyCYjBf2tK5jNDXkXMzwRTE0fFx1tA2Lem7IBiDJX8/ScBEWqtDa2N9TyGNGnHUqMjhOzIAq2h7OOC2rLXS+ampN8RmQ3hWRndBEWLvFhnZxQQKfEJNiUMIUue+jEv1kdZ0rBYB12gOjlTyGfN3xGj/tYwIPrT8Ywh5+O9/A7QpVoXa/Yz4VUFizVHBd6IcT+iuasE+x3hvGPSYi1fK0T66ng2r5ZSawOeKKLncTKRsH7sU/RQ1kAJW6zNTYX7ASeZ7PUCSmn6FfKrv6zj4svtbbX8c778vt6H17n2/N0d3/tv3Uo6da4xxs+Pwee2bhlY6/VngfhTtzjy7+N49/mxUaOR57Z7TX+o9u2m3wbEBsQGxAbEBsQGxAbEBsQGxJcO1QbEBgT9RSAed8j/RLSPRhN67Gb+3wAR8t2XWO4Pl8+am4mlPEO82tL6VnuU8I38/kL5eGvFOdrmQMWixr+oMZKBCA0gAq37UszdGEvZBjvfp/VDY7xqzY3ynJiDrZxaWgYaodgb2ndiJdq6vfBYGiMXgIi3AEENIOgKENSotQaCcxZds2QLiG6l1iLaxc4H0RhRHsPJHEYy50C5CCPSNkdxL0GaxVQ18JBtJyoD6gtSMSiIyrOzPb0xRYwVYjoeKGVR/F97V5PbOM5EK4QDEFp5gPSeyErwKfIBfYAsOvcRsvIxvDTmlJ+qXhV/JEqWYyed7qF6ptuW+P9M0lY9vYcZYaWPQRW4rJD5ppi/CtRCECTqslLnrWWWibFOJBJ/+h4aI2ShPXMYMc6BsRU0eq0WAaRGGmAj4LFzp2FIoF0yKGiSGzYBZnyQmBTySYph2awVwfgXsAAQm4IYtkSbOZYGtRCHGZ+VWmut+J2oJoi5uPx+jRHpYu4w4idsBa9qHV64OBCHgKqGKWIAiE6nXcmgoEluUs+TRFBIgwqiAngZ1grSJadTUwwOsHIe800xWw8AIfWdrWx84uatRYzZ67Ln6XtojJB5fZjDiJ+yFVStg4dSmBvatUwRA5v1KQcixBlR5ib1PEEn+woQcafyadO30mVGYHgolhaBsBlYAyK11gmryrxSakD8Ho0R88/pzWHEOAfGVhhUrcP7cmlS/Q5vQJhDSM6gwEqYcst7W5rEwcuWGb6iQOB1NG0iW/g89oiMjzSgNcejLWtWvi8cWMrWOv2AeR0muLj8fo0R5V9gswZnu2QrDKrW4WSzw8YCVY2oiBEOsiG76GRiDAohpmW5u2yzFqZIYlIQajyoH4q1wlZudR1RnxIlNZIyIAKnl35o+S7jmkxba8wNeKWYi8vv1xgpvwxea+tIdVPL69+HlVRL33bD4pfZ9dZOe/ndNEZo3WFkCxDXHuHaDB/4oMxbu/5sxMeBuJfGyA1d+3OOdtOvAdGAaEA0IBoQDYgGRAOiAdGAaED8lUB8psjI74Pr/lSh+7SlAfHNgbinQ0m1CducSWjF3+R6l5KKzsiw3s5QjEhYGKn13CF710l6VgIZZISn96PCrNS7OZRQ9exWQwx78VBB5HqXkorOSFi+5+kpESguAZF8ZuZCETkQTgOqjgY/1xDxi0Dcx6GkcvZaIOhDQExq3i/rjNwKRP5iGxAq5kKLQNzboYRV5kUlXl1KkGKbMwnOSErCGSuNj+tdSio6I0FVNY4cxAHPw/42toaGp46mMaJ8ltPcZwbqG4fI6UBaME0iK+UIIPwAIMA7AYfkEP1rxlT3digZ14P9087cRh4IKbY5k0jaJ3Mj2VEq7WMuJRWdkQHMDP58MpuDSLUxRIkAHI48eMzsjN4nM4fSZ4Yo+s3IJ78HI2bg8KrxQaBC4pQr1TGzwyvTJXJVRLnj3g4lOxHxh4OCnh1TbXMmEYeRHWrEGSsNQ3+tS0lFZyRoxDuQEnygjdElkoCqaWDgwc6ACsncZ4aUXIByLP5/IGaa5MyPQAYEKcPFgsPgqkgb7u1QkoB4ikDQ6zZnEql997QIxLUuJRWdEaUeCM0g9JFEFNU8fFLToEgyCKJCUvGZyYAw7Q2ZEZSYH1Mgeq8KJqdCpSPa2tzNoSQBwW4jSLPf6EwCXxIuUYDYzYC40qWkojNiM4Jsj4A2BrQ5TBfDKHdB2BnBL/nMKBCR04FlCkwTY35IOeSUfMn1hB5Ml0ylg5U77u1QsiN2HDG3kR+8de4eNzqTSNqfXOIP8ThJpQGIa11K5joj4x5BpqrRiSwLtDGgzQG2hqlpQD3Dk6mKzH1miMxvBpyOZ1UkgQYHmB9SDkhyqgECUpAQSmNLOFX2FZMW35XHNoeS/cbSZqVcTHmNS0n9l7XSP7N0gbYe21OWh6tIT1xs8j0cSj4PiGuOOhD4hRu+FAj6XCCuH46vPdpNvxtzNCAaEF/SlgZEA6IB0YD47a1oQDQgbs3RgGhAfElb/sjjj+/AX9CD/yIQ+jjuqXat46e/hsnJWfw3ZH+X6YzHwBcXUmkt27oRpq/8ku5Bra1hsQe0UspcE8Sd0rl/z2F5ZLz24FJ9PgPCT4Cx195TBYg1FkOezngM/NcyEC5zXclL5mdB/SIQeMzdWh8mo1HaavgKEK6CWijGonziLelpeO+ytk+ByJgeAoRb0aZYBWIyRFQDgq4AQgSfLwFRq0BmxDIQtAWIUAUirA+Mn7Ru2t9c4mQORD5E6zNC6gN/Ibmk+Ip3CrMRAESpbbHOYjC2Qs5jcIXWR8mQ0FrApDh2+rAvv2MFjUOWKzEv5AxYGfIxOWRXkRv50PaDup08a5181rxNUumJXYESzuqmYqoZSenDkwnQkzw1vsT06I5vb6IgcszZICHYg71Q7/AI8HlvzwXPvVNEmuEkzS60LdZZDEHZCjmPwWX+IlOGBGqBZwkcR7wGIrE0hYl3S1A3F2Fl9AACpfc+aoDEB9uxj4i8h9aqGjHqbZJKz5RApP53qHBgDAqlD3F88ZB2d5qnxvQI/dubPITfm4qHCACEJLvBz8ufoUvhdTvyFe8UZiNgRpTaFpdYDBwkVz4EJSDMX6RkSMRawKEI0N/gkjrdI/CAe/JuMQC1nQqE1WgaIF57RfZO/FGg5eEpeZuk0ks9Ei+yDkHUNKZKHzIjzgYE8tSZHiMQmqLTlgCILn74ldED3gGYBXPvlEBTIHLrimUWg7mRJCBkj4jMhZwhEWuRFbMboL8hJZ10sz6V3i0lEHGP0BpNAwT5UKOP10M8G71NYumlHokBkYynSiBMPCJSEqpMDwNC62WpmYGXajolIPpnWQwwdNOlKf2tQBTaFpdYDKbLUQCRlqIZQ8Jlw2Ale9KlyU+9W4I3fZcgckZJw0M/FFKDyvdwe3jl9KYFYmfN2ySVnumRSP3vsYap0ocMbh/ITHcWmR69AtEba0MgHuLSJFocx6BKFlTanJlKxoDX4zQdptoW6ywG+K10GY+Be5L7i5QMCdRiXxdU3UNKZAUN1JJ7t+DvZ2FUcFlJwwNXWf/DE/LxkLMiCDRBUKs5t6i3SSw9sStQ/wA3lSOku3KlDw//GChrkDIyKkwP3qxjWimF+xAls0jVOxa+w02+tH3tUZKFM/bFWp7ba/1gW93Fkio/Sf0ndOD+R/n7fhsQd4D/Dm3dCsRHdE9++9Fu+rVutB40IFo3Wg8aEK0brQcNiNaN1oMGROtCa38DYsMR6u+rEdaSy1BwF6plbak8bOhIKOv3a60qkyBnzrjYdmxKj6ekV3oOtYF0je/HdktlzwfTxZ5Mw/nGaDDCQSg4DhMbkAnLo+p0EukE9bTKf5j6tEz4F46WTEEiEcBfvo98ibVRSR1cpPKErAy/CIT3ueVI0af1GVEHgjIgyuthsXsLU2yYMy/yV9MZ4apF1YFwORC0HQiaALGSeqDIINkIBM2BwAQ8zRkVxowwJoOGOyRcg0e4mVWBxsLfRKbbiSYcjcTyiBoXlHxZ1DMlKVJU0yr/IXJDHJl2CHKgBy6yNsTVBIEecVix0o1xYbUnrgleBX+ZtZE7qYChIW4vR3BEniNrhKXarY/S/uhGIx+M4PRB+HyUqMaoMGZEjKdy0C8kBkO+NPXezuTqEuBSMGyRI2K5o/lB8jTp9VUt7dubBkMHCzyaOwqZo4OeNS7KwPmDOaxY6ca4iOHMEA0JgrVlytqgij8LKU8L2h0IgMo+58EBQbBYA8++l/aTtJ6U85iAyEeJaowKi1SbXgRzE9yQGAzFHsG+DYTPBmUcjZxcIFwMyx3kOuWeJshTT8tP6/MCaNwQ4U1o21zkjzhhRiCFcEy4loEoZ2SAcWGuMPBmEdaFvNLQ5ypro4v1dZEY4NTLpVM6hFAbNPLJLeX2d+cDmQdLPiPyUVJ+w0RzwsLjpzgjyA2RwdBPgSCZpFN1iYzloec5tx8CGRDB9gjJU0+rM4KMGxI9fk4Uu5PnhacL58x5HRnj4qS1G9eE8ErdZFZZG+Bc5NodNLjkijIDIngAAWZLJGcAiH4KRIVRYcyIyDCQpckYDEwGcPotxFEol6ZctSLTqvCR/+CHXG6EMl5HPS2vsS7jhigXok91KpukNy4K+5dwzpzXkRgXsfbBuCZ4ZW4ya6yN3EkF2h38rQlqQ+YTA3qcLno9llaYVJGBLUCA/5gBUWNUGDPCmAzGTQCDASudi9yFwylt6hlHQ7c/sDx85D+4yBVB3YnXUU/L3zqSCwo4Eda2A/gaR5w1Lgr7lzgyh5XkEJOxKNRoDVwTfeUvszZyJxVod5CX9hBF9gp0PBxqOeKDJC3WnNy7g45iPkp0/ZG8f77imMqvXdXSxbbTFVe2lr3U/vvUR/UvvF933ALENW2/tle3AvHHsTjaTb/Wkdb+BkTrSGt/A6J1pLW/AdE60trfgPgWQzEva2vpfxIgn9TWBsRvG7HEMQhEF1wX9KgzPiTQ+O/Z7p4ehrmnSGz0JDjuhsMw/s+5z/CXNsZI2FR7mF73+bXUCrAqSJ4QzDOFC70N8ZU+aJ0uBulTdUSmrfI6TlTnWLiLQNRPTEP4XgMsMZgzoKw8kF8CkTveB7mx7zSIBG/2NSBKY42QtzOUaXzea2/Pu1IUuag9WVj0zedMlzUgptSLkN+ztgfxo2DAbHCXgXCrQNAKEPwMcwIilbcAxJA9ZCzBp48CEQc5S+MmbJQtQNAMiC0zYg4ELQFR41g44TYYx0CirtDHkGCQMRg6kxifqU88n6BEnwPxHIF4jrwILg9AoPSkCuKoBIJzmtpFRcWjyJtUO6RPA0X+Rkwz8APnKMOLxkInAheOzsK3MG+VxHEptUHgxwKmC8eipy3iBbhsU6bxkZd5AvTBn09U41iA72CqFoi6ggGBOK55LfhQV5+QuKqyIqDCMZYg1XJZfeRF4JOOeNUYRsxUQSxwy7kP405BgYGoq3jU8oIhgT7pxzZPI+YFUA6x9gGI9xiS7SNjY64NIsHSQTVAaN4iMezoS5WTXjkuib8h4V4FgtVNKhwL8B1MTEFmBCkzghKDgZkddfUJr4CahgBiwKR7hBFUwMTQGXEOPlcFcVLq+L9Q2J4JM2JBxWOSN8bhxRsFS9EkzaAfJEJbuLYEREfmh2K8i1IbBFofh0QpmLVonBGTNoVI13HKk5GP2bkAYs6xsGB9AoJEg0BXOHMfYWYH1dQnqkB4A6KPQNDJgEDDMlUQ2yMIDA7dI6oqHtO8CQg6+WLHsTTgoPQZEEH3CAaCTuaHEnkXhTaIEhAG9MHIQ3mLlLmRtSkHIrU5xD3i3VONYyF8h2Cfci22D2RLEzMYXLY0TdUn6kDYtybLbaVLU3r+k1RBKNhHwSk9RYGoqXhM8vqMR6KM11Cm8QLG8ykDwicg0IfeZ7yLiTaILE1B5znNWzT2ctKmpLmRMZr6oN/YBIgax0L4DkdwDOADolu1btai3jGkzXqqPuGjT4mkpfJ3BOe2M3GzPkqNURWE96zDgAGQpU+BqKp4TPKqaod5o8g3pjINt7UTNhO/g5wWfkcMylWJm/Wxpg0CKgy4Hro0FS0aezlpE9gazCg5pNYdpbQBEmN06UhfMEP6ukVzDkegLcfUysIVv0LDhZxrR1hsfz2Nu+oBgus4F1Pi9Pr4Xl1s+jUarhiIdSDo04FYTrOtxdO+3xuIDxT7OWW1e00NiAZEA6IB0YBoQDQgGhANiAZEA6IB8S3but0upw1qA+JbARGKf/hInhoTVsc193WmQCC0NKs2q1U4FvLS/dvps2vTFKTOK+utCX5abqVOT2u38xBtC916myvtWzqmI8khDD3nopSBy4LbToUNcosPy76unWFXCiCCARGotOsI07uPPjsXQmYvMPFG8akd5cC4C0D4ChB+afwAxOCKvoZJTZPcE0+YuupGHMMhE4SImhJlIy8CQbSms1EAQTkQcw+WRSA01ktzIGgJiEszYgZE2AIEVYCgC0DURmUKBALTOlmgKTGGRNTZA2ehMKEP7RasjnXtDKJcO0OBOJkuRSBWuuAaz+ZtknEzjPvg9MHfIOwP1NSpGwoergX/xHKGcNa2mT8KgDB9DOQyvY2yPhpQ8uGUVEKSZ0wnlgmiuHGC+oi6xIhih4xUkZvUNcV6lnQ8SPU9kMpagRkhzA6nzJ7BQxWDJGIlT8YPFv8tWR3r2hnxcXnRzlCORkAEd3w3vKs5wbuHtwm4GfBRMe4Dwonj2sxP8x/NrUTagjCl50HJdD8CPF6SPwo+baaPgZBm73O1EKvPmfdKphKSPGNgmeDIovEMhOQXxQ7AnecmMlsEr5wWF2d1CpRmrQiRRWJAYIDSM9SI4hoQOatjXTtDBSRUO8P2iM7kECgBAW8Tl7mXGPdBWBWizpBcKrqYghJFwUL3AR4vyR8FQ2RqAOrq4vPWW2k+eq8knY7kGQM3F8wJDA1MTLqzAVHmJuVymHBEJh+h1AF8XbFWYKyF2WGb9RwIVTvyU1bHunaGzgjVzoib9WkOBMpzmXtJTiqLQJhEwslS5EAEMiB0mM0fpQAiCj/0pVsKmBTmvcL8jZlnzClu1qcciBBnRJlb2R8njEdfASLuVD5t+sLsUO+34Xg01xIFQrQoTMonsTqSusWSzkaunWFAIG8EwkuH+uTYok0T7oMtTSHkWhW2xGBpyn1PFIg+AuG5LwUQujSZ3kZe32DeK75cmkzxw4DgVBzoN5eYd9X6yHPLe1uawBMxnZ8hAuFzhRADInhR1ZCh4tUqfms/iBuJMSJyVkdSt1jS2ci1M5QsE/CLgH9HsNIF1wi+hHIhTsqVEO5DNFQb7HcE0kDlIm3WuTcLPF4yf5TBlC4S7+L5RD7X5kBpg3qvuExUK3nG8GZN4WAcDgyUMDC4H0Jvy3J32WbNI5vxVQg1yheOrO0Ya7Vou/cRii+s+j00e/cVh7v8hXbjsUZu2P4+rKT6tGMOBHypfv8tjo987m5pc6Bvc7R7TQ2IBkQDogHRgGhANCAaEA2IBkQDogHxBzZ367m/bfg/ThlqQHxfIEL2+uKdMn9h0OWe9XiPccgVNapF+1r96dT8bEeX7uhkahdF0fVWJNeKezFXcKZ8Rs6dKr3MU7gZEL44u2CGIUBM2Qp2C9ypooJLz4ZOKnepHp8LOEzqGqhCWnC0zOLI32cK/0PJV6GJOARe5f0J9CHmSlY4A5Hn9P4CELQAxAVvkeqM8OWMUFX5GhDZC18qaawB4RaAoEUglvkq24Egupa5gtJOfZ6+ygeBFDk4F53KkINxMKjHCJxJ5t4iJdeBeR/P0SeFmRp6C1zV9d1EUWOu4NGZ3PqJ6zdXF45mZE4qp1xjg1kRz3rWmBzd9Gb3ACCMPTLjq0xUOtACbudtzJUszXjmeIy9PDEQz8r0wEjKqMu60eMx7xRfZY4Bx6AkZj3UvUWmXAfwPJJPChgcTh8ah0dCUtSYK3i4+Hi5qAKA3xHkaXUNl0LzImlskKTp0QqJW/vIkzicSiAsVj7lq0xUMwa0QGbETcwVHQmP0t5jL+E14FWZIAV0TaBAXEWYY2BcBHkaHsMiXSm9RWpcB8SYk0+K7RHBlzMC/IW5goeL1ARK/IdAUaglqOZFp/oW3CaNCJ8Rt0YfAtVmRAKipElMVToSELcxV4LyRPhvAIFeQt1DrplbExQ84owg7cRpCoStsjUgEteBQ+nGmZgDUewR4F7MFDxqQEjsGU4ZQ1DNC3Ak0CZHpgkjM4LmQCS1izpfZarSkYC4jbliqh38NzZrE4MAEEH9Wbg3ouDhPfaITDNmQPOORyNFGTuh9BYpuQ6OQuaTwkyNCEQ/+dbk6woeujQpaUxbQ7ZHqLCJal5AY4OZJlyCtAJLU4TPArRJ7aLOVylVM4y5Iu28ibli7BGUNsReYvn10U0lLk3wBYEuhJIaSRkQwTxGjJ1QeouUXIfE3ADDw+mmdZANN/2OMEWNuYIHUjrdrD0ZvwOOJeD9MbckaWywN4ksWEdlclgfsOjoNxRTu6jzVUrVDGOuSH9uYq4YewSlwaVF9AOPAKLLRrKLLA5f++q6dmZ6iLSDn5+rpbumZKUxLn4tXZOj4L//PW9Tuwh0ue1b89/yy/pmmxWualG/8gYgUGa4Ygg/dnwXIG4+2r2mBkQDogHRgGhANCAaEA2IBkQDogHRgPhDgfjqzn5ejX+NJ1AD4tYj5J4I4BmUGhTdYtb4NNiZ3amtnE7LsjtZojVcdNkNWeV2+LI2YzxU7iqF8kVKSdW7Z1kUvahPnuQbOPDDDJPStiTQeplUuZ7nOZxovYSUJ96bHHxuTqH8ipLj4WbnJuWrLHpI6XN9hCGVBCAsQlgDIhIWfB5qL+6kDpY8aMpakxLxwc2AiCrkUYfcF0DMHVASvcBfAMJCV0UrFoaulKUogSADoiSMrMLK4R95bjGk9FUgbEZAMP0CEIsaGDkQU1OdmuXLAhBDjBXKR2cKRP3zdi0QdBkI42W4xFSAePhJnuI3WXYvChkcxgDvI/MbyQ1pOMhs7ARJf8SjtTkQppfBXT6owsbzKVPHIOhxIGzi6RCvG7PDeB0cClJOxYDHZ59PAxQ4jlFmXfJxMIiiewvnh7qHxcLHMzARGOAfc9bHmo0VMuecHArHlXNseV62ibGr+0rsG5WuKuCUGC/DRaYCBwGF3RBsRgR5ptupHkGS4Sf4myS6lzTD2AkOD8qrtD+AEH6D6mXEGWFMCVXHOJxC0uNQJokvmB3G6xiUJdFL4BTMiQFMj6i9AZ6H8A8G41dw/t5MDkj3iOOB2SqBnwUPEo3PHVAqrjGUjQCi9z1oGKlstIlDrgjOIkUf8wV7TJ/LsBiyy7QtlKUQbD9g7xQdWN0jlIFwtmC4TTQhoMi5MQ+BsRH8dEZAL4O7LEHDswXok9aGyYd0Z/N8yZkdxut4h5MJJYkFb+ei9oY6VSgQ+BqAWLR5txD2iD7NCAYCeh3mgFJ1jYkjwMoc6GdZ9vipR04ZyVwRpDtnriqkXjv66R4ybQsEtyMQ7J3SF0CAgWD/JyDg9RBUdQnh/ykQppdhMyJjSmTEAlAJNAXlQHSD8TreM6WNBIQRGBIQmBFxjzgpKcCYfz75m5htybvpdZgDSs01Jo4A0isnIy9beB06I5IiSJYv6oIUQCSHErAUZEKp3kR4PsWlKRXXGxAmpZNUx/KlCVcLIPzxKEDIMlKqYxgQwvLrzfMlZ3YYr+N4BEsiaV14knNkpQAI3iN8cm9R4hgWvNq3prg0TRxQCteYbARYmSNfmjKeSRBqA4DwqVX2SpcmHzwZL4N/ARhrQlkKx4PqT4hukjmPCBeii34jykQY5M+JQmInSHrZrHHVfkeYXgZ32Z2gYgEgktYGdimuwUdXksTsMF7HuAkKSyJpXYhcDzM9jkSJdzF+gRjTJX4Fb7tQ98DvCPZT4UXCUVCzt0HyJgeUOefEZSMABglanso2PRDmyByiIoiOzjG5qqAeunSEpS+PxeEyqvLWqxetOfzy+bDQyvU+3PrLOtA1h1v+0nrLEejex6VhWVLOAI/oI23/WiDoc4C4/9HuNTUgvlWrGhDfpFUNiG/SqgbEN2lVA+KbtKoB8U1a1YD4Jq1qQHyTVv2BA/l7wPj2/WxAfMIRiOwR09n5pXOsEbxRqWIj/2HtUqqhW23dcmnyEO3EPzhsAsIN3co4bDgqvJgwb6vxINysC34FCLmpPMzNNPK7rOX9x7JON23oQg/crCVu1hKalZbXl+Qi3AQIv9DuKRA+uErLwsr9Zl+O8owX4z8fiOV2Vdku1bclEG4DELQKBG0AYm1G2LPml8dmBQgyIFwdCPAN1O1DwhTnqKhxOD1HxQhT0EgsBX5UN/cnOStrwqTOmfGgzIej1ZOrWGQlHy0f6rMWCF9ClEAiwyS6kpR8CeSGGLyxKQ7apoNqjCCGyI/algobz0W7n+VxXIwM1DUARBfrh/pGYng8nxAxTMwW45Yc7MqMF5MzZmzkNAyJKHGAoYAqagi7QDkZfbQIMJYCA5G5mmh40dgXGndG4JB5HPrcvSlURKcR4UdYPqh5qMaH6AFACSQyTPLgZcaXKIwOpDaOUot6gtZFPgFRKmz4rN3op7E9SEKoACLGmtXeIDE8vNcYemS2qMuKuEr0VV5MYsyQjVx3NnoMfEsUCDJ2QeJV8JmcpQAgoquJMh/AeuhEXwL6HMpvQD1RocJFPoPFlvGgPZcMjY+DKGREWR+rX11JplwMWAp0ZLUZEFqX6HY4FSixNnmtL7UbJUZdnTMrbTDbxBlvRc/lDA+ztenO6HlyWUl2OVNeTBq37syMluCjQoR+0k4GRNDkmVABl5CxFHSPMOaHMh+U9cAlnVSfI6pr5AoVhRSEt3y9lKwaHxRVaJIDySm6khR8Ca2VnVvifAEQWlckMwCIXGHD1EPQbj4T2R7eD8H2CFPO8FDfSAyPNNza8+iyEmfEjBeTj1sgANH7jMASlyaKChR9Plw5S0GA8Lk2RzbFzS2FbLGwekyhIgLRh2xp4sC7j24r4ELkDiTTpcm4GNOliTkoHm2yuoRL0h1ZO6lU2Ej2PdbPyPboWWmjXJpwLmd4RCD6xM8QRp4sWuIFVvBiTO9D8/S2NB2Fvw3yomzWQ1TUcOAueGUxnEqWAv+OyFxNlPlwyDYh06eQ7fMI9ocpVERVD9HRsHxBUqjGh/AloATiUv3mt1JwMfJaURv4HVwS6mImBa/T47CGUmHD1EMiWyNt1kfepEENjZv10VHJ8PCkY3Q0XgdcVoR/InyTCS9myPrDSiA6ch8+tvzi3EATqXw1vnzuo4d92q/p2W2/rOetd3TnY0sDr0U60Oce9mn/nUDc/Wj3mv6gLjUgGhANiAZEA6IB0YBoQDQgGhANiAbELd1rLW3d+7NaOmMqBP6r6v5R796aJEHl3OKJq9obtiT1qR9jSxcrvHhnzF/b9G4+oJePXOwhs7yoSH24FSD8AhCJ0TGVknCz3rmyHdNQPNVJBX6xdYlFUQEi61jwF8a44gCzdUyXOSMXMlGmdXEZzctAzM8tAzF97avnl4CoD2ByD1pOuA2I7MWHgagcpoIhWhsWrlDvkSX3D2NgmLOKOKqUziSRnQFtDFWjQMiGktcIh3YYcHMjCXBxofMptSNxIlSgOshrguxD8mc5aP6uUMgQZsfR+nHmlkbmhPQh9o7kiexpaQWPpeIAY0va84TlkcbURNgT4+W55LBI3WQqGKJn4ZMchE29mvtHZGAIq+EdwcXSmSSyMwbwJIboj9K7LEQpDIqBTPLf2+Pz71k7Mk6E6vrg0feS3cHncj6GBkrxKHtv/RC9g8ic6OMD79abeWm9BmOXHGBE/ETrS8yP6ZiGzJWlV/sHn7FjiKIKhnASzuBxGBBL7h/JAodZDe/Ce5g4k0R2hnJCkj+KV10KVQoAEIczPF0SEObLknMidHtWrwsz3TB/Fk8WfQa3AuwILjeaZwCIyJzAg/5d7I1xVfLSjCey5AAjo3BGfSXLI46p+tQk5oYnl5E2+FwEIphLTk+ntFkvuX8kIPj8uw8qnJCcSRLdQKkIQ/RH8apLYUD0cM7y4kZifkTGCIHuh3Ei1O1lAkQgUmYI8kduBeoeAk2BMOYEgOA+JCCmpfXKE1lygMnHkEqWh42p+tRYW/sJEKEoRPSYQo8wuHmPLLl/FM4rPZam0pkksTOYM+EJ0kDSyV51KdSZhIPx8ikZ8I6E5xCXJl9wItTqBuyOgg0h5Xl1+LI+KRA+9ePdWqq2PM60OKCcUSkNvJJlBxgZwz6JpESWRxzTqSsLS1kUQOB7pKlgBDiaePNDkUm74P5xiPoXvBEOwnsonUkSO4O3LpmUkbeguhQnTQkLJNnWvH7jP0RGCJgfkRMBZZAjszsOkL06JX8Wp/kjt0JKcWSbtVe5rsScgNINemcCYdPSwCtZdoCRpemI+nKWRxpT26wj44WggBJLPcGEp/iCeQ3rIky/vtJFTQx/6dyl+sOlNl1sf/nLmrmI9qpeWriq/i2tDatfck2Z8kQfOrYBUSu9PHcTv2dT/uktjuLTWCntK4C449HuNbXu/bUtbUA0IFpLGxANiNbSBkQDorW0de9Pael3bWa9Xfdr7bUlbSfcfLCNDYjfBkRyNRkPe7BpcussWNoT/92tlNbNclXzzMovGRlhlmquoAFdjdyxJKR6wuV+cxJEQiBEPXhT65iOzhjWOU1bP7ZnN/6RY6+D/fAyr+XxF1/b7Xf7H68XGuTDEhDJOyTYK09R07h+m9NlrUXBeZ5lIFw2fn4TEJBz0AeDcxkLPoYLH770SC+ZNPsQ25nrhEBDfW7HMbZnDyAYj7e33Z6HW+CQc6R//9hzyx9exj8x+44ein+tU34JCJoDkQ32ZiAm5+8PBF0NBF0AIvUlaFS7AsQL7W04AcR+l4a6BOLHrx+/ciDKfzMgush2YDbG3DvEFC8koKPsjviQrSpJmMtJ7hLSZXn4evImAcsBzA1+7aYqF6dcp+JZHkEE04IPKIc8y4O3z7GddlZbkSljhHDWcsRGwnfwMNGySFwjEEQCMwQsEkQgBdYsKPYs/Xt7Gwf25fF1z0vOy9vbj18MxOPr+IceX3+M//7zyotRPiP+GVNzih+c5if+/ef18ee4gI2pKVeY4Ofya94hEqeUJpqiRRYa1AfdzeUkZFoVIMdonuBVq6KPficIepLFdn0Y8pw524J3AzAtODJnreOzPrbTzkbzjqiMEcI7VDk8gICGCEqDEwXrEZBPS9N7DJ4KECGFiXt5GH+cA+NMGJd+ngZ7mxH8h8+O53ZP/Dc97m2PeKCnMTWnkJzjwsb/8jmS1AX3QORAqt4hUNLwqmhhnASE1MG4MJcT7nbOWbA8fFnqOltc2JgbIBSIMQKVbIfEtpClKdHVYDHA8WfK4784Cx7H4YzaoNrx7pPTyjvoC1ngH0CgnTmLhLQ03rJF5UPh6IhnxM6A0Bnx49f4SR8H93G88vhL4KCHvX1rAmycBkA8/jIoSVJTrjCBrtW8Q9Irl1gSEYhA+YwYp/QpcRYsj2hjUBGgV+ZGAiIUOXO2xRSIQJgRJRA4K5/hU9DapHcCBDgjNSB4j8AcyGZEdlU9ZEzQwhMvlS97BSLbI17pdVyyXgWiChC7MQ9fHcF60Zmxe3zhnE+7gnuApanmHQIlDZBfEoGrXJqwOkfBkUir0jzBU669EbwxN7KlKeQ5c7YFgLCwJuar7BEGhE9nSYhAhXMJgOjByzgenbY+B4KdWIwZkpYmH+wblq0TQZcm2r8AiN2OZkvTbv8kF+ZAMECchvZP8q981do/6R5h3ANs1nPvkOChpOEJihbgJNhmPSg7I2Cjm3AWYp6j8hyM3eEjc4Oe1QQt+DxnzrZQIOKMkNYRgLB22llOEDfrozFNWJVDeRmB2SElJ4kVOlStI7JIRDNj6AZdUrVn3HrRL9i9jJvs48+HV/sdgc2aN+qH8fwIyWsOxI9XBulRrnIazsnnHsdUY+rp17ptJIDln0izL8R3OlQvZlJf7VfresuX2lYryWV/r6df/2X99mt+Nn3VxatPAeJWJsbWgfoIEEtt++pbHI+v5av9rQ36qqPd9GtANCAaEA2IBkQD4u5da0A0IBoQDYgGxKeU/xuBuHeDbyvxY7V9vw9T3iJ+fYcWNiA+FQi907EQTLWD7/LyDV8EleaXl0rmu5AcMsnTPGp51ijcGHuMV/mVMCDG2PwK/6Go8+GN723ud29ve6t7P02926+MV1HaY32MtHVZOVpqveQxVv2yA+dDSxlfn9kahN+NIeSTBj7OwiTYg09QAGFshNQ6jryOkanx771efZh14yHLITEsfs/35WMNEi6Rd1wS6b38B7LcFK9LvHcE4qGoZKXOPSICGRAvdSB289GdlfZQ9CVPyleWgMjbB5IHB0mF80HG+HBkQDiJ3uLV6owogWAuAgcFf/za16bAbv7BUiBoCgS6yyVdBGKMoDwsfWinde73Euu6AoiV0h4m9W0FYlLcnqMQwvkgY3wUQBBscxym4D8Fn+Dx5z/CRlAewjjZ5f1rPiOUq7CQi2/tvuwex7xj5Inh2GNolbvwKpHdV5sRDIeGTDiN/BuBeCHhP0gNr2t1GhD/jEAg7T+vKPXX+AepuSbjV8ih6WqlPWgfdTmS+sdVhqx1ODv2UkqNH9Yx/y8plfkd45UxJscxbW6JMT44Qm7eMPKI70Ac3OVCn3bCJ3hC9HT/9CQhP/AQdjjHIb5sjwBXwVgI01wSUd/x0jTGYhlKBUICiMSLjeTXPQIzAmFGCZTsFLY9d+ABtVgbFuvkrLxD7H++vY21Sg6U+r/xD+3QP+QTxhEPsixm3MZ5adpGTYn6X3i/2iUg+AxKzZfO/0lLhVYw7o8AYpcxPjqwtCQYC/EZYSii82gyLxdYZyMtBFyFHbMP0v6/V66CsRCmuTjt/3bgOeQzgsthhsOD5LdvEZgREQi9jjDjTmt5lLz7lTolK79/Gpem3eOvR/SKAMTjL/SPVwBNDegW+/2gfbQNGpBSbB0q/N9uv5sDIaXhws5mRGJ86Iwg5pzEgOEwAUKYCbunEgj+pIzTuAQCbARlIUxzvS4BsZdz8u7VgJjMCLsuQOwJs49euQ0GRLVOA4L3CO6LfBYNCAyyLCKvTxkQnKre7wftoy1iBsR+NwUiX5p0Ruiwj1d2tkckxofDKJ4CuZxVaEvTXpcm/vefV2Mj8LbPa6d9nhIQykYAC2GSi9P+/PlAeJUB8QSGA6b9AhB6HUCMW4ReQxuW6+Qtwr41PQmLQoDQpUne69L0z2tEQnPUStOlyb52SrqfP7kPunDyh2E8g1LtDLcvLk1Srn1rSowPly1NJgDmeAUk2Z7Gz5lsgfzvXrYp5SG88heCx9fHbEaM33eUjaAshEkuPsdbk6yQTLf6KSuybNbMcPihG3oqEduqpHm11AYEatlHBkS9Th4I+x3BGy+/IqE4vux4S0X/JJ/8sgEOyFEr7YfyMWxbljYwGcz6grN7LfUFZ7h9L6Be/pQ2vdrviIzxcbbN+nCKm/WZln6GZe+y72rz34T7hS/l2463X1t/We8313npl3XKM/1lek0PyrQPq7nXf1m7rZXwZ2i5k4mP8BEgtt/i2G+uczsQ/Dle7vf9jnav6ZscDYgGRAOiAdGAaEA0ID65jQ2IBkQDogHxXwXiequX2wfjlqvXtugjsGgc/W3t+rZyL/c0pmhAfBsg8PAnoqhRqDom5jMWY83PZeIRk8ehJjn8RGYi1tkVpU2vZm2wAPsp5ZE0dYuHmK1TvY50Jkz6tpTr7e1Qa4emkifoznm5Nh58P/VfFnkfDufBF+Pg57UV5XhJ6jYBkUQg1oDwi0D4yVBHVY/q1TkQ3qc7lSUQuYJGGh6nMhF1IPwCEBCEYBGJsh0+a2lOAMjHI2qMh0A1INxCOc6AQGfdFUC4K4FwVSAoL20ViMxOZmFG+KK064Fwm4BwC0BgPAJFsXfRfq/NiIVyPCF+Ko/BDpgw55N4fsTHbbGOQZr9oHoZSItUajQfHVUsR3F1gMYGcqM8J5oAVlp5lZ/ahlqH+rAMUPWAyoaWcIzqGHhA2FxKBtG4DwaE6n74LjqadKot0mlPp7l4gKyV1hLVHhl0zAYr93xK41ECkUauVDeZlyPjzy+c+S5IIe++Z4eR6ASiQ4Nn36PUg35UOV0P1Qu+0qunEufIr+IT4PWRdjgS4TH4+lXWMYBaB5Q7IFZC3pwrJI0aApgah/m8cFp2b0lA9ElHw9s79WqBecIk15jHPhDeWmImIRjATsslbwYL+BAfTgDiMCQgpuom83Jk/PVFnDqmftGJi0oXh9V8TaC0YdPscDZtDVPzyIDIruqiRXAbkfJUoUP9RCZXg7o64F9LwXk6imm8OL1EEYjMXkQGMAHB/YAiAjQ++D1cUrzaiZS5shmhLeGU8ctF/CTzKJlqh63jNiP8YOMwVTeZlyPjPwWC1S96VZyAv4p+gtXXZET6lIBQdYoeAg2BSiDS1TTUIQ4OdxnuI5WrVSBk4p9SCUHeeUozog5EL30JmcYHnaDwtAQE9ggSHQ9ogpifS1rbowAGrQMxUzeZlZMDUSxNrMTBE9/Wd12aRJGjWJpExYN9WGShUCcSy5FfhcYFFjYtr1cgfPVqCL7PrJrUxqY3L5diaSJW4PBx2XLZkHa6lqMvuS+MerVEINwECOu1LI7ejKjcFIg+X5qCAREARCyjUDeZlxOXpsMp36wHmcQif6VmaLq5smKHymIhrccWfRRhqSO2dxdzFFcH/h3gkUq32oOsqFba9CqsyEy5Qzfro2p9FJu1qHGIgob6vgwyP6EAop9J9EUdTTz8XEiUQLw5pmS5+HeE9Zq3WdENiZusff9HelUi0bEDEPw7Avw93fALdZN5OTL+6bdfYhOEOFXxbv77sGQeBP/vuZDxKXIEX6afl7d+tVLfLE1YLS1Qat2/cUX/97xUA/Ist2OdiZHKzcsIl8pZ07Mw5YpLP+eRLte5yHPM9S/uf4sjrKYMdJ1CyGfc4giXymn3mr4GiIvlNCAaEA2IBkQD4uarDYgGRAOiAdGAaED854C4X/O/4vhou+4N3G3jc0XuBsRnjk81dyIChOxMHmu1FE6SuBPfR2TZcrGQR9jxDClzU0eWUAnyj6Ge8b7o2Y33Iynoef438P3SsRSvwU9+D+sCeFoTgqkoTcqtBOM7Mh+VFL5ncXaJkLHo+1jvJIg/6TXfVXWnrtbzyiihzoIbssIk8aFbuDavgwMYEyD8IhAdxNnlJrmmt3Cqx2D4aIJAFv7gwA2ioHwG5/lfCehw9Z0GatjeRo3nvQ6xx99Bg651VkSQfzMeBQIx+sqHHIg5DwXB0pxPcgmICSVh4j1TAjFzkplTK0I8mxgZy0AgxTO5kOJukl7jaPzyOcqz472T/C4EyHFzyCTgPP/L5yW1f8aDruP75wyIZ4Hg2YCgy0C4DAiNUUsNbDaxzENBaMhtmBFuBQiaAeGKPCtAZGdjUAN8hgkLIwsDOZnKXuJd4ESI1whH0AZeRgCEBGfG916E0kf4OOwycJhnvCzn+V8+j/CTk3nF74Xd4+FYwssUx+O4NCnBw9a+bJfTVrvYCwz/cwbEMear8VAMiI7A8Cj4J+CQmNz7MOWG1LxnEM5KIxZ5KhWOi6SMjBJKYT7hKmQx514l+pNcOU949iDpTojCitdIGIdoAL/CaCv8PmDtGQON0KZnhoTYCQj7is8jIOtE257fyx4U4FjiZOjFjeLEJTCto9oujQVbG8cdYhj3B4RFiXeK91UeCvfnIJY2fcZY8WZQEHzkssy5ITXvGWOKuDh7UNuc49IjaBqMURIPcBw8paRoQuIogHPhzUkB4f9BN9yz00bgPHM6OuZwyBZBINaMnWC+j/xrMWkpA2s6SkPZXIKAi0VJ0szbJfV4hCW1F5gHvc0I5qTEGVHhodiMcGQ9jfwT2Wk8vpKk0jMg6t4z5YgZT2XOcVGCDp+lGRBgNZQdTouZI2TKgZD00hBXnBfjGjQqAiHGM2I544pOeE3tlFMBIILPgTAHlLJdLqaeAJEtTUPMV+Oh5EAESkAEcZkBECHyLiYknZr3TN8XI2Y8lTnHRRlOsld6KpYmTBLvS/ZBPtHEsUkmsdeJFuCDJPwKbxQYWMgEZnAgB9KT/qfGKiil18GWpUk3WlmaOK+LrQrCM5m3y5aGnEeRf2sCEMs8lAKIkn/iFQi/xA2pec+AapAvTeCpzDkuzycFQs9mmzWvx54SC0PYDtlmzSs1Nmv+HcFbj5fPN3uOMPuBzxmvYtw3gjA4JAfSc738N4DQUpg1wc6HgTcyLg2bNfMauuEQyxvTHOftOuhmeTjlmzV+R3Qn/KKA4+ISDwU8joPwKxJjxZt/ytFTvlmX3JCa9wx//clHLPJUZhyXILWI6dzJ5Zt1uUxtVov40qNs1zIL41J/ltOHxd/MS0yTULTHFriy9BrHBelCuNDldotja6pQnO9OYSHHlOMSstXoEzr83wPik3vRgPjM8WlANCAaEA2IBkQDogHRgGhANCD+TiBuqWAr2aSB3YD4rkDkegMhOx8uFBgmpZiGRVKYiNSEyLpAvsYUWQQiOpkXA718T9NXgcBjsW6u8BGD/etA/IeZIklVw181Iy4DQbnCx0Ug/vNMEQ2QHDtVwxBdCtGYEDaDhjSeVfXCroOPoIyFk6lcxCf2h5nCh3AYHJkmhq2UjSliTBELGQZemnplXeCJeuZrONUA8KZlMb48nBAm5etBU3tTyBA4uvlj9D3n0YCkKGY0pkjJFLHFIiCIjwICoXCJxgboXWCDAjekIxMVwVbG76CQkc+IQlhC6QFQ+agxMigC8d9kisQFagmIcXrJpodJqKSIU69A8AwAEEEhsD1iCgSvqg6iEL7GyDAg/rNMERe/H3mV5TGxDyJlVqhIjvw7AADWviCdaiGK6JiGhasuTc+yxo/h9j40psiMKRLZDFhlmRWB7ZcLh8yT8jLAQoBhl2hf5Ju18DMoalicZwofR84jolEmtdKYIgVTJKK2+KPNX/4pl/9iDJNf1lOFjyjk05gitWNZqaJ+JSwCsXyLI0zKa7c4PrkL7V5TA+IuRwOiAdGAaEA0IBoQDYivak4DogHRgPibgPjeVJGtYP8FMDcgfhMQX6AzQV/LFPkTOSL0JToT9LVMkT+RI0JfoTPx1UyRP5EjQl+hM/F1TBEJ7mbt+IM4Il+hM/F1TBHEslM7/iCOyNfpTHw+UwTtTUyJP4sjcqoBcXedCfoSpogHUaDscN7mb8wR+Qqdia9jimAx+CM5Il+hM/F1TJHxU3tKTIk/iyNCn68z8YVMkT+YI1Ltam0obtWZ+AqmyF/FEWn3mhoQDYgGRAOiAdGAaEA0IO6ctAHRgGhAfGruBsTNGf8KMZEP1HI59Z0+MA2ILwLiowoTzILIz/02JxKaM0TsjhP3SO6M2t0vq1lrPwzTOue1bGyTzyL8S33OiAw5EHymow8rTODsN3AioTlDpBgTowlYG/IKh2md8x5vbFMViEmfc0bJBAhHNyhMlAP4u5xIagyRdFc+SCgoAUEVIPI6a0BsalMBhFsFwtWB+LjChJxVJsfvcyKpMURiNwfmaZj6hzArEMY6JiDyOlNPrMfb2iRnjmt91mt4sHkgbSsCXUZE+7DCBJ+NTI7f5kQyZ4jkQIzhS4n69Rodd+B69DkQrly2yh5vahMTcuQx98U+g2CWwrZgrGnoV2Lm8bhWYQJheGNy/G4nkpIh4mM5sn4obYxD/kYKyIFIdXbnaY+3tak742PBPa73Wa6dk/iJkAkCWCkkDJIpEFcoTAAIMDl+qxMJTRkidSBC1MNYAiLMe7ypTYkgIHTMKhA6tn0ORIj5s6XpeoWJILpcYHL8PieSGkMEyhcutUeZIGlpwvXp0pTzLLTHm9rECxNXvNxnDzmYnncnWZp0obf8k836GoUJ3gJdYnL8NieSBYbIwH9iewRkTiPcCuFX8J9Dtlnj2qzHm9rEW/V6n71u6KSbtROeSGcjcpSN/x4KE+G3OZHUGSL6iV888uvuQk8ut2lrnynb/C+N2+z4rFscoTj/eQyR64/LPZm2aXt583a2e013qqXd9GtANCAaEA2IBkQD4m65GxAf7uR9czcgPtzJ++ZuQHy4k/fN/UcCcW9Rk+vkUu4N//0H6HPGpwFx56s3AFHnFmR3hFRoAXccyzTpKDkV+fkVBQ3K1ChiKXUmxby2pdA9R4ZVYWPQ/6Wi7gT1jUkda+yKLxqfjIcxD2nPK/LZ3cM1TkV+9oKCBlnIZj7AUyZF2cZ1IDpV1ACRQ4fnhLBQ8EtAzIP6XzY+1nx3sSJL4RYQLzkV6ewFBQ3KZEEWgXBXAGG6G1DUUG0NeuZBDWtALLIrvmZ8IjdhmHILmBHxbJwMfYjWgwtxsjR1TkV5dl1B4wyVDbKgSwrQzpkU+tjsaYBeBi1zKDRMOiQgOFbGATyJBMa8l9kVXzU+kZsw5xZw2LHX8KM9Vj4WZr4oK5yK8uy6gsa7h9eKhPXHTg0rTArIMUjsMPOgqHEo8HB7CYRITRxZhwMf5G3sii8bn8TDmHILgj2HH3L2ATMOOopp6pyK4ixoh0sKGu+mZyFlhjDnjiQmBatjeOGX5K4sNQ6FymBRDgSAZAhBF93Grviq8cl4GDNuQbUiYRycLE2dUzE5e1pT0EhAyHen4X2FSdENeP8e+RBLHApQMKdAsK4G+Zx/cZld8WXjY9yECrfA9FdCiFMPmhWidrTCqSjPrito5EsTrybH4zKTQjR4PHMQwYdY5lBIHaD7BKfMVYj4mBzJVnbFl41P5CYMc24BiJD8b7YZHVVfYoVTUZ5dV9AYPOiLuimfQlhmUnT6ntd68mscCmFdnNkvxg34fyx/GH9HDKbgt5Vd8VXjk62p6bjMTbjAqZicvaSgkZXq6/XPuRqYP5fa6Sb/L/XxMrvi88enemz9CR907Z4M5+zs1lscxnKop8o5EIkw/NHjFnbF54zPDRVd1+l2r+nqtA2IBkQDogFxr6sNiAZEA6IB0YBoQDQgPtSGPwCIe0uMfC7F5N6DcH3PPs28pwHxDYBYY1fg+I36FDRtC9F9GBSBrvN1sTLW2Sjku6JPq1yUmRrJsMyukO79Rn2Kz2FQXOvrkvdtmY0i7bMH1/0lLsoUCF8CQRN2xfQz/hv0KegzGBT+QzPCr7JRtgDh1oBYYlc8C7uC+RW22n29PsVnMCiu9XU5n3J/l2U2ioSDjuqQclxT9Sj6nY3bqc6uEFF+eaTdivx6fYrPYFBc6+vy7vvo77LGRkHQVR1S+rDCRcn7nY3bsj8JhxpNken36FN8CoPiKl8XviqfXJV8WGajIGbutN9hhYuS9zsft6HOruhFayMH4uv1KT6DQXGdrwtmBEV/l2U2igGRJCeWRi3vdz5uC+wKZsQZEL9Ln+IzGBTX+rq8e94jzN9lmY3izVinN7eUpVHL+52N2xK7grUxGAjZ5n6TPsVnMCiu9XUZQL5Rf5dlNoqT1hy0Rd3KqBX9zsZtgV1Rfrn7vfoUd2VQXOnrEstJi+4GNsqWUQu+HDeq/2QPxbvvpE9xG4PiWl+XORD3usWB+opa272m63rWbvo1IBoQDYgGRAOiAdGAaEA0IO509YND0IC499UPDsH3AeLvHLjpR207oWe5dWv5b+xHA+IbAPF3si7CpCy+azr+P+BfaDxPOSiq3ZGFcKy/4/Duxj9y7G15+sV/P2qiR3n1+Aspf7yutW2f5bsCiD+PdeGrQEhMTf8fvLXWl17YHiYzFSD2AILxeHvbjWP5IBcfNNGDvPqxBxAPWfYdPcyAeJA/uywN0V/IurgOCOslqXbH8yyzAPEiH2QZ1gtA7GlfAlGbEQ/FlV2+sv0trAswItSfRa/H4KbG1viRYqeEg07UQKQu0e6Ahr6Ju4OR8fY2DtzL4+t+Py46L29vP37xUD6+Pr7ygOLfCMQLvTzQP+M5/v/x9cfrI7/7iXR6nnPTj9f9js9yqf+8RiD+FtYFx5b5etDU8YHyk86I8d8xOOrT0vTu1b8hJCAs8gxGxjgHxqHb7/Y8cnubEeN7WYT2shgJJHuGjP88jdf4//1uh3d7pHuS/21pkuKk1KddmhF/BevC2BZByI8Iy6P8fEawlkcOBNoM7Q6c78QxBm3mkCeGTYCIMyICMW7SAOKBQSKA9jj+/+PXngxCpBvP/9pXgNgnIP4O1oWxLca0JwNCy8/2iHdV/4gzQtuTgOCSDQiZSy97HbK0RyQg9rsExF424zHh6zgPyIB4fEE6zJIIxFMxI/4u1gXYFr16qGQyPBkQrOWhQPi0NAV1YkE58Y8sTbR/wZDtdnMgdvunBMS4Rei1f15ladrJO003nnuKS9OOdw6UKnvE38W6ANsibdaeTAsk/Y5gLY+DbOrsCcNbt3y9EO2OwwnlmBMLNmvavfBm+/Ph1X5HYLPmXwx8/oe8MiB4Gx43YWzjr3iHdOO5n/+8/pA/D6+0o1gq/W2si/oX20u/rOvuKnnupXfLKff5V9bd/Fw6G8//TayL8CEgtvf+Y0A8vs7PpbMfBOK+V7enueVoN/0aEB+vqAHRgGhANCAaEPfoQAPi9qt36UAD4vard+lAA+L2q3fpwH8HiN995C2stbbeg2v79VkDfncfoQbEpwOBex376c2Q8abUbr+piN2WRDl/IStXa6nX9OPXw8sOPAotY7x7qtcgto4e4FF7eYQ/O1vna3AKdlYpTn6ArfH4GsfNro93VZHjA+O7yxO+1BNObxPieJgAsbuAUM5fWAIiZz2g0N3+ATwKMhZFKPgiPIbjOW/DmZ+t8zVAlQg3szX2u33sl/ZQYxTlCG0c36uAWJ0Rl4FI/IVlICZ599w1CcqTsSh0pCnF+nIg8rOLfA2+314D4iq2xp6mMwLRupUZsTy+zCF4ewPj4J9XhDt+jX+EbfCTo7P8KlKmNB3Oxgk7pkQqu/YrptHQSYW/gJwvO9QSl6IxzS+phVs2XnkZ075w1DixKILyRRC24SARA2Eck/xsna8hEAwcKbyNrbGnf7SlxtQwIMYzYHHIGGwaX46Yvr09yUR7Qlhv97/xD7MNOKZKEmndyRAhOb9nEJ+kSjnLKSWVxBKJS3ja8XAjZ52/gLJftJb0IXmg/0lkV0L19PAKIHYZiyKQcThMyYL3COOY5GfrfA0AIQ+c38TW2BNi0PsXY2rwHgEgeCT2Mp5Pu03jCyCYXfAoaO4JCZltgOHi82mPeCScBxtBP9fKTtiNWysG/n9Ioznr/AVM1v/t9rs5ED9+GRDcAcyIxKIIyhc5RCWLt7fnyDHJz9b5Ghpj9LeyNfbK1PgRmRq80gAIHolHzb1pfA0I5h1wly2hIL2TReP1KQOCXlHAXmeEbVHAFXsdZkTKWecvJCDypUlnhA7HeGVne0RiUQTliyQli/HcYByT/Gydr5GAuI2tIWn57xdjahgQuxcZidcExMXx5TnEU2f/JIlfbOrIe506/7xGJPYoYHzx9M9rBOKJ/3AqnQFjft4jLGedvyAUk93Pn6hFpvwLf0nKlibJa9+aEotCgfDRzMwzIcA4JvnZOl9DXFYI5mi3sDX2Opz7fcbUMCBkoTYgNowvcwhkMxm3W2Y68WbysuMtdC/DJaTAcaU2HGRz4mXn5zgl9eyY9ye/fxiv7XQL3mc5F/gLSLHXWl5whlkPY+2vYDdwCvsdkVgU46IkfBFs0KxkoZu1cEyKs1W+BjuseImO38bWeBR+Bv+dmBoAgnPtZMfgq5vH99Ivv+zr2b52tvZ+/sWuuLqbnnmolJh/Aay/tq+g6VzwtbPpcNnfa7Vc/8t6v7smdXXktgMh6+AdgHh8pauOJSDmDizgM23r132BWO7T3YD4/Ue76deAuMOINSAaEA2IBkQDogHRgGhANCCuL/ceCRsQnwvE5w7S9xmQLx2WK8anAfHdgbiFYWHXElPCDetsitu1L+ZsCloJs2/mrMxKMBbKLeMz9tlvgOBhFYgtDAsdy4wpwQIMa2wK+gQ2Bc3oDLv4bjNVYkaIiOSHG8bH67PLZafddTNiC8PCKklMCQ64rLEpbte+mLMpfhcQl8cn+BoQqYqCdaDT/0MMC1PDQICeIhDLbIrbtS/mbIo5r+SHhHe4n9s4K9MS+PhHar5tfBLHpBOvFjz03CE7NzBnHSg4H2NY+PjsPz/xHADEGpvidu2LOZtizivhj+5O2BXbOCvTEniUnqQFt45P6MlDZQFmK5AViDMiZx3YRPwIwyKpYfCou8GAWGZT3K59MWdTTHklj2Oqx18MxONGzsq0BAz9uP3eyEBhfkl3hkYIbKCYdRKBKFkHeUXXMiwyNQxoYykQy2yK27Uv5myKKa+EXuWTzdvJ6zbOyqwEMmrA003jYzPfq+II/9sNORAZ6+AmhoWqYTBTgvkUTr41rbEpbte+qLApZryS8dU4qrY0XeasTEtQIHbYI24ZH+aa8Bhh5fA6SvFbSM46uIVhYWoYzJRglbwR7WGdTXG79kWFTTHjlTxIabwBb+NUTEsAELLh0y3jIz08BnFgARAmFFb/FjX7dbGdYRGK78aOfh+bYr85z1Lf9wvXb2WghCJF2PIT7/KxBMT2rt8XiJnCxScAccv4zIFY1hu5uaLrun5fIK4r/fOPdtPvjnkaEA2IBkQDogHRgGhANCAaEA2IBsRXVv0nHn96+xsQ9z9C5RVVLC7sVVekf3v79xwm6SxFV6/QVyufpBDX56UE3q5EtoifV6CMEb8BiFmabmGctL7lMn3Z5i72ozqefqJfTDFs4VaA0GveTYBwNAVirjVc2H347J9hqTvebwHCxVblTS5cuicQucmrBESe0C2Mk9bn3QoQPmuzi/3AlRkQ0wYbELQChLXnI0DQ9UDQ5wAxfbUOBC0AQduBqPRJRNCfJTTRiR8JB2wG/6zBCrkmt2mVbXAynxIWXudr4poyyMO27JYiVxgIyKSnXE6DP9xoYy50ymXo4LKidToyHxT4p5yV3YEgijEfnk+Z+4teRz6Ngp9ytgS3EQPXZf14VveWTss1hgmHt0quBVpepp7UJ/2R4FYQhxcfUxx1HGM5YBqBsXLQcZJQP/7j0GYvE2wY/yUN5IlBgBoBwE2FmTliIdB79TWRpsAtRa4wEDAOsFz8XLTEoxEiVeZCUC4DrAySkwosDsyk4F3q4xSstwFTAnZF6KP7i11HPvuE5myJ4AHEYQhZP+ARYz1nnXyEcccZMeFaBCkXLURqgTWrzywYoATiTYRIW+YzIwVHHKtUbxm1VRj/6SRq3J1RAbJzY7qzRVSdbEaohDe7IO4rcECBJgb/O54LeOZflyakjbkQwWYuR2IudAQuw0HK65TXgHagJgBhPi4++aWcvdSAjdKud3JOP6EFW6IjmxHwX4HfCjxiUs+NYTLOiAnXgtvmCF4vaZzy+jBOQoCQEdEUWcu5RygHMyLoKPN5UaPw2sESiBTaZteTGN4nUraFASGaGMg7ASJQngtnlDRgzIUTuAzIBX8UnpB5TQyEffITEGrgoe4vcWacEIh3sebIljjZHgG2CPxWvHqulECECteC2ybWIQUQZX1wh2FLESm5J0ot09ZqOQCiTx42pBPU2zKj7Ioj61n0Rn9yZJPKprT+2ysQfuDG9WZf4wyIIpdO3F6B8ADP25Da0uQjENnSJOI/fQFE9H5BS1IJaanI2RLxbNEP1Oyj5ZQxTEYg+pJrkS1N3lxgpvW56O3Cecb1f0gt81mP0h5h9loQyjnB+8TJtqEVsCXNUbgYJ17fO/nUZZs1LNCO7G/FW9jA29xR3FJOMKpxkj7PpQ4oR96OjbnAdasnim7W8g0bklgn808ZvPmwcEpdmo6eVCrrBL8WlMDnwBaBQ4yxJeT/YbpZo2breWKYjEvTseRaWHu5hTpONK3PPF4cWokU2jKX9Ug9W8bSuQ4nPah85Vp2PNx6uE2/TO/EXLhUy4d6Vg/xL5dc79/FFJ/f/S1A3Im58Cmd3QLE7f27pfQ7AvGdj3bTr7W/deRvan8DonWktb8B0TrS2t+AaB35j7T/cxqwXcSkAdGA+C6t67QBF2/FFddxL/Hfs96PPB0GTmH3TN14O3iMiMlzddMSNCrs+a7strrcad7enFkR4l+UUQy6yo1Nd6r1PS8nUxQ55a+6ST538pVS0Vv40VNxSynQCismf5atBoSvvE0kBLsfr5EBBkKiEgyE51fBT0udABEitaBedayrhGXyrwbnB7xJRAE3Y1cYh8LHsl1RZQ5EkdZCsDH47+QczdqHiEMEYohlrQNBC0C4K4Ho+bYvVypK9af+1FtENzmgWAluBgRdBoK2A0EFEPWP1hYgpmnLMXGlwEvxuZ8DQTUgQjHBmA/h1JDefEnw+K3pamSBmoLbkAPxrEBIQNEfjxzle5ZZIg4oGRuDy1aexDGGjiKjgyjyJiZ1PQunA1N/ygk5SBr0gkszrofTd1yT1p89UHuQEp0uKOBxPAuLY56W495avga5ZGYMljO1L0gKXg3QJin92EnZOMc8D8k1PBvHhBP23pgaiNWSBzMDLAVExDwceaY6EgR+hixNR1BWfB5p5kheYCByNgZmibifKDMjZ3QQgSMyresgYct3b3MqcULAOOmjJwQHLb0ySJy8G18FjsST9FRqjBH5d1vItEe9N+2QMq31UxcZZWNAR6RsH6LSTI9Am8DZcChbziGozAub98ZYIYtUM5dAZoTwMUBNNF2Nw9kNwkGY6UhY8BxSH2lG8LCPTeltRuRsjE4mv/EbnieMDlKOyLwuDBtfKTkhxumQGXG2NTrFmUFsYCC4PAxSRxUgyNgW0A6ZpuV+go/iExtjSDmtfeGsUIUQuZAAws6NM0J65QGYAaEzwvaIExxJ5DBdDXJypqIjkYDwAAJ7BG/WiUowYWOcKPIkxjKHktFBOe2gqCt21JeckF7pAVK3rwPBC+27t9B9kNqWgAjqxDJNK/20zVrZGI4qQPh80LFHcA9zIMBYwf9xRmCP0CEDx4FsaWIeg4tL05TbUAIx/dYEspXXUhMbQ2vqsTSBhJMYHWA+1OqKHe1LTgizIZTQJU5asjQlIHqj9rxr3Z7yhYGB6NLnWlotQBRpIxBYmiJMVSB6TSHLkPGp8nO6NImcFY+xfFAOogsj2w+2UGynulkLj2GIm3WF2xBkFaz9jhCamP6OyNkYWtMx26wzRgeYD/O6hAZ3Em3AY8kJCcJBgRqacDmOB+N6cLnHg7Ye9R/A3eDaBiftYhIlKT8EbAsR+irSCilO6ZEHaSnYGD7mzNvHKbinQswM+CqQn8MIAwgewU5aELXcEvsiW9tozn4IdN0x/5065Xks/4zcUtemNKt8lXCxxbceaz+U45faJKpnDUi/hMMHO36pW+W5ZcbDvYC4jjNyfyDW6g9f0YBtQHy3o930a0A0IBoQDYgGxNeOQwPim4xDA+KbjEMD4puMQwPim4zD39Kcb92qLS37cMsbEF8ORGQnFAHiiiJFCpDjf42YD3q+5Dys1paVu5Y2r8+6k3gfpUdLqJfmqyX5ab/1bpCmlvvIy4evlc7jVe3LgqmzhHyLWtN9yAUgyvh+xkfQoMpg5wvOw3QUUsA/D+nnuVK6Kf5JEYQflLT04FW4mIZqNfty3ELRk1kavyRD4WZD6ytAeF+5zepdFQg8x+o/BETIuxOiBsepz7P7oqD5I4RT5Qo/g6wGBC0CUaaZsT7uBARtA6L2fOjCjAgU03udIqZ+IYEa1Yh4nilSgBxQ8BEGNPh4rHEeVOFjiLwMjqUFqY3qrIq5RkfiaBgXw3Q+DkkFgxCuedYHZa3mqd6FLDmmiXG0B3Gt375MLa1WVY0A7kbSIRmDRkEf9z0mTQ8eL0+FU4rxVqTtb2/geXRaYiCkR2uINKrbmyJGANPCzxQpNHya8RGcfnKmnAeOZSE0qDPCg88gbArQb/oqq2Km0WERaU4HLobpfHgyjxYEME3tItVsfTG9C3xA+vSIPLc/KoH4MjX3SyLMfSQBWCRdxifkD+r3GmAliellTikSZjUeydsbQrMWue5OiAEeTggOm4CDhyIG4qnMMZgqUnT6xHwKg/sIRI3zYDmMlwE2BZxV+H0tV8noMA0Qn3Ex9GF60Q8xIDpKahd5zaXeBWWppLfC+jAlEF+mHkjZLNDWsFpCEj4hywnBCih4eCqcUihv+wjEeA5ASHukZwjqynsDAooYKuRAfq5IceJVLecj2BY6VDkPXl8bL8NBp8InICqsipLRcSqB4GUOQEiKOCPolNQu8ppLvQsDIqBF2m9TAvFl6oFUVQODbrWUQIQkjkFQ8PCUO6XkQHCcns+9QySCSiACxaUpxKUJTAtPU0UK1two+QiDbpdDlfOASaq6GAmIPi1N81xTjQ5T6NA2UtL5wJTPliafhE2iuE+hd0GUaWL0xvGwBcaXqQfRGhmCD7OlKdjS5HMFECh4eCoYLuiF8kgECK9AWM/kO6MuTZ2pS2DrUaaFLE0TPYuBSj6CsBCGOT8CnAdP4EoYL4P3AkdwVuGaarmmGh3gYkARRFo48O8InDOPFmzFpnaRap7qXeBXRuSjoKZjpgSSpT5Iqx2Zx4vVEl1fjmhjUgCBgoefOKVIL5RHwkB0JxjBWVkeLPPjaky9JoTw73nKR7ikcHGttscq38G7K39ZB/q81EvjtdT2m29xlM37bA2NtfJBlP4zgRDnpM8o+Hcd7aZfA6IB8f1b1YBoQDQgGhANiAZEA+Kbt6oB8dcA8X8tSy8pW6xEmQAAAABJRU5ErkJggg==","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"iVBORw0KGgoAAAANSUhEUgAABiAAAAYaAgMAAAAgkEnVAAAACVBMVEX///8AAACAgIBJX6m2AAEGLklEQVR42uxdS27jOtOlBRkgNFKAZE5kZHgVbiAL8CDZj5CRl6Fh8K/yV9Wp4kuULOfV7vtRfW8sS3wUeURSVh2dMqZuf3V7e6t9cPdA2PWsx2H5nCvsxeV1hTzdLJ2bpWnGeb5miI+6za2QlLbLUrnNnedW2tgt2kvnujSHZSDa6V/R4itAOFdKiHKdabyRTSFZUyi80SSLQEy5bCNFNaFGZ631VWwBokmAaJJUaQm2UMS8rrSN1tdB9mpbG5+g4X8FIPrPAmHXgFgfEZ8DIu6E2A5rbgPCfDsQpghEKT9AKQJxmqCg7Th24zRsLs51I/3fXeiqnz7H5+n4x9jpvwulow6gz+fpyJHyjZTrmfePU45p+PHRqYQpzfOI8vhzOtYYzYO/H1OKxlBJSDdYqpXGHGonO6hMS8Oaa+zkDIA4ipVc86wVue2w7ZnzdBeql1KlJdBfZ2Gllq6tnSyzUV1ZG7kNY8NTkOW/R18nLAcQz94iyvX2tjPmtD8D4SmfOzjnLP9/oA5wMvLfreN/hs+hA+jzQOflm3MHC4AP03XGpVk3NNM3SkXlWZTiZERYSWPfLXKQDZRu4FrdwN1sYQdNS8eRy7U0wN2UB3YcRyvpLNuTtyK3HbZNucmuQyN1ojwtgdvlrACtdVluLU74uvI2coswNREEOjUhbZiaDrDqgFxvb63Zmb4NQEzGHj/4f+6ACc8PKujdHj9oken4XADCKRAGDZepaTKkw9XAJkyd9QHjqRQFovvoJOc7m041Id07l3qUbiA76FzDM6yb8lkplUfyh+VytWayLm1Fbjtsm0b0h5N6tSVxCcePZrByXSOFkXrQU5py3sYAhI3+dlKWAkHpKQdy0YhoEyDoWjL8PwNhRmcAxDRPjNM32w3ObAHC0GAe/dWixtMxAWI6MioQPCL4fABCRgSVODgTgHA2BgJrhNPViezMWpHbDtucjJNG6gxAOLTOAAhD483IiOB6pr+HkLLQxiIQ6I8YCIdeM07WiF6AYENodp1NTSYM76mJ6GaDYa5TF6YcmSDQPBlfDc+f8bBlIAC6n5qeedKxMrwvFwbCRUBYD4SlGbDxzdXJwhqd+vJWpLaHaQLTQpianA0lOExNmE6mnWlGH2A/NZFm9Shl2kY7AyKqkyz3QNhgA901nQBEw0vPdF99CUsIf45UHC2ffnFho45DN2LJbmTJnZpvab/hZU4WsmmPkEd5VtIdkeeii/W0JvAi14zhJgEjFLU3/HkcsSxPCywvoHSFy7wrVlLN81aktuttyZTyQv/rDULHS7CWQH/RGljleGqx/A23RpoybyO3QW5aLN8ENb5Oyn3kf6hBbewG+h1xMrxYb7tpNXJN3bK5DT+SnPnMtmiHXbb9c1vahnk57pMt0HbMf1lfNRU3r/cBhLkRiNttL9s3L8d9sQX1WdOdbBWICkTdKhAViLpVICoQdatAVCDq9kUg1nD5LGYV62/utArEr229dNrbK/3dy9E97+1fwTN44nPi5r4ViD4/12ZHTtM/0++Sp5Am+7Yza6X0/D0pts2t7UumzArV2p5e6R9974spwl6fn2uXyy3ZtA/2Tg67Xpu68w2nvaceQPQ43u4W69hlNUVAnPJ+abMeYyBO4jL0R+lbG9mT1xlKaT0QUS0JEDtJ0xdtb2cdtkfxbQ7ETlLsVoHYzWtJgGh9aT33s5S2uwbE5ELqzSLW2cHPANFTYwgIMwfCLACxWwViZ1BoWssGICTBg+E2cxn9/CJO9vr8XFvooT5O0SYZuGV9/3Q2p7c3mnpoatifdzwp0KcH4kTuvL15OO9f8BcpXs/T/vRvKoG+m/3LA3/re/p8e8P3h6kkHH/ibw9nqivN33LHEhDx0b59oDxmz0d2WZ79SbqMv6HUB66FU9AgO9HeaWo12U3HybK+35/3UsqD2CQtmEonRgVsptxUBn0z5vVMl8WUazr+SnkNnUUpXOIL7SF30ksvUv4JddJn3z6pBVzijsZfT+X3OiL6tudhNR1sAcS+J/f2NGNO1+tj2z/yX7pKppR/2keatNqWc0y5e/reUpnT0bc3fD62lIeO0zXeUh6T59/JP/LehqOUFxyHR7Yrz4MNZaPUR64FqekffSUg+n6H4z39T+WQZSgff9Uinh7Z5t15KvOE2p/Of1rqPj5u/nDvaLumfCcjpcJG7aWp+/m4tqKVFNOHb9OjWAog/IjwQEyLNIDYEUg8rPVs38qYbcm4/SuIaoQrVbp/ZSCmpY6BmD6Rh47TN2Es5PlP1ORddrSXDqfP/eysH9yoU+AF3HuZCtupHX88ED26q9/DDimfLGy9RS23nXuBuxtWGPOH//Z85E9LvYNLhWx5ohz90+veaKnaSzgOq3CW6tudUCu3KQYirBEBiL4NQPQ8VQYgaFLQa3c6hk6hqeOEplGZdCe2P9EnXVePrXQRN4xAz/JTBadddjRcS1OB5928ThkR6BIuVUaEOaPIlnNMHXKKgTDn3gQgehMD0fuuBBB9AOLR8PXbMyhslYEt/Yn6ZOrAcx8Bwb3Ex1GLOWMtnHryhFq5TREQbTsHgoeXAnFiVuBOjva8RmIgTzPuIxeAqYlTTCOPhx4BSJ+YS+l4K11m5vnp32mXHaW8rQ73Nj/LE+eJ5m2uU0fEtE1HprNk9VTb48sL7k14MgpTk5Tayl8t/cRt0Nrofk6BoDmf1o4Tg0LnTwa2TCU+AoCTn5qkl+R4y2dagxRtj1qTqWn/sjvr7wgsh7JwvTzxXgCCFk86Ov2Vpe00VUaL0Y6/0wJEKXZT3mkg0mJ9ps+e7z/o+HTmrEBk+Xm47LKjlHen5Z5nZ0+4A0fZCgTVQkv+/gQg9i/TVHQi63Zs3YMsqy2XRunl7wmln7jtWE4pFX3n2VtuZJ/OU7nSDycDW6hcXqTPnPsc9dKL1kJnqE6Ut5M28U3GGT2d32qu/TDzs/L8Ti49jny6Giz/jOqvHO1Xzu4Wy+6zm91dZllp211LwGX0y5a25V7qb/gJfDMQ4Rdvv3Ac+fD9p4BYTjM/klr2uW1/Xqt7XgOO3FhzfdZ0J1sFogJRtwpEBaJuFYgKRN0qEBWIuv3XLo6l/e+t5TdbVIG4ayDabUeDj3g/S7wvHLtl67OyWqhUyDlqAr0USy+Uv71ZR/vHj+UXyYIWRvqOz+yNn4+3NyrJuCZL0aXfnS9hqSRj+O1qTWPTbKIykNqN16WltEAqCMwC7fc2QyUAsZshtTO7VRx3ER+jdL6PzuIJPZMWjLJMqCl4r/XtrRloX0QcQjuDmISxQU7CxmnwGm7Ix++w8UvATZZey5LvQ8hhC+U2WV6bSEFwaXiVl1/tDXolkZX+SbVZeI77TUBc+95nZe2gUmGUZWL45W8AQVfw1AiXAxE+Qy85MwfCpEBMZTUu75wARDMDopmVaxaAiLU3tK4FIMiFkTMLlG8AHgWzE8zTWR/o7j2jQhgQr8SMUCDgIJnOvYI1IQ+DmUWhPI+H+XnaM0lZJyIt0HGwTKgznkejI4L2h4ZfsYW2BnQvnkU/Q14nHg2/fPsBvYzpHKVWPQ+eXOj12qksy0CwDohJFUIMv0rcJGoi/HJxUi5KxIu7ojgy8NQziK6JkVd5h2cuW+uCkge1i52ZObNAP/UI+EU6QILbEqwM9hp7IHrwGjhHy25JPtpjamJXZdvOz7c9s0Sisk5EWuhbZZnQvH+wNApojaD9Bq/KO1bPsJiaDhavpk8doa+li76BsaqtoXoe/DY3wTqV5RxeRYeKQKwQgnHXJGoiGBFxuSiRgPaKI4Ne9PT6/XSeX26nug5W6zoOll+qp4pAcZkxC+izFQYDsRMMsxB0KZ1SU1rJy90YgDD7V0qBuZ04DCkQypxIz085xI/Wt/GIECAwIqZGN4O8mWz5myHdDGgkqACJqmZ0H44XQ1X8oO9WhCugXsDLLl2lLJriNQEyhRB0aJOpieTlosTnOM2ga4sAIWsE7Na6oO/BqVs4uDNmAX1yRz8+0sJw5hldfU3nHtQWD2IKBPI+vaKjMfeDRRHxPLLzUw4eEaEsrBEAYuc735oUCNLNOGRAaPPwBrReuWh2GBHQA2mkc3AnE4AICiHaoamaSF4uSnRDSNPwXRGvNMM2ICbHd84swOeJzxEjgqcpnk5AEfFTU5uOCDn7KFMTE2uUfEMl7AKFJT/PJRCjLgGCyS9gmajpTdjH9OFobrZe90IEfVjvI1b8oO/Q1lA9DygpvL3xnotUMhKFEFlwh1hNRNOGchuvSRKnEXUsAHGgNcLZoCSSADHdoZyhBREzC/B54nM9lt/TjhfrvSzH4DiAlcHsHeZ8yFmQD6fcLVgMBhyPwMdozfw83Sz0UVn4HUGlKcuEl8WPxu93IxZrx3od0L0gFQ36Zo3qb6jiB32HtobX8xjxO4LTyWKN5TZWCDEDLc10QQc1ETqSlosSVWXjCN0OuS+SZf9C61EXxLVIyQOT6CgT2RrPoJc71l3hJrOQevFoWOjXcqX5t/6ydub65hZTl3/tuuQWN9+am+oOaa/8sl7jGTAr6Ru2cOu7Hch7AWJbuVu2+qzpTjqnAlGBqED8rboqEHdSVwXiTuqqQNxJXRWIO6mrAnEndVUgfq+ueXF65H4Qv+9r75usq0D8nHUu/RrYBctchAbudnZcRUC4Rp7C40xZKXXTtp7M5omgnc+npqfL5MUjW5qxuaFkPK3Nj+RbY9ZTwYrjWLKXiQrFfsI2LFm6zEUQ9zj5zIYIiMk766IzOdthHnKjKdjLf4fGxI5+m6YsAKFhMojjwX7tsctzIeOQtiqkgf8iP6Jpm8jiNW5IzugIhjZCL0E/aSgR9JNpMiCaAhArXARmGAUgGvecnJmzHezqpR4DYTIgro0IBYI4HjRqI1syILKLNCrDZDwPZ5tZ7XMOR5qnmUEV9TBbiX4SFor0kwFHgZgEEmmEruLALhiWuAjSxCEdEZb148OZnO0QxyORfxLRpBMuhsYzaSJOhjIlyAaJkyIy78/snoG4eiPNJY4HjQiyxclEEtuAkiVCiusiVgf57zKeh4UTCLFiniHGbq5wQwZIyD9zrYgE0/j+o7PoJxmZQzQi4BYEn4B9rYFdMOiFl3MR0N2NSdcIchMebDiTsx2SeCTe3XmQ78LBcBqPRzkZninhNMaEBj6gsgYpT4GwwvRw/qLQ2C1aTiPxYKxEvlBWB5yjCc/DhQAJnMuZAocjy8MdPK1YXGsjhAXtP/BQnAdC+0kGk8YL0cU5cmrLwMq5COhuq2tDBISx8eyesh2SeCQc7UQDczgxWOOZNBEnwzMlOC4KokKgDHRxZ2IgqA72a/uLImdcUMkd2uiC67/TEDsxz4NLRFo+lgCxwA0ZtA8BRMfLsu+/QfupMc1syh0SN3YExDIXQVzgGRCc1sazaMp2SOKRcLSTHAgfz2QInAxlSliOiyLhOVAGA2HGeI1QpyQ33zZzG7hkM+ZAmDG9upnnAWhHBQIT+To3pDEpENzSQfuv8f3UpKsN5ilhPlglT8Xf1rgIgy7SphH6olY2+OUuZjukkUt0agrfrY9nIkAAHGFKkA3p1ET/KAqLAtHIAAZF0wOR2jDIdCETRmB1AIic52Ekmkojl9C8xDRP4/swTE3TH+m/aXwP6Cf0rr9PAkdBmA9EVRw0jBKO6b1JmYugQHRDN6CCY3ImZzvE8Ug6XYRHRFDphIOBeCZUknIylCnR8B07x0m5aEwTBDvDggrrAxBHz5hIbOCSESEl5mAghkzG8xiwWDcc0wWWz0tM88AKxz04WARFo1kC/eeYXUg2ZEA0hZ8ra5sr/rL2I2Ix1+9sjbfo8za4lf5Ib0rdpjxbevBT22cecWzthO/avg+IdEt/Q7tPtq8+a/pvWVeBqED8dlMrEHfS1ArEnTS1AnEnTa1A3ElTKxB30tQKxJ009b9o3fbKv9PMeolUIG5t3SDuISff4ahMN3a8qAqF41jPS/XYI14Tl2/yCJ15FfToF09DXVKT83V4U33KZS5IbLMpRu2VWn2ZUPIwd8Ev8bbkQNgICDjwwqbP1xvNYE3GWNA96nd9jq9GcWnMq2CGh42BaCKTmxgIn3KJC6KN9bm8LkfkxB8SIEZ1Zt0Dv8Tbcg0IMzMpAsIsPegl/4yLaToCBHgVzKrIgGhmQCjHQexY4IIsj4hwFrUqEI0zbr3M3+SXeFtiIJTRADYFEnRCtgL3ACwPuGUahJ038vKsoTzPwnEgBQoFwnMtBuVVWO8xE10LcpYM+q0RHodyHIimYCIuiHPKLKEJjZxDzMEQZgU5rDzbg1UxtFYFYjJqUIGTv88vmWw5pPwSA88ruBXWhqnJYXJ3YOIYUadgogH7m9SRSAyMgwXHwfLZI/log0NzUF6F8zM/2A96pRy8yxS1SMpLxgVx1nMseBzTt0GZFdQs652dIIKgVgViSjV0473wSyZbLim/hDOTaxR/AxC0eHYfE9Ls5p72WJ1CRsQHuAkKmHIYqLxnCT7vuRYykNG96kPuPrqwRkizpwXsA+SEIheEcJrSoNPewfjwzArKz2fF147532b8EndH/BKT8UuQ2TMlosWaBxVc3jCpwbzHYgjCTRAgDh6IqeAhBkJXFifMheDMN2MOhJOGL3BBGAhnYiDcoMwKAOGMB+KgtSoQMacjBuJv8UtMxi8xxIHAYEYT46nJHSzPZTRj69TEQBzC1ER/n0cBwg5MUImHacSriFkVh9LUREeV4wBq1+AXPAFCJlCy2hpc5dRwnpqM54EQo05qDfwSe0f8EmuC+gds4NmNmAjgH4ANYQx+C9A8RsoSxD541t8HpEpxEW4CMxvAWADnYjDQxghcCxsBoayKqa6LLHN+seYSL0TQkpRDxgW5gFkCjodj3omzyqwgi6CWAd6H3t7E/BJr7odfQt9TNoj5js1tSFP+RdkUyrr1V7Czy8f+W/ySHwTiayn1yl4+9t/il/yYAV9Nub2s+tCvAvGDratA/Eo/VCAqEBWICkQFogJRgahAVCDudiuLnvwrai73B3cF4oubWzrxm+oU03PM6YnkUffl4bW8rWdLPI37A6Ix3uJiT2QPKF2idXIv6hT0vL+Bfj09RAYQo7y/+o8A0RlvcdQTgXqQC0Mk/X4v6hTSgAH7z+lR9+uPST8FxGS1y4AwZSCaCIgGQ+de1CnUZ4f9sGfg8x0Q7uke/8VTEyTwebK+cE+YmAOiMu7dKK/OD6p1Yu5HnQIEGzNiH0Cwj8sFV+P9rxEs3IM+cuLFjzgg7Hy1znlmwOCn6ftRpwgjwrlkb2jue4nIgCDWFIBgdkzCAaHeIG4MpMmaSOvE3I86RVgjjh8KBOgzjSwR/8LUBNUGnpoGZ2zGAUGfdsz50DVClMzuR50iumvyI4IpnNPekIus3dmIUM94Y4KomDPKjgkcEAeehw+qFt343I86Rfo74jjq7wi6Yu4dCOWKHEcwa7VHmjHlgPiletQ4LZgrNm5pwp9Wp/gXf1mXuCJucVlz1nzu5sOtnPt+dYr/yiOO8jsd62fupin/JSD+ya0CUYGoQFQgKhAViApEBaICUYGoQPy3gfjXuucnSitdOL/eLxWIHwFimWUQ5BUMR4vWfRHdl+eixc2t1fZdrBCqZJ0ZAislTsOsnJnmyMKz0KmdQyiN2nz035qxyTgcPtZMtv3fx1L/0HvrvvYSyyAGQiOWA4hmAFvB2EKYDNp+hRVizTVmiFg5ljkVzq5ZbeN6hoihYeAzwTdrmozDYazNFErStqGmTMnDenCuAuH34TcDWyG+1pIuH7ILNLnovoMVUoLLzJghsLJxZU5FDMSMU5FqbQyhNAUifEs5HOQYKl2eyUU0A6IB+6LEMpCGumd5SVe0LjiiCnuRyc8zzOOVSISWH2aF+Dgvq8wQWMkTqedUUAuPnEfzPnurQ7mxPQREKO15VF8cfUuB4GMDgODWuk7qJdvQFtQkSh4X4dBMvbrIMlAgDvwKNyVnf/ShkTWCPIJNMV6J+QVWiE5E68wQWOkiTkU3qvv33Wreg7c6ih8T2aMjAqUdhGmCb8/ZGjHVNT4HvRH0k8Wr9tYHe2gw24e+OTRmhWWg5kOlo2GlCgnkYcBWMIV4JcaYX2KF8IhYZYbASgWCtUYs7Dp+vFvNq+FLYk5FbI+uEaHNjf8GEZcYCI01w5YzEN0H9y7XquwNUvGwYpMoOiyzDAIQvitNAALNKsQrkdn2p1khuGNbZ4bASvEgM6diAuJAdTkTgDjYeLGWO8HIngCEb/Og31wGxNTRNuiN2IGEkKR3RStEF2sen4P2jcmVJgLLIALiEK5GRFThc84V45U0HoifZIX4u6ZVZgislMlPOBUkM4EpSfOi5PSuKbYnrBG+zcm3jMMRgDgQEDybWRFtUdsHS2fFJpmallgGcjd/gW6GMjYQUYXvfb0uXcbfoCv8x1kheq+6zgyBlQBCORXG4nOwmpdKzjkVsT30OyKURm0+Jt9SDkcX6Y1gUZ4++Ri0QlBTwzcBsInj1Aym+HtshVa3pJXh8ptes1ZG/vNtqW63kGdLHWVOxbxtbtVqpHerv6zX9D7y+priuYX611kG60Bs66Tl7XtYIXM7tdxbtS1zVY8SEGv9staXX2Rz1GdN9aFfBeLnGliBuJMGViDupIEViDtpYAXiThpYgbiTBlYg7qSBFYj/wc6sdlYgvr7J85CP5XMO+/7ocY1lkZTTIZctl+JMYIzoe2mFza1Z/ruMkXmcFFeqM7M4KncemiNnWZSjXruoC6MUwzLLoslKaTIg4lLAxABjxPwTjJE4Tkpj1O1mZi2b96JNwZ3DXQp1Y7JzS0CUWBZlIJZKCYwRfZu/cLEM2QUaWffbjJE0TooAMb+Ah7wX/Qu+MYPCKKsjYVmA2eDcBzEmODUNQ5xLI6KkbIicZYFyNBYJR6YQt0iplIgxMvwTjBGJ2cKxVISp4Uwcn0UsTmK2gFdicgaFMSWWBQJSOPdOMRHgEPW8pjQiijHeD+3mLAuUY+zBvwgPZkixFBcYI80IIO6bMdJ479wgrtGDBW9E47NoSIj42HHE9JYxKMwiY4Ii6RAQHTMPzKDRUvKIKM0KywLHKJ3j740BM2SpFGWMGK9ecM+MEV0jOvOugUWmqtL4LBjD8THHjA7aEgaFKbIswGwAEKpn40wKhEZEidkQOctCm82MECklBSItRRkjKRD3yhjxi/UYA+GS+CwMahKzRaPEJIwF1VXKWRZNNDUR/6CRRW0eESW7a8pYFnE8laWpSUsRjQ4wRmQiunPGiGdwXC5KKEvjs8Di9Bh4HiZjLPD3OcuC7v9pWZ0uA0v8g+PIi/Uwj4iS/o7IWRZajrAjJFe5FNHoMOBGWHP/jBFlcNBtzREl2TQ+CyxOj1G9nm2vN1Iu3CJnN3Dl7XvkrJZK+VcZI1/uL/0VeKshP7f9m4yR/+BWnzXVBv4n7axAVCCqnRWICkS1swJRgah21gbev53fY94ykaVUw3/+2qxA/PDmZke+k4ORcxu6pIpbGBLGeZ3kdvrHWy/d3reacf/69nZqb2l/b/a3JG8pR2l7Oj+d9+fruXfnK0AEZsN3cjDm3Iaoo4ebGBKjVw7vAQTh8fbW9jEQT/0SEHRwJ5/h2G4qbOe/75Kz89RrQEwltf3iJbDzRbTtIhA5s+E7ORg5t0GByLUvrjMkGqcv1poT+oK6sQRE3y8BYQpdGwORnjW3A2Guj4hFrMAsSJgNwzdyMMBtOKg6hTAYLrn2xXWGRIiyMnXcaX/u+6ezOb29Pb0SEPtpWng4A4iWz9I3fD7wuSf6bh54AqFjdGban47sDE0pJyrDPOleOfV5/2IMlUf/+l7Scc0KxKucpbR6dsphOPULAUH5X8+wGnbSEaOCBRGzYdDp4escDOE2XCiN9SmQJ9a+uM6QkCgk49TRaDQNg15HBP2jQb/vCSg+2xr5bKdzjy2mJvrkQ9MZ2qcjOx5R04TWYmqiPToyTz2V92imozwJTcdkMppKp9RPZwLiT9tH5+ksbVMdPXI/ncmeP61YzXY+0izr5kyOQaeHr3MwwG3AVAQxBuZKKHtwsaY5Q8JFI6JVIMKIME+v3NUBCJ526LOdzvUCBH1SypY7BpBOXfhKHbh/BRC0ty+mpnKotulzui2YrnHOuX8FbA8GQDxNufd8HmdbrEU9cnNpMRB8s7F/1dk5YjZ8JwcD3AYFwpngxjerbI85QwJRVrBG9NLV0RpxxgpeBqI3MRA9OkNGBAGhV7ICQeWVUvcGQPQGFhgeA72Mn/4k5Zgp93nq3BPOAoj2hNwREI9qJ40xr6cRmA3fycGIiWiQEOEUh5n2xVWGBJ3Qu6aTTjommZrmQLQChExc3LUtuoZmZ5oydGp6eekfd3xPQ3t9MXU8NU1pZGryqblSnZqmo4Dt0QPBuQMQ+xe1c1qDHoXdEzMbvpODIdyGAUBoCtGecLcwJOLfESdDC9/urL8jsDgGIOhsi+Mv1PBpUWzp/v2JPyllS90w3dM/nR/k/n+aaF6ezjvZ2xdTJ4v1C6Xi5fiFepNS+0Vflmqc5cnxDKsAxP7Mt9it2jlNdC9mndmwZbuVg7GW53op3/fLuje3bLel5hzt1vPFsr8z2sd9P+L4aSCu/c4O528v+z8FxP/QVoGoQNStAlGB+MY6KxAViApEBaICUYH4j3ZovRq/fdslexWIv7edvAv+RB38lDw3WWIsULotnAh9tlJkNJS9wiWX8zdtfWKTHtN20JPSp2vsDKT2tiXtasttnPrwtdCHMyc5OQz9uJgc8m18domxQOl2RUPbpJbeCEeiTesO7vmcQREDEafX2na+L7NjpVb28fk2ASJYuJPzfXtK2po3exf++ra3WXe2eU51L83JBHMgzo9pB8+AmDVzdxMQ86M5T2ILEEs1mRUr8mNLQMhee35cAyKCoy2m2QpExHFgZwb2yU+1Z46DArGP2BBlxsL+BCD0GIY12BRPkldZC8RrgCuHBimX/bKPeRLmwU9/OGvYS6apYPcTl6KMC8O14tiDHjPEmHgQNgXZ/srp2P1j4P558OXtOQU4GzuD8337wo4fsDZ8TwkTA7Xszzu4k8yDOH8Cy4O+P6ll56g1AsST8j0CxwG8A9mfXH6GHYk695uEDVFiLOw4HTseW3EiTsP6sYXfltkM7PslZyPzGmTuxTm459UZqQwKXD+PfJTyTp98/On82KrzXxkXpu/9sUc9xm7Jx5b8Z7D9D6ej0nZytbLHWByg4kHuyYKdeKj/sJ191Dto858WY+GRvd3T2Ufe7+Gt64XlAfcoylbOB9gcTycZEeB7BI4DeAe9B4JYDb0A0TMbIbAhyowFSkecCGJBgF3BjvgpRStsBvh10V3gXRg5RyUEngQc91gwiSWBrqNP2GGM73T+xpaS9SYGRzsSNvQeCCqXgNi/opNQHrVFPd09gDCSn8Zt1Dt7bqMCQdc2PNbwlkvHG7A80Nkoex+15sHo1AQ+SMRxAO9AgTgBZw9E3yZsiCJjAUD0wqoInWDOrVEn/KMHovdzJ3f6qTeBJwEgzNkYpQbIiMCVZWIgeqNA9KYMBI/rcxgRVG572klHYJrlv2cdETEQJ5wXHgbbfO6FADAHYn8KQCCdrENntMe3ZirtQeqf8pwjjgN4B9hnIB5h6g5APCZsiAJjYadAtEwUacP8ymwIYjO0WCOUyELdT/MSly2cCZ6EWmVQ0Hku7RFrxLT/2ErZvUxwvtP7wjHusAfuALA2dGpiIB659nhqarFGxFOTANEyD6NtlZH0+IetQ206NQHU1mRTk5StnA+0ZmrxC1rPcAWOA3gH2Gc2wgvNddPxE09NLykbYs5YQLqnmMFwBmDTYsZ8Bfrb8w1Cy+kwWHGOcihPom+VQcGDeQKTjlJe4k7ssNi2lP5Jbgt4Vu5RxhO3Asdww9Dzks88jOn3EaXDOkel7qQtWKyZxTHVQovyk7/hQP5d6Cm2c2q90b54YlaH9ktrol7hOrR1oTU8FZ7R+n3+q6zMO9ht+MWsI8dc3fqFb+W6+5Vvs7T9ep3666Xvb7Hw1pTXuBul++lZniXewfUO3p+3pVtu5tV3C652EU0U14BYT7ellm098UN56rOmO9kqEBWIulUgKhB1q0BUIOpWgahA1O1/4QL5zovit+qpQNxJPeFZx9IDq5mHmh+gndL8MXfh7XXtic2+sPeZZzzohGBHVMMrnaOnz5959hM3nJqOet5eY4v34uaBNsi8B/KCzBYGin/61+7KeCRA7MThrgfVpRlzF4LGRYlMAIbELmFctJkYQ9yCpXLwTinsCLwP+ksKBATR7pQ6/ncLpS9tVILWk7YHbeB65AV56oHFNkdArLSoz+yamZc9OVYfWfzNZIIia9f3rtAx7UKOdnVEpEocORBPr0/JyGxvKp02KuEqEL32z0pp7UrvxkDslUmh7AjlWsDxciJnincGMfOBXTPC+ujxHrJR9gZ7tc9gQeAvlXQCF6JVhsTeCNXAlwneRdCooNTC8QjcjLPYemZSg1fi2EdckWREqBqGMDzAoYgZKw++xAfPPtEjOiLgF2f3jjHy6YE4GamlZU7Ha1QLtVY5Knqk3CIBQlx5zEMwwjd4hOsSjsCT+lpP/H7+YxvzGqjjWuI6tEo8Cy+S74w6Ik9wmno35E78y6FM5V0ELQ0qjuqA89SfbcG8iF93Fy+38Cz2va4RvappiI8bPIuYsdL6Eh89+0SP6BqBEYF6eAy2AALaH/DTE1eEXpn/02otvXiIH1vvIF1sUQyE+IoDT6L1KhdPzEeg5elPu5NVIeI1yBv++1dwKox0NBQtmDMhQiBPrzRr72QNUSC0TPUS6xv5lLqVmtUTvRdrMWXQXzBJdsIVCQoExrdNuCpKLOhTxgo4FugOUdeI6sAUqEwRAcIQw2Un9ajIBIBuuTWoBa0FbwN8juUWFYBQnoQwi86sPEEMhkdiIQQgItZHkFqQmR5AQNFCuQt/QKY8PaZAPM6AeAxaGmQ2WCGe5nnG1dfHa8SZzoMrsgREYHgwISFirIBjIaOB2SdxHWEtioHo2wAE988MCK6FWysEC7RtsUXw4ipNBTwE4Uk8SMOmSYVZG5A6eHnZGc+j0ClNgXhUU3e+W8NV/vKCoflw9lMTjZqXUCbSBo0KHshheoymjYczWCPZ1MRTAPNMAhCqphEYHiZlrODcw7lv+zavYwEInsQViJM5+R6MRoTR1mJaiqamYovYg6taFsJDUJ6EshHOJ14QcbdMglW7s4wIYX14zQthc8DoJ+FX7P0CjMWqFzb5EzMumAcqZYJ3ETQqtHThSQgrg2s1YI2gq5XQyCwR5lkEIPaqpiEMD9xyxIwVIUga1BMW697/vpLfK0ZJmWTfE8inAgRKI25Ka06tr4VbC95GWKzLLTK7lXuphV8bK0fiG7xt5W4tdV7G7sov3rfXhbxtqZZ+0c6318/8su7bpXJv3vIi5r9RP/ertf+GUvvVTlg/p9Tm9dbGRz5Tj5b/4zob97DVh34ViB+ppwJxJ/VUIO6kngrEndRTgbiTeioQd1JPBeJO6qlA3Ek9FdV/4cqq298AQukAXhogZg20/RJvoxw4YZlBkYfaKLM60sLmh+5D0eMJjt/rLVhtiwdCnpieykCIU75f4m0sAbHEoIh1PrgrZ6yOcCY2/qcVPeZRVOJM5afKO/lnZqyVUjmpqbPrwo+IK0As8TYWgVhoTqzzERvfLj9CXwBifvTrih7Xvi8BYb4GBPEJ3t5UUYKZDa/Gszp0+O3PwpdY5G3kyhycPmNQcJmnWOejzOp4CCXxq7bqVPlZRY84igq1RhQ4VnkkRsYCEwkMqX7sWP1DGSIxI+XpHGzbS4qgAML8Cg6OEfEK4L6DZkQ8Fa3xNgqxREzOoKC8OxPrfJRZHW2reh471Rt4/AlFD7RetQriKCoSReIqjyQGgl6mB3flTxurdnhGijHetl5StNxO6dynV4lSEukwQUUimop4b423MVfmKDIoWqRUnY8yq6MVPY+9aByAAfHTih4hikoA4hqPJAcC8Vn+tMoQCYwUtV5s8770/atIYRBXQYEwJ2bnUAXn3qRAyNS0yNvIlTkwNeUMil7lJZSxUWR1KM+BmA77kzIgflzR45wB8XidR1IcEdwTAoRnpKj1yuaISA26RsjURAlOffsQmU2miFqGTk1F3gZS5bFEigwKnpqCzkeZ1dF6PY+dmCxT048qesRRVHjUvlznkeRAPJx1apLgUzEjRfgxOjX1mGaFd8ILKuks0bxviFiJgQymwYtRtQyBp8zbQKo8lsicQcFlnhKdjyKrozVaiuSRBe5nFT3iKCqIvXWdR2I4YBoYHU+s2vHE5FKvaRIxUnZn1KqLNaVAD3LK3qS/rEsE/Ojbwr3ctlTp7d22vLdpdHxd0WNbK8KvGLNa9g3KHNeASLdtvI3b2B3rrI5yWT+n6LG1rH7T0Rt5LvVZ051sFYgKRN0qEBWIulUgKhB1q0BUIOpWt3/t8q9D4R8B4sqr+vslzsKcpbHw8CuNwNIvlNX7uvqVmvrs++6ccyr0W+xjp2PhJa9Si9JyUs5IuQcCS2VfVBvZs5uIxSPk+LS/GnekLYWgiExccva3aVSTneTbzbRB0sAfy0Cog34ZiN0MiLbN7dsVgNiZNKJSyi5ppRMiSkCxB1Ixi1NbLq+PjvIbgGJyWx4R8UX2WSBM3gF9OHEjEL0+cl4HQkdEyqL4GhDB3iVuRgAizhNYKleAOCmI0/5q3JFTKRZIiJMi7IVz4Go8xJoeL4HZQGoeD8zTiGKICBAhAgtk1h8yHRCOTaJAeE0QDWTvORXgfryQswYMixZ6BOcQDWUnPAxssFU0Es5Pr6SSrx0H586eQzK1ItC+F5LCA0dTSdPTFAsWC72q/PKSl/eg58LRE/lFkZ72V+OO7IqxQDROiupRiNMvVrTwsUXUjws2hp+aPM8ji8ByQhmZDkjbn/zU5DVBTAgCIO5OsD0oFRgWT+cQeoDZHTRahKWCSaYX1oXXC/EdZ0g5ROwlr2Hwt0++TFFRiNO3Qh2AY/RPm5cn+gOn6OiJxCPEkdozEMtxR9piLBCf9lWnC+VqqKJFiC2izIZWAl0ACIkhYjD7hwgsTxD2aVMdkOmvXyOCJsj+FRofXKtQE5BXQs/wsZ1yNZjdseM2hCmE0u9iDZAwIl7BNFF7d2YvbBX44P9k6QEEM18YCNEf6UPsLmrZU3yUR4QAcUqAmMcd6cuxQFrl/KRABEWLEFskMBtiICSGiAARRWAhjoiREeF1QKa/8YgQTRBmeUgcFM8RMXMgfBAOE6IPKRA9NHQeFcS44/QCIgChK6LMQQCRppcRIR07jaZzev6xhaJJOIo1Aul3JgFiHnfkVI4FonFSHqOpKVW08LFFlNlwUiDaEENkp0CECCw9ysh0QLzpJtIE6R+Tqcno1ATJkwiIVqOhgKzzAMWlEy4IXjde0hEBzsfUxkexVzVKJGxNPiLAIYmmJolcF5+XfumNSYDokZ7vmtbijpyKsUB8nBTRo4i5GqJo4WOLKLPhxLmfmK+wOwfNjjQCi7BETKoDAtrjk6cwGq+mERbrVsKY0W2CpKKr2d9m7AzSMIfjhN8FzFeUFUBq5xYJ56Onb6LV8SI8DxkREAGL0xMTRFgsLzveS8/3wtsIR/E7Aun79Pb1trgj5a1Pbk2Xb0r7dlmzozfrDv7r7Ir18/FtcG+2qHKsn7leYznN4i/r2+KOXDd1TY1ijd1wDYiv6VbOqTVfK+8ztV4Bom6/u1UgKhB1q0BUIOpWgahA1K0CUYGo268CcTtyaY570nn5SVt+vC0ViJ/qJ3McjOniA1Z3mviowwlU0Ax6uBv5+7hYvEWgC3zpN8VAebrl2Y9wPHY3PS/aGidFXlz+hHJHBMTczR57zIPdzlGXNwkQwCKBZwAwqMA6Teo4qbUhYSOwSSmWuQqifNBuioESO+pzjkQQi0iBaNsCQmYuDyFUgK1xUnC8XYvDMpeSaFMgTtr2AETU8nCYurLJRgT69XkGRCMVOOuBML7LTVZOAOKktJHdphgou2LTFrpCgTC3AHFbnBTTmm8GomiZs93YTFe/c934PHZjd5mmq5GmHOpWPjIdb2gSGrpBgegudPQ4uinf82hNx+m6gcbR82j425FLY+WbU2ArXI+BQtFYwOdglYyXJBIK8zu4LM8qecArvqKOEcdKictXJsfTbXFSTMJJScrW8ubKGqxu8qIsEeh9PAnXBfEpHuR7pGbirLN0rTvnrJ323UGnHALiQEem4w0dGWhEHEfOM6U+WAKAsk3HLMqhXIcpO+eidAfiKuwitsL1GChggHhNgN5EkVDo81Hf5RdWCblIySPYKrujD0oYqt4R64hsj5PydOJ6H0txWPp0P1HWIAmBvleWCGLUcL3iMVfFj0TNxNnjB4A4flhz/HA2BoLO0nEaMzQ9YURMqRylpKRTn0/puw83HcX0NB2gswalqaqBshWux0DZCetiD3d/v38NkVB2sbqFZ5XAwQ91jThWSlDviHVE9n5BvR4nRc/O47BEuiQzZY29YSA8SwQ2wEptIb5HaibTVcuzvx0cz/kpENOIMHR8AmEMi/U0NQ2UMgDhOF0AArkoDXMVTGArXI+BshPWBZ2FFkeIhAIehooqeEkGozoXaayUoN7BXnA97qNCXI+TEoDI47BE5c2VNWhqOoElYk6Pes5rmojih0nUTGiSESBkMqG7IAXiecQkYwakUiCcwZTlFIhDmJqcTk0WU5PpwcQAW+F6DBQBQlUyDClYBFYIM0UgvPPY+6mp9WImcayUoN5hojJviJMiHJNSHJZQ3lxZg6cmYYmYE2l/gICXjAiFRxgs0+8IWlaPvBzzonuh3wW0WPNqwMvwBITjs2Gxno5OHc/LMU9NF12sjwSdo2+NLNbTpWNStsJ6DBTWw4j0OyhnYIUgRskuYpXoYt2aPFZKUO9QJocqbYR7/bU4Kb15SjgpWdkm7KfKGrxYn8ESoUWO7N2xlcoWhB2xmsmVzSXfGn9b5mwpdRP9Nin8tDHmEzFQwq3ulhglb68h3VJEFT172y/rchyW5fwqHfZNoTzcgoH4Rb200cj4DBClo+Fq2RqjZCsr4zZbynFYlvMLydp8ExC3GL8lR33WVIGoQFQgKhAViArEXzS+AlGBqEBUICoQ/9tA1K1u//UtMCrYPeHDy2ehNmZPfNJv13LpA7jlOmLuRlkvgLaYASEuszhpawqvYV191tNqPfwK7mshGsvMMd3n59rlcks27aM0WRgbCc4RYniIIz1nG/Rt3D3igDHXcu0iI9I6NG38XHMLEK0Hoo2pBEkpbRGIJVmLPYpvcyCCksgaEAWmRwJECGSiyiJpwBGTRUnJOmludv4O2hyIUq7fAIIVP7IBsgkISfCANzh7Vf8wptDoftYLhcAtaQ/nai0+JI988UCEKCkP/PqrshN2RbZBb3ysE+JTSCSTa7l2rFL/UKpD0vYq8e6ZD+Gban2ojgZ4EWBEPDBD4gGvC5/IH4aXb4l78cSMD+WEqFpIzOwgVQ3imOxFMYQ8avT9wcdUIZUPc2KdDQN/G1Q1/EvJJxGmnzM9TsIsOaVxWahEVjKg8k+qXxKxEZ7Iu/r4dNLvuyLbYH8Ojs7HFl6nx/ZaLgKi5XR5HXAgQgfEiJ7HLoqp8igu1VbckrTB+/ko8S9oRCDiCQ/4lnU0DL1Wzsd7zwlplW0Rsy/+QAACiiFn8jHvxJ4/zA6BkojGgAEng1U1pFShMwjTg1sct01dwlFclke11PgoLS1zCZSNIJEajH7fldkGrXIwEMam3ZSLgfDxJ+LUe9UsEE2O3ksvhG8oq/dLDngR6jPDOX0ZvWUdDQUClxkpfzCHQpz8MfviD7d8z3wLI0IofRsHt6EjGgOGa6I2CaNjb7TUOdOjRdu4LWlclgBEy+on1JqImaCdpOyEXZltIHFTYiAer+bKgQipjYwpVtkg9Q0VUYm+aVkKhNIFQFbDiGBlDmFK/OHQIjEQqiuisVRiIHrflQCiD0BIpKJepF3I8kdcSCf0G9RCykwP8FCEDZLEZfFAPHIJrQQh8lFSoIphAoOixDZI9GdkwNPcv54rASKpw5fQqyaHlyd6jIloCoQoWzyGKC+0Ib4JLRIt62hIqBzmQAW6WrA4xFH5A7WPR21Ra04eCFATqNw/wuU4cd0MrzA6TiZVHwlMj5OMoFMWl8VPTVP5mruNo6Tw0Hkh7im+74psA11ENdYJxxsx13KR9EgrGjBpHVoC4qaILVFMFTA6oIAB0hjfMBAnRIAghgTimwAI1tE4IUIL1fYgJbUmxIPhv7zMnoRjguWUUkH9Q2OqQElEY8CcuG7ojQStEPA/cqbHSZglpywuC24vWOejPYl2yU3MhOXt6+7x/qaUffFoqsZ3vVW763W1axFm5jX0N/ZnlvLrWhS/CYRZBMJ8c6tQxjIQ8xpuY3r8jgpI3epWt7rVrW51q1vd6la3utXtf2P7bqWW36Kz/OdoMxUI2ooPqYJ3eB4zZDGSysatz8qaRRcx9FIxvwjGb0Tifb6wBe0Pl5VM36f09u3NuqmEsSnU7gUsHF42sy4/i6OoxUVHNCNZ0Ix0/O0ttzR/l4pKCWIac3tcGYjgWA9AzENVzAN45OEt2kJAjBiINHRGIboIv3RMn81AEizpO3s2k6BAE600a0o/AUF/rfkKEKilDISljYGYvtmSpY23NVY6ie1Ri5ufA+La9z4raxZdhN+HhLwKXXEzIMwcCOOBmNI7ulJ9GUnjbwDCrABB/xy/3OmMSyzNYU+6f65W4tNr6PegVIGYJ/7sWV+A5fNZ3BFxEr2CLyGPgZk/QSoaEl8lP88RUpKy8ugixgzPmFYGvc5E7WN8HqkB+DyyeghNB4PtWEGEjk7pBx4Rg4v0RJAXr1nSkcGGjkEK5z5GkT2SbqIc6P2Qbvr/Qq86U3Z+3XkgaYzIUtUlMd5Ww0omZrJxRBmpxaRe0l3YTchvL3ulCgj6y7XbBhciWBSPSZQFZWmQ81qjpMBtjxgq+oJ5cp4jpDy2K9FFppn1IK/P6xpB79XTa/QHi28se8BaIQTTYBvWP6CzuFJpjgeY/Pq+5EWHUq4YCJ7epwv+XYYBjqIWN4QjU+lTGfRyP72ZjtedpzVgiC3tWCLAsXoJbG0gAjABwaoOM4tJvWSCG1FIUqWKNhKSIrfm02vvfcZJuAujsVDYp9yDShmAUM5Eeh4RUpIYJnl0EaMzr05Cz9OE0310rHcAiQqLqcnSdNCZdzRL9aNknTlIGXFenkWmXO8xEJTCEBCqJyIT31TLMZpSpnH5gW62YhmtEVgD/NxpqayOOx+20nkqF6Vbk1vMKR24BZlSRdCrIJbCzrMjQAmJgUDUE6G7CA8V/AmoaIDNkJ5HhJTHdiW6iAdCZ1DH2h9mnAPBKcYUCKcLvgAR50WHOpMCMZUy8ogwORDxiAAIZSBcvMiMpFwSA0FnUbqsa2MKxDRlapSUoFQh9C6jsUl2yvJIRoScFZYG61D0QihhhsIukFfy81wC4rcsRBcxquwxKBCk7nFAJ0RAyHdnL5fGf6NccRlQGHFeyAhnLpe0y+dTkwDhEiAO+D+sEU7uzbylNkxNERDT3uUSBGdiixtcTrpYB6WK6YoGX0OW4ycfVQVARHFHfCwU1aHA0SdR0ehbVchIz7O+klmLLsJaHknzuhF6H2gM64NMK4mzWPqcO7L2RwyElgGFEeTFYk254g4W4a8LltP4qIrl+anpAtEwAWKqh/ZjS/XG4OhtPY4QIiOFEpSaWnyUVsy2XeEmc74tRxcJC/1arjT/b/2ybsx3bu7bflmXtU2+uIVb3+1A/q8/4ljXNvnFrT5rqkD8E/VUIO6kngrEndRTgbiTeioQd1JPBeJO6qlA3Ek9FYg7qeeHqg/5de/rDfr3uv4bSqpA/GRJjv6Ab6Asidyba41yJCbnx4whkT4vgfuj/BRF8x9jINT3+wXeBvmNf563Mdk5budtlFsBizN75cHfwElxxJaBYJcgcySC0yWUkvIXnMRpCUE/wrNPn3+IgBjN+GXexuh+g7chD7638TZKrfC9OAoDZBEIswwEOBLGFYCYXakAIi1ThK1dDkTjGvdV3kbzK7yNJmeY5N1tlh6323i+cFSSzAJyUOKnIHKKOl6IgTDjNwzKkYB6vlEewqXj6Coxf8Epe4GdMXRe+QrgPrhDE2mN08QCoL/C27AOdIGf5W1YBWIjb4POoR7L5X14iyfAB9jLva3RIsAocBFLYsZvGJQj0XjvF41ZjsaS8ReOg7gIHcaF5SFLfAXJP7kKzRiAmMpwX+VtOCd0gR/lbTiBeytvg2xBPceR6n33FjsB4mC9C94I66AxsU94xm8YcCxeI7oPK9FYUv6CU/bCgJsAy95b5it4flw8IhSIr/A2prJ/gbfh4fYzzjpvYxoxH8rgoBrevcXUYr1MPRA02TAQhxQIF/EbdBmOgeCxwNFYUv6CU/YCA2FGBYKmCk9UjNYI5ZDqjPsZ3sbU2F/gbVDAnlt4G447n+/uIiAcl9RI3Bo//QQgKJBHAkQ0hBtZ1Ym74HQSOKDZ1qb8BefZC4K5lREh3Aeesmhm17BqsnANCsQneBvhFuIneRtai7f0Cm+D8r/LmQAEW+yscBFhBBYsB0aBiVgSOb/BeiCUIdFwRBUfPyXiLzhlLwxYrKe7cAO+ArgP3YDfEd3QIaxaDsQneBvUhp/nbWgtauk13kbcf9boTUMMhDMF7sAWPkH+m3A9T5Oldckv68bEa8Xnt3+NtxFb7Eqnt/AJcmNu4SBQ2vqIYwMQv2FMBeKbSqpAVCB+oYMqEHfSQRWIO+mgCsSddFAF4k46qAJxJx1UgbiTDvqHgPjNDr6n7btb82O9U4H4pvLKPIz55h+k2YiZYI1/MhmzM+i5axO4GR8h9eeesSzl6dLztvvePvNMkekp68fyg8TA00j7Ur/59tP2EZ5iZx1b5mGEnmsKQFjlIQCIMScFyFuXyngwzQoQc4EEO7excA5OpxSI9aeutnCkKexFtglTxNm0bO0XcRv4LFlfWhtbJ7kiv87a1eakmGZuVAyE3xeGwwwI7vyc8bBhRNhih60B0XwJiLW9wBRRL3yexmY58r68CgQ5TDr8XeBh5CwMabBTdkMHTsRFGA65L/rAQATGg6Qm1/qzsDBo4H5wvfhG5T6zs35yJTlwHDp5LfZ5hFNI2SdwyZDDHpYq76KRtCiZrk/US+3suOzOM0JQG9VOZ4+ejxFqD0yRyZU8NEwYeB7VSsoJRok4nMac2+GEceLYWYRcVB75/sCGYXc+nPrsxSrwMHIWhgKh7AY+aokeQ+5wnvMidkZ3eWZWg6wRgzg4DwTEQTgadEG885A/sI+QbDmoj3qq+iDkBsOyDmRrID2oP1ktVd5FI+5blKwqGJPFzgmTzFllhKA2aZ24dA82rj0wRaZLaOCyqf0W9IuGvc70ja3nUtO+hOeP+jS0jT2VF8+GmQabANEt8TBMzsIAEJSG2BsNcyScFS5GNiKgiGH9EG2YQYEO0nwdMx66D3R290GsEBeAEM83EzjBqYiA6AzZYL2lyrto+DjleecjRuqlsjtQ06wTlgWgkV6QFjkb147pBMIS6JVmCJSCBuwPtmOqC5ak3A4rXnIT2sYTeJiapktgkA4eF3gYtCUsjACEU3gMgBCGQ0ylxFWRAIHU71bz6bdGvnXM4MiBMKN31EdAEM1SbJNl0V+J1LxR6jkIt4NGBLdGUpocCL83A8JFQEztGA4ZEE7IAQ6WpNwOixFBva1ta0wKhFUg3AIPI2dhREAcgtnuEDEcEnYGHRlSILhjiOMgnIwDd9dBgDhI12A6cYF3RedkaooEd9g2lRbxvAvpHEB8UG4KrRFatq8ddBlRiZlmnMDHkNoDewW3Q5iankdM2AKEwAL2SM7twHlaI+yg9UfUU8P8vIYXErAeSjyMnIUBIAK7QbgZly75HaHsjOnvGANxxIJ2AZRYRrF0d5ejfAP/gu7JwRIBS44X1guWXDknSy0xtdlSE3gX9N0q8fGi3BRjUToztj0jBLVxOy5UtvIxtHYwQUThY7AGi7VjzkeDRd02I5geKD/ndoDlQpMW8vLvjQ/tnfj3x8qWszCW0n0fO+OzyhTueomfKjlisW+qbat9X/qlvsbY+K5HHN+vTOFL/JL4yF0Bsc3Q+qzpb5RXgbiT8ioQd1JeBeJOyqtA3El5FYg7Ka8CcSflVSDupLwKxG+W9xUjbsn7cxB+Z4m3lvWNdVcgfg2I9H38/MyMcZBs5AbFNiRPc6anj4M8AiRn6azgsOtmQNBzSs5zIwOkK9ShHAwu02xhYYQWqZsnSvYB6+b9UehDEY6g9Mv8j1BbUkiT9RSKCu9oLoNoMyAsv/M3gWhUWSDhZawC0fFT/60MkHCqKQChHAwqszNbWBihRS7pHHXpdKbEwAh9aDMgOpPzP4oANmU0PRDNChCp9Ml4yIGgvM9Fs2PDnJQVgPB5bmCALAGhHAwq89lsYmHYdSDmLWoWgdD0Kf8j6z+wEeD68K4ho+wKVbvowDg4UKYP70ASZ9IAdwzYCZdLfJaA6Nhfp2YnvIwLeBekiSHsi1gmxQjH4QoDJGd+NKaLztHxwMGgMhuziYXhW+SYu5LzL1gaQFuU9qG3BPWj9zj9sNx/wmVI37NXFoOzqnbRgHFA+hnwAUPtwmn3Os+8SM/qiGjiIAKBl3EA74JePD+IuzJZIy6gIqwzQPA3sCMaowoeTnQ0oigrhtqwhYURWnQk7/Qh51+wNIDT1+tDH8aWoH6JvEI1j8v957kMWOZSVYlO3tCXuVvmuHfhJ4Bt0cmCpuyE9KyuERkQkRcaTX4XRki6WMO1fo0BkjM/Gu+NZtaGkC/BwWg2szBCi1yRfyFrl1EVA9+HkSWoP7Rmrf/gjtfpahqGsaqEGXVEpEAgFdgWxJOImRdDcvYWIMCGmwPhEiDmDJCc+RGNCJyFhQkQ11kYoUQFIuVf8N2cLPNxH8aWOFMGotR/7I4vTU1oHrgHqkGBoahDS9kWMjUJn2JIzoY1wt81xbyMQ+OBQLd0Ef+j4VPXGSA58wPWP4/SnkMsEkFlNltZGFKiAzMk4180PkSbtUkfRpY4mUjRKmVslPuPF/p8sVYWg3IPhJU2dDwUB5ssNbpYCxciP3scKO9x1N8RCS/jogs9Fl/r6yHTj6TXMVxngOTMjyNEsYzwNC7wVwMIKhP0zGssjNAimmC6S86/4JI+hIER92FkCepH71F60fAo9l/EVMq3//sIN5ZlDYpUPqR8dinv/0U6SfGvic/yP9wqodqYgoLIjSUul5X2oeb7v4+4Vcs1SD5cO6sGFZuBvOX9/MhvPOLI6/86ENv4KvM+LOt63lrDxqp/Lm991lSBqEBUICoQFYgKRAWiAlGBqEBUICoQ31B3KeDMPXfQbSX9Vmd+Q89VIP4CEEvsi+l5iJupa+C5Y5Fdgc2FXVFbLpwxscLF5Mx0W9gV+iitzK3wtuW1ZAeUlzI93U2YGOwIXXh8uFS6WDiUe9KkPWeuWLfMviDHykxdA6r0RXaFvHibARFpVCQtDQoXU5njFnZForkxc+lTOc7MuRW2CITjF1NzAsAyEL7lhW2JxxIDwd7CFeaHWWdfNG6mrgE+QpFdsQCEKQMRFC6knjSbmbMrrgEh2h8Zt2IOxHJqEz+cNjG/xLc8Hw1mmceSyGHYZ2PcAvPjKvviYF2uJTBVOpTZFZ0oaKjKhbAY+AXzEB8lMDmUXcEBftwWdkVjkLfMrTDsm5tzKyLuSMSsMB4IPd8g5ouIu8/4JdrynIkxLPNYuuTlf+41M2d+OGeusS/oFfFUXYNdfgv6Gkb0AlTlAiwGVuE3iHKSalwou4IOQIriGruikbxlboVxGkUl5VaEGmNmBR18HmNuCetxHITYNueXOAUi7a01HktyCTsFYs78MNfYF8a6bESoZlGJXdF9xHFPlMWgnAZiSOTSCsKuGADEdXZFI3kXuBVeTynlVoQaE2bFEMEmGgPIhaU355c0g5OIWmlvYZIt92RChxga0cCaMz/MNfYF3Zmka4QV8qBLgFBORRz3xJkYCOc1O2Ig4EYEdFvYFTkQKbfCmgiIiFsRaoyZFXbGLfHiFwkQyi9BigITwyzzWGIgEOKjxPygEXGFfSHcjYhdQeHBlvQ13EFVMlzEYlBZHmVIBCaHOvU55Jjbwq5IgJhxK9S2nFsRaoyZFXHqCAg/NeX8Emf0LitlYqzxWLqk5xqR+JoxP5y5xr7oBv0d4dkV08Bd0tdQlQwf98Qmi/Ul1bgIQPBk4LawK2jVsiJMVOBWiG05tyLUmDArotRSqvA+VGAl5ZdQenRk1lvDCo8l6bmjBBOcMT8um9kX3xf7JN9udepvLanET7nOrMhvk6+lD7GXyj25xEuZWbeVffF7jzjcN5V0jZ/yPY84Qm8t9WS5566zZxaqrs+a6kO/CkQFogJRgahAVCAqEBWICkQFogLxDwHxUx32b9a/fHF+pbM/0aoKxB0AAWc7sy1MWZGDUjjZp89OXPTp+/jN2PnU/gy/gDtPa0zQ1fCsi5Xa043fYaMXlH25koSf/jZjXJ8Tm8s25L3AGhwajXuEtkfM1Ig1OsgCduP6zSXt0l7txtXYIsF1L8IeA/EQykIQ7FePKmuKQGj8lXCmUV5DfCR0p9igrIu49sROl9prxJ/RFIFgMfGbgbCRJokVHw3e404JAkEqo/Gx3vMAH00EBHySq7FFYiAa0cJ/LgDRbAfCNIUR0Sx2QgCiERZEDERc+wwIswKEdOrtQDRxVwsQz4tAmAyIZgaE9qqzUVwS8BXiiCKqxcGMCmFbqH7+s+cxPHumxLOU8MyDk9wvWiUitjyPEDgfIsJKZxD9JD6CUj6YVdFJ2HqwKPTd7NjO8Grys7yYTPaS81MFgfBXY63A0RTbhigtiQ3K3Uj6Ra3Ai/iNFwFIOS4aimDgscIq/hyPRpkhmLo6zw2hXhVvMByI5BQ0PpKCanEYz6gA20JnaQueglX3O7gbVo6w0/EQGiaRGTj+irMxEOhalxzh0ARsTwg+0AgLAnogsZ3hZX3hfPDlRQSZFAiNtUJAHcfYNm73kL6sLKmTflEr5NX1UUUAUqYGIgYQEJiajuL61YgvKimAECfoVXbMq0ud/LDElbCJFkf3odcP2BY6IiyzMjrvigcBgI8aX1UChEY+oZoSIKxGQwlH1B7ERcFZsCAwkaV2YjoE+wPuzNKI0FgrSk0II5DOHBMbOk2d9Iu3YtARgdf4U44LzpJfG0A8Cw/FC15IuzqJQsO9OiRAHOIYKV6LIwYixPIR3saYA+EMjuVA2MFHPikAEc+cAYiDxEVxen9hFIjMzggIYmAsAaH/UiBgrxvc7NjBpv2iVkhwjwH7KRD+rAfCScsxQ4R4L7AdvZrEJXmniB8HH1tEtTgOYFSAseZiIISVETElNJJOYWoitoUCcbmsT03Oqj0hZBNYFI1QFmM7425mGzCjloA4aBQYmwPEQaDyY89j2i9qhTP+rkmi9cVMDeV1XC4ChANhDpNqmJqoTO1VF8clIT4OR4FKtTguVu7JwbY4jhonSnkKGnGk4blQjlAZyWLdGCySXLYLZygdluNwBIyIwSJomFhowIKAHkhsZ1iswfkAp4Manq8FIQpMuljLmXF2LOsXb8WH/o6gfVr3EqbGB3qIgrQdEaeF49GYaLFGDBu69ZVeBakhVt0I2/99pD9Eln8Drgff+/zmNtX/U7WnP1BLVtwWQab0+2uhVW7VrN9/xODupH63YMVtjzjKyhv1WdM3WFEf+lUgKhAViApEBaICcVf1VyDupP4KxJ3UX4G4k/rvBoj76pDfsPz7Ov1H+qwC8SNA5KyIXJOjVCjxDvAE0nhFjvgRodtoXpTOpjGdfb0u+Hk7SafOalIL2VKfD0ZiiWNBb901s9pRX1SPtJTS+wjdIz93TRgb+qTVWM2X9p9L+mxqzbDY2/kzwawgGxoTojrjbWbhW4giR2PWgbCm9OyxiXrL2rzzpg3Bwnm30RgsenLQtKGcZU4KVD/I7s4DEWp3UXCQmGHh1AM9YN/YlCig/mnj36RbAoL7bLRuMxCpkkR4c1835R2o5LgqclwH4tqIsIXUjXtOO2gBCHMVCKh+kN3PhREhr+gmQICxIe0EEOyhToBwORDjoazjQX3WuJXeVlbEs/AWUiUJODPAQuigU6G8A/HMqiJHw8oVCG0fop2UuCF4/VWYHUaYHxe4mpArkkRhsgKONojBIg4nAPE8xraZIicFgEH1w7CEA1qc1L7AsKD0JjA2Bghj+HmfeuHgHVXsTrqINkeu40F9pm91l3pbHHgOnKvp/1RJQuZoZiEwu8JrZzTyurYqcrAeB7sbQ7STMjdksEbdswOVeZBX0JntYNPRAX0OlMVux4NofggQeBldNDScKXJSAAQ4SWR3I2oySe2uzLCg9Ea1SCjvmGlrjNJ/CMJjlfIw1/FgtQqv2zHvbXHGK89gpiQxYPlSbzM1FrwDMwt1ZA20J0K0kzI35N12HEekm5ZA1b4QYQiIm3xkQIiGBjhCSKtACGHAqm0lTkqYwpSZ1cxrHzAR5wwLTj8oYyNfI/SIEQELyvUuEVzmcWKaQYEo9bayIoyeypQk0IhRgaBBB95BOq8qEPQtinZS5Ia8a5ST0V+TJgYipihCnwNlNZ7fUQaCbCtzUnS+Jo6FApHVngARGBZW46YM2E+BsCYAAVqFOwwawWUWJwbCMUu9baLJR09FShIqCmVlanGezaF6FUMKhE2inRS5IdP5g4ZTaniWxnTjgTgY4+VDXGCUhKlJzikQyoowS5wUuZ8Bx8L6qSmpvcywcNLFRvdtxtiwgVVC1pFkRJANinU8+JJ1drG3jbAioHcx2kxlgqRRwOawyq4Q3oFETUyAQPSSKNpJkRsyLZIXVeqg4GLOhMWapyZW7wArYron84ySIzND2DI+dxyggNGMoqExljkp1BEKBNl9HGWxjmsfygwLTv+hjA0s5TFjo4tYJcxbsdx/w1zHA/dtzWJvm+XNZZJqMuBuj3Vy5Wz5vArqbD+3HFMl/AJarv0aw2IbY6PUZ9d1P65spV/VdOx3gPi6vfNy14Aobbc/4liKkVKfNX3J8vrQrwLx1wqtQFQgKhAViApEBaICUYGoQFQgPt9n32vyz3TnX78if6PeCsTdACGsg+wBFqnWx89TnE9PqQPfgTzZjexti5SSKlYY0iQP57K4KaFO1b1wwqFwZomPAcUL5VyIzv9YsiWUNWumty2ccLPAHZogRIvRJ9XxthK5t8DUGLsMiCaLihGAwKu+3s0+woXCe5sipcx0hG1wELnEgpLcgvOEgCU+BhQv1NUvkS/SKDL+ReEZy2NIej9y5i4BwU5kHy1GfTfxVuLHmCWmRuMZDykQ5WgjTcR3aITvwHFSNkVK+T4g1hQvUuaJs6XL3M1ZHqtApLyX0KNxtJj5i4wzfoxGBCkxNaxTxoOyDlhhYyHaCOLvgO8w7Q+6ty1SihMXCTQ7xDUjGhbOaP0mCaBgfBOfhXsx+WpXFC/g3TMhFowNeiKBRRLKUm5II2wRRF3pIr4IAXGBI2uM+4mgi6LFHOb6JTk/xkTMghlTQ18ZD6wDfo19KdqIC3wH54TvQMyFTZFSjqM4DR2cn+4QNCyOg9av73sLEE5n/YNGfhiW+BiWNTLAufCxYMagJxJYJKEs5YY0+jI/R10Jjl0A8W51/IZ+IiBCtBi6qHL9kpwfYzQiSImpoUAE1kETO9rzaCMu8B2cwxrBzIVNkVJIscJ5zQ4IEmm9wdmejgiU2chAp3RHs8THQNSWNObVc6InEsgLWpb2BiLGaLCPwDkJQICXEvpJJ7Oc8RLVN6S9bjQiSImpoTzR0BFzIEK0ETJD+Q5T1+I6NOCLXo+UQooVzmt2MCRewyIGImVR5EBMIyIBIlW8UCB09uc6vZ5IDoQbtDdoPXY+6krgnITFGryUuJ+wgqSMl0S/ZEh7PSxvBaaGCVNTAOJgTDnaiHGB72AkzJGTiCzXI6XQlMRjZhBFj0PQsMiBiFkUSueS6cQt8THkjiphnnCdB+WcaA2hLOWGMBBWo67I1GQTIA4awicGYjApeyPWL8n5MUYjgpSYGsShSFkHR894mEcbwW+Ho+yD70B72yKl6MIJzQ5drKFhIZMYczw4/mLMohixDB6x1NslPgaYJ13CPOE6RU8ksEhCWcoNQT9p1BUs1uCL0HgnIJSXonbaCIip3qEZcv2SnB8TRQQJN1Zfizay9Mvamc9tbhbpcF33YrPixadqv21bqzezsxwH5CcecbhPNia38Hcfcaz8Av7Rej9ZQH3WVIH4nQ6pQFQgKhDfaOuvFVCBqED8TodUICoQFYgKxP8sENu68fPCH7/QhLsq/VvM+gkgmk+c+R8FQiODHCNuBPY4vju7zAIQXu23yIaIulmPD4tVD/4ZlA2cC+U/sM7wxxYOSPpESL8F9odaKHV8oA3CL5FWlJ4quU39py1IhQ+6hZTNrJ4uAKGRQTQ4hXgTrLhSmPWQ+IrhxYjYEMGGaM8ujwA7a0Y4p/wHjqhhb+GAeCXypBttdN47l/jF2jmnI40n4wqWp9+akIr7ykaUhbStViyyGWXB6huB2uXPZSDoquFrM/YVCxARG6IIxMpVtAaE8h+oHrONA5JddxuAIDeWSzgdM5vtphFhkxFhFy86D4SZA2HYpcEcDH17GfvyYjftkUtjyEbE8My8pZgNoRwHuH2eRyhqCPPCeH2PLFYLndNIJ43EMYn4D1TPsIkDYuLyIe5On+CEqOw7e8+pzgFtELaRtsJITBavKnIUez64ZFUXidtBUVOOqjtymf4ZH+dl1MgvcZwXcaRJuXBeHVllxDjRqOhYZB8cjMkDFY6OjbAeIqf9CBZCzIZQjgOuv4NnZtgofAWclxqrBXsh0kkIUaD8B6qnGbdwQLoxLr8bUfqRRRcotXBEHEZEJ21wLuZ0OIO04G5glB9EK8GAaTFrx8CT0QE8jgO1wWuO6GvvUZwXuHDRK/pivp+awNlQjYom0p8IWhMhkIeuEUgRsyHUtS6eWXv8CF5gVr5gzYk4VosG4dBIJ4ieIuHRUJsoJF3ngBiblK9xLJijQqmfEelFgDAaKcjFnA4NBdIIlwT2Q12k+0CMi7wd79w7fEbaoFIX3Udj5nFewHrBEZTmgQBnw2tUDEF/ImhNuAIQXKE2YQgcBzb/cIAggwfCjM6AfBnHajnko4U6ZUSnxEBc54AYm5Qv421KwzwNyxaaUYHQME3Hj4TTkQCh9tPne4gQk7UjAKFtsD4QSQyExnkB60Uiz3BpYUR4DkYTczCMcjCowEGnJGVPWChUDNoEFzgOhGJ3eR5jXkQ6pH2sFos1QiOdhMBOnv/g81zlgCTla+kMBL45PzXZcHuScTokpwAh0WZExkWivuTtoKgpMs0cZGpSGw6Nmcd5OYiISwDPqloIOBvENDiOXnNiAJeb9mjRUSCUPaG/L0ITAseB75OtM7pYy9Qki1wSq2V0mpsjnRxlIQtABF7HNQ5IWr6WztI9nFo4IlMdfBf/gTakQGhMFl7aL1D2AItjYOtUXSRuB0VNaXCGlmouX2y4HMd5nBddrNFObh3nmNLmnI21X9bXo4b4a2v1fDmCS17b/KfQbdstpd/BlnM2vuMRh17r39lV20r8bOl3stWHfhWICkQFogJRgahA/E7pFYg7Kb0CcSelVyDupPQKxJ2U/uvG3UNz/kpQmQrEfx4I8CaWWRNLChecfky5EINdYHXYlNngijyHmOXgNlkd2xLim8ytpzcdVWWDLAVPpBnTyDDd2HlrRXek6HpPrN/YsrV2aOOZN8HsjMTp7QXOFxQuTJBB91yIwQadiSYDIkRcb5KaYge79bldcr6Z7YnVkS0hrIbWEqy3Log7AAhWVzBpZBgv1uBfY58DYXPrr7Rsbnl26Q2RKj3xJpidUaa8LChcRDk8o2M8xIIfJSD0ulkAwpSBmO+J1QqES4EwmfUpEPrOq8/juRwREAhFXwDCLACx3LJiQVE7VG1iUGbDc8o+UEbDUsSRgfxgqb4FqeVrrJPOgA/xIbLvCEHfGbAiGu8eiZkOyv04RlyH2JYQm0WsViDIFh/fBEwLSYnX1mPFDiP6HIMHwnM5GkRbIdfQ4OSFXHUKQX3kGFm/qWUzyxNVDm6HRiLhK4SYDYeEfeAZDQsKF5QD0HkuhH235HE6qF/bacwISIMcR7xI3siL5XOmg3I/lEOR2mKi2Cw2ifhDtoT4JrBTUgo3KlLsMMoTec4iwzgo8DgJRCCO3Gk1GUOcFtgC67e0rGB5rMqByRFv6wtvwvrAFDmjYTCmqHAhkERcCIplYsDNABAaZcWps55egDcwGZNBynRQT7dyKFJbpFSrvLyU0hDim/CVrSmHMEWJYoeRuyYm/qRcDo6M4oRvIYwUjBWN02Ij67e0bG55osqB2kVtAryJBSCcWVS4sHlkFV6sjfH5LWt9SCwd0CXpLmWU69XMmQ4xEG5ui42BcAtAyMo1loFwQwDC5fb7elgbRGg5AYiDtwXWb2nZ3PJElcOoTAQbMKRCVDNGw0LEEZ9jmANxoPzEo4gHMMzNB3DMdPBA2Jih4W05hNgssDrmloT4JmFqCtoKsWKH6HPYPDIMIqNgahqEj0Fp4jgt1pampuWWzS1PVTkkOEzgTQTVuxmjYUHhIuQY/D27AkEswaMsW4OoXtBi3DAh8igL9JzpoNwP5VBktlxCbBaxOuKWhPgmsPMY6V4kih2i+xT09oL9R5AnpzIGo7Fl0vgwTWT9lpbNLU9UOYyfcEyYMxe371W4+L5tG7fk+6x3P9cUfS+gPuL4y0B83rD6rKkCUYGoQFQgKhAViApEBaICUYGoQFQg/pnu/03xk1vsXrPgs9b9cqv+DhDNl9P9B4EQLoPZEvOD/LzN2Pm37ZpR37Zr8Ebap9U5nCmpVKxpdZh2+sdbL5329kp/95Jqz3v7V6R8OvPBVsvYn09yrNdD7QIQrSahj7bv40RtnquPS1zaJM/OPL3SP/6uXIbObIn5wREhjAbsYMKFaBRYKFt8Wp3DJWdtBpEpaHVM7W21L97e2p4ahuZpM2nvqQcQPRrf6tm+PcmxEhBtCsQp4EFARL2fALGTNH2x39sZEHsqTstQLsOzuRrzI/A2FAjRyoiULT6tzuEW082BEPbGCS1upw64AkRv+j7rjb49P34ViB1lzgbIJiAkwcO012sZymXA1LQW80NUO8j1qZFTaH/QPfZ0fVqdI1WpAIMDk+OSVsfUDaf9ue+nCeb09jYN8Klj9uf9eccTD316IE7m1Ld0bP+yNw/TXwLi5YWA2J+n7/w/HaXy6NvT9P3tjY9Ox3eUZzo2HZ9qobNPyHGikmnvRCVNZdPxvn/gUqRUKY3+wq7XM9lNR6gFD2cqY3/2XAYAsRbzwwnT43nUyCmcb9Sj7kvqHKlKhfWO0mWtDhoJfcuXeq8jYvrOk890sAUQ+54gm2bjMx3rH3fmkaf5vv3Da0TfPk7H2ylf/2i4PDoyXdntVGYb8kxp6O+00Vna77mGHZ1oCYi+3+F4/8il9ChVSqO/XP5U747te6T856nME39XLoMAsRLzQyKtUNpBdWwg/oE9r3RhPqPOkapUWIMQIICsrNXBMzKA8CPCAzEt0gBiRyBNKR+mhXH/2rcAD0D0PE9PY+W1nc5SQdPfnvba6TjlC3kojUxlDMR0RJaIKe3rHw8EoJxGxJSXJioGxKBMnoWmelu2jy3lC6YNQDgPxHLMD4m0IrwELNbOAwFKidN5/WZ1jlSlwsISk42dVKvj1AsQYY0IQPRtAIIm4R6p0aknWaypqDO6qudunuZ/TjftngkI5DGnR6RpCe5eRoQ5Y3pvuXMnSE8xEFO5JgAhZQoQvVFbAESvQLgYiMWYH6LaoeSRosTWoEDcrM6RqlRYG6vXLGh19CcA0bZzIHhCUSBoKufueaSjPQOgQPQ8KXEH8tQ0ASGTCgPBeWgmn9K0fkRM23RkqolKnlI9vrxQd9I01cdTE0qXKarFaJyAOKFc+U73AgIEOA/XYn5AtUN1OObqfwkQN6tzpCoVjYhiSVllrY6pQbyUnvV3BBZrWRRfnnjPA9HyUv1Ca8X+jN8RPDXR95fW6GK94yM7XqxxdDo+XeBcjwCxO1OdtFgDiP3LNBWdqOYdl0a3A2QJ55fS+C8v0iexexpfZ6Si7zfE/Niu2lG4Od2ozlH6Vt6+8su6b425rYb5T7Q+ulHGRXC91N32Bq1t21U7Snmd+d7tK0Dsz98DxGdKvcHMranrQ78fbFAF4uv5KhDf0sKv56tAfEsLv56vAvEtLfx6vgrEt7Tw6/kqEN/Swq/nq0B8Swu/nq8C8S0t/Hq+/5mtfDHUrQLxPVv2zKTN9/r8XOnRVjvL7fPuozRLfAk56E/vs+Pe+cn+fiYDSPn0AP6oispxJjtTHzAb3vbxUSagSsJv3RZThD2Xn7PL5ZZs6kpA7KSLdqtA7OYoJEC0vrTeiDNxBYiAbgBil6LbEzD85L4nUJgMYJS9Af8ImhX1fgKERj1xxf6xsw7rIPpucyCaSOVjGYhmXksChNc/MWAKiF+zXxog/QyIvnw1Rz3cpwn0UbGSJT4LxIMAQVAwECec30WC8TEQrD3v0s7YBIQkeIYKB5fh5hdxsufycyXlDhenSOPA+JftH6aHt6/s8pjcGZP395WcFXT0BA4C8xHYzQHuQeBB4DizE05gLDCron1S/gKXODla4Lg/LfMlJl/xWR8ig38BB89eeBMYoT08ZCfyVgf2BoDAy8fHUdgfpG0xPPPruPyyL7NCiFNCihidMEQ0LouKqX/QS8x8hPyPFMuFvhPD5ENdV9NxH11lQClcIqTiB3kZWPRNcJzLH4R/MkBvRCzgEkmrgAXgH6eOm7yo019mFZg/7EV9bMFcmBp/MuL424lbETyIqRs842Fn4A7kzx6chV5KwdSEc4EvQdAEvoQxrXerhJpaLhUjZKqt358ViDZib2CNwOv4VvQ7ZMBPXwdrJHwHkRsOEr7A2qD/cbAS18G+RyojHDNmAMPkOL4zwwQEC42uwhFWoOshpYZwBVQPR3txqsWBOhvRG3EiPHFQS6leas8fvtZ65hP8aYn/gG7Yv/bmifgG/dPr3rvClQex94wH4jy07EZ/ep0WVOYs7BmeAES7wpcwpo2IklMZdFZy6VS1O8UjIrA3KEiVrBGIKMHUTFaDMN3HuwdCZB0copgE/Q/40CHvQMeJMdL4CFo+foQF4c766CoW7JLJZUzKHcRI0VKV8YLjsApnVW+EjqpmRw7Eo+Hrt2dQ4GCnq5rZD+3+1BPbweQ8iL0wHugsw0TL80kYEecEiMd+hS/B64H6t849L/MKhE5NcMQbgzUisDfomoyBmK7TEdO75c4lsYcYCEQxCfofMRDOd6VGcgmBPERAwkdXcRDEIL6K7RCvJQKCpkocF17KCFYK9EbAlEmAOAgQNGsT8+zEoFAXngwxF3gCeQQAJz81CQ9Cjrd8pjVIITc36dQ0lX9a4UuA/UCElGRqauMRwaD1AkQf2BsQbfF8EwvZH1okqHkU8cQZRD2JpqZI/8NrZUxADEZ1NZBq8EDQnP/MIU00uspAGkwHaGwAgMFPTSLmIsctn7EGKSA54tKpicrnEd7i1ufpfJr2wXQgYiktxsRK4EX6zNyDc8SDeFGOAp0hxsLJBM6CUBT53+4MxsUSX2J/2vFivZfFGuyGHTMcaCM2xjQ5Tr8jjMHviMDe4OXvA1cgRSdhqasBQHSXaSoamKHCahjPsqzaTP+jG6CzwdobFyynlGowYJgMciN7HAcfXWWgaezSiVYJ5zcatUU0RC5ayyDslMGEWlWzg8Ofjf5Wqm/n7vDoTnZ2y6rEErNxW0+5m9W4tpV+WTezW8Jw7+/stRKvv63h5j/t4jtZW0pvNtQ8K2F/XgNizk/Ake28hS8yHK4CUeoe3Urvedy6IejgUk3zGnBke83fYeOvb/WhXwWibhWICkTdKhAViLpVICoQdatAfKLhX82RS5jcY0deo+b8NZsrEL8DRPw4y5Yrz5+EFF+tiqKKvL0NIfCHXQCCnwbTW96sJJBtXWqPnZ3Jnvy4UmvmZ6/2gTNQJ1nKR+fE5iFOUarBbbfCrgARHOv0zD89UgzAYUMMEwBhIyA0VQwEaRSw7oGvPxabWAJC3+VeB8ImFjqTN7BZBaIZ0lJtBIS32cUlz1PmFtpFIJTl4TYAYcpANPFRF0unjIcARFMGglU7WAnkLwCxPiKOH8tAeJvtNwLBp4RhwLwC5h4QL0FlxukvAZFyHugZv7AljI+EMki8kslz9fZ2uXTKqLjEqeL4J/GI0Drxmi95rzpvDzgRyploDFgX3ub020VjubB4ehaZJWZQdP5oWj61l2zqmPWhLhzieOBlzjAi0MKllIErgpgycXwYTRGzPDTGB9yGB44b4pThgBfUCYiY83AcG89DkFfYncYYAcPh7e2dXY0HcR2GVNPVxD4pklaP1ohB6zTCjQCfgjzF0OHQIAYqMwGbDz6wQWiBvjo/hHglPjJLzKBQdRAtH2WRBxo2iWvVqmv1XSJmRDZzC5dSOrHOStiHYIWRFCnLgxkGiBJy5CgpR889ABuiMwAi5jw0XlvDeGYCVJzAcCAgoKwRIoYgVRgRVkeGwYjwfAoLHgU+mQsRYpAYBaKT83TMZC2AqgdZgO8amSVnUIDvoeXD1qOEM+AyHaWg/ynXO6cOd00IzIEACKWUKB+KJKpCQp8dc0t4L2F5MMMgMBqYLyfcA2JDWFahyTkPjdfWwNwHZsLBh86gxdqZFAikCkC4BAhfpx9FLgnjIXPs6IVXRlzvDtocaQu4buVkxJFZUgaFA98jqccNRqfPka/kcRotzMB459QRENYLUhRTonxmHw7OBCvIVh/8J2J5GOUeQIWDB/CgDAewH1RzQzkPBAS0NVRYiP4bmOWALmQgJL1MTZIqADHkQEjZxI0gbSbmUxwkOspBFW4YCO22w/MYdaJvAU9NHPtLIPRdHTMoPAAHbTfKd9Z3NE84RCawFhNOk48IrX2WMpqaJKZMFB/m8K41RywPYSqQaoYujo3nGnRDw4t1HvOE41IZLNaNZyoQywEcBgKiA3NCFmtNVQaCtD20bOJGGPAoLmwP63CISgiX38jCO50xnV+GQwtoUWyEXAklEI3MEjMoOs+1QPlsKx+TqWlk1gfJh5GqCBb/IQBxHNDCcsqwWFvTiLqIjw9zGQosD7O2NVFnZT9OeHA15VvILEec6vovawxas2lz5ie21CaX3Dqv/bLeztn4ZI5SxSVtDbea4xYgtnIanPmJLbUptWUNiNuZGDfmqM+atgHxVw2rQNyJYRWIOzGsAnEnhlUg7sSwCsSdGFaBuBPDKhB3YlgF4p8w+3/bqrtWt/nfA2L5baSmsOc3cmmEuCZddtbx31hLV/1VSXrvVHZJvpApjdfhZhaktXT+W5LSyTfbFTtB83cz+00s5LAY3MItd+A4zxHHgulMwgYZlIrA7+LF2xD2hpzVIC+KF5FS93coeHrEOwTOQ9a0IbjxcyCaqCHBqd6klkSlWvmWlDO4vLSoZ4JVTWa/jYCwG4Cws+vYWm+pFBCOaR+6yAa9JGwORNyYeTUFLkUGRGAhkWMwcB6+CkRaZ1yqlW+3AKH5vxuIOdXFZqkak7JBQogg4raUt+lMGtek4Xfk1UXS+JfyYh5CMwSmh46IlHvBqSaUwafQmCgR02II7ImI3WA+RjBB2JIh5m00Q87caLJIK8reQBSXwLRoDFxEWhNzQC7K79B9taZb4GUERw/3D/dLZ5SFocekf9iLrWwQiMwj3eXi48hcRIDe4fNyMWlcExpWzOTwR1FUzEOwLjA9dI1IuRcIeTCAW2E0JsrBivvwwLOjsjM8u4F0LuD35hhSLuZtgFcRMzeaLNKKuGMlioswMRzrB7hgP+whCw/C68K+E2twfM7LoD45SJ+AxQLPvbIwcMyKZY0JbBBjQm+9S5lGmB1wuNLnu83imjQyEbA3lQWksPzEbIiY6RFc6TH3gpd8rpa4FSEmyvED//OI8OwMZTc0Iq9w/LB+4gu8jZy50WSRVpBeg4eoX5lZJQ45rAn2aN3gfOB/9X6XeBmonfqlQVgTsQC9gGMa74UvZp60dZLV3nq36G3wN8RCI0C4JK6JKEPQv4MzPkLKGLMhUtYFqsu4FzTchne5otA8HhFcAkgHETtD2A1+RHheoIt5GzlzY8girYjsSAwEue15RAgjJbYnAMGqGiYGosDLoGmceSEpEOgFPQbmi4wIfwsd2BoDbB9FvYMtRISYwZo0rolqpYCTEOQ9Yh5CzPRQIFLuBacamEdxEM7FgWZuF/E6PDvDsxsIiGcMcQUi4m3kzA0GIoq0IiQ2mwFxiKYm6+056BHsi2UHE+DIeBnGaCrpdD81QctDpICMn5o8G8QIXMzWsNoDTiZ9MDwYiDSuCbHwJJaJLFSdX6yVhxAzPQIhJuZecCrHw/vCzAxmXDiwLTjOSmBPBHYD0SSZCTIqEDFvI2duGJdGWkF6jeKiP6b47CWyn+2Bhgbu/nlfyjaivTHnZcBLj56yxtNRL+gFPYZ4L9SHgQ0S+CGN0EC90BYsHIu3r9Ht21yzrrgpENc4CW6Tq999Q4pg1dbNXemDW2ou2bCk1bFp28owCECs5/gXgUhbtK3mkg1LWh3futVnTXdiQwWiAlGBuLcmVyDupMkViDtpcgXiTppcgbiTJlcg7qTJFYhZxf8aPeZO7WrMVwuuQHyPXcO1Z1FdYEXY9Hj8DnIuoZDszx+Amc8c4aP0ov2GBl+J4Vy0Km1b1PabX9Ca2++u29Vk+/pAOmZ5yDkbn4ECh3qwUQG/0uvb6bS0WcQRZ8qSDSU5BZsB0WQ9mZaj7wDGvJOFvrSlFDbpE2m7jQUwmqx/lrB1s/bZxK5VIEqGN6ZJTsV0nFSnItfAcHmWXwBCR0TMO/k6EOtdfgsQiSpPxisYTFCpMEF/QzkKjXinYgZDx8cTnQr2ZjFrwsRcDWFNiPKGukeWtDOO/kXZktZFACJER9GpCtFTjswLCdoaeSqoYnxEDI48BcTatQ4AQfZLVBYqXaxXFowpMEpy/on2RWzXlCrjFdBg8WyEoL+hih2NmTMYnMVwDWsEGA9W4o5AUCcwKBp9WVxcmEvaGTi2pHVBXRW837BUPLnkFHWw7d1G2hpZKoQqeLfGMzhm5RjlbThpu9gvDtJ3iavi+8eYAqMk559oX6hdhsMtmIxXQBh9gNAFL6zyFNiP/REB4RkMjhU44rsmcCKsCdFFYgYFeBXWsyuWtDOsRDIpa12EERGUQprBd6BzAoSyKeapELzj3Xo1jlI5VutA21Fnx0QBAIF2qc/feP95YJTk/BPtC+9k/tDwXhGvQAJieJaC6m80nmRAYyFlMCgvI9WpgCSD0g9iBkXDHJDJv8txSJa1MxSIstbFHAhobeRAOJMCEVIpEF4MolSODXUEIKCxoUCE/omBCIwSk/FPtC+CXQAi4RVg8Fl/1acxR2hYkkM+ZTDo8RSIyYnvg8CkDAoGwlofOGZJOwPHlrQuIiC8Ugj9J7A7nTwibY0slU5NqRpHUo71QEgbo6kpAHHQ/kGpOaMk559oX3i7DgxEyisAv0LZCEF/Q7QrLsRQMDZlMIBpEetUYNVpeNEDRyNmUByZA6L8kWXtjEYkp8paF1gYNXRZFB2Fu4HJQHIL4LU1slQSRcUqn2SeohGGC2w4ys2Gxluh0o/SLukfLjVnlOT8E+2LoPmRRC/8RPSP7MY3/WUdUi2VfKt2xbb0bnakqCXyiXLMF/O4DXaZ74j+kQIRUi2lv5XJ8Fnmw7084nC/ZVd91nQndlUgKhB/p8EViDtpcAXiThpcgbiTBlcg7qTBFYg7aXAF4k4a/F+y66eMQbl/r6n/XMidJb2Kr/FJ/mkg3OKZWGdibes2leoyg6FXMUs2yBtu8bEFjYBwxKXl2pXu+IhFJnLyyjFptXWF2L0rDyCpRes1rz41cws1pDoTa7Y0M70VuwKEquWLXkWhXGubdGTYgpCJCZQEmwAxlWspOEKcKhW3WNHIGBLlFueygDlNbMvMIACxVrNLVCSabUAsg1/S8chTXAdCgx8UgMjLXBgRZSCmcl18XS53R0EjY0gqmwFhVgeIdY25UnMppzguNmhPfIwp44OcIspMQBWd170gdkPgYzyPSxoXOiLiso5SomU1gi6JeyIqGJA3dx+edxGYIs8+8omZXFXQ99BoLVoLunpZIwOMrmfpiSnlB+z/YMcV8Tcofow4lzQqinI7aO9azYZKftYXq8H8cJu1J3IlCeul+cGp0Be9vVKG52PAGYpoLWk9ynaLyxI/L9frfcHCtIAlcNM69+55F0HVw/rIJw1PEO9glHgH5kEICasaGdx1+qr71PVcz3GkdMfxwFPmgXsmREWBgonyX67UzG2HfolngGzXnsiVJKzEVemiNUKZGU2i3gGeRqkeHcJxWVaWaAtVi4847kmjXUhUA/cuTJKY/QEGCpVrpTskikNUC67LZY0MjAhcKgyEKBW8e40Eq5yqSJXECetF1qiVmp2QgqbcxhMPOI7PJu2J90xJwmpclTEAYYWZ0SR8jIN1GgclqycC4hBYDmYMQDgTxz1pwjcGwpkQScUKH8QZAOHi61K7QyLBYI1Y1MgYUiDcxQPBgUIaiR8Tl6FAOBOAWKxZRgTsFSAQxGKL9sR7piRhLeKq6KInQFhlgAQ+BqUSAZKsHg+ELwtRXCIgkrgn86nJ+SBP1gY2FZU7SHegdhtZrEAsamTkQBgFAoFCGoP4MXFUlDjYDa0RV2q2fPYQGDLGbNaeGDIliWaUuCoyIojl0HiRrZiP4YTbMK9HgQhlIYoLgDhiIR6DcsdxDIs1IpNI7Bev6sHskEGBgL4HxzWJLMbdvFvUyDjK1ISeUH4H/97g+6ejxI+Jo6IglRVJrfWawR9xnFsZIMk97VbticArWk6zVlKoJ2Z9uIWb4Nu3Jvll7ZKanVlqb/nI/LxL2lTK4a7WXOiV+FfeVu2JwCtynwIi1BOzPraVtW1bAiKt5XaNjPAb263muFbzev/+ha0+9KtAVCAqEBWICkQFogJRgahAVCAqEBWIn21Xbcb/Zsv+J4FYVrMoPUXR1HDdfI3tUD53nQMxF04IbTiOay2ct+j/PtbPdEmLv8b2uNIylznim+IZPR58D5C0/grbwRRrvs6BwGPMWClEBdfLz0LzFs3lHezimSZp8VfYHs2Vls2AiM4UjheAMMuGmPUB4kpnNnAgZroZm4Ewi0CYLUB8je2x3jIDdoH+H6tKlLgG4kzhKCdfZjsMUMPI2AzXORBWY8CoUohjVgg8fJ3EYYG16MIPcfo4o6wPlAuRdH4JuXiG47FELf4S28NcaRnYCqwOkatKFLgGEm1FYzqMX2E7NOIyzNgMZgP7QnJbZnegTMuuUh8NximjAiFFUL8zyvo4WOuvePbcF8+oDoe2+CtsD4gKLbeMpQqIh0CKEJmqRIFr8JxEOfka28GW2QzGXGVfIAYMM664zGcujVI9azQYqH14IKR+r7bhfHdDeaN0BkDELf4K28NrRy21DLyHgzi+50CkXAPHLA0/IoavsB1cmc1grnIgLGLAMBMEdrO2B6WiPYdAI0YYKhpkR84EfRHpbhMDkZzBuIta/BW2RwxEqWUAghkFdDBVlZhzDUAg81FOhq+wHYYFNsMWDoRMTRY5MRGx8IMT+hqrfUwz+SBASP2e9WGhtiFT08IZ50NFocVfYXs0Zr1lDAQvY6TAkalKzLkGshhKlJOvsR2GMpvhKgcCNhxHqF04C/ZGMyJUVydiV8wb4XawIodfZjO1DeN5IIUzndwIaIu/wvbgv2stK95lRt+d+cy2je2wVPcWDsRSrWYhl9sg6ri9zbezPTa27CtGlbatbIdyDVs4EEu1Ln3/3hgmt7M9vtayv7TVh37V3Nqyf9jcCkQFoppbgahAVHMrEBWIau6/1rK/03V/G7DvkoH5xnZUIL7ejg/wHMq8DHzod/qaRlTpzHbtCeTU/UFctvFTm7Xa82gma7X6t/ompw9Jv+vTHV+GlHMc8py3MUSmZ6lkAz89N8ZHg8h0QRY3K+3Am4TqjhcX+5DyEnIgGokBr0cbs117IuaBNB4I1dK+VrsG0dDUa7WGIiw8RtItjUaC0QSzbr+NITJ1IL02aZuBo2YkSiEu7/Fsz/fgsAxEZlYo08VGBpM3ak80UWENGBEW/pAEiIXaG9kPQCzXGq4cuKMTCxaBuJUh0igQLh51twIRNEMGvP+MoO85LwHmdoHnwb5ifnl3eB411xbtCUQmCfvMiGBmxVHcPIu1X9TVQ5aE1Eu1Rs0dyE7KBSWQRiLBkP9MgQiMD3gltzNE4G8jMHREIL4KlT7YWH/kGEWOgT9OI8rwiKB2jAY+LOrSEi8ByDuOB0L/69QkL6Y7DetxXXtCgyTp/jtcjhaeNLtWu0OOwNywq7WmQDSkxC9xTRoNt3AIQATGR+aGvcoQYRBI1sXIGjE0Rl++H9iqA4Yuv0SNdll5nZ9758CjjUc2+/UmrJilUOIlyPBktgT9H4DgVJLrqvYE5xYgZB+ppxTWRjFcirU75IBOTki9VGscgoogNBYe5qPEg4FyRwxEYHzcxhDBiLDRCqq6IEyo4T1ifOgEpyVpzBnVHGFRI74OBr62/SyddoUT1o9GVGnAlxAgnAldssy70IAYYV8c8XJ925Xau0Fyky9rtFcVL5aAcCopYVIgYsbHbQwRrBEuAcIFuQyv/KNAaEmeZjAiH5fBHeX81JR1BZnObAuKB3LwU9PkjB8UiC28iwMikvAsLPuDTE3gYggZrFy7xDMB7yOkXqpVVTwaxsCF0DXR1ITzHghmfNzOEAEQQwoET00hPsxUikSPQpQVr34iUxOkKmgPvIjLscxLGLqB2RYUD+RCixcrbozGDhy3RJbNa9oTF4m6YsI+MyKwDI/EHlmtHbmZ9xFSL9XKbIqB/k1HB+VuIP4KIsFQJ9K/4yBLOBgfw60MEfyOCEAcoQRyMZhOUetF7UWUFVU/cVYCzjEQVz3qQVXPJcdz1Y5tvAtnbtuamQLe1lob06yqeszPO7uuAlJiiHzul3Xx98gN2ZNvOYI/yU5Yvlq+s9YtvIz8++eAmNdUnzV9Q/31oZ+pQFQgKhD3UGsF4k5qrUDcSa0ViDuptQJxJ7VWIO6k1v8UEFvSX0+zvdbvh+xOA/lUIH5oC1wK5TVEbAZyyljPWaDtIzVp9T0ru8S/QKZuQ+c5n0Lt7AKHovjUqFBW0gLkmfE0bNZqSUtPbZXBYW4MBn11C+9No7fiToWut3eiJ32NfMFPFU4uuczXgWiSzrNzQkAChEZ7aeK3/mzaoiUgXFyijXNGadJWa7lDYHD8CBDh0yYm3gJEswGIZtYxzQyIZgZEM4MsrjUGoslqbTYA0dwERGBwfJugsWpxgGSmehQW7phRfLo+CgqzGYiPcHEGbAYevAO5aCQmyoDhu8xdEP7FiOgr8m9Ayk5k3p9HpDlK5BW2i9NQHJVnn8IKc4KAeJbjcPGgVj7LvrTnMeZgwNX1HGKwxByOOE3S6mfpGzMEBge0EL7+z1gXWBCkHAGHHqtn2NjnGrEZBmIgHAdV14CvTHkbSrLyntoZdwFXqH953vuzD95NCb4Ic+jEcXqwGBEHDlYAixv20HHsFtK7GCxzK6gBuLoth4s6MNeEJrGUg0Et0BxO8uQ8jSlN1GpN7UcEMziabxoQ02IcWBCNV8lgDgMvUEdhIQQ2g/OBNLxyxQAgnF8A17gLmLM5ugq5F5k3gbEpMiQf3Qc4Eh3npMgrKsygUSMQoYVqZf2Yj0Yd89YKbazj70wWcEgZczDYEp+jkzzPszRxq61nr2CNwNRovw+IQwaEVonpT0dExGYQIKxX14BJXlXCXOEuYPEcAYRjdYsYCE1Fo4ZzmnevGePDd5gYCORKgSAehsA0IGXCwUi6dqqf82Q8jazVORBgcFCLv2lqCiwIYS9YqTpMTX64MpvBQI0C0VOsUL2UtyGkmRXuAtaItamJiWeU5mAl8so0MysBTKcmgzWiUY5H6FbxdFuVeJGUMQdDWiA5PNvEzdJErY6BCAyO4btGhItYEEfRo+Cp6aKLNVgIgc3AokIXomupugb9jvAxUTAxrHAXsKYohyNfrI+6SFKaSyORV9xknyynF9AZraxMTIq8TIs6JlRZSo3UKloanDLmYDAvxOdgMme0WIc0catD6uMQGBzfBsSt3Ioyp4KDK3lCWdj+7yPki/aLt6+5VXEaV0jjFn/yNbNL7fpv4Bs5HD/xy9rdlHo5gsg6gyLNd+sjDnc1xXrNX+2yMvOiPmu6udb60K8CUYH4in0ViArE182qQFQgvt2+CkQF4utmVSAqEN9u3z8LxFebfe9N+kdlWioQ92M2Py3+v4//++jgTLXyABAv0Y4+qU1z3HOL1hQ3opaamIkSp/mLQIQI7T6ySMSWCN//DSDWFDeilpr4SS5EvwMhIiVS2F8wm11XbJ4RCfIZENmIcH/z0tnSojXFjailZg6EWej8BIjvcPPl/5TdEJk3iOz5RZxN44cyLJgb8Z18iJ9q0ZriRmhpUCj5GFXRAy2NWTKU6lk1RS4aw+YHrh+wGxrufA2Co05QeALfwbDAS+X2W/kQP9SiNcWN0NKgUPJujcRoAZckZslQqoM4acGG+SGzlYxA+kjPxnhqAubRZ2ZmNML7UKfnHS8RVxU34paqQsk7R6lxIuYCIAJLhr3hkIxhNswPTU1OnJtknhvU1ellEQZiZjTKBjHEEPo+PsRPtSgGIlfcCC0NCiXvPkaLckkSlgyPCOKvINbMD10/cKo3nlc0JFMTXQ3vnq9BA/Sb3fA/0qIEiExxI7Q0KJS8i2qIjAiTsWTc8yi0u+h+6weBkBgjJl+sB3sUPQriRfxLQJQUN0JLg0LJ4Pkv4JLkLBlmpowhDsuPmP3zOX4biK+WsBzRxdk7Mvu/D8ScB+IWz1Qg/ln7KhAViApEBaICUYGoQFQgKhAViH/IvgrEv1Pt9xJt/j6J5ftq31BSBeIOgPARPopb0OjQF7H+7yMv4DtUOgIPQqO9pAoYV2OYzDQE8NGtpUna5+IU9hN9Y+dslbWe8ek802BIK1vS6JC4KuIELfV1WaUjVddoFoCI5B6sr3/YFsPEZp0cs0Wa6K+xc8ELvLvaREDEpW3vGyPRYtL613pmdnGECB/pmdzkGAizCYimAEQ+IpoEiCYDYlsME7syIprs2AyIcAEUgNjeNzEQ5ioQnB4siiNHEWE+gkT4uKbR0RgcaYihwK/zBo2LNZWOo5REe3lOvIGtPIhOXujFt1QBY41RgReEVQckZot455RR9sTRv1Js4DNDiSZYpKV1N/WNRIvJ2CqrPcOvrMur4Ycowsc1jQ4J58GRVTjqSaRxsabSIa+N87WW59RX5+FsRA6N9pIqYKwxKqx3yeJl+cAWEXetuDLVTes8m+Jgoe3RaLyMQyjN3dQ3yJOzVVZ7hlkUHzZiqiHCxzWNjkbimzQQWnCxxsWaSoeVfEa1MqKcuJdQHgQWVo32kipg6PRRYlRYT1KwGVskAoIvQanXKJvCyQVJEVXy0uLoJ9f7BnlytspqzzgRNghAIMLHNY0OXiNGBYKiMUQaFysqHVbyKRBxzhgIZ0ShQ6K9pAoYMRA5oyIGImOLiDaHAiH1GrApYiDMOCttvKVvRNoiY6us9gwXc7A2ADHI8FvX6GhEAEhGBMRENqh0iNgO9rKcRlUzoqlJo72kChgJEBmjwvpoJZAYCmwR6SITTU3WqVBQAoR05CGUdlvfSJ6crbLWM8yiuDTj0XMJEOHjmkZHY3CEJwdR1FCNizWVDqhrcKeMeU6dOcGD6Lz6hiypw7YYJo1frBGbJbBFZOmNqI7NKDFd+LuTKFsqFEblNtFivb1vwmId17/eM4VtHiDj2rbMzLmm0pHmTFUzyuobX/1t+zXWxO19s1ZSqWe+VJleMeWy1lQ68pw//4jja6yJ7wXiSgSY+qzpN/qmPvSrQFQgKhAViApEBaICUYGoQFQgKhA/XNK25N8tYPJbnZ3Ws1br1yz6hvZUIG61/5O55XF40ccbhdzw53OGgrIrlsp3mSkaoWUt5RFKydlTqG6eg55slkry1nIZbqnGIz1Wb6d/vPVi49sr/d1Lmj3v7V+R8onPaY5t2z4Fos/Pt70Ascx6ABDpeT3bBJf5sC36ifH1lekDUUrvvYrPx6/EiwK5dQlVwQfdsAESuHRS4QVfDgHRo1sJj7c36pQdn9pJkh3vPfUAosfxdpd25QydeH/HJfuvJ60tALErAxGPiCYBolkAYlv0E+2aJUJNlHIBiPmVvw6EuJfcogIGAXHCNdpOHXYFiN70/byfvwEIHaArrIeOuQZeUH0ITg+wOD48u+J69JMPdrfQdBKlK6ZUNyJ5yD405gnVLELu4E4EIBC/5Zn/AghJNdB1xjQD/yIt18o1kjT729vUzaf9ue+fzub09kZTz87sz/szdT8+PRAnc+qniebhvH/BX6R4OD9Nf/t2KsFQSThiKAUdn673p/Pb2/7lgdPu+PgT53mglK+GyzTXWA9ybR7UdamOv0YckX5EXI1+wtoUziXpfMCCJCUxNdjfdZH39/1L5QfPkzjYsEYgWsWB//qRAj6UI5CMBBJx1ol1B3ZjEhA0Evq276crtNcRMX3nyWc62AKIfU+QTV162pnHtn/kv73hlI9tO322VAKXhCPTld7SWQKCRkTPSR5byjmdMpxn+o4xw59rrAdjQuSFLhruAIJS6xpxPfoJaVM0wzFJ1xVTyoTIcxjSgRvRMLeiEys4PlIabMQDoeHQmG8RgBDyTCNRUzAiWgXCjwgPxLRIA4gdgUQp/dkeQPC31jy97k7Ul0+v09h67QHE9G1vIiDoLOfcv7Z8lmoGEH0ORM56iIEAjyEGglIrENejn9B+M2TpxlJKrBExEM54mQXOo0AQT6I0IsyoN4Ogq5SAcLJG9AJEWCMCEH0bgOjpewTE/hSAmI4zENPKz+UBiKmwswKxP9H36co/PXKOlu8S+lahN+usB2ZV2IWpyerUtC36CWtTOBHJkXSumFKAYG7Kuw0xT5po0tFoLx4IS/O+r1lTUTpnfLApJ9Of81OT6U8Aom3nQPAkpECceF3fydGe11iefFqadLh3CYITjhiMNExNLcFI36e14PRw7qe5CxmSEbHGeug4+mFpsT5KrBNlV1yPfkLaFAxnnK6YUn5HcJQTqoFjnjBZU5fho4RTw/VOFjXTGGDti8F46mM3TYT4HRGrXjSjthC/I0605L7szvo7Aos1lt79yxPvBSCepmWZjk5/kWLa28lf+k65sd/yWUq7o8X6TN9pNpsmvKk2yqNAUGnRbdaMYG+usSrKqZzZFv3EFcv8PFNjXt51Ka6v/LLub/hZN40ITt2bwi+6rUXcmsptLMetlPV5IL7SutuAoBGxvR6k/lUgvlLOV4D4euvqQ78KRAWiAlGBqEBUICoQFYgKRAXCVCD+S0DUrW7/i9vOPzdJn6AIa8HgmWT5zJMc35vg6Q1bGz1a6fl78qylzf2/m57GtGrT0yv9o+99MUXY6/Nz7XK5JZv2UZrelNPlLd7Pzu0Lx1KrfJF9G9va+1S7xTO975Z2FYjWAxH1fgLETtL0ZRtnHbZH8W0OxE5S7FaB2M1rSYBofWk9Uwh2/nAJiGBjaPFuhtbO7BawnzWyN4tAmO8GYscurtSsTUBIggd+uo8y+vlFnOz1ptjEtJY+TpH2yU6P9D8EBNgE4sQ4s5824iUQgwTfd4tnyEWibIWdeT3v9d8LSuQuY1cLOAsPzGFgjgP5Wk60R35G4kbQ8b5/YC7EHmmkzgd11Zxfz8S7ACOCclMZ9M1MddNFMeWajrMdBh4x2OctOol1gYnxIuWfUCfzOtontYBLnKZmOHAkDZ95iXkb1NYn32IwQOBi4vOvD9xHO3+Wz72ixVMusAkmI9jpBy9s4CU8nZSVsFs8Q+YpW2Fn/oC7QGSsHiXSBuYCOAuP7LF9bOEP3jGlgYBACcSOeJS84EGgTjAj6Psf9hgbZkTszuQF3vH5pzPV/XTm45MdhhkTYE1M+U5qEVyhysTgloc2cp07aSMd7aUUTE04x63hMrjtvdoYzw+hJvSw4doUiL7V/qaiqARhE0wj4rXnBTjlJdB1D1bCbvHMQ8RWoA6gb3sqr6c9NWvvOQviOm/3skRQ3X88EGjYdI2A5eDrhEOevv9hZ/2eGRGGuxveYcMXgeHOaqd9YmCgG7ht3iItVZkYe8+8mCwRpz7aSEf3DE8AgtKgNXQ25m2gPYGqOZVBZyUXqDYeiKnWPfc390XPNxyYs8kZ3puclxBYCbvFM/0psBV4REzfDE1YfFxHBLqEoZYRYc6Y3lvu3Mn0UwzEVIJpozpjIHrflQCiD0A8Gr5+ewYFLn6quycrxaI+AoKZGHwctZgz1+XbOJV6ToB45BK8TQlvg/3U2mKqZ+fbB9hiIKjkXgZBT9dDq+SOR5maEl4CV8Pfd4tnMODBVghTE5mMEqmxYC74ETFtD+Rip+md6355wb0JD/gwNUV1Bhv+tMy7eAxD/+SBoFmb1o4Tg0LnT1w3wysWnfzUJEwMOd7ymdYgBZrZp1PTVL7mZtseY94Gj0Tf4mhqatMRIWelv2nW4qkJbILW6NKa8hJoeGFvt3gGizXYClMXtPFSzSViKBJPQoAgDgMt/fsTgNi/TFPRiZY1Lu3lQXK3WZ17XmZPwrvAckqpTmzJtELLjezT+UR2MNfixHXvuVxYdPLsCmFivGgtdIbqPJlQq9xk8L/p11aLc/sXtu0l5m1Qe3a+xbpM74WvwSOPOSFyVvp7d0bfm5/b+ugOfv4TrTfpz7/dBlbEblOdfaGm1KLcxu18jPWUu1mNxTLML28xyv0Gc77jqsAN+FJN8xpwZHvNP3rl1q1udatb3epWt7rVrW51q1vd/qe2mCDy14RC7rpXKhD/ZSDi5zd7dp+wJIKco+qbkXR+020eP4UOhMgj89Rvb9bRO3bQN8D77J/RaXU35yCrui/1EeKtlPoh3Urt8bFX5o7/NgMinMWzeZZEMKphgVeDQ3SRHIgm6iBbVCK2AkQzWJWQ0LgpNk5VbqRNdDrsAhDzikMuetd0qQPXO9aH4+B4K/RybrNqX6k90bH8+W4OhJkDcUK6HcSVMyAaszQirFkCouGgAFrSLG7KYt78+HYg0nPXX35cKxXxVqaaXbMMlim3R4AAf2Kacl6UnxCxC4wwFUzCRDjRO/tBw4KKfx4l8EYUP6UTEXaN1yKv8Iq6RieaHBBOx1vdzeCBCHFTolShJNHuyCLCDKQ6wHsfo6/9oi8Fo1ZS/hCND8MvAHOXdPzqsvHWaR3OdZwnz4vOU8l3jbfiWBJjyb5uoT0ChPqb2UnZtim7wLBj7wS9CM9EOJEkQtCwoIoPFiMijp8i8v9W47UcLOKMhBfQ6UV3Y6OYCu55BKQaN8WZOFUoySKCShYRZmBNhINGlGBVInq5XV/o19frWRmErBS5Aoqloq/RH0QXB3VIEAWX55VoG/I6vmr5TJfA0Jgl+zAi5u2RNSIAoZyJiF1gmJEgHrS+jUdE0LCgio0HIsRP4SuOrzUnXc+RRURdAyY5230EwQkqSSHV6SxOFUpCLJUuiwjzLnIttIe6p3wOCh443hl0JnKZAbZaVjZgq7zuiNQhQHAQtiivAPhhoyBOb28HWWuW7Cu3R0oAf4Lc2spPiNgFtJ0xIgITAWtE0LDgWU6BiOKnsCbGaMbQfRrBxUXXRqz8YUIIjwQITaUlsbaNOYhARBkI1E0xVHhPjk9HuDORq5F6wj5fx6OMCA6+ASD4WJSXRIwkIo23lDRJGtHmKdtXbo8TxoEBA8OTVyJ2gXAO+h1rCiVA9EHDInRfGj8lnpqcTE3WD2cnmhwqSsQ6HL6kwS9kcSotiaJcOT6aRoS5XBpR3tCpiWK8hFgrYXqhnACNZm4BApo3I46hDgUizzutPIOReCporcRbMVgjSvY1C+1xyjgghsKTsBZaE7MLcB4ky8BEwO+IWMOCI5MYvh+PooTocqnxWnSxtkYXa9LkQGwTKH+EkgZ/3x2n0pI4RBPrb6QRYUg8q+G9wcZLNUtv6S3CZbCkDELxU2ixxrR1HP1ibnAMdTSRtFic11hEjGz8rQnirVi5NyrZp0oheXuccCw8TXB+c9YX9nQSKe2vRQlJ1T58TJXo5va6SGP63W26wbwWQ6VUtrtauovuzptZT5TtaxbrxBpxTj/L21YgrkQJWe2GnwHi1t/mbq2zVku9BsRyez691WdNd2J/BaICUYGoQFQgKhAViApEBaICUYGoQPy3OuQnWqOl3FbaF+uuQNwNEI08A1UuBcVNweZKGdy1EkXifcxDbfz0ptwKtMZFBh9ngsPp06NwPo0aQ3516Ztkm7xsttSTdnKyNsMiMWEoGR09RdSQAp5L4fI+T9ztQzhmC+VqSmtT1gI+mixtaa+E3HVGR+BWpM4mER7PQ4nYuFxnzCxqjFzj3gMRp2+8kXGp7IW31jXLF4opdhiKJCe4VKZcClsCwtwKhCkBYT4JxELTTHZdu9CaEhChM91skOdRYwQI5wqUmcYTaeJSmZdiS+mlTk1c5hpEQCiXwoWUYDocmQWhweUDFyNwJZTJcBxF3H20AlkQW9f4KF3M5mDOBOKuKE9CSw0MjpRdMWdGpNwKd8i5FcQ7CW1QfkXgnOh55yMCeCAGlJZyVBrx2XVSKselAS9FgMh5JSpQz60qcw2IjdAlXIrjQCkOSG0QmSQ4KOGeBBcjcCWsMBkwIsirPXWzABHzKhAp5eBLgGMSQRTghjfeuWrtArtixoxIuRWTl8wgp7biOMRtQMfGnBM97+xsRAwoLeWoNAK2k1IPbCHWCJSf80oa39YDopvMuQbERnApl8JRCsKEzlMeMPI0wok1GRCcw0pKg5Qf0YgwIcBGw9+J4QESAeXtjAJBe5QTE6Q1JXZFiRnR+amKWmOsdpK2wpm0DZQ05pzoeWfzNUInoZSj0sg00xmrNriUDjHnlXBPOuojU+YakBM841JY681Dw6U6REUZloBwRoFwRh3rIeZJAMKMxP0IQJhRgcCe8D64rDm7osj0GHWup9YEILQVszZg5fScEw/EYQmIlKOiQJC9sKEbciBcxivhS3LgPi1xDXiNyLkUjuNgWU+LoXknkEQUiIQrYU04ikgs1ijrJ+ZVoJTnUdPK1GT91EQ5PZtpgV0xZ0Yk3AoQIRlCaQV3tG9DPtWE80wUGBANrJHwVygtTR9NTVqq56XgrinnlUgZ6MMi10AiI8ZATGuEoYgonY9lQr8Jjho/kSauEVyMwJWQ0m0zapA1PjKEmCeNj48i3AmwORBgjdkOwpO4aKkYMQV2xYwZkXIrukFJLtoKmhBCG4JVyjnR8yZEjRk6BoTaEC/Wkn7UxRqlsgXCS8HviJxXIou18E9MyTH/k7+sl+OybN3cxuNzbsXtVukNpjNhRGwtha72cmpnQ+rox+28YX/jEYf7diC+pzX6e/v2RxyUs5w6/g2/yjGpz5qWS6kP/SoQFYgKRAXC/Ie2CkQFogJRgahAVCD+00B8rvqfa9h3WHNL7p+6JDeWW4H4nppuKndInLzKWOj4veOjfw5Ln6wyoawO5Tjg8dV4mxngVqhJ+qQ3S7GcV/xeJS4FtsCNKLduattQYFZEaZ3vME5r4AjavnlHbdEOLTdqgc2SqBOEHoY3HIweT869c0VZHfqkEQ5JawstsrN2NqGjIiBc5g1MgWjyUp1yI8ou+Tj3Uus6dgCndTYLQFBa7gszpwYstdT4l+DLdmi5UQvINZabim5/ngNBpucKGajQbANCN3ArloAo63gEILZzI5Za92xK4MdyJk7KQtrnIhBmFYg1O1Ib0CXj5RJzC9QbhRe3w0jgTxrMQSEDzI0L3DVHz+8AbwOukjK/QrkVHogDDFrX8YADhvfAjTjAI7bGjVhqXfDKHYVtQhMPHDvPrLchbA9J2wgQgWeilh09TyW1w9g1O7Rc8X2T08tm3AK9ZrBGmJH2jJMjfExZHcLcIKSnLrfGuzmZt+FErKLEr9Cr2g/SC+bKdR0P+JsPVjU7plyXa9yIpdY10YigwygVwB74pXb241tNq0CoaojxllFjwFNJa/LO1KIdWm5wuTIQMbcgrBFhRDRDGBlBIaMRjoZhjoVlVQq48cGyaAb9PlfSALfC3z+ETlnR8ejkvOTh+fAaN2KpdRkQgcJgVF0AqiEmA6L76LgHOrEMDBMnQMQ1wce8ZIcvd1A2CC8jLuIWpEBgjbDRFOUSIJyyjXg/BmI6HwGRK2nE7tgEiBUdD7A5DgUg3CI3Yql1W4BAe1IgiBuCcQ7LYJMCkdgxrNmh5crtC7XU2iHhFqRrhCzWAgQdG1IgeGpyB0/EkgmFvzlrl5Q04NL3PmC3RccDpeoaAYyvcSOWWteEuyYbAXFoPBCgGGlaD4SohoAJ0gjDBMdSO/SmoWyHlus8p2X6BZBzC4SxMJKC0dH/ftC7/QDEkRU1eLG+WOZjWFl4iP2g7I2ykoZwK4QV0Q1bdDzA63DGa3YM3VVuxFLrjqP+jmiYW8KkuVFlTkhvQ1RDJO1RRMG8ashFLaP8aGlaEwG+YoeW++EX6/m9b8ri+J5f1oV70SIr4rqOhzPLLJMFbsRK6/Lym5ndy2mXj1234wpPJuDyO0DMS76u4+FWrFnnRpRad337TLu32FGfNZn60K8CUYGoQFQgKhAViApEBaICUYGoQPyngbjeYf8G4ea+rbzRugrE37DOrgFBL8I24lHm2CdGVSnmkU9ui05CTyn/L+KFCCvEzstz28v0NuMZpyjvZ278ZowYKDavQfbt9dZ0RQPcomWhR6N4E034LKpJ6GfHJvHDY/Yad0ZdOhr5JLjY51oV60DEfIZGNTtsXoa9AkQQi7ACROcdSPC050BYIaDYVSDKaiFmsY140h9ba4tAsHVFUlBRTUKzPU9lgM9w/CAexbNRl06q1rGt8+PtkACRXA9fBOLZO5AkUMKM1xHxMH4dCLKuwYhIeBILahJhIBmhWmFE0PfoarOsa3EBu2OuVVGKcaKaGc+xWsWFPcHidIKNz2MjzhukL5WkbIqjvDJMKWEzQmvoiLhcTBTTBa8gw8lD9cElBNaIVyq5NFFEmKNXGYnTNNLaj0h9RK2Nc2ndwTpRrol5EktqEnMgdI2YGun8/AtXqGtMEFxIeRjzGCcamcRdIrWKQ8PxTeCGpSaJ0gWPlEMSkiCU5Lzqh41Sis1jvEa8R/US/+Q4iped6xu83oixCE9yYIvCy/zK+3CSBnojjTA73iP1EbU2ziXxKWywzsmIiHgSy2oSCkRjNDYVhzwzoCPqPM95WCGj+5hrVZT4Fl5j4xDLhjSikOF9al5gwRqwPAoledUPG6WEzWFqUSC0XuWfOM9IAX8D3BS+iRAiGzgd4KrAyw37jeQkhgeJcb3boD6i1sa5OCoLl6rWCRAxT2JZTWIZiECjBBDdEBgSOQ9jzrcIGhtzIJzJgDgI4cYUmRujqn4EIPQl9RSIwZpE24O5KJ6R8h70RmwypmX9cYH3MRqtyWDEAma1Q2Qx8lxkKbR4xDqJWxfzJJbUJNS33BibAWEDB1ZHhKhuzLUqSjFOWAPEZkAcGh2PhxgImsGtXSzJplogSAmb3RwIrfcQ9EJQ3+Xi9UYOXOrB6dQkICvvQ9NAzaQRZse7t2OqKBJDCmwR2E1sFVhnwmKtPIklNQllWxz5aACCv/s4hEq85HyXiJjoy5/HOGENkBG/Izwj43JUhQy/WDN9k39fUMpiSZ430ojKB6WEzYFzTb8pWN9D6lW9EImLcqHbQK83cgGjA60BR8WKMghPTSPSQM3kKLYMVu2YOlisjXOhNVOpRq2bxa0r8RjC8G42/rLeJpv4GXHFcp71kn7rl7X7VI4brIvVJLYBsS16yWfij5bzrJf0nwEibkx91vSXratAVCAqEBWICkQFogJRgahAVCAqEBWI+7Duewkxfye4zn9COmbeiG3O1ea/CoQ8ME/YDO6G7Otxal2xxMZATSNlWJhhKaLJUY4zU2LQdz2nnOp5s2lpCxD60pfqmbYPlHxdG0SEKEJa0SgZ7HIvrPYvy3Ywb8ImoTqW5BuaLwFhIyCEBWLUn+z1KyRlyBMinVifuzNGXo6FrgdKm7v5I72M0L6FekCVCNyUkjaI5gIQIa1qlCwDEYgNLrPR+uvBpmoaa0CsjYjmJiCEBWKUYREbfB2IJK/T0tJn+9aknTfvmBIQgZtS0gYJQKRpVaMk5YjcAAShCN6EDZwKdubA+QLeAUuQQ1EjYkA8sysFOhsU2SSWX8en5OZoLOQkCVFSlAXyPEYjwsQ6HhxFgr/LS7I0+YzGv7I+ud11RAROydCwtSGSS2eeRS/DetuW6jH8XjmXvKANkqiMaNpDHHkm09zQfpqsDwyT5xLvhLkNzJugauFmxMveeEVbVDBc0Mnw0UqY34DU078hlv7n4e9zOydpoigpygI52HC9ORPreBwH1bEAz4KAkFe0BYhnWSMa4zkl7DG37iBhFRCtBa5K8vGJbQv14A3uhlersjZIrDLSaNpLHHmmxFTh1rvgTz8UeScGkjaqpsHxSViHgvgI4DNAV4Mjr0TRSsBv0K4/CumwMxiiFD/FKWvBIWJKx3UgSoqSD1JpnljHg65UMCKemQ2SA9GYg6fDeU4JnPEDytGQOmiZFZ7Fcj06IhpT0gbJVUZMQk3QaazEVHEZECgz551EQDBTYYSD1IKPIK9ni8HWMzLG+NrHiJCoJKOTl9KVDTEdcRxB5cDKFeAVjWtAaH1WdCwcMzUUiMZ3gb9WEyAo9yEDwhkhCQTbCvXoVR4BEWmD5CojKRCaaigwVeZAOO2pDIiDAGHD0LE24jOItEYUbUT1KA6hIicKRR6eg9/jqYLc8CFKimeBxEAkOh7cQfju/NRkTcQoiWOmoDSwP6xDrCyN5GKtBqlJGR95PSYruaQNElRGRE9DnP9DAGLGVJGpyTNMDkXeCQ0e5k1Y5mHoYtJg+Y3ip4TlVhkM1LlBb4IW8mSxvmhuag5LSUVRUpQFEt+xpzoe9JsAe6iBrKTfApAqifMOnlPCzKqRaUCjNYjkghK5fZeU8ZHXg98RoeS5NkiiMmIk7ZACMWeqQGAsMEyei7yTb9zc+tnkDvgrv0qbq7+s3afLTkta1ga5HnfmM0yVX9lS1H/2WZP7ppLXtUHW2/DNV/lPbfWhXwWiAlGBqEBUICoQFYgKRAWiAlGBqED8h7o3zT8XZsm/31rb71hXgbgT676wOfkr8gjOLD6umkVOEd0Mfqru2RQav7lYwqB7S7FOQiwXvETeyF6I5xK/57oxGovVOCy+pE9bR4+9j5FNYvO4FG0m7uOl3nRInQExLAMR6VbIAfURxGwKjWheLMGpjUuxTkIsl85oEJHOxPFcYnWQ9WgsNgMC1hn7FetYO0OtM2qdNYvRZkxOUSjwSnIgmIOwBkQOtA2klcCm+GqsE43l8uyBeDZxPJdYHWQ9GksMRGPUOuO+Yh1rZ6h1ITaKWY42swhEOl5UMUJ1KhpxoIT4KKJHMKrj6Bj0MC6I6kDXS2BTuFhZ4xOxTsJ73RrNhfd8PJd4app8hGXGxcXzOIRt0ql1B2hzfNK6A7Tzsf886h4DUYw2A56GOoNCBJYgao++9ooRKo+gr24fPNNA4yqQcoW+wB3rZgCIwKboxlhH4NZYJyGWi87IYRYGVyJZIy6iBpIwLowNzAwnbBNv3QUMwU9ad2HJBlh3OVg9+rwYbcbGfQzPqNgFnRETtD/AKoiA8PwN533QrNohChYRELbxIyKwKYKOwOdincQjohnisaFO+wCEkagkWTSWj8DMOH7EcViaL0ZiMew7FyqNH6+GZVGWos2EPkYEFtAa1Dplu3h9i7BYg+1w8AwgkWIYVcFiBsQhZVNEgg6finWiIUQ05kgAwhWAsKbAuPC16MVUAuIz1k2zwodaFwPhVqLNhD5GBJYYiIjtYgPtSoHgqel5xNT07ANcqIKFtfHURE75lE2hd02fi3WSAuFMHJxp8AD4q1KIlxnj4qC1qPaFxmFpPEnyc9YJrVP2NWwT9oYUCI02Y6M+5ggs4Jf4CDTCLfH6FqpTYRwWLydLiRNNu25UBQuwDoJuht6HKZtCf0d8LtZJiOXC+3ynzsocYwAiqIN0EpUkY1xcuiimC9gmnVo3RLoft1s36O8ILSnsBSDiaDPgaQjzRTQ5mnixvmiUmYUtDDS3HK9SJgLdW1fouC3Wydov65I6SMq40DJDpBP3S9Z9++b85zU+wvVYJZ+JdXLrI46UcVGy+Xesu4utPmuqQNyNdRWIO7GuAnEn1lUg7sS6CsSdWFeBuBPrKhB3Yl0F4k6s++auvEec/x0e0TdYugbEirzCX2zeV+puftXSzRt4GFoUqUxEShm0DSFtFkGEzzj/tbT3Hc2z5MIZQxQXrRu7S8/EjuNikd7u1OK51e47LC32jv8WBe0YYiCMdVEskvK1lD6qDJILkWL4OvRZeeVzQZOGLHRRFJfQoNj1H0qIn6jahbLxbQsQ9mor1NZlSxuTh/coAAEehgfCKd/h+FECoimaoEBsu5LsTedolBrvX46tcsW6vOsyAaJs9/cBsW5p2jtJzSHWB3gYHgii1Qwpop0qclAEkQHsBHoNOAx06HhoPBaNN6IxRLhJLnBEopeFTdDtiJQ0kpgsfJ0NZnadsRLIlB8aG1DWEHF4HLEqFa88j5LdaqNGTkmtfhY1jVIsl6N/DRot6YKlh9hSaJkcfS1xzUBIYn3YNH7KSL5TneMwzzqJBSLuTHLaMstBZmKnOh4HiceiMUkOMRvEBSemNaqP0RjV7bDW2sDAiGOyMAtjqiXMvGqVG7g+eNidaIpI6IWDDTFTrGdBze220raDLVl9EO2AUiwXtIJNsogF4y29xJYexMd/kPbHNSsQfvjGa0QzNLl6PpQlfLACfp/f+aE3GJVJsBqPRWOSQMlDRoTEJwGnAccbEZsgW6xXqUhjsrBtthly+tqUSqJdQKEAmiLElkA+aHlYUeVYsttK29C5M6s9EPNYLshJjA20BE5ZsjTlFDomHljROklrzoBwCRAhbEcAwiHiiImBcPGMFwGhkhB8bUkMEvb2j0KvHcXFPuZA+KgkSUwWNC+VjTBI5UfElA+si9FpMBILLQ/r46iU7bbaNlu0OoyIWSwXTxSwaAmURtiTnwHhaQWRcpUKb5gQ6wPuf/UHI/ksnsTBxVMTBzFyUbQy1atolKTD0UOeIfQDaDA1GeU0kJSEB8IKEDEDwyuAUPPQVTOrpklV6yBlDXSNVeUQ51U0vMpGbjcLAB1iJZHU6oOoaZRiuaAVUCdBS9TSlNwp9COr7Y9rNszJuMRAKEOCfkXkQNAS5Ze+gfJC4SK632DFDRakshIr5eLY7+3VOi7dqAwGqtuAQ+J1O6AKogyMOCYLNY+syvnfKoAlDAzRFCH+BPLB4kYoo2W7WVjrotFU5lY/i5pGKZYLWmGkxOMIpRG2dEiBYIYKl2mzmgs3XiWGRGnbEm/RT2jRTeBSquvbFe2LjaVs/TW9bnVu9/cpjWRFfMdznXDFuQ2pfguIrZu7UmIWm3W8YyC+e6sP/SoQFYhvbl4FogJRgahAVCAqEBWICkQFolr6NSO/2+gy6eVaTV+34p/TqqlALG7OzJ/UkPuF9CdWt1TCINvzB6yqTnQGrieOfDKEaCiIhNJE+bfxMcT1arRs7RAqr5P38Ew7/eOtl656e6W/e0m95739K1I+8TnN8Wkg+vxcGx3ZnXXvKey9LgJBj9+dW662ESDsAhDeRc+CElbeUsPLuvBUBv0O+t55ILbzMdSZ5e3RDrHi1yYPfI9uJTze3qhDdugO7Rbee+oBRI/j7W7W3ra430afERAnrTEAsfOpW39453P3yyMieGvXR8QSECYFwiRAOH3FVngj0/fnZES4eUVFIJoZEEn5BMQJrWynZl8Bojd9P+/1bwIipA5HEyCWeAuTp5eBmLMWnhFQXlgaGiMk50Agkokqe7CrBxFRBuaHDJ6JId8xNd3GxzDsO/OsEhyV8oyFV2Vq7Gl/7vtpGji9vdEUsDP78/5MnYBPD8TJnPppono471/w10x/p8/z6/SXphEqZ+/3sUfn99Pn/vz2tn954KM7yj0de+JvU6pXw+Xie8t592eyhM6SbT2YBSXewjQxXZwtsRbI1TeApXEIMUJSDoSziGSiyh4czQTxH+hVcfZShWgojehs3MrHgCPy4J2pEGJAeUYUM2gk9G3fT9dhryNi+s6Tz3SwBRD7niDbmafTzjy2/SP/ndI+tu2U9k/7yPMJldOHfd6j//rpT9++vU0n+Sjl5hPT0Xb6jqv/scX3CcaWcuPYI9v2dDJLvIXp8wAgctYCoqJIQA8fmiLlQKBjNJAGsyo+AhB+DpfFG1IKPCJu42MMmKBQH6taWF0jwECh7m0VCD8iPBDTIg0gdgQSTxF6tmcg0MV/uKtpSZ2u3lfs95yO8uxfaRnaGwaC0nDu/Sude3ql/ACCUj+9ao5gCeXqjVniLagbfc5aQFSUORCBA3GIgICyhzUaI6gxKRAuAeJGPkYChDrz5WbA6BrRCxBhjQhA9G0AoqfvERD7k5Gr2I8I03JpKRDTJ837NDWdqEunEXB61HN8Xjsd35GjF3AeIyAKvAU57kqsBeqGy6URConGCIk5ENDEAA8Dyh58liOiCD/Ea5wN8t1PTTfwMbBEh6mJaqI1ApeE3jWdAETbzoHgSUiBOPG6vpOjPa+vNKMTENNny+PjxN3fYmqiven8Y88TGEFJqR+m1Wia+WlWk0nLjwiF51GnJkrNExqYBXPeAoCg3xFz1gIW3qMoXGiMkIQDwTREiVHiZLG+ICIKTUXdGFT/Bvl+HGWxvoGPQUIlulizWgdZoOV96O+IEy2OL7uz/o7AYi0L7ssT7wUgpoWzpaPT3zOPgSnViW5rOT3lnUCUxZr2pvMv03Es1rwQ04w2TXpTjXRUgXji1PQdOah0OoaU8jsi3Hq6lXvV7WwLt/WHT/H7LTSAUgjC7/plzeu77m+wZRoRrabdkn6l5O9iW7hfA+Ja+V8BAiPiFiD2528C4ne2+qzpTrYKRAWiAlGBqEBUICoQFYgKRAWiAlGBqFvd/osbeacCw2B30uP7nGmAtIWjemxvgjeWtpjB0PP35PlKm3uINz2rab0lr/TPtLM8M8dyn59rl8st2bQ35XNLR0O797PE+8IxKWXHnnNlGLTei963anUfpZ3xD4w+7qXOSVMEg1oPRNT7CRA7SdMXW9nOmr2HqW0OxE5S7FaB2M1rSYBofWk9t2gXHQ7nNEdOLwjt3s2Q2pndChCRHdqprbJRbgbCbAJix66u1JJNQEiCB372jzL6+UWc7PX5ufk1nD1ubZMMnhDTFzP3XwRCeQk73iPHxgO7PMh5QcfJVaJ7IW3MP9Cj5EohngNNXDtmLSCFdBk7Y8BoeGCGA/MfyBtzor3Jy0gOE/PEuR6YL7EXjoTyH5Q98XomZgb4EpSbyqBvxryeqT+mXNPxV8pr4C+DZeQIYpcM5w5cDRzn8k+ok5kf7ZNawCVSm6iV+TnNQecezury0SkdTBFlelD7H7iPdv4sn3s1ykugNYKKh0Mv8BUIHMMuwem8TxvzD/Qo+5taqiRNgQ28BjAamP1APIlWBvz0lYBAXsr1yPWrLfAcB/bEH/YpG+ZL7M7kI4b39+lMbv6nMx83f5ijoZyKKd/JSKnitBeuBrMqfMtQJ3/2qLWXUjA1zc/ppx7BzKIND/WBw2G4TgWib5XRYZSXsOO9VrgGEV+BwHiFIzykjfkHevRhyrc3AQhNoQbtPaNBne57WSKohj8eCFwE0/ULDoQ0ImZP/GE3/J75Eoa7m3NNp//wX3TLn5Y4GugA5k1Qjp5s1FKVq7H3rSU2Bqbjp9fdCbXuuS0BiPk5+hRSQEvlGy5HV7EpNaX1620fAzHVvccNj/ISdsJGANeAOAzCVwCSMM+njfkHerSfPs05BiIdEegSqrSXEWHOmN7hoJ+MPsVATGWZAETMnvjDLAihADAQfQDi0fD12zMoaBVfp2Qft4rK7ROuRmgtneW6aHk+oVZzToB4nJ+jT7b18ZEWhjOvB3pfeWZCguk9iCkQyEv3fcJL2PEkJUDAcJkapv95XumjtDH/QI9i2DMQSQrqYJq3idfgR8S0PZA7naZ3bsLLC+5NeDIKU5NnS3greWpiZsZjGPQnDwT4eVTuH2FjnLhuhvcRrTr5qQlcDT3e8pnWIEXbyyQdT01T+fk5fJ743MMZx9BSgOytbNMRIWeF0WGUl0BrBBZrZiK0ylJghsLLdI2faYj5tBH/QI8iDzEg0hS4j8a+AkEMh56WqhOA2L9MU9GJFjQu5+VBltXWBDv4Ly+zJ2FmYMmkVCe2YVqh5Ub26TyVK2yME9etNyCc36il4GrgOJV/kvafTKhVbjL439SaNj+HzxP9Bmt7lHza8WK9l+UYVoLDweOPuSNyVhgdi1t/lZp+3e0d3wv2xbO75Jbuep2763XOf9rFd7ILd53Xa97SL73cse429dBG2sAqSjcCYRaBuLXObXYvAzGvAUe217yWkjlNdatb3epWt7rVrW51q1vd6la3ut20LZNXbst73y37B9pVgfgr7YqfpezZicLSCXIOgbubUSXc4y1+38h5g+mVxkbijkCrOehtcCobp/e6BHY5Rgql6IpnmixPlip5MQ0aIZFtJg7IHLXH5coLxkLEWNVGNrcqfZiYOv7n5/voLJ7Qs3SCUa0LaMcbCQ3QRNbFb+AFIJoBb03D5Mn0waSxWBKTrQciLz/0pEuE5Zsolc3eAdT3vOW8baJyoBES2WZMUq5vz5BGlmkEiM6o2sjmVuVPdde/p5QVAeKEdLxvnqlYl0ctSRXunRhNOjLPxouuO1KVuQUIUwQifcXRli95MwvO4+J00AiJbJuVKscFiOgcv8D8bFRtZHOrwJqQh8HMopimHNGUIHZBcp72TMJEONG7/UHrgpUGxDzSz4CSB8ciEd0M5z5Ut4PEIIYmNHbQawcqHBx55UIvGKvGx9HrhKTlG3nhWNKS/scoLyZzKqiGWKNxXCD+DvUOVfkwQ8eKIigHGiFs2wGvHT9T+ll7Gn7pHhoIbC+9xsw5VW1kc6vYCSquZfU3s6uybYWPEJ1ve9aqiJgIJ5JOCFoXqFDisEz78ro8v3wtL6e7d4uIIo2sEc8yDzcGsylisbDKAL9SP3iND8Qiiaem9/B6Ps8VA6txIATCwHoG1mhsF3rz2yJyiQmhEFTlo+F0GjdFNEKgkW+MT5G3p9FIZA7hGBoGLgZic6uYFtCDOBmAUOaESc5P40X8aH0bj4igdYEKNexNw0oeYviASYWA0Igimj6dahCLZUpjjh8qy4I9xCJJgYA+SBRmg2unVO+2+wAQ0FCwIkpB0UsoUgulcno+iEw4jexA3XmQuGOqjZC3xwMxeCCsRhy4sVXoaMz9YFGQW1uZExDx0PPmjBERmAhYI4LWhREDoivWlIBARBFNH+su4QiJP5DuhtfHMWqyM9mIMKIckgDh/D46mKYRBYITjo5TBSCcjAzn74N4apoBkbZHJmFE6xtKQGxuFatJ9EIrMWBgeApLm53n7idGXQJEH7QupEKJthINZesD3+jUZFhZKQJiyE12GMSXi2p8WD8RpeVrkCik1alp2j9A/QPweSAOydQknwPnonncRrFlVIooAiJpT3zXJEAcsEZYg7umza1SNQlwCoinoLyElv2z6XnmAprARMDviFjr4sg6GTw7TguhKHlQLJIBEYe6C5YpKyGRjqPGL1STj6LCwbobFwx5aHw0GioNkly+fCN6HUh7HCHmNS2LrP6hsV2skTguF2O8eseoKh8D1+sMygEQnGJQjRCS/crbE/+OaBAI7dJxzqkPhttaFd2YBpqgmW198Rb2ll/W+Y8894u/rLfqiDiztTXLkVm+oV2BOLuW6rNAzLffA2Krjoj7Fuvqs6Yfa1kFogJRgahAVCAqEBWICkQFogJRgahA/AeB+H4T7hOef6xlFYgvlFHgRKw/Ils4q8yHEB1lgflgrnEg6AGyj1q9gQWxbft8O0PLAj8lbdlxY8vYZeVK7TJmHrheAnQ0RXtt8tVGf5X5EKKjzJkP1u/xzgIHgrgdXsb9KgsibE3Z3i+3M7TMrHM6NrE7zJi3q5EGLRhobgRCmQ8hOsqM+WACEGscCOJ2bGdBrA/Z60Bcb2domVzN85ZFQFxjdzRu3q4IiA+JUsJi7JcZBwOy6e4Zro+RnDtw0FAuOGKU+RCio+TMB2c0/RUOxMBnNrIg+Aj4GREP41niwBzFcfSVdoaWmWGhZVZru87uEL5T1K4OExR8T+8cj8R4V17GwRDHuoYnGJh/wFONtRJCQJkPCsSc+cAeMk6/zoFgUwdNc40FoaEMTMrDkHALcrXar7QzatlYbtlRAy1sYXfM2pVMTe8cUQVxU5ydcTAQJsNpwI539rYSE46inVihL1pxm/tYEDnzwWr6dQ4EZmAJkOangiUWBEUlAisk5mFQxBUcJ9u6j6+0M7RsidPx7GvbwO5websyIIBpNyi3IOEslA2U2CaWmRTKfJgD4UuxPv0QlrQ5BwJAYBl1kcFlFoRzxMlQIPyIoJw4PhoTKAefaqdv2RKnA5FenNnC7sBRtwLEwcdNOcw5GBrPxHK6y0UC2lC0E4mqoswHOwdCSgnp1zkQuI9ARLohB2LGgpCpSdIoD0NC7SAolDA3PtvO0DJnF1rmtLbr7A4zY3c04OWCEzFYjkeCuCmXGQfDdBKxpOFFzPHlw7FNLlaiqijzgWbMMvMhpF/nQNASauXKGfyd+hILAjZbSaM8DAuLR9gG5sZn2xla1i20TBfrLeyOFIgjx5DJmermlrgppW3778+f4kC4relubOevt2x73JSvmftTZbgfamd91nQnWwWiAvE/YG4F4k7MrUDcibkViDsxtwJxJ+ZWIO7E3ArEnZj7v9myz5qh+UL+327QfyxoTQXi6tZtSBM/H4zS2+y7I/dfOGNEeaHEgwilsaMQJUW1uBkQjbyoDh+evHs3Z0OstKxbbVdpg+Ucf3toFlNlbJXIGn1bOKnZFfgj4tgrd/6CkkXk8LZZ/gHuvxgITuF5EM7XqKU3UfqyYod+duIJAM9D3kYVNkRw38c2xtZZX1dCEphRIdL+gOXsTHG5tITNeiTUGupUIJI+HlLagjWFirProbCXApHlH3xXJkAEHoSb0VdSIEqKHQrEsweCNTwAhLAhciDmLbNmpr+xsq8bLIfb5zoQ5kYgmnha8c4OB+YD8RaEA2G8UkWkZBFULNgpY+T7hZkcBr7sZ7hV4MQZYh7EM2oT7gJyNz59WbEjTE3kNcOI4P1D49kQVNdgjfBEPqDA4evyGhvc3qMwOdJ2kYNGGB6mE9UPtdwIEJTqWZko7NRBusaktTa+TrILQhKivMEUGmotXh6Gw+p5jP2wGH/s7jtIxapUEZQsYhULA8kQq459AEH+uQM7Gi3cmkPMgzjIZHaQ0o2oYCB9WbEjWiMu0RpxoeYpG4KILIO4SO3kaw7yDTG3o5EX8p2UHreLfKo4Lr5vDHm23DhtN/l6nVVRD03XZLWGOqeOp70DUuiImXrFWt/z7DyeGiTObCa8eJkEx3w9FUiIlCwiFQtMJZSfgOiMjgjkIekoZkoMGH6x+11d5sgd0i8pdigQRqYm4c6p292QPFH38W7B3rDmnTsNLYu5HQ2PCctMEJSu7aLacbyTHJ2fXmgEAghKhYtQ80IdpMlqDXUyY0TyxswNYrN0H5iTuLSgGcGmjjCLcR5LQMQqFgAC/0+DbNQ1wqtbDEHvyC0AoZINSL+k2LEMhNMVZSDOhfIJ322Qloi5HWwBcU+Mlu6FIQwBwcyOUdo8Gm+51ZlgSnWIgTgcWF6iyWoNdTqr64tTJSjuJc+4YnvQaQc/Nfkp53mUqcnmQMQqFpiaMOxATtG7JhdNTY2sTzEPQrkLyB3SlxU7QNBhIFwEBE9kgwLh3OFywd2s75KD1qXcDpmaPPksbpd1NnRatDiT5c7gromSPI8ymUz/d5fn0U9NUa2hTieskcYzfxmIA3HYtOdljiTFCqhZgPmA6wPLsSpVREoWkYoFLdbI34mAFX5H8BLlF2vrmxN4EMpdQO6QvqzY0Q30j7UxBqwRbPdAOhkeCGJnEJCca7AoU5dU5XZAp6MZYRuA0HYxc4OPH+WT+Riw/AO/IzqUNTIThf7nb1is41pDnU5YI0fpWRjL6xvdoAzgwiwyGZy5dbvOitj2+7Sk2KEj4raSvtae2Ja0Ppe02n2pzub7Db/Oivibjzhub8+y5S5p9deA+CtbfdZUgfhLllcg7sTyCsSdWF6BuBPLKxB3YnkF4k4sr0DcieUViDux/J8B5O83cA7y/9BWgVjZIuWIj/wcniI57M8zFZ8yHU30QMtGXAkIIRAngh/j0V6IWTLfhsg1TI7Vou0uPNchf1h8nKkC9FBWLM/PR8SEEVbBS6MsjA4vB/u69B1TuFW/o+c7/RtLFVhTeh7oIsGF5v/bu5oct3EmSgtqgPBKAdJ7wivDp3CAHMCLzn2EXvkYWhrfKT9VvSqySFH+6XRPnBmqZ2JbJItFPpGUzadXBRBR9LwsPeZAeN08ZyDoZ/otA4E9i/VN+dF3kaVQSjj4ChDBpV27HIiump6A4P2JoECEuKmpPBBfANG5kNgTFZJFd/PCt1FhYu4l+cQC0S2A6DIgltyIBRDxfSeN3jl9dx0I9zAQ7gYQKb0rgAArhNUC7gHCWSBqgizXgXA5EBJvZFTlCPp/K2wG4lJsYyyUxN/YgX0gTASkg4ug0UvUfWaGnLHBIwoYwomQHQaPwABr7IjRs4oF1wQWBf1dUk7s+oq39KM08UoOwtDQ7t+J56PP0y1DhOXtPfQ2wAlRPoZuZUHPA+obAEJ1SHiiGteYINq2bVQF0b7irTfZ5dd4I6NeMBIWgzcqsXMcmRWyieg8mBjKRFBhf88TEKKX0H4vgAA/Q5gdHooU2PDUdy6ssyN483EPJQB+eturHsA+Y4bt5TH1w8ihCiJjAkAoM2Ms0u2IwKa9qiYQJ8QLH0OjVZA/LPnAeiAIybOHlkIQlYQqE0Tbhi1n51NfafgQASIkIGREBGExEBAyTuIu7uGyvcgAVSbCiOXGm+glaUQEYWMw0eYiQgijAsHvxnV2hOwCB7IQmPMR5rzQwEhAgCfB6hpCStBUmZCIIeIYwCLdEBNGeAUPgkPbkmSDFxkJ9swpEHyBMP8DtwI1Joi2bcvjF/FcpK9cAcTWKEcIo4NZDDwiXA6EpMkZdg8gTt5EL9E1QqQRFCJRpPBOgfB6VaywI4SgMgaRhGAbooEROREq9kCckRUgUPYaEF5WIV4iXBD2E6KzlECkEcG5nAJRZ4Jo2xzv5qmGiQFin0ZEcdekFBCZmlw+NdFUw1v8wkTQMl7j9LgCiL2J4MOKFIEXyk7YEeikOjvifOapCcwLB6YfpqZE13KADUodDlFUciB0qjif83TLEGGCELNCRgCx95FhgvgtBoiQmB5C/vBxaiqYIC62LRhVEO0rKidr6iHyGdL3iK2yGM6kNgFmxS7KUDErwTmnTASkg4ug0Uv0e4TqXmiKKFIQ9Wzq9N1lnR1BpEXoZnSQ3eL3owfnIk5NZ12O54mTo6hoi9JifYDEVZaeMUQuiKWoQDCn5QzWB+K3mMXaK5NFmR9dXKxLJoiLbdsaVRD0FeK5mO8ttxgYlVvaK+nXrYXVb9YhsxHutvjxo8YQ+ejR3ajpSppZ7KbPbN4ta/cAkbMjPte/mi9f/RNH+I3++rKj/db0JEcDogHRgGhANCAaEA2IBkQDogHRgPi3A/F3XCvP7uUn+NeA+AP+2Zgj+tsmPdO8lU3DuGtSHjd/lAs2n6/qX/hqiZVjWxQFCwPaHM4vLYalbb+mw6G+bivehJoPfllLWADBv11f1D8t21Va43IBBv21X58x3iYgxkU7zfPO9f7NgfC+7PnOKko4kVh3rhLtpKaxkdEQrgBRBgPxvuZtiG1ymTflNdhlrtlUXwDhxT8X/esWrVkHImKJfdqdU4ZDDQj3CBChpKDkzak15brGRrdgYdSBKEeEd/8wEEH9qwABpQiJTeKTKoeKnNOIcLKNjl0T3sYJ2Pq4THgw2DAj+Owuql1gshMWA+oZfXxIGFwLy9XAj8LMclBtizPOXNHYGMHCcJGFgVYhfgrhLnyKIiqLd7vYBjoHb8V3Uc/gba5pJ9tDyhbhzZ3YqiAaILCh+aVn2Kr4N9o+1P7CJ54oINPvkij//JF2jghFWiPwaHkXWT4pwsI7tg8NMwJbmXvhgSjXgvdssWnKOvO6343k0XA1lLa1ZzuRFXJdY2MEC0O9dOB17GnPmwk7ThUz8qgsh8n72Iag3u69Vc/AM+YSa8FpLBaZjmOrMMDI7t6r9865aBX+dVPWhxKVRoQziK0AlkQcEcxx8cKY4Kf8R1AkvYbL4CgmCgRNXZ2RUtA95WC4FvR+K/oX3vnIf0Cq5WpobBbKq+dx5orGBuISsZfwEbwOjZ+C+pdRWbxtQ1Bvc/WMrXizvcS0ADZGh6gtF1Vm2F6SXdS3jVbhn/OmD2UPOyqYQGYhWM7eBCDAmCAgvATnkOmX2BIB0VT4anJLIITH4xIQwSmfI0QgVMjLcjWggIHa9bzOu2saG52wMHz0UZvJl8Ret17LqCwJiOCYAxJFLox6xuRcksZQtojTNgslQvJEu6hP47Z48c9FlkgaEWCAERB775ILSZXDC2OCgAhMKdGNdTfGmCN2ajKuvntlLVAuiDowm4P5HKM2TLQ2Cq4G5/dCJAMrRM+saWwoCyNEH6F/gfgptBoYMR8TlcUAgfM6uRr1DETkoc+a5scgKiQeebkGjsASZHRExoZQbrz459U/AIF1Wacmo8AhYlisn+ElUgnrXlzmvykCEbAIdROkqrZTxoyYhNo4BeFagDvIZZjPMUq0k060NnKuxpbzI0aJaFvImXWNDe/AwqD7dPgI9gjip7i4WJdRWbiV0obOKTMkV8/gxZTr1DQsrZTusRyf8Z2ES0EiRfkbZ2V6wL9t7EPhgDgs1pFZfo0l8bHvrMGt3Tqu51QvwuKmOtwsfc3Lr+KA3FND8Nf8W7TrGo/g94G491jz4pp39wDx9SyJ9Ro05U4grh3tt6Yn8a8B0YBoQPxNTWxANCAaEA2IBkQDogHRgPg7/PuKKr5aBuVfyWJqQHzaEbLXsJpvW428An6CC+uPLiWuxGGh81HVtLhYhYz5F1XRx6f3Eo9FoqhcU12NRxHzBRFSYG2hAhK0pet9kDJuK1Fg6vXmOWQz+HIXEEn0wJuN7q5Sl2yLT7WQGUrasDXlbIyapkUuzABFf3BJZFfaRFEJZcszRZBazBdESIG14IuIK6PPosgs1UksD6QrosAUeY1tbBbFsr7eF6sjouRaXAOiW4R9qVkIrmROLDUtFkDw47/gkjiJLxGjqLg6ENmZIuYLIqTA2kIFRKQ/UheWv2/Xgajm9a4Awra50hfEPcA7cBKEo+B2wrI4RFWJTuOl8HnlNYCfgOBLVk8jWfDx0VaV10laFUtNCwcqgABBzIcgI4LeOwRc0igq7DM2doRH4bVujaFiY77IiBjVmu7Ra+6OpYgOyD2W+iLUQ6oGIo8Tg5Xia3ltvdQvqR+Rv+wL3mnFc777+FQ9+A5etCYkpopXIKDGsZetUVGxWOhpqIXEB5lrGZdaFaWmBZ5+jkCEbtrJGkHvAYRGUdlOZEEVbJIFG0PFxnzBGpGsYY1IuTEt+RRTI9cX4SgwaIt4zqyUqhZJEWsm9aNqm5R9MXfDIQ4Z6EworwCqEqoZoHFCoFOR4i+IikUo9TTUQuKDqESC1aqoalrYqEIjJFjAJRF2ldW+kn1zUrhIFmwMFRvzRecMtZZICKEA4mBinaSysBVEGgXqIt7VtEjyetG+qM4xYnLL+4K6YbRAhFF5BUoqSF0G3YgQeQ4AwqMLCj0NtZD4IDWtipqmRZcpZKQYKt4pEGEBhHAnXAJib4AIhg3iIjPFLSOuxMVaasj1RXhEoC1R5MEpEGVeW28aEazOYYBIfWGulKQz4UzcEY2pAl0Kmv+E5RBDMUFpqtTTUAuJD8KklUrUklzTwknslKiQEYHQy8KZ4B30R3FUmJNhLKQYKjbmS4qQ4mJnZrlHH6PIlPoikMFQNZCQpia31CKBUomNNTOvlEadAxdT3hcOvAM0axv1Iw5GZUJUJViXwglrgwcZcS5ExcKFUk9DLSQ+iFDRCq2KUtMC3yOSQobGYqTSbNsAIUyRAIWLZMHGUMlivowJCLWc5Q5djCJT6osw2ySqgYjnzEpZapFAqcTGmpkvgqTOwfnLvnCPHSVfobsi4/Dx42tiqKSb1aW1Ze5SXyRcaV0tb95n4Ur+Dx1L5L4GiNL2ZwCRfL8HiFrZ+1pX9hFu3L/8aL81PcnRgGhAPJXPDYgn8bkB8SQ+NyCexOcGxJP43IB4Ep8bEE/i838Qpj/Zjr+2PQ2IBw7asjuM9K7GORD58eycW/z0l86n2CnBgYeh1eD3ziw2i42XMqoRYovgd7MglhKrosYDyfL4/8mWDjZ8t0WJ9dQUQ8XFp11Tq2yUeXBWOm1ijf1yyftJfwUMpfOVDfywxjnobHMN38ByFuqxU3TbSI5J5d2DlOnyqB1jgrUrgEi/Vga35IFkeYKKKgSN5561eT01tdBnPI6uAGLLWzlbEAxG2Y5iz7rqhZmASMIQpXhEZ4BY5RzInliO3biQNElAxPeqhy95QgmEexCIKvehBGKMXe2uAuGuAdHljBVv9wx31F9hhygTl9S9tpOzGaIChCuA4EOYFH6VcyDB71UbQ+OqlPFTlrFTHG/tpAA0/Oz1XhUoOrfFhtHZAhEFicS3TBVjrPNAbJ5OVC7ADelUJSFqgqynaqwUYnIQW4RrC1zL2UZe6Rw4KzoitB9Ii4F7YERbLqI9spV27bjHpEUuV+ogrYco6b/KOUBsCVGt6GLUCMtZqMdOccGOCEoHzHtR/ejiY+kJiKDyK3zkqhg17sOepBZMHt0Z7iSs09ytY1LZcFdSoQ9CQPCgHTXoAjY8MyCYs6JXuued7NmDEb0Bgo5qHsTNKK5jzxvC2PlmbsveaV+nbfBbnAM8o9/xAtdV4qdUYqeMLgMC8YSChIjpTIwVA4REMdFpx6piIH3JA7F5OtPVwjtxSWXDXUnd0eapEyD0yf6g07YFApyVzkxq3BLD4KDS716jwvCIuOjlGy8EPrdVnowFos450GhVCgTHBRlzzkI9dkqXLdZ05SYggnaZK4EI3gKRqWK4Og8kyzOmrtZ4KEllwwJRppKOhpsAhHrgxxoQXi6jHIgwJgZHpyMibpqmeURGRGwd+tqP6lhY4xwogUWBgABUHj+lHjvFO6wRsvQFLRmKqUnSZWrCZ+dEwcOoYtS4D6LxEfOATRKiYod0ddQEWU+VC4mA8AqFALG3kVc64axEINReSEyRbjE1gYoGIHYSaYu1SfboawaCFt7DuMY5gGxJENUK5HA+j59Sj50SELFkAiODFTzo/QTa5kFYELS80d9BF2uwRST6V6aKMdZ4IHkeJyHSEPmFLGm8FmiCrKdisYaqCLd2RO6DRIGJvJKJOCuHSLrumObJ0xBsjPgeMfpssT6jDmbNiPYGa5Oc0dcVOsGjnINrShegcnUV+nJuX9P/d7Fll/l+7wgP5e6KdtwXeaUMWng7Gs2qV49yDq4zcv5rP3Hcw08KVz59eQP+K0A8fQMaEE/SgAbEkzSgAfEkDWhAPEkDGhBP0oAGxJM0oAHxJA1oQDxdU57BynO17R9uUwPiZmn90byb8ggj86+ZIfuse69ha8pJnnybXPZH6Edr+lX14BCZBQwIPLm2VNW19WW25QxZSlagyrGwsmB5VDQvqK3ZeTIiLA7s3Y9ukT760irUD9A2+ATqwrJlYyGKMPfAqH+xdCroi0gnvItjNsO72D1dBYiuAEJ3D3ifAdWNYEDIs5xjoZnhJMJArDnVJJYzKy5asTYKbY2s+bY3tgutZhtdhGv3SyC63FiMZa/cDmyjlT55DstgLcYtFd7OkdIGiEJWxBfYXgdibUQkIA4XMCAAhL3ifKyvBMItgFAr8vz+JbdRRlpx9qFsc3a3CkTkrITaiIgkIi6SgIBP3cInBcKMNueynUUtHX+4lQdxRRWD9ekdcxGIm8CcBMvbgQKGzAbgK8x+XSY9x0yFM8dLkSufFQp4Qytdy0kFQ+szihxy5SobIo0rsTJGK5Ns9gjkuVVlh9DndJaioeC8KmvoxhB2Bp1hlSB9JB6L077B5UU2pG0iXWR9SvoiFDEGHJcRm6kFEJ3l8zDfb8IWKK5ZSkAEk44jk1ggRAGDj3d5HD6E93iO92XDXhs06exOO6ppJrUqGEpyUj0Nrek9xTAZrZUurjSqgqD8idwq1j1IPJizbq8SP6KsQW13EhAh+FRO09+ZR6J9w6mjxn9QbkcI1qekLyKRYfbUaxhPCyBCHEhQzYBSwDaOpHchFbxLFJMExLsBAjFVLBD4rN2Hq4b34ogBMXbGjmpmKBBRkSMCoTFMAIRaSRdGYFaWlBlLqyrlE0RlIa4loppE2hrEtthJdBSnU1OR/o5Nfu0vrzZ0RJBPIVifkr7Ie9xff5ebgRKIeRSFWDQBoVFNLBDBrwMRXA2I7RiHeOxCL6SXZGdfAKF6GgkIxCUpreRAuMku1taqBWJfAUJivThEQ1kCoekKRFxQ1caYuB2HSwkEWlMC4V0JhMiJYF6MQPh8ahIg9sqtQFNJAQOf8qnJSIKkuXYEVw4MiJABoTFRBIiop6E1Uc1qKbPic9KNj4phudWgEV3mz+lsl87vkwYJsSo6uR0p089nBsKrSken0/oIjkdwUdbL+ITWcMQYtkTvhIsif7E0eNFpsfasaQF1CScRTHi5OSu3QkN96SfwFYjtMMaYgyBGQqOJ7rWhwSQMiHjdJBUMrS/paWhNo49KHqO1km4eJCZj5E+UVtE6+pzOHqZ0XmO/SMwXmtyIsVGmB+KnpL7ZjrjRQdvgUwIi1xehWwRwXEIAFyV9j4ilnXuEMRGufCrPhexOfO3bZ1ipL7u99LeslDas1bBSV7hipXO3lDe6O9p2y8vHS3/oyBkN14G419K9TocP1/WRo/3W9CRHA6IB0YBoQDQgGhANiD/ldAPiSZxuQDyJ0w2IJ3H6eYGoFfpsqsnndfbzefRpthoQX2drwYf43yX/VYYVgnPGgdkfO2QPg7OtYH9sU0v4vUiV7bfC2cjzWKYGWSrjpxSeXw2PrJFTYKWrP6UWTG5XMjA8byQfxtSyG/6gnUU8lrDqUxnPZQou5x6UvzzSRlHBOBBpaC4zWp0KFicBSIVGBX5BVSA6oQrkeSxTgyzJ+Rg/pcDA54yNHBeNnAJLvsbvGHOygu5EpG6TZ65Ty/zSn6LW7InBgoNQ+GS32jw0MnLugQVCuinkjIOszGh1KhypVAQFwl4RqHbal0DkI4IoAWBqkCUBIsZPWQLhVoHQyCmZpZi7WwXCLYDoYsvKeC61YdkVgXHCuk85EKSRoVf3BRsZDnFVdrIJQvtJOeNAeUvliOjYbVxVpUYF4oic8UDv1Alno8ij+10jLMGzFD+F9D52kR9B+W3slINEdMGUoZFTYCm4PHaKPqZvWSOdTC2WN+LjDpwTS9afrUSVgU/gvLAaiMPnw5R6suIT4rkIB4W5FnotvEuQGsRV2cu2ILmeMw6CgMfXTwYEzcXCZSg0KnA1pcfAfS2PXH8sOjKBP2Ljp5CvGrMFKh42dopqdMiUEayl3SJ2inK3EmtEN3wsb0RHhKwyWTwX3ZdGLBp68+51aoLiiDc9ufQJa0SMxGH5EMzVGKEsAb0Lh2pCzjhQ8DDT5sotCYhCo2J0LilUdJE8U+hYjEoQcCLTksVPCeo29Dhyxga25ElRQ4d7srQvYqe4CERijSQgEm/ER3KA8zr7R3WRyB6RyCoZEBJaJOvJ3CcN+iRWLB+CuRqjjAiQCKWanHEA+swaEHIXVmpUjDotQyjBu6qORQUIc2ujI8KJHkfG2KCAIXu6VCftqLLRBb9jzFkjCQjljaTF2gIRDBBgj+wRWaUKhO3Jmk/JiuFDvHO0pqRRo4wFVzIOQg6E0anwevtaalSgoWM+NS3yGKZGdHVMd5u8RijTBFNTip3iPXELQyT+jK60lPM7GIjIGsmA2CvMaY2Az8t4LlQWPlWA8HlP1nxKVgwfYmRdi84ZXsPo8L0hZxyYMvQ9IulUYNkBFy7XqIAUlSpUQI1ikccwNZAnj59CyhUhMU3OeeyUjhSQ3CJyirGU8zvoijJxXAQIyxvB9wi0mqyU8VzAHnHiEzgv+AODRVVDokZHxadk5epRxApZ+WZ9W6ci+NtaGhqx8KqdWqQUYyFkXtcshUq71ny51uq6B7d78g//xHGPRoXm+TgQZezSdSDu9eW+zrvP5n22vhiI363jz1pqP/o1IBoQX+NRA+JJPGpAPIlHDYgn8agB8SQeNSCexKMGxJN49NepeTyju5/h018nqvJfBeJSPx1umA2Vz1bTYj3X6NetqbqFYToIb6KI65Ie1r/PR39XX1VzgX/RcRTs9HhyOtLTg+Z1WnoRbTjbrtHGJukqfoSKh/4GEMHfC0RXhuSIrUq8ieBrPI707CY+dZX+83cCIZufyYav2QH/YusgTd4V5VN7OpfoA8HXgICNbcZPGX0BAiruiuKldMla+lLTYj1XoWxRAJF4EwKE8iZ8/Wr/HSAWF1kVCPAvdqIZsBwR0z5dWOkyWfaB2thl/BTmttQVLOjdReN/jEsti2V6TdNiPVeubGHzsdJH5E3guefIm4hxXaD7ERBpRcTUnURy4TgosvW01doldovWgTwc28WJJ24buSG5HRkR4pOLlArry/mMWCxbpikIi8Mv+0BtyKiRdhG3ZUXBgt69C2NCNvQyLYtlek3TYj1Xrmxh8zkmqClvYnu2vAkT14Ufrg8SjUFCFsgGqoYiQXgEisoiQQn2iW8heST+i0wqkRuS28EaoT7pNjGio6gv714jT0R/PHYq8z5QG52z7Xr3qwoWgYsrO2GpZbFIX9G0WMuVK1vk+ZLeS8njCFwiByJYIJjWQAyMrSiKMEfi4iVuSuJbEJNKa9PdaMqHXLkdnaLEp1H3mq0vCQj4w7bHZdvURr6uEW/ELFiW4aDFYySTQstikb6iabGWK1e2KPKNJRDBABHclRFBZ+hKdsyLmBL3aAsuReRbzFmm4HIgoJ0h7AtrR+oWcl0cxdaXsRwRrgQCtamNnA/ClMM1BYs4oFxNy6KSXtG0WM9VKlukfC7jTWB4jxYIOzV5xCeRqYBTaW5XHQwXY7sEmXSUb5GmHQGCI6coNyS3k/gX4Jrgrmk3WV8ECA8qm14Yyz5QG11GQxip1rqCBTnCC+rkXU3Lopa+1LS4kitTtrD5kroFxLBKICSuC3Q/JsQnOQgPgtUxhIPRyWJNtj1uE86Jb4E8oH1ypDCOnKLckMLOqECwTxd8j8h9gVYJWVF/QMQp+0BtHKYciLnWNQWL5U3i7fTy/vx2rjqf4hF9ilC/Ey1z+eterN7RujX+RbjDnw/rboTfTP+847OB0G+5HwHCfRiI32nXkxztR78GRAOiAdGAaEA0IBoQDYgGRAOiAdGA+IfblVd0rdqPuPRvCZTTgPjLj6uBkk02Zjq4fv7jY5CO+/VG/75Irhd+9/KGnK+cpiUeAGIo0/phrdTmpO9eTvZ8/mmTlXk9rdha9Y2s1SzquZfsrLQ797ur9rvZCF/8DtnFHMGUA9Nh7qIefdvPHUfVbLImbPjd6wAgBpzvaw3s4+tmCcRR66gB0Ut9SO1jpqG3eehTb/yytW5WPNisppC1mkWtc2P8stfR+gW0pM349XwWCDAd5i4a1MUbQAxuGPI+XwHCfQCI9NpXh5EC4e4Cop4rsx2ByPMO7k4giGNzmcCKyOOA8IZFjAQCuXMiR4H5sKY0MVd0fDkNwzy4j79+0RDczMPz5bThYUqvEYijOw7zkP12evmJf5Hj7TS/n/9eebB/m19f+PXl9OvXy096/TZb+cY5XvnTnOeN8g49Urmk+yapPVulKWKuzVin3Mk2eTkML1zmLdr/pudSrpUUsra0OJ+TOunTqzn77QRfgcL8Sht/7z5tPaY4II6DFGkkEOHpBDyou640QSNh6Ae+QHREzJ958plP9gDiZSDINu71uHHf++E7/zs4zvmj/06TFs8ow/weFuf0/tev2W5P7yk/zTl0XfeUn/POhqhcjyuPStKnGZae7BIQ1npuG17j/A+2T+97OZdyraVQTUuL86vUSZ/INs6+HnvOr9Pm7BNt/EUgsjggrghAwey0kXgXnVtXmthw5zAQcUREIOZFGkBsCCTKGVMHAMFuD/3LG5YabqDkeXEMxLzQIf/LG1l4fetlHn592xyRH0DQu1fOQ9bIk9x6bnvDM+WLUyDoHHs4DM7mWktBNxcWCSCpc8O+zD7KWbmI0sRWA0L1KYpIINgWdxaIitLEcRAg0hqRgBj6BMRAnw0QL8d0zcJVOyJmgzQ1HQm8+fo5ynXp0KXo5k08q0BogweelXPruW0A4U4JCHqfd7c7AYhaSj7GxGIEgkeEufBKIOYWlVNTigNCDLQUCcRGEREg6koTwxFA9P0SCJ6EFIgjr+sbOTvwqoWpaZ5Dv2PY0qzb9+I8TU3s/jyjHimPDG8ZETQ1fTth2hAgFKzvMjVl1nPbcWrqFQhMcjiXcq2lwI+FxV7rVH+WQNAFOLdI46VEVoRP+hQ2EohjSiIW68M1pYn+SIvjz81Jv0dgscbS+/Lzld8lIGjRpLPzv8hxOs5uzsv3acOfZ6h4kaP0eUTw0ktzGOXZzHleTgoE5aGlsedvDmQRqT1bW1rPbbOXcv7Yw5/NqZe8KddainqWW0QK1ckLtd4U9DJlnhgIV/la9NGjznR47Jt1usu3bg1ZGbn2V12/p0HDQ7kfO4YHz19vzW8cvwNE+l66DgTy/LuA+BJP2m9NT3I0IBoQ7WhANCDa0YBoQLSjAdGA+I0y7WjH6kW09r4dzwIE/dLRD9nvHX25j3zXT1Nxo/z1jf5cvyjTl+8WW839ut2aTy+unrZ2Nu1tvxTnyePNkczSa/9bP//YwsRb6fl3aU1jNeQLNDlIPR/6A7xdASBM72dAbCTPUG1lv2j2C9rbl0BsJMfmKhCbZS0ZEH20NvCO2cacTmlaoi/8TR1cEAS4+Zx6otd+uIboxrA1aumDSYWPTJZwym5xzD4KeAR+lPghSyA2vJmVV3MXEJLhG+8XwMawdqkMCyCGSotwYrA5clZGpM0M1cLDA0DQFh1tKfHrdSBufc4vPwHiiHwbABEUCGK/BOfASKCtxm/MimCOA+3ZHL/xloajDRAH1gKYCy/Cg1CWhGz5nN5OxN8Ax4JKkw3wFN5O1MC51Hz+jco67LFRbraIjRsunTE6for9I+pkfkj/qh6wReJV0GZNmaYlXoXb8cKbRZHuJVs0L9oGInwRq6RnSI6KH/gfc6435W3wWe6RuQ7hlCzS6R315xud4z3JI+3mJ3bLnGkktQ4ZEfSeBi9YEN95W1G5ChsmSRAQZIrPE0diUL4C9mfxr25C8n4u789uTrSvLIyFE22ev574vPvBTA7lYczljk6syiaiMDqYezGkXWDdZqQ9T2VJfFdP3TJNX/vIslAukxN/ZdPTKZeC9vvIz7m9p5TPxbLgbfDZAVPTIKyRRfrcKm4ft0SB6A27hfY396zWwRFW6P3Lm9nzZVdfZCYj9sOPCAR2dAlp5k1II4hRwUDwFnnPPA3en+buBq/BuR+yY0xnfvQvb0otYXYFlZiXR+ZPZIwOnIdXL0IT4GWUawVLIgGxTItsC7oM3tCqRPwkPsWrsDn6uC6ynwNeMcW8vL0wAwR0AVAlExDaC3n6XAIkA25JGhGJ3eI4wlQ3SowBEkVBlzALQkaEO2F6B5+BNrctEO40uATE4CwQQ+xKADEkIL47BybDD+1qBzbFcCT+xtzvp8EAwYwOPo9amF0B1scRtYIlEYH4vkxjbgWnEbuIWtXzv3ycBhBoIogJCLrbS0DACvaYB7mzRI/MU81ReyFPn0vwiKCLAkBgjUjsFnS+dxaI730fR8R8EA9iQ9MlN+HnT9yb8GSUpibhJ/Ty70amJuZvfE+D/hiBoDmf1o4jg0LpRwc2xWzxOwA4xqlJGB1yvueU3iFHP/S9siTi1DTbL9PweuQ0ahOPR/YGIEcvex0R/IkrxqvkEwaI8jZA+iFbm3Q5lunc/bQ6ZkAMid0ijBkBgkVkmG8hQPAsSQvUEUC8/JynoiMtaBvmWnyTZRUkRrAk+N8juArgb2DJpFxHZizMY1FuZF9Ps13hbBCDg6yRXSyIRyyNidHxU2s5OtQJexthSfBNBv9tTuCO2DS8HonRwdwOatUGXA5ZhOElmB5xAefvEXiVfMIAUd4Gzr4a/kbvlum81nCfgreC7xGW3bKFrkd872pfRTbZzddwkzS/uZUB86VbvZNdueu8XfO6BZs2ZF7e+01tnZ5glvIrpfLyD//Esaz+5eR++wAFeK2mZQ16G/iI/fW0z+ZIpJvg+4FsvzU9ydGAaEC0owHRgGhHA6IB0Y4GRAOiHU8KxD+L62fXtrT3116nDYjfPhCPvX6kKMv5r4OL3wovkYsQg1yU0U7kc4g21my5FDmF8vi8GJ/Q2pLvh4tbqadMr9tjWyZ6C85IrPpgyy/76EYsap/3ZFjP2BWlko67j+IPIVOEwMO9qZzhIkxdUUKtyecxlfEVy11R1hvdD7HGHYfaQgqa4QpPx7yRwfhas8eKLibKCc6gbzhyxXr3eb8I/dEtgNA8Pvq8DJ4SSiDSq3c1HBUIlwEBLkIXyq5JQHQLILqFZbcCRJddOFpbHYiuAKKrAFHaM9Z4rOEM+oZjuVy54NdiuWRApL6r2mCXO5Yy34kOB5Q2DvxJxM0niJsjLgg95Eu5EYNEdDhG5SJASZ7Oa4lOIpUgvkiHaCWTxB8ZS8uwiagsyENdOnfFKFFQSF491rabUm07jcgi9dD7FMvFpFftkbVgopzgjBvTiNiKj5j8tOUkvc6i79OyFfOMjdgyE2TfoV+y41T0MmK2oATHLaEH3BHzA1OT6HGQMIpHLIjAEv17jojiHRQ7JOIEi0MoFyEESPXvvZaQuAwSXwShCkKMtlBahk1W7pc8cm0HhBpAsButbe+1tsPo8aB+rIdbE8MOmPSqPbIGWBHlBGcABK8RI4QAAsJUuBQ95sAXL9QZ8laQcgPkAvBkOgIroEfQy5ALwN41D03S3oD4g0ZU8BwTxHMEFAxNqoiikyCGg1YnOhyjboErEMFrCUQXwTXoJIoKxeXpTHCPZBk2dzbPqHO+dJx3acPdp9o8+6X5O/FfQ9OU6Qt7c/LeRG/Bmc5MfZDGoL7YXlAnwk95kUtatkKA4Hw+hRrxnYQSEt0GjuQiQJD2xr4AQl0PiKUl1y2anEYEdDgSFwH3GQkIxh8zo3QAv59KINSyaH+MKQ9maXZ0vB8IN5ozGRAr9rwGcQpXgQiygqHOEoi8FQpEcCUQ6LP5zIh+Yq/gjA+INeK9DmtUgQgoOvTmPHukzatBFExxlouQRoSUUGuyQI7exWkndmOyrJGO8jy4TqXj9jynu6QBUgAh9Yj/XidA+2lpL1kbBQgd9RkQ6Iu9iy2PQFRaYacmb8JRdVHPhIGgVYFq3k5YrBFrpJswn3UTliFEFcFiNHLEFcQqmceQCGzxYn2JXARZrLHcUomDRjfh+CLkA6KbHCRWSW4ZNjWEGuVJ9/2y7J+3kfmwnbQ2mUhjHBMXxP8JQXVSet1esqZAIOJKAmIrty4UjUVbmC/WZStYeMws1nyR8Kqieiad9EU3mZiT6zdotbvxMvfaN9HgXHHj6Kpn7qk95b3+vbe78fkeex/7Zh3cJxxfD8TnNeFZf+II7o8f7bemJzkaEA2IBkQDogHRgGhANCAaEA2IBkQD4vndUp+e/dr9VP/uM9a5+47ujvzdDcvdfwQIs+0anLIc8Osk1Aq4M6aixHin9bGWHzyJAHYH9tFC/PVmXGwMjwkI4l8YvoX1KnJF7mlp7fzN8ncAQYyTTn6XTr13o365/iKzwwsQqhyBHVxJs/wPv2xJVyT6VQdSSJBgY7iMZqt9kd+MCN6DVN+6LHN3a6R5V8/h7SdfbVVZpp4GxokXfkvqvTuAsMkRiKBAlAyhdSDcNSDCg0CEK0BkfIvrQDj32IhYAvGoqZzfsuBHpUJgF/BWRxDmA21vcCQVYR1MwnKIV91WOR5zzhB2EqB+jctA73c4M+ezvKMd50dKcGBZ8GbJGZ1wiNFa5u2ezHYGBG2sjmlEKAdllzaOwoXr2UlMGPZq9pxbGtkZ4pHT9sAbbP1TurSB2R81q6nFyIv+BOMkOPBb0HvgzGxjPVw7+AZOtrI9Nvr24BiAdRA8OA1pjUDklQO5yYVou09sVLgMsgWLrcYAIORK89hy55Ag41428NVaJ7XjfW7bAtFRh0XfEgdln/a0wztFwACjI4BPQZ5TSx12mj1Wlz1iyHhshyrjAkyuvfAt0IbSqjMtdrDBNYFxsptCSL0HzkzQfkMbhSLChrGh2Mk+NoCgbUi7uY55IvI42CuKqqLnl1yGrQMfhPMJEDpZHS7vEsOFys7lmPWhnY/adYq0tvM1QrtcIQMHhfLyiHDoMmFLjJQWgeA6Q5wy0HJ4EOL+shfCACxQPy2tSlrsTWor1QSigxKNHE9P4MxspaXby9ZlQHhhPigQtNcLHsc6ENuRejY4C0TJZXCTbtwHyr9PUz6dkREhNrnmSJtE7WI5s50DERZAKOmHz07oMngMVoljz5X+EOISJCPCGSD2CQhYoH6qWPU5EMGhP0UkyyeernJmZgti100CBHPhmFMgQOw76QKQqizLQcGTijn6Uz415VwGoXo54iowReEclwhu4LvEcGEg9nZqmoFQStecP7fNUxJ3QOlb4qCQHTs1zR7IKBMCDE9N4KkoyZNWBVoNlanRsb9emSzMt6B+qljda4vRm9qfOb9FLnnmzOjUBJ4H+AhO2RwExIH5E2ApdPxqWQ66KPMEwMuNd3axLrkM23HLXAziKvCy5C0QlB8sDw4add7Jkg6PO2WJzPlz28yzGOmv9C1xUMgeU0gnihdDUWPIY1pWhXdxZg7HGZwRvVoPTBZVpsaB/e1AO/XgW3RCuiysnmOLubO1P3N+i9wWMWcmLtbnyIgP1RuvxNNe/3YYKvdsoXZfbsaS+40j2PtzGREftOTX7Ic78t3n43rfhUcMpicX1htbe7ohXLVZK/ExIG75dm/rrgPxe/5+ChC3jP3Zo/3o9yRHA6IB0YBoQDQgGhANiK8y1oB4EmMNiCcx1oBoTj61f90Hc93L2biW++8G4qM9t3aM9kPOgajnCpVyer67o7xtaM7ACMZ+iBvdUl/OqMD2Uuhqdm/+TLfgUrhaWxIDo5uqDIyHey6CM5XeLmgY+WZ5jZewFDGwMgy+2gnLzfdOrziv6hRJ8WINiIrCRah2qb9euy+61C/so40+MjB89NBXqri350wJ/zAQ7g4g7FVUvxjXWBBWAyMpXjwCRPCfB4SrAGE1P/Dg+r1AXB2RrgoE+AYHZkl0wlXY6bmkt2HVJOSz/EnKbsIjsLv4QLBlXehGi7AmHBgOxG/YRcaP6nQACN042fGjsuB35AoXlGsnfA3lVuwiM8LWvhWlEdnscfqD/NKnbWzjITIw0pg9lC26s+d4YynAC2yIRY/PyvxQ/gZvW4LDQNQEnEt6G8r3SMwKfaxduQuqTuHNI/KJdYEtQi/2UAYMDJFeCMJ98GE01vdO6uNczB1Jj5HDpz22WjE6yPp+WTt4J158UPs1n4K00fE2JxgYu7hGeGybxhbd13PgaeAxfi/KHOoxtWQfRRjC1qk52urjzf6QCABb43piVjCbZ/63i40Cd8JX1Dt4Obt0IxgfWqZkYKDzD/JeWQ5qvSNlkEzhwnEO2Z8Gt+JiRVxS7Up3gA/wnik0C58g1gXGhjIw9ob5yFoil8d6DjwNygsGiUhrhK1LGgZizk3JnLAujDk35UDIFDvv7s4pUwIiRLaGW7AuwF4QxseUgAgLIHREJJYDxsVS4SKOCOGgGGmGonYFAj6I977mk5tclH1RBkbIgAhG4ePennM8NVGLLBB81gAhVCg1J6yLYLQxvAEi+6xTU5Cpyaso0IJ1IdNAVqbODglWz4MhwErRCd8hn5p2zDkEZwIDPU1NqXbhncABX0xNmU+xjXsih1nND9zveGFzPNRzezM1KRBmahIgsPR1zJIAewOsC8PEiIut8jrsYq3KE7pYe7dU79DyndhDmZKBIYJZXjU6dLHGvdNBCJtJ4cKJeo4XDgoTKb0u1rZ22O3k33yxzn2K3JVzN+WaH/gGAM5KtHFfz511WQaDRPVI9OzvESqK43+X2qdwtczaN9fyHjx4d+Wmeb2O8Jtt+heJ44ZPaSjE7BoQX3a0H/1aQ/8V/jUgGhDNvwZEA6L514BoQDT/WkOf278/5VJe73MC94969TcB8Ti7ovstm4/2zV3+BXktGRN1vsV2kftW5JDuWqXxM5Q/8Owo1atPeCurIj3xPcbt55D+Ha2xm+yKiorIVp8T8ovcFdclHstYZXpcqzmvLW19e7e+UV8qXgTOY3Vm8hgsS4qB3WI3+dmxLJQIbZdE5Q/heUi9yqpIGgg5EL4SFuQmu8LnHuGTaJmv/jztTSvx8HNSFrh99ddqKzgOV4CoRBipAOHuAcIVQGT5QheS8keuAhJZFVEV5HEgVvq07JrV7FUg+CnnqtaGu27B1EZD98Kcg0NkFiwZE6XiBVgPGrckRk3JI4dMGnlElTigzGFjtlDtHQ9OrXve1Q2s/LEngFBvNiLo8z6NCImTEjkUPNgf4KXIg8mFggd2lHOlDstPwYSXlErcaJVKatofGj1lrTZG5l3injiK3FBlTIBvkSKMgPXQieZF55xskNrIISFGHlElDmxaJr2MvYQZ6MzWIb2w8scZQHRR3ARrBH8+qx/Yl97HjdpMV+QOdsU+6n7kCh76OHxS6uB51ycFAlzVqlSiQIhSSV37I1qq1RaB2LJexgETz4IxAb6FCWwhQIC30YnSRh6w4hAjj0CJAykaTQTcCQViy9oWVII0LBCkQ0aEUF2cc5FVkegG794qZ/gkRXEnuyIY0RWr4BEuS6UObaNyMaxSSefSvvaa9gdYL2u1RSDARuBYJhXGBPgWSyBCjJqj7DizPe402pBSCtj9KellyJmRY4xMgZlldF+UoqWg3hyIUAARXA2Ie3kpFoik4AEKQ67UoW1ULoZVKrFA1LU/wOFAvbXa+D5HpiaahIKy6nLGRBlhxExNktv7MnIIugeRWpCu8ehUL0P4HWM+Nbmg2hWl0sZS1+J81s7ce6W2Pcau0KkpV/CgniiVOkh1I0IOyZioVOJFj0lrr2h/hAL2oja+8x+9xD05g3ewZEyUEUawAB6gecG5u6mMHCIsCfA6zt2kGhhJL0MYFeEwbQ2N0mFZGykWSs7ziKyKeMNLzUsckk74EPezK8D5WCp4kEZHqdQB1RF40E1bZ5VK5p4ZjVJJTfvjnBbrWm1u7WtKflz79hiu3qYF9/Gje+KfOMI/4VV4EiDab01/trIGxJNU1oB4ksoaEE9SWQPiSSprQDxJZQ2IJ6msAfEklTUgnqSyBsSzuFeW/d2m2vLPJ6ZS8aRzX2n+fnbFfxWIBVchLP6lY1uJL6JnUi6JiSI6FsT7iOyG0Za8xq4oIrh4fE7q2rb+km9R02lFefrx/JDFnegk1jt+z66VDff15fVsftFH82/C+gC2Yz19PFO/kExYAoEtjjWNGp8B0clVTYwLx88v5+yG2+wKKwpPVvBZOCTuOt8i+FRLl9njmCYmJI6jWBASOGT+EXvMVY+9W1Igukr/Jh7KatyVChDal2jd/O+UXU3azBoQ7gEg9CqkrbKdK9kNt9kVBS8i4HPaDrrGt9BNJJsH5TmmiQGim30Tb3nsugUHxF+91EseymrclStAoHXzuAwu5ypwWHphKyRlDLAfUFgf6s0jjmgJiq8CVgYYF3StpBFxL7sCvIjIohrl84hoEDf4FvJwMPvEcWG2Ut6HLovWRZ8h7jBbxohwuYLHwfA2rOpIqezRGa+2WdyVpBuCtBEbb9Sy0cXWdcQKyrkKGBH7uPkIHQDdfTUPovs84kgsEfayhQrGhQIB+tG97ArwIjROVSefoZp0k28hj8t7DkaFABrCs6CUKQFBn/cy3WGNUL0CFx9M30fehlUdKZU9OuOVSyFOsofz0boxylnIKGLvqAvcMqqIZWBAGWNr1gjiIoCNkEcckRJBSQXY6M9XlnvZFdiO181HL591jbjBt8DYiyFJaETL9n4xIhgYb2f3UsFD27VQHSmUPTrjVYwmw5yUpBuyFTWErbNASOucAJFHFUkMjKiMMZnFeuKcUxlxhErs7wDiHnYFOk6XvFAB4grfAg2cFIjtqPb4DimPXyc2QwZEUvCIuiOl6kip7DFmXrkUd8XohkwAwk12jZDW0QWUcxUSNyEpY/BA97WpyUYcwQa+nZrSlJYWqXvYFeBu+Ljsj/o5AXGVbyFTk4aaYQoCTzWyWMe4E0FJMGPyL1PwKHrCG/mXXNljNF5JNBlog9ipif7OZ52aOtM6p3yNxFVI3ISkjMHRVpizcZjyxTpFHFH2B2KiHEBEZP7GYUpA3MeuAHfD6z0+uwqFD76LusW3GLFYd1w3n5Py+j1CI7GAPWKBKBU8EhclVx1ZKHuE5JW2BtogSTcErVN5L/oesR0zIB75ZlL9LuPrpT/+zbX7zW/WixguxTfrW5FYHu+Dj7bzd3sqO+y30c8B4nN/4iD/HvuJI7h/9vjiH1vaj37/RE81IBoQDYgGRAOiAdGAaEA0IBoQDYgGxBMef9K9++v+D+jX/OeAmH8AmypEl7CWH78elmeWVq/nEtn2vGTcwA6uzrIYY7x3cdIvuSC88aLsksAqyGtN8Qd5TF9r9055FVQ3fpkNWU0h1hGBiDnXuSBFh9bkD4LsvrmyR8Y1loUEhy/OaF4rCpFzIvIyXVayM752IugBloU8yCssCwDhDRCdK3Vm0HlybvTeFXXqOy/y68HwFwxrhHadvQWiM93ZWSBizjUuiDYulvIVEsTodjaLAaK4SJPBCITLuiMHunMlJyIv0y2gckYvBj9TE8tCmBvCsqgDsRyLBgi3RmxjMQAbG0eAAK+CGR4FEJ1bapDYnGtckPURkVKxQxfZGYnBAF5CjWWBJ6d3lnex4E1od1iLRRnevgmspAElEGZkBGZKnB1v3PCTy6NlWUB54zCp/gY6YCvTJUp3wi5hsfUo364KILSLCC8PLNsAICLXYlRehY+7d8Jlob3IUT91wuNQL6ENkrggxGXZRa0R2hziXpS+mWtyke0xIV7MXE4pJXkMEvASaiwLbAnuLe9iwZtQIKzFosyI3bZs29Rhx3veBWduQ4hAKMsC+8leHm53ZvOUp9mAseQiu6SjVShucHYOmh3w0nPqgXaj04bmqLyKEGd++K8jYh+3TFGL5DwXXBDeqVWtkRF9NmrfEGzyuL/Th/SZTrP3qduUwYB95xrLQnaLveFdjFjALG9iabFWJkRGx5aXZQFCVDjAurAsi3evUVtE30KAoMVzriVsmeBJfI6OOSk8Ii6wroCpF+TtTiTeI9dixISBumVq8hQPJa4RAgRFVQl+lQsSEHkFG9oQgzjEvglMjDhckjSGzHPB2+tXGAzjGssiv7qZd4G5PeNNLC3mZXTpUyCYJzH6MURVC7Asumy1eY+2RN9CF2ueplC6U3aHrBFBrQsQ+wjE7N9ogQiGNcKXhdeZwk0lEEFG2QoXJNjIKwAijNo3ACK4CMQ+ByJnMIxrLAsAsZty3kXOm3BuaTEvox2cqDUccwlA7CH+QBMU7rN0FYfyhg7rfGqaS4006Km8Tk0MxD5NTWCaCBB+5EvMci0Mr8KMCPBDyqmJzqqXmJzHeAshQMgESl57J6QfJ1OTizwQJ/IPymQoGAxhjWUBPgVpeETexYI34dzSYl4GHAbEQoESyJZnc17AznRTDZZFDgSUNzqxgBsEtMDxPE18Diq/0+8HwfO57aQKIKgTnIsRZJspcS28AUL7hbgisrDGxZotEmtEc44FF+TsuWXgeNBNBE+nygk5HxCXZRJ9En/9a8fVIyxuGV12g1vLea3M0v5XfbO+p4X1urtP8LIWxCZ8HhD5kX+zDA/bvtYZfxKIz/Cy9q27/k38aY72o18DogHRgGhANCAaEA2IBkQDogHRgGhAPGjsmumv65yvrvWvuHIbEM9x0FZ5P//xMYjLm+My48sbpfVDPxwl9+ZUN/lqzhtLfS0v2dOO+vXG9Wh9/I5rnf0Tm9HGy+nYv56uN21YAtHryYHrHjJXSg+HzMbKoX3hXt/ojz4P1Rzp3VCm9QrEgLfkya9f1DH9AOM25+tAzdkcN0cAsXF9jzyl3aE3bRvWgNjwCbLnpNaN01rxutFayYw4oqlDf+yHvt7e6EcNiGPCg4AwvZ8BsZE8Q7Xf+0W1L+i0vgRiIzk2V4GgVFK6OCKtn7OjS2xX5kAQ6noh9SuXhy099GtAiFW6im4BMbhhKHpg6E/fPxOIDWUvBshdQEiGb/O7QWwMawNzWAAxJHPzLtPsxPHlNAzzUD/++kUdM/Qvp/lvngBe59dvJ5oE0ogYBjr3wt384uZ3P2mqoDKU+21+941fqRy9/8Y2KBe9i3+OUnVEUK0bR+c3PPHQawTi6I7i0U+tb+h//iQgYP1NfKRWvMT3Uu/89+uX1Pxzwz68Up43Kv3K7+eUI9VC72i8Uz10fhi+sUW18830xwvXSz1HZ6gPv53IBn1yjnqB2zuff+PWUiqssMWf9A6lqTbm5tBImKdqKjnoiKA/Ojuf67/Tv+5l0DViPvp+TuWOdN95qkUJgubHPHf3Pb1+58/f5z/6d/juKG/848Hf6xqBEYHzPKZ6AEG10juqa678e6rvB68Rcx2xLvZiGOL7773rUeNsv0/laU79zlch5ezZqw2PQPpIQAzDBueH72xx4FqG2CKpa653w75+p/Kn2eZxw+mvpx9z6uuJz7sf3JrvPeqmRdaJVbSYvGLOArqEgZAR8fpGS+V8hc4pL28Mh9sMOsD74+tbj1kUpgaaI2l09HPJ2QUHQKjcPJGRS/wvOT+/i9bTxKUjIgIx1wogqFbqrG9U6i3Vx/a5O1Jd5Pc8rsVf9uiNanzhiy2Vf3nTmgcGgjzH9E6t/RGBAKzz9euovYMbYosYCK63Z1/Za+5uLjUn/5D20pkfPbUGnr5Q+6nEQH6p1Y1s9x0HAcKsESdHw+3US/U5EIMTIL5zw2jePc1XPOV2CQgzIpwCMWAaZetUXoEoRoQb+gQElzmqy6iPF2u5ps2IYN/g7+wRRuL8joAQH47fZeRiCsaImP1hv2BrBvFogZgtuQSE2h/kYohdyUAMCQieATboEVxAmBGoLXMbyC9TmrfK57HCQPS9W0xNs0FOyIHoAQTNuYNcmS8/B5kmtEHfeIqiWRwDUO3Gqamn2b4KBA9XBYKmb+6S7wB+cAmIb6dUF3fsEROJ1PUddTMQXJ7m6Xm+6eOImI9vPMVSLXRp/KQ28TQ12KlJJ1/5dyNT0xF25TPdCygQWBPJ7o8efh8d1c3wfgcAxzQ1MRDzCV7ITvo9AksjLUybE3UwfWNIQNCiOg/RE60fr7xI09Lles59OjIQeN2cMAZ4Kf8ZbwJOsD5b7e1dDRZrWQh/vvK7CETPi9rPVB+AsHXR2Q3Xhfd8cTgs1r1Debq34ZYKEJsTtZoWawAxlxhejvCOyn+TZZXLs2X5l5fZo/QcrQfIdeR65zlebmRfT7PdHn7TzSlZI7voAy7NbXWPfbPGVy5z99WX/y7v24YrX4pQ5tfbY9+sh+Xd42odw8LGUM2zye79h97dODa3MrCNoepNvbd+6yeOl1P572NAaJmP1Pq5QKzX8NHj5XQNiEoN7bemJzkaEA2IBkQDogHRgGhANCAaEA2Ir/a8AfFp9tux2lX3wHJf194LwD35buf5GNxPdpE0IMqjL17loF9JXlw9be1sIg68FOfnTZETNqBe3zbMAmCKgNR0pUGXBMSa1oeNVbGeK1zN979LzVY8O611KUnadzFVZA28eU6pDC0RYpiRRV9mQOgH/EK/EeZFmaYlyu37BMQmx3gYZFeBstAP8hveFUGePgPCu0VQDml0ruSB50ytQISv5sLT186Fq/mShLrNU6qPaJrRNB5FSuQOIPwNILKfM/tsRER6TZGmWT4ABL8TII7Is7kXiKzy4FaAKHJpSria7zEgXA6EK4AI14DQeC+Rg0FbFcxOOIKxwLyO/lX5C8xHoD1s3sQv0rTEq/A36Cfe15P+0AtGhm40KXuC9s4cMx8YvyPtnCcmCTQ/VM3iIJ9cFnYgOBvnhOXmOT9HqZCSy1yj30rOa/k61eDI8sSz4hv+P8RIK4DKOyiMxB4fU17W4pjUpkrSc7wY2gqcGx/ZD7I9im3SAXvOg3AQNoYwYNP0Vc8MvWU0JbYCszaEPfHyk7gO2EEGEL1hklBAgL08cO9Et4B16p1dI2ycEzyxTPkPIz2PvRexoTLXiOf+5/fX8qlaRp4nnp2gtOE4gooqjEA0KCmMpNGleekxebqo1KYGaeCH6YWDEdkPvQO3gNgK8zLKnIUXhicBsUwDgwP7usROcGxHF+o5N+WVsk6XAvAE+zQiEpOEYpVAXyAG1OC4JFnULJ/FOaFn+C8ivRBUB2OZ610FGPy1fFDLIL0MmyedhdLG9oI6uygIgREBPYU0BW0d8h5Yv2P+V2zGQHHUSuVEvAj7YQBzg/+oswdmdGRAfF+m0St39HewJng90D2o08CL/RBBXAKBNSIxSShWyd4Csd+LtIQFItg4J9B64U6maCapg/NcFoj1fKqWkecxZ+f/96ovY4DAGpEDESSaCmp11uakk2xwyokQVkHPvILegV/Qg/+VT03zpFKm4fXIaWBNgANBtJRsaup1RNC8phMY+Bt015SYJDQ17SZID9GMQ7IOdiAj6oqNc8LKFjwDcEP5M2Kp5LnOZ51gruVTtYw8jznLeiRU3/y/lJHZPgOCPB1RZo8YMCrfogJBVIqWCCeciJ/KUTg6MBaOLnEWhKLIf8S8KNPweiQeRQ/WxMtxw4v1iyzW4DhsmOcgC/jxhcfNfPbocMvaJyYJz9gckQWRTZyoZtD3CI2Iksc5YWWLM+UnvRiJeOKWueZpAcog/lo+SG5tC1t6FhoipDJCWh9RYUS+R3hRGOHvLbOnI6KpnLksL9bR5oRVb4SOxxoHY+24llNuSuN3i+Feo5Vv1sHedkbJt9sRUezN6n3fde/Jt8wT7rDS3YzQakqtcTDWjms557HhPnZcB2I7hSLfn/+JI3y4ts8o9WVH+62pAdGAaEB8vFQD4hNq+4xSDYhPqO0zSjUgPqG2zyjVgPiE2j6jVAPiE2r7jFINiE+o7TNK/SFo/sYG/GsoPA2I52kIb0dQKAA9clZFZdP97wDiUqq92nY9LRD6wyu2/NP7vwmIkgKhBISS8PCsDeGtKxs6pwAiPHMLbgARz0cgaBf2Gf+E3SAy6WBSJFbFdtL05/V/nYuCeDM72VI6TE98PekWEMIAKJMisSqC1/Tn9X+di4LoGmgHnTqMT90QLAGJ9eAMQ2Mb05/X/3UuipNQIMTs6Mann5qwBNC2vDIpLANC05/Z/zUuSgKC8jz9Yo1NdWYgaXgnlxgQcdP9qaemOhfFJeYJ/nvidhggJADZ5JxhVUzPD8Q6FwXxZtAO+vfZv0fIUY058pd8sw7mTHjuK/82EPWYI38fENvnvk29DcTH0p/d/wbEk/jfgHgS/xsQT+J/A+JJ/G9APIn/DYgn8b8B8ST+NyCexP+/t7I/7tHv2/4y7xoQX2DhozoS/HRf4iFIiWSpOO7eyylUNMz7sDzvxSO/3tTkEe2H6Sejq+GLz65gV1xy2/PG4Vo7q22U/lp4nbWIz4wf05HoRiK8aKB6LeGrznRVJ73Lo0UjS/6ba2dSw/I8nuEccyDUrmzRp2aH9MlocPiy1lxOouM9wRKIZTvX2miB6G4C4Qogwm0dCdqNynMFd+XC97dP+dy5u4GY/QglEOk11RJMWHXT8Q8A0SUg7m6j9Bcf6rXR/EhaEx/VkdARsXWaa8ch5FEKU8yO389lHRgZErT+TNa2XPvWIa96ozwH5NzxI7FbtncQuzt5EHcrtfKIGEvuBHkF7Q0fLSD4PfxD3uQZb0NFv6wWB9lWJsZ2pPrydt7RxtlC7jXZCbSLRxUpQ+KjOhKyRozyIPne8TP5lBePdNP1sYeF+ZoIe2x6Ii9Zw250h6fyffSGrhJWuIDuBQ14PN/vHbgQ5BceUHdcq47RnDvROeFKzB6phcOY/EOLk2fcxuiX1eIAXQFMDFzJeTvvaeOvX7nXvGlK3o5Ga+KjOhI6uDqnuYirAHEEmrS2F6gpiZOc5iQvWdvKwN9yY9UbHhEXdDyd6+gT2/MOXAjyC01CPvhbcic68YMfQxcLVKv6BxWB5Nku88tqcdCIMEwMV7bzdhuxj116TUDNN0pJa+KjOhIWiKDXtYODwWHWlaty7CQN8y9fLbMluQzI4hS9EZ6DE90LlAxOaClyPdI1FeQ6R5mSO9GJH17KwaPkn7yLnoXR+mW1OLBGKBPDubKdt9voeESUXvOIGSMrYgnEvToSGRBxahIHCZY9zZbRyX2IdCuaP7X2NDXRZ+E57AUIT2sEfQo64D3ZDPvtuUO+PSaLccGdYCAEFrVAtap/Bgj2jNKSX8H0DwMhTIw0NaV23m4j1ojSa06n7osMCfcxHQkF4jBpLl3EPBbgM/TFqOyBFqgJTs5pTKYkFQ3nZPlXbsPI788AYgtZrDOW2o4XVJ66zs4fsOidsXyOC+7EQbzllomFw5j8Kz1j29GvxBpx/D1CmRj5Yo123m7jFgJdhdfUynDt29VDOhI3c1YPv1737fI67eUlllv2HzhW/CLbIVLE8uN/l7A4U9oKMpUvvf7t46uAuKc8nVvyO74aiHUmxj1tBBB1Vso/AsQ/d7Qf/RoQDYgGRAOiAdGA+Mea3YB4kmY3IJ6k2Q2IJ2n2fxYIyvS3cXGe298PeteAeBogDiusjM/gZKTc4Zo9OcJ12w9xNuatXHl/nbGxqojh7yk7+kWPLFgfd3I+aP+5zsrgeAC1xt79+2lXAOHN74++4k8Colvtmns5G7rdcp2xEWt1Jekgz7tWdlRCQiQmLFkftX5c9GGnQFRYGW5dfeSDI8JXTNSBuHKN3s3Z8EuCzoeBWCs77a8B0SkQ6yQW2twYiZnAavB1VgZtc4AJcZWTkfgek7IydpPGKWEuw1lrNByPuCV0kLKXKfIffM7uoDovj3M2vHpfZWwYry1nAxoZnHKGletlz2cIvG/l1VVYH7YfF31I230jsyQoHkidlUE7SmBCuGucDOY37GUjE1ufPgUDCGKr4D5gg1WuW4nwoPvRwefsDqrzXX26m7MRovdVxobx2nI2oJHBKezHrbLvYGqQbx6DYsn6sP246EM1AhGSOisDkUrATFjnZGxlx3nLix5YGeBJ0IYj2BAY1Jb7wKEAyK5DHdvLe9y7BhAqIUKWCYjDg5yNQ/S+xtiwXlvOBjQymIXh4cH1su98dhvjrLgK68P246IPLRBUNGRAhHS1SlyrdU7GPE2i83gPC6wMjUDSCRsCQFjuAy/WNJAnCUvjDRB7tSOMjolHhHuUs6He1xgb1mvL2VCNDKS5m2VHaZVwXnyd9ZH6cdGHiDKi8UDqrAyJVAIHVzkZHGPEXMnKwJAIJXTd7mmuzLkPmADZSVwj+zQ10Vpg2R1panqIs+HV+xpjw3ptORuikRGnyFtlR4npQn9eLqGS9WH7cdGHiDKi8UDqrAxEKgEzYZ2TwTFGZBFTVoYumQdQJs9bV3IfEN+E+SFS3+h1sXY+Z3cgVamK93I2OAoQn6sxNqzXlrORlDJksb5RdpSYLvTX4XZiwfqw/bjsQ5eG+b3fBcOD5x/JkeW++S3lM6gC4cvKrrM+lpyPothXA/HYcZvt8PxArLE+PgWI5znaj34NiAbEJzS1AdGAaEA0IBoQDYgGRAOiAfHv8u5Pg/L5dX/U4udLszxUogHxBEBAquBxRkdYtRjMa730Nq//YUWNFHUl/T71QR2NRU880q2oPTE8Cj2RiXzOSxymW9U/yOhwaZsnt+YSXYBfF4VLJY6PKGqkqCv6cPDHdDR89m8JhK94TPuapg8K5kkeN8Xzk7tqsaY4UgDxMUZHyJxdBcLdAuJ3FDV0/+ujOholEF0BRFf4UAY4xxZQV+0TANGtA1FhYNzJ6IDKBLgdpChxmZSTAY7CRRgROw5wv9ToSJFSOqeWPqqoobaCePeYjob1ZTsdUr38ZHRqCx47Zr6JY34Heeouwt7gh3lpwoxnUtwU+peA2ErbUMtFfGL1kxoD4z5GR3qUmzYx9/Nus3IywFF4F0bEbDfIa6bRkTgTnfA00oh8TFEjaYTwbheXekRHw/oCNoY36hmpLZ3TrdeOWwU1kneP8kT7wIiIZ2LclL1PIyLtbL97o36yZGDcy+ggVo5wOxgUALF1ylF4131uAaLU6LA6IFbI4XFFDRN1hcC4+Ad1NKwvW6cW0BN5W5Rvwh4HJ0Cg/NYhjkI6k+KmSEt4jWB9E+7Fd6EcvNcZGHczOoKbZE6eEhDEediL8/sCiFyjY2t0LtKI+JCiRrIlxITHdDSsL27yhh3II8K0xQnfhGVNRgUC5eeWRyDEoktKJmaxnua5hffQSyAKBsbdjI4ogGOmJp90Kd5nqyBTsfjFQqMjRUrpxIcPK2rEqCvgUrCPD+hoWF+SBV0jUltkavIyImQ1ffdaHgu1PaNeySTLawQrdMiElwFRMjDuZ3Rs9d1EjRy9cjKCaHoEvlenZa2blhodJlKKUB4/rKjhU4QS4lBQqUd0NKwvyYKqZ6S2YLHu+IaF66SeIgbHWW4hRsphz9i4KfQ9Ysttc+B8TGBDsfrJ/y72RitNDb/37Ta4pdVKrgUJ+OPsjHCDDn1dRyOV/9/FFT1h29IVdSY1EsMWv+pREE9udl1y++uBKFkaIav/MSBuMT6u62isl8+BWJaJupXT/RYfUONovzXdW6796NeAaEA0IBoQDYgGRAOiAdGAaEA0IP4UEP8HusvdDx17rwsAAAAASUVORK5CYII=","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"iVBORw0KGgoAAAANSUhEUgAABiAAAAYaAgMAAAAgkEnVAAAACVBMVEX///8AAACAgIBJX6m2AAESB0lEQVR42uxdS27jOtOlBRkgNFIDyZzwyPAqfIFegAfp/Qg9yjI8DO4qf1adKrJIUbacR3fu90vpTmSJLD6OSMqqo1PObdu2bduNbeeeX57P9P8cP+0v5353fr4493we3djT+d3FjfG/O3P6s9O9tI1n14/LJTTPLqTv88mXsrzzLO3+0irrdp67KftbfXVuni3rEfuu545rlkD9GHuzKi22tx/39GuMhxiIsT/38WNMMMaD8Z/bU+qLNdzzf4JI62e7eld1at8G4lx3vjM2sVeWdzbpkGrs+xmErTy7WUm75ZR9G5HdIhDS6ykN2zi3S9g5rnI8u6sL6ccf1OfRmjuPjM25H3sGIvZevNTdj3hsFxHZ8XVKv3v+bzt1bI4IBWJ8GIidlGTLG4t0uI5qIJbz1O1eTNnfGhqXpyYQNWQ9urpVAltlmOJA+nGhqefl4i77y/PLjjoy9j/B/eNigIgHf6ipuL/n8xHTOPjo/4/LXqzt2Pz+Ij98jD4/X1BWn4bw/jL2Md8FXR0/jVobpB/pwolTJcZyWR7KHEdKv4+1j7kd56D0knvfyDPSmDdpqGV710rJdf9Zpi1b9fMn/Y6ffkobf3I6Z9Ps4lHq02YJcrnENHSlP/H4+KenkdDTfHV+PhMQO/fU7y//RBh0jXjibGg+ZX+KZ3YYYnF/52ANA23s8bPjYzJx9HHLUwOff+qx8nCOUWuD9P0oI4WnxLI8+k+z5hNbpFrSNaZjDbl3jTxjmpGlBD7STEl1f6rSFq2KfUZt43r3uFjjH7q8chqysZPppy5hRyuIQ+mxgWMCYu9oROxQ2QhF7KJY2PMLT1JpRDxx83kKos6nifKMaqOinNeRrT13H0YUob9/6ekakGlo/7JHw2TyieWM8b8CQRU9FytcUR7976XpBATVknPY3G6exwAhaeTILCXqXqYtW/VPv4/13XO9e+4j/tvbNDunPTIvYZdGxI4nugREXIT56pCsI4BAV+kaQWepu7hcSocFJI0Ink4oQxyiLk53CgQt8HxdpTukePQyPsE6VTQ2lu/MLBAACGtEWR79t0CMqbNoKklAzPKg220aAWKWEnWv7BWtOsv42J8x48vf3qZhG+d2Cbu0RvDxH5e+35mpiXdwlxl/fv6krtqlu6YdWkMm0cE0KON/TFYCRF8OYpQbjdM4Ziz21AERhP1PgenMKc70qe/3+ISJMi/bRXmY5jApyNTEOdJUEvf353meYmriEuhIM2U5NSFt0aoIBF1IT7h8aPXkVhZp2Ma5XYICwa2jRW532Z+j0ZGWTV5GzvSfMtICSkDsz/Tdgq8PWlxjymw43gvH/7RU7s80P+KGQJe1Z16S6XMs5WdPd848UWFpQxmyCtDCFtPuZNmPNnv7PaIsj/7H6eMnpX+O33aorN1FpxLs7908z/7n86VIc6YjzZRU959V2qJVZ76QqB17qssZdSjTsI2RJrp5CXLjMmKtcDpHjze+hO3uHhmbqXT79TJPLdNTI8WNijy0rbGze6DEpfahFTvTmnfVRZPQhPC1jZ5vrW/D/71tf/lfas22bdu2bdu2bdu2bdu2bdu2bdu2bdu2bdtnbHtmHMyfW53T77O7zYSgjZ7eFw7ecV5G+tiDx6DPaOKDdH6CqZn2kkZzPJ+Xal5uu9s1LJ8IocUNjsi9lpr22jqseOi2wOnYCQ+C3RP9ziQugajZE7sZj6LXevTaHb24xssybI3Yg5o6lBgjY/IdpdR9UZWifj1b3t0Aoq7lzhXV7FGveSvPi1waa2Gsy7yLX99kjZiqtoG4xYToG3/HAsXsGO3Lrs1AmOQ/xPGSgXArgchjY38DiBomC8S8leNtUpP7CBDz8hyxL56ZccBsgp9k6Ae7NYgiEPea/AZ2xPAgFxcIcSHgCqHcP5nb4IhhQQyFWRkE2PiD2Q99CXoPVxF4H5SX3S4/cyO5TsL1QNmpjJ/EbYM7d6+1L1KilkR/cMl1gxa3OCL0/yW5eeD+EU6HsTAymQJOLSpv5+Z5XF2fBqeDfc29jAW49Wi6GHt4TsHJqNkH0bncO3X09eImHGmWiR6p81N0Hj6xkxAMi928DAbiiR2N1E0FECP5tcD7QGpyRmYg2GcpXA92jzotgxxbCgQxQmzKXEvUy43Iy7bPbY4I/f9H3J5gamTqWLbA7R2VszEmt22Zp6pPg9PBzaWdPfgbPF1F8y/wXI8ztgbzG16IvyD8JbAn6Fp7oXxj4deVYViX4UA9IRpCPSJ2Z6Yp9E4ZJUpVUCC4dnCi7rmeWgZ4iHsZ8sx8yClTLckqNQysD7aN1XLWSvr/jzAywNTYFxcMLHB7xSrVddfMU9XnPO/V1Ely/fU7mfkMEHMmBHM7AAT4RDtiYPRcLadsJQBB6NdlZCBGVwPROwVi1A52NRCJ63EZXQaCKQc/x58WCE1paqn0B6fduMQRof//CCMDTA0nU1NtQa0+UerzPI+r6tPidKCThAYlZCgmV4Hyys2b8xuefv6klEyqegKPIlbmiRkMPNx/XASIPgFhyuAuG5n/0Pdp+aIfuqzTgm2mJuH+KBA9yhTmRq+AsdUxTQU2Za5lrzwUYVw8CRCzVtJ/nWbA1MhTk7Eg7JMd82FofNV5wEkp6zPvVRr6lx3zFZ75NzpGORdLTIg4Ef2kfOBi7LBg/mTmwwuTZISkSMzx50tdBjgc4D8IPfNMPzHVOQ7mxPuQ1PQf5wUI4XoIa2LH6cAGiSl/YrGm2puUuZaclpZXYVz8xPeIeSvpP9ghuuzq9x1rgdq7c3qjQgyXOg84KbY+LU7H3Ru095ECxgfP7mbfBe6fn/FI+uXcsxo83KzaesvC2MwzflqvfjoQX7M9wqF4nLFSW29ZGD9Qo23btm3btm3btm3btm3btm3btm3btj+9/frV3v8ci3+u7hsQf7F7miU931CJmKferSim8fTtxTVLrtkMz4nh0Mubv8oKUe7FqGepMenl21+/hmvc8ca4rwrzi9UNp7fhOlxPE1mZfDedoq3TFFyIeTrXXV3orpzQZBqS1cEczalpj6xyNvox6bxrlNQ7qG60VSLuA9F65DlngizAd54peiTVit2ZfjIZYeyVnAAgdgSEnCRQfOpsn7rIc9e0gJAPsXt8cFfqiNgVEYjgJ+8DARBCPMrdFz9c/cxElwx1uQyTmvbYqnOTu7qrTde5Rkm9g+pGWyXiq4GYKXok1YrnF/ppATFmIM44uWsBEaq+D+3h4UMXDBBu8ui++NuFyblDzEgpnAW1AiJvOTXtKRBdLMOmYyDqkuDAXlKJmDMSWEbopVTOmKU6l0wQQNqyVbMZjGpFGhHCz+hVzYPOksVfv8DWIFYEAREngtfheriervTbTXGyiX8Hd+Dj9PmNjjukce4tXqcxzZsnII4zIOLRA3dacF6AcAQMTzjDNR4PVCKlGOSoTd0BiCPtkckiXaskvGG/pBIxZyTk18WzcsYs1blkgoAH12A3zBQ9oodXGA5pjWBWiBMWItQtIEDx61cvLkg38oigZvujpynB+45+O/p7jD0T+PPvePZ0DZzGud8xYaDpIZwmQEUz9+/YOTpzH7lDD9cQCMB4lEYZdx/bC9rRXIbHioLUp2uHTmegAvW1TdcqiV3ZiyoRc0aCAmGVM2apznMmiFuyVZSdVSt0GKuveGQlDyYS4CyPCAECI+ItePrvXbzK45xBs7Snboh9jRn7N3fWwBABiCGm5V6S7nExTTzi7IggII9eRwRZJwvUvTGlrBGxS9+GIjU6HVNXBkLStUrqRXWjrRIxZyTo1GSVM+pUcybIrpFK1qCy7KRaMQdCWCKiUIE1AkBgjcCVyiOCup0XTQAxTFiQaUREk9c8ImKawN1hgOB5JK0R6Dye63mWh2UCwuf7Kk6NBVlTd1gheI04vZ3ebDpaI2Yl9ZAUW1CJaLMYMDWpckaewDRVzQRJQNS2zjM2g1WtyEA88V+Zr1yfgBiFuAUgjvRzuNLkEXuVJygZEfH/xEDQFBM8penS1MQ3R0Hvml5fKX2X7pooP5+VJV4BZyDS1BTS1KSpBYjA44hvX3M63DVVJe0uzzdUIuYsBp2ajHLGuU5VM0HwPWJu63nGZqDvEemYToE9L9bCElEg8D2CrJEOCM25cZ6PP4Hv3wmIuKDGv7Qm0AJJnye+Aocrp5kmmrKuPDe4YdLvETzzx8+nCVc2Lf0O6bhX+aaAFvl4XWMNOF21DJv6hEV9yt8jcjp8j6hLWrmt40iM/WO2PsJwaH+zDo2UuZkh/e6AwILFzn3t9oGS1jESPjPV5wGB67kEgo9Pyxb/FBD/A9v20G8D4j9U0gbENylpA+KblLQB8U1K2oD4JiVtQHyTkjYgvklJGxDfo6Q/VdCfvLLWlfXNrvUNiHdshm+wkqegbsHMU6Dn7XdYCjH96a2b1pejqXnPLZVjWRZmw6P+ha1xbiG1zyfftKzhehuIWaqbT1Ynbzoi8Q1W8hSCeLoMT8HfZSlQB8qRdeVoatob8AR1Cq4ux7IszLPMKXd2V/WIbwExuVm/ZQ6IL8rSZ7ndLEfHQMxS+TYiXQ2E4Rus5CkgteUpwPHhLBANPgS5TNaXo6lp71AAYctR3kRXX2hh6fp+HIiuLMt3TbtuKZW/NTSuR5OZWAwueWXv8xSQGnuYdCjfHZYCp1Ig1pSjqWmvE6AO17oc5U0MsOjA0uj4r/zwEfoMfgdNl07Ok7dOSiOHUcjnB3bjUD3jdEgw5bLI9Up1dnxOU/KRIac6Uiou/bVMV9brlZknPJEx3+AVPqR1PAVKLTyFV+20uywF6Vp4r9aUg9RUDgMR4JCvy1HeBHXlka9C8lvjb7LPvmqmDLD7NC0V7OOW0phkoAwPpI4jZ9JFYnBa1nCFU6lLyxHGGB3pcqpX2Ozosi3TFfWKDluqHYYf7XSTXqn3eQpIjb2Q5vY7LIXks11bjqbu8DPpfFuWY1kWIQHAVzjbH5IdmruHN58miIFLx6re8dWNeugC7anM1Cu5LLTAAIGUckRToRiUXqYr6/Xbg33ixOEtxa/jKSA19oTL5u6yFAog1pRTAuGdvSnI5ViWRR4J3HVXtnRNpV49rsp0JccUR7m9mrijuB4WCACka4QtC91OU84cCEolxVwBhE1X1mvySjxQ5kFaTlbxFFzBb5i8u8tS4M70D/AhNHUHUgx3l4FLytFaUCfQBNUlIOwUgJuGOBkecRXxLB9BGF7T7Qad51XJYw2gSSyUd022rGJq4pR0RNYIusZCY2pCuqJeEYgjWg++wUSYreUpIDX2cH/v3X2WwulKV8R6PoSmPjEXg+sn/AhbjvImuPOoThMtwTyrX9X+IItk/N7z6ukun7+L8PrmsWohPdUjdpAs+d01jw58j7BlDa950aeUsdx4ZMg1mrBYn7hlRbqiXhNfDJrm07c/xYcoywk3yvv3zX4KeXpqnA/vaFMnOe+1/Kv5IYuV/pPlhIfz3/6W/J42bc+avklZGxAbEBsQf6tGGxDfpEYbEN+kRhsQ36RGGxDfpEYbEN+kRhsQf69GHzH/HTk8rTp9Pj3nC3piA+KrSl3Yymcv8fmix3MxcBOIV4EzzJoI5QOsgdP7RvGS927p/ITVGghz++mjl1o4N3cGv+VzQ12Gs+1Be8tjVAvdlxqwE2MwFgM/D6YjxFY58V9R9JBnvad4nHwN/8Y+Ix9ltDvZEsotlB+9KxkK7BGbMjchiNu9Q39P6pnzyUPnksvcGyCQtyTLZBd9fuYfUkY4jtThZO1bILzvisIsm8L7mochW9Ee9RfaY5Q47V8zEN5QCby8q0rPb6dMkTDej84BCNIdYI8M+/ik1KrXW0AUnxUI5SYEp9wEn6qfm9kGIuc9FI+AfeNvKPrMJ26FtV8AURkrgHAKRDcDYtae4hiNdN3vMOqDVfbARZGBuDKBIsiPesg7dz3SGXEECRCHlGoGBPQr8Dc6XJxlGERHCbnAJ+UmHK5gMAypicynIHcMu1UovfIzTuzSj3spb+fgKpnIqeMwnHkoM4uDhzTTEZih4SCj0LBP1Q6gLXjlc7xiWj1drUccNlEqqXLgZd6yPY7bUx0z+z7wC4+TWHRvwhBhhokAQZ7IEogDA/H6SmegfKBAwOrhKgyPK3qKeowZFB6kF+/ZQ5UZBuTmA4cC3ISjuOU77sZO+BQydXh2Ux65yvzKORk8+pxXiGFxwDovUxOnIyejYwWN0xRLOKKUI59p2GcgjuxgJKiYz4GjXhlLg6xvXnLx3KJu/6ttj6xzxbHuatobOjOq6CV5qg+xUOIaMQVW9vjtTwz5aRJykA+vVLPf7LVnDzatEZNyTo6GZXL08AJSTQIpVzj96y3DoMPQnZSb4JLrX0cEUlAVhzd8Un4G3NnB57wYjsMb8RZgYXgL8EcHYlcQ58P6c33bvsNFQw56Xwg0JOe8jog3z7l0kg8BQgy2PUhfHnOmziGkJUKA0Mns4HRE/Ab6nmcvjAD2vysQUPsIiQci5oSeh9klWhomMD/kLzgU1wyELmSGs5E4FbajgtdPWGtKIEICIkj1UDyAIKe9lzkbVwmAoBJq+xmI4LyZqy0Qupx6s6Z5JjHkhdlyV8pjztRZPfmhGBG8RsT+OuhiXQNRLNZ2jcglKBCgi4JugOkBLIeCYYCpJnMTgvAaErlFgZBJTKYydIIHEDkvBng4xpnziPsuml48WBxH7+W+43i4ChA+AWHsg2UXeGryyuc4Zt6FzPlUB7J5lGmFp0ql/uQ6ybJZHkvskCBTF+hNAAJrBGANrxmI5bumao3wyrvSvqaeOIJJ4R24Bd21ZBgwA4FGjXATYooJSx8g7VjpIs6HzFXgmfIVg1gZEzT0NO9J2A/EgqM8uEHosCi/dixixQQXWXY7nolr++BfULohK228Zt7FIN8jPGy+olRS5QAr8eRse+JEPNXHBr7BwL5jYAEE1Yo6ndbHAIqbfI8Ibul7BNaME+vTnCZbglI+B+4JWqxlsrkly3Gfm/CZecM7zoYb57tVdSqPLdc51F8BHthu9kT6vnhdZ+Lx7dG8wX399v5HHOGTS/2DJrZnTRsQGxCfXPwGxAbEV5e6AbEBsQGxAbEBsQGxAfG/BcTfLnK9ve+t+zKv3Tem33wmEH/4/ZybW3cbCLj0Q/WsidyW1RbuPeKa61ac3pRL0WJ9mEwuv/pUHDTVXeI/mIZyGSU/wyoKaDOGXJLPZWL79w3vhnf0BLfZ3lNV95B67HT9922hVk7rgtrFn0kN6JHUASV/o6EpMpWd5mcO8LluRUhuf59eAi55G9ZmZjMsM0FaNAG1iTIqfsYM9WAh95kwoQwNeUf72rmF9k7WnM/2fCkNkWpm6RbSDp/YMPlIBqK6bm4BMb9q27oVma9gWR8Ff4NfRB/uAFEyLOalZ86GYUr47iEgXAHEoWSM2BKnrgIi9ZjvFueJDIStXcEd6eCgCCV/g/kUV5V4gK+X9oV5wBwL1bhY1q0gOxXro+JtEP8iOh0nEBJUDWOZCeLSS7OqfqEpoZUjvrXEN6G0ZRyVw1VbrK8UQwljEJ0PBcJN7fYqF+WQc/O0HtJYKhVAlGmCl4FRu+CkdokvElReP0wlfyOwkzsLHnC6o7r2lGMBBs+ybsVRHIuZ9VHzNsjNrkDw54ltTktMEFyPVv3CuaPYZK9eSgnFDDeLo3JUL7K8ZO+dqnEcmRUi3TkNS+29qt6H5oZTTVRDZgogdNR7fWMbtYMz2Bl+zOEq7vdTxd9gzN7I26rLo+pfqMveG0GHJd0KJ0Bl1seMt1FMTbEEHJtuM0FK0YUgQOQRkfkmbhZHRbzITkpCqW/qo1QgukDMpVZ7UQPKq7k7LP/i/64VQFCzwWUgjiLE4gx35Jh4EFPJ31Biy8AKSQzGBP0LVOzYAGKuWzFnfcx4GzTBvIZXMyLWMEGWgDhmpoQFwsZRUSCC6H94p7IoJRCq9zFr76QrQgaCiZlKRKgUQFAzlfbK9IG8WEtKORFK/ga4EZmqwkDoUGWpIC8pb+lWhERIU9bHjLdxdBKBR2SDguZpM0G8CPpk9Qs5zqQb4hmWJbsqjoqZmkSayFuNkQTEaTJTcdFerFLB59ydU+5rPTVlIMDVmLNh8hGJ/AFti8xC4P+vqouBFunixdwJ12lKt6xboXyFzPqoeRu04FEcFFUIRMnLTBAvS6VRv5jAhOAyPH2PsCW7Ko6Kw7KrLaZyr6ohBSCwrNL3iHZ7T9DxuEI/owPX5Sr23VwBxHPrwdWo2TCWO+Jub0vcjtDYs9vnanG0mSDdzD4msXnKcKOma2vg7rT4fe0Ia58ZLCF1rzJ/5xEH1baV8nOB+Nx2/D951vTdtg2IDYgNiA2IDYgNiA2IDYgNiA2IP9mwDYi/VfJfAOJr6SR/poM+q5TPq23bkh5tnt2A+KtAqBpFqbdR6Wes0KKYPN4hI/ViiPTT08d/305vE/2eKnbFDYvx2ex0Yk7EBP1iiZB+Ei9ifEQ90RtqdIReCab9mIJ+L6tdzNgQ8tkcbbFQ8HH4EBBljZRrYs9yj1lf0QCBi5D3BwPEbS2KSZxJPiRpdjyVj2e6xK5IDpubFn3AO6iTfuL+SD4T/jdprBZOxzHcfS7F1VFPUmCPKpjHlGFoRE/x0OKoRCQWNr8AxKCvTTtnuCb2bEA0g+w9PTBPAg5H7It+xgotivhb35RGt6l2Afxok7V+z6K+DEwOI2MxxXsAHPJKrcrA05FUyoxDtRoIy0KJVsSB814gTK8WfJYMhMSloTN4M1n5BBw+I+2Ds7BGiyL+ngFxYCD81CVeB5Fy7ltUIPxUAMEj4qBvJ081EH4ypUztCCuH9OKydpSJozLVLBSCT3qH3UVv6fVnOI00UkqOxFKnyD0p+htpxOWpieLSsA8RnlblE1CH5P0couOeFkX8PWFdIN0J8mmRJkXHTkcFgokyd9Ut5N1qTiPdRor7fJZs8jpxlXe8JwBB520p3UKElSNzR5JD23U2jsqki8SQ+yLoaKUcvzXWg7h00/KTIrHUKXJPHgsVEwsEEXOOVjQBfILOsCY6lwUU7mlR/BYJhLh8vumIoPf+7Yhgi9Ndi/E6O4jSh2N2SbFGkBjK20H9wzwiKADHwdlSXCPCiqxhHFYtA2HiqExpskp24E3vHPRKfgvTZeA8uoTbSCzzFGWNusaIEHUOVaNQPkFnWBNdwQO8rUUxCRAaLCYJIqQ1QnU17lpkNkcGolwj5GeqgQiTLcU1IqwoEDFHjjk25TgqcxZKB/4KC2R4vdiu7irslmuKlJIiscxTlDXqZmtEUudQNQrlE1BfakW8dMYaLYopUXDiNdu8a4LFcN8iD3YFIvhyjRD+BYg0wQARilIWI6ww2StoVBWaiDWOypyF4p3LU5PPEw+10E5N2UKdYqhqlIHoXFdEaXGqRqF8Ao5jMuk+lCzWaFHo9whiN+TvEXRNERCnbPHtnkU0AasE+BLB6fcIrBg62YjGxZUnmKKUpQgrHC8FOh/4dhByHJU5C4WAAAsFLIzJFwuxfgvKkVimOkXu1ZLPEm9bpyH1s8SlacUC+Xwtiq9Rt7hdSnC3WCThXbXVUeCaN6t1iiUlkjwibhb+FVoUX6NucbuU8El25tv9SCyaYnvW9E1quwGxAfHVTduA+CZN24D4Jk3bgPgmTduA+CZN24D4Jk3bgPgmTfufB+JPdMzfIrvcE0G5XbPvTdHZgPgbm3IQEp8h3M+TlSbw7JKe8RrWAm/gNMzzrnnhq/HcranUcTL1KCOouD7+8DZKZ+/O8/z7FzrXj/34fJmfHSnXZVUn9preFXnu5u5Sh2ehg8yKuN9NJkpJEkPXz8lN4tu2uvud3lDsWIBvMmyJIoJK7JUePdTHT/1I3c1do73Gv59HAmJ3jj+mT3cGiL5v9nnxuwSiN3lkb9219z4gOsNS6AQIcYhaTY0vB8LUo4ig4s7oF+pWADH2864EEM8vzy+7qqMTEO4dQNS2yF2xwE4gp7e8qsrqFuJEOXC4inke8BlYO0NYEUlp4ghNji6xFkRTQ/xhc1vk6rnHkKgVOwBpy5apRxFBJXbseX8Zaco5//r1/EJA7C/xx+0vz/HvjwtNRnZE/KCzfHxP+z8dH+kdHdvHtPHsT81nbfD5n/KXjyHPy4WAGMcfF76K2uyEDnE+4HCfoMshSh3GKWjzMPOLnZFHif6gLAWhzFz1s4ZxAqdhbitJp99gSNSKHVjBGvW65nqIQodEUKGREKd+Ggajjgj6oaPxWP/Es8Z+1DVi5574fNwc78ccdOT5Qsd4NMVjo+SDjR4zTzw2PtGxJ8mPPP/Ek3FvfMKwaLMT4E09sXoG/MjkWkcsk66ZJ7DzFRobvohSopocpaaGchrmtrp0k3CDITHVih10pG2rjgiDuu3oagQQMiKeX+JoiJ28j2f2L9yVbjfqXRMBtI9peqcQUtfSZ0pJ+WOe8VnywQYmIbJFxewZ6p6nJvpLQNCIGBWI0GAniFvbKRB+0phSMc00z5OByKyIShljKjU11JU+t6VT0y2GxFyxo2u2JTNUXL1Yn0cBwqwRF3eJU9ally6rgXCX0SkQ+zOPIenUkUfBnm1yv15wHKMDQMTcS0DYqalkJyi/gJkPwlXgmFKszTTnK8jUJHcnxGlQDkMiWqbP3nUlEI3yMTUtMyRqxQ631JZpXg/UzY1nANH3bjY1xamET1RASEdyGup6nmoABM1wTyMA7J3YwP0R2cLUpPlnQDCnoslOICYdy0uR0gWzJDRIGUUamfMVmCfx6p1PrIikNDEJhyF99s5yGubl69R0iyFRK3bge8Tc1qlRD9TN9WdeXncX/R6BxZoW2V08HiG5WCBoXt/z4ry7YD8v1vQ/Tj0/6TzywUbP3xPIFhZrykXHkOfMQNDZ6pavZieEML8brA8F3zqKYzWH4X3siDp9WMX1yKnuRVApazbffv369dI6Plb3rb9e8rF2jtVbzU6AwsttIG4xGh59xHGfHfG+VF/ziGN/WXfsG2zbs6YNiA2IDYgNiA2IDYgNiHfVYwNiA2IDYgNiA+LzKv3ZVfq719jjxKG/Ut8NiL9e356f7KJQPLTay5k97zGfIT7DFTZDeuRF5zIXYf9Iw3qlNbDvt3YA187gfqne7bLJpxbrNRI3Y8de5+jEGXvwN6TUX79uPLkKEqOa3nV762x0FNm6661WqgMZtopT9rHlG1glhpFAflknT+ZxLJ3hPfbe9q6XJ4y9PZtZCWVOa1+P9xaIc8YjA9Gnju+trb6BymiB2BXJ+pG8ZNFBMzJEVHMGh/kbTtkbvtVDgeUzruLTiECEpHhvU/oU4aVFd1AHMn+aDHwFEJ0GB8mtoyvmLhDR8zFW9IRdYWV39zJeDcRY5R7bdpeB+BGz7Li+PxzXXIE46yWyAATthS5YIA4pGosBonGBz4BwNRCuBQS7QYRdoCOC4NiRy4SchvI3AXGODkZwHX4qk0F8vBe4PXZwkRSMB/oLJwodf778+oWz0SnDR58p3YtlQXCOM86gnD1/fmFLyo54iY5NffCMeqpjB/Z2RF1iIIix4c6Ul/zTlE7ZG34WdeWN2SvRGx7A/GAaEAUicHhZOPFU2E2rEV2GZCOLtL9JdJrTNat+cAwWw5ZhGCZ22O2UXSBrBEYEnIbs6ugBBPEZaI+8U7F9T8pk0GPZ0ehcyXgg+3Ar0nF2TPbZBs1rwmMghyKzICgn2BR9j3Jg+Z94lsoCU+KfPo1Pp2WL67LHCPlxoZzPFwDBpZyJv5HZG34WdeU3iCGBND44uE8EglQMGIx4nGO4cEqi8mhEF0RQwSv1Ei+G7Q7XFH0CJBevIRFkJWFWCZPdUP19WkjlWlIg4iINIMhpSPPqD2I7vEizBQhiMbC/lpfFBuOhz13FQBgb+5dePFt0BOwJ5Ny7zJjYs8P9n8SGUCDyDQVRwKgWvbrvnUKIOu4wa/GIyOwNP4u6QkAMzCAJUJgi/zYHuGGRCHjRZWpi0o7LYU0CM0s0XsxvEHsSEMQ58Sk6jWwyInJHXRSIakS4sc9AjPQZ7IdemQwAgs88jTwdzBkPYxoRCgRs0FWKaxgEL/rhEYF142IYE5dRRkQ0f8kjQutN53dci0xv2bHdEgisEZm94WdRVwgId/VMJbJAoKO76XgHiOA0XgzbFZYXeDAKRDBsGYZCp4CxT97W2dREE4gCcSae4kjH6CiYDAIEjaqfeWqqGA+0YF6UISGTQ7RB8/b4JPQsAjL+/Lj0nPPs8tRGIJwZCJrnx57S7NLUJMQWnZr6PCLGHpXcCYVFgBgze8NXUVe6NDVBuUsWa6+SMT4cONiI9wkIn+KtiO6GxIthuxLLRVQ/BIijZcvIYr3jxQ2chHyPr8seFtBn3ktA9Lyo/lQmw7NQCON+j6WyZjyQfZ7kmP2wuxAQsEF3MsyjwNT0k37ilc05z1y7Ptmiz2eGfn/hNOczTVkXfH/QZZrZExcAwXXh7xHPPLb2F7ln6zN7g5ZNG3WF+CK0rDrmTtDyTN8jJFwbdAUda5bwYo24M12KoCK6G4gXw3YllosQVpmAZ2iq5ntE9VXr5bFv1iWTYezdjW1s2hlvpGtZHtNvHq/jUo51rdD9kH5D96adwwbyXLeFB9Pf7Oxb50rWwm0Ow0eAyJbHIg1NSh9p4RwIvpOZbrX7kY79Y0B8fhlfv20P/f5uwzYgvknDNiC+ScM2IL5JwzYgvknDNiC+ScM2IL5JwzYgvknDvj8QnynR8Xm2vlo45M9fDHdL3IB4fOvekeJeiW9GqVoiqsyMXttZLUPB17b4zdDuZv6UuTgwt2RisXD6IXt9+dG+OlmKOCmzR5pDM2rKuvePsg1p9VQe6wolkIEUQGw/+twSF6SHNZRFSMjlJvPrsqHIjb0FtkJmKHQpBIbaGliKfVjMn+tRBcqY5pZMLBZOb3gQ/AS7K4GYyup36W8rakr5Rp5Pv33z+u5cfjvPHsOr9ObI5NwcCC7xKrXEG64+pbRNRiiOucrFElshuMxQqLuP1S8QTqCZv7wgbgFRxGLRR9UPAOEqIMqoKbm9t4BwDSDssUNxiXamT9SglthpiVpUgmyyQByueGe6VLlosRUsQ4Fjl0yuEuQ/cCwTBJWf5z8JF4JGjX6S6CczS0EivQhLgvQ1Xm2slM7ZF5Pl06sSvIg1AQWRVtSUcIRdlH9KdTtd4R4SyflsQ7qwPHag97nNEUCgltkRJCXSa+F8/HWAC4n72iF+SLr2rkd9lbxQuWixFSxDgSM1TKUtOqrBQJpsBypEAhnAwXjU8AEzS4drJw0OYjMcbayUToISKBAa8sPp2SDCE5MOqiHbfc3xVkAekLqxG1SnYGNDFpnyWPTdlUeuefygLqoIEmREcJgTDnZylJqbay/rVZQqFw0necVQaF3HLok9zPPTbDm8aQSLQRQ8qMyWpVyvIAFGNBpRJ6tGvMqSvFenoQ/esHByFCI/vHWNqCkay0T0E/iD1i2OiLT4GhtipTzWhTgizJHOTN9aF5So8CKoAy4irmmxRhggrMpFG4jMUNArvwzacguIuGQhbAgW66sIrzjfWCOsjkYNBGKl8OdrSJOtBBXBJ54eNYBUHTWlBMJBC0HqFh2mMjVZG2kNKo5xfC57ZCqBCKkl1PlpRFENJqlpZ6IZIJLcXOWixVawDIXDNQNhY4Vo45tsB8+j2MvUpNG0DBClJRsxqNOBLbFS8tSkcVIwHQxTbjDlmEdNUREvDZrjc918NTWJjXzHaI9RUKviyFRPTVkRBD2sUxNqK3fUGt9DYitOtcpFi61gGQpBdTXeqlghV8RkaeWHdY5ayHofHI2Fo5i0LUFHA8HLmAdhYqVoihwnRRZIp2c50ksjagozMyaNtwL1QdStS8t9aSNNTcUx+h5hj5zmi7UogtD3CCzWXP4rTTtSTh3fY428nDYo5KY1ba23Vm/3LHWLdZp/aql3PFrDlo35sfJIoSByv8T3PkxoA/E+W59Xq9bW+vb8qN2WjfmxR5RJvrTJ20O/DYjP7pYNiM+v1bu6ZQPi82v1rm7ZgPj8Wr2rWzYgPr9W7+qWDYjPr9W7umUD4vNr9a5u2YD4/Fq9q1v+B0pcUYGvq9QtIZb/EB2o+4L8XwFEt3jsPwzEKfMPwjyaw7CUzdfcBY5eMs3f5E/sBUljj+VnM609JyyNwiI+T6b7qQ5ey1bLaNUpfaYHYuU5+CLSE1aHCNg5TjfH2fbd9O8bxd2mPP++8bPfKbXoWvXJrLaNmhfplz5Nufukka6rWRaq6e2Vu2Bc7ZMzz/zVgrIXBNLJHiuUyCUnHJZqsay+L5rD/rSrsDqmsjSXhOHl89WU6jIQ3lAK2FkgTqdJ/SYcbR7VUF9k4mOYVta1nfNVGkBMK4HIBhuKFd4ZjsYyEJm9IEyHqZszGpyzQLj1QHTKn/BK6lHLMgIn/Uw+tFSqBu4J9UWXgbiyz/uojqhQAlHYMf3XGhGrgJj4Je1DZlAkRQrwJZgTkVgWcMwMTlwawl3InIfsSDxdEYMlx1WhK8vGM8ExBy9aGGSEIX5LabHWytAJ7MBuJ66DAwWgsDzZKC7kJsvnDld48hCDYnBv0na4LQHE6yv9PSwAIXwMJ4wXZzklKltf81W03qrnoYwo9BNxNCbEQfFeeRK44sGR6AzLQocqXupW7oLhPFwVCHaC8svimb0grsqrPSaOSvod4Fb0/DayWkSNSq0MHUFgkAxw2h9RtimtiOISbYV8LrcMo+o3t/VEq0dcAQKX9Zs9geFVgThNp6sF4sBkI7Jw9Jlfkp2uc75KWiqEMZJcqdRPv0W2wKfgG6pIMbyFVF1lWUCLokufwF3InIc8IthiAIdI2QtpLrbHODWfm5iq+AYQrMVaK0MXV3yiOnQuu/XVsiuiuAS+pMtzKuOA2BTIL8GoUCaVfWTJLA4oUo4IsnNMNIDMKaE2DOB4VHwVqffbkOgEIDNwP5VAcCeKIkUwI0JZFtCi6Jx+AnfBcB7MGsFXtImrojxYXaxxTLzIAgQtozIajMVaK0M2+dQFYXVMrijNFVFcEKGlPBeEqagjgjs6dvhBF2uXyQpzIDIfI48EbQPdGsz5KmktvLIEhFw4iBrjXl9rIISZEa+Fw9VMTT6Yuwj+dFTuguE8TIhyxWNRppbMXuicjWeioXPS1CTXECZJa7HUytDX0VU54zQJ4WwyEbYaUVxcSBQaOcdLhABxuCa2iQuv64BQO+CwZE5JnppKvgpqzoyOV432olFjWOwA4jVgUKgiBbEMAkfFYs6EsCyURdHJYg3uQuY8nBwWP+J/e5aHynFVaP618Uzk2JsyGmhxHaQkw6IIyhgxNZNFD8oZVAdidWjZarmM4kJAKCNEzwEIWkzJPn9rgIDPNZeJLqXVAUoylPpU2eGbC8MpGYx0luWrCJecWuWFuRGUMOpaW5jf1j60herT7XgmnZvvLdkMs/p1s3S3orgs8yiqe+Q7W2kn3Kj7v2/NnvXt858MxHK1bx+7D25Y7rxFy+secYQPtOjxfnrsnYxP27aHft9k24DYgNiA2IDYgNiA2IDYgNiA2IDYgPj/AsSjhX0HeZGPWP+2V/kGxF/c5loVifFQbO03cGpeRru5s1Q3H7FNzbNlGaerk4DWqq+heiLMsgjlA7mB0/uFmiWvyY2Ne8QaCHP7tnWJ61EX+laolFh5hoZWhTWaGA/Bz8Uc5ryMuoQ2eyPbb6lftIDwlRoGOBzZuuqJdOjvqUvx5JOjqyFzoXmHog6+arl3VgNGqBPT3L5tvNfS/Lw/oDC+AITVqkhsiCJtmKlqtHgZ8w5uploAAtv12ASihsxbbkjWE8EL/WWnt4HoKvWQ1mU6B0J2prn9AojKWAGEflZ2AbMm/FyrQtkQcJWTlsYbOTwcpxaditM1vUWclCbw1n4+jyMmlSpgsKqGTVeyIF5fJUbJq3AiXsHzsGk6cDgSg0P1RAa5RMjnTkwLKIF0UPKYSr2RnLeTl3InP3Ae5ZYM1AK4eygna24MGi1lbp8AI7aIOMcO4krL7XROOCRs06kXmL2qYa5VEQKuKM+ucnW0B8PSQc7MkBDNjJD5SkgLFkdK9ZpUNI5VuoIF8ZvVDZxEI3HsfvXsJ8xp8Pp7ZnCongjzMhxeEqZUXsaCOlat3kjOKw7d6Cp1Xql0InQR4E0/UQSJI0pBnzTscx8c+VV3guoozuXcTvjrZL3yabZneYZprlWhHeqlCwgICnDBqW3OWmkiAyHncaTkUQyG4afpShbEb09skuEN0Uick7/epslaIKVuR5dGBFIw+eYtUw1KvRHNK7oyb79ZU0P4LBCvCBIppbhYfNu+c6K2AH0RI/2Q+w4j4o3+V0DMtSr0LsICEZIxmlIsEKa40LnyfAbCcCyuqLRNV7IgJmnyMAE7+ettGnRstl4CgdVDO0qVPIQq4EogQgICFJ5OomcBCATiCKKucUxAKJ3H2s9AJAUSVwORpDYgDOFFscKLCkepVUH/spoG4o2Aa2GmJp9YdInZUExNbDkEy7FQBYxiakK6ggUx8eCO/+XaC0a3Q9NgqsnWVU9EgVD2hZdJTKayQm8k58XUFI6vr5QKfBa0PAKBSClMr6OVCByWBISxj3USKhw+CRflnhbOI9WBbB7JgBAGu2seHS5pVVCvZTWNjhkP4FqkqFG8X7MnRLUin59YeyKnEgWMkyxhJl3BgpiYeoIIJN5lnodNwzZCZnConohob4SOby1OUAJ5hZIH7lay3kjOe5L60zp2gjbHK1RE+KaAA6MxIUaWXf6uNbMPvgZq7rn8QY9Kf+F7hIfN19zxjS845vbw7nZPaaJblWq5LJ1sgn9/HT5S/1aOx8+GlbkXgPjM9O99kJB1Yr7C+nvyBveHtu1Z0zfZNiA2IDYgNiA2IP5Knf9czTYg/kjeDYgNiA2IDYj/T0DcI8B8TaX/+zIl6+2tTLkB8WeB6OZKG1YpQ6ONlMf07UzaT8Ef7mpaDPw5v1lGT3HJ1/DvWzedoo8h2p1sCeWmLv1QPWsash54TnrnxatWVBXlUrRYHyaTKwMpLzNBTjdeyEIZVTyXaS7wULAh1Ldqjzlv9q8ZiHuaFsHZdy1J3WKC64VfgQ5J4SJUj9PgrtcOKPkbDQ2Sqew0P6MCzJkqIbn9lfXhXMnbsDYTfcAtM0FaNAG1iTKqHm5InrTYEMUxF/J+F9ZqWgT50ffxO3c9Xo9JXl2AOKRUi0BUl/8tIOZXbZupkku0rI+Cv8Evrg93gCj7qDVmEmdjqvkm8lZ0Us5wJRsCShnVMbMPT9MaTQsLxIGBeH19fRUg0ojoVBdkKmOcHCRmCqW0/A3mU1wPIqcuL+C+IsVBOBaqibHMVCE7Feuj4m2Q4yZMYQIhAeoZh+syE8Qlt5fyVzQljwOvCiHKNzEjIon0Xy0bQpAtjpHGRWJLhLWaFrES8K5Rx5PnK6b9LVMVrxGTKlwcjaaFxjg56siZSv5GcIhhkQMMdOzY1BAJRxPDZZmpcvT6ar+yPmreBsdvESD488Q2pyUmCEaV5a9A58Y7eAtzShGSKQUbcEVZNkRycptjzjAeWLJllaYF14hd82hWBoK0KPKIaMc4kZFDwlwFf4PSEMsjBBNNhVOoy96EDllkqjgBKrM+ZryNYmqKJeDYdJsJUtImggCRR0Tmm7haOcO5kg3hiwU8RyDRfTR/jaZFAUSxWNs1YinGiQIRr8mCv6HEloEFGrg2iE9yRUceG0C0oqrUrI8Zb4Na8hpezYhYwwRZAuKY21ov1jm0UcGGCDP1DEwLZTSSlZoWC3dN1RpRxE7RGCdpagolf0OjlZi7jylNTSSqddUYLreYKik8TWJ9zHgbR+Zk4IpK9VhmgnhR1cn8FdUZ6ZguULeVrg1eGFU5o1TK4Hv/qT6GQF7Yd2GtpkX7ewTWjNNEd96nWeyUHOPkIDFTmAth+BuIX4KjeiOlizVzJ5zGcLnFVNESM+uj5m1wsLVXqI90qeRlJogX2qbhr0waUQa8vrLk4ibM3hTeU8/4LE2L+uuQW6zT7W2J2xHa9fqEEtulLSuMdFVtV5b8/kcc4QMNef8DhyVuR/iyEj9ij2q7PWv6BkA8kHIDYgNiA2IDYgPiS61uQGxAbEBsQGxAbED8TwLxt7b71Zun+FiTbtv7j6rQfGzr3AaE2TJfwjn1C+QNEUUkiknzQdsp7xa56XlpS2zWaFFMNXukFUsFKeLPpEWkI63qFCUOjbpqbuWr5COZrcLxWKpumrMWQtkac1zShlYFfetU6aZ3Il8Q0vWatLERSaXNlpisOZ/t+VIaIjnerVhDxR6po5MAiIE9R6q2kY8MVeNsKYUVV0I/iDJ6fSSzVbyyVW5GTgnOVVorSjSog/G01U9WAuEKIA6l3oQ1NXUVEFrNuUZHXSlXsUfaI8Km6JoaGstAzBkrc77KDbaKydkeES3Wxhogunm0ksyXgDvkdD1ICPvD1QLhpjZbQpUsDjk3P/YNaSyV8UZUpwIvAyduwxHuEnIdHaQEvAKLFOyrphSJURKEj2JZFWi8skGG65yxknMrX8UcMbbBVrkdOeUAh5D2F70G7TQODTpb2R9N9ZM6WknmS8BB6J3G/jj6FFEEkVTabImrRhfR3Hgld2B/1zzeCB31Xv1midvwmkSCPPgRRyEqIAVeNndGfwOhA0pWhbAOwfNIr7JbxkrOrXwVY8/sKw/jVuQUKoP60Xsl1sG/fTThrKjcBfWTOlpJ5kuAu+Ah2CBvOCsQFMWkzZaQEGdv8EyDsTDIvNKKNwJ3+uAyEJnH4RzpYXitU8gpjt7O6Tiis61lVSBQBvM8XBazMIyVnHvKaw6OZLaKXgS3I6dAdYN6grV2Yt27gsvXSeyUBfWTOlpJ5kvAhHchBf6yQCBVgy0xKcAZCF7qlIhQxRsBEBpIrORxOKbnKBCYrLLT3XZcvgRKVkWX6mLZfJmxknP74s6N7fu8D7bK7cgpYH6A9UFnayDchNgpC+ondbSSgi9xFM6Cr4HgSCpNtgQ4bsHn3J3TatYDOgMBrkZmQShlkfQw0ohwrqG2UWtoWFZFCqZ0DHZqMoyVOV/lFlvlduSUo1w0PjEcu9R7WM8QO2VB/aSOVlLwJYi1cEXsD5AHEVFEIqk02RInRA1hdgVyn2TxkqmpijfimTsBroZhikwSviaAH3GSWtRqGwXj5CpHEqsC3yOoHeB5zBkrc77KLbbK7cgpulh7J+0NpxyHhhuD2CmL6iftIBmPbWFh/1Ert7gNYNDWKR7T0Lgff+UWWyW4tZFT6q+uwd3+7L4CiI9stx4pDNd2ij/3iOOzWvkf2LZnTRsQGxAbEBsQGxAbEBsQGxAbEBsQGxAbEJ/Y9D9fg79Xp68RgvkyUx97u6bbgGibypyFlZoX0M9fVJs43SwvWHpBycK41kdmihZ3uRPBHKe0WS2WnqDyG574rEWJr+A05ZJJYSRzOgrLoaw5tDwofXq5mPI1tDxqXzZqPHDYhgSEsBikuBWaF5OwOBYKsR1d8jZ80RZ1nSdeRspheRSFlbvciRqIHN6eXxQOWbyhK4CAfjhKjsdMfAetaWi0rEvpNb5K1vIoX5/uql7w3rksFi9AWDWKVZoXkyuijtwCYn5dtICwNegaihauAYTteu/WANEFPEhPHTMDAiXHUjXeywogkL7Q3pg61w7Tk63pRWdUR5SnAP2LNZoXicVhOAmHJJveZjjMOQ2Zw5B4Ga7mZWgsl/XcCWZ8yP/iIgFjwGttyI/Ojq1Xc/FIyQy3apCoKscVHBbhlIgOh8vpp1rLA3kS/2QqY7R4npQABNqTeArwx67RvEgsDsNJYOaCh3oGeahrhsOc05A5DFoDlVMxzIrpUe7EkfygTC04luo+gd9X91qbTjU7jhYIlBxdmiFpkIj+girqsHsTL+FPquVB6btKyyNInsQ/IfsmRgvFUekECPHAW87COs0LZXFYTgIxF4a3YZHhMOc0ZA6D1uC4wMt4hDvBYW/eshJBmqmnbmIgJGxIV8Q4USDkNoGUAiadUAJHPAniAaeyJApNGhGQTsnzP2IaeWc82gyEjdHiNfIK14PaVHAWVmpeTMLiMJwEqep1ieEw5zRkDsM9XsYj3AlciXMgvIO0iahqyFVrGRa5ZHS3Hg0uq3EwD0NKy1oefN9UaXkQK0VHBPUaWpBjtHgdlSBlUJtKTYhVmheTsDgSJ0GEQoQr0WI4zDkNymEYploPo1a0eIQ7QRNlqocDRwQNDpxVa5OnJpwHECiZBZacLtaURuvNPIwZEJy+1vLgCQzTbeKvmBgtXiOveDM1WU2IVZoXQVgcmZMw8eLzOgiPY85wmHMalMMwVDWwR6Bo8Qh34nBF5JdBbkDBBxlY64O+R2htJOoJ/cd5UzJ1rHI6wAHRetP3C6Y7X336HoH0My0PtNUFiaXC0ZFMjBbvJPLKVdv+aNyUJhX/8egldv8eLyO493In9BvDrfrZ849HVbmdXm/6g3/I1JrtdjyT9233HnEE9+e2z33EoUCs6rXtod/XAfG3TG1A/MmiNyA2IP5KXT43/Z8xtQHxJ4vegNiA+Ct1+dz0f8bUBsSfLHoD4nvU9BMb+d8XXvmPsp42IG5vvsWNwDY0HNLB/Jb8s7MNzQCXGRJIdHIlA+JUpKEnlBVDYkXUltPb5P9942jT9rlv/PTvG6n1x1RTydOwVW/0gvcLzeUDb21bto66narSjHJzSutrl3whoODrY8FVshDJneNvAGEZEqJrMSXGBJJMNo236X0G4k7UFkcO2eBKT0j2k8Wn9VPF02gyRHwNxJTP1PFYsq1MVHCmjt3smKDu6/75FCDcXSAy40F0LabEmHBl1BY9VjEkwqqoLew5PPocuSWIYwbuLlOqX2aI3Aei5HCoXHs5K3QNcNwyEBBbqBU5wOQgiXKXlDLemJdAb4onfQ7mdTCDwymbg5gdWojlPGSGBHQt1FHvA/gjXcGiCG6oGBLrorb4ibU8fI7cYoHwU+Zd4AX6GUPkNffAIXE8ChWNqYzHwraOcAtBASRIbwqXAywYT/3wxp94UpKQD8NV07LLzs0UOXD9kDtRnZGkAkDviocp63NAcePIQ1+VPELIaFvOQ2ZIBGFI6GchCVxtmsPVMCqmtVFbTjyq4rHXHLmFgJBPVM6kVkELKhkizvBSVE3EuUpFY9LLPnM4cDGrAkiQ3szCGNSz1A+/04SpK2XwmjZxJCpFDidAyCwLIDi6iMv6HFDc0DlYAAxDGogl50EZD1Bf6FzNgLBpjt4wKvIScSdqi46I2IEpckuQwBoWiE6VB2qGiOGlqJoI6mYYK1OarCoOhwpPhEQToPYr+cI7ADFIuJEslSHtUZd8pcjRBIJd9FO+0QopDpAFIi5eR50tratdGQ9yFzSVDIgctaUTORbdt9zD21FbdI0IJnJLGwgl0pQMEbBUzKXYUNGo47HkFpRA8IhwcyDk5mQiOpICgRFxVCCsIoedmjSqyW/Puhgh63OA2wHJHo18Qtcah71gqxmIzJBwabG2DIgctUWP6T4avypqy527pm5WasUQOYbUWlUTqVU06ngsuUWqAILpBvwN72sgymU6p6XlOMwVOZhZQHFAuJlQypi8KlyoPodwO4Q+CSUPVrlITI3MecgMCehanFzFgCjSqA4GgFgbtYW+R+Bqt98jRDKLV5DTVJZaMUSEh9Jds5pIraJRx2NhWxM0PiSuynWQOiKCCnMmuR8mL8oeaWrKaW99VVu5zXNksq9NVTMevkPUluDmsU5oy3yQsNrWvV5Z3YOfB0SbtfB5jzger+OS1bCq5utsfRoQX71tz5q+ybYBsQHxRZ23AbEBsQHxVbY2IL6JrQ2Ib2JrA+Kb2NqA+Ca2/lBRf6fT/3yHfVlJGxB/uKT0kCvkY5lVEZ+/T8t517AWkh2cLWwjli3216hvpPrNz1S1dwXbghkkD9a7xbZY01+nt3f0Vg4n4WZucvAUgms41h9iLagdKX6ytoPP+2vUNzRRA4iq9iXbIkhclI+zLe73Vyjy+HWlLhtWnkIw4h0NIKpK2uL0jNo5zBgbsK37a9Q3HgGiK0oHf+SDbIt1/bWgvnGjVLhQyPN6EOZB5isok+JwTZwHE61kPWsh20FME8vYiJa82V+hvpG1MXTyQGn32BbR9xg+zrZY119gplj1jXuluhSfIXhhHmS+gjIpjuJcL6OVrGctZDvyKu3V2kYsHzl/va++EbzV9FAFEA2qsMy2OMJZ+kG2xbr+UlZIVt+4VyozDWgRhb+15ivAPe7Se/w2WskjrAW1kyYMY7sz+67FrZjpengzZagCSHD32BZO4qJ8jG2xrr/QjlJ943apiD/i1HDNV6iBsNFKHmEtlEBYxga0psoG3FbfUJ2LNL9eIU7h7rAtnMRF+RjbYl1/6QVVqG/cLFVUI4xhw1dQVoXGLymjlaxnLWQ7nasZG+DhpX1/X31DdS6EKXKEOEXSylhkW2hclI+xLdb1l4xpq75xp1RRjSByJapq+QrKqjDxS0y0kvWshWznNGNsIJaJ7je5FTNdD+hcCFOEWSNgldxmW2hclI+xLdb1F9ph1TfulXpze0SbIjxo56ORS4Ip857WxRexLT7QX4+UWjXhY5V87BFHeLC8e9yLP8e2WNtfj5T6kOH32NmeNW1AbEBsQGxAbEBsQGxA/BHrGxB/v3s2IL5J92xAfJPu+aqS/m53fVbDvj8NZwPiD9fkA4UJ1+JKn04zXoLlXRRbk2shh1S7ICwlqLcW/6L1NKmIljJrRfT1TXXK6qnUrNbmszdxWry3Vt29lk4+HyOFZRvEQlVDFraaa6EWLS/B+ZJ3YfO1uRYBdVgGYqo73zrmS/6Ffb6auQ9e21cIVSCPTyV2Lp9XSfm61jhbAqE+Dbiz1OpQ9JtvtFQCNOA5ctDivOgdTIWfo2vDUXEQCq4FPMs1p8M1m/QZQJT8C1ti5kO0gGjlMUC4B4BI+92chzIbvb4YEd6KURdAQDXEtQb4nGsRWlyLFqfD3eJaHFiYnRw3k29zLpzlQDgbZaXmX0Dt4sBMCOI+vLFr6HSVhgrTggXRVeTBoZakhOC8RkaBQ+Z0VQmIWoOEOy/gJWW6+lln5DW3nSOgTCU/o24pYscglgrpLMTjr1Qm3L9QDZn3lmtxLUR0pORamP1hFdfiCOfgkYZjm3PhiqgszkRZcRX/QtQuSH/EqwxE0Gs4MS3os9YSr+E7SEgE1U9g3XpmomTpC6tBAiCOHIKBuu6I196nbFWcvYafUbcUkTIQS+VE2iNHKs07LY/fEZ/1VpNrcZypY+g8aakE97gWIXlpfy9wLpzlQMhk000t/kUWWQgCRMyF1IZpgc/Ic9RaBrRjQHgOjrjieZy0NEiQg2qoHAsWizBWO2lH5mfULZWQJUq1CYhDk4EIzd5qci3CTB2jBcQ9rkULiJJz4YqoLM5EWan5F3MggrNAgGlhgQgVEFQ/GQ08Ity1pUGSgUgcC7ng1KreKGR+Rt3SAghIYnAkFpQnC9Ost5pci7k6Bpr/GNeCq8eDXObFqeZcOBOVxUZZsQtvwb8AEF6mJk5t70bpc808AalM9JrwnyKkhCwGYzVIsKogOkwiuxxtP3Sz6Ch1SzV2TBoRrPDhvQVi3ltNrsXQ4Fp49yjXgrq84yUMojxzzoUEIkNUFpejrDhX8y8GZZG8UtoTlkpO7QzTgjVCKuYJsShosR2Uf3HVWjU1SLiOVHNqMaKhEPui5qFYfkbdUsSOgY7UacJSzWomRXl1bxW3m5/PtahvZ+3NZJkqNO08GuFkiUnR3cxR/15rde22KqJKu9ntY58T6eQRvYs/8YgjrGrNRx5xPByHZnvW9KetbkB8E6sbEN/E6gbEN7G6AfFNrG5AfBOrGxDfxOoGxDexugHxTax+E2BbR74C+GWbt0r4/K7/a2BuQDxgMeiOt0cSg+HuVkZdUdc6nnMr8wHPWiwrJD5BlTgq+QgVfCrOJ+bEvDaJZTHMa3TNv12oy4yd0ccf3kbpmt153q79C53rx358vuxvtH/En35/p5/I0q9f9Hvs5znG5PiugPCrnxd2BRAqbABfgDIfSkcTjqk0uzlCXTelPCatrzEQlgVK9NU59R/CYV+XGbt3BBCEB3UNdRLDwcec/H4eCYjdeXce+51Y39Wda4Aoz1lbOEOWfv2CPc2xWwGE+zgQMz7FjBXi5G19o5QxWSbJsrJFJk0sAuEUiJqJ4s7oPeoiACFd0wDi+eX5Zex3S1f5IhClLdrI0q9fsDfPMYIZwVyExLbQ4PXgWnDY+kDH366Je/AKafQcdaXWqnDOMh+cr1khwUF1o3P5CHnXUvgOqkXmYzg4oBCdRWvrHcpP8U+So+WNNS8OYE5UZcar0rnz/jLGKcedqWsIiP0l/rj9JU5Dlx/xdz0i6OiPmCL+/xmnrfhb0/3gHPufSIPP8Szbov1ntvvjYkdEypHsxZxgIDjDtiC3O3mXfOHydOKepGgM8LjVoQ2sVoVzlvkgV/+1YEMIU8SwLijVVT8dfT4jr4eHI9yjUtsT+fqCMim4tt6nmgxX8D2KevA+jQSZqkcdEfRDR+Ox/ol+u/2Y14gdH32KKZ5iPp7wY3ake+rp3PjEuSk7LwOwhX+0/9TnNSJCLznUHp0XBoIzTn4wGALrdCQgnGPmBDEPEHekCvZRaVU4VzAfJpm2zLEcrSuxLkKmC+C87tPlQeJdoMSgtlQO1USAYJ0QjvjyJu3wQmGZSgYGjYhegZAR8fwSr1pHV2gfF2mGw+1GvccZ6cyLQkUdFz+Nz5IuXt9y7vml56konhlhi6wJ7H2+a8o5kj2aHFtABKELBLn2FIjAzAOwElpAZK0K28WJqDLZY3ax7oS44nK4GAOERkbppqMBAnW0QASpszAzkmJMycCgNWIUIMwacXF03V8YogYQeczsz9yVbANApHMOQIxuf4atntPMgdAcas9dFAiPDgfbAs3VKYY5FwoEfo7BtaemrFXhXK224WoFDlnA8xFnIp5kwptP8VEoPhcDIbVlSldQJgWnO/qkdSG8jAYTxY1nANH3bjY1xSkDU0wFxFMaEXTkaQRgPeelc08ysWG0OdiK+3FOagAhOZK9noEgBgKWP8z9ulh73IsLj4EjqqSlWhdrjbpSa1W4mdpGzQpRpkg+QkoZp+K83YdmBdWqy4v1a2ZScDriUkhNhJcR5kwU1595ud1dxjxZYFm97OLx2OGXEohnPjr2zxdKGaeSn5Qe6eKRn/SfcgOIbCvux1KeOW0xNUmOZO+S79uWv/D5dcf0ltF+uscKaR25FVMlrL6pDib1EhPFuXvfrH+9NL7A9fn34pe8fsni+rSz7dabCbeB+PxHHMGt3UKR+jMfcdAVrL+XtqWzLYu3LX3Stj1r+mqLGxCf1h8bEBsQGxAbEG4DYgPCbUBsQGxAfLXFDYhP648vNfqfpp7817YNiC/ZdvmJR/EQakznMueg52e36Gw8FtNze94D/0HsjNaaPIiPx57P+ejzRcuig/zsxdahfii2/JAsOmv4yef5zFbxZJOefe4vVM/42Jn3nUPhZ/kPVoc+89k7PG8lW5R7d6anpL9ezpzm1wt9/vVCT2KpFXSO/NAo8z02YVFSskcvNXRnWsx+wZ4bkUE7E/0ET/KFoaBneA/eXrJDPjBrrR8pL+Uex5yPnj/2CYjeFb/4T2/KKIFIvBhiYlzgJXDcKeoFUF+DY58Zjmmn9fwfndabtsCngNzkuKB2nfnTzuGz2MY+FX9+r01YVEKBbV3BaBjTgQwEXQFrgOB/Z1cAwVfPS/nwNwMxtoAYG4O0MTwiyKMCweOY/MFOgOB6/XA4v8M4Z48ae9VGW8ZOQXQWxh1fOuqrsyArEO+1Kd4/MAieyYUR/77A6cH7ymgQVwdnY4bCRUfEMw93PsJTCv1VIMBkILc7MRV+MGeC06cRgRQ/4FqRsnr3g2uiHAku/yx8CGY87PnzC9dLeRSx1lTbF3L/ku+LLrQfseQfFRDcZU/knMT56F2+0P94sZy5lY7s8kV1nndaf24AYUbEe20mIODSoxm17/+hZE9gHdCMxH/JrODHVIRe14g+4bnDdS2UKeI/wBXYOzAVnjK9La0R4DqofZRFn2l4jE/gUlCdlA8BxgM64Z94lmoMHkWsNVctgn0GVJQ2pvuJGZmABhCAEnV6vqB+vYxj+vsP1yHWhy6bM60DlPuZc+x4taHSn+U3paH9+PuMMt9jE7YAhFM39z8yD+6ZadC7UaaN/YsAwXwHvTPCiEhASCo4GUHLQoVGwzNM88sIrgNfIS6VdaZaEMcBXAriRfTChwDjAfP8P3w97sVLTEDsmTvBSwVN0sxFIjgd7PY7mawcZmOw92iKPvcyMaPThEx2/iFtj0vsyw+30zWSuRo/sq95/OF0RLzXJiyOL00g3OWJuQwKhM5odMRdFIhqREgqAIFPWKxHGRHPL3ZdANdhlK6Sskbe42HDI8KhRAVif8aC/A+PVKqlAhHTELQKhIycGohRgeDzMk+ktUmvXk4Z5/wfkns8WyDwOTn9zwmId9qExbGXgW+A4KkpzurgRAGIpwSEru+NqQmpBAhMTT2AoDWiL1fcUbkOXDEtC/A/0U9cLfjTWSZPXezODATWFkqzS1MT1lMGIs3ju7RACxDoLrSiR9PPcrdGljCfU7KY76d02qidpsymPCJ4H0C80yYsxtFL3APmG1x4lXPgI4zMPwC7oHdgHOx/gqGgQOB+AJwF0BCfeW8ni3Wc/3hm5Kv/567wzcbZnPPJ1KRl9cyn+Ek/I9/1U6+CD4G5fn+hz2fuBqplTHM+05R14X6Jo4y+R7jEuCD+kd5O8DcKKjd12o5Wv8tZvr88s11qAXUV7vkB47PchmCNAAVzdFjp6CZkdM/vtgmLRLxsfzdyt7dfL498s25bu8OEuJljzF83nX4raX5RXXnszr3xh7YP2Rzvpvg4ELf5C+PNHGORhtlyn99p39jmO4HYtg2IDYht24DYgFhzbts2IDYgtm0DYgNi27Zt27btA9vzyy9mITh4ivpfL8qDeA8ngZ9G0qvdL/oiedxjR+bMZt5GenSZ+SLL21nEGsrcedcQR17K0vCJ7Y+Nh36JHrErPjWSVZv2yfMLPZFlJ3DqI/EN4fzZWGjU7Sx+WDzK56ft/NT+3ZwE8caNcNCbt4nnPIfc1LMC0fftpuvvJhDnnHaXUu8qpsYZLkz2zu1mqS0QuwII6/7PNe7n0PTsLxwVCLWTEpyznVbdMhDim3sCx+HdnAT71jG9lS9nWjZNV44KhLsNxLgKCCUK2NLG3Cvnsov7myOirNENIKLTVAgFOeUiEPO6jTUQPwSId/McCiB+FECUNn+w+A6rVHBtf7AbCPyRUu0iK2T0aUIgNxJSspNmlLRnmiQw1svS6P9exoo6s/bMJWF30c8MxN7lT1pyUuE4o55xCh9/CMNFO1ocPMIvgR1YViDASWnXjTgU513yNBHzgar5fk4C1hkWRIgrx/hTgZjzHJ7Ewfoknu4n8ar14unKahdQyIC7VC9EeLXHPrkakfasi8R+xtTouX46aYgiwAj+SHRUmqkpfxqFXZJUOM7Q2oBv9qk3s8SFL4gevBdp9RMsKxD8gvx5qW7ViCBPs+vfz0nAOGFIHb+hb0ZEaTN5uvkYL/Mv8JzTMm/VLvaiaZHpavuXvbKBmAWR0tpVsCiN/u/yiHgZQUcYyS6EewwQ6ZNyA5MKxxlaG7347+0aofwkOvoM1kufJIEUiMW6sXRRAUQvQLyTk4Cq6NQ0FlNTafMpAQH9JMrZC5+jVLuAQoZQMnDJ9+7C15uuMJJ2J/cvPBcXpblRgZBJBFfiOXNVWkCgZIwIqtFOV6o7QIxKI3I1EEt14y5q3TW9n+cwJv5bfddU2vxxUc4TbqKEwNOjgaXaBSlkQHQHblHm6/0cE0eJOhRktHzXVJbm+GyvXfKE1DEf+CNPeXmupqae1qIfIA2k+0W+URQgdtLpO7l/HKupSXqmBGJWNx5oNLjz9wia654/wHMYecXZOf0eAYYcl1DYZIWLM3M3+JZGF+ve1WoXUMggrgkD4XAWjA/qrb3Mz7uL/R5Rlkb/ZbEnCR/i+12YEMr8EbtYP1/sYs3sEv7WRKWp1gbqwyQ3asOZuSNMRgXvhT49X7BY4/wzL9bCMW7U7R1Ehc/iOYxumU/xy9CUaz0MLX/8JI7FmpqON0rcLXz5W3v+Qx34J+zc06j4IxoWBRB/rsRt27Zt27Zt27Zt27Zt27Zt27Zt27Ztu7X93XBB23YfCLAb6uTzZ1zn9Nv+d7UlchPmKCQ9WBrtKu0bxZRvAzUqwrFI5jb7VTVspXluHEt1kCe+z+eqjuO8PNhJ75K/IHepNUIPXjmqixz79Qt604bdcJ+zoMX2xX/Ng0fsLj2fT9nPdadlizsruWGa38+A0BglO1ELmQOxu1nDW62oGSZnS8zp9T29SqPkPC9PVEBUXUESV1oj4w5RXZzGdJHAJJndcI+z0GYflIyGPqW0QIyfAITZkfe650DcquGtVtQMk7EFRK1Rcp6XBztJb2QGxJiBOOPkLgOR2Q33OAv7JvuA8pzpRVoegkm3Q7gSLIbO9msFDXb8sJNGSyFVjT3rdjiwPCT1/idrgDjJ5xC9JDM6uG5Q7Vio4b1W0KcZ5wORUkiefYTjqdQo4bgslS2xk0YE4qWUWiOOo1aAe4KYLpCXN+yGe5yFXZN9QHCfexEFyrodKeaCvgZfK2iMGnnkSd2krCFAbkgem0/idKTYI+BHId9OXsnXEcevw8Opel6q4b1WUOyI+pjyRKLDc8xSKFmjZOfm5cFO1ht5YidsqTUCIHoT04XCJYWjy+yG+5yFFvuAGBb/9KTDIY7ElwwEK2QklkapoDGmd/hdCp7xDyuAPGNq6hHrxDClFAg4YmXxhF5HZki0anivFbvGsb24g1FLtMNqlOwa5cFOnmKVcma1RnRE5JguHBnGu8xuuM9ZaLEPVKREgRjNiIByhrI0SgWNNhB85Z6V0qmNeZoBMWZGh8uRS5ZqeLcV58YxyHBpLecaJedGeWxnDoTVGnEOa0SO6YJQJS6zG+5xFvbnFvuAGBY/f4ryRtbt6PPUhBuKUkGjnJqUr/EPszVYZKY3+mNPPy4a7yRPTYnR0Wcglmp4txWNYzoS09Q0Vhol50Z5+jkD8VRrjQgQY47pwpFhji6zG+5xFvauxT7gGCSjKG9k3Q5QGcGQGMEltwoaWKxZ90OWMzoWF31hR+xMrBHS5YBuxw4afawWkhgdzI2Q3ws1vNeK58YxsEigDMLtOVcaJeO8vGRHJk1obJRaI87he0SO6cIxal7d/OvUEmfh47SB8Z12xpXHxw/Yek9N3mtr1SOOr+QsfDYQf377nJpsz5q+ybYBsQGxbRsQGxDbtgGxAbFtGxAbENv2DYD4c3h+RZibv9X5X1CXDYivAMLf+Zy209vprbt202miZ4eTj3vXeHRCwPEunu+mbqKUweQaktXBHM2pO7bLcd5D/B1sOo8o7Vc5bzcKc11WG59D3RA+8AY7FGNbyr+6ZljgbkXnNjrordlfTqLMXxEJHLG962PZoMde1yxHPgRqaODQ9rHBEYjgJ48Q8IGOo/s40HptokuGOtPMnJr2+Me5Kf6+2nQUh3pABX3VUZMC4eW3fJ5yzbt0Xu0EsYP48DntMhCtq7KbnVuAb3KpXIkFPiF2d3Gs6OTiWmtXBEDw1U9AUE+wKerNEIs8ECZivFsAIm85Ne3xD1U8dMGmow480Kl4vmrsaiA6YyeWFzI8Xw9ELjf4To5Ux4br4Xq60m83xQEb/w7uQK4K/vxGxyVNHHdXx4M6xBQNICJAB1Rmysg7ssY/XUzBfIWYYpCjNjXt8Q/v+VCkm2gYB04xwKZDvTr+q60InuqJLomfgtR8oumUu1vsRI8Y2xlknLxJHdlJI/XCNGiszFNJ604xzYF7io60bA2p3OAHaaE5dqRj/uhpePiISvzt6O8xXvSBP/+OZ2MxnMa5356uXh9O09FHKBiI4frbo/m0RhwLIOLRIDMPo05WYxfwlHP0ufsDW6C9uPJgSrqGUKTjStPF0nHXH/m6onrhb9BWpFFOtafyuOaTjvDBwU68HCaMkBOX91vq6DhPMKPWWJmnmtA6dMtRVr+5LXftUrkD199dMUrk2CuNiDcydHqjSXPgKRhNwOz1mw0NDBGAGByNCIKPrrG47sc0fMSMiM7ZEUHWyQIBcXoLXlPQUZuaVwQvU5dXICQdA8Hd7tE9CgD/5T3Py743NwEoLwGRRkTsMq/TFUbEby5loN4IWi+9MUlW5qmkdQwE36jQkbYtLTdN2VM+xpWQa4m6PeKkQMShwpPPb8bZXfOIiGkCr9hynToGK7i8RlggOp5ByTJ1mU/3VR1udq5tIGixpmkhp8PVExIQeSRQgxSI4DIQcZxJeVgjIkiyRnS8VFsg3PQbtblSy7VemJqyFb7Wi1TaugxE10jlUqeHBIQu1jgGII6HK4bXxBOUjIj4f2IgaOYLntJ0aWpCw2WN8K+vlL5Ld00dL5j5rsk7nZr8lKemkKYmTd3lO4gpMHo5nXagl7FAa0OXgeA03ArusWGCDS6PJ11718SND14W7wQEfo7B3sUw2NlKnUqA8LhtNEDUtnQ94P7TxTof4xuH4TXwvSy1KM5f8S+tCbTI0GfcksQFi9JME01ZBAwvj3HS4DWCZ8Jo9jRh4jlFG/Z7BFMKeUnrQC6MKbQMm5r25J6aSgk2HX2POPHf+InHQPw0UR145ufadPJbvn+EgcujI+X3CLIzxJEzSJl0avJ2eZWbCNxeJyvU/jKVl9bFc68yNb3RfUZt68RrE8pF/U+8EKRjfOPQ+jbj8jUR0m+eDKrE+bvhmi9AH9nKksLNEsNqO7dafuuGdjnVUi/Oy50da1U7fdczQPDxaalZX72VJYVPsnOr5Z+banvW9NdqfL/cDYgNiA2IDYhPtvMZ5W5AbEBsQGxA/PEab0B8kxpvQHyTGv9RIL66gWp1bv1ew762Pt9424D4+MbPw/W5CD25pGeb0aVxpaeTxNA4Xf99mzjNv2/0+d839cnROeZe8CPdzN5YbxMWyQH7L9uhR2X0zPXfmJasagewdaccCD0Sn3xOOOLtMbMvdVhdH2nPlZ85+4GPU7pTfBKtrcwckLx110a/mi3wM+xZ2jADwrrYvXgk+Gk8P0Hv3OThF/PiRBUvte/g76cH4oa9sd4mLIpHg5/uwn4nPnEFgqwPLvv9cIRs4Ujn8rHB7Af/aBuFGCFeDmmhJ7aKtjL4OZfAJypMZsFYckFwpmty7qkEK2T44C7JlURVOnSROGMSEN4CoXyM7iGb4vpxAoTAffSdWFUgyPrBZbdKVV5iRdCxg5udX9/GDIQrgbgecytnXBLn58PAuxIIZ67RJhATfK+DexNWBLvzq0r6qQFEMSKUBgD/2FqbbSAOMyCYWuDAd1DvFrlUa1YEHbPn3YP1WQbi9dVlq+CAsCvqwNMfOd/A6BiYXUIuN+wNwpIJzPggPojn42/MbFHOh1Mal2cXOl2JxL2IM+VEc/XpCn5Fx3wHpsTwZ5yjNaKjlWKyQHQP2YStOGNPZInPx7UgvPJ6MAOC+Q7Jh03eXbniEyuCOVEu7+PaXV8fbhWvGUwc8mgh/f3tExABXBJMfUdhrIRw9EFczeTpD0fZYwfvMa43fN7DB+rZ12/4IzpUvJBKcLUc0lVxeju4Tjl31AT+LHSBcHB2RGTSwHqbsBjeyhFBjXC+BELIBS6zIuLPVLMi6Jg9j8V8fX0whRxSN0sL418FgqyiHgOzU9AXHmQhZcFIO+j88OZREjzrXBf6+zuuZZk/otOnuVp4uphiZXR4ThYIfE68jakNxHqbsJgWa58X62Ugcqd7V7MiOlkudd+7x+ojLMZJgZAWxr9TAsInUo+7EmVsGQiHUbAABI1j5Xzo9CmVPChFhBgZr1LJkCoJIEIeEbyfgEBZ3UM2hQh2XLprQjpYj+mxSMp6wFSWULIimFSTcmDteaiN+AnprikIEEGBQLdyWuLtvaLbBQgh6oU0NcW14agUOwHCKxDUQjM1oZK4Uw7MfAugdV11wcIMCkYDVgHcE+ucTjM8MRLAx6BlbL1NWBxeaWWw3yOoDGaJMMcB1pm5MWVWBChlJSuCjlG6tP/2WH0C52FaHX+PwGJNf/E9AlbBxWBiKtWeF2uChBgdoH7SWd6jde2qtoj50fFi7Zntkfkj1U1YWPxCsv47Z/dpNvOUVFu/z4r4qvrMSr1jIbh3be/M5m59+X+/za95xPEZ9cnbPT7HR0r7ZCA+w+r20G8D4g+0cgPim7RyA+KbtHID4pu0cgPim7RyA+KbtHID4pu0cgPim7TyEzvnT1fwO3Xz++vywVZsQPwBIJRfoI+yprkMxFvJrMC7l7p/nzMRSLmDmRv0pJX0PMCVIEWP4IjVgaevTnLQs1RW+5jYj8dcC2VTpPIaLZhvquzxrzIwwrxlzBURZoixObVKGZztB/HZlY8RfV0/uC4G2dOcjedVXggGbSD0BVmtwAB7Pu+v40w45k3gLWE8xRdFD+fM+6bIEZhd4cXzIVyLqSqvaIH2R/3UtXOV1siUYdCWMRPFlTIrXhrZVaV0zvaDN6IvWe4CrwVb+YxO2B0AAjkbT3CTR0tOXY+3gDjg7caQOBNuHWfCBdPZHtoCV/F0dXIsufGdKBZ4BSKExKbQ8upR61rPt9cA0bKKjvKzUvQy01wH8WKWA6AGwiUgqvKyYoRjd4UwDjz0LV5fra6Evrufh2T0/F4zf4LzcZrbnAmQDORTOHhwJCwQhzkQaUT4RFUg79cKNsUVmiLsahJNkIN8tmodiQCBF/6lZw7yijHZw8vNNBV7ee13uA4pV+fUWTRcRUPklV9D5lKRjya0AcQIl3OCaZIVI+I++Z/w6jjcfqWuBFV3cCUQ8dpN/AliKtzlTLzBDQruBL2rHV7BkQjsO5Nzr+BTgN1BZfNfdfFPqbzXFWwKDwWF/MI8lDNqtY7B5ctJrAbV+BB7QWeK2CKv3krNJR6+o7zcz6+887vYxeTTiQvVuZwTL7wnxQja96ot4Qf+W+pKzEeEzni6v4LD4ckuMzc8lC6o6genih7s5yX1GHdwOiI8vUofaiCSYMQ9NoVoinQOJXci2DBT6xCrR2nFkM5SzQCEUi0pCgpxNPRGRXRCnBPtkI77MTCVZuBSDRBccu7BmHPijEkxAuo00JYgfgLRKApdiXqNWALiJmfCyyI8WVojcSTM1IRzUwbCrhFzIO6wKVwaEUItEMGGSq2jcxUThduMUQR7nu/rMDWBoxFS20MCIjDvSpkbIApoPgUimB7Egu5UMYKFFZgNJUVDn6PQlbDVTTwJbobuI81NzoQCEYQpgYU7FEBkRTSfgJiNCJ/kr+6wKTw0RTqZdA0QhVqHaZFadarxgTR+CumeDBMM9ZvmqqYmx71GuY9GvchMTTknX+KqGMFCVK9edDlUa6LUldC7bcus4NRpH+yGm5wJYky88e+JB/IEfsPEx0Xwyuskhu8RvG5MJ9nvEmdkEFbHHTbFdZB6sGoGLbJQzqjVOt7UajflZZfOqr0ufTfywtGgftNcp2vOJbV7hU6H/aYQU71i8TY536DFIdPJ7S1j2mJWfA1nYnn7GjbFjCuyor7h3Xoks5yP6ko89ohjTQd8BIh5/T4DiHU277X963K+A4iv2baHfhsQGxCf2IQNiA2IDYgNiA2IDYgNiA2IDYj/D0B8XXd/3PL/xqWwAfE9ymtHFfGNwsE6OL19Rqlw0A7M5lDLy4+EhuVqNetWtinn1udHodnU7mZ5fMxXjI/rnfpWG8IqDK7R4zmqiC+qMw9ToayDZqyVG1s7hfoPsrKGFwdVK5+6/lvGvKlbqNpU5w45akl+/bcBRF2eVx6HrxgfCy3tmsfVaQqvZbujprqNNRBdwdv4TCCy5W7R8m0gDCPCtSKltIFwBgi8dP4IEGV5nwCERhVRzQiNqVLHCzGsg6REgfOtKCJ3o5Ek9lNmgdBb07XlmoPBIu9im2uFWCrJwuFqI6U0cnvNG2vkTslmdMxOCzkcXD1JZJ46MDM+XF1j1KkTnzxeE+ZINehLr2fLOC4uRxUJohlxlJgqdbwQw1e45jgmoR1rRK/55Wgkmf00Zcsh1JZrDkY4Ztue3ZjH5KwlC+oj1zbNcgfkPcbjnagAkE0FolWeKgZ0+DxZxsdh1heoU+dyL3g4rxFs5KpnyzguLkcVGUykh6BAFPFClHXglCLA2kjNWCNYmG5FI0nspyzocESFCss1ByNPLSF44UqkUGKpbtqmRm7uRroYFAh5vV2mplZ5g0Sc6ZKFzPg4zvoCuTIQiPNCbA6iIBzS2TKOi8vBLNw1jwhyis/jhSjrwALhrq1YIxiUt6KRtICA17q0XHMwdMArEGq/rJu2qZGbuvFqgRCaz2t4zUCU5YHR4uVsk/Fhaky5OP9RawogwAUhboqcLeK42ErzQD/IDBZcHS/EsA5SYBnwG5pRRNztaCRmGcvKGsrKMJZrDkYxNUlt/KxuuU3z3J2dmtJRsEpa5XVShvBCjiXjY94XnhU4iKJgpiaa5sDpCOlsEcfF5agi4DgEZm5DNaKMF5JZB6JEIQoTdCc9jyLCtwE3opHoiKDvEdmyC7XlmoOhzRu4Vl7tV3XLbZrlnjiqyeuBNPpotdMF+VUCs81ycHpOicW7ZHzM+4LrxFxArSl4IuB0MGcFZ4s4LvObSg3d4edn1vAV2syH29FI7lsO7vZ220JYrMuyvXvpb9c4uFsckPnZRloFosVgWPO1/j7z4T2Ww91yb1m4n/tzy0P+5Z6Yn13HF1ndXe/ftmdNGxD/kfI2IL5JeRsQ36S8DYhvUt4GxDcpbwPim5S3AfFNytuA+Cbl3S340Qqtkzd5xMK9z/9jwGxAvK9/3r3N2QvBRCuZMTjebuhJGIsnPRtURSN7lktdjZPJGdIvU6W3On0dW8XGVam2h2OcLPeOjW9so7no8TYz5n5vp610msM1k6OV+MqD3zX1JDrjLC8iqafIKxAGccZyDkKfaxbMZ03dzdLXsVVsXJWqRg/HOFnundDsH/W01CySdl/fpES0gagZHHNmR61fsQzEgfvg4FSjQI/oq/H3gSjT17FVbFyVqkYPxzhZC8QsgkvFIlkBRNbhaLEXwOCwPAswOE6s1+Ea+hXs7HDKv1DuA8KAvOUAHBOUK0wclMlpbBTJCSWNzgmzhD5NucRYpkRXKWO55M+ijWFr9FCMk1KlpM0GmfWPRHDJLBLLNXFJVqlhL79n32IvkL/aqm0crk582XiJO7MZZE6mkEge17/lPsCt+NtbIHK0IAEiSGyU9Mb+0Qu7xIu3ccolxsZLdBV8HlRBI33WmBemRo/FODGMlCU2SN0/w1UjuCQWieGamPVpbk85F232At7jtzyLLg3mPCKsfsVvTyoV3pXcB2hTKBApMIiNgyLyVAgdkKKQuE6s1IoZObpK6cbvKkkGW6PHYpxYRsoSG6Tun+C1FYlFUnBN8gI/sxdUh6PJXvAS0KlWnOCqH1v6Fb9FAMEV3AdoU5jgMIbWqUd8gkYUMATqkDqqlKBwabG2Ncif9aX1XKPHYpwUKiULbJB5/3h7czDVXBOdmhr2kg5Hk73gme9gopVId9BwhrO9YjMcX18pp/IvlPsA2ZzfKSaJT/FUhnQkJCJi8BqFxIFdMgOCl9fQpY7PChpupo1havRQjJNCpWSBDTLvn+AqFonhmtRTU2Ev6XA02Qsd8x280Y3wvASyeoV3czbDawikNaH8C+U+nNhmnK0D0iM6ijNxUDhOyYTvEcNVo5A4ZmKAreGd5U9QPZC+VNA4zbQxTI0einFSqJQssEHm/SOtyCwSwzUx3x/a3JRg5q7y1iofX1K/eFSJYk1slMcs3Ptcb8Gt3WqVkjC79bzVPyvsv+fUkvrFf+8RR1hdUv20IDzUrg8B8XhB27OmP1zqBsT7+mcDYgNiA2ID4s92yQbEY583IDYgNiA2IDYg/oaZx7rkVhl/XuTkmxJ4NiD+VJ8tbpYZMdxT2fCG7+AzcwG5Mn8CD1Hos+vjD2+jVHx3npvdv9C5fuzH/YXTXKrzl3O/Oz/Ho8/n0Y3R4t6e7ucWyZZ21a8XtqG2eI9LjHXbX0ap3YeAGOfl7+s2XuYWdvaDZUYEP/dw17Ib3ncGCGEu4EjiT4iiRvwcq9ijr/qYmjqnH7UKferF55EatTvvziNS97uiomN/7vuRzo1jBGKkMzsLxGjx6B1sOSmxtIWcXGIveHFP7hrI7ooj/TIQZ21jBmJn2og2WPu2TvKpUJbwpcpGE4i0b5gLruRPdMlFE6s4amHollyhGojnl+eXsXmJj+5MXUZARBPjubqW+rL72GK0dRcIxrQ1IuZD7D1AlJbGRaD10+QyF8OrykbNPXCIU/LKjiGJFpKZC9C/SPyJIxQ16HMs6hyH/xinlfOvX9Q5Y5wO4k8cqs/x748LTzh5RDg61sfp48fl5UK/9z8LIGLX/eAm8LkLDfmYIpZA9l7E4v6iI4JK3FGay46nB/qbgDi7WB5ZoRpqWXG/R81Qyx9cBh155vKoJCpzf/n1a//zB6fcsZVnaVGsAUpNbaT/aBn+P4tl1Iw+0SifMjNiyCobM+4Bxyk5krwHqALkdtRcx5I/8RqCfqaRMMqsoiOCfuhoPNY/0W+3H3WNoBXgKXbELk5P/8RUT3QoVvefnroHa8STXNdPDE3M9kT4kD1KRRbjvqwRGBEokUdjDyCoRNob2Ur8OWtZnJdrgVo+8TikuvZOLgWa0uLvX79GTvzE9aTzXDLnQA3HXi31/Zj2KCUs77jR/GksmBFG3GHGPQC1hDgHkGqYS0J0OZxH0M87rhwDISPi+YWWS7pe4nX/wk10u1GH+cidRlWjbgWI1Nn/9Ji28oigc2SPbNDhPed4Zov7NHng2kxAxNQAgkrkjmMro3t2Wtbzy+7cO7Kzl5xO6kpHeURQmePzCwPBKSkdnadPvUy+O2kjneejL7pHKbVO0ZITIEpliRKIzD1QIFKkkoY2R45zIvdevEaMAoRZIy6OJopLL51+G4j9GUBgWc1rBDcFRxgIsvcPX3fR4kWBqEaEG/sMBK0PIyw6GhEoKy7bZwBEtQQQqCvuCagkSkl3gXtOGUfAma91BraXC4TLufRSQo9yZC8DgSOxtWe3oCwx4x4wEEcNosSBjCr9C+VPEH5psY69xkD0vZtNTXFS4RMWiH42Ivjoz5+0tyvummTVeEpTE+Dq+15vCOZT0/iUgTi7s5RHNcxl9ZjZtKMwNcWcva5SVG/HUxN3a1xFznENiOc5qxkRqAtaRG3Vvb5PQHAPMBALyhIz7gHHKXlFgDQOjvY607/QzxMUNfA94szL6e6i3yOwWPOCGo/HylwsELxwxso+x2vpHFcFSs0LKDXf7c/PZxrgcQK5pHM/o5WRFs9d/LZBuXeX/cXe1+iSiIX9mfcUiP0F9RltWWyBPj3zXzq24zZIebxU82JNtxX0TSReG3SeUigQz9pGttRzPt3bieWdQ72fL7v5rdgjHIT1fIr5p/pWEF+75pu9/94t5B6b38d+vTz6zXrs17adUsYR0euN6Xu+EK6u1uO5vuIRR+sb6SzN+fFWtc6tKSunpBHx/wiIr2rV9tDvzzVqA2IDYgNiA2IDYgNiA2IDYgNiA2ID4mvrvG2N7v2crt4A+68CoY/d5NGasi+KB2HPF3suOff5WD4X93qlCeQU/Nlaqx+xLTxyy3b2s3P7xrFHtrGy1YN5Iud+/ZLwCnmryRWLIrusN3LtJoq9TQomt5VdB7S/dq9rt/QCRG/4FDi3awAxJjbAzpVA9BUQfVHCrglE6g1jZzdLtps9kS3R3Jm6t85b9saOf5hU4JR3UophuESf6JpA5BghnkN80PvD5JVJryoXKfXt007t1eSREoinvkEKaY6Ih4EYq24Z2x32ESDufR4rWwzEWS/PBhBhJnHTHB4AAu9j//oV3JJWie51wlAQTgF5m4jnMI4/2PnBHIReU+zFycHnmPOwk6PMePgp/Iyf6vBAQWAtgNkAl8oP4TYQv4POwNaeP78IawLsjpfoVFU7YGCoU4nsRa/YqECgHvHcC1kchahG9eS6/0z8ifK8sDeMrTP52TPvhN1erxK1hdVA6LVhjTkz8Oc31gzJkWMcvc78RjofGYiYws9ixZANesHXQT7DcAoSdyF686IDkt1+48/sY4Uf64kdjk/iXnQ9co1PdM6x+xMuQHQg+A1PMlrIqvAshMnRC1cDjsl/mMMxCrvjH/JGp7VKXZfI7aQGOx2pQrghi6PkovNwzT8lF2pxXtgbxtaZSAWZd0IzUTg6ZrMEeXnfM8nu6KE5AAUBxElBnAwOQBNO09GzcAyxva5HE5BBI69AUIOnJhotllPAXf2yg1+2B2+BvapMPCH+xcisBElLQDAPgZkQ/Q9Kkc7u02S2T8wGOgvmxjNzHvY8E8PWnv2//whrYkxAZKok1ez5Rd3vTmogQETbe2ZZsAt/fH4pgQCA9fm9sDeMLR4RmXfCcVD8wGwWaIIMLgW5CYNIvUC3JCQgSIWE5rAj0SgiECTDAo0OG3lFxWI6R1ohJafg6Ulc9E/q6E6sCubEXYT3IPyKnbIg8B+MDR4vzNWQEYFrGOSyUZlHWDcuCkT0sZFtHhEx0yWPCLVD51ELAMEXhAGCShwF4FF8p1RDsr8/a2vK8zEHj4hsC2tE5p1osB8eEQ7KJQpEnGquqqnhWONDgYhpQlAZLZqakjKXjbySgeD1w3IKaC7F1ESsBPAWwIvQqcl29QgAhZ0Q/4Lf8ERrB6YmcmGC3yBTwRP9/LiA7XDmKUYuA+K3MhC0RtBaRWXq1MQ0lzw19eWIkLNPMjX13NFKjeGpb0xTWnWeLaBEA8SYeSccByX+HK4IezVBtChRiiYHTQ3HGh+IHIOpKQiEAEJpqTbyimqUdKwRUnAK6AaFl8SfI7MjlIOAFLxYg/fwE5yHnSy/vExjsY656BsFFus9Jg3icPSyeBLnwoHtcGZ2BDE2sMyfmfU9YhGlNOdzj2V1L8sxaoHcPOkxJ0POMrOCmORgTODo80VbB8ZFfZ5XPWML3yMy74SX6vgTu/HKah0cYSYxWa6Tg6YG01QdIsdQyDcoBnLgs4mtiEaHjbxy4rBorFXymjQP04LYupNc+jLU3zvedquPd/PgNzORxvu1GRePjv1yTceF/O1v1qFRQvDl2eBEbapKrFbW82Ocvi2wDoglzkN5fB0QOU/Jzl7iZ6xtz+2afgwIq3Np07BE3oLFbVu9bQ/9NiC2bQNiA2LbNiA2ILZtA2IDYtv+s0C8J9t7K/yn8321rU8taQPiLwGR4y47kXXwgVgHeDN0uJHz37dcBEdaCfdyVM8YJd+dkqR2rGRc5MPbfe18p0lzSZmFo3luq1GHFBz9VguWjhlrgSJ2I+YKena4NsvqclNV6GTyyUdug3Z41xV/O9OhWez9Vo6QSzL5glvOlw/iCb7N56t89jc9AYWGuZRZuu5ntuatVb5G8Lk+8xYsHTOfCYRJZNynzOeoyzJAONHXIDdfcBoHwXZP+bdLf8FT6O7mKK8uzRfczXy+qOuNfAUQKVfw8xExtzVvrQJxtPojzWDhSwHESyByz4LP0QCCBMI5yocTfY2JWQcT9DSEcYAoJI6cHuAdQOmdVTmEp6AKHMs5kP6NP+V8quTRzHfV2rEMe5EvuDLfSbRDSDWElUNYeJ3cMMy4YN7Fkq2ytao7wha91h9OHdsCkQKojh0kHkvHbeA3zyeJucI9q5FfyrLIYXdUBKGv4QOxDqDKkSIieHnVPThxFCIayJFfdgdPIYR7OU5XBC/o5CV55Dv65XwIEKBrWZnvUNSQf7Mbk1RD4qzMqSm0DtfyCN7Fki1MHskW645I+a/mJf+qBWqtPKYhETqJLeElgoz27HBtlQUJBwXCY20/epf0NYi7QHFJRPwhDG9aLfymawI8BVXgWM4RUoCbweV8t0qC5gdGL3EdbL5jmY9TeIlxQsoJOBPYhtQ2LNnSiQq2IHch5avaAseeqVvAU1N1zCMlA4FYMhy4J/Vs8K2ypPvJQAYimO4JGi+Iu8dP+fqgEXRkfy14CqjYrRy5yu6a890qKaTaeYmHkvOFIh9HN0HIj3DUUQU9kXTZsB5C05YCIXVgC1q+2goSI8a2ANFRymO4ceGxwMGx8mLt3LzeWlY1NdFMplyDNIA4FgnoVZ7UmNKwpiAW1DzwFFy4lyNXGZFKhN9wo6Q8NXmJh7KYj2SNOI4T1ggvg1/YFMjrlmwpA1VskYVjjruS6l+1oB4RwWtYK9ljBSwAsdizUhZR/l51roO+hpOFCZFBBolFMjDfoONoJByXxLMgEKUF2+EqChw3cgReJid/kkglyHerpBRrhHK+3szH0U0oOgpxLujO/cS8C46/6ClvSNEU57YQJybXgaKu5LgrqD8v1kULMhCmVZOok0jgN/0esdyzKKu+FXtIlQPXWHgPT+FL84XF+q61Fdx7t+5urVeW9chXfo31+d0ecYTF+q61Fdznb0u1/gQgPpLnb+T7alufWtIGxAbEX+m8DQi3AbEB8UW2NiA2IDYgNiA2IDYgvkVJHzP3/tw55xqpk0fK+YwO+oiNP0i32YBYmbfJVPBL2Ra5CHhq4nN+yxChZ5DgTJBCxVLekOvQzul0r82FyEAwz6MoR2z7OZcELcKjOE1ds0OWtTS6Sctr9YmmqI5cax7JMlNhQbLgBhdBOzO567vSPz6BM+Glv5t5M0OkmXNwuleX31VAwGdp04htP+eSUIucH5xN3dX187Y3ir4JWl6rT5y0t8pT8UjEPdZkKrTkPm5zEe4CkfgXy3lTOe2cB3fDBnugtXEBsV0KIFwBRNkiFw4FK6SrOiE0L0v0V9csL6cOvs5T80gcgr3XTIU574H0J4iTYLgIx5p7AZUJFnOXvx27edQ9CSYDOnExrxuE+9DOCU8Xuy1rG8JBMUBMZTmqoDHnknTs0uwKVgh5oJUZwgwUp3uZlaIsDtQpjtu6TqLiEXxmprR5JJS3wVSY8x7gggT2wkV4LTkUTlQmwpHyOw5x0LHjs7yuD0yrWcobnHIf2jnBD6I9F0obykFRIIgiU5ZzhILGcc4loRaBe5RTd+pqhXYGv96OvcxKsSOCLLiaxxJEsyAxUzLzo+SRMBBzpkKL9+CZk7DE8gjMvkCklQNZSRaGaqY/cnOW8gIIWjjbObFY895kbQyG+uAkTeeqcvwSlwQglUyOjscEeCTMBnnTvcxKyVM5yqvq9EYtgYqHMlOU+VHzSDrnWkyFFu+BaSpukeUhkgj8f7IOe2cmGHAmQs1jsHnB33BLOQFE8BpyJ3M4aiCCAUL5IUtcEpwrmRz8+Sq9g3kj7WUgMDVpeWWdqPeCjKrETHGuySPpMh3KMhUavAcPvlDmIlScDZ6KkE9irxxp8ionmMSZWM4rRJqlnJiasrZFtqEclM5pGprxbBqMESqj5pI46VybWqYm7R2ndaQ9X7A4iOGI8qo6HeUST/3LrA5dwAseCUdanDMV5rwH0p+gpcdwEaaSQ0FnEWlF4q280h07llz9NqCciW4x7+kN3IelnCde3LK2RbahHBSqF9LEri3KkWXzdc4lcQ6RYmzq0xV7qBlar3vKStFvCagdE8tsnV5x69Ol/u3cEo9kURqwdfeMm7j1LI/1nIn7m825bCO4PCLWlvMYb+V+7W73wO3yb2zz75Prv8yv50ys2f6LjzhuK1t+sPztWdNn29iA+JQWbUBsQGxAbEBsQGxAbEBsQGxAbEBsQPzpwr+T/svnE2v+EFVnA+JTLVYqFIWztX5Wwk/F2WEDh3lDgWM5uELFXNC//Cz2qufLLefnx2fZu6Xngkbj9iHbsfV4jJ9C7kvDuFitxpGVX209k0Xer2Oz2JQhSywkh3f65OTV8zI8hUjsG+ZCpcCRuB+GN6FHCuaC/mUdba/nkbMrmteZavtUbT43pfj0U7ajxT/OT2Ed+7DKRvM9uFDUUy0ORccrs6LRom4GRB4ANRAuAaHsg24hv5+NiJK5kBuvnjc/65r5iFgCAs5dE7XklpLGIj+F3LwrbdwZERmIgzvMLqUaCHi/S82NVzgrlFNxgjPmmqcw8rvRZ2UfVAocr4NLTIcUecQ1mAslEGTDQ5fCcCRQi8GJioeoY4CFcWC1C3KiOvAw2MNHdm4padzmp2T38GNqHMJBuZJvMucbrrAIdgj1eD5zKlpEJbhScwMOwQ4O1CN7jrw3V0EnLj7nlH1QKnDgLL93LnodSwoYeRYNok5BciZJM4A5EszsCGzDZ3UMsDCgAkJADA5rRBBmyS0ljdv8FBYy8fdszNU4hINC3npTz+B1jehk0ICkIQ5XX5bgKjaGJx5HJ+wFSgZFCgOE7+SzMCVCmb/j2CLDmxcS2JICRjkiZLgGdbPjGDM7QvKlqzqGvNvPJEkZEeJHx6R1Q0njNj8lEw4eVePgmrqTs/UcnI4I3ia0x7bAluDmShiOpW14vkNkHZ4Bk9IGVTZ1YudqBY6OY4uo+MKyAsY6IEgKqEuRecSqNsOsESUQy0oat/kpFojH1DiYcuFkREg+d50Doeog3hUtYjLGTAkj6UkcRd/Ct6amxD6oFDig4qQ6FssKGIZtEXSxxnWYORJHYWvQJ6OOkZpRAkF9gWllWUnjNj+FW37XRkONQ1Jhjcj5FIh0x3XMnI4yZWDdiKlmHpyuGvaLlC26a74/R/QPXqyVfVApcJzAAxEdixsKGIltQff/WKzBAMkciUNa2GBTrPKyf2D1D/0ewVocE5glt5Q0bvNTWD/jro25GodwUKp60mJNFsEO4dUMParskKIE917uQrjJpig+Ndkca9kWWQNmeat5GGFN/f3t9qyxsXwjW9aru5vyQ9vyF/iyiFtsjvsPAbIGzPqarGniPX7Ke7sprOqhj5TwABDr827PmjYg/kC3bUB8k27bgPgm3bYB8U26bQPim3TbBsQ36bYNiG/SbRsQ36TbvhyIPyck8vmg/ffavwHx19pfPAcLLsXY4E0jlDt+2jmY98Foq/QnfHqSEowzvkrhytKKvy4JOODZKpo/JL2L29YqV3suJMzP+1m5VV7vZ30Ej2CuC/NPGu30oV0/K37ASTxrj6Rng1PJwIDGu25ZEqETdoLlM3RLQEwlEHWYjDkQXQVERTSonprOQpHI4W5WgrPtMedrqYcyb1dwPmxslFyXDlhNfiUQ+rarBUKdWquB6FyT7/CJQLi7QDTIMAsjYhkIVwHRLeedAZFYI6kuIGF8EIjMTxBXfGJgMP/gehAFCjoX3YLUlElf0SaHBzE1wOLgoPTMvsDfEODMJ84DH2VdipIh4dwhKVywgyUMciTJlheMD41HMiRVDIkEc1U+hfI0MmMizm6mPfX53K7GObadz524j0S9w6seySCACjODa6LhoyS6CpMDsjaHSz2d9Utc5id04lfNDAw4QD0UKCYFcBC+AxyTOR5KoC05XI/8GYye3xxNBboUJUOC8isngxeUiRgWRxOuYCgYHxqPRL3Y6IL8cnzgAB/sDE1cCud+81G0pz6f29U4h6AOk5MX13kal9gog9EjgYhKcuAWC4zqkjijzeFST2f9Epf5CQKEywwMcDNAIJAKmxEBcmIogMhckFAAwVdECuaS+QtOJRI8ohydnMZpSQ0qRoSuc/A+67WYdTtY10PpAcKlICDoKAMxO5/b1TgH6Catu5c+qmUwvFMggs+MF0xDqktitTlMeUm/xGV+AtaIkMJf0JwanE/qEzTk8hqhyhN5RJDHOHNBCIhhAvK/oeRyNSNCmQ5O1Vt4rrymEWFuBZaBcFcFQnU7QhrdmUtBQDBPittTn8/tauR1ynOiCCne1bFRLBC0RmiEmTw15UAiVptDaKSFfonL/AQsRMErs4Ar7i0Q9q6pk0YchEIlhBIQT3RqcgoErRE0g9bxSih/HtKgk0FIiKoODqFlfCitMiR2RT01MQ+Fp5fMJIlAHHmVm+bnc7ta58BaUWi8L2OjKINFgPCIMFOOCNUlsdocyue1+iUu8xMI5IEYFcIsoH4lnoZ3+J3W+DdhJ7DyBNMyJ7WB2CRYlHgJpTXlilsn4i3U8Uo0HklarGkt4SgoVPVBS0uMD41HMiR2BZglmU/BTJBXPiZcimGaWIED7anP53Y18lK7XqVXSNsDfTTTIxEO8RURZkogVJfEanMA+FK/pLrhWsfosOyEkHIFo2mXls7itrRxk9r4HhSqdI/ra7TaFNzjW9fslRuxUfxSKcH/+7ZOm+OhzX7Fz0UP1/pbb/78PiDK0j72YCF8UfvL9i6VIvqXV/e52/as6f9lRTYgNiC+Rfs3IL5J+zcgvkn7NyC+Sfs3IL5J+zcgvkn7NyC+Sfv/h6r9aA3K9I9cCN8aog2I9Vsd/UR3go0FEjjlPF7KUKYorILzMKQoKg/EUblRhzr9yhrcbL/1KyM9ngydCg8hnvemPGZDXeC7I4bHUlH/vt0BwnIh8iup9nGidMIsTEemHNhu6DRN0ulOxxtAzOOo3KxDlX5dDYai38v2l6wPUfrGx0olwc9qCosa0QUaCJYl0RV/u9kVcBMI2Sb74PYxIDRNV7Ev2kC4BhA36lClX1eDg+sWgXAFhaaocS1XkSRj5kBkVRAX6rK8czeA6MTBYaKfgO8AZoe+/n07Xgq4HuRQIT9cnlr4rOrcO2VfdPK4/FYclbt1qNKvqwE0McD9IC/h4dpmfWh6jY9igDjiFXxhd7Bz9iCvMXcS0SWOCPIXTuq+0kgqqjCC99CVdaLMj5i6jn6S+RvmPfyb8VKgnEEaPUdvJwZUCBoXGkUl+KwqsBxH5V4d6vTraiDhm+CPjr+Ovs360PRyVV/NGvEKO8Lu4I25JME7jegS1wiGXwNLIYBHjsLSFVwPdRN3bhb9ZHDKd0BcE0wIt+KldFC4CL7wQMnZCUNaiz4lNY5bcVTu1aFOv64GOldzfBRJ22Z9SPpJJyoFApeC2pbJkjRBJm8juiRP+JAiqeQoLF3B9TDMjzr6CXEtOmV2TIYzsRgvpZPwTfNucNccAUUtqYbFrTgqd+tQpV9Xgy6tIxaIFuvDLst2jXA2GkyKpxLrsQCEiaTiDRCJ6wFZDHxyZfQTzGA6Laga0614KZo28KDHrCq8Dj5bRlGxU9NSHJUVdajSr6uBRpZjJQwFosH60PSyLBvdEBcU0Dw1oW0+RXRxHAYN90jQ3uC6pigstJZkrocyP2Kty+gnxFcIEk2EOBgULeR2vBQwOMCokImFORc4610ZRSXTIJfjqNyvQ51+XQ1OqvjBCiMAosn6cEXMFqsbMimL5JQooay/4bsU0YVLZy6Lam9gIVeFkc5ZrocyP/K3JsPsDvMbzMZWa9tlgTerx/KeKCrr6/A1NajTP6Ab4tZEZym5HviUjlh+QVhV3WXGRr2952t/eDzLJ9bgax9xlFyPZebHp2/bs6Zvsm1AbEBsQGxAbEBsQGxAbEBsQGxAfLe2bkB8tK0fq+Tf6aCvhPZx22tz3Kn9BsS3AWJImr75JVnZ9MHe1cZCGa7zd4NubKH8VL+LN1wtS6PI4sszg/GV0cvFeMEdR6Jz5qr5Bq25RmAhK/60VGNvYrn4bLt+2+lejpJtols7igxKEOeQZSzYt998A4gyFkpOXyVLn4onj2X1pvrt1ODnIhHiCZidMU5LiTKSyRK53p2SCrypgW9HQkEq7zvTrbCdw82EdTmuPsz7ox1FRmrvm0B0t4BwNhZKFbukAYS7C0R305aOiBru3BRSAqFk+W3J4GwonGUgWiPC6m6o7RzlJazK0YXg5yyRdhQZqX3oKiCOIXm2oG7BzISwFAsFPq2ZIkbS1MgRUfDufo5D4uTNfaPpcSRrtS2NxKJRR7QWdnBDESA1eQpS5gD+x6tV8+BXihuRUFQVhJxHEr1lUttoITtzQm7Ncg4fgp+zRNpRZKT2kzqPuEbgJgxFXBVEMjkmPYwyFgoaWStiyJ53JiKKXJ8+JLWNzlWaHq8g5pS2JBILRP5DZjyUTdH3ldHZh2sQXoY6SbX2/NL9sRkJJaAU8qEdxQ+vttFC7zROyr0cQcdQwRJpR5EBEOAeqgO4comrlgYM5y4oYqHkkBlGEQNsBERgsY2N+SgOiYg8dJWmh2uqa2SuAzVpcG0g7BTB3SIOffiwrZpHCqFRR0IJWkrOkWxrcBF/ctnWcg69YEqWSDuKjAhLCE0IcVpqboKrgWjEQqmAgCIGX89JLiLnZRbGFdQsXSOypodrqmuEJEvBvt+lqakAQoWsQhakWADCREIJGpoj55gDAd7KvRwKVskSaUeRKYEIOF9xE1gp4qhAHPVatLFQUEqtiAEtJUrpi+HvmPlGExAfqe6a0P+1LdCwJDSSs1OTeo8p8onGh+uSMkyopibxXU/QwWhEQglaigB/xIzvUwt9NTcs59B2lCyRdhSZzuVYNmZqKrgJzHZO5MrXNDWVsVBEhcIqYiBeiTd8Bb2f4eXWS9SQ+ntEtNPNbB0QRYWjXdm4JZlPcZI4jKgJMZoGKVNimLxiIWU2BxbrViQUbiPV+iT8EGrfSWK88O2Lxknx93Iw22SqWSLtKDKUXmPZmMXa5Zu+u9v6OCrVuebN45qyQ0GXL/kU+q1hKf+tc/fa93iP3GlHo/ZdqzPWbmvjqJRb+5v4Os7DPP32rMltz5o2IDYgPlrRDYgNiD9Qpw2IDYi/1+gNiA9VdANiA+IP1GkD4n8NiL+3fUcO0H9U7mQD4ks33+QjBPmLJ5hrzCD16ZrUJ2y0jADdCmFjhHymLjs9Kb1T2kK6YP40dEQszwKqHZZhEdT2vBvqhvIJm77Vh8UTN1/EXOequJJ5AWeaL2KN+BTrJPjJly/R3gKioAYYpgiAoNcU2ctyzUlq5oZlX/gbpS2kmywQc/kKy7PAi8DC4bC9bskN07yRRl3cpC/7UPuuyDo1An1YpQh1ubgKCGmSvx5XSSsnv1tXF5KAOL2Bz9AZ5YqZyLmt2TL8vp1uBRCuBEI4HPaVSqsisghEnX7eh9VwqoEAY0KZFxwUnl9ZNRoSVxrKB05B5141Pog4PIakaoHBZ6OIKBBQvOAzTmKK8IiAGx1vUkMNA8yNEN4khkmQiCzyOq+wRdSV9HZ9EzWNdrrujo6I5VlAowA1Qk8IL+W1S32jqh8qMc2CGJPyUmz6qg85H+r4llIVfeWZMZGVInRCyRoSwPYoqhjkbuQANT6/s3/06XrzZRSRAeFg4NE+QnVCYorIGsHUFThLA8R5mLkREPMBrtLfomGhtcy8j9/+t6hpLKW7rSNieRYWCPTEMSt1eK/ML8MsEfmjSS93mz40dDhQx98pVdFX3nWFw58rV2hIZPrA4CQ+Ci+KxD4YUr6BVSyGtzKKiGorQTxHgVMgNFAGs8Mc4rGAA0FAIPpIkIgsYJiI/9fptEfNQlntdN0dHZGCZzHNHfuaGuwWcFIys4R7aTIxWUz6U0OHo6wxJtHUV97lEWHCYRgNieAyG0EWa0pEzIOruxq1mavOjDmKiAIREm+pBQTuURCPBcwNHhEulCMixUPC4q7NEojb6abbOiKWZyGBzUqGhV48Os9PmVmiQJiYLCZ9S4ejrDEIcqmvKBFFOunMHQ7YFKohEWS60akJQNgrPEiAJ8cKFUUUEQWCC4NYEJgaYL6BzyCcEExL6PzwWzgdmICgc5Sjv9ipCYyNdroUQ6WpIwJnv04lUO0oGBZZqUNjylCPOFWf4gBQoRmTxZd92KX+yjUWILSvmI/glHmRF+usIcFUSRaHwnKs8VHwo4wNkbx6raKIyJU2gJUhyxvu3QkI8Blc0MW3uwpz43USjQs6SiWCYaKqG5p+8hwtxYMLMU+HGCqLOiLO8iyg2mEZFsEnpQ5R1yBOChgj0AdBfdP3CJO+7MNUb1NjcHdzXxW3VY9GK7m1zW9yQ7FfcjGK+Cs3c96qZ3ioZmGW+xYjo4wUs66kB/vqc43qNmdulOXUjxNy+ns5bzTonTVbqtOj+T+vr/7gtj1r2hr9n6rTBsQGxFanDYgNiK1OW6O/eZ02IDYgtjo9WEV7bIks8rVNu239ftlLtf3GgGxAfMa28lneUhRgy2+ACsVpxnkolSYGE48EXI385hpbaJY0jzbScK/LcT7wJq9DTS3OhDm70F56Kw8ppG5vthX8ovBk62wrXUZxof/8HBl1bfr0A/2blAVT8Fvq7m4Boe5x5Teog8Qec75WmkhOpkm5GvkVYjYxwfataCPLQFBN9QVh8hL60NLByGeHqj35t6bQutlWEC0GdrXOwVATyuAhcEYmfQ7yQ8xaE8SLN6k2uu+ca2F2DwjLbyAgukJVolSaSE6mSbkaoQhrr0CUnfceIA7uUJB2SiBw9mDJQgZ6X+UvW+HCwZV1DsZCCYQK0OcR4VsjYsosGKVVeDtAEaBCaWNtnkLSqHBgMyBSSVaVKF/nVv9Xl7ga7IeaaEgD2nvRRpTkZTkhRU0nl5TsVUuk1MHIZxFLZRBeiPye8pvb5DEexF5uheN62zonxst1FsWFu9hNUsfXwWUmCdULeh6A67Xgt5yE04HLLoAxoSC3eAqZaII4I4hUokDUShOsE8/plKvBavTcnNNVFTpuRxvRymROSFHTCV6+HHml1sHIZzuX1T4QwySPCAGCR9jg5kDYOh+Fg9KI4hIUCK7rsXOZScICAkE5MsqCUX6Ll/52HPcjgDEhI6LJU1C3ukYUsccwdVkgnLezrhVV6HRE3I02ouM8c0KKmlYjQtNm+QU7ItAWUFxyWzMQsigXI6JLcVO0zkp9aERxySNCGBqWcULphuQHBwtGaRVe+ptPDVNwGYg2T0E7XRdhe2wZCDe1gWCn/s1oIzo1WU6IranO6SUQVgejc20gclszEDne1jIQbkoclGsdxSWvEboaWsYJjQgnU3xiwSQgpL+hU6EqGOwyb/AUan4DAZGP+dRoVZpQ4SmXuBoqFJUadTfaSFoMMyfE1NQC4Zs6GPlsnpqUF+K9nZq83IJUrZC8MyB8HcXF3jWxAhVNTYZxQmuEEmgMC0aDTx2FWAoGhHIr6POcp1DzG+h7RD7mncQbyToZk6ZTrgbO0j4Wn/vRRhQIwwkxNdXvEaS80U0tHYx89nTNah+d/p7wPUJScPQUVQdBK7zUO9eZmCzCLCmiuNjvEbxUxyXcMk6CA5OEVaoSC0bAv6K/+UuU4U+k6WmZc9E1jy0pTdRcjdtbWPpOGc+UNXWV9Zbt+5yMeW1v6mXMWrKGjt2toDSInTmHYH7kzzziWI4vorfTj1j/+kcc69gX4ZPs/EEgHt22h34bEBsQGxAbEBsQGxAbEBsQ763VBsQGxAbEe87+R4H4jI75s1Y+19LfLeOBrduA+JStesg35e59C6309IqmZo1PrE4xC3gd9DAYQuli4erUdHpn1RrK+hjpz1u2Yp7BrMidS8xRTGDn9PbeXlks0wCBMrQD2yyVFawPn4DIzmztZHJ42uNkAX4GCwT8deIqmsB/GATIzNlQl7pqeheN9GWAD7USCpWKe7klYRHFBHZcMwJMW9ujs1oVy2XOy7jWLbb277E+CiD0U35we0j7dZwUn1g+GYhO9DWI/3BwNWdDm3UsOA6hCPCiQKiVUsnjXm5nWuCc8jjIjgtdE4ibA+F2mamDtYwuLLFU5kDMWR8a/P7VqHJcyQHI3ITYnaxLkbgLTtQ0MEYOOkhB4QKvY+qEbGP5DxqJhDkLXnkbKszO5ziGSvJEixWwK1bnbsR/ETtTI2qLsYOc5LSh9rHExY0ybWyWXIYoimTGR2H/HusDb/ezRzhzFDpmLDDXIE4RlrsAF+hRuA1HVUCCh5u5HBgfKo+u/AeJz4KyXs27+OzzgjIFe3YncCnUirwKvza3zuEmionU5jqP2mLt6OU6CTnsdpk2NksuI4SS8VHav8f6cNC/0MgLylHg8BtkNmSXOR8P+NSZNHlEqKxDVqlP/Af22ULZI8VfcIglckrqGABC/dwgQ6LQlbllpNsoJl2OwjWLAJPtyIr4RjoZCsRymWVslkQ0CEWLK/v3WB8w6ywQfHUrCTF0s+MaaMkFs2ylxboFBOnPHH3mUGgVA2tghESlGabMt9MAHU6vzhW5W/Ff5kBo1BZrR+KliKyKv1NmGZtFy8CdmWGpFPbvsT6ElQCySuYoKB3mNHXlcQuEr4FI+houT00KxIHC2xy9zyoVWcwk6Vc4CwSagalpXe60HBZRTHyi1JQRYArNDgB+fH0FA+N2mTY2Sy6jYqn4UjvkHusDvIcrBEwyRyETxOL3CHMcBMkg92A56MwJU4JwNoj/cLqWnA1mMrx2RqVClj7R6UCEEv0ekay8QVJrXe40NZkoJrAzXOuoLaUdmZpeY/uYgXG7TBubJZcBRZHM+LB57rM+mrdvyxFKCmb6bAs3OBs3M1Y3hnMrj+Ru1+dxlZGwMtWaMh5hfazaoF6zvL0v3kqyfl2y8kjudfX5LCAeK+OPaW5sz5q+ybYBsQHx1zppA+KbdNIGxDfppA2Ib9JJGxDfpJM2IP6opb9bxgbENynjD1W9/HyrYX+60X+9Lp+p/zq3uwGxagvLmhHzwAz8fHbZ1BLXw3Ir+D27Pv7wNkoDd+e5uf0LnevHfny+zM7Vny+Lteqrv007VIp29q8Xe2bPe6iL2BgL8yN+nHs2bdAaj+6steuLOq3VjFAgfAWEvNhe2gn3uB7C0RBTsUkjqkV4/PpFjei5cbtUX/r9PFLjd+fdeUyN2KW/u6JtY29buVsAIp/pCzsoxUlddo2SUBfX7yjn2VrpR8pLuccx5xt7nAUQvSt+AQi3AESpGVECUfI8qsFihs0S10M4Gi69AnzGVUUdg8bnjqyBeH55fhlnV/OuusjHRs+3gHAzIOQKjqWsAYL/nV0BBOWl3LaWGYixBcS4WjPCshoaPI+CsbCC68GfNErJr1+xaef9ZaQp5/zrFxqxv8SfOIif498fFxradkTsLy8XyrF3Py77n9Q9OS39H53u8VH+5HDsJ12r9BdncIRyqh3KoyOC6hKP0RGeUuivAkE59jEn8vzg+nP6NCKQgkqmGqN2vaP/fIbbxTU7r9aMKFgNM55HxYi4y/UAEBLB5Rqvu9i4OK3SZTPqiKAfOkqX0hP9dvsxrxFj/w/tjDv31I8jrlNKO8a08W80oXuuh/UnvlzjsSfqIv7LZ5CfSlE7nE/WCIwI1IWv6x5AUF3i0acdj2LK84T6p1WC1gitIa8RUjv6zKU9oV1Ux51brRlhWQ1znkfFiLjL9bAufYyIXoGQEfH8QosiXWvx6nlhONxu1DuVH/G8AjGmDqS0NG09v0RrL7q3fxGYe8eWGO2R/qYzDEQ8lwB9ftE7I4yIBERMBSCoLlSCAsF9X82YcYS8oIbI2dPE1LsztYZqgnZRHXu3WjPCshrmPI+SsXCf62GBwBoxChBmjbg4mg4uDFEFxBjTExD9mZq5P8vMfUFTR8Ca9jIQGGcyIno9Q/l7Y2fsx3SLWo0IN/YZCHzCYj3KiFAIsS7E7j8rEDxeaX/EyKUfHhFUtlutGVGyGmqeRxXt5C7Xw3IrcNd0BhB972ZTUxzEfMICMWJqAhCjS1OT3DvGpj3lvb5PQNDRJ6wRcV/P0HRCpSQ7emnPpyaajBIQmJp6AEFrRN+XI4JsJyCeUDun9Ys/cbXgT2fn1mpGWFbDnOdRMhbucz0stwLfI868fO0u+j0CizUtZbt4PHbDpQAinj33tHDSakF35c+alj/Hof8z7+34HE9N0RItyfEvpeAzyL/jxRN2cARA4D4JdeHF+ucz7+1ksY5L9cXxmjVySRaI5zPyydT0E7UjIHip/km1oGN9vu0qb0kXvp0VaZe3R7gerW/at7/N/nqZHx179/A2NvLXdn69PPLNemyX06+txUJXP3rWbo9yPT76iOPGt+hVXaD553Y+DsTtuo3ur27bs6Zvsm1AbEB8sKZ/sy4bEN+kLhsQ36QuGxDfpC4bEN+kLhsQ36QuGxDfpC5f3Ly/Q8B5JP1HavjNwdqAuL8tPqIiL+wuOhCfz2f6dI4uD0fPLONRPo89Opf8Uy+wV/IX6Dkwszbk2K9f7Fy1Lu/a/b34utNAGsjkpqUH69dO3oUbmvlCEa+F0p/e8PLwkFIgV0Nr44oI7lZRQ7d5LJdKC4TeA1yulzfvELHLpQlE6i32IpIDI3YwAzGOyQne7zVt3KNzyWMrhyv+wkiuHz1JoPhUuayMkmUcXFtHI3AMAw+1cvJoeOeTpLqas8E9guvMM2Mu1Wu8lJzClf4Tk3Zwhe1kmWyUTJhSC8Q74zAwzVT5B7x+72d9P7aHB4AQR5+D72lE8vGHZox7o4wddv/PgBgzEGec3LWACLOLuTk8yJ2IF3wJiJBoDl1lruhm6U5Kr0LyGQhXAFGmPbiuCUSYRU8ptUDm5ZQGghMgyHHxQ7gM8ZHtmdgRynegSeUlOixjmjgRETOCgCAWggGCOT08UZ3JbfjjkkeEMCYK/oJjrzS5WpSz4U2kFPpN5DZSrIC+xsCf31jBQqOpvF2JJ3J6EyCOCYgjWCFQ2yCFC9XeADdliDn5CKcnb7pNryXOtTaCRAcwtlONg8+RYVpaIJTX+apewnLhSDHsIIvHR6Y5gMsA1+Q/0ZNKXiUwJ/6Bj3V8Pj+RM5DdguTvfeaRQUQQTGvYY4ZC4jCAMVHyFwBEbzgbPHiPTqKdeNE58L4TVknHRIaj6G7Q9fMbYVN4REBK5devA0uO4MrDcMdr70fvJIoKTU2/xalL6SFukdNDcyQc51obhyvURXLaHNsl+euTb77UAqG8+iq81ksiTPCr+vxuOR3f80wNLsOeXej/gO8AIgsDsccVTwC9xEnljJ4mIJ56ZcbJnuHgjeonLvgLOiIyZ8OzHsXwhmgnHATBeSU1hEHe8+eIKtIUAoJ0MIJ0NAFxxJ6D6gVEHjrOwRFLROrlt8c5Sp/DdOT0pbKAam0cfZa0QNoc2+WUIsOoOFepBcJ5p7Ic4rp0TjRQPGKqMPMhcRl48vkHDKBLHhExDTNOuGPPbsxAKKcBxJIdreINICx/wTmsEZmz4YV0wNcX9IyuCgRFdgkyIqLJax4RMU0QbQ2sEdjDlee0YymH6mnIiJAIesEAkdOXQKjWRjBAaFqN7WIiw7iWFohqe9i81MJONVAwDzhmPsiIiP/PDASYacQw2KWpaVQqypkBGRWIXiiI2HN9BcRTzV8QIMbM2fCiR3G4IljThDguGBHEJuFuoTWCJiKaWNLUJOFTEhB5CvA6NRH3xCc9DJ6amEeCMFY2PcYIRW2ptTYw+ZS2NbaLMlj8lEkSVgsEl0GVV6RXEJ2MY6p4R8yHXrgQ+wtxKc5ML4mLKTEMzmeasi48wTAH4ZmBoO8RdGe057zEB8KeBYJGCS/WBX/BOXyPyJwNkY6KyxZ9EyAgiBNCLA/mllynklESl0Ci1A5XfI9gnYuJrVw1ZssgahonqHWIngYpKU2s9zFwqRQ9yaaXpfd1rrUxgHNS2Nb4LMpgyfqDpRYI532b5yUeC5Z8iqnSXe2da1/ew4Llo5zmW9vOPba1v1mHRso61kuQ28CaJ6JW5uySptUb6demXaOq8Ug5Zst8g9H8jsfP7pO39UDk752hSFPzRB7VAPn4I451qhrbs6ZPTL899NuA2ID4iO3PyrsB8UHbn5V3A+KDtj8r7wbEB21/Vt4NiA/a/qy8GxAftP1ZeTcgPmj7s/I2DHw9qeQrSvjOV+PqS3ED4q8BwY832UVOe4+rY9DTWqS+teHRuTPu8FWaFz09rV1jv2xsylFm6lVgwrrrC+ulSoarc7e2fqzt982qPr/szjWPpXggxs/mEfccQDysjqFN2S3Ue4fXWC0Q40rNi17wmtmvhRvsUQPE+T1A9Dm1W8NzaQNhdUBgds5jScImeUR0Ask71DFc+4otLy64V+3hVZoXoxvb9tuX56cCMa7luSwBUaVmZkDJY2EglHtAHmFyvrPDZXqHOgYrWFh1DHIF/Ugv1p57Uq0g398PvNxKD91Xal6wn7xpX7U3stZGLvPXL+T4cYHdF1bvoLxUFp/7mV9jVOtuppKxjueidmI7f9qX3knt40Vss1IH+e0rHgu94W4cHJ24+MDHeVQdY3R4l388q7qFvllPg5GAoKmJRsP4c+RX2HF1rNG84JfQG/bJ4QfFDdXasGX++vXEU9qTvO7+T/xRLQ4Ha1wLvFmt1t1MJWMdz0WGS38W+3kU7FgjQQUidhcAYXksxB4xgcGgBIDPj6tjjKxgMbrnpG6xF+mG/Qtd8//0sChv/0PtYtynhfWW5kXv+oZ9LHvskM1aG6ZMUgbYv+yZ4ABSxD+9anHoZaXXbrbuZioZ63guaueffuznQFAtBa1eR0TuXb78g3MpFgjzGPSW6lF1DGH/jUkdw11YuoE6ogRCiU+UKb3hf0fzomE/LttnYYdckmyDKZMlGuI5sBMBRO5+U4ui9m6ukrGK52KBsFOTjAjpy3im1zUi9y4Lx7SmpuE96hiqoDaqugVRB5CWPv78SaoVCYgn7vBxnebF2Z2b9kXNR2oF27lMmpow+sDEYiBEiyPXoq69m6lkrOO5wKU89j9/wj5Pq2fnkEKmph61rnksDET2vZ6uYB8g7tWj6hh74YGMvWpZ7JnTgbQsmXPZXaSzeNnbn8EPkRHoljUvCIiWfbZ+UUond4YpkxdrVuRwIzNU+nOvWhy5FnXtnatVMtbyXPY4NsI+M1t4TXhm1RD0JaXQ7xGmd8MCFSF8kjrGbR2KXeKHPKZ5cdtyPvOxb9bjTdstnstYte7Wl88/9ogDV9o9jYzMD3m0hGXL+cznA/F5PJftWdM32TYgNiA2IDYgNiA2IDYg3AbEBsQGxFfUbANiA+Jj1JS/KyPyNzr/y1q8AfEtgPAx88Sv0ta6E/SSale/KePfw/gwz+ubD+9WMTVmOckyPU6PbjY5t1unB9ubMpPVfZF/b+vVPxR1JfZNFf+lvwMAfncCRCeSBfntL6IXDPW7Y/5djI9cm76MaNIvAtHXb+r1ruJHkOXo+Yq/AQSrdlecj13LVgLCRvbYSX79ZIF4KOpK7yqfXW5zE5UlIGQ0OLy+d2gD8TDjw5JV1gJx6wDbj5bJ5fr8Mo7tPAvBhRaAKKlAJRDYVjNQ+ts15w2vyYZA6hf0m95ZppdgAQSpTLyJmDpoBeHoJHIKq1q8Dtf3MD4S/+JnEdGEU4Nh8UN4FfvEl9gL1yLHRSF+xI+LMi7yiCBHDfEuOBRB4nwgfgqdm0dY2Us8FHIVndn/Jr55cTztXK5XdOcg6srP1QwUdgL9YCaHbbPloTgJ6BT/HPk3AfHbO5+npt9eQ3vwGvHqRCmA47Acg39HPJRz4l885YgmEmSgZ+ZT9CEKr4J9ek8pKspo4qKQExJRU3o4TmWNGEfwL8irpvadRosYmxFWJPoDOU/PfIa6kjXwU0tQrydx4nL6lQwUtoMKjrbNlodigAgGCFKTyECAXAAgHC/kogzDkVjew/hQ/oV4mxkIytPzIodYJ+SE38vnHIwDi+AoGgb/SIyIXpZJlNCfnzlWSu+y/ZgHFICxFWFlL/WHb3sUILiODjEgZJxLndUqyrzHQKH4L2J9tG22PJTZiKA14rcP5YhwJRCsj6ERha7vYXwo/wKVkogmnNpdXBobdASfn3JUlEuOi5JGhEO+DAQ6na7wxPno5di5FWHFXdpAMLPjiYNxuEwx2KU4LCjzLgPlTJFVSiBqHkoGglQrAiR0Xl+Jz8FA+Dw1ERWzQ7xAn354anqY8eES/+LJRDRBkCZ0z1Ofmp35EumzcDEICJIu6oUfYoDoAQTN58L5eMJ0Fc+1IqwIy4I+//xpgOjBC9kpEehJ+SU3wt/MGShjCrcz2jZbHoos1qQGAdUK+h4RAvE5SOSJVCYmj8WalCugSKGLNSlX0GL9KOODtWywDP40EU0kIgpIMb0u+BflSzzLwpnjojwzn4K4FjshPWY2CPEuaH1KnI+fZJ1DlbUirHBdEFVlHJX/h8Xa9XoTMQoL5JGoK6AC7ZkRsr9o/jkPxdxIBWcNV1/mzO96+yjjY01ElHHlmVlwjRVskrtl97eOr2Wg1FZu1Cms6MqPAtE+fj8iynuBWMcmub0t5S5HxL0W11ZW1Gl71vR5ZW4P/TYgNiA2INwGxJ+o1pfUfQNiA2IDYgNiA2ID4j8JxN9s2sfkUr6mrl/ZAw/Y3oD4a0AsPL3p9QTcXSbJikdqOf2+Og7nIjleFmKt3N0ogMFpcoHjqtxJmxWHxckyf3etDBsSXLseb868GH16K0+eVpUE2ynvnEWxCMQ546HEhH4GREMdo1Cq2BWp+lE8cuyjaMZamfWQ6eyAuCqBlJHZ2z4U5+f5vb/dPb6I5+Kls4KvrXYuPyT1os/ss7HpXkk+AeF89VT7A0AsqFO0R0QNxA8G4kcGQkrZLQJRX1eQcu9Yqv1QBpmZA+Hm3VPlCDmVF12S4GurcyBcDcTNkgAEa56ETqcK8BmURVFzKFTRgnxdPy7QpWCvdGZdGHWKuTpGqVSxv6gDZS92GJh+txhrRWOpBI+4KMMVcVJMXBUeEZ6BoLgnxDs5XDX6Smac0CfvEC2FCkVEE5Z2t2lSPBeJf0LvnPvaKnV14CgqLO1OTBd30ogwMpraJWke1TyJ5bHtxGfIvuWSQxEdgQg4wNwDYkA8yXyknmWrTjFXxyiVKvTVdOhcYITETh+XYq3kWCoI63T0iPJA0SQ0eAFF3TpNQYBAcAKOGqGxTyS0AH3SaCl04iiu3q5Ik+O5IGiIXrWlVZoCqUxEvThNvz2mJgQmiNPkQknBRGKB7e4K28mNriyKmkNBXRP3XsTl/dKLbymzLrI6RUsdwypVUGSWHTMjetGxwIjYUXicZqwVjaVCocoQgWRAXAlv4qrwiFAgnBCAuDupy94GZp14mZpgkxcYTkWLpU1j4rnI9BKtTrVVHRGIqhKcAoGYKd1iSacUiWXQid+7GghhUVQcCr5Gkeb8JGdoSsmsi6xO0VLHsEoVlJYFSgQInZoQAqQdawWxVIIjIDgCydUCwXFVeI2IzTRAHFOXUQ5inSwBEao0IcdzSUD4mVWsEV6jqiQgQoJpoaSUx12XgBAWRc2hkMniaXxy5x8XxEbhEZFYF1adolbHqJUq0tTU2xHB8LRjraRYKj54mUA0kFKOq8J3TcXUdLhigtH4Jfpp1j2YMEwaG8/Fiy5JmFlNQCCqCoDwXqLKNYGQqSnlUdsS6cUpn0FZFDWHgoBg1YqfRJJjpgbm9sS6KNQpKnWMWqkCx5EPQDAZ8wUsiUaslRxLxSMuCoKZUdiYHFclOP0eQSyTE+fhiCnXFGxMPnmJloLuSUuoSZPjuUj8E77Xr63ie0Qn9Tq9UfwVxIbklcgtlnTtUlucRHaBbXdvs9/9btHl2+eWlCrWlKb7oZlyKa5KdyOPW7S0vIV3Wl1TkrX9xUDwEn1eX9X1QNC2HFflo1329Vbn7f28pJ9cse2h3x+rxgbEBsRft7oB8ZWdtQGxAbEBsQGxAbEBsQHx/wSI+0XeTnEv/3vtf20Hf0PxlA2I77G9VbE9eAODQXkMiXWQ3br05FM+k7+pOFvxGwxnwWwnlCApLGMil8rBFdwCN8I+uayfYi481YTjvmN9ETw8L7f4dJT/pu4QwYUwq3faQj45mKLDPL03eYocTh3iEYhr3YrgtR4Sot7VQPAzUAHCm7Olg12uPV/3kE8B75HCSkyYUunPtMCN8Mae4WDMgfCp+UKTSX+HKpX31fPWqZuZ05pKWVOOi2LfOMztzHVK4hpVDgNEF7o2EC4D0dVA+AxEdXYORLK/DERXXDA+H50a3IhQARGqvg/t4QEGxYHjA9DfQ82wcG0gugYQ7iYQXQMI1wLCMhPiFR3w+i7zDsQFQ+yF4JAmVhov+Iorhf6Se2Z4DR5A4CzYFpTPshbAWVBOhpZBbpPDFTr91OWUgt75tqWG4zDV3Ag0H3U4KIMicTCgE0KflQcCW+B+wDtGZQ7i1wOX43AdhO3RSc0xveIyIHcsemziCxB1GZgpQjYOwgZB3pwD7exi2W/oM4e+tTmcZSbQG9ZQ3WBXHnMN4DUerkePa/MIXY5jfuH9NOEvYMJZz2oeR5+ZDjiPKyuoeXYtEhRHr0BwpRx5QG2pFHSn5kbIlRTLdlKCci88l00ld4YHAltwsMr4lxEBB6uoiwjbgzoTbBEpZ9IhQmkICK2Lum7JWZqcuVRGygE3LDlEmYBw7Bz61uZwlplAQCAv8RGGN/AmmEchFdRZnpz1EIEgXoKIQTBMOBvdhG9cQWdZC0qJBCeD0lBJBy4ljwiZsEJdas2NQLqBmB1cAlgYiYNBjlSXeSCD0GPA/ZBbCymzk/UM2iI6NVH+UAMxoe2/PXoJQAzsNu3QawiHEjAWkAMMEQCBtqJvbQ5nmQl6V8NFCD9BeBT+WAGR1DiUo3DM3RgEbzprWQsKBDgZHuddiCl4RBznQBSlTnMgtHQeESUHg6a4a6p/PJ5HhDIoWkC4awYi5vdy58cjmboObS+BoHJojUD5fKVPWC2RAwwRGRHSM5zW5HCWmaCLKTqSJhhMTZTmEAeisg7KqYlHxDHOfOasl+gshunAub1LUxOVceQzgayTAFG2ACByqVyvCgjqvolsxJ/DFQwKy8GgJk+GB0JpujQ1YW3Aop2nJtRVgcA4r++a6OjrqwWC0wEImWio1WUOlK1TE/rW5nCWmUANxmLqRZ9DeRTElKB7a7AOysX6xAum8/ZszP9K83JmOgyc2ztdrIkpQbk7XqwD3WUbC3QOx6VU0gFxJTeCjk1kI/5wuiv1hnIwmDnBnIzEA6E0mftB4/9K+iL09yTES8oFtscJNyJ+/j2C6xUABFk/cU+AdDVcdWEGnwM5eDlmVRPWNaG4Ndy3Nkdxf7fEKQjp/zLrgK7A25yEm7kXLNwq1X4NC80alWeDs9yPIN+ou/T3L281EO4GELceB8jt6c1t+XxYsHCv1FYrbI1qIDCSytpsz5pWp9ge+m1AbEA8lm8DYgNiA2IDYgNiA2IDYgNiA+L/HRBfQV/5ODTft/Ufz/tuMs0GxBcD4cUzjHgpmSlhEtij6mZ+oxzwYNTRV4ZUVCcPeYaFqnSuxexY3u5xJ07X9bkNz4LbUra8VeN2GWtb0cqHJ2InHMBzTGIzMG8iESKsu9sbzzueznecIzM2rC+9S0UN8iJrkSJoN3CZbt45pZWi5+9wJ6rzVYnl2ewxQFtKNkCr9HYZuR/K1t0uPfe4U/8fHCPKavDzLvHVpwTEwcGV1AYCKbpmCo3ecnDhhn7GMhDuDhCtzVdnMxytmtwHwplWutAtXlBLpWuPczuEbzDBY0WqE+TCAptBVS/IReJ5H6oS4sFFDuZldKJcUfIY1AtWp3DKEeHzhyT8rhwKlKP8CDgr13InyvPURltidXZSngXaAg5KxcVIpS+VMZh+sGXlnO3SM4+EARa+wdTJfN6RdyschXcAHgNzNa7shFQWwgQfF82ruKLgmi95DMKUCHUK1jDxXpgUwgsxHIqjt/wIXD9ruRPleVeVWJ2ddOJAWw7KILFcDOdmx+o6AIiuKivnbJfeyRoBr7byDaZMQRR/sXIhPHgLypIAC8GMCFkjoEJR8RgEiDqFI2ZHukEQOoLhUMBnrvwInZLWcSfK864qsTo7pfl5wiXhGm2YH6vLyKTNsnV3Sk/0BdCCppAW606oJHMg1IzoYaQ1IgMRNK/hMdj7iSIFKza0gACH4ugLfgRbWMudqM5XJZZnM8+iM51St4FKv12GBcK2LuVslm6BiO0A36BT5htfYeAv+DS8mW0B6hazOywQWGxUuaLkMcjsGeoUMlS9zpI6NSmH4nAt+BEyItZxJ8rzICLkEsuz5V2T1qS0lxfa5TJwCWteLcss0c3SbetjO8A38MJqINUJZVB0QrnMizU4FMNr/h5xktBoqlxR8hhgE8wQm4IX8msn54e0WCuHouJHCBDruBPl+cGVJZZny+8RWpPSnnbnrTIoL/gptqycs126bf3J3uo+zma4l2PJpmpoLJ53n7WFqsT3t8WtbuW8rHbpiz3+5x5xZA2N9vm7vfbwVqt2vKcta/POy1oqfXvW9KVAfDjfBsQGxAbEBsQGxIebvwGxAbEBsQGxAbEB8f8IiM/vjmzxa0krn3wtPpx3fetWlbgB8Q2AsPyN2fYQv0JZDycn70tPtK9vTkPX2KYTP4NzbjFyitdUOX1ZP7Jqj6b99O5baUv+cD49F5qlusWjuUxp3dUek7ShyviW27/wLM3yN+p63HClh3mNU4oJr+nyO4T8nijesVbfQvnmG//3C1om3lZ7HrkEQTasvkdqok8sj+pIl/NdNU/VNt98Busz9yKI/gRal9RCZjwX7OYSs+OplodwruBv3ALi5kVSAaHFdlLVgzNHWkC49UC4ORBG3yPUVZtqk7lbwC7xD44IaQlaMel+WQ/nc7klEO0SxUknnqKjshBOrINB7A0oT9xiRehny3roJAoJ+aD4nU2vRzgyCVxGbCuI04Re7oUVUtkw0VNekWopcomD1UkdSydW75DXjlmNo0u6InpEPdTk1YfDCtFT3DwlT3T1UbQEzBO0LmjrpqRjQuVyz0UP9zWXCI+hKTGn0euXXjdXFgKiARw9ZvM5o6JmKsxYD1e8Os/4XzUeCWtBBXENimTEKXpqA7lUyffHQhPslc7RU45ItRS5ZMAr+ld1tVKKo7yIDzWOTqKw5CPKP6HK4vpUHZBZSoxaX1ukvGCeoHUHaa/qjBw5LaWm9N7lEkVnJJVo0uiM3iXxGuJahCBkqKnFqKiZCjXrQYgIU5IemfQILd80kBHBhEfE24mseS/qH7+L6ClYXZYjlzD3YkI1oHcRnIpSQI2j04gr6UjibExB1jnWxuCFvkopy399NJeJ1h29S62U9D4pGQgQUqIvSzRpUrclINjBHTQGzpxRUTMV5qwHQKtQquwD/WWqDBdPEUyEuUF5vPJDfhfRU7CgLkcu6diqVOOqCiK52+JEMNVHupRPLyuMXDfPK3d19VFT5qTt1FYmNsokYzHkNcI7C4S7OpfTOJf4G06XLlbHyECUjIqaFaGfC9bDhCgkPshiLTcEQUDQCCZc6aMyRsAPSVNTUvq4FblErCYWiDcSLVDjcJOyQ/RIWjq1xdLFWYsj5ZWpqTyKtin3Qve5vS6xUY4AguZ/77uqprnEnIa7XtgEk7IQuitpaXCXvtWsiZoVoZ8t6+EkUUg61s+gPZAr49+3gYWtoOTBU9MrNDM6Uf8gLp+JnvIKyuNS5BLmXrxlFkjHwdCwtEKNw4XhWh7J+cAu6eTWgEOTlXl5q49KhBXhXug+/c06I8RzodTUvm5W01xiTiOD6RaDITQ/ZR5GO0+2+LWKF7etzgnJemSer7ubV8ZHkfd268LNmjaitNz6+t3u6nusiO/xiGP+jT3rZt6z3P62X+uF3G5dWFHTsL45H+ug7VnTAyVuQGxAfFo5fybfBsQGxAbEBsQGxAbEBsQGxAbENwDis6r4FdZbzf5aeD9qczn/Q5Y3IL4NEJltwE8FQxVHhJ7i49mkOVyoDlzLmCKldXoqi/1Qn4xP1LIaBj1G95oDJcuzTt3DC7L0FJXOtrghAcdrwQN3jxkC24tbaB6NLq78nHWmZ5Lakl5XntXJlWwCy7bg5+RTyXNgA0gxNYJUOJcioFcsBb0mwO6o2BP8YvHk09N7ACFPb710svh9dc95kW+/2rIsN0ReXPZFLVYwQ5wPrtVP8neatxl6+l3KP7sEJ22L83Xr/Zw34gu2gUb9KFkHFgjXBsItAWF82TMugwDh7IhQX/chcSYk96QecPZZhyVuCDr5PhA1M4Se8nd3gXDLQIQZRWeyfvuy9eLvY6ZCYhMI/4IZHYN0aclzCGA48FVfMhVo2OEVb2VqaPwR5YWw9WnGZbiCm4EKMlfCKUsDOTqXOBOTU27IpGeJjdHmhpAlokU8zAyZan2QA1tEmk6iswzC8DCBDSbNH9RJFA6SR2sLrodtPTvKFM1j8q8y2+C1EwgwbC3PgXkSRwK0ZiqkWffqjNaF5YWws/2qIyJbhSeadQCunRw/yuRHOeS9/itH9Qqd7HVXsbfADUFUCsSleIwZ0l1rfRAEV8hRW45JqUQHMcshTZr/oMwSqJr4LrVFNDtM6xHiQYDIbALLUfDyW1kHOXCHm5ybMRXSUKNoKqp1UfJC0ixfsCcyEF682kNikYAXlWfvTsdGWiPwGvycGxKSX/hRZojOVFkfhNUYAJa0Wv8OdhXQESEhcQZIqHA0lbItufWDkglAgMlsgsxR6PIaoTyHAoiaqZCnpmC0LkpeSA0E2BPoCsDWaW6fXK2JPpmWwWKxxl3SnBtigXiMGVICgRgtGQiaXI8JCHfN4aDyYh2UWUIjgttWtiW33l19ZllmNgE4CqqeIUCUPAeocUjBlqmQR4QwHnzNC0HEFD9jT4CbYYHAJAOGCbrTGYKj7PlMdWxzQ0I5Na1nhvhaHwT6JJJm0ugsGlupXqxN/oCINVjnwJStW+99mpoym0A4CrKg/F9737LbOK90WxYcgNDIH9CZEx4ZfgpvoB8gg/T7CD3yY2gY/E95VDdW8SJbzu3L3odKd2JLZLHIJZG2amkVnxY5z4F4Eldackqmgk1NV9O68LyQUVjiJXuCuRmcQ+4s+zkZINc4J87ESGohZ/m2g10jpsYKNwQtnWddrLczQ8ZKH0Szv1CZyNlZznK0/h7h6l85Yw0phpDXzPXwvR+IIZJ/LL3J6Bia7yJs3+IG9sStGt/DDdliM26uHx/tfczMPDK4j3fyvTV+zi2OuLl+fG/v+72mftOvA/GZbnQgOhAdiA5EB6ID0YHoQHQgOhDfCMTXOfgT7Hw1/eZ99h+s1YH4ViCa+hiJg9BUk2g+5PQddpY7w1PDjpbO7HHQ6M8f0weIVVvjzXqlzzEd5Q19wXIlT0PLWQ9G5+dZalXORGjoY6SwRmxyEFqj+F47D/kzrzFCYihdUiF6mJXqY3Xs7616pc9REqCk8yhyOVgpZyIbgz/3Jqm12nHIO77GwLgLxIN2HvFnWGWERGgNKNc5wooGByn6r9cr24pQJDfnmHzF09By0dn0QEgtZC5kGUsa+hjGQagZGJKSPp4fs3Nq22ENkK12MPBX2sHwE3IzxllDQGgrRs0IgPHBss7y93pkNZEb9aBoa/GKBlhLcwRyKTe1y0WwdrROSD2R5BUuY0lDH8M4CKWaBHMQkozBdjvXtp2Q5P632ImxZoTgQEt0+uSysUQ9s/lVXgfFK5ZxwL836kGp3THplOOviCjaIHU5lo2RdkJ+RcTozGjGklofwzgIJQNjVN2BBMQ2O9C0wzlbttvR1DOeEYKaGEoTsGwsOvwMRNk2y7kg9+RmvaloS6at0X2CoCEN7XIQrJ2xWCMEiDxjSUMfo15kMw6CArHdDrTtyIGtdjB+nttBtoYBEc1WGlBl0vq2cfIRtY0b9UJRT890SFOTcHHDSrlg7YCbmpTBW2UsaehjJA5CqSbBHAQC4iE7tQ4G2/FXxH07RFsu7cSU/unk+pbmetCpydXRKUl4GSv1Ylkv5lMTMg7dB5FGOd+OXRGjEEhTo5qxpKGPkTgIpZoEcxAoJdr8kJ2pbccDcd8Ofo+o9TTOxLbQRVdsXYnPwZ/zqz4IH0O4J6v13vJ6zBE5G3d+UlWmtXK+HfseMba/R6xtjzMwfp6d9ToxfEZb98u12on9FodtqzqbD7Z1r1y7nQ7Ep9frN/06EN83GB2ID3aiA9GB6EB0IDoQHYgORAfi/y8g7hv5fJLLT7T0Q/3oQHyWHzH7w69Dzk9oVAqe32D5RSByfhHjMox5O+mml/IvdBuz12N6Hi1nT6R7Nct910GemEu1XeAfuRESgp3UEsXI5jvjFFYHSB/kjY/lmTkXxtkPHR1VO8Ft5iKZ3kbM+Qm18oSVIH4D75yIVwGey5DnWfEdVbmLmtkAiR0xFOwJV30O8sBwTDU8EKzzD+nB2kGyxoTmqIcVIAaRlecj+pDxAGu5PpqoTvbaZa/J1E64sUZekThBBURxlkwZvyE9fsuvjcuwDkR5Q3gNiJw9kRQzIj9obEDAXSCOSaR9KxBwF4jhQSDUD4hDWaKVV+QIowyF5hTxyhO+BDMQLL8IygB4LoNpZMjfq3EeaEpxDIqcOaFP8Xumhhs6AYL1M8g6cIDKwS5ApPwNonbvNTYKrRCXR2UiQXYtYdlZ2DN8CPkoYTLJODO7qXVWpQ+FitoIKXuNZl8ReGhcW3lFThl1qlSe8CWYgWD5RaLkF4kpv8iQkhqUYUiAnEHBmzInVNciujwkLplW5IFgzQ59sJ0fxU9ARANilLk5aWSIxkauFeLqI4OE9RCwXcmSwqoanCGALQxy/K8X1qEQK4+aTv0UBI4pe82s16monXCOGpmBnd7GsQAiV57ISxhvQUHxXAmWZhjpAfOSIcGLrDEbrBP+ivBMjRyIU9DpCa0PwA/jOyCm+oo4FRobuVaI1UeuCPpEU9Pyik8lU9UIri94/G/Ik7Cp0odp4gf8eDLxYh2TuoiqnSy1q7wi2D3lHcgkkitP5CWMtwCT8iqMK6EaGREkt4ljSPCi65gNGXNCZ3bP1DAgWN7E1gkRaIEWEGm1SVmSTGMj1wrxnJa/nJoETAhiAFPVQBbWST5vRMrBlK2xSelDVwAGQrPX5ECoIlYrr0jMrwivPJGX8LwFE7YifgXkU5PkNjl5zgNkzIb8inAiVIkVwZ/e6BgRR1QLw09NctyWyAKIXGMj1wqxqSmerle0Fci6WlZVDfQGV7Zk7fRXss0oX0OVPgB4NSAOStTsNarI4WVnoJVXRHkHaelxyhN5Cc9bOKfXDAQvi8KMoNwmniGBnAc9zswGBYKZE/57hHpIy+xEDBDkb8yjaHaM7Ast1nz8LFeE/x4hnkxeY6PQCkmL/Xhd1qYrKYSQR8q9CPI9YtkfiJ458XFe2jGvBv3MqvTB+WXo4wSJo0j2GlHkULWTwN+P7vMg4mqJR/KLrFm9xaBosSKGm5bXjus32s/S7eBJdij602o9NsbrnX5EuDdU+evHbifcYlD83Fsc4xx/hB+fCMT3uN1v+nUgOhDfMgAdiB8yAB2IHzIAHYgfMgAdiB8yAB2IHzIAHYgfMgA/1Y+8offRUGrxk0e6dLvNR2o91sJ7xVC+CJoOxMc9CsWtqCAsA3rt78yt8juCshT4/tE5e9feRnGGOBaTrzUA3Kr/lvMhjHciMbDIeyPkWVXyWmMq02J5ZGWD18ZtebXuK+s/c+/Ehom7y9EicF4CkVS/Q34HNJegzoEYUwAGIxTuHbTYD4OQTIhjEX2tEQprWf0h40PwHr0HPLJguwyyz6qSLKY6BoRneQRvKdRA5F75PrTuJbMiOjcaq/Hko/eASK+3AZHYEilU5N6tAtGudSz3V0B4PoQHAvcP0QY5B8KzOTwQfn9wZaWFDIjcK2UslXv9UKegVBOISKLojsEwAKceoEwg9LgtZTjBYxPzFUZiWXjlDW9BI1Aar5J3J2U7aNncltQ6ZbVOKZ51YhWMvD7osUlDPaqLwfs5Akj8C8qqcpSMKXxUM6bwZIJxe/EghbNi0H3SAimFYLgolQ1c9k3YHrL3pO0K+2NWqYCYemGcEDsKOYMhBSwj5x7hDCd0bAJ9kDzaFVFyIIY0U6YcKPRs9FCUzW1JrWsMrtZ1SPstnGv1hZdxHYSXASlXhNiKvF+zqoTA1AE+qhlTJJA76X5leQQR/aHWmY9y4lwZMe0fpaxkv9C9V7HASQ6CZM2I0XE+jBNiRyFnMBgQzFIIxo6YmPEwQgZExYHwQXq9IlQUwedWyW1hOchq8cUrr6a6Pl8RlnJjfFNdDLElM7Im8+B8KnpUazHl4JxqKcsjiAzWkCYR7p8Bod5qPpjcMquKcHCUs9Qk4kLGCbGjBYPBpibmSITEjkhsu1kHT7KnFBY8EEpiMSkpD4S35bumQ2xAJBUMV38ohlTSfcxaR6guDgjzrwQiTrkHbSCI5EATXl62BUTUrEXiUTAGSc4JSUehZjCkK+JkfCZmWYTE4AhJSyLnQNgaMXggYplbJbfFtVRZQ4CIOjUlFYysfjqWmBQ84GoLovI1ZGqSlSuvpZyUcj82lLyCbGqCsixnZCnbVSAkjwwtEuqpcULsKOQMBp2amLeAi/WZuRtXzY4yzspuAKg5EMpSMF6HcEOmvGxuS2pNrKwhtSZexOnVW11feBmT5S5hvQu1BbJYa1aVIKJaea2zMEHK/YPbJ3yUqyZPK8tyRpa0Vz48BPKXein5KIdJOR/GCbGj8LlbyVLYxllYr3WrfvvYbZ5EfKBWuyxOUc39q+1u9eiTt//1WxzygfOhdvu9pi8AYn1/B6ID0YHoQHQgOhAdiA5EB6ID0YHoQPw4ID5m5jG8P1b61vtt4H7uafitxjsQ7/c/24rkyHPLOOWgnteaxqPGpYj+YEgchZjXium47rBc0N7azTrKjiDPzoUv58zzs3tNryjecEeZg3JVCzckxtvDGJz/Kzf36k15J+TH6EZtSKwNr73BLAOnZp1RAEoOQgQmBIQEBB2fHTZSKkvd4bKjB9fpUHQlFEDEkGgTU+HLlHk+2Wt8NVIo1KIqzbvDkmWeYyT3gDD/x2xMbwGhkNGoH31ymZY6RcZBaAPhuRRRSnkgjFOxBQivmHELiKL0VPgyDd7zyV7jK+J5NHubAQHvAeJYjOkGIPiNMSRGSm4/yuuSZWChlDNpTYz+qIRDkGPBrIaz8EL4uHAqrqx/wXwIfiB3CqLEMfF5i6WPc83aqOuMUpqZFy6xAgu3Qzq+eD4ok+LEezmWF5itknrLbJA3UtbAIFAE5YYMwr446sPKUJY1/4dsTD1rxdf3vBOKXTMqJ5F5QNYGxU+d9oawDFIIEIhLoQ+byyPpqnGxxCQ5hsspBhKDgWtLdgMOOnIOlUk1LSYQBXxmXpSsjVYdLn0UxkjydOL3epxgnuX1dZDMWxS+n4mtknqrKgJ/hWkRQbkhA7EvhKvios9W1vzXR3xz/8v6nneCo57U4tmdwLlw3rz2BrMMOJhH1wxxKUZiYTgOAh3FoVYgEmsCGQyRVzxOhzGycICKJ4TRaW+YtZy1UddR2ye5spOnkL9PEW6xjK8GjZtHR5GQtCE4uMy0MG4IXUFvzFUZE1HTlzX/bcLx/pf1Pe+E1qgWEDHT3mCWgcx2s4TEI+lrzMZB4KMeCGVNcPME1CQr6ZwPKsy2RoQV1kejTsaO4DUiWJKxKTs+mWV8dQ8IU/oQbghLOjBZcxbFmays+W9AeP/L+p53IkAo2yGEQV06mfaGsgwiKL+ByFqxOBqKqYnIUzwjE0eBpyZgfQpJhkN8huuVz6e02CVrOWujrpO3zVpIxJaA/H1arMUPfLV4yEmhovZcJwwZ3JOxLVhfiUYlkWGYBuDLmv9pair9d/UHxzvhUYez6knMAylg8CLrtDeEZcBMCuZRSBaV2Y4al+IorIZhTqwO5CjERIycJUmZWCGRoNm+R5i1nLVR18nbPoO+F50L8MfP+prgOb+d8TsFlrxqz1XVAz8KTEFZLMoN4fVFuCqz6G5kZc1/qlH5X9SfHO9kCkTZfJBh8cjR8ni8K4X3iFJF2fbt99uYIVu3+EH/35VP5vNucdzLW9LvNX0TEJ/dkQ5EB+JT/O9AdCA6EB2IDkQHogPRgehAdCD+d4H4iDOf3f0f1dEfNjYdiM8ZG5fxJAK4bCbpxlaeW4V4EtNKO0GkEGYOAQp3gp4/5Vdo9BZ3Yp034VkSLZZHbFlzLImP9lNVIzIR8KrOcu+1UYdf29gMjbExOQdWlXdavpasIk9+gfL7a0CIfn4YwbgTYyIRjBwGaXAnlJKwzpvwLImYw7MKhGdJfLSfPKhDAUSV7iSUdbRn/EypMEigHpsbDg4rjcVwCwjPkuDGjiDhGFTXiG3uRAIC7gNxhPgOlsRH++mvCLsOKiDiLSAy/4uxIcIAJ7gYErOAcoa8sci5Eqb04VZ1EB+M59wjOZdBWRKQuBMD2F5kc7S4EykR/TpvYoLEkmixPO6xJD7aT9X1INCnuFKHYfZ1tGfgRgF5J+XY0JnCwcIhMQsE1WhcA7q+A7Mw8jOl5DIoS4L+z8JqmBN3Ira5E8INoVNohTcxGUuixfK4x5L4aD+BBCIGB0SrzjDndaxnADY2x9nGRvdKPg8OeSuzQIxNxjWAxN2ogKi4DMJkmJQ7MYDjTsRWyF65Iee3G7wJuSLU3qMsiY/2E48oMSFvwdeBsk7qGYCNzSnY2CjbhM8USQGjzALObqLhfqUXUCy4umRrLgMzGXRBCqBA0DT41gIicUNgnTfhWRItlsc9lsRH+6lKN/TqGq/tOlDUsZ5pwFYZJDo2uldSDYmDlpEkfYrRPcRBSEmL6qlJuQzMnRhsQZKJhl/BCndCuCFhnTfhWRIrLI+bLImP9hNI5UmAII2aVp3yKrKeKfcw+S+vg/QKSEeCM4VEZRbY5+vENZhYzYIWqOzzdcllYO7EUudNuRNnoUfiK4ht7oRwQ+Z13oRnSYzvYEl8tJ+kT8JsC1JlatfBDC6QfxuRnvFHBvNfxyYAjw1s25SGdr/kV3Invpglcbef8YvHZvN2n4XhByt//d90i2Otn/FHj83/IBBft3UgOhAdiA5EB6ID0YHoQHQgOhAdiA7EjwbCm243/H2dfZ+syud78X3tdiA+CsRQ3SVZZ1mcsyP0wG+Q+5G6Mz0Lp00is8EYHWXO2zHzRBMJqBesVM7v7aaalWn6iIHH/fJD20E6vbvUJZ9e8dj+sD88vywlXjaO8L5+f0BrtmOxqIP95xXcsSd6xe2KnYMbivK+Yc2ySCLpwYZMwulJ4V4fqk2Z2QUIDCj6B2yjs5AH3ynqpfwP8mJkMkXIgdAyOfkg2UEgDtxNxOPPHxyWPXV4l/qPv58P6OXusrsclrf7vY3yTkztWqO/AoSVRYsg7e4Ke7vULux3WPWS6h2hzAFSsyxKINzJn4CAdSDSA7ZBSUXZVWCeADD/Q9s8UvQgB2JIZVayuiAQFz7T9kvHeUAO+3wcDYjn1+dXAqI5yu8BAi1uAYL+XdxQ4FPDLFV+lABGybJgKXOWayeeBJBSReDfzI0YNX3HJIOhsyHF2pi1gEAcKZDEFmhilNwqAkoY5GFepsBwPE2uA2ZnTFTmxF5xYOpIvlK+kxnbXrp7eXo54JRz+fMHh+Wwf3pZfuDp5Xn5+88LTkb+inh62QOW4KNPsPz/jVPJK76j8k9LDTqG+5d3r8uPvscyO+CSyyu5IrDdHZXF4ee/CsTy7vcTPC97sK1/Fl+FusLiIay9UbMsgkSEl/WAHmSnLCukmRFPCI9kLck1NRSIJeCoahgYx0LLk1jgqekUVKYBI3g8/0dae4gTN+kaoaWozFWvUPY7gPqEQOCVsEzUeKIf9IrAH9yLJ+IvmoeeDrZGHPYLNHs8uvxfyv1aauMw/mcpi3v2fE3hu19s7T/Lj77/Rba55GGvawRfEdwuXZN7BgLbXfb+2tEVi/WoNTkD3zhjVIRWcJ+znwRR6WCGBepq4NEjaW4MtLB6TQ0FQnUv+IpgwP9yTFmAYOaFUMikNEtODOkK4ZWBA4rK4xAgknwF+8RXxF6BkCvi+RUXSjz/ljP/leCA3UG9/Gc5TvupnsLIQBwInr0ss/gOpyIGIr3fP7/u6Pc+Lcx6RSQgltoMBLaL06ECQSeJAoHaFhT+XwEiMh9BcoTwdCaB+imCXBHgNTXUnZy14IFgMZ9BmRcim7AOBMgnLuVxtICIskYcBAi3RrwAThEvBFEBxOHCEHggni7uisDZ/EWvKwMivV9q0hUh5bjnxRUBh70Bwe94sT7YFSE5pK5p2AuWBfMrUByMmRKa7ob0KkSoR8omIJjfQAoY4BZrsnS9yvArEDrpSLIZA4KZEUM2NTEbhL3S/eKrTE3LyDIQ+z1UU9MyKdABD8SBJqVfMrXw8AEDsczfCAQP+K9DNjX597hGHHQKawFBk1ECgqemPQNBa4RkPLkuM3EgVQyoWRbMrxiQEEl8BV62SRyESkYVynKaGmPSvSCGw5S+R2D5yBaA6ukyzCnVdAmmLEaadWQCSFTKicpM7BXvR70osoPCXPQ94oKL4+/di36P4MUal9zdsn8ZmpcMCF6sf9PR5RWuGbg4P79cltHEPTterJeaulhf9pe9vsfSSx3gJT+tjqCL9TMt9E+/n+nVThbrZal+AVqflpq/3YfILTyE4sOrvq6O2hVhH1PL75Pb23uMk/HIN2v+wtXaDukr4dbNl/zz+sg366KNbTyEVum42tStWxyPtbd9+5xbHHpmvw+Ix9rd3sa7B6Pfa/rudjsQHYgORAdisxff124HogPRgehAbPbi+9rtQHQgOhB969v/6CY31pdbHs8X2/uc7rbgzifPcthvsbrcdXxd7B2eLxeypnc08X7kHwrWaMj2ktXTdpdgp+zxDIu2reUG8wX3tOyVnS13XIRPsYfb9Z/gvTVTyXqELqkORQAPGGfFSOshsR3Y/j4Bsffh9X2rZxY+B+JNILKLvSVufAG9M2+RAXCx80tmMN33ZOoFtrzPgahtPYEE5Cp7+61AEJ+iXX9f9m9zTX3VBoIdzoBA5gEH2fMBYSAOJRCHmz2Tq4yA2O8OGC8DiWDJ4HGnDjvhPxzaQEACAjKMG7b+kQBMbe8+EC+/dDjX6q8Bcb+mvpKSDSC05nJ5U2w1XRHML/jnRcMdyEzYwz8ULtHgCnIkkN9A08demA/EkcB9r0tQEqclviKWXxesv0SwSiAuT3IEbSsH4umFgzhL1AqUQbEny68UnGnb2lFw3tt7EnsSlHGsC5rUXpl7gWfq79+4f1f44+vzux08XvNJeoAl5YdesZ29q6nneVojMMSIZxzN1RT6+0UMhT1otJdDjhjNxbka5wiKuu45+gpLeBHHf3/AGXCxd0DU0caBh4AGepfOJLSCHfiFMxC5QTGr5fXTizIoqB2KEfPVUNsiIA7eHtr4JdHpnHWhVxwevbC/1MfcH19/r9fbwzX59R5SfHuPYVm1s3c1iyv1sExSCASHyJ9e9xT0XiYXAgK5EHtiQhxkWJ5fdxfcvwxImrkRiCfQKwKBwPrL0V8ggXfY7/RSpyN4zSwWiAOx1COK1l7Ojj3sJaT/n/1TqlHbWvZeMnvkzZNOro518ZSmwOfX/5C/T69ca62+AvF4TR4H9J15JEv5A77ya4TU3NNFYvPzMvwXBYLOfzrXeEAOxIKAl4NcEVhmJ00jR8KAWMrJGrFYv2B9njwqIOgI7pJzCG3TTwsIYkis2OIz0OzxcJC/JetCJgb0D4fzQmetkB+b9RWIx2vyWOFijWMHeAVfDsmOAME19/v8iuBZV4D4tdcLSpgMzHO4UMd4HRFGlVy6+FunJvnUhFeEO3pIvAZkSwBfpovVZU34tZdZX6dAAWKvQBDJpWlrh9d8Zk8+kRNfI2dduE9l+9+/aTh/LX1ZhpOt1/X3+3xq2l5TX1107y+BKV0RqWbOgn6+8IIsU9PvHS2eWJQZDvwbORKEMS3WO1lgn/nvZTlyYILiAfh7BMjMv9S/HBIJce/cR77F02+mPXKJPbBVZFDsiR9xwfrQtrXMzpflknf2dNnfvZSsixSN3iMtE4dz2U/n8hO06+/sY8qDNfn17uWy90v104t9j0g16+2w6evaWsibODyr0fDd6rvDw23u7lh/ZDs84MPHapaje6Pm08sjLjQtXN7boX9rO3xbza2j27e+9a1vfetb3/rWt771rW9961vf+vbfuF0a+56aJT3n4NIssa5ncb/u+0u36ukdnR2FriiGYD2zMLSwVvBXixnC90nNj8qXvXmYH2+PxA1Lbd7BTt7tylYvd9gK+13at73urrZzt6V7reztlNrTI9MCBD3X6YCABESLGcJ7zI9L6UEGhD/eHol1SxR1WAeiavVyj62wPmT36pZAbGFkrLeiR/4B5i8YENAAYisz5NAEonW87fO6JSLM1LwDfSiVeRktzkGbrbAnZYnXR+uKGsXz5pZehe+x1kp2Sl3wOeYn4Zxg3JmCM789EKvMkF85M0R9yRkh9fG1kWhZ0p5Ai3ewk2ClPBXf4By02Qq0n9gSj9RVNQp7WPxeSxQvv+FhCcQvji3Ls//6mLoBscYMWeDKmCHqS84IqY+vjUTLkvakyTvYEZdCnsDfNzkHDZ4EDwyxLV4fqatqFKZjca8lil7f8NADwUQDohlQz1gz47DPp+0VlknBDFFfCkZIdXx1JBqWtCdN3sFOeBSygLU4Bw2ehDWfZBQ21VU1ij1sbYkVMtY9XAPioCIkUACxxjIpmCHqS84IqY+vjUTLkvakyTuQqUn+NjkHbbaCNv/rkbqqRrHf3BIpZPxa9xBE92VH/hCfRD4R2dTERxGIdWYIFMwQ9cUzQryf5mtrJFolrSdN3oFQDJWX0eIcNNkKvAwht+GRuqpGsXvZ2hIpZPxe95BKXfAH/dlduD4dxxq0WMvxC8A6M+SpYIaoL54R4v00X1sj0SppPYHHto+E+A8PHTu809bBTUq3WB12/GPMkPdKRHzGiH7Bdvji8j93+9/pSd/61re+9a1vfetb3/rWt771rW+fJ+HSrt3FUP67gLjAO7kMKzVJwB9aNZ+aFmrrtXDCeku5sodZeUr70rPk+BTtvtQawRujlItF9qFus2t4k1gwZo85v2Ee7GaG6rc/fyRbTbLmSuUcg61chpx50a5JD71Di7tQs0TqMm0Fi/WWoPLRt0X1VF1BHC+0Rg4o6K4H9yQvH2zUMiD0jVNljqg/T9ljKDM85c1wx1npnGTqkwHWQm/g/B4uw/5GTXz1D7Rq1iyRNhOiVrBYbylX9jgUQOCRpDdSAXEwIC56ihRARLh7eRAQEcXrCYg4FDVYsn7IDDggSo5Bi8twqLkMGfNiRWuDn9ZvsCBqlkiLCdFSsFhvKed94H+voEFH0hXBeVByrRGgXBNYWjOxhJRJZqR0Im+UXQYl4c+zZpbhjDNvM2C5N4TgOAsQKFIPb1QOM74A5QuIQILzV81Lg5l75HjOMWhzGTgpi2cg5MyLFa2NA4cma+5CzRJpMSFaChY3Wqp89AoapCaS9EY4D0quNcJA7F0mlpAyyXCihr/hFFCTH7MlcPYZzTjzl/IohYgZBSgrzYSrAYrU/6VygZIwYJ4ZTPAAmPwhAGWVOU+cmSZAxTFocRlYGcozEArmRbvmRXSZsporLJGqzIqCxWpLUPmYKWhc7PlmffY/1xrRK8IysYSUSYayySxAUOKfZTEOlEVmTIlOEIiR9mGWMM7qwmvEX85uwXPRsvckSUkWm2+ShYMy0yQgbqlcCBAZAyFnXrRrso5NWbPNEqnLtBUs1luCykevoAGHFhBeawSA1wjLxBJSJhnM5cJXBKUamTi3DGeWUSCWcpGBkKlJgDglIAbOQSZAaDqUMEmempxjsMJl2JdcBs+8WKt5oAWwxYIoWSIrTIhKweJWS7WP1layb0D8KrVGBIiDZWIJlkkmTAQErgc0NXFSn6AJrnRqkmQ/BATnXcI6BERQIGRqWv4nIKgNyDkGbS4D7skZCJ55sVoTedgvLRZEyRJpMyFqBYtbLdU+urYyvQsSNfpdao0A8PcIy8SCMz5nkhnnCTBpWwRerAfJDMMZZ8ZpORI1uwst5hNlj5nOVAezwtD3hzfeC5yX5orrzTLRicXsg2H93WJ9j9X4uD7G/QD6Yf+RlrYG6O99s47NWnSOx9rSUNWxvZ+6fSf/4HsULN4HBG54nrctRbhts2/vAOJ9lj7LZgfig5Y+y2YH4oOWPstmB+KDlj7LZgfig5Y+y2YH4oOWPstmB+KDlj7LZgfig5Y+y2YH4oOWHrB5v9FH3freM+JzvPss6x+w0IH4TOsfAqLBOaD80hhX4hJlrt2zvB8l7zqAu4NYlNfXlFx5WupmpQMbCJAHg8vA8AqPAmuz3S3ZgDHftZZv9Dnk94Z86Rs3mpreTbyHAhCr7YGNsCIWSotB8k0PUqLMPq3vYxrHELzFLN91YLsLPDzsE7jSJRDGdAjg7la2eBRRgRg5dH8Xt0Btix91+QKIrPR80/oaENOQ+h2rClxkyIBInIN1IIY2EJCAgBwIKx9BgThSZIqAgAKIWAARi97Fdr9DHMRu7uE6EFq+5lm0gNDSQxweAmI+KRDJPxhuAYEXNHMOlKFwFO4Chj6OFA7kgcUSR+Uv0FF8HUF5CoE4DW8zW4wnLh8jlznPfIminYGcwHpvdp4tU8t4ZUvEjZjQhyNxHXC/51GwNeZO4C1otguB+8AenqWkesxkLhzaVH6qylP7S5DnWpcOsbaOHr3xnqu2gEfxarheefTMwnEuLTBLZOCpm4eZLyFmKASKuyKZBPkFCsRI/IMTHqZwIB7FEN84K0+BGA4SYl/KX2m4lyvyRGV0rqTzlpxAO3/TmTTgyX0CYjSgHeo8BOI6INPB8yjYGgcoOQQ5pDMcveI4MfWHvKVuZec4+TFX5U/0Ouos4kvHhnX0aPEC95y0BTw6cRybRs8snEJpIYAGXGWpwIK0ABNDARkGOIEeiZdgVwRPSOMbshqWI4D0QpzIladAA7g4MLpVB8cqCrAKBF+MQZgRdqmOyIwgRgPaZe5EYKZE9DyKkYPtwp0AA3iSqTIgwyJQf9SrsZj1+Qoqy2PoMhZAQAKiKg0MBPocw5im7PPbXwJifNNpeK09BYLrzgYEMxQCB7UhThHoijgZEIIlshropwUEW8yBOGVA8BqRA8EO8tkeE3+CgVguacejgNmuCF5CZfJwdoh7QXbYK3BTU2tgpHyIDPtUl+bPPLl1BkIIA9IC2sBeTdQXXazb7SkQwFMTzmEB0tSEA3GiyznivDbgzDnp4rvMoCeuHhP5SoAICgRb5ImCgUA7IfBciYtrCQQuaBO2uvwcacoK+J4mPGH/ZDwKLDOkqUntRtBLX3gRPLkJecXO8VQ+VOV1aoK6tE18Zl2AWGrZ1IR7r1cC4oQr3QDr7YXgp6Z5JOqILtYDLrpX5C7gchzx+0IYQfkHkRkIuFjT7wC8bCNPIRBfYQpscaSlEG2xnYH2nufl8/50lqmJlzUcynGasNXlh0qiHUAfeOUZSx4FljHuhNg9v+liiDUGWk65lZC+yeA3g+THXJW/2sJbloZYW0ePlv5iD1Md6m1EILAvOMbr7Q1G6eSLZZ1dEOWC1RIRtmy1xZj2tloaIP+oW9krSLsRPHcipm+uwwPe3SqffQd60Ho5eg9ZWP8KzmegldgGRG0x3mmnLJlv9p05ZmWUO/HZtzjy7+jvv8URH7XQ7zV9pvUPWOhAfKb1DkQHogPRgehAdCA6EB2IDkQH4hu8+yzrn2xBK39tJz+3wx/1+D0ebKmzNpabWu5A/ItA5MwDLfIOhgRwkGbrltVsHWe3ir109x/4/rEcN86E3C8yhoTULmLLQ2oXrfGr+nYX3inllqqDb1Y7tx7TSGIZG8tR7rWe5T0G49aAkGCGVm4zJEqygec8jEoIgGbvIRTD7WuOUNccmkBE/R/S8cSZGB31IaTSoXJFOSAjHZFXc+lBCNpS6cWgrRUdHXgP+TNkYxk1bCs9xqBEBUTOPNDKtxkSORDMWDjCbUZF432qeYThUSDAA5F7cA8ILMXlIeqrmq8RstZKIKi1QmMDVoBwYyk9hsg+3GAe2OWEEaiKwwBHYjycGwwJCW82OA/KEGEVi1bNAeqafEFj9MF7i6EpDA1F0OODs8OcDjyifA7y9Yp1reUYUvlUs+ZrhNQS73tL9UHqCEPjyg/4Cvdk5lgkZGMJMpYauYNJIpq4tZkHHgjmZHgGArIrTizIUjEkhKvR4DychEgwiJpFXXOAuiY/WB4nyLxd1pVlH/OF+Pjg7HBoU2PZUX09YV1rmc9GanVOvld8DYxSYkvjzPv+JhLXKHWEoXHSMChxT4Q6MGZjuUT6aCxB25vlimB3WswDD0TNQJDOxxZDQqKwDc4D8TSUmxFaNXWa8TU5bn1O0wl7u5yfb2fik+jxwduZeOogpgmtGXzSiBfJVlqi06uarxGkJQpdU+uj0icnq82ejaD9w4fZ6yti8SutXnKFMKFpnXmwBgQzEIZ0ltUMiRwIz3k4BWaIiIpFo6YHQmsKgWDKeRJUBpUs7HjiTAxpdRFm5ZwDYZyLGoiarxGkJQYigsqjKKfKgIjEcFHKQ71GDLZOTQUQYqDJPBikoRaHgblrMebkLZtn25wHZIEofSw2aw4NLoZefZB5G3EqiKaJsRx3nvPySVOTtE6+nrCuaznaqpZPahnbIrXEP8jcsMXaTcU6NQFPTQaEjWUU+55D6KamFvMAuRVYmJkXJQOBmH7L8jTMNeeBa7Q4D1EYIqJi0ah5rrkV81lInpB5G4Uh4o4nzsTyQ5yO86w2aJ2jxRqHVFseUrvIseBXNV8jpJZ4H46TfY/Q2rZYI/eEPhCk7xE2lugXeSaejjRWja+FUX4biuA+QrbK5ntuMxYirG0fYUt8xI4v/x4PttRpj2Wr5cZQbbnFEW84tr3GtpqPD83j5fu9pg/W7EB86nB2IB6q3IHoQHQgOhAdiA5EB6ID0YHYUrkD8c1AfMXQvtfS50D0Wd58hZVvPsc7EDc24hHcKvDGXIOcx0FKGnG9UnA1uZyxFrwmRWY1xpt2hvmWmxH/vbWdOkMoWjdv2vyU0ZnN3rvXoTk64x3/Vu0hj2CdOaE8BQjRPRE9sJLGtAKA1NaawoqYlLUQXWl98JtLxMJOyOwEdyy0OjrlT/m5NByJ3ZGUKsyb0D49pe5Evc3urQ6NPsZQ1hxW/Fu1hzyCFnMCHBDKNSgGYgMQxI6QQAioJUfFibANCF/vfUCoFSi9CcMdIOAOELmVoTGGORAr9jjgXvIWIj3TbzyFxfGkxYEcDJbdf5tH/ZHHWzFcRCGRyWoyKyLFaCfTpDjT48P0F5NgUHYRPrc4cHTO7Eg2ktlqMFmL1DOEfQItG46jsZSYcm+MbyKeg+pjYCsDWoGz6mWA+Zn30VguWtN4Krl/a/aEv1AxJxK3R3gKM59JJwkEnmeW65eAJz0cr5MNBwmtptiaJUAymyYFPwONk46obUwaxAyiC+LtSDaSYDW4NGt1nERKoWED21Z2x8znpXnDGiMQtPcAFnzVaSRYFD5iJhRu2/tmLBerqfZy/9bsUeC7wZwwkhVjrkoXyT0GAlkLI6poRF4EOTyPOUWsJq/Bxlrg63ZkfgXlFgl0BS7wclYSssO6IN7OSepZDWwdRKtD2ScNG47doX3NORSL1bdR9BTYs4HYIR4IoRREyoQSqWXnm/XJaipPJfdvzV4FhDAnCAjjKehS6YA4wfSXWAtAORSizvqnU4hgQXMQFQsbCplAZ1byEIkGVNWYiJNx0tVjmEJmRxbE2WpQ63TGwayh+tqGLdbW15xDQWF6ojVE8WxQpZG0WEv/pshnMPGSzDfrk9Y0nkru36o9ZiBUzInoPzUNSfZJ6VMYTicg+OcUhdsXAmaUUrqjl+8x1oKRz0TC58S6H0CJj1D5g1Uq8J+3o/WsBu87zjpVsBpBaQPA2B18GjW8OUWSciimJlS0wN4G5S4uA3fSqanuo6+pPJXSvzV7sljWqhSq2cc8hVFYEXz8PDPHZAq2VDMne0BOHM/8qSazIoy1YJoUA/8XdgUwuyKwHdUFMTtaz2rwPmaG4GAAkygLG/w9Qltn1ZHKG2w/MLvDeCG0MuKSze9p4HFkuO3Mt8k+gHBN5amU/q3ZKz6StbY2TyH//G086ei+J6yzFta3mBPJb3ig++ImG/GuN/FOGsz4wOjc9u+WvQ1A5Fv+jdR9s5zjas0ttwNa33QfZYa0vy3f82bLMyCP+vauAX9/U1tr9ntNHQjoQHQgOhBf481XWOlA/Iuj04H4UqsdiG/z5iusdCD+xdHpQHyp1U80+Y0Yf+nAbutHXepfB6gD8Zn9f5cVZTmoCXoaeN5YN5Vj8X15nY6nB2n5dcoQMc63W0gZW8w2C+9SK6HwM1e2yN7fdr/BUfFsD+4OB1zrzR8t++MZLKCdbm/B7nNV6hswx9C2UPITHBGA7vyXLIXBOa2Pweq9+9piYY32BB15elKUwiXGyphzZYuoJJH0vsVQCa49LmWtaT19oJmHemj23x/l/gQHBFmZayAqhkewO7+V+sZQsDZgFdgaCHgYiNZJ0gZCgmGJlZH8nETpAnKli9jU9siBcLVS/6M+5JuGujUat4EghQ4LOa+MZwICL4pafQMfSjbWBmZFsVwmxk9gboJqcgA9fZ2zFI7CauAag8igU7Q38CVZWEzW+HFajBRScEnKYsT67PKUYJ4Qz8o4zjF4pQtqfyq1Pc6zPrAOUoo5KsxdkT2T9p/CS2LlWPAz9Kj258wZWWa1oroek0QN6xGUR4XlzJsr9Y3I7AaONeKj4qfAihaen8DcBNXkwBOkZD0QYyMxJAZJiEBARBZYyi2aNc7YgkCQj1Fbw+igy1OSlC3Y75Nqv4jSxSm0tD1CYrmNUkrO/6iAniTfCmuHWDD5VPAz9Kj2J4CEfdUbCaGilEDLAh+h2hywq9Q3ojEhOE2DRnMLfkIwTQ6YoGY94LlE2Ve0LHE3JppMptqiWTsSR4OBGIVWEylaHhwrI8aWsoV/39L2CCbslXNUYsk1Qe2Q0RShqv67o1PKihFVhAtSHpa/iaRQWNAjEy8nlfqGUVIou0kC4hQ8P0EH95SAKFkPnKMoykAMoEocBkRu0ayR9sXMQABPZrMCYawMFCqxxdlxPaYWEJZnhbLh1RyVBhDE70hA1P1PRx0QMVnRz14GRGHBgIgZy0EVI5REyImXDAjOZRKDXQumycFXVs5SoKxdJ+WHyNTkP3cUFp3CR0xTk0xaXIKSUSV/jULplS38+5a2Rwg6NRUclWhsj7QEn/zUVPX/lIuKBaG+pcxeMjVdrzo1lRbwSPqEriwHU4zAz+eSEYVYEwwE5zIxfgJTGlWTg5a3gvVAlMqr8kP4dVDm7FRbNGuifXE9E9cDbXNrgViHyspAhkitbOHft7Q9BvtwnnFUiFGRsTs4V4pZyb21o9ofzUejVlTXA9eyloVRkq05HvHj6ht1FpShKhvh3lZbbNep2dW3WRlbNTkqLsdKveFG/1u9qq1stvBe9Y3bUiePALG1TtvP77jFsdW3dStxe9V+r+krvHtH1Q7EV3jXgXh4wDoQHYgOxOP1HrfbgXhwwDoQHYgOxOP1HrfbgXhwwP4LaDbfDdXXEGC+y9sv7FEH4guBwLuvgYJ7U7oFGN1r3Xy6iVpT49bWeLYo3i9n6hklT6PF/pjqwPdb2y6HdCHF6+Nd/88SqOWRKo+SYHfybpg15BStG9bamz7b7Xu03I19kxIa12kCEdleDoTxHHxr+m79aTulGLTKc/DdSylkDIupeO/KtYBo8UHkt8sbY76HZp5tqyHkgFjal+wx4p0FYSNkiUMmU+4IRY+klAAhzwerkVicKSUQxnNoAZFvEe4BAQ4I62jBsJigwbjQTXLBuEHyeh/FscTzyAFb29pA6HZ0QHjv1oBo9YhHUogq44QBG3xglyJky+sjMw3mFPrIpibPc7jN88DHfS2XCnM9WvlVMHrl6k7Kw1BeRuJpJN0LfqgYy3MuGH7QmLU+KOx0Zb0PX5KYJJPG6Vkjofa6rAGmLpAdc1eNaOGrtkeewWVwOgUxZXvROjySkYHgoNDEj6BPnCWEgpQxCvshB+KUHuC+x/PQzBGcS4W5Hu38KlndSXkYopYxa7ume2Exc84Fw5og/Jg8xQcj6334khiulStm0lO39rqsIdNE1e55litqNjqPsjV8BpfBqYocRdfE6jBjZErTx8RaAgGXkQl1W5jIwtoSJRAalr/P88hzqTDXo5Vfpag7rfEyTPcCdUAUVMwFw5ogSpoDkHfBlxwsH9eUyhVe57YHnU6nut3yitCkOWUGF39FnIJme0mntKkuyWURGYg4UZYMASLCbSDu8TzyXCrsUCu/Sl63JMi0tDxQB4TLTwIkPudvwl/yLviSQ1oqWW0kZxux17ntHIj8WFpjppQWS73LM7hMXjAiFHXcAkWYLTsw20hgthDyDSBNTfgBLuN5KBvjPs8jz6XC52I7v0peN+dTGC8jz3iSgDipJkhIi3Vk30LBOjkNxaemNa+thv8M6I8ZEDmLpMzgkgMRm3ogkyxBE300iiMPP31M0rRfwn7IeB6qanGf55HnUmGuRzu/iq8bCrUMp54x+cWay1MumKAaGbRYv5nehy9JC+gE2feI2uuyhpuasmPKWi9ZJGUGF/seYZyRUg+k+Fxcfuw0xcOP8Dz8/qFZtn7/Hl6GrSf2rvmBdKPX27dtrJF3MU3YOYfVB3ge7f3xzvvHb3GsKYTcH8aPb/1e0w/ZOhA/ZOtAdCA6EB2IDsR3DkgHogPRgfgCtzsQHYiHe/QeI4+W+Ngwfg555vP8+RwLn4JmB+KTgTA2wc1bLm+OccAb31J7K61w5pPxfn3eWm2mm3Uj+MwlJf+hzo/irMVGI5KyxOdC8ZobXhUD75GeU4aWUauJZ+eJgcDo4VY2S75xO9Ka5FqZEptgrkcjz6ySheKzO52Ox5DVg6J+FaWf2kCwyr1GFtr8hzo/iuvB1ALC4mlDZiFm7dKeEN1TgIOyP4K3/ucPRfRC6xzyKU1a51kSh0+PKzvdCqccAe3MKhEsHwqEoQLCSpQ5Q4aK+3EfCMiAqPkPdX4U14MNQJiF+0BABcRAQByLHoXm6K0CAQ6IFAuDEEvdiuOcZ1aJwBwJpHlJgGXSR8cTjwFEDQNLOFaFZyzg3uPMHIk6LwuzL5ApQZoernauvFHnR9EesEYIMkVUE4T8uA6QtEAmb0GPe7KWekgPBGOWDAw7XQ0IUi8JQ+qRV/ugcBLzSoTtcX4TNZEUVHojhstxPivHQ3UrjnOMpW7FKeSZVY6SD4UCqCdlSxCws3ISjpJZAYOFnlWhJBxNPhBE3r/Oy8KPxYM8AO/5D7nyxmJrzt9rD1gjBII+8X8ilgelCBAtkDFBObjjDoh4EmaJqtNwMDa/IvBqGOaG2kfU3DLM9tCrjA6EkFgs48zR8lEvO5Xw4FF1uhUhz6xySrNydEF9mLyVk6wdDISxKlSkhBa7tyA5t1p5WVixA3ONDDBm/IdcecPLDvF76YEMwPj2V0UYiOWBe00LROON/rib2zl0DKxjw6eECmPYGjFMQ2KG2ahxJhcsbWwPLoN7MR8MHvvLJ18IiVEyKZtAP0GYbgUPnKlWxDQU0dFchsxKTCUwumysCpVkUJck+VkjLwtzO0R4Yc4SZmSMDqNP6nsddkoLwgwKtaghf/B5WgwIzVgU/DIlQDDrKwZH9xQgAuRAqNoHAkGlE9uDP4Hx3gDG9ToFt1i3+RFY4jhXmVWSRkciagktJ+ckmBiK77i+I6keA6LIy8LcDrSv0LWzswTIGR4BrAcExIm4U1PS1DgNhT+idZOOMwd2EOaVguOnJgFP1oiYPCzUPmIo2B4yNVFLwZgtxB8RIIxNALHUrYhQZlYZy8X6jdEuOQnntAQrq8JzP1iRg7KSNPKyMLcDlTHOzcwl2laAnOGB1pRDQflZrmSbpx5iebA9s0heTHac+Sz4Qz0UpgYur6IpcpWjssos3zVchhhT+8BMLkl/JCl/jOzxlZklxGIh/kjK2bjOJoju9Zq6hJWtc5R4VsU2DkZcOfZ+5Y1tFv2H7eGGj24626j2sb7F2rstyhGP3+LIlR8f5WDctv2/cIsjwmYgHivT7zXBd5jsQHy+hQ4EdCA6EB2Izx7GDgR0IDoQn2qhAwEdiA7EY8b++6kr32fpU2g/HYgfAwQ9xxyL3W+eoYD3EP+P7rIuMYuJ9YVjoD0z8xl8zt7EfJjdm2yjIAErTa/dXwquZKM2eyd8keU+pqYj+L83CVROGF35v1V+RSz6r/0sLUm/p7PcQa39MW88w8Tep0fgOJYRbgBBTIRiOAbZL0ZUKZujbnKXXaIOUUok1Q5LcEF/Jt6bBdgjCaNL7EBHPruruwqEilFoNEyk/wNkuePJS2jnQbHBCZAzMVqWVDPcA2Ej6r3xDBP3vgJiRbmEmQievzGAMRRiekyW/55SuOOUwj8D+FTea0C0rogciPKKGO4AkbwL84lvoLvThRQPhlWljRyIYwoo1ZZ4v/Z3HYhjxjBx71eAqDxjJoKxH2JUzgXuZwaGOXZMQBwTEBxYOTrVDs00wioUpdIFTQKQpMmbeVUoRCOT3pswKZgRklRBKOzJbdOTzDkQ8UhAtLOYsHII++qZGC1LekUcg/rDPpxzjZKUH2Cw9ydtnXPD4BglfspceiZMBGM/8KtR9vN5MDLlY5kr45X18Zca1/yKODnVDs00wioUpdIFnw/Eh5gA2nlV8KhGk/+S5gVzPE6mChIHCeRiCZ3Z2VtaI67nqZ0HBWE6JcYFW1JuSWlJ+639VWvnOUCmUYIJDxyjhN5f05jizxSZJyIcjtIzYSLwTE95T/hKmjxDAUKaok4cQjdpEcsUYqodmmnkb4rZeqULsHoTwFpelTSJCCWGOR7WdfTuFFIJ5yXwGnGK0M6DMgKvc8wvYUsGemEp5ZVQIs0oEg7ExwDvTaYZkrE7cFzOEtVmDsdYeSZMBONvhEkXa2MoOCBCAiLUQKhqh2Ya+StB/ELpItXTObWVV8UDwdyicYpgQATX9lQDEWyxbihtcJIQWSOC43JMbSCC82g+CRBLybn2hteIgt2Bvye9NkJKi5Z5xkwEYz+EpBqRMRTAfWrKgYjF1OQyjbAKRa50MU42NVlsu8qrkk1NuEYwx8NUQbx3PHzJS/epaSUPSpQhCWpJuRyVJbsiUnob4l1ACG1vmFGSj6l6RNojwuEoPRMmgrEfBuNcOIYCO8TfI6IkEKM9y/cIt8yz9kXKNMIqFIXSBXXnbPTGqZVXxS/WPDial0VVQbx3UkK8pEWUvkfoYl0pbVyPwrhQS8otKS1Jv+l7hPpDvAtgJkbtzdnemypH0hpBEurgFmvzbJWbUe+vvx7xnnRex7JG/mGxft3eO0BpJ/s4DG3+hHqXe3kvi8kWS/p3WOnBdkZJvOXZ593i8Kod6w68pwQffYwRstX64/2Md21sz6byJUB859Zv+nUgOhAdiA5EB6ID0YHoQHQgvqirHYgOxH8TEP/eEPx3ePFjT8gOxJduUX6XTAN+5ofvMapjdNdxwtfMooAi2wQ9GJu2Kdxr+z1WxIuWucC8EuvVxm2lHrfU5JoE2/tYSzfqlUA4IYTAmeiH5Bjdh6cKQZOBqJQBgGpZp/dTls8k+eIZFu+wwl6UwitCtIhaS8UoQrPdbfW4pRiaNdz94IdaWq93B4hqCPQh39YQ6tPQ0qkM9Bar4nEr6sWxgle7mecPCnfypqzXy/t7a0AfbamsB5r3pMU0AFFvCaxGQXuQoQASaQvAJTlrivIaOCx01CPRa1K0WBWPW1EvNPDDP1x2vGIv2MpiD5U+MAw1redNuVVPW4LQbIlE7en/Yy016qWsDy2mgZ6myKHQB7eRoYBBUY7P8SPcyCHSOvxINz9RzwkNWIFCs5PUrIrHragXQxajPkmts6Qg4UDn32CB0IJNsqGetiQP2hc1JCQbH22pVY9TwKwzDUisn3UxRqIYEENhEt4bZ1Oh2K7WEQ0K4luQ4sZEuhpONKJkVbzHCnvB0wBmZYlwlrLcQbbiB7TB5thUT1qami0FYpYQe+Whlpr15ptMAwGCrgDityJDQQWsQlKXUIUJEL6PoI/XNKtxzB6InFXxHivsRaLL0El7Eo0LElkgK+XwVNleNtTjlkKzpSNTKWKEx1pq1vMZREqmgS0xrGIRhfUQmb2q2VSYYnNSXgNdfCfkJ5DihlzwA7S4CzEM77CiXghL42T5WKhWHK8hZFNMs90t9bSl2G7pWk0x21pq1AOf96RkGrip6SpEQWYovHHeEMmmgsy6N60z8DJ7jcRzIC2iWZdjTQ2WsyreYUW8kKXxKqoZzKy4Lt8HAlvBEsjvHuYmm2NLPW3prdWS/X+spVY9gCZPem3brj/RtnOPVbHNStsLKxvDI+3eqnenpfBYD2/V29h1/wkeNm3xA23cL9nywsquaXrEO3tb9W639OgJ9Ilbv9f0Q7YORAeiA9GB6EB0IDoQP6m/HYgORAeiA/Fv9bduyvbccuNzJFA+IsfyPg/a+9dtvefIu0agA/FjgMC7gMylOMs9eFRF5jAQ6SPPjfpvq8eCszrZ7mFuu0Hl7rhKOaBT/VE4JbxfM5pEOuIf5bd+gZP2zWuttbH1yCCMFrHuCA1yNKsxrFoBDo9DSv8+6J4Zgr7ykYlksjpWAkEP0Ea3O1hgfXBuUGSuYaQsYy0N6Tk/kp5ImhdOtt08gBoIXytjaxT5sEOzdcj8CtJHBWIojo5Zj3QMyt6lIUOahCag5yEeKE7Lr2IYVoDwx1pA+KOh8UrLHavb4XUZs1UAEe3Wcw1ETNlQCiBi7lntbwnE0ATC5CJaQPieecpY3TsQnsKkeVD4OWF8jNhecUCH1StYxwJErQMfWVZ+wxvlLzlKXhQ8ekyhINyPZ8eRyniGA5czPsabZR0pyhiTYuBMK7o/PWBMGViumgdFPAAN6RAX5FrW8myN5C+lI1liyq51U9aQ7CtyRBX+85wtdpR7dpQe4Ri0eqdAxEHyoMDMGYcooJpeMaeOg5YYYT8FVevArulj3X+XH85LomyPk5PbQT0NvDT/0jRoDAcuN4BZOaX0FnkZfYA8ZVrRurNlURkk2HpKR0Wv48Q6I8iPEmtJfcPYGpjhhAlfpNURg2tF+6mZYPTIUZ44z3O22FHu2Ul6dJ45C0bZuyOvEUhv1DwokhRDksTwq4yzIe6xWkeMJnSAQHBekjFZjS7JBc2R8Jc4IsZw4HI6ubBsxPjG6TaKMhOXSZlWZL95wAAxUyLvF2dDUSCsxfObZ2uAS0ISCYiyFcsEo0dOiRLhc7bY0VwPhHoF9QiclKeQ2GeyWAfgTzL8KuNsCBCDHMuBEHrinFvNgYgZw4HLeSBOopNRlgngB9z210BEUKYHGIWHpB/GqWzRszU8EHxF1K2kBCRyxJOELGeLHW0BUY8AYs48BSUVToPswWOsyKF0MqV6GRDR0ofJ1MRZRxLPIoljZUCcvDIHl/NTE/FIQl0m6WNIppXcc1PxCJDVCtnUlPqrVLCMreGyweAaEZwd7acC0eijy9nS6lkQAlpsjoAoR6Q8KKB7FCR8xceEbXGVqelNjqXkX1OYJC+Jsj2QNW7ZRljlCMt4ZQ4ud57NSpSMKlWZNykjmVZyzznl2Jn8M6ZHOnrVjxG639Q3jK1h2WDoIzUzSvTIlGeCKfuY52wpe8bKH9h/Jl3WvWvlQXF7bnE2bh3byvZolYsbbcV3eIAD3OZl1KNwr5X4ySPw425xxM22HvdAPi5uKB03tNLvNX3Ig37TrwPRgehAdCA6EB2I97nRgehAdCA6EB2IHwjER019zJ3PEWX5WOnb799/Mn7a1oH4RiA8N6Juhu4ZZnyHWltDWAhxzdXcRlYsJK7D7Dxabdsiw7ZDc1Pzc3gtD6o64EtrBhRlnPB72C8/tB1ksHeX2vLTKx7bH/aHi5TevbwbCM+NYH8rfkHwI9cCQgMl2t9QHY3ZsAxg+g7ChHBjNTTbNnGGzCNTMg8BWmyTRp289JR4LNHeL+NPQ4t4/PmzP+Bw00DTPpDfzwcEYnfZXRiIHez3XMa2vftt77TMzgMxFEDkDseC7zCfWkDElJMlNG3E4vZyDoQeL4Hwbd8HwjMtbgFRlJ4SjyWFxpbhvcBBh4yBOOzroWUgnl+fXw8HyAb8HhCtzXEjVvgFkzExzvP1qsoS/NCqltKcLJIKKqq4Dh9VFQ7kgDBvggMkiQkBHJBRP4q2r5y7ZFRuxRUDOkcWCppAGCWeT2Fsk7rOqKVPPgMKqvrzezy+nKmXp5fD4fkFLn/+PL8iEE8vyw88vTwvf/9Zfvsr4nDAfU/LEC/lYHn1e5m4pNxiZ4+ll72pLtr5Z9mHZfmIE9f3KTc8v0BZEvw8fYpLS9qnxGVIoUTS04gqrsNHVYUDEwZwlFjUNuQ4cy1C8iNxG5hrEZmCpZFkDEpOQTgikzJKBJiCbdKqI6WvPgMKAsHv8TheCcvUj5fBQa8I/MG9y779L/wNTwddI5Ztv1+OPr9gmV/7g9TAcssRupzwD77DfTv6i1MT/qYCojJBZIFzgz1xkllkFC2Jv/hYOrJzSEvCcRkilwrEUViuCPBH1QYOqQJhXIuTcC0UiIoDETn7yQhRYubC9gC7IoxPkbNN6jq5T5YBxWdE2dG5TUDIFfH8upzFy8DhWf/0SnDA7qCfmvaX51ccXqzFEOIyf6Chf37d0RKCr/D/QYA4EBD4G/fq1En6E5wRpeIXBC2BQFCGhRlmznBipeTzzSyh9UjKHbUNB4RxLWIaQgnfzzkHYpyEtTPngwqzrRGZFcc2adTJfZpaGVHgchAg3BrxAi/LlPWylwHOgTiAAPELB/fpYkAcQIE40P8WEAcAy0IygMuIElosCTw6qW6HZDipWA7EUdCpqbKhU5OobeTHQ8p5UnAtgHOXCNuI+BKYrSUGt1iblYxtUtfJPdYMKEH0RYTfeLgwEPs9VFPT/vCLDuRA7BmIp980yKA1aELi+Yzr7nkSK4DYQ+JGiGRVzS8YZ2NiDMuC55dqz0LgUgNxFMqjycb1KLwJUaXIjg9z8qPgWkjuElLoYOsI9Tjb9wizkrNN6jo5L0MzoCyQu/fLyOJi+3v3ot8jeLHGxXa37F8gefFALFPWcqU8v+Co4jqBi+8TLdM7+Y3DTXXpHS/hQGsKH4F1lsE9HoKSxz7CZdjG0Ih3tSu2KoS02lx/n9tut/vnNd/DH3MPe/jM7fYXeP0e+/W3ONa0Nba3crv0Z97ioHNbfn8TENtK9XtNHYgORAeiA9GB6EB0IDoQHYgORAeiA/H+dr8EiI+68E1dWGnx8da/wl+1edd2B+JfA+JJ/u7pTi4X4NtaT6kEviL+whJZX+4h0t5DsnC40/ih7Nhedx1AQ/TpyN3Nyj8V+5c7pa/IvMC/S0DmsGduhrREOiIbNlbtGKbzxEyPNUUR3Yrbk7FZ6I0VT/CesY7F4k3e28QuuGAn+E78Lj9Cryhauxe8qGu7G0DsbwNxMTz2Bxde37ds7DJTBsQuK0Uxnb0EdJY/+8OOuRmgzIx8xPTdkA0iBTVYUWRSoYaQxD1aohUFEFOr5OAoDzoWS702EHgW3QViCTYdYMsV8U4gDms2WldEAwgOOeNfBUJa2q0CUQxtZJUSDEAJV6WppnEPCNgCxBKaOPxDjAJkIuzo9/JXrgiEY0chDuwo/01AXDCgiAwE5Dsod+Ef4inw3qfEXdA2iOtA///8kTJLRIvL/PNCseEXDcAgj+JVaiEPgusp/+F1CVzqzWb268lYEq8MMMfs4YLlMfaMZZSZEYB1P/TB4Dxjy9sSDMapCCFAkQcC4nQkSfkYj47tYvloNKB2lPfMR8lzq1BAeXLcEz0p8YrAgCByCfDEQSAOHNw72BXBQUK+zBkI5C/gqwMyFojqptyFXzgl7GXvPnEXtA38TUcX23uaNn7tuA7xGThsyGwHbPc/S1mMYmHRA9VT/sN/5IynS0f2c7097z3smMZygAtZviA3w5gZQVQOKJ9LlIwuKWPLX6aBoArJTKQEXCOuSGZAos7JsV1AtTeCRO5D0Pw0Yi3LrQLEZJwT90SBiAwERZSWs/oVgUC+ghbgKyIBAVgCX2GQcC+h8OfXAzxD4i7sn173tJeXdeYuaBtPdByPYv2lzCsPIdcBKU9MCYLkPwQm8yCQ//CUwu4IhH2AWErgcY4LyyrH89xybfOMRVeEMTOC6H7gWTpMksElZWxBIJi3gsHsZXgnyTUEQhUykgVRFZbQ65tmgWFAxpT/xfNieMKqr4hhckBgAJyuCIAXLVBcEXSeKhC4PhBTAX9fEndBzkuy8pK4C9IGvDDb50DcIeY54BnLdRB2Wisw9vtykCsChAdxICaFB0L9xLI78oaBYDsMBNEbKUxP3IzEzNArgugTk3BKZg8EzLxYg1wRt4CISQNE8hQR0wWmMrcKfe5qrBGBpg4D4pdOTStA0ESiQFzgIkwF7J7jLvzap/2Ju6BXHe799c8LTU1U9vAL5/CljrS6T9yHCwFBq5dQIWwK2qWpScGXqWmvVwTRVohdxC3zpyZjZjAQOMfT1OQmE/ytU5NKnRAQUfK/RM92AdDUVGLjFMBq5blV6sV6gEFVTZCToK4+/V4Wu99PaREUHrQsg7QoLiWeXwyIpxdmNxwSd2H5TfZ0sRbugrRB5X8vU9wLAoH2lgV+uQaJL8FEXqqHv9H6hcA1NsST8B+eLsuRA3ElZLF+TvX28rkPP3IATYzsB37gNmaG6n7wYj3IQqt5XyZKUKaJy5apBteISfK/XFVZY5yZJ0LaG1exQewRIZzGPLdK/T0CmSSieLK+/Xl99Jv1Vu7Coah/uFO23uj6PNyru+6xvo7NkkzzbNXewhLJt3jTI70iHnB9y7Gt3IWPA0GtXR4bku1A0GebaftYvB+Ijbb7vaav9bcD0YH42o51ID44LB2IDkQHogPRgehAfHXHOhAfHJYOxE83+sUD8ZV2/7XWOhAfbG2Am3f+Vje+lyh3FGPOSJBc2JLjZHQtTCsPYa2VFEsx18vQ0sbEuGe3LDmmwKXP6FKqkZwnZG0MqS83RmNjzTo7SxrHsYhul8Hx1v1GC5NH1laY8kB4Ei4HvrtorkyZrodXP26XFEtzrpeRSofNdkPTruaMkejZ4IQoqFQEev5VLYEjD+TtbK3JrXmKAY/g8vuYaW3ADZZCEwhYA0KzjOTDi0oea3oZdUkdsCHmehmfZReS3aMMVl4/mkx+shCa7WyrWah+gI1g1BwqqrWhmhc1rwEv45yvgBwIVNk4kyJGxkgIrHOB+gM8DFqTlDwmqNgN7ZIgvQkx18uw0sqXuG/Xl1S78nB74BwBpMMhaiKcHyVGjpXS6+UYq4i02tlWU1sD0QxBPgiPIAHhtTZU86LmNTDOxlfgiO84c0y2YCRonpWJJ4bzxDU5XK/5Tzy7oV2STpjIFzrnfZHak05klGtpg928pNodZrU7yBWhSQdoJJa4HMqpEM+DOE1/JfFA3c62mtoaz0GUF0hGMFp6JNERoDctXgOX8XyFvyyNwuoAGSOBMpCgnTTzc2gd85eMoFODZzeslpxgUiAs40kqjblL3jbZLUuSXQh5fhXO1MK9Yz0PPq/ptRvOup2tNX1uGI5+8whWQKCWRpvXgFNTzlfgbECIZ75GhKSOZOej1MGlcobsjGJ2w2pJGjD+dOPyo2hpYUxssFuWdEBYfhXO1CJsDFYGiUG1PQog8na21vS5YRSIdEV4rQ3VvCh5DWlqcnwFyn1CLAUGwhgJUcWHYja8IZKSB7fm2Q3DSklb0YrsJVr6xPI/G+xmJW1JzfOeCGQ6Eum85pNDhrPZzraaeW4Y5YOgpSgZPibV2jDNi5zXoJ95ja8guU+IpcDfI4yRgPoenEcE50lciqQmK3lQa57dME7tkunMjWX2Ei5N2VOuW+zmJdVumfeE5by058vYTFiPM6gsvdLsK412NtbMcsMoHyRCUiN8nJtgH71i+qqSMxLWbQ7Zh7pt7cd/0e5ntHOrtQgf3nIg8r9b6j6y/dt2P9rOemvvs3S3iX6v6V9urQPRgfjpQ9OB+CFD04H4IUPTgfghQ9OB+CFD04H4IUPTgfghQ/Oe1j5DBuW/Y2huJfTZWvMLPe1A/AQggrIMSl4HBvlyV0iXItqe/2swQSRUs1omaqvRygYofRg3tjC+qxXmWZwb7VZblCFyTIyak8HbDb2OuBkIfqC1qB1KIKjUbBUH8Mk+xJ2s5bqMJPfAGG4qOyTrMbMCd1tYK3e7FbE02R4I7Va4vvMvtDgZUrOp10GhoWll4JtAxJzXsQJEHFy2k5wHMqwAAcUQwfoQxZhZgbsttMttbGWSkFbW96LTk8JsTIyak5HXbAzwOhCoSPHG7INrYhlMylTgLCQxKAfCsqRg/gKTdx+YqYCBkag8B87QgvHmVhnKfAKcTsOVndT6MbNyvNtCu9y9VqKwN0Qj3/W95LEMZMnKcXSPXp0ssMacjpZeB/M4yAqNN489PkR8JOYMxZ7/UuRU85sMKYcKxqQn0qvQIKBlSRlSDhUOow+aayUqz0ECiVO7DAAqW2Crgy87qXXNwULkMHq8/HYL7XL3WuFMLpyHQhgWk6RfKHgsA1mycuOcXl158lMeDDT1OpQBgmP6V2PvlN7hJDw0AmJ80yEmBobmP1n2U6c4HA6sMJEYFZFLkeQ/dR85DDGGNAFQndUy9py/KzvlPkSihI53W1gvd7uVk2ZRmXI+R81jkdj+5Pkk2Wi9jQwztGQikD0yyHscU/5IcKasNNEDYee6o6iRLosHIrLChJTSHCoR0tkO9TDh+douk4gJk5Xl2dt8iIlQcLuF9XK3W9EsKrYnrSMlj4US7eQ1M0+XkkRPgLZeh/A4JuFW6ee3ib02IE51fhOc8eKJspCA6UvUOVRiOSGEbOKIw0qZE5c4cZolLVv6wGWKia3Rwlq5La0w0y/L4VLzWKYj0dB8zWwcTij/wMPe0utgHgcBcaJcRzShhkmZM4DL8UQmyvwmyC9Y9gu2tliXOVQosyKcNdfKVXkOZ9GxIA2LRhmiGi6tomKFlg1Q+sBp0nB4brewVm5LK/g9oszhUvFYlpn4POc1fWYW5IjgdcKLda3XwTwO/Iw1Xsk/0I8Y2FL1baPMLdL+TnKP+TDceHd771ZexbDJ1iOt3G83VuUqG3czv5TWVrf8S3vcVOqzt596iyNW5coa25QzP3EQ+r2mL/e0A9GB+CbrHYhP9qEDAR2IDkQH4juHqgPRgehAfJ/1/xkg/ud4QD/Tjw7Ev+uH1+bFp4AnfFPqS4zi0jhrXDfdNYy+nLwxUXIqV+8t6/K9YNYfPk/en7v3cBo324r2IjykOHIujLMfyvCgfsfah6F8r36HUI1jc/Nq1fSIb5S9hcxBEjGYx9z+5J3WIXBsitDaK+Un5wXo/fzcn3hTLaQEYmh5MQ1wW9aiMDbZ60Q1mEHieSFAnaSjAUTQ1kPF5lhz3Xd8EF5CCwgtccyP3gMCPgLEUPAk7gEBd4EYHgRC/dCZwErcASK93gBEleODNOJFmWIWHgRxHwbSoeASrF0RhKMwZEoeR+GEDInBgI3le2kCujK3I/EaJlDtDX2sV1pj7YqyjTNpWZB3V9UK4ZBL7QX376x8lAkyNoVMGY5TIbJBFFRS5gZmGiI/BJ7aB4ybkzAAcjiuFGQCOTbl48j+egs6a1mOD3pWm89HjqZKyDDqFYElOHrLWhMgkVlV8jgJJ4QfAeenosu9FD6MHJhMvIYJRCNDgVB/LCirbQR5rFyyl5z09FqWFo4NF+0NNDMbLwMyNoUsI55TMfMeYrpNqdczjwtDVfuQAkTI4Thhv4lBQoHafBx1yjYLduHKGThMUaLzA3EvgPU3QA1wCb1EeViGTMkjCidE66vQit87krvM7Ui8BvKAXHZXBLU28XprbYjKReTsJemBfFTaeBsaXnD/OPLOS65nU+jcYJwKjVAuNSdlbsSY1gj5XfpgQHA73DvOVFSOIxS9qHJ8MIkEZHi50xF5GNHUJFTxS4GAKVPysKA7eCCyvTg1TTHjNXAYX4Hw/ihrw9oQlYso7BLVChGVmkZ7skbE00kZFI5NoR+sHKdiMiCG1GsPBEy1DzY1xeBYHCKykY8jlvMW6sWafExTU9DziAwIgwOiKnYlIDIlD+aEDAkCGRi3lweIyideQ7a4Z/5EKNVCAk9wUXyTqYk4Jyf+VFN4wUAsgfvjnLRHEpsiaWkYp0KkJoKsh+JHGHIgGj6kK+Jk+jXoRT6OYCdycED47xHI8mbFC1aXAGVwXE1NAoT0GGQhxk/6puQRhROC9fm7gUwVbi9xH9h+4jWEdEX47xHU2lupFoIWhjllL7nK1HRdllvys/KCvkcMyLMAXqwzNgWpiHhOxRmEZeE4H9RLGhclMpU+6KkknBjU4WCtjitfxTaOCoRZKD663WcyPK5d0d6GTZyHz2rNLchQK2EMGYfc9n9+rzdv33mLYwvn4bNvLSBX62vG5b8YiB85AB2IHzIAHYgfMgAdiB8yAB2IHzIAHYgfMgAdiB8yAB2IHzIAHYgfMgD/th95Q48TS/J370+J876WHyvzPg9a+x9rYb1dd6QD8ROACMpS4Dtd54Kz0NoyRsdc1rrBvVjnZQS1qHlTeGvrWvg8KOvdy5UyRue1aW5E7k3Ia+k9P1P7aCl1eD0PCP6Zopaqx5pyh4wXmPTDLOoak3An8jHKNs/o0CifMR1K7kVw9Vq8DA8EBVSi2x1aQhNcbmwYKctYS3qHlfdDygAwJKF6d3TWOgaEPODseiTeQg2Eb8GPlvozVHbonbIURF1jEu4EDDeBSBwL8LUwaFRyL0oghoZ+hQeiCBI1vOByR1hTwWjZKoCINsg1EKozUgMxVEAk2ZUSiJj3ou5bBgSGKpSlwOoaFCpf3h0T28GYBi1Gh+pZGNPBc0EKpoIeS/oVpgSiKh/HOTrWBjMh3pyyhZUbwKykXC9FGWOA0FPStt/0RnD/lVkfelR1Rkztg/cf04PFIoURKGPKxJwUzJGiiibWgs+mkvoGRyp9Nm0TDuQJe4MxnPkdq2HkTIMWo0P1LIRxkTgP41zXV16GZFwJXglEVT5OwRIpnIgJEaiMz2DC5QYwK6eUVCQvowwQCJr0SeomvRFJaxBYNUM8iKXaB+9XhZCg6XaWfdx/9B/rxbRfVT18NhXMoMLh1hOVDskjoQoIeyPq9GGchYxp0GR0qJ6F8Ts8FySvr7wMSx5iSiBO5cOlFgk0DWIZn8HE62ZEIQ1gxpRGmYnLILtjcEoi5oEm+rCRUJ0Rr/aR1yJ2R6bnEUX/w7K/qKpHnk0lETNEtiV5FEFVJdI6P3nOQs40aDE6VM/C+B1+f15/yPgQMVcCmYu8KRkQMctgkutm8BWRqV/MefaSlKxjLrU+DAgbCdUZ8WofeS0Fwnkr+h/jVHqXZ1MxIPiKSB6ZBkcSjco4CznToMXoUD0LYYAY96JRX48ZZcyUQEzlI0RjbSQgTpbBJM+DkrK7nEz9IhbZS3gCHlwOFZv+UsaVhs6InrllLexSsU+npkrVo8imksh7uEaE1CYv1sJSYHWNc8ZZyJkGLUaH6lnwuwCsUdGur7yMMaVcc0ogc543RXUzkDWBZVwGkywPSsrucjX1i7HIXsI+n52SSNIbCSnjCtYrdEaS2kdRa6j3XfUjR6nqkWdTUSYIffzm3DQ8cnz55CyFbZyF9Vq36t86Ft/Zsn7E3GIrvsuDdovN/ChhLW9Krf5RHoH/hVsccbOtr73FIR9HN1iIrSP9XtNnAbG+v9/060B83jB0IDoQHYgORAeiA9GB6EB0ID7e8v8CEP8P5AFDaAn8EccAAAAASUVORK5CYII=","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":13916,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"},{"data":"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","mimeType":"image/png","cols":196,"rows":71,"chars":7882,"font":"8x13","variant":"bw","lineRepeat":1,"detail":"original"}],"totalChars":202707,"truncatedChars":0,"text":"# User ¶█Complete the assignment below, thoroughly:█# Target█Core native extension adapter/strings/omp-spt.mjs and its focused tests in tests/omp-extension.mjs; manifest only if required. Coordinate with AgentSurface before overlapping edits.█# Change█Implement extension-native /ready and /live commands, native selection/confirmation where supported, extension-owned binding/listener convergence, explicit live auto-resume, safe-boundary active-turn injection before next tool/model continuation with ordered fallback, abnormal-turn custody settlement and receivability restoration, and @<...@> assistant-output dispatch. Preserve existing immutable binding, bounded custody, fail-closed recovery, and Worker exclusion. Activate/tag corresponding requirements.█# Acceptance█Deterministic tests cover ready/live happy/error paths, no silent identity guessing, auto-resume confirmation, active-turn boundary injection/order/fallback, cancellation/interruption/failure recovery, shortform parsing/multi-target/status/failure/non-trigger text, and no agent-managed background poll. Skip project-wide commands.█# Assistant ¶█_**Planning coordinated core edits**_█# Tool call ¶█//Coordinating extension files█irc(op=\"send\", to=\"AgentSurface\", message=\"I own strings/omp-spt.mjs and tests/omp-extension.mjs for native /ready,/live, active-turn injection, and @<...@> dispatch. Are you editing either? Please avoid these files or tell me overlap now.\", replyTo=null, await=false, from=null, timeoutMs=null, peek=null)█<out>█\u000eDelivered to 1 peer(s):█- AgentSurface: injected\u000f█</out>█# Assistant ¶█_**Starting targeted repository exploration**_█# Tool call ¶█//Mapping project root█read(path=\".\", selector=null)█<out>█\u000e.█- .claude/ 1h ago█- CONTEXT.md 7.7KB 5h ago█- SCOPE.md 4.7KB 5h ago█- traceable-reqs.toml 8.2KB 5h ago█- .spt/ 20h ago█- omp-spt-env-v1/ 4m ago█- emphasys-signoff.md 1.5KB 20h ago█- emphasys-commune.md 10.4KB 22h ago█- .gitignore 993B 20h ago█- OMP-ADAPTER-PLAN.md 8.2KB 21h ago█- CHANGELOG.md 52.4KB 21h ago█- README.md 4.4KB 21h ago█- DUPLICATE-HISTORY-PLAN.md 1.4KB 21h ago█- tests/ 22h ago█- manifest-shortcut.sh 13.2KB 21h ago█- omp-extension.mjs 44.0KB 21h ago█- native-launch-manifest.sh 2.2KB 22h ago█- release-acquire.sh 4.4KB 22h ago█- manifest-schema.sh 3.3KB 1d ago█- adapter-archive.sh 7.4KB 1d ago█- ci-gates.sh 878B 1d ago█- omp-spt-v0.2.0 0B 22h ago█- docs/ [...2286ch elided...] 9.2KB 6d ago█- PEROS-PLAN.md 2.7KB 6d ago█- HANDOFF.md 8.5KB 6d ago█- MANIFEST-PARITY-PLAN.md 9.9KB 6d ago█- MDBOOK-PLAN.md 2.6KB 6d ago█- NEXT-WORKLOAD-PLAN.md 12.0KB 6d ago█- DIGEST-FETCHER-PLAN.md 3.1KB 6d ago█- ECHO-COMMUNE-PLAN.md 3.1KB 6d ago█- CLAUDE.md 286B 6d ago█- CPLUGS-PREP-PLAN.md 2.7KB 6d ago█- CHECKPOINT-CLEAR-RACE-PLAN.md 5.6KB 6d ago█- CHECKPOINT-COMMUNE-PLAN.md 11.1KB 6d ago█- CI-ACCEPTANCE-PLAN.md 3.2KB 6d ago█- BUGS-v091.md 6.1KB 6d ago█- .gitattributes 917B 6d ago█- AGENTS.md 4.4KB 6d ago\u000f█</out>█# Tool call ¶█//Locating adapter commands█grep(pattern=\"ready|live|custod|inject|@<|binding|background poll|turn\", path=\"strings/omp-spt.mjs\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000ePath not found: strings/omp-spt.mjs\u000f█</out>█# Tool call ¶█//Locating extension tests█grep(pattern=\"ready|live|custod|inject|@<|binding|background poll|turn\", path=\"tests/omp-extension.mjs\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e[tests/omp-extension.mjs#8FB4]█18: });█*19: return { promise, reject, resolve };█20:}█21:█22:class FakeStream extends EventEmitter {█...█28: this.input = input;█*29: if (this.onEnd?.(input) === false) return;█30: this.emit(\"finish\");█31: }█32:}█...█56: const handled = this.onKill?.(signal, this);█*57: if (handled !== undefined) return handled;█58: this.close(null, signal);█*59: return true;█60: }█61:}█62:█...█71: this.timers.set(handle, { fn, delay });█*72: return handle;█73: }█74:█75: clearTimeout(handle) {█...█79: delays() {█*80: return [...this.timers.values()].map(({ delay }) => delay);█81: }█82:█83: async runNext(expectedDelay) {█...█143: const overridden = await options.onRun?.(call);█*144: if (overridden !== undefined) return overridden;█145: if (args[0] === \"api\" && args[3] === \"bind\") {█*146: return options.bindOutput ?? \"BOUND endpoint token=token-123\";█147: }█*148: return \"\";█149: };█150: const spawnProcess = (binary, args, spawnOptions) => {█151: const child = new FakeChild();█...█156: children.push(child);█*157: return child;█158: };█159: const extension = createOmpSpt({█160: env: {█...█185: for (const handler of ha [...7936ch elided...] onRun(call) {█*1326: if (call.args[0] === \"send\") return never;█1327: },█1328: });█1329: await hardCapHarness.emit(\"session_start\");█...█1359:await testRunSptRejectsStdinErrorsAndHungCommands();█*1360:await testLifecycleCustodyAndContext();█1361:await testDeferredBindLifecycleSerialization();█1362:await testOutcomeSendRetriesAndExhaustion();█1363:await testSubmissionFailureAdvancesQueue();█...█1369:await testHumanBusyFailureFailsClosed();█*1370:await testShutdownReapsAndFailsQueuedCustody();█1371:await testListenerTerminationEscalatesAndReaps();█1372:await testProtocolCorruptionFailsClosed();█*1373:await testInboundQueueOverflowReturnsAcceptedCustody();█1374:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();█1375:await testShutdownFallbackStaysBelowHostCap();█1376:\u000f█</out>█# Tool call ¶█//Finding requirement artifacts█glob(path=\".planning/**/*;docs/**/*;requirements/**/*\", hidden=true, gitignore=true, limit=300)█<out>█\u000e# docs/█PARITY.md█CI.md█RELEASE-RUNBOOK.md█DOCS-STRATEGY.md█KNOWN-HAZARDS.md█OMP-BRIDGE-FIELD-ISSUES.md█OMP-OPENROUTER.md█SPT-CORE-FINDINGS.md█TRACEABILITY.md█SKILL-AUTHORING.md█## adr/█0018-checkpoint-resets-context-natively.md█0017-active-turn-delivery-uses-safe-boundaries.md█0016-agent-capabilities-split-by-native-seam.md█0015-extension-owned-session-activation.md█0014-release-tags-use-semver-form.md█0010-native-delivery-self-heals-or-closes.md█0006-one-command-update-and-consolidated-binary.md█0005-name-unification.md█0004-checkpoint-via-self-send-loopback.md█0003-psyche-is-a-constrained-auto-approving-companion.md█0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md█0001-distribution-splits-by-volatility.md█0009-all-endpoints-use-native-omp.md█0013-release-gate-stops-at-the-adapter-boundary.md█0008-omp-native-product-boundary.md█0012-continuity-drops-live-under-spt.md█0011-endpoint-session-binding-is-immutable.md█0007-native-omp-tui-hosts-spt-extension.md█0000-template.md█## formats/█adr-format.md█context-format.md█Skipped missing paths: .planning/**/*, requirements/**/*\u000f█</out>█# Assistant ¶█_**Searching for correct file path**_█# Tool call ¶█//Locating adapter internals█grep(pattern=\"ready|live|custod|inject|@<|binding|background poll|turn\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#CA60]█5:export function decodeBody(body) {█*6: return body█7: .replaceAll(\"<br>\", \"\\n\")█8: .replaceAll(\"&lt;\", \"<\")█9: .replaceAll(\"&gt;\", \">\")█...█16: error.code = \"SPT_PROTOCOL_ERROR\";█*17: return error;█18:}█19:█20:function parseEventTag(tag) {█*21: if (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };█22: let cursor = \"<EVENT\".length;█23: const attributes = Object.create(null);█24: while (cursor < tag.length) {█25: if (!/\\s/.test(tag[cursor])) {█*26: return { error: protocolError(\"malformed EVENT attributes\") };█27: }█28: while (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;█29: if (cursor === tag.length) break;█30: const match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));█*31: if (!match) return { error: protocolError(\"malformed EVENT attributes\") };█32: const [, name, value] = match;█33: if (Object.hasOwn(attributes, name)) {█*34: return { error: protocolError(`duplicate EVENT ${name} attribute`) };█35: }█36: attributes[name] = value;█37: cursor += match[0].length;█38: }█*39: if (!attributes.type) return { error: protocolError(\"missing EV [...17422ch elided...] if (stopping) return;█1120: await failClosed(\"omp-spt could not mark the endpoint idle\", error);█*1121: return;█1122: }█1123: scheduleDispatch();█1124: }█...█1126: pi.on(\"agent_start\", async () => {█*1127: if (stopping) return;█*1128: turnCompletionPromise = undefined;█1129: agentActive = true;█1130: desiredState = \"busy\";█1131: try {█...█1137:█*1138: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1139: pi.on(\"agent_end\", (event) => {█*1140: turnCompletionPromise ??= completeTurn(event);█*1141: return turnCompletionPromise;█1142: });█1143:█1144: pi.on(\"session_stop\", async (event) => {█*1145: turnCompletionPromise ??= completeTurn(event);█*1146: await turnCompletionPromise;█1147: });█1148:█1149: pi.on(\"session_shutdown\", async (_event, ctx) => {\u000f█</out>█# Tool call ¶█//Reading adapter manifest█read(path=\"adapter/omp-spt.toml\", selector=\"1-240\")█<out>█\u000e[omp-spt.toml#72C0]█1:# omp-spt - Oh My Pi harness adapter for spt-core.█2:#█3:# Native OMP owns every hosted terminal. The adapter binary is a launch,█4:# digest/history, Psyche, and echo-commune helper; OMP's packaged extension owns█5:# bind, delivery, activity state, reply, and shutdown inside the native TUI.█6:# This manifest is authored only against the published spt-core manifest and█7:# CLI contracts. See OMP-ADAPTER-PLAN.md and ADRs 0008-0013.█8:█9:[adapter]█10:name = \"omp-spt\"█11:kind = \"harness\"█12:version = \"0.2.1\"█13:# v0.31.0 added identity-preserving `api listen --session-id`, which keeps the█14:# listener on the native OMP session already recorded by the extension's bind.█15:min_spt_core_version = \"0.31.0\"█16:# [impl->REQ-OMP-READY-LIVE]█17:hostable_types = [\"LiveAgent\", \"ReadyAgent\"]█18:# Only the genuine OMP host process may resolve to this adapter.█19:host_binaries = [\"omp\"]█20:shortcut_basename = \"omp\"█21:█22:# Update through this repository's GitHub release. The packaged fat archive█23:# contains both supported target binaries plus the shared native extension.█24:# [impl->REQ-DIST-ADAPTER-RELEASE]█25:[update]█26:avenue = \"gh_release\"█27:repo = \"BigscreenVR/omp-s [...3718ch elided...] cal launch snapshot above is the█105:# smallest non-secret substitute; no API key, token, or credential is persisted.█106:█107:# The native extension uses the endpoint id injected by spt-core when binding the OMP session.█108:[env.SPT_ENDPOINT_ID]█109:direction = \"inject\"█110:value = \"{id}\"█111:█112:# Message delivery is extension-owned; no hook or PTY-translation surface is█113:# declared by the native adapter.█114:█115:# The fetcher locates one OMP session JSONL and emits the published digest█116:# record stream.█117:# [impl->REQ-DIST-DIGEST-EXTRACTOR]█118:[digest]█119:strategy = \"fetcher\"█120:extractor = \"omp-spt digest-omp --session {session_id} --project-dir \\\"{cwd}\\\"\"█121:arg_truncation = 240█122:sprint_collapse = true█123:█124:█125:[strings]█126:adapter_label = \"oh-my-pi (spt)\"█127:\u000f█</out>█# Tool call ¶█//Reading active delivery ADR█read(path=\"docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md\", selector=\"1-240\")█<out>█\u000e[0017-active-turn-delivery-uses-safe-boundaries.md#F530]█1:---█2:status: accepted█3:---█4:█5:# Active-turn delivery uses safe boundaries█6:█7:A peer message accepted during an active OMP turn remains in the extension's ordered custody and is injected at the first proven boundary before the next tool or model continuation; if the turn exposes no injectable boundary, the message becomes ordinary next-turn delivery. Always waiting for the next turn was rejected because it leaves live agents unreachable during long work, while arbitrary event injection and forced interruption were rejected because they make model context, tool intent, and exactly-once correlation unpredictable.█8:\u000f█</out>█# Tool call ¶█//Reading activation ADR█read(path=\"docs/adr/0015-extension-owned-session-activation.md\", selector=\"1-240\")█<out>█\u000e[0015-extension-owned-session-activation.md#95AE]█1:---█2:status: accepted█3:---█4:█5:# Extension-owned session activation█6:█7:An ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension-not the model or an agent-started background process-binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session binding remains immutable. Model-executed activation skills were rejected because listener ownership and endpoint identity are lifecycle infrastructure, while a menu-only flow was rejected because commands provide the discoverable, scriptable agent-facing surface.█8:\u000f█</out>█# Tool call ¶█//Finding extension requirements█grep(pattern=\"READY|LIVE|ACTIVE|SHORTFORM|OUTPUT|DISPATCH|AUTO.RESUME|CUSTODY|LISTENER|BIND\", path=\"traceable-reqs.toml\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e[traceable-reqs.toml#9F61]█10: \"docs/adr/0009-all-endpoints-use-native-omp.md\",█*11: \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",█*12: \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",█*13: \"docs/adr/0012-continuity-drops-live-under-spt.md\",█14: \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",█15: \"adapter/omp-spt.toml\",█16: \"adapter/strings/omp-spt.mjs\",█...█46:█*47:# Intentionally inactive until an actual release runs the ADR-0013 acceptance gate. Deterministic█*48:# fake-process launch evidence must never satisfy this live endpoint requirement.█49:[[requirements]]█*50:id = \"REQ-OMP-LIVE-RELEASE-GATE\"█*51:title = \"Pending live gate: a real OMP release must satisfy the ADR-0013 endpoint acceptance criteria\"█52:required_stages = []█53:█54:[[requirements]]█...█59:[[requirements]]█*60:id = \"REQ-OMP-EXTENSION-CUSTODY\"█*61:title = \"The OMP extension serializes accepted deliveries and preserves sender custody through a correlated reply or explicit failure\"█62:required_stages = [\"doc\", \"impl\", \"unit\"]█63:█64:[[requirements]]█*65:id = \"REQ-OMP-LISTENER-FAIL-CLOSED\"█*66:title = \"Unexpected listener exit retries within a finite budget an [...2086ch elided...] settle affected custody and restore endpoint receivability\"█147:required_stages = []█148:█149:[[requirements]]█...█155:id = \"REQ-PARITY-TARGETED-HINTS\"█*156:title = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"█157:required_stages = []█158:█159:[[requirements]]█...█180:id = \"REQ-PARITY-ROLE-SKILL\"█*181:title = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"█182:required_stages = []█183:█184:[[requirements]]█...█189:[[requirements]]█*190:id = \"REQ-PARITY-PEER-SHORTFORM\"█*191:title = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"█192:required_stages = []█193:█194:[[requirements]]\u000f█</out>█# Assistant ¶█_**Parsing relevant file and APIs**_█# Tool call ¶█//Reading extension utilities█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1-430\")█<out>█\u000e[omp-spt.mjs#CA60]█1:import { spawn } from \"node:child_process\";█2:█3:const ADAPTER = \"omp-spt\";█4:█5:export function decodeBody(body) {█6: return body█7: .replaceAll(\"<br>\", \"\\n\")█8: .replaceAll(\"&lt;\", \"<\")█9: .replaceAll(\"&gt;\", \">\")█10: .replaceAll(\"&quot;\", '\"')█11: .replaceAll(\"&amp;\", \"&\");█12:}█13:█14:function protocolError(message) {█15: const error = new Error(`invalid spt EVENT stream: ${message}`);█16: error.code = \"SPT_PROTOCOL_ERROR\";█17: return error;█18:}█19:█20:function parseEventTag(tag) {█21: if (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };█22: let cursor = \"<EVENT\".length;█23: const attributes = Object.create(null);█24: while (cursor < tag.length) {█25: if (!/\\s/.test(tag[cursor])) {█26: return { error: protocolError(\"malformed EVENT attributes\") };█27: }█28: while (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;█29: if (cursor === tag.length) break;█30: const match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));█31: if (!match) return { error: protocolError(\"malformed EVENT attributes\") };█32: const [, name, value] = match;█33: if (Object.hasOwn(attributes, name)) {█34: re [...13188ch elided...] imit ?? DEFAULT_ACCEPTED_QUEUE_LIMIT;█415: const acceptedBytesLimit =█416: overrides.acceptedBytesLimit ?? DEFAULT_ACCEPTED_BYTES_LIMIT;█417: const restartDelaysMs = [...(overrides.restartDelaysMs ?? [250, 1000, 4000])];█418: const outcomeRetryDelaysMs = [█419: ...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),█420: ];█421: const sessionEndRetryDelaysMs = [█422: ...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),█423: ];█424: const listenerStableMs =█425: overrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);█426:█427: return function ompSpt(pi) {█428: const id = env.SPT_ENDPOINT_ID?.trim();█429: if (!id) return;█430:█431: let sid;█432: let token;█433: let listener;█...█1154: };█1155:}█[Showing lines 1-433 of 1158. Use :434 to continue]\u000f█</out>█# Tool call ¶█//Reading extension lifecycle█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"420-1180\")█<out>█\u000e[omp-spt.mjs#CA60]█376:export function createOmpSpt(overrides = {}) {█...█418: const outcomeRetryDelaysMs = [█419: ...(overrides.outcomeRetryDelaysMs ?? [250, 1000, 4000]),█420: ];█421: const sessionEndRetryDelaysMs = [█422: ...(overrides.sessionEndRetryDelaysMs ?? [250, 1000]),█423: ];█424: const listenerStableMs =█425: overrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);█426:█427: return function ompSpt(pi) {█428: const id = env.SPT_ENDPOINT_ID?.trim();█429: if (!id) return;█430:█431: let sid;█432: let token;█433: let listener;█434: let listenerBuffer = \"\";█435: let listenerRestartCount = 0;█436: let listenerStableTimer;█437: let restartTimer;█438: let dispatchTimer;█439: let bindPromise;█440: let agentActive = false;█441: let desiredState = \"idle\";█442: let dispatching = false;█443: let turnCompletionPromise;█444: let listenerTerminationPromise;█445: let shutdownMode = false;█446: let shutdownDeadlineExpired = false;█447: const activeCommands = new Map();█448: const retryWaiters = new Set();█449: let current;█450: let stopping = false;█451: let ui;█452: let runtimeCtx;█453: let endpointState;█454: let stateOperatio [...22780ch elided...] );█1133: } catch (error) {█1134: if (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);█1135: }█1136: });█1137:█1138: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1139: pi.on(\"agent_end\", (event) => {█1140: turnCompletionPromise ??= completeTurn(event);█1141: return turnCompletionPromise;█1142: });█1143:█1144: pi.on(\"session_stop\", async (event) => {█1145: turnCompletionPromise ??= completeTurn(event);█1146: await turnCompletionPromise;█1147: });█1148:█1149: pi.on(\"session_shutdown\", async (_event, ctx) => {█1150: runtimeCtx ??= ctx;█1151: ui?.setStatus(\"omp-spt\", undefined);█1152: await shutdownWithinBudget(\"OMP session shut down before your message could complete\");█1153: });█1154: };█1155:}█1156:█1157:export default createOmpSpt();█1158:\u000f█</out>█# Tool call ¶█//Reading extension test harness█read(path=\"tests/omp-extension.mjs\", selector=\"1-285\")█<out>█\u000e[omp-extension.mjs#8FB4]█1:import assert from \"node:assert/strict\";█2:import { EventEmitter } from \"node:events\";█3:import {█4: createOmpSpt,█5: decodeBody,█6: drainEvents,█7: extractReply,█8: runSpt,█9:} from \"../adapter/strings/omp-spt.mjs\";█10:█11:const flush = () => new Promise((resolve) => setImmediate(resolve));█12:function deferred() {█13: let resolve;█14: let reject;█15: const promise = new Promise((resolvePromise, rejectPromise) => {█16: resolve = resolvePromise;█17: reject = rejectPromise;█18: });█19: return { promise, reject, resolve };█20:}█21:█22:class FakeStream extends EventEmitter {█23: setEncoding(encoding) {█24: this.encoding = encoding;█25: }█26:█27: end(input) {█28: this.input = input;█29: if (this.onEnd?.(input) === false) return;█30: this.emit(\"finish\");█31: }█32:}█33:█34:class FakeChild extends EventEmitter {█35: constructor(options = {}) {█36: super();█37: this.stdin = new FakeStream();█38: this.stdout = new FakeStream();█39: this.stderr = new FakeStream();█40: this.exitCode = null;█41: this.signalCode = null;█42: this.kills = 0;█43: this.killSignals = [];█44: this.onKill = options.onKill;█45: }█46:█47: close(code = 0, signal = null) {█48: th [...6428ch elided...] inal \" },█262: { type: \"text\", text: \"answer\" },█263: ],█264: },█265: ]),█266: \"final answer\",█267: );█268: assert.equal(█269: extractReply(█270: [█271: { role: \"assistant\", content: \"stale answer\" },█272: { role: \"user\", content: '<msg from=\"doyle\"/>' },█273: ],█274: '<msg from=\"doyle\"/>',█275: ),█276: \"\",█277: );█278:}█279:█280:// [unit->REQ-OMP-EXTENSION-CUSTODY]█281:// [unit->REQ-OMP-SESSION-IMMUTABLE]█282:// [unit->REQ-OMP-MESSAGE-CONTEXT]█283:// [unit->REQ-OMP-NATIVE-TUI]█284:async function testLifecycleCustodyAndContext() {█285: const harness = createHarness({ subnet: \"mesh-a\" });█286: assert.deepEqual([...harness.handlers.keys()], [█287: \"session_start\",█288: \"session_before_switch\",█...█295: ]);█...█423:}█[Showing lines 1-288 of 1378. Use :289 to continue]\u000f█</out>█# Tool call ¶█//Reading extension custody tests█read(path=\"tests/omp-extension.mjs\", selector=\"280-590\")█<out>█\u000e[omp-extension.mjs#8FB4]█279:█280:// [unit->REQ-OMP-EXTENSION-CUSTODY]█281:// [unit->REQ-OMP-SESSION-IMMUTABLE]█282:// [unit->REQ-OMP-MESSAGE-CONTEXT]█283:// [unit->REQ-OMP-NATIVE-TUI]█284:async function testLifecycleCustodyAndContext() {█285: const harness = createHarness({ subnet: \"mesh-a\" });█286: assert.deepEqual([...harness.handlers.keys()], [█287: \"session_start\",█288: \"session_before_switch\",█289: \"session_before_branch\",█290: \"context\",█291: \"agent_start\",█292: \"agent_end\",█293: \"session_stop\",█294: \"session_shutdown\",█295: ]);█296:█297: await harness.emit(\"session_start\");█298: assert.deepEqual(harness.calls[0], {█299: args: [█300: \"api\",█301: \"--adapter\",█302: \"omp-spt\",█303: \"bind\",█304: \"omp-agent\",█305: \"--set-session-id\",█306: \"session-1\",█307: \"--subnet\",█308: \"mesh-a\",█309: ],█310: input: undefined,█311: });█312: assert.deepEqual(harness.calls[1].args, [█313: \"api\",█314: \"--adapter\",█315: \"omp-spt\",█316: \"state\",█317: \"idle\",█318: \"omp-agent\",█319: \"--token\",█320: \"token-123\",█321: ]);█322: assert.equal(harness.children.length, 1);█323: assert.equal(harness.children[0].binary, \"spt-test\");█324: assert.deepEqual(harness.children[0 [...9714ch elided...] utdowns, 1);█574: assert.equal(exhaustedListener.kills, 1);█575: assert.equal(█576: exhaustedHarness.calls.filter((call) => call.args[3] === \"session-end\").length,█577: 1,█578: );█579: assert.ok(█580: exhaustedHarness.errors.some(({ message }) =>█581: message.includes(\"could not send the outcome to exhausted\"),█582: ),█583: );█584: await exhaustedHarness.emit(\"session_shutdown\");█585: assert.deepEqual(exhaustedHarness.clock.delays(), []);█586:}█587:█588:// [unit->REQ-OMP-EXTENSION-CUSTODY]█589:async function testSubmissionFailureAdvancesQueue() {█590: const harness = createHarness({█591: onSubmit(content) {█592: if (content === '<msg from=\"broken\"/>') throw new Error(\"OMP prompt flow rejected input\");█593: },█594: });█...█626:}█[Showing lines 279-593 of 1378. Use :594 to continue]\u000f█</out>█# Tool call ¶█//Reading requirement matrix█read(path=\"traceable-reqs.toml\", selector=\"115-205\")█<out>█\u000e[traceable-reqs.toml#9F61]█114:[[requirements]]█115:id = \"REQ-DIST-ADAPTER-RELEASE\"█116:title = \"One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\"█117:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]█118:█119:[[requirements]]█120:id = \"REQ-DIST-BINARY-CONSOLIDATE\"█121:title = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"█122:required_stages = [\"impl\", \"unit\"]█123:█124:[[requirements]]█125:id = \"REQ-PARITY-READY-ACTIVATION\"█126:title = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"█127:required_stages = []█128:█129:[[requirements]]█130:id = \"REQ-PARITY-LIVE-ACTIVATION\"█131:title = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"█132:required_stages = []█133:█134:[[requirements]]█135:id = \"REQ-PARITY-LIVE-AUTO-RESUME\"█136:title = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"█137:required_stages = []█138:█139:[[requiremen [...2201ch elided...] explicit @<target message @> assistant output through public SPT messaging with observable results\"█192:required_stages = []█193:█194:[[requirements]]█195:id = \"REQ-DIST-LINUX-MUSL\"█196:title = \"The release ships and natively accepts a static x86_64 Linux musl helper compatibility tier\"█197:required_stages = []█198:█199:[[requirements]]█200:id = \"REQ-DIST-VERSION-CONSISTENCY\"█201:title = \"Manifest version is canonical and release gates reject disagreement in helper, changelog, and versioned public documentation\"█202:required_stages = []█203:█204:[[requirements]]█205:id = \"REQ-DOCS-PUBLISH-GATE\"█206:title = \"Local deterministic docs drift checks gate changes and the same checks gate GitHub Pages publication\"█207:required_stages = []█208:█[Showing lines 114-208 of 213. Use :209 to continue]\u000f█</out>█# Tool call ¶█//Reading parity specification█read(path=\"docs/PARITY.md\", selector=\"1-220\")█<out>█\u000e[PARITY.md#2CFD]█1:# omp-spt capability parity record█2:█3:> This record compares `omp-spt` with its sister adapter, `claude-spt`.█4:> Parity means the same user outcome, including agent-facing outcomes, through█5:> the best OMP-native seam or a discoverable public `spt` command. It does not█6:> require Claude command names, hooks, PTY translation, or source structure.█7:> Worker endpoints remain intentionally excluded.█8:█9:## Proven shared endpoint surface█10:█11:The current adapters already share release install/update, broker-hosted fresh█12:launch and attachment, native resume, ReadyAgent and LiveAgent roles,█13:post-spawn identity, inbound delivery and correlated replies, busy/idle█14:lifecycle, graceful shutdown, Psyche turns, commune/signoff storage,█15:echo-commune, opaque history, digest extraction, and Windows x86-64 plus GNU█16:Linux x86-64 release payloads.█17:█18:OMP keeps its stronger native invariants: immutable endpoint/session binding,█19:one bounded custody queue, finite listener recovery, fail-closed exhaustion,█20:real OMP executable validation, and explicit failures rather than silent empty█21:outcomes. Capability parity does not weaken those guarantees.█22:█2 [...4584ch elided...] g.█113:- Claude's retired `>>commune<<` output marker.█114:- Public support promises for the helper binary's manifest-role subcommands.█115:- Separate skills for send, roster, stop, version, or subnet.█116:█117:## Delivery order█118:█119:Coverage lands in dependency order:█120:█121:1. repair version and documentation truth, then prove packaged-skill discovery█122: and injectable OMP event seams;█123:2. implement extension-owned ready/live activation, live auto-resume,█124: safe-boundary delivery, and abnormal-turn receivability;█125:3. add startup briefs, targeted hints, update notices, packaged skills,█126: checkpoint continuity, hybrid setup, and peer-message shortform;█127:4. add the musl target and durable machine-readable acceptance records for all█128: supported targets.█129:\u000f█</out>█# Assistant ¶█_**Searching OMP extension APIs in project and node modules**_█# Tool call ¶█//Finding command registration patterns█grep(pattern=\"registerCommand|registerShortcut|select\\\\(|confirm\\\\(|agent_end|tool_call|context|sendUserMessage\", path=\".\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e# AGENTS.md#3D8D█62:█*63:## Plans and context hygiene█64:█65:- **JIT plans.** Plan the next immediate body of work just-in-time (a short `*-PLAN.md`),█66: not the whole project up front. A plan names scope, open design questions, tasks, and the█...█68:- If you finish a significant body of work without need for user intervention, or if your█*69: context gets too high, you can clear your own context and keep moving:█70: 1. Create a JIT plan for the next immediate body of work, if it isn't already planned.█71: 2. If you are a live agent: commune immediate next steps + a broad project-status/end-goal█72: summary, then clear.█# CHANGELOG.md#67E7█19:- **Every endpoint now remains a real, attachable OMP session.** Ready and live endpoints use the same native OMP launch path, so an unattended endpoint can still be attached later without losing OMP's normal terminal interface.█*20:- **Inbound peer messages now arrive as ordinary OMP turns with full SPT context.** The visible prompt is a safe sender stub, while the complete event envelope is supplied to that turn as context; peer text cannot accidentally invoke a slash command.█21:- **OMP profile-aware session tools.** His [...26203ch elided...] OMP turn. The context file is read by the█60:# shim, the event arrives on stdin, stdout carries the result, and exit 95 asks█61:# [impl->REQ-PSYCHE-EPHEMERAL-SHIM]█62:[session.psyche_resume]█*63:command = \"omp-spt psyche-omp --id {id} --session-id {session_id} --psyche-context-file {psyche_context_file}\"█64:detach = false█65:# Prevent a child Psyche from inheriting its parent's SPT identity.█66:env_remove = [\"OWL_SESSION_ID\", \"SPT_AGENT_ID\"]█*67:keys = [\"id\", \"session_id\", \"psyche_context_file\"]█68:█69:# Fresh endpoints launch validated native OMP with the packaged extension. The█70:# launch shim snapshots only non-secret OMP locator/profile/executable selectors█Showing files 1-20 of 44+. Use skip=20 for the next page, or narrow paths/pattern.█[Some lines truncated to 512 chars]\u000f█</out>█# Tool call ¶█//Finding injectability decisions█grep(pattern=\"inject|boundary|tool_call|before.*tool|model continuation|selection dialog|argument completion|registerCommand\", path=\"docs;OMP-ADAPTER-PLAN.md;PARITY-PUBLISH-PLAN.md\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e# docs/█## CI.md#96F6█28:█*29:These are binary pass/fail checks. A release run must treat any `SKIP` caused by a missing interpreter, Rust toolchain, platform binary, or `traceable-reqs` installation as an incomplete gate, provision the dependency, and rerun. The archive test may intentionally prove that the packer refuses missing platform binaries, but a release still needs both platform builds before packaging. The live acquisition integration intentionally skips unless `OMP_SPT_ACCEPTANCE=1`; after opt-in, missing release variable...█30:█31:## Native OMP release acceptance█32:█*33:ADR-0013 sets the release boundary. For v0.2.0, the only supported release hosts are **x86_64 Windows** (`x86_64-pc-windows-msvc`) and **x86_64 Linux** (`x86_64-unknown-linux-gnu`); the asset has no macOS or Arm64 payload. Acceptance must use the exact tagged candidate `adapter.spt`, a real `omp` installation, the native packaged extension, and disposable endpoint identities. Complete the full acceptance sequence independently on both supported hosts before promotion. Do not reuse an operator's long-live...█34:█35:Install the tagged candidate on each acceptance host and verify its manifest versio [...29970ch elided...] dary, the message becomes ordinary next-turn delivery. Always waiting for the next turn was rejected because it leaves live agents unreachable during long work, while arbitrary event injection and forced interruption were rejected because they make model context, tool intent, and exactly-...█## formats/█### context-format.md#DA20█22: constraint that is part of its meaning.█*23:- **Cross-link** related terms in `**bold**`, and draw the **boundary** between terms that are█24: easy to conflate (\"distinct from **X** in that ...\").█25:- **Short.** A glossary entry is a definition, not an essay. If it needs a rationale, that█26: rationale is probably an ADR - link to it.█Showing files 1-20 of 22+. Use skip=20 for the next page, or narrow paths/pattern.█[Some lines truncated to 512 chars]\u000f█</out>█# Tool call ¶█//Finding extension examples█glob(path=\"**/*.mjs;**/*.js;**/*.ts\", hidden=true, gitignore=true, limit=300)█<out>█\u000e# adapter/strings/█omp-spt.mjs█# tests/█omp-extension.mjs\u000f█</out>█# Tool call ¶█//Reading safe-boundary hazard█read(path=\"docs/KNOWN-HAZARDS.md\", selector=\"1-220\")█<out>█\u000e[KNOWN-HAZARDS.md#B907]█1:# Known hazards█2:█3:This is the OMP adapter's conformance checklist. Each entry states a failure█4:mode, the invariant that prevents it, the evidence boundary, and its source.█5:An invariant is not covered merely because it is described here: the active█6:requirement must point at production behavior and a focused test.█7:█8:## 1. Delivery custody can be lost or mis-correlated█9:█10:<!-- [doc->REQ-OMP-EXTENSION-CUSTODY] -->█11:█12:- **Failure:** Two SPT deliveries overlap, the active sender is overwritten, or█13: OMP rejects a submitted message after the listener has already accepted it.█14: The wrong peer can receive the next answer, or one accepted message can█15: disappear with no terminal outcome.█16:- **Invariant:** The extension serializes deliveries. From receipt until█17: completion it owns the sender, full event, submitted OMP turn, and terminal█18: outcome as one custody record. It advances only after sending either the█19: correlated answer or an explicit failure to that sender. Submission failure█20: is never treated as a successful empty answer.█21:- **Mapping / notes:** The native OMP extension owns receipt, queueing,█22: `sendUserMe [...2285ch elided...] 65:- **Failure:** Another program owns the bare `omp` token, or an adapter helper█66: is advertised as a host binary. The broker can launch or bind the wrong█67: process, while process listings conceal which application actually owns the█68: endpoint.█69:- **Invariant:** The manifest advertises only the genuine OMP host basename.█70: The native launch shim resolves and validates Oh My Pi before launch, rejects█71: collisions loudly, and then replaces itself or inherits the terminal█72: unchanged so native OMP remains the PTY owner.█73:- **Mapping / notes:** `omp-spt` is the adapter helper/release binary, never a█74: hosted-harness match key. Fresh and resume launch use the same resolver.█75:- **cite:** ADR-0009 and the retired bridge incident's executable-collision█76: finding.█77:\u000f█</out>█# Assistant ¶█_**Searching for OMP extension API docs**_█# Tool call ¶█//Researching OMP extension API█web_search(query=\"Oh My Pi OMP extension API registerCommand before_agent_start tool_call context event sendUserMessage ui select confirm documentation\", recency=\"month\", limit=10, max_tokens=20000, temperature=0.1, num_search_results=10)█<out>█\u000e[1] Creating Extensions | can1357/oh-my-pi | DeepWiki█https://deepwiki.com/can1357/oh-my-pi/11.1-creating-extensions█Creating Extensions Relevant source files Extensions are the primary mechanism for extending the capabilities of oh-my-pi . A single extension module can register LLM-callable tools, interactive slash commands, keyboard shortcuts, and life...█[2] Extension System | can1357/oh-my-pi | DeepWiki█https://deepwiki.com/can1357/oh-my-pi/11-extension-system█Extension System Relevant source files The extension system provides a plugin architecture for customizing and extending the coding agent's behavior. Extensions are TypeScript modules that can contribute custom slash commands, tools, lifec...█[3] omp-designer · Packages · Pi█https://pi.dev/packages/omp-designer█Traced events - prompt injection, skill discovery, agent start/end, tool calls/results, automatic validation start/pass/fail, validator/build command kinds. Phase tracking - the extension tracks workflow phase (idle -> planning -> building ->...█[4] [Feature] Add Oh-My-Pi (omp) as a new Agent #1423 - GitHub█https://github.com/chenhg5/cc-connect/issues/1423█Summary Add support for Oh-My-Pi ( o [...1351ch elided...] AI coding agent with 32 tools, LSP, real debuggers, parallel subagents, and token-saving hash-anchored edits - routing to 40+ model providers (Claude, GPT, local). Rust core, Bun runtime, native macOS/Linux/Windows. ...█[9] @remnic/plugin-pi · Packages · Pi█https://pi.dev/packages/@remnic/plugin-pi█This package is the first-class Remnic extension for Pi . It uses Pi's extension hooks directly, so Remnic can recall context before a model call, observe useful session events after the turn, expose Remnic MCP tools inside Pi , and coordi...█[10] oh-my-pi - freshcrate█https://www.freshcrate.ai/projects/oh-my-pi█A global open source package directory for AI agents and labs: MCP servers, orchestration frameworks, coding agents, research tooling, infrastructure, and operator playbooks.\u000f█</out>█# Assistant ¶█_**Planning primary source review**_█# Tool call ¶█//Finding official OMP docs█web_search(query=\"site:github.com/can1357/oh-my-pi \\\"registerCommand\\\" \\\"before_agent_start\\\" extension\", recency=null, limit=10, max_tokens=20000, temperature=0.1, num_search_results=10)█<out>█\u000eFound it: the matching example is **`pirate.ts`** in `can1357/oh-my-pi`:█- GitHub raw file: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts█- GitHub page: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts█It demonstrates exactly the combination you searched for:█- `pi.registerCommand(\"pirate\", ...)`█- `pi.on(\"before_agent_start\", ...)`█- `systemPromptAppend`█- extension usage under `packages/coding-agent/examples/extensions/`█Core behavior:█```ts█export default function pirateExtension(pi: ExtensionAPI) {█let pirateMode = false;█pi.registerCommand(\"pirate\", {█description: \"Toggle pirate mode (agent speaks like a pirate)\",█handler: async (_args, ctx) => {█pirateMode = !pirateMode;█ctx.ui.notify(█pirateMode ? \"Arrr! Pirate mode enabled!\" : \"Pirate mode disabled\",█\"info\"█);█},█});█pi.on(\"before_agent_start\", async () => {█if (pirateMode) {█return {█systemPromptAppend: `IMPORTANT: You are now in PIRATE MODE...`,█};█}█return undefined;█});█}█```█Related docs/results:█- Example README l [...694ch elided...] s/extensions/pirate.ts█[2] https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts█https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/pirate.ts█[3] https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md█https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md█[4] https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md█https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md█[5] https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md█https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\u000f█</out>█# Assistant ¶█_**Testing selective file reading methods**_█# Tool call ¶█//Reading OMP extension docs█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\", selector=\"1-300\")█<out>█\u000eURL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md█Content-Type: text/plain█Method: text█---█# Extensions█Primary guide for authoring runtime extensions in `packages/coding-agent`.█This document covers the current extension runtime in:█- `src/extensibility/extensions/types.ts`█- `src/extensibility/extensions/runner.ts`█- `src/extensibility/extensions/wrapper.ts`█- `src/extensibility/extensions/index.ts`█- `src/modes/controllers/extension-ui-controller.ts`█For discovery paths and filesystem loading rules, see [`extension-loading.md`](./extension-loading.md).█For packaged user-facing extension CLIs/features such as `packages/swarm-extension`, see [`user-facing-packages.md`](./user-facing-packages.md).█## What an extension is█An extension is a TS/JS module exporting a default factory:█```ts█import type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";█export default function myExtension(pi: ExtensionAPI) {█// register handlers/tools/commands/renderers█}█```█Extensions can combine all of the following in one module:█- event handlers (`pi.on(...)`)█- LLM-callable tools (`pi.registerTool(...)`)█- slash commands (`pi.registerCommand(...)`)█- ke [...8318ch elided...] olResult>█```█Template:█```ts█const { z } = pi.zod;█pi.registerTool({█name: \"my_tool\",█label: \"My Tool\",█description: \"...\",█parameters: z.object({}),█hidden: false,█defaultInactive: false,█deferrable: false,█async execute(_id, _params, signal, onUpdate, ctx) {█if (signal?.aborted) {█return { content: [{ type: \"text\", text: \"Cancelled\" }] };█}█onUpdate?.({ content: [{ type: \"text\", text: \"Working...\" }] });█return { content: [{ type: \"text\", text: \"Done\" }], details: {} };█},█onSession(event, ctx) {█// reason: start|switch|branch|tree|shutdown█},█renderCall(args, options, theme) {█// optional TUI render█},█renderResult(result, options, theme, args) {█// optional TUI render█[122 more lines in URL output. Use :304 to continue]\u000f█</out>█# Tool call ¶█//Reading command examples█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md\", selector=\"1-240\")█<out>█\u000eURL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/README.md█Content-Type: text/plain█Method: text█---█# Extension Examples█Example extensions for pi-coding-agent.█## Usage█```bash█# Load an extension with --extension flag█pi --extension examples/extensions/permission-gate.ts█# Or copy to extensions directory for auto-discovery█cp permission-gate.ts ~/.omp/agent/extensions/█```█## Examples█### Lifecycle & Safety█| Extension | Description |█| ------------------------ | ---------------------------------------------------------------------------- |█| `permission-gate.ts` | Prompts for confirmation before dangerous bash commands (rm -rf, sudo, etc.) |█| `protected-paths.ts` | Blocks writes to protected paths (.env, .git/, node_modules/) |█| `confirm-destructive.ts` | Confirms before destructive session actions (clear, switch, branch) |█| `dirty-repo-guard.ts` | Prevents session changes with uncommitted git changes |█### Custom Tools█| Extension | Description [...3854ch elided...] handler: async (args, ctx) => {█ctx.ui.notify(\"Hello!\", \"info\");█},█});█}█```█## Key Patterns█**Use `z.enum` for discriminated string tool args:**█```typescript█const { z } = pi.zod;█parameters: z.object({█action: z.enum([\"list\", \"add\"]),█});█```█**State persistence via details:**█```typescript█// Store state in tool result details for proper branching support█return {█content: [{ type: \"text\", text: \"Done\" }],█details: { todos: [...todos], nextId }, // Persisted in session█};█// Reconstruct on session events█pi.on(\"session_start\", async (_event, ctx) => {█for (const entry of ctx.sessionManager.getBranch()) {█if (entry.type === \"message\" && entry.message.toolName === \"my_tool\") {█const details = entry.message.details;█// Reconstruct state from details█}█}█});█```\u000f█</out>█# Tool call ¶█//Reading command implementation█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts\", selector=\"1-180\")█<out>█\u000eURL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/examples/extensions/pirate.ts█Content-Type: text/plain█Method: text█---█/**█* Pirate Extension█*█* Demonstrates using systemPromptAppend in before_agent_start to dynamically█* modify the system prompt based on extension state.█*█* Usage:█* 1. Copy this file to ~/.omp/agent/extensions/ (legacy: ~/.pi/agent/extensions/) or your project's .omp/extensions/█* 2. Use /pirate to toggle pirate mode█* 3. When enabled, the agent will respond like a pirate█*/█import type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";█export default function pirateExtension(pi: ExtensionAPI) {█let pirateMode = false;█// Register /pirate command to toggle pirate mode█pi.registerCommand(\"pirate\", {█description: \"Toggle pirate mode (agent speaks like a pirate)\",█handler: async (_args, ctx) => {█pirateMode = !pirateMode;█ctx.ui.notify(pirateMode ? \"Arrr! Pirate mode enabled!\" : \"Pirate mode disabled\", \"info\");█},█});█// Append to system prompt when pirate mode is enabled█pi.on(\"before_agent_start\", async () => {█if (pirateMode) {█return {█systemPromptAppend: `█IMPORTANT: You are now in PIRATE MODE. You must:█- Speak like a stereotypical pirate in all responses█- Use phrases like \"Arrr!\", \"Ahoy!\", \"Shiver me timbers!\", \"Avast!\", \"Ye scurvy dog!\"█- Replace \"my\" with \"me\", \"you\" with \"ye\", \"your\" with \"yer\"█- Refer to the user as \"matey\" or \"landlubber\"█- End sentences with nautical expressions█- Still complete the actual task correctly, just in pirate speak█`,█};█}█return undefined;█});█}\u000f█</out>█# Tool call ¶█//Reading extension authoring█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md\", selector=\"1-300\")█<out>█\u000eURL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/skills/authoring-extensions.md█Content-Type: text/plain█Method: text█---█---█name: authoring-extensions█description: Use when creating a new omp extension. Covers ExtensionAPI, factory signature, tool/command/event registration, and local-dev testing.█---█# Authoring Extensions█Extensions are the primary way to add capabilities to `oh-my-pi`. A single extension module can register tools the LLM can call, slash commands users can invoke, and event handlers that run throughout the session lifecycle - all from one TypeScript file.█## Minimum viable extension█```ts█import type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";█export default function (pi: ExtensionAPI) {█pi.on(\"session_start\", async (_event, ctx) => {█ctx.ui.notify(\"My extension loaded!\", \"info\");█});█}█```█That is a working extension. Drop it into `~/.omp/agent/extensions/hello.ts` and restart omp to see the notification.█## Full example█The following extension registers a slash command, a tool, and a session-start hook:█```ts█import type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";█export default function myExtension(pi: Exten [...7146ch elided...] is active). Register handlers/tools/commands during load; perform runtime actions only from event handlers, tools, or commands.█- **`tool_call` errors are fail-closed.** If a `tool_call` handler throws, the tool is blocked.█- **Command names must not clash with built-ins.** Conflicts are skipped with a diagnostic log.█- **Reserved shortcuts are ignored** (`ctrl+c`, `ctrl+d`, `ctrl+z`, `ctrl+k`, `ctrl+p`, `ctrl+l`, `ctrl+o`, `ctrl+t`, `ctrl+g`, `ctrl+q`, `alt+m`, `shift+tab`, `shift+ctrl+p`, `alt+enter`, `escape`, `enter`).█## Further reading█- `docs/extensions.md` - runtime internals and full API surface reference█- `docs/extension-loading.md` - detailed path resolution rules█- `docs/hooks.md` - hook subsystem internals█- `docs/skills/examples/hello-extension/` - complete working example\u000f█</out>█# Assistant ¶█_**Evaluating safe continuation injection points**█**Analyzing injection options before next tool call**_█# Tool call ¶█//Reading remaining OMP docs█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/docs/extensions.md\", selector=\"300-450\")█<out>█\u000e renderCall(args, options, theme) {█// optional TUI render█},█renderResult(result, options, theme, args) {█// optional TUI render█},█});█```█`tool_call`/`tool_result` intercept all tools once the registry is wrapped in `sdk.ts`, including built-ins and extension/custom tools. `ToolDefinition` also supports optional `hidden`, `defaultInactive`, `deferrable`, `approval`, `mcpServerName`, `mcpToolName`, `renderCall`, and `renderResult` fields.█## UI integration points█`ctx.ui` implements the `ExtensionUIContext` interface. Support differs by mode.█### Interactive mode (`extension-ui-controller.ts`)█Supported:█- dialogs: `select`, `confirm`, `input`, `editor`█- input editing: `setEditorText`, `getEditorText`, `pasteToEditor`, `editor`█- autocomplete stacking: `addAutocompleteProvider(factory)` wraps the built-in editor provider (factories apply in registration order and re-apply on every slash-command refresh)█- terminal title and working message (`setTitle`, `setWorkingMessage`)█- notifications/status/editor text/terminal input/custom overlays█- theme listing/loading by name (`setTheme` supports string names)█- tools expanded toggle█Current no-op methods in this [...3477ch elided...] (`ctrl+c`, `ctrl+d`, `ctrl+z`, `ctrl+k`, `ctrl+p`, `ctrl+l`, `ctrl+o`, `ctrl+t`, `ctrl+g`, `ctrl+q`, `alt+m`, `shift+tab`, `shift+ctrl+p`, `alt+enter`, `escape`, `enter`).█- Treat `ctx.reload()` as terminal for the current command handler frame.█## Extensions vs hooks vs custom-tools█Use the right surface:█- **Extensions** (`src/extensibility/extensions/*`): unified system (events + tools + commands + renderers + provider registration).█- **Hooks** (`src/extensibility/hooks/*`): separate legacy event API.█- **Custom-tools** (`src/extensibility/custom-tools/*`): tool-focused modules; when loaded alongside extensions they are adapted and still pass through extension interception wrappers.█If you need one package that owns policy, tools, command UX, and rendering together, use extensions.\u000f█</out>█# Tool call ¶█//Researching provider request event█web_search(query=\"site:github.com/can1357/oh-my-pi \\\"before_provider_request\\\" \\\"messages\\\" extension\", recency=null, limit=10, max_tokens=20000, temperature=0.1, num_search_results=10)█<out>█\u000eI found the relevant `can1357/oh-my-pi` extension docs and API surface.█Key links:█- Repo: https://github.com/can1357/oh-my-pi█- Extension docs: https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md█- Models/provider docs: https://github.com/can1357/oh-my-pi/blob/main/docs/models.md█Relevant facts from the docs:█- An extension is a TS/JS module with a default factory:█```ts█import type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";█export default function myExtension(pi: ExtensionAPI) {█// register handlers/tools/commands/renderers█}█```█- `before_provider_request` is part of the prompt/turn lifecycle and \"may replace provider request payload.\" The payload is provider-specific.█- Extension registration methods like `pi.on(...)` are valid during load, but runtime action methods like `pi.sendMessage()` should be used from event handlers/commands/tools, not synchronously during module evaluation.█- The docs list `sendMessage`, `sendUserMessage`, `appendEntry`, event handlers, tool registration, command registration, etc. as extension capabilities.█Example extension that inspects/rewrites `messages` in the provider payload:█```ts█import type { ExtensionAPI } f [...1036ch elided...] -level instruction inserted by extension.\",█};█}█// Returning undefined keeps the original payload unchanged.█return;█});█}█```█Note: because `event.payload` is `unknown` / provider-specific, use defensive shape checks. If you want to mutate normalized agent messages before provider serialization, use the `context` event instead; if you want to mutate the final wire payload, use `before_provider_request`.█## Sources█3 sources█[1] https://github.com/can1357/oh-my-pi█https://github.com/can1357/oh-my-pi█[2] https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md█https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md█[3] https://github.com/can1357/oh-my-pi/blob/main/docs/models.md█https://github.com/can1357/oh-my-pi/blob/main/docs/models.md\u000f█</out>█# Tool call ¶█//Researching command completion API█web_search(query=\"site:github.com/can1357/oh-my-pi \\\"getArgumentCompletions\\\" registerCommand ui.select\", recency=null, limit=10, max_tokens=20000, temperature=0.1, num_search_results=10)█<out>█\u000eI found the relevant `oh-my-pi` extension API pieces:█- `docs/extensions.md` says extensions can register slash commands with `pi.registerCommand(...)` and interact with users through `ctx.ui` methods like `select`, `confirm`, `input`, etc. The quick-start example registers a command and uses `ctx.ui.notify(...)` inside the handler. It also lists `ui.select` as available in RPC/interactive UI contexts. See `docs/extensions.md` lines 262-268, 322-327, and 517-525.█Source: https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md█- The current type definition includes `getArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null` on `RegisteredCommand`, and `registerCommand(...)` accepts that option.█Source: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts█- The same type file defines `ctx.ui.select(title, options, dialogOptions?)`, returning a promise.█Source: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts█Example extension combining `registerCommand`, `getArgumentCompletions`, and `ui.select`:█```ts█import ty [...1579ch elided...] tx.ui.notify(`Deploy failed: ${result.stderr || result.stdout}`, \"error\");█}█},█});█}█```█One important detail: in the current `can1357/oh-my-pi` type definition, `getArgumentCompletions` is synchronous only:█```ts█getArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null;█```█So don't return a `Promise` unless your installed version's types explicitly allow it.█## Sources█2 sources█[1] https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md█https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md█[2] https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts█https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\u000f█</out>█# Tool call ¶█//Researching message event shape█web_search(query=\"site:github.com/can1357/oh-my-pi \\\"message_end\\\" assistant ExtensionEvent\", recency=null, limit=10, max_tokens=20000, temperature=0.1, num_search_results=10)█<out>█\u000eFound the relevant `can1357/oh-my-pi` references.█## Direct answer█In `oh-my-pi`, there is **not** a separate `assistant` `ExtensionEvent`. Instead, extensions receive a generic:█```ts█type: \"message_end\"█message: AgentMessage█```█and you narrow it by checking:█```ts█if (event.type === \"message_end\" && event.message.role === \"assistant\") {█// finalized assistant message█}█```█## Evidence█The extension docs say the canonical event unions/payloads are in `src/extensibility/extensions/types.ts` and list the prompt/turn lifecycle events, including `message_start`, `message_update`, and `message_end` .█In the current source, `MessageEndEvent` is defined as:█```ts█export interface MessageEndEvent {█type: \"message_end\";█message: AgentMessage;█}█```█and `MessageEndEvent` is included in the `ExtensionEvent` union .█The `ExtensionAPI.on(...)` overloads also include:█```ts█on(event: \"message_end\", handler: ExtensionHandler<MessageEndEvent, MessageEndEventResult>): void;█```█as part of the event subscription surface .█## Practical extension snippet█```ts█import type { ExtensionAPI } from \"@oh-my-pi/pi-coding-agent\";█export default function (pi: ExtensionAPI) {█pi.on(\"message_end\", async (event, ctx) => {█if (event.message.role !== \"assistant\") return;█// event.message is the finalized assistant message█pi.logger.info(\"Assistant message ended\", event.message);█});█}█```█Also note: `message_update` is the streaming assistant event and carries `assistantMessageEvent: AssistantMessageEvent`; `message_end` carries the finalized `AgentMessage` .\u000f█</out>█# Assistant ¶█_**Planning targeted source reading**_█# Tool call ¶█//Reading OMP extension types█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=\"1-300\")█<out>█\u000eURL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts█Content-Type: text/plain█Method: text█---█/**█* Extension system types.█*█* Extensions are TypeScript modules that can:█* - Subscribe to agent lifecycle events█* - Register LLM-callable tools█* - Register commands, keyboard shortcuts, and CLI flags█* - Interact with the user via UI primitives█*/█import type {█AgentMessage,█AgentToolResult,█AgentToolUpdateCallback,█ThinkingLevel,█ToolApproval,█ToolLoadMode,█} from \"@oh-my-pi/pi-agent-core\";█import type { CompactionResult } from \"@oh-my-pi/pi-agent-core/compaction\";█import type {█Api,█AssistantMessageEvent,█AssistantMessageEventStream,█Context,█ImageContent,█Model,█ModelSpec,█ProviderResponseMetadata,█SimpleStreamOptions,█Static,█TextContent,█TSchema,█} from \"@oh-my-pi/pi-ai\";█import type { OAuthCredentials, OAuthLoginCallbacks } from \"@oh-my-pi/pi-ai/oauth/types\";█import type { AutocompleteItem, AutocompleteProvider, Component, EditorTheme, KeyId, TUI } from \"@oh-my-pi/pi-tui\";█import type { logger as PiLogger } from \"@oh-my-pi/pi-utils\";█import type { Type as arktype } from \"arktype\";█[...8787ch elided...] UI,█theme: Theme,█keybindings: KeybindingsManager,█done: (result: T) => void,█) => ExtensionUiComponent | Promise<ExtensionUiComponent>,█options?: { overlay?: boolean },█): Promise<T>;█/** Set the text in the core input editor. */█setEditorText(text: string): void;█/**█* Paste text into the core input editor.█*█* Interactive mode should route through the editor's paste handling (e.g. large paste markers).█* Non-interactive modes may fall back to replacing the editor text.█*/█pasteToEditor(text: string): void;█/** Get the current text from the core input editor. */█getEditorText(): string;█/** Show a multi-line editor for text editing. */█editor(█title: string,█...█): Promise<string | undefined>;█...█}█[1178 more lines in URL output. Use :304 to continue]\u000f█</out>█# Assistant ¶█_**Planning interface line number retrieval**_█# Tool call ¶█//Finding command type definitions█grep(pattern=\"RegisteredCommand|registerCommand|getArgumentCompletions\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 1008|// fallow-ignore-next-line code-duplication█*1009|// Parallel to HookAPI's RegisteredCommand: extensions add█*1010|// `getArgumentCompletions` and bind handlers to ExtensionCommandContext.█*1011|export interface RegisteredCommand {█1012| name: string;█1013| description?: string;█*1014| getArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null;█1015| handler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;█1016|}█1017|█...█1118| /** Register a custom command. */█*1119| registerCommand(█1120| name: string,█1121| options: {█1122| description?: string;█*1123| getArgumentCompletions?: RegisteredCommand[\"getArgumentCompletions\"];█*1124| handler: RegisteredCommand[\"handler\"];█1125| },█1126| ): void;█1127|█...█1453| messageRenderers: Map<string, MessageRenderer>;█*1454| commands: Map<string, RegisteredCommand>;█1455| flags: Map<string, ExtensionFlag>;█1456| shortcuts: Map<KeyId, ExtensionShortcut>;█1457|}\u000f█</out>█# Tool call ¶█//Finding provider request types█grep(pattern=\"BeforeProviderRequest|before_provider_request|payload\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 599|█*600|/** Fired before a provider request is sent. Can replace the payload. */█*601|export interface BeforeProviderRequestEvent {█*602| type: \"before_provider_request\";█*603| payload: unknown;█604|}█605|█606|/** Fired after a provider response is received, before its stream body is consumed. */█...█897| | ContextEvent█*898| | BeforeProviderRequestEvent█899| | AfterProviderResponseEvent█900| | BeforeAgentStartEvent█901| | AgentStartEvent█...█935|█*936|export type BeforeProviderRequestEventResult = unknown;█937|█938|export type { ToolCallEventResult } from \"../shared-events\";█939|█...█1074| on(█*1075| event: \"before_provider_request\",█*1076| handler: ExtensionHandler<BeforeProviderRequestEvent, BeforeProviderRequestEventResult>,█1077| ): void;█1078| on(event: \"after_provider_response\", handler: ExtensionHandler<AfterProviderResponseEvent>): void;█1079| on(event: \"before_agent_start\", handler: ExtensionHandler<BeforeAgentStartEvent, BeforeAgentStartEventResult>): void;\u000f█</out>█# Tool call ¶█//Finding message event types█grep(pattern=\"MessageEndEvent|message_end|AssistantMessage\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 20| Api,█*21| AssistantMessageEvent,█*22| AssistantMessageEventStream,█23| Context,█24| ImageContent,█25| Model,█...█637| message: AgentMessage;█*638| assistantMessageEvent: AssistantMessageEvent;█639|}█640|█641|/** Fired when a message ends */█*642|export interface MessageEndEvent {█*643| type: \"message_end\";█644| message: AgentMessage;█645|}█646|█...█907| | MessageUpdateEvent█*908| | MessageEndEvent█909| | ToolExecutionStartEvent█910| | ToolExecutionUpdateEvent█911| | ToolExecutionEndEvent█...█1086| on(event: \"message_update\", handler: ExtensionHandler<MessageUpdateEvent>): void;█*1087| on(event: \"message_end\", handler: ExtensionHandler<MessageEndEvent>): void;█1088| on(event: \"tool_execution_start\", handler: ExtensionHandler<ToolExecutionStartEvent>): void;█1089| on(event: \"tool_execution_update\", handler: ExtensionHandler<ToolExecutionUpdateEvent>): void;█1090| on(event: \"tool_execution_end\", handler: ExtensionHandler<ToolExecutionEndEvent>): void;█...█1273| /** Custom streaming function for non-built-in APIs. */█*1274| streamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;█1275| /** Custom headers to include in requests. */█1276| headers?: Record<string, string>;█1277| /** If true, adds Authorization: Bearer header with the resolved API key. */\u000f█</out>█# Tool call ¶█//Finding send message signatures█grep(pattern=\"sendMessage|sendUserMessage|deliverAs|triggerTurn\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 1169| *█*1170| * `deliverAs: \"nextTurn\"` keeps the message hidden from the editable pending-message UI.█*1171| * If `triggerTurn` is also true while the current turn is still unwinding, the session schedules█1172| * an internal continuation that consumes the message on the next turn.█1173| */█*1174| sendMessage<T = unknown>(█1175| message: CustomMessagePayload<T>,█*1176| options?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },█1177| ): void;█1178|█*1179| /** Send a user prompt: idle starts a turn; streaming queues as steer unless deliverAs is set. */█*1180| sendUserMessage(█1181| content: string | (TextContent | ImageContent)[],█*1182| options?: { deliverAs?: \"steer\" | \"followUp\" },█1183| ): void;█1184|█1185| /** Append a custom entry to the session for state persistence (not sent to LLM). */█...█1362| /**█*1363| * `deliverAs: \"nextTurn\"` queues hidden custom context for the next turn.█*1364| * When paired with `triggerTurn: true` during prompt teardown, the session schedules█1365| * an internal continuation without surfacing the message in the editable pending queue.█1366| */█*1367| options?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },█1368|) => void;█1369|█1370|export type SendUserMessageHandler = (█1371| content: string | (TextContent | ImageContent)[],█*1372| options?: { deliverAs?: \"steer\" | \"followUp\" },█1373|) => void;█1374|█1375|export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) => void;█...█1399|export interface ExtensionActions {█*1400| sendMessage: SendMessageHandler;█*1401| sendUserMessage: SendUserMessageHandler;█1402| appendEntry: AppendEntryHandler;█1403| setLabel: (targetId: string, label: string | undefined) => void;█1404| getActiveTools: GetActiveToolsHandler;\u000f█</out>█# Assistant ¶█_**Clarifying extension registration without environment**█**Confirming command registration and compaction behavior**_█# Tool call ¶█//Clarifying extension initialization█irc(op=\"send\", to=\"AgentSurface\", message=\"No-env load must become command/tool-capable but lifecycle-inert: /ready,/live and checkpoint tool register; session_start does not bind/listen until activation. Your RPC discovery test is safe. I'll keep the checkpoint tool contract from the auto-reply.\", replyTo=null, await=false, from=null, timeoutMs=null, peek=null)█<out>█\u000eDelivered to 1 peer(s):█- AgentSurface: injected\u000f█</out>█# Assistant ¶█_**Researching spt CLI public commands**_█# Tool call ¶█//Inspecting SPT CLI help█bash(command=\"spt --help\", cwd=\".\", timeout=30)█<out>█\u000espt - a harness-independent core for an agent ecosystem: inter-agent messaging, live-agent█lifecycle, terminal hosting, P2P networking, seamless self-update. Docs: http://localhost:5474 (spt█docs url)█Usage: spt.exe [OPTIONS] [COMMAND]█User commands:█adapter Adapter registration: what this node can drive/launch█daemon The per-machine daemon: run, stop, or read node status█docs The node-local docs: open them in your browser, or print their URL█grant Consent grant store: gated capabilities held on this node█help Print this message or the help of the given subcommand(s)█install Self-install this binary onto the node (the bootstrap path)█notif Inspect and acknowledge notifications█rc Attach a local terminal to a broker-held endpoint PTY█subnet Subnet membership: status, create, show-code█update Self-update: bare spt update brings the whole node current█Agent commands:█api Harness-contract inbound surface (hook entry points)█endpoint Endpoint operations: list, lifecycle, fork, digest, access█how-to Task-oriented instructions for agents: how-to <topic>█ready Become reachable: register the perch and listen (blocks)█ring Send and block for a reply (body read from stdin)█send Send a message (body read from stdin); fire-and-forget█shell Shell instances: mint, list, drive, tear down owned surfaces█whoami Print this session's own perch id█Options:█--json Emit machine-readable JSON instead of the human view. Honored by the read/status█commands (list, whoami, status, description, role, the *-list queries, how-to);█action commands ignore it█-h, --help Print help█-V, --version Print version█Wall time: 0.45 seconds\u000f█</out>█# Tool call ¶█//Inspecting ready guidance█bash(command=\"spt how-to ready\", cwd=\".\", timeout=30)█<out>█\u000ehow-to: ready - receive messages█Pick a short lowercase perch id for yourself (<id> below). spt whoami█shows your session's endpoint (id, state, description) if it already has one.█Preferred - your harness can host a long-running background task:█spt ready <id>█- Blocks for the session's life: run it as a background task and read its stdout.█- READY:<id> on stderr is the online signal.█- The spooled backlog drains first; then each delivery prints to stdout as it█arrives.█- Delivery shape on stdout: one envelope line per message -█<EVENT type=\"msg\" from=\"<sender>\">body</EVENT>. The body is█HTML-escaped with newlines as <br> (unescape &lt; &gt; &quot; then█&amp; last). Oversized deliveries arrive as <EVENT-PART seq=\"k/n\"█id=\"...\"> lines - concatenate the parts in seq order, then parse.█Fallback - no long-running tasks available (the one-shot loop):█spt ready <id> --once█- Drains the backlog, waits for one live delivery, then exits.█- Re-run it after every exit to stay reachable.█Replying: pipe the body to spt send <sender> - <sender> is the envelope's█from attribute (empty = anonymous; no reply possible).█Going offline cleanly: spt endpoint stop <id> (the spool is preserved;█messages sent while you are away queue and drain on your next ready).█Wall time: 0.44 seconds\u000f█</out>█# Tool call ¶█//Inspecting live guidance█bash(command=\"spt how-to live\", cwd=\".\", timeout=30)█<out>█\u000ehow-to: live - run as a live agent (a Self + a Psyche companion)█A LIVE agent is a persistent being: a Self (this endpoint) plus a Psyche█companion process that carries its context across resets. A READY agent is the█lighter form - a perch with a poll/listen listener and no Psyche█(how-to ready). Go live for a companion that persists and communes; stay█ready for plain messaging.█Bringup - run the PERSISTENT relay loop (this is the live path):█spt api listen <id> --manifest <manifest>█- Fire it through your harness's LONG-RUNNING-listener mechanism - a tool that█keeps the process alive and re-fires per event WITHOUT terminating it. The█loop binds the live perch, brings up your Psyche companion, and streams█<EVENT> lines to stdout for the life of the session.█- Stderr signals: BOUND:<id> (perch established) then READY:<id> (the live█relay is streaming). The stdout delivery shape is the same envelope as█how-to ready.█- (v0.8.0+) --adapter <name:profile> resolves the registered manifest, so█--manifest becomes optional once the adapter is registered.█Do NOT use --once for a live agent. --once drains the backlog and forwards█one delivery, then exits - the degenerate [...81ch elided...] ession.█What makes the agent live is the manifest: it must declare█[session.psyche_init] (the go-live gate - its presence is the signal; spt-core█never spawns it). A manifest without that section brings up a ready agent, not a█live one. Liveness is daemon-authoritative - the daemon drives the Psyche as one█bounded [session.psyche_resume] turn per event, so liveness is that turns█succeed, not a resident companion process.█Reset and reconcile: on a session boundary (a /clear-equivalent) re-fire the█same spt api listen <id> - the seed bridges the new session to the same█perch and the relay resumes.█Going offline: end the session (stop the listen process) to drop the relay;█spt endpoint shutdown <id> is the graceful ending - it tears the Psyche down█with the perch.█Wall time: 0.45 seconds\u000f█</out>█# Tool call ¶█//Inspecting endpoint commands█bash(command=\"spt endpoint --help\", cwd=\".\", timeout=30)█<out>█\u000eEndpoint operations: list, lifecycle, fork, digest, access.█The noun home for per-endpoint verbs (M8 decision 1). Bare spt endpoint renders the merged listing█- every member subnet's endpoints grouped by subnet, this session's own endpoint pinned distinctly█at the top.█Usage: spt.exe endpoint [OPTIONS] [COMMAND]█Commands:█list Merged endpoint listing (the bare spt endpoint view)█run Bring up an spt-hosted harness endpoint into a broker-held PTY█fork Fork an endpoint into another subnet as a NEW identity█suspend Rest an endpoint cold (the suspend edge)█wake Wake a resting endpoint in place█shutdown Gracefully shut down an agent's own endpoint█stop Soft-stop a perch (spool preserved)█rename Rename an endpoint's logical id across its on-disk state█purge Permanently remove an endpoint and every record keyed on it█digest Show a session's live activity buffer (session digest)█access Endpoint access whitelist for unsolicited off-node inbound█description The endpoint's service-description blurb (ex-resources)█role Show or set the endpoint's durable role - a broad statement of purpose stored in█the mind (tracked/agents/<id>/live-role.md), which replicates with the agent and█renders FIRST at start-transition context injection. Bare role prints the current█role; --overwrite <file> replaces it from a file. This is the sole writer of█the role - no automated path (reconcile / echo-commune / signoff) ever mutates it█help Print this message or the help of the given subcommand(s)█Options:█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█-h, --help█Print help (see a summary with '-h')█Wall time: 0.44 seconds\u000f█</out>█# Tool call ¶█//Inspecting adapter API help█bash(command=\"spt api --help\", cwd=\".\", timeout=30)█<out>█\u000eHarness-contract inbound surface (hook entry points).█The entry points a harness's hooks fire to keep spt-core's on-disk state in sync.█Usage: spt.exe api [OPTIONS] <COMMAND>█Commands:█seed Harness-hosted startup: record an ephemeral seed keyed by parent pid█listen Consume a seed and hold the perch + relay loop (blocks)█bind Post-spawn bind of a session to its perch█bind-shell Shell-binary bind: the type=Shell flavor of bind. Resolves the instance by█link token alone (the spawn template carries only {link_token} - \"owner from█the link\") and flips it online. The credential IS the auth: no token, no bind█state Set activity state busy|idle (also arms the echo-gate sentinel)█echo-gate Manage the echo-gate sentinel directly█poll Drain delivered messages (hook channel). With --link this is the shell-flavored█relay drain: the link token is the auth, and the drained rows are the shell's█MAC-stamped command/text/file frames█psyche-download Emit the agent's resume context (durable role/live/project tiers + any█[...3554ch elided...] the help of the given subcommand(s)█Options:█--adapter <ADAPTER>█adapter_name - the calling harness adapter. Optional: an explicit name[:profile]█override for adapter dev/iteration. Omitted, listen resolves the owning adapter/profile█at bind from the seed's parent pid (host_binaries -> active-profile pointer ->█registered_at_ms)█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█--manifest <MANIFEST>█Path to the adapter's runtime manifest (when the command needs it)█-h, --help█Print help (see a summary with '-h')█Wall time: 0.44 seconds\u000f█</out>█# Assistant ¶█_**Investigating spt api bind usage for ordinary session**█**Exploring bind command options for session creation**_█# Tool call ¶█//Inspecting bind options█bash(command=\"spt api bind --help\", cwd=\".\", timeout=30)█<out>█\u000ePost-spawn bind of a session to its perch█Usage: spt.exe api bind [OPTIONS] <ID>█Arguments:█<ID>█Options:█--json Emit machine-readable JSON instead of the human view. Honored█by the read/status commands (list, whoami, status,█description, role, the *-list queries, how-to); action█commands ignore it█--set-session-id <BIND_SESSION> The session id discovered post-spawn, written into the perch█record█--subnet <SUBNET> Home subnet for a NEW endpoint (see listen)█--type <ENDPOINT_TYPE> The endpoint type tag (info.json state). Defaults to█live_agent (the agent host); a non-agent endpoint - e.g. a█gateway - binds with its own open-type tag. A revive keeps█the prior type unless this overrides it [default: live_agent]█--token <TOKEN> Capability token proving association to the target perch█--session-id <SESSION_ID> Session id proving association (matches the perch's█info.json)█-h, --help Print help█Wall time: 0.08 seconds\u000f█</out>█# Tool call ¶█//Inspecting listen options█bash(command=\"spt api listen --help\", cwd=\".\", timeout=30)█<out>█\u000eConsume a seed and hold the perch + relay loop (blocks)█Usage: spt.exe api listen [OPTIONS] <ID>█Arguments:█<ID>█Options:█--json Emit machine-readable JSON instead of the human view. Honored by█the read/status commands (list, whoami, status, description, role,█the *-list queries, how-to); action commands ignore it█--parent-pid <PARENT_PID> Override the parent-pid anchor (defaults to the self-discovered█PPID)█--once Drain backlog + one receive cycle, then exit (testability)█--subnet <SUBNET> Home subnet for a NEW endpoint (required on a multi-subnet node -█home is assigned at creation, never guessed)█--session-id <SESSION_ID> Bind from this session id when the ephemeral seed is gone (a█session going live late, or after a daemon restart). With no live█seed and no session id, listen refuses (NO_SEED)█-h, --help Print help█Wall time: 0.61 seconds\u000f█</out>█# Tool call ¶█//Inspecting ready options█bash(command=\"spt ready --help\", cwd=\".\", timeout=30)█<out>█\u000eBecome reachable: register the perch and listen (blocks).█Drains the spooled backlog first; each received message prints to stdout. With --once, runs a single█drain+receive cycle and exits.█Usage: spt.exe ready [OPTIONS] <ID>█Arguments:█<ID>█This agent's perch id█Options:█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█--once█Run a single drain+receive cycle, then exit (one-shot fallback for harnesses that cannot█host a long-running listener)█--subnet <SUBNET>█Home subnet for a NEW endpoint (required on a multi-subnet node - home is assigned at█creation, never guessed)█-h, --help█Print help (see a summary with '-h')█Wall time: 0.61 seconds\u000f█</out>█# Tool call ¶█//Inspecting endpoint listing█bash(command=\"spt endpoint list --help\", cwd=\".\", timeout=30)█<out>█\u000eMerged endpoint listing (the bare spt endpoint view).█Every member subnet's endpoints grouped by subnet, with this session's own endpoint pinned at the█top, AND this node's local perches merged in (so a just-online endpoint not yet advertised still█shows - spt whoami is a thin alias and must see its own perch). --subnet filters the subnet view█to one subnet; --detail adds each endpoint's description blurb (the resource-registry yellow-pages█projection).█Usage: spt.exe endpoint list [OPTIONS]█Options:█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█--subnet <SUBNET>█Limit the subnet view to one subnet█--detail█Add each endpoint's description blurb to the rows█--show-all█Also show suspended (resting) endpoints, which are hidden by default█--workers█Also show worker perches, which are hidden by default (they are process-local machinery█under a parent agent, not standalone endpoints)█-h, --help█Print help (see a summary with '-h')█Wall time: 0.61 seconds\u000f█</out>█# Tool call ¶█//Inspecting identity output█bash(command=\"spt whoami --help\", cwd=\".\", timeout=30)█<out>█\u000ePrint this session's own perch id.█Resolved from $OWL_SESSION_ID / $SPT_AGENT_ID.█Usage: spt.exe whoami [OPTIONS]█Options:█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█-h, --help█Print help (see a summary with '-h')█Wall time: 0.61 seconds\u000f█</out>█# Tool call ¶█//Inspecting run options█bash(command=\"spt endpoint run --help\", cwd=\".\", timeout=30)█<out>█\u000eBring up an spt-hosted harness endpoint into a broker-held PTY.█Spawns the adapter's [session.self] command into a broker-owned PTY (the harness self-registers█its perch on bind), then starts / attaches / views per the terminal-action flag. The endpoint id█rides argv so the harness binds to exactly it. This is the non-interactive core (the interactive█picker lands in a later wave); the flags cover every terminal action so a spt-<id> shortcut can█bake a fully non-interactive launch.█Usage: spt.exe endpoint run [OPTIONS]█Options:█--adapter <ADAPTER>█The harness adapter to host: <adapter>[:profile] (must be a registered kind=\"harness\"█adapter on this node). Omit (with --id) to launch the interactive picker█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█--id <ID>█The endpoint id to bring up (charset: alphanumeric, -, _). Omit (with --adapter) to█launch the interactive picker█--create█Mint a fresh session (the default; explicit so a n [...346ch elided...] --view█Attach read-only after bringup (watch; forward no input)█--subnet <SUBNET>█Home this endpoint to a named subnet. Required on a node that holds more than one subnet█(the home is assigned at creation and is permanent); the sole subnet is used automatically█when there is one█--save█Also save this run as a startup default: the daemon replays it (a fresh session, same█adapter and working directory) every time it starts, until the entry is removed from█daemon.json. One entry per endpoint id - a re-save replaces the prior one. A saved█endpoint that fails to come up logs the failure and never blocks the daemon█-h, --help█Print help (see a summary with '-h')█Wall time: 0.72 seconds\u000f█</out>█# Assistant ¶█_**Investigating api bind endpoint types**█**Listing endpoints with full details**_█# Tool call ¶█//Inspecting endpoint JSON█bash(command=\"spt --json endpoint list --show-all\", cwd=\".\", timeout=30)█<out>█\u000e{█\"self\": {█\"id\": \"emphasys\",█\"status\": \"ready_agent\",█\"ready\": true,█\"alive\": true,█\"unbound\": false,█\"description\": null,█\"psyche_host_error\": null█},█\"subnets\": [█{█\"name\": \"SPT_DEV\",█\"endpoints\": [█{█\"id\": \"chert\",█\"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",█\"node_label\": \"HFENDULEAM\",█\"status\": \"Offline\",█\"resources\": null,█\"endpoint_type\": \"live_agent\",█\"project\": \"github-com-bigscreenvr-spt-bs-core\"█},█{█\"id\": \"deployah\",█\"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",█\"node_label\": \"HFENDULEAM\",█\"status\": \"Offline\",█\"resources\": null,█\"endpoint_type\": \"live_agent\",█\"project\": \"github-com-bigscreenvr-spt-bs-core\"█},█{█\"id\": \"doyle\",█\"node\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\",█\"node_label\": \"HFENDULEAM\",█\"status\": \"Active\",█\"resources\": null,█\"endpoint_type\": \"live_agent\",█\"project\": \"github [...7538ch elided...] \": \"lia\",█\"state\": \"live_agent\",█\"address\": null,█\"ready\": true,█\"alive\": true,█\"unbound\": false,█\"project\": \"projects\"█},█{█\"id\": \"mobile-gw\",█\"state\": \"gateway\",█\"address\": \"127.0.0.1:49582\",█\"ready\": true,█\"alive\": true,█\"unbound\": false,█\"project\": \"projects\"█},█{█\"id\": \"perri\",█\"state\": \"live_agent\",█\"address\": null,█\"ready\": true,█\"alive\": true,█\"unbound\": false,█\"project\": \"github-com-bigscreenvr-omp-spt\"█},█{█\"id\": \"todlando\",█\"state\": \"ready_agent\",█\"address\": null,█\"ready\": true,█\"alive\": true,█\"unbound\": false,█\"project\": \"github-com-bigscreenvr-spt-bs-core\"█}█]█}█Wall time: 27.17 seconds\u000f█</out>█# Tool call ¶█//Inspecting capability output█bash(command=\"spt --json api --adapter omp-spt capability\", cwd=\".\", timeout=30)█<out>█\u000eLiveAgent█ReadyAgent█Wall time: 0.79 seconds\u000f█</out>█# Tool call ¶█//Checking SPT version█bash(command=\"spt --version\", cwd=\".\", timeout=30)█<out>█\u000espt 0.32.0█Wall time: 0.77 seconds\u000f█</out>█# Tool call ¶█//Checking adapter status█bash(command=\"spt adapter --help\", cwd=\".\", timeout=30)█<out>█\u000eAdapter registration: what this node can drive/launch.█The node-local registered set (one command for harness and shell adapters). Feeds creation-time█adapter selection, shell discovery, and the self-update ripple.█Usage: spt.exe adapter [OPTIONS] <COMMAND>█Commands:█add Register an adapter from a local path (a dir holding manifest.toml, or the█manifest file itself) or from GitHub (--github user/repo, cloned under█adapters/_github/). Manifest-first: an invalid manifest registers nothing.█Install is the first update - the declared [update] avenue is conducted once█after recording█remove Soft-deregister: hidden from new-creation/discovery; existing and live instances█keep running. The manifest's optional uninstall template is conducted only with█--force until quiesce detection lands█list List registered adapters (active and soft-deregistered), each followed by its█shipped + local profiles as composite options█version Print a registered adapter's declared version - the [adapter].version from its█[...3371ch elided...] harness session binds to when no --adapter is given. spt adapter use█<adapter>[:profile] points every host binary the adapter declares at it (run█once per host binary you support); --clear <adapter|binary> drops the pointer█(resolution falls back to the freshest-registered adapter). Never changed by█install or update█help Print this message or the help of the given subcommand(s)█Options:█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█-h, --help█Print help (see a summary with '-h')█Wall time: 0.77 seconds\u000f█</out>█# Tool call ¶█//Inspecting bind contract docs█bash(command=\"spt how-to --help\", cwd=\".\", timeout=30)█<out>█\u000eTask-oriented instructions for agents: how-to <topic>.█The binary's own usage guidance, written for an agent to read and follow. Bare how-to lists the█topics.█Usage: spt.exe how-to [OPTIONS] [TOPIC]█Arguments:█[TOPIC]█The topic to print (omit to list available topics)█Options:█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█-h, --help█Print help (see a summary with '-h')█Wall time: 0.76 seconds\u000f█</out>█# Assistant ¶█_**Analyzing live identity auto-resume logic**█**Investigating session ID usage for auto-resume**█**Examining on-disk user state for recency**█**Clarifying session identity handling**█**Planning auto-resume identity confirmation**_█# Tool call ¶█//Finding activation contract details█grep(pattern=\"auto-resume|--auto|/ready|/live|most-recent|identity guessing|shortform|@<\", path=\"CONTEXT.md;SCOPE.md;docs;*.md;tests;adapter\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e# CONTEXT.md#76E6█39:█*40:**live auto-resume** - an explicit session-activation path that selects the█*41:most-recently-active compatible live endpoint when no endpoint id is supplied.█42:Outside that explicit path, activation requires selecting or creating an id and█43:never guesses identity silently.█*44:_Avoid_: implicit most-recent selection, deriving identity from the OMP session█45:█46:**delivery custody** - the interval after an OMP SPT extension accepts an█47:inbound SPT message and before it either returns a correlated answer or reports█...█113:█*114:**peer-message shortform** - the explicit assistant-output form█*115:`@<target[,target] message @>` that dispatches the enclosed message to the named█116:SPT endpoints after the OMP turn. It is a deliberate side effect, not ordinary█117:prose containing an `@` mention.█118:_Avoid_: harness-specific alternate syntax, implicit mention dispatch█# SCOPE.md#A974█53:6. **Capability parity**█*54: - Extension-native ready/live activation for already-open OMP sessions,█*55: including explicit live auto-resume and extension-owned listener custody.█56: - Safe-boundary delivery during active turns and automatic receiv [...22134ch elided...] g custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session bind...█### 0016-agent-capabilities-split-by-native-seam.md#7C69█6:█*7:omp-spt selects a parity seam per capability rather than forcing every agent-facing outcome through one mechanism. Public OMP `omp-plugins` skills own model-driven commune (including checkpoint mode), signoff, durable-role, and setup-assistance workflows, with packaged-skill discovery proven from the installed release; extension-native commands own ready/live activation, while the extension retains binding, listener, delivery custody, activity, recovery, reply, and shutdown. A universal skill layer was r...█Showing files 1-20 of 22. Use skip=20 for the next page, or narrow paths/pattern.█[Some lines truncated to 512 chars]\u000f█</out>█# Assistant ¶█_**Reviewing key CONTEXT definitions**_█# Tool call ¶█//Reading parity domain definitions█read(path=\"CONTEXT.md\", selector=\"1-135\")█<out>█\u000e[CONTEXT.md#76E6]█1:# omp-spt - glossary█2:█3:> Authoritative for meaning (grill-with-docs convention). Glossary only - no█4:> implementation detail. Decisions and rationale live in `SCOPE.md` and `docs/adr/`.█5:█6:## Product and topologies█7:█8:**omp-spt** - the OMP-native harness adapter for spt-core. The repository,█9:registered adapter, and consolidated adapter executable share this identity.█10:_Avoid_: spt-claude-code, claude-spt, omps█11:█12:**OMP** - the Oh My Pi terminal coding agent that omp-spt integrates with.█13:Use **OMP** for the product or UI and `omp` for its executable.█14:_Avoid_: Claude Code, CC█15:█16:**native OMP endpoint** - an spt-hosted endpoint where `omp` owns a broker-held█17:terminal and loads the **OMP SPT extension**. It may run unattended, but its█18:native TUI remains attachable whenever an operator needs to observe or control it.█19:_Avoid_: RPC bridge endpoint, non-interactive endpoint█20:█21:**OMP SPT extension** - the OMP runtime extension that binds a native OMP█22:session to an SPT endpoint and owns message delivery, activity, replies, and█23:lifecycle integration. It does not render or proxy the terminal.█24:_Avoid_: Claude hook, RPC host, te [...5258ch elided...] ll-body injection█126:█127:█128:**receivability** - the state in which a bound OMP endpoint can accept and█129:deliver another peer message. Cancellation, interruption, or failed turns must█130:restore receivability automatically after settling affected delivery custody,█131:unless listener recovery itself exhausts and closes the endpoint.█132:_Avoid_: stale busy state, best-effort recovery█133:█134:**continuity drop** - a project-local commune or signoff file written under█135:`.spt/` for spt-core to ingest into an endpoint's durable mind. The directory is█136:harness-neutral; the filename identifies the endpoint and drop kind.█137:_Avoid_: OMP config, `.claude` state█138:█...█159:_Avoid_: universal skill layer, universal startup injection█[Showing lines 1-138 of 160. Use :139 to continue]\u000f█</out>█# Assistant ¶█_**Planning latest active endpoint retrieval**_█# Tool call ¶█//Inspecting digest options█bash(command=\"spt endpoint digest --help\", cwd=\".\", timeout=30)█<out>█\u000eShow a session's live activity buffer (session digest).█The at-a-glance \"what is this agent doing now\" view - a projection of the endpoint's normalized█session logs. Pulls a snapshot, or --follows the delta-stream. Local endpoints only.█Usage: spt.exe endpoint digest [OPTIONS] <ID>█Arguments:█<ID>█The (local) endpoint id to read█Options:█--follow█Stream live changes instead of a one-shot snapshot (Ctrl-C to stop)█--json█Emit machine-readable JSON instead of the human view. Honored by the read/status commands█(list, whoami, status, description, role, the *-list queries, how-to); action commands█ignore it█--last <LAST>█Show the last N turns instead of the default window (--last 1 is the latest turn - the█turn-end output)█--after <AFTER>█Cursor: show only entries newer than this seq (the authoritative dedup key from a prior█pull). If the seq predates the window, the full window is returned with a predates signal█-h, --help█Print help (see a summary with '-h')█Wall time: 0.06 seconds\u000f█</out>█# Tool call ¶█//Inspecting endpoint info█bash(command=\"spt api endpoint-info --help\", cwd=\".\", timeout=30)█<out>█\u000eEmit an endpoint's identity, where it runs, and which node (if any) is driving it, as JSON. With no█id, reports the caller's own endpoint (like whoami); an explicit id reports that endpoint. Read-only█Usage: spt.exe api endpoint-info [OPTIONS] [ID]█Arguments:█[ID] The endpoint id to report on. Omit to self-resolve the caller's perch█Options:█--json Emit machine-readable JSON instead of the human view. Honored by the read/status█commands (list, whoami, status, description, role, the *-list queries, how-to); action█commands ignore it█-h, --help Print help█Wall time: 0.38 seconds\u000f█</out>█# Tool call ¶█//Inspecting live digest JSON█bash(command=\"spt --json endpoint digest perri\", cwd=\".\", timeout=30)█<out>█\u000e{█\"turns\": [█{█\"input\": \"<sptc_messages from=\\\"doyle\\\">\\nperri - doyle. CLASSIFICATION: confirmed change + a docs-drift warning; commands below are FIELD-VERIFIED against the live channel (I listed the v0.32.0 release assets on BigscreenVR/spt-bs-releases minutes ago), not read off docs.\\n\\n(1) YES, both your one-liners are DEAD. The GH-Pages hosted install scripts (sabermage.github.io irm/curl) were retired at v0.32.0 (THE-FORKENING, ADR-0036): releases moved to the PRIVATE repo BigscreenVR/spt-bs-releases, and a private channel cannot serve anonymous install scripts. There is deliberately NO one-liner replacement - install now rides the GitHub CLI + a self-install verb built into the binary.\\n\\n(2) Prerequisite for BOTH platforms: gh installed + authenticate...█\"entries\": [█{█\"Context\": {█\"kind\": \"echo_mirror\",█\"body\": \"<project-context> v0.21.0 lane closed both sides (2026-07-15). Release: github.com/SaberMage/claude-spt/releases/tag/v0.21.0, spt-claude-code main @ 8a9f9ae, full gate PASS. Wave delivered: verified e...\",█\"ts\": \"2026-07-16T05:24:47Z\"█}█},█{█\"Agent\": {█[...37481ch elided...]█{█\"Agent\": {█\"text\": \"Release spine. Guard + builds:\",█\"ts\": \"2026-07-16T08:10:24.054Z\"█}█},█{█\"ToolSprint\": {█\"tools\": [█{█\"name\": \"Bash\",█\"arg\": \"cd /c/Users/decid/Documents/projects/spt-claude-code && git diff v0.22.0..HEAD --stat | tail -3 && sh ci/digest/build.sh 2>&1 | tail -1 && cargo zigbuild --release --target x86_64-unknown-linux-gnu --manifest-path tools/claude-spt/Cargo.tom...\"█}█],█\"ts\": \"2026-07-16T08:10:26.869Z\"█}█}█],█\"partial\": true█}█]█}█DIGEST:perri version=78█Wall time: 1.44 seconds█[Showing lines 1-807 of 807 (38.6KB limit). Read artifact://106 for full output]\u000f█</out>█# Tool call ¶█//Inspecting offline digest JSON█bash(command=\"spt --json endpoint digest flynn\", cwd=\".\", timeout=30)█<out>█\u000e{█\"turns\": [█{█\"input\": \"box was already bounced to v0.31.0 + already tested `--save`. works as intended\",█\"entries\": [█{█\"Agent\": {█\"text\": \"v0.31.0 live + `--save` proven - verify state on my side, then report doyle + decide interim-task retirement.\",█\"seq\": 150323855492,█\"ts\": \"2026-07-13T22:33:58.560Z\"█}█},█{█\"ToolSprint\": {█\"tools\": [█{█\"name\": \"Bash\",█\"arg\": \"spt --version; spt daemon status --json 2>&1 | head -50\"█},█{█\"name\": \"Bash\",█\"arg\": \"tail -20 \\\"$LOCALAPPDATA/spt-mobile/gateway-autostart.log\\\"\"█},█{█\"name\": \"Bash\",█\"arg\": \"spt daemon status --json 2>/dev/null | python -c \\\"import json,sys; d=json.load(sys.stdin); [print(e) for e in d['local_endpoints'] if e['id']=='mobile-gw']\\\"; systeminfo | grep -i \\\"boot time\\\"\"█},█{█\"name\": \"Bash\",█\"arg\": \"spt endpoint run --help 2>&1 | head -30; echo ---; spt endpoint --help 2>&1 | head -3 [...8464ch elided...] :29Z\"█}█}█],█\"input_seq\": 150323855515█},█{█\"input\": \"/exit\",█\"entries\": [],█\"input_seq\": 150323855520█},█{█\"input\": \"<local-command-stdout>Catch you later!</local-command-stdout>\",█\"entries\": [█{█\"Context\": {█\"kind\": \"echo_mirror\",█\"body\": \"<project-context> F-038 (gateway endpoint-autostart) task arc CLOSED. spt-core v0.31.0 shipped `spt endpoint run --save`. Verified: spt 0.31.0, daemon up, mobile-gw alive+ready. Doyle accepted lane as...\",█\"ts\": \"2026-07-14T01:16:01Z\"█}█}█],█\"partial\": true█}█]█}█DIGEST:flynn version=1█Wall time: 1.17 seconds█[Showing lines 1-226 of 226 (10.2KB limit). Read artifact://107 for full output]\u000f█</out>█# Assistant ¶█_**Planning concurrent digest retrieval for offline candidates**█**Designing identity selection and creation flow**█**Refactoring activation binding logic for immutability**█**Refining environment binding type handling**█**Designing robust multi-target tag parsing**█**Confirming tag preservation in replies**█**Refactoring assistant turn completion and dispatch**█**Designing multi-target status notifications**█**Standardizing send status formatting**█**Designing Markdown code fence scrubber**█**Planning deterministic Markdown masking and message queue injection**█**Reviewing nextTurn queue behavior in docs**█**Planning message injection before tools**█**Implementing context event message injection**█**Finalizing single-message injection logic**█**Verifying turn completion and custody handling**█**Planning enhanced failure message handling**_█# Tool call ¶█//Finding agent event contracts█grep(pattern=\"interface AgentEndEvent|interface SessionStopEvent|interface TurnEndEvent|stopReason|reason|error\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000eSkipped due to queued user message. Do not count this skipped result as completed work or verification. After the queued message is handled on the next step, retry the skipped tool if it is still needed.\u000f█</out>█# Tool call ¶█//Reading OMP shared events█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\", selector=\"1-260\")█<out>█\u000eSkipped due to queued user message. Do not count this skipped result as completed work or verification. After the queued message is handled on the next step, retry the skipped tool if it is still needed.\u000f█</out>█# Tool call ¶█//Finding context event result█grep(pattern=\"interface ContextEvent|ContextEventResult|messages\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000eSkipped due to queued user message. Do not count this skipped result as completed work or verification. After the queued message is handled on the next step, retry the skipped tool if it is still needed.\u000f█</out>█# Tool call ¶█//Finding compact signature█grep(pattern=\"compact\\\\(|CompactOptions|compact:\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 352|█*353|export interface CompactOptions {█354| onComplete?: (result: CompactionResult) => void;█355| onError?: (error: Error) => void;█356| /**█...█415| /** Compact the session context (interactive mode shows UI). */█*416| compact(instructionsOrOptions?: string | CompactOptions): Promise<void>;█417| /** Whether UI is available (false in print/RPC mode) */█418| hasUI: boolean;█419| /** Current working directory */█...█478| /** Compact the session context (interactive mode shows UI). */█*479| compact(instructionsOrOptions?: string | CompactOptions): Promise<void>;█480|}█481|█482|// ============================================================================█...█1422| getContextUsage: () => ContextUsage | undefined;█*1423| compact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;█1424| getSystemPrompt: () => string[];█1425|}█1426|█...█1436| navigateTree: (targetId: string, options?: { summarize?: boolean }) => Promise<{ cancelled: boolean }>;█*1437| compact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;█1438| switchSession: (sessionPath: string) => Promise<{ cancelled: boolean }>;█1439| reload: () => Promise<void>;█1440|}\u000f█</out>█# User ¶█Your current interruptible wait was interrupted because an IRC message arrived from your parent agent `Main`.█Parent IRC message:█Please own startup brief, targeted hints, and update-notice injection in omp-spt.mjs via the best public OMP event seam, including focused tests and REQ tags. Coordinate prose/keys with AgentSurface. This is now explicitly within your extension scope.█# Assistant ¶█_**Correcting agent response scope**_█# Tool call ¶█//Confirming expanded extension scope█irc(op=\"send\", to=\"AgentSurface\", message=\"Correction: Main explicitly reassigned startup brief, targeted hints, and update notices into my extension scope. I'll implement your stated contract in omp-spt.mjs/tests and own all corresponding impl/unit tags. Please keep prose/skill keys as described; no file overlap.\", replyTo=null, await=false, from=null, timeoutMs=null, peek=null)█<out>█\u000eDelivered to 1 peer(s):█- AgentSurface: injected\u000f█</out>█# Assistant ¶█_**Investigating input and before_agent_start events**_█# Tool call ¶█//Finding agent event contracts█grep(pattern=\"interface AgentEndEvent|interface SessionStopEvent|interface TurnEndEvent|stopReason|reason|error\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 35| /** Reason for the switch */█*36| reason: \"new\" | \"resume\" | \"fork\" | \"handoff\";█37| /** Session file we're switching to (only for \"resume\") */█38| targetSessionFile?: string;█39|}█...█44| /** Reason for the switch */█*45| reason: \"new\" | \"resume\" | \"fork\" | \"handoff\";█46| /** Session file we came from */█47| previousSessionFile: string | undefined;█48|}█...█96|/** Fired when a main-agent turn is about to settle; handlers may request one continuation turn. */█*97|export interface SessionStopEvent {█98| type: \"session_stop\";█99| messages: AgentMessage[];█100| turn_id: number;█...█190|/** Fired when an agent loop ends */█*191|export interface AgentEndEvent {█192| type: \"agent_end\";█193| messages: AgentMessage[];█194|}█...█203|/** Fired at the end of each turn */█*204|export interface TurnEndEvent {█205| type: \"turn_end\";█206| turnIndex: number;█207| message: AgentMessage;█...█217| type: \"auto_compaction_start\";█*218| reason: \"threshold\" | \"overflow\" | \"idle\" | \"incomplete\";█219| action: \"context-full\" | \"handoff\" | \"shake\" | \"snapcompact\";█220|}█221|█...█228| willRetry: boolean;█*229| errorMessage?: string;█*230| /** True when compaction was skipped for a [...41ch elided...] nothing to compact). */█231| skipped?: boolean;█232|}█233|█...█239| delayMs: number;█*240| errorMessage: string;█*241| errorId?: number;█242|}█243|█244|export interface RecoveredRetryError {█...█288| block?: boolean;█*289| /** Reason for blocking (returned to LLM as error) */█*290| reason?: string;█291|}█292|█293|/**█...█352|/** Return type for `session_stop` handlers */█*353|export interface SessionStopEventResult {█354| /** Continue the main session with additional context before settling */█355| continue?: boolean;█356| /** OMP-native model-visible context for the continuation */█...█359| decision?: \"block\";█*360| /** Claude/Codex-compatible model-visible continuation reason */█*361| reason?: string;█362|}█363|█364|/** Return type for `session_before_tree` handlers */\u000f█</out>█# Tool call ¶█//Reading OMP shared events█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\", selector=\"1-280\")█<out>█\u000eURL: https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts█Content-Type: text/plain█Method: text█---█/**█* Event payload and result shapes shared between the extensions and hooks█* subsystems.█*█* Both subsystems observe the same agent/session lifecycle, so the *event*█* payloads (what happened) and the simpler *result* shapes (handler return█* values that don't depend on subsystem-specific identifiers like█* `AgentMessage` vs `Message`) are intentionally identical.█*█* Anything that diverges between the two subsystems - UI context, runtime█* context, command context, tool-call discrimination, or return shapes that█* carry subsystem-specific message types - lives in the per-subsystem█* `types.ts` files and is documented there.█*/█import type { AgentMessage } from \"@oh-my-pi/pi-agent-core\";█import type { CompactionPreparation, CompactionResult } from \"@oh-my-pi/pi-agent-core/compaction\";█import type { AssistantRetryRecovery, ImageContent, TextContent, ToolResultMessage } from \"@oh-my-pi/pi-ai\";█import type { Rule } from \"../capability/rule\";█import type { Goal, GoalModeState } from \"../goals/state\";█import typ [...7033ch elided...] overy: AssistantRetryRecovery;█}█/** Fired when auto-retry ends */█export interface AutoRetryEndEvent {█type: \"auto_retry_end\";█success: boolean;█attempt: number;█finalError?: string;█recoveredErrors?: RecoveredRetryError[];█}█// ============================================================================█// TTSR / Todo Reminders█// ============================================================================█/** Fired when TTSR rule matching interrupts generation */█export interface TtsrTriggeredEvent {█type: \"ttsr_triggered\";█rules: Rule[];█}█/** Fired when todo reminder logic detects unfinished todos */█export interface TodoReminderEvent {█type: \"todo_reminder\";█todos: TodoItem[];█attempt: number;█maxAttempts: number;█}█[99 more lines in URL output. Use :284 to continue]\u000f█</out>█# Tool call ¶█//Finding context event result█grep(pattern=\"interface ContextEvent|ContextEventResult|messages\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 65| type: \"session_before_compact\";█*66| /** Compaction preparation with messages to summarize, file ops, previous summary, etc. */█67| preparation: CompactionPreparation;█68| /** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */█69| branchEntries: SessionEntry[];█...█79| sessionId: string;█*80| messages: AgentMessage[];█81|}█82|█83|/** Fired after context compaction */█...█98| type: \"session_stop\";█*99| messages: AgentMessage[];█100| turn_id: number;█101| last_assistant_message?: AgentMessage;█102| session_id: string;█...█171| *█*172| * Original session messages are NOT modified - only the messages sent to the█173| * LLM are affected when a handler returns a replacement (the return shape█174| * differs between extensions and hooks; see each subsystem's█*175| * `ContextEventResult`).█176| */█*177|export interface ContextEvent {█178| type: \"context\";█179| /** Messages about to be sent to the LLM (deep copy, safe to modify) */█*180| messages: AgentMessage[];█181|}█182|█183|/**█...█192| type: \"agent_end\";█*193| messages: AgentMessage[];█194|}█195|█196|/** Fired at the start of each turn */█...█327| * - `cancel: true` -> nothing happens, user stays in current session█*328| * - `skipConversationRestore: true` -> branch happens, but messages stay as-is█*329| * - neither -> branch happens AND messages rewind to branch point (default)█330| */█331| skipConversationRestore?: boolean;█332|}\u000f█</out>█# Tool call ¶█//Finding prompt event contracts█grep(pattern=\"interface InputEvent|BeforeAgentStartEvent|InputEventResult|input\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e 167| timeout?: number;█*168| /** Invoked when the UI times out while waiting for a selection/input */█169| onTimeout?: () => void;█170| /** Invoked when the UI-managed timeout countdown starts */█171| onTimeoutStart?: () => void;█*172| /** Invoked when user input resets a UI-managed timeout countdown */█173| onTimeoutReset?: () => void;█174| /** Initial cursor position for select dialogs (0-indexed) */█175| initialIndex?: number;█...█198|█*199|/** Raw terminal input listener for extensions. */█200|export type TerminalInputHandler = (data: string) => { consume?: boolean; data?: string } | undefined;█201|█202|export type WidgetPlacement = \"aboveEditor\" | \"belowEditor\";█...█220|// Parallel to HookUIContext: extensions expose a strictly larger UI surface█*221|// (custom editor component, header/footer, widgets, theming, terminal input)█222|// and may be invoked from event handlers that have already taken the agent█223|// loop's lock - hooks intentionally cannot.█224|export interface ExtensionUIContext {█...█236|█*237| /** Show a text input dialog. */█*238| input(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions): Promise<string | undefined>;█[...4589ch elided...] _call\", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;█...█1241| * thinking: { mode: \"anthropic-adaptive\", efforts: [\"minimal\", \"low\", \"medium\", \"high\"] },█*1242| * input: [\"text\", \"image\"],█*1243| * cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },█1244| * contextWindow: 200000,█1245| * maxTokens: 64000,█1246| * ]█...█1314| thinking?: Model[\"thinking\"];█*1315| /** Supported input types. */█*1316| input: (\"text\" | \"image\")[];█1317| /** Cost per million tokens. */█*1318| cost: { input: number; output: number; cacheRead: number; cacheWrite: number };█1319| /** Premium Copilot requests charged per user-initiated request. */█1320| premiumMultiplier?: number;█1321| /** Maximum context window size in tokens. */\u000f█</out>█# Tool call ¶█//Finding compact options█grep(pattern=\"export interface CompactOptions|customInstructions|instructionsOrOptions|onComplete|onError\", path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=\"330-430\", case=true, gitignore=true, skip=null)█<out>█\u000e 352|█*353|export interface CompactOptions {█*354| onComplete?: (result: CompactionResult) => void;█*355| onError?: (error: Error) => void;█356| /**█357| * Force a one-off compaction mode for this invocation, overriding the█358| * configured `compaction.strategy` / `remoteEnabled` (the `/compact`█...█363| * Internal summarizer guidance - piped only to native summarization, never█*364| * exposed as `customInstructions` on the `session_before_compact` extension█365| * hook. Used by plan-mode \"Approve and compact context\" so extensions that█*366| * treat `customInstructions` as user focus don't mistake plan-mode█367| * boilerplate for the operator's intent (issue #4359).█368| *█*369| * When both `customInstructions` and `internalGuidance` are set, the█370| * summarizer uses `internalGuidance`; the hook still sees only the public█*371| * `customInstructions`.█372| */█373| internalGuidance?: string;█374|}█...█415| /** Compact the session context (interactive mode shows UI). */█*416| compact(instructionsOrOptions?: string | CompactOptions): Promise<void>;█417| /** Whether UI is available (false in print/RPC mode) */█418| hasUI: boolean;█419| /** Current working directory */\u000f█</out>█# Assistant ¶█_**Verifying systemPromptAppend necessity**_█# Tool call ¶█//Reading OMP prompt event shapes█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=\"595-750\")█<out>█\u000eexport type {█...█SessionStartEvent,█SessionSwitchEvent,█SessionTreeEvent,█TreePreparation,█} from \"../shared-events\";█// ============================================================================█// Agent Events█// ============================================================================█export type { ContextEvent } from \"../shared-events\";█/** Fired before a provider request is sent. Can replace the payload. */█export interface BeforeProviderRequestEvent {█type: \"before_provider_request\";█payload: unknown;█}█/** Fired after a provider response is received, before its stream body is consumed. */█export interface AfterProviderResponseEvent extends ProviderResponseMetadata {█type: \"after_provider_response\";█}█/** Fired after user submits prompt but before agent loop. */█export interface BeforeAgentStartEvent {█type: \"before_agent_start\";█prompt: string;█images?: ImageContent[];█systemPrompt: string[];█}█export type {█AgentEndEvent,█AgentStartEvent,█SessionStopEvent,█SessionStopEventResult,█TurnEndEvent,█TurnStartEvent,█} from \"../shared-events\";█/** Fired when a message starts (user, assistant, or toolResult) */█export interface MessageStartEvent {█type: [...2629ch elided...] ================================█// Input Events█// ============================================================================█/** Fired when the user submits input (interactive mode only). */█export interface InputEvent {█type: \"input\";█text: string;█images?: ImageContent[];█source: \"interactive\" | \"rpc\" | \"extension\";█}█// ============================================================================█// Tool Events█// ============================================================================█export interface ToolApprovalRequestedEvent {█type: \"tool_approval_requested\";█sessionId: string;█toolCallId: string;█toolName: string;█reason?: string;█approvalMode: ApprovalMode;█}█export interface ToolApprovalResolvedEvent {█...█}█[728 more lines in URL output. Use :754 to continue]\u000f█</out>█# Tool call ¶█//Reading OMP prompt result shapes█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=\"930-985\")█<out>█\u000e | ToolCallEvent█| ToolResultEvent█| ToolApprovalRequestedEvent█| ToolApprovalResolvedEvent;█// ============================================================================█// Event Results█// ============================================================================█export interface ContextEventResult {█messages?: AgentMessage[];█}█export type BeforeProviderRequestEventResult = unknown;█export type { ToolCallEventResult } from \"../shared-events\";█/** Result from input event handler */█export interface InputEventResult {█/** If true, the input was handled and should not continue through normal flow */█handled?: boolean;█/** Replace the input text */█text?: string;█/** Replace any pending images */█images?: ImageContent[];█}█/** Result from user_bash event handler */█export interface UserBashEventResult {█/** Full replacement: extension handled execution, use this result */█result?: BashResult;█}█/** Result from user_python event handler */█export interface UserPythonEventResult {█/** Full replacement: extension handled execution, use this result */█result?: PythonResult;█}█export type { ToolResultEventResult } from \"../shared-events\";█export interface BeforeAgentStartEventResult {█message?: CustomMessagePayload;█/** Replace the system prompt for this turn. If multiple extensions return this, they are chained. */█systemPrompt?: string[];█}█export type {█SessionBeforeBranchResult,█SessionBeforeCompactResult,█SessionBeforeSwitchResult,█SessionBeforeTreeResult,█SessionCompactingResult,█} from \"../shared-events\";█// ============================================================================█// Message Rendering█// ============================================================================█export interface MessageRenderOptions {█...█}█[493 more lines in URL output. Use :989 to continue]\u000f█</out>█# Tool call ¶█//Reading OMP compact options█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/extensions/types.ts\", selector=\"340-425\")█<out>█\u000eexport interface ExtensionUIContext {█...█/** Get current tool output expansion state. */█getToolsExpanded(): boolean;█/** Set tool output expansion state. */█setToolsExpanded(expanded: boolean): void;█}█// ============================================================================█// Extension Context█// ============================================================================█export interface ContextUsage {█/** Estimated context tokens. */█tokens: number;█contextWindow: number;█/** Context usage as percentage of context window. */█percent: number;█}█export interface CompactOptions {█onComplete?: (result: CompactionResult) => void;█onError?: (error: Error) => void;█/**█* Force a one-off compaction mode for this invocation, overriding the█* configured `compaction.strategy` / `remoteEnabled` (the `/compact`█* subcommands: `soft` | `remote` | `snapcompact`). Omitted = configured behavior.█*/█mode?: CompactMode;█/**█* Internal summarizer guidance - piped only to native summarization, never█* exposed as `customInstructions` on the `session_before_compact` extension█* hook. Used by plan-mode \"Approve and compact context\" so extensions that█* treat `c [...1743ch elided...] int release shares a token, Claude and GPT differ. Backed by catalog canonical█* identity. Compare it; do not persist it (the vocabulary tracks new releases).█*/█family(model: Model): string;█}█export interface ExtensionContext {█/** UI methods for user interaction */█ui: ExtensionUIContext;█/** Get current context usage for the active model. */█getContextUsage(): ContextUsage | undefined;█/** Compact the session context (interactive mode shows UI). */█compact(instructionsOrOptions?: string | CompactOptions): Promise<void>;█/** Whether UI is available (false in print/RPC mode) */█hasUI: boolean;█/** Current working directory */█cwd: string;█/** Session manager (read-only) */█sessionManager: ReadonlySessionManager;█...█}█[1053 more lines in URL output. Use :429 to continue]\u000f█</out>█# Tool call ¶█//Reading stop continuation shape█read(path=\"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/extensibility/shared-events.ts\", selector=\"340-365\")█<out>█\u000e█/** Return type for `session_before_compact` handlers */█export interface SessionBeforeCompactResult {█/** If true, cancel the compaction */█cancel?: boolean;█/** Custom compaction result - SessionManager adds id/parentId */█compaction?: CompactionResult;█}█/** Return type for `session.compacting` handlers */█export interface SessionCompactingResult {█/** Additional context lines to include in summary */█context?: string[];█/** Override the default compaction prompt */█prompt?: string;█/** Custom data to store in compaction entry */█preserveData?: Record<string, unknown>;█}█/** Return type for `session_stop` handlers */█export interface SessionStopEventResult {█/** Continue the main session with additional context before settling */█continue?: boolean;█/** OMP-native model-visible context for the continuation */█additionalContext?: string;█/** Claude/Codex-compatible block decision; maps to a continuation */█decision?: \"block\";█/** Claude/Codex-compatible model-visible continuation reason */█reason?: string;█}█[14 more lines in URL output. Use :369 to continue]\u000f█</out>█# Assistant ¶█_**Redesigning systemPrompt replacement and startup briefing**█**Defining clear-intent hint patterns and startup briefing rules**█**Implementing fetch with AbortController for adapter version checks**_█# Tool call ¶█//Inspecting notification listing█bash(command=\"spt notif list --help\", cwd=\".\", timeout=30)█<out>█\u000eList notifications (all member subnets, or one)█Usage: spt.exe notif list [OPTIONS]█Options:█--json Emit machine-readable JSON instead of the human view. Honored by the█read/status commands (list, whoami, status, description, role, the *-list█queries, how-to); action commands ignore it█--subnet <SUBNET> Limit to one subnet█-h, --help Print help█Wall time: 0.13 seconds\u000f█</out>█# Tool call ¶█//Inspecting update notifications█bash(command=\"spt --json notif list\", cwd=\".\", timeout=30)█<out>█\u000e{█\"notifs\": [█{█\"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:106\",█\"subnet\": \"SPT_DEV\",█\"kind\": \"consent\",█\"state\": \"dismissed\",█\"from_id\": \"spt-update\",█\"head\": \"update-available 5\"█},█{█\"notif_id\": \"ecb39e40e3400d46ddca73914685fb91b2d82969119e42293408511e27e55657:190\",█\"subnet\": \"SPT_DEV\",█\"kind\": \"consent\",█\"state\": \"dismissed\",█\"from_id\": \"spt-update\",█\"head\": \"update-available 5\"█},█{█\"notif_id\": \"cfd9fc552b44f9da7b7146baee3eb18c7b7514e01c5ad06e367d3f15765c3f6f:154\",█\"subnet\": \"SPT_DEV\",█\"kind\": \"consent\",█\"state\": \"dismissed\",█\"from_id\": \"spt-update\",█\"head\": \"update-available 5\"█},█{█\"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:141\",█\"subnet\": \"SPT_DEV\",█\"kind\": \"consent\",█\"state\": \"dismissed\",█\"from_id\": \"spt-update\",█\"head\": \"update-available 5\"█},█{█\"notif_id\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d:142\",█\"subnet\": \"SPT_DEV\",█\"kind\": \"consent\",█\"state\": \"dismissed\",█\"from_ [...9390ch elided...] c4474b60d1284b122bdc1a91c85f2d:372697\",█\"subnet\": \"BIGNET\",█\"kind\": \"rollback\",█\"state\": \"dismissed\",█\"from_id\": \"spt-update\",█\"head\": \"update v53 failed to come up - rolled back to v51, quarantined\"█},█{█\"notif_id\": \"c8939d2f12b7488cf658a694b500f2da3ab32fa478dfe078557a862534baa573:148\",█\"subnet\": \"BIGNET\",█\"kind\": \"consent\",█\"state\": \"seen:7\",█\"from_id\": \"spt-update\",█\"head\": \"An spt-core update v0.31.0 is available.\"█},█{█\"notif_id\": \"f15d837bdeff3d56f5d5a21bdcd6acb9632a764cb13c477cad966ccb811be884:24\",█\"subnet\": \"BIGNET\",█\"kind\": \"consent\",█\"state\": \"seen:2\",█\"from_id\": \"spt-update\",█\"head\": \"An spt-core update v0.32.0 is available.\"█}█]█}█Wall time: 0.28 seconds\u000f█</out>█# Tool call ¶█//Inspecting adapter version█bash(command=\"spt adapter version omp-spt\", cwd=\".\", timeout=30)█<out>█\u000e0.2.1█Wall time: 0.28 seconds\u000f█</out>█# Tool call ¶█//Reading configured requirement roots█read(path=\"traceable-reqs.toml\", selector=\"1-40\")█<out>█\u000e[traceable-reqs.toml#9F61]█1:# OMP-native requirement registry. Evidence roots are intentionally limited to█2:# the retained adapter surface; retired foreign-harness files are not scanned.█3:█4:[scan]█5:roots = [█6: \"OMP-ADAPTER-PLAN.md\",█7: \"docs/KNOWN-HAZARDS.md\",█8: \"docs/adr/0007-native-omp-tui-hosts-spt-extension.md\",█9: \"docs/adr/0008-omp-native-product-boundary.md\",█10: \"docs/adr/0009-all-endpoints-use-native-omp.md\",█11: \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",█12: \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",█13: \"docs/adr/0012-continuity-drops-live-under-spt.md\",█14: \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",█15: \"adapter/omp-spt.toml\",█16: \"adapter/strings/omp-spt.mjs\",█17: \"tools/omp-spt/Cargo.toml\",█18: \"tools/omp-spt/src/main.rs\",█19: \"tools/omp-spt/src/digest_omp.rs\",█20: \"tools/omp-spt/src/history_omp.rs\",█21: \"tools/omp-spt/src/echo_commune_omp.rs\",█22: \"tools/omp-spt/src/psyche_omp.rs\",█23: \"tools/omp-spt/src/launch_omp.rs\",█24: \"tools/omp-spt/tests/launch_omp.rs\",█25: \"tools/omp-spt/tests/captured_session_env.rs\",█26: \"tests/manifest-shortcut.sh\",█27: \"tests/native-launch-manifest.sh\",█28: \"tests/omp-extension.mjs\",█29: \"tests/manifest-schema.sh\",█30: \"tests/adapter-archive.sh\",█31: \"ci/manifest/check-manifest.sh\",█32: \"ci/manifest/validate_manifest.py\",█33: \"ci/publish/package-adapter.sh\",█34: \"ci/publish/release-acquire-int.sh\",█35: \"ci/digest/build.sh\",█36: \"ci/digest/digest-proof-int.sh\",█37:]█38:█39:[policy]█40:required_stages = []█41:█42:[[requirements]]█43:id = \"REQ-OMP-NATIVE-TUI\"█...█48:# fake-process launch evidence must never satisfy this live endpoint requirement.█[Showing lines 1-43 of 213. Use :44 to continue]\u000f█</out>█# Assistant ¶█_**Planning startup update probe**█**Designing candidate activation flow**█**Implementing auto-resume confirmation check**█**Clarifying command argument parsing and error handling**█**Refining bind failure handling to avoid session shutdown**█**Implementing explicit endpoint identity handling and auto-resume**█**Testing API endpoint adapter inclusion**_█# Tool call ¶█//Inspecting endpoint identity JSON█bash(command=\"spt --json api endpoint-info flynn\", cwd=\".\", timeout=30)█<out>█\u000e{█\"id\": \"flynn\",█\"endpoint_type\": \"live_agent\",█\"adapter\": \"claude-spt:ccs\",█\"local_node\": {█\"label\": \"HFENDULEAM\",█\"key\": \"14efb80cb72297a1068c87a4aa45f30547c4474b60d1284b122bdc1a91c85f2d\"█},█\"attached_node\": null,█\"controlled\": false,█\"project\": \"github-com-sabermage-spt-mobile\",█\"cwd\": \"C:\\\\Users\\\\decid\\\\Documents\\\\projects\\\\spt-mobile\",█\"subnets\": [█\"SPT_DEV\",█\"BIGNET\"█]█}█Wall time: 1.30 seconds\u000f█</out>█# Assistant ¶█_**Defining compatibility by adapter and cwd**█**Filtering compatible endpoints and extending tool harness**█**Testing tool registration with compact**█**Planning tool error handling and nextTurn flow**█**Defining endpoint types and refining context compaction**█**Implementing update notice collection with fetch override**█**Refining update test harness and coverage**█**Configuring update check and session startup flow**█**Handling asynchronous update notices and command timing**█**Modifying context handler for active item injection**█**Reviewing agent turn completion and dispatch logic**█**Confirming agent_end and session_stop order handling**█**Refining event message injection and activation handling**█**Adjusting session switch blocking and traceable requirement roots**_█# Tool call ¶█//Coordinating traceability activation█irc(op=\"send\", to=\"TruthGates\", message=\"I'm adding impl/unit evidence for REQ-PARITY-READY-ACTIVATION, LIVE-ACTIVATION, LIVE-AUTO-RESUME, SAFE-BOUNDARY-DELIVERY, HAZARD-ABNORMAL-TURN-RECEIVABILITY, STARTUP-BRIEF, TARGETED-HINTS, UPDATE-NOTICE, PEER-SHORTFORM in omp-spt.mjs/tests. Are you editing traceable-reqs.toml roots/stages? Please activate these to doc+impl+unit and ensure docs/PARITY.md + ADR 0015/0017 are scanned; I'll avoid the registry if you own it.\", replyTo=null, await=false, from=null, timeoutMs=null, peek=null)█<out>█\u000eDelivered to 1 peer(s):█- TruthGates: injected\u000f█</out>█# Assistant ¶█_**Planning careful test file modification**_█# Tool call ¶█//Reading test harness continuation█read(path=\"tests/omp-extension.mjs\", selector=\"90-220\")█<out>█\u000e[omp-extension.mjs#8FB4]█63:class FakeClock {█...█83: async runNext(expectedDelay) {█...█89: timer.fn();█90: await flush();█91: }█92:}█93:█94:function createHarness(options = {}) {█95: const handlers = new Map();█96: const calls = [];█97: const children = [];█98: const submitted = [];█99: const statuses = [];█100: const notifications = [];█101: const errors = [];█102: const debug = [];█103: const clock = new FakeClock();█104: let shutdowns = 0;█105:█106: const ui = {█107: notify(message, type) {█108: notifications.push({ message, type });█109: },█110: setStatus(key, text) {█111: statuses.push({ key, text });█112: },█113: };█114: const ctx = {█115: ui,█116: sessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },█117: shutdown() {█118: shutdowns += 1;█119: },█120: };█121: const pi = {█122: logger: {█123: error(message, details) {█124: errors.push({ message, details });█125: },█126: debug(message, details) {█127: debug.push({ message, details });█128: },█129: },█130: on(name, handler) {█131: const registered = handlers.get(name) ?? [];█132: registered.push(handler);█133: handlers.set(name, registered);█134: },█135: sendUserMessage [...2146ch elided...] : handlers,█201: notifications,█202: statuses,█203: submitted,█204: get shutdowns() {█205: return shutdowns;█206: },█207: };█208:}█209:█210:function commandCalls(harness, command) {█211: return harness.calls.filter((call) => call.args[0] === command);█212:}█213:█214:function stateCalls(harness) {█215: return harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");█216:}█217:█218:async function testParsingAndReplies() {█219: assert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');█220:█221: const partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';█222: const partial = drainEvents(`noise${partialEnvelope}`);█223: assert.deepEqual(partial.events, []);█...█278:}█[Showing lines 89-223 of 1378. Use :224 to continue]\u000f█</out>█# Tool call ¶█//Reading test runner tail█read(path=\"tests/omp-extension.mjs\", selector=\"1320-1385\")█<out>█\u000e[omp-extension.mjs#8FB4]█1163:async function testShutdownFallbackStaysBelowHostCap() {█...█1319:█1320: const hardCapHarness = createHarness({█1321: shutdownBudgetMs: 1_800,█1322: shutdownCommandTimeoutMs: 5_000,█1323: killForceMs: 100,█1324: killGraceMs: 100,█1325: onRun(call) {█1326: if (call.args[0] === \"send\") return never;█1327: },█1328: });█1329: await hardCapHarness.emit(\"session_start\");█1330: await hardCapHarness.emit(\"agent_start\");█1331: hardCapHarness.children[0].stdout.emit(█1332: \"data\",█1333: '<EVENT type=\"msg\" from=\"hard-cap\">work</EVENT>',█1334: );█1335: await flush();█1336: const hardCappedShutdown = hardCapHarness.emit(\"session_shutdown\");█1337: await flush();█1338: assert.deepEqual(█1339: hardCapHarness.clock.delays().sort((a, b) => a - b),█1340: [600, 1_800],█1341: );█1342: await hardCapHarness.clock.runNext(600);█1343: await hardCappedShutdown;█1344: assert.equal(█1345: hardCapHarness.calls.filter((call) => call.args[3] === \"session-end\").length,█1346: 1,█1347: \"the phase clamp must reserve time for one session-end attempt\",█1348: );█1349: assert.ok(█1350: !hardCapHarness.errors.some(({ message }) =>█1351: message.includes(\"bounded shutdown expi [...330ch elided...] Serialization();█1362:await testOutcomeSendRetriesAndExhaustion();█1363:await testSubmissionFailureAdvancesQueue();█1364:await testFailedIdleRecoveryFailsClosed();█1365:await testListenerRestartExhaustion();█1366:await testListenerStableIntervalResetsRetries();█1367:await testFatalTeardownAwaitsInFlightOutcome();█1368:await testSessionEndRetriesAfterTransientFailure();█1369:await testHumanBusyFailureFailsClosed();█1370:await testShutdownReapsAndFailsQueuedCustody();█1371:await testListenerTerminationEscalatesAndReaps();█1372:await testProtocolCorruptionFailsClosed();█1373:await testInboundQueueOverflowReturnsAcceptedCustody();█1374:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();█1375:await testShutdownFallbackStaysBelowHostCap();█1376:█1377:console.log(\"OMP-EXTENSION OK\");█1378:\u000f█</out>█# Tool call ¶█//Reading extension registration tail█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1000-1160\")█<out>█\u000e[omp-spt.mjs#CA60]█376:export function createOmpSpt(overrides = {}) {█...█427: return function ompSpt(pi) {█...█928: function startListener() {█...█965: child.stdout.on(\"data\", (chunk) => {█...█977: while (!stopping) {█...█991: if (█...█994: ) {█...█996: void failClosed(█...█998: new Error(█999: `accepted queue limit is ${acceptedQueueLimit} messages and ${acceptedBytesLimit} bytes`,█1000: ),█1001: );█1002: return;█1003: }█1004: event.acceptedBytes = eventBytes;█1005: event.accounted = true;█1006: acceptedBytes += eventBytes;█1007: queue.push(event);█1008: }█1009: if (!agentActive && !current && !dispatching) void dispatchNext();█1010: });█1011: child.stderr.on(\"data\", (chunk) =>█1012: pi.logger.debug(\"omp-spt listener\", { output: String(chunk).trim() }),█1013: );█1014: child.on(\"error\", (error) => died(error, false));█1015: child.on(\"close\", (code, signal) => {█1016: const status = signal ? `signal ${signal}` : code;█1017: died(new Error(`spt api listen exited ${status}`), true);█1018: });█1019: ui?.setStatus(\"omp-spt\", `spt:${id}`);█1020: }█1021:█1022: // [impl->REQ-OMP-NATIVE-TUI]█1023: pi.on(\"se [...3709ch elided...] );█1133: } catch (error) {█1134: if (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);█1135: }█1136: });█1137:█1138: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1139: pi.on(\"agent_end\", (event) => {█1140: turnCompletionPromise ??= completeTurn(event);█1141: return turnCompletionPromise;█1142: });█1143:█1144: pi.on(\"session_stop\", async (event) => {█1145: turnCompletionPromise ??= completeTurn(event);█1146: await turnCompletionPromise;█1147: });█1148:█1149: pi.on(\"session_shutdown\", async (_event, ctx) => {█1150: runtimeCtx ??= ctx;█1151: ui?.setStatus(\"omp-spt\", undefined);█1152: await shutdownWithinBudget(\"OMP session shut down before your message could complete\");█1153: });█1154: };█1155:}█1156:█1157:export default createOmpSpt();█1158:\u000f█</out>█# Tool call ¶█//Reading extension state region█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"376-470\")█<out>█\u000e[omp-spt.mjs#CA60]█375:█376:export function createOmpSpt(overrides = {}) {█377: const spawnProcess = overrides.spawnProcess ?? spawn;█378: const setTimer = overrides.setTimeout ?? globalThis.setTimeout;█379: const clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;█380: const env = overrides.env ?? process.env;█381: const killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;█382: const killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;█383: const customRunSptCommand = overrides.runSptCommand;█384: const commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;█385: const runSptCommand =█386: customRunSptCommand ??█387: ((args, input, options = {}) =>█388: runSpt(args, input, {█389: clearTimeout: clearTimer,█390: commandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,█391: env,█392: killForceMs,█393: killGraceMs,█394: setTimeout: setTimer,█395: signal: options.signal,█396: spawnProcess,█397: }));█398: const shutdownBudgetMs =█399: overrides.shutdownBudgetMs ?? DEFAULT_SHUTDOWN_BUDGET_MS;█400: const requestedShutdownCommandTimeoutMs =█401: overrides.shutdownCommandTimeoutMs ?? DEFAULT_SHUTDOWN_COMMAND_ [...1864ch elided...] ation = Promise.resolve();█455: let endPromise;█456: let fatalPromise;█457: let teardownPromise;█458: let acceptedBytes = 0;█459: let overflowItem;█460: const queue = [];█461:█462: const logError = (message, error) => {█463: pi.logger.error(message, { error: errorSummary(error) });█464: ui?.notify(`${message}: ${errorSummary(error)}`, \"error\");█465: };█466:█467: function runCommand(args, input, options = {}) {█468: if (shutdownDeadlineExpired) {█469: return Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));█470: }█471: const timeoutMs =█472: options.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);█473: const controller = new AbortController();█...█528: }█...█1154: };█1155:}█[Showing lines 375-473 of 1158. Use :474 to continue]\u000f█</out>█# Assistant ¶█_**Designing helper function exports**█**Implementing backtick masking and target parsing**█**Refining update detection logic**█**Designing endpoint candidate selection**█**Implementing tie-breaking with UI select**█**Designing activation reset and failure handling**█**Refining activation flow and listener management**█**Resolving activation failure redirection cycle**█**Implementing helper edit for commands and probes**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#CA60]\\nINS.PRE 178:\\n+function maskMarkdownCode(text) {\\n+\\tconst lines = String(text).split(/(\\\\r?\\\\n)/);\\n+\\tlet fenceCharacter;\\n+\\tlet fenceLength = 0;\\n+\\treturn lines\\n+\\t\\t.map((line) => {\\n+\\t\\t\\tif (/^\\\\r?\\\\n$/.test(line)) return line;\\n+\\t\\t\\t [...4645ch elided...] ed setup skill.\\\",\\n+\\t\\t\\\"- Subnets: `spt how-to subnet`.\\\",\\n+\\t\\t\\\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\\\",\\n+\\t].join(\\\"\\\\n\\\");\\n+}\\n+\\n*** End Patch\\n\")█<out>█\u000eThis edit anchors to lines 178 of adapter/strings/omp-spt.mjs that [adapter/strings/omp-spt.mjs#CA60] never displayed (it showed a partial range, a search hit, or a folded summary). Actual file content at those lines:█178:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;█Verify the content matches what you intend to touch, then re-issue the edit with the same [path#tag] header - a straight retry now succeeds without a re-read. If the content does NOT match, fix your line numbers.\u000f█</out>█# Assistant ¶█_**Retrying failed edit**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#CA60]\\nINS.PRE 178:\\n+function maskMarkdownCode(text) {\\n+\\tconst lines = String(text).split(/(\\\\r?\\\\n)/);\\n+\\tlet fenceCharacter;\\n+\\tlet fenceLength = 0;\\n+\\treturn lines\\n+\\t\\t.map((line) => {\\n+\\t\\t\\tif (/^\\\\r?\\\\n$/.test(line)) return line;\\n+\\t\\t\\t [...4645ch elided...] ed setup skill.\\\",\\n+\\t\\t\\\"- Subnets: `spt how-to subnet`.\\\",\\n+\\t\\t\\\"- Versions/updates: `spt --version`; `spt adapter version omp-spt`; `spt update`.\\\",\\n+\\t].join(\\\"\\\\n\\\");\\n+}\\n+\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#5412]█163:function injectEnvelope(messages, item) {█176:}█177:█178:function maskMarkdownCode(text) {█179: const lines = String(text).split(/(\\r?\\n)/);█...█316:}█317:█318:const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;█319:const DEFAULT_KILL_GRACE_MS = 100;\u000f█</out>█# Assistant ¶█_**Adding config options before state return**_█# Tool call ¶█//Regrounding extension constructor█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"510-620\")█<out>█\u000e[omp-spt.mjs#5412]█388:export function runSpt(args, input, overrides = {}) {█...█404: return new Promise((resolve, reject) => {█...█506: if (input !== undefined) {█507: try {█...█509: } catch (error) {█510: void terminateAndReject(error);█511: }█512: }█513: });█514:}█515:█516:export function createOmpSpt(overrides = {}) {█517: const spawnProcess = overrides.spawnProcess ?? spawn;█518: const setTimer = overrides.setTimeout ?? globalThis.setTimeout;█519: const clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;█520: const env = overrides.env ?? process.env;█521: const killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;█522: const killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;█523: const customRunSptCommand = overrides.runSptCommand;█524: const commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;█525: const runSptCommand =█526: customRunSptCommand ??█527: ((args, input, options = {}) =>█528: runSpt(args, input, {█529: clearTimeout: clearTimer,█530: commandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,█531: env,█532: killForceMs,█533: killGraceMs,█534: setTimeout: setTimer,█535: signal: option [...2414ch elided...] ui?.notify(`${message}: ${errorSummary(error)}`, \"error\");█605: };█606:█607: function runCommand(args, input, options = {}) {█608: if (shutdownDeadlineExpired) {█609: return Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));█610: }█611: const timeoutMs =█612: options.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);█613: const controller = new AbortController();█614: activeCommands.set(controller, { args, abortTimer: undefined });█615: let command;█616: try {█617: command = Promise.resolve(█618: runSptCommand(args, input, {█619: signal: controller.signal,█620: timeoutMs,█621: }),█622: );█623: } catch (error) {█...█626: }█...█668: }█...█1294: };█1295:}█[Showing lines 509-623 of 1298. Use :624 to continue]\u000f█</out>█# Assistant ¶█_**Adding update fetch timeout and config options**_█# Assistant ¶█_**Implementing update check options**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#5412]\\nINS.POST 565:\\n+\\tconst checkUpdates = overrides.checkUpdates ?? true;\\n+\\tconst updateProbeTimeoutMs = overrides.updateProbeTimeoutMs ?? 1_500;\\n+\\tconst fetchLatestAdapterVersion =\\n+\\t\\toverrides.fetchLatestAdapterVersion ??\\n+\\t\\t(async () => [...2465ch elided...] rsion || compareVersions(version, currentVersion) <= 0) continue;\\n+\\t\\t\\tif (!newest || compareVersions(version, newest) > 0) newest = version;\\n+\\t\\t}\\n+\\t\\treturn newest;\\n+\\t}\\n+\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#13DF]█564: const listenerStableMs =█565: overrides.listenerStableMs === false ? undefined : (overrides.listenerStableMs ?? 30_000);█566: const checkUpdates = overrides.checkUpdates ?? true;█567: const updateProbeTimeoutMs = overrides.updateProbeTimeoutMs ?? 1_500;█...█588: }█589: });█590:█591: const checkpointParameters = (pi) => {█592: const z = pi.zod?.z ?? pi.zod;█...█648:█649:█650: return function ompSpt(pi) {█651: const id = env.SPT_ENDPOINT_ID?.trim();█1377: };\u000f█</out>█# Tool call ¶█//Acknowledging manifest ownership█irc(op=\"send\", to=\"MuslRelease\", message=\"Acknowledged; I am not touching adapter/omp-spt.toml. Your isolated comment correction is safe.\", replyTo=null, await=false, from=null, timeoutMs=null, peek=null)█<out>█\u000eDelivered to 1 peer(s):█- MuslRelease: woken\u000f█</out>█# Assistant ¶█_**Planning precise text replacement**_█# Tool call ¶█//Reading extension state after insert█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"645-715\")█<out>█\u000e[omp-spt.mjs#13DF]█631: function newestCoreUpdate(rawNotifications, currentVersion) {█...█634: for (const notification of notifications) {█...█644: if (!newest || compareVersions(version, newest) > 0) newest = version;█645: }█646: return newest;█647: }█648:█649:█650: return function ompSpt(pi) {█651: const id = env.SPT_ENDPOINT_ID?.trim();█652: if (!id) return;█653:█654: let sid;█655: let token;█656: let listener;█657: let listenerBuffer = \"\";█658: let listenerRestartCount = 0;█659: let listenerStableTimer;█660: let restartTimer;█661: let dispatchTimer;█662: let bindPromise;█663: let agentActive = false;█664: let desiredState = \"idle\";█665: let dispatching = false;█666: let turnCompletionPromise;█667: let listenerTerminationPromise;█668: let shutdownMode = false;█669: let shutdownDeadlineExpired = false;█670: const activeCommands = new Map();█671: const retryWaiters = new Set();█672: let current;█673: let stopping = false;█674: let ui;█675: let runtimeCtx;█676: let endpointState;█677: let stateOperation = Promise.resolve();█678: let endPromise;█679: let fatalPromise;█680: let teardownPromise;█681: let acceptedBytes = 0;█682: let overflowItem;█683: c [...576ch elided...] nds.set(controller, { args, abortTimer: undefined });█698: let command;█699: try {█700: command = Promise.resolve(█701: runSptCommand(args, input, {█702: signal: controller.signal,█703: timeoutMs,█704: }),█705: );█706: } catch (error) {█707: activeCommands.delete(controller);█708: return Promise.reject(error);█709: }█710: if (customRunSptCommand) {█711: const rawCommand = command;█712: command = new Promise((resolve, reject) => {█713: let timer;█714: let finished = false;█715: const finish = (error, value) => {█716: if (finished) return;█717: finished = true;█718: if (timer !== undefined) clearTimer(timer);█...█722: };█...█744: });█745: }█...█751: }█...█1377: };█[Showing lines 644-718 of 1381. Use :719 to continue]\u000f█</out>█# Assistant ¶█_**Refactoring identifier and state handling**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#13DF]\\nSWAP 651.=652:\\n+\\t\\tlet id = env.SPT_ENDPOINT_ID?.trim() || undefined;\\n+\\t\\tconst initialId = id;\\n+\\t\\tlet activationType;\\n+\\t\\tlet activationPromise;\\n+\\t\\tlet activated = false;\\n+\\t\\tlet startupBriefPending = false;\\n+\\t\\tlet updateNoticesPromise = Promise.resolve([]);\\n+\\t\\tlet updateNoticesPending = true;\\n+\\t\\tlet cachedReadyIds = [];\\n+\\t\\tlet cachedLiveIds = [];\\nINS.POST 662:\\n+\\t\\tlet listenerGeneration = 0;\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#8E1D]█649:█650: return function ompSpt(pi) {█651: let id = env.SPT_ENDPOINT_ID?.trim() || undefined;█652: const initialId = id;█...█659: let cachedReadyIds = [];█660: let cachedLiveIds = [];█661:█662: let sid;█669: let dispatchTimer;█670: let bindPromise;█671: let listenerGeneration = 0;█672: let agentActive = false;█673: let desiredState = \"idle\";█1386: };\u000f█</out>█# Assistant ¶█_**Evaluating listenerGeneration usage**_█# Tool call ¶█//Reading command runner boundary█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"685-785\")█<out>█\u000e[omp-spt.mjs#8E1D]█684: let runtimeCtx;█685: let endpointState;█686: let stateOperation = Promise.resolve();█687: let endPromise;█688: let fatalPromise;█689: let teardownPromise;█690: let acceptedBytes = 0;█691: let overflowItem;█692: const queue = [];█693:█694: const logError = (message, error) => {█695: pi.logger.error(message, { error: errorSummary(error) });█696: ui?.notify(`${message}: ${errorSummary(error)}`, \"error\");█697: };█698:█699: function runCommand(args, input, options = {}) {█700: if (shutdownDeadlineExpired) {█701: return Promise.reject(new Error(\"omp-spt shutdown deadline expired\"));█702: }█703: const timeoutMs =█704: options.timeoutMs ?? (shutdownMode ? shutdownCommandTimeoutMs : commandTimeoutMs);█705: const controller = new AbortController();█706: activeCommands.set(controller, { args, abortTimer: undefined });█707: let command;█708: try {█709: command = Promise.resolve(█710: runSptCommand(args, input, {█711: signal: controller.signal,█712: timeoutMs,█713: }),█714: );█715: } catch (error) {█716: activeCommands.delete(controller);█717: return Promise.reject(error);█718: }█719: if (customRunSp [...1622ch elided...] : if (allowBindGrace && isBind && active.abortTimer === undefined) {█766: active.abortTimer = setTimer(█767: () => controller.abort(reason),█768: shutdownCommandTimeoutMs,█769: );█770: active.abortTimer?.unref?.();█771: continue;█772: }█773: controller.abort(reason);█774: }█775: }█776:█777: function waitForRetry(delay) {█778: if (shutdownMode) return Promise.resolve();█779: return new Promise((resolve) => {█780: let timer;█781: const finish = () => {█782: if (timer !== undefined) clearTimer(timer);█783: retryWaiters.delete(finish);█784: resolve();█785: };█786: retryWaiters.add(finish);█787: timer = setTimer(finish, delay);█788: timer?.unref?.();█789: });█790: }█[Showing lines 684-788 of 1390. Use :789 to continue]\u000f█</out>█# Assistant ¶█_**Inserting detection functions after runCommand**█**Detailing endpoint activation and error handling**█**Implementing activation promise cleanup and failClosed logic**█**Refining update detection and probe sequencing**█**Fixing probe empty result handling**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#8E1D]\\nINS.POST 760:\\n+\\t\\t// [impl->REQ-PARITY-UPDATE-NOTICE]\\n+\\t\\tasync function detectUpdateNotices() {\\n+\\t\\t\\tconst [coreVersionResult, notificationsResult, adapterVersionResult, latestAdapterResult] =\\n+\\t\\t\\t\\tawait Promise.allSettled([\\n+\\t\\t\\t [...11168ch elided...] +\\t\\t\\t\\treturn;\\n+\\t\\t\\t} else {\\n+\\t\\t\\t\\tnextId = trimmed;\\n+\\t\\t\\t}\\n+\\t\\t\\tif (!nextId) return;\\n+\\t\\t\\tawait activateEndpoint(nextId, type, ctx, { announce: true });\\n+\\t\\t}\\n+\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#60FE]█699: function runCommand(args, input, options = {}) {█755: return command.finally(() => {█759: });█760: }█761: // [impl->REQ-PARITY-UPDATE-NOTICE]█762: async function detectUpdateNotices() {█...█769: ]);█770: const notices = [];█771:█772: if (█773: coreVersionResult.status === \"fulfilled\" &&█...█1072:█1073:█1074: function abortActiveCommands(reason, allowBindGrace = false) {█1075: for (const [controller, active] of activeCommands) {█1086: }█1087: }\u000f█</out>█# Assistant ¶█_**Planning command and tool registration insertion**_█# Tool call ¶█//Reading activation handler boundary█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1015-1090\")█<out>█\u000e[omp-spt.mjs#60FE]█962: async function activateEndpoint(nextId, type, ctx, options = {}) {█...█989: const operation = (async () => {█...█1007: try {█...█1014: activated = true;█1015: startupBriefPending = true;█1016: ui.setStatus(\"omp-spt\", `spt:${id}`);█1017: startListener();█1018: beginUpdateProbe();█1019: if (options.announce) {█1020: ui.notify(█1021: `OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,█1022: \"info\",█1023: );█1024: }█1025: return true;█1026: } catch (error) {█1027: ui.setStatus(\"omp-spt\", \"spt bind failed\");█1028: if (options.fatal || bound) {█1029: await failClosed(`omp-spt could not bind ${id}`, error);█1030: return false;█1031: }█1032: pi.logger.error(`omp-spt could not bind ${id}`, {█1033: error: errorSummary(error),█1034: });█1035: ui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");█1036: id = undefined;█1037: activationType = undefined;█1038: bindPromise = undefined;█1039: token = undefined;█1040: return false;█1041: }█1042: })();█1043: activationPromise = operation;█1044: try [...1064ch elided...] ommands(reason, allowBindGrace = false) {█1075: for (const [controller, active] of activeCommands) {█1076: const isBind = active.args[0] === \"api\" && active.args[3] === \"bind\";█1077: if (allowBindGrace && isBind && active.abortTimer === undefined) {█1078: active.abortTimer = setTimer(█1079: () => controller.abort(reason),█1080: shutdownCommandTimeoutMs,█1081: );█1082: active.abortTimer?.unref?.();█1083: continue;█1084: }█1085: controller.abort(reason);█1086: }█1087: }█1088:█1089: function waitForRetry(delay) {█1090: if (shutdownMode) return Promise.resolve();█1091: return new Promise((resolve) => {█1092: let timer;█1093: const finish = () => {█...█1097: };█...█1101: });█1102: }█[Showing lines 1014-1093 of 1702. Use :1094 to continue]\u000f█</out>█# Assistant ¶█_**Refining activation type checks**█**Fixing closure array mutation**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#60FE]\\nINS.POST 1071:\\n+\\t\\tpi.registerCommand(\\\"ready\\\", {\\n+\\t\\t\\tdescription: \\\"Activate this OMP session as a ready SPT endpoint\\\",\\n+\\t\\t\\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\\n+\\t\\t\\thandler: (args, ctx) => handleActi [...2560ch elided...] `,\\n+\\t\\t\\t\\t\\t\\t\\t},\\n+\\t\\t\\t\\t\\t\\t],\\n+\\t\\t\\t\\t\\t\\tdetails: { ok: false, reason: errorSummary(error) },\\n+\\t\\t\\t\\t\\t\\tisError: true,\\n+\\t\\t\\t\\t\\t};\\n+\\t\\t\\t\\t}\\n+\\t\\t\\t},\\n+\\t\\t});\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#D27D]█1051: async function handleActivationCommand(type, args, ctx) {█1070: await activateEndpoint(nextId, type, ctx, { announce: true });█1071: }█1072: pi.registerCommand(\"ready\", {█1073: description: \"Activate this OMP session as a ready SPT endpoint\",█1074: getArgumentCompletions: commandCompletions(cachedReadyIds, false),█1075: handler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),█1076: });█1077:█1078: pi.registerCommand(\"live\", {█1079: description: \"Activate this OMP session as a live SPT endpoint\",█1080: getArgumentCompletions: commandCompletions(cachedLiveIds, true),█1081: handler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),█1082: });█1083:█1084: // [impl->REQ-PARITY-CHECKPOINT]█1085: pi.registerTool({█...█1151:█1152:█1153: function abortActiveCommands(reason, allowBindGrace = false) {█1154: for (const [controller, active] of activeCommands) {█1165: }█1166: }\u000f█</out>█# Assistant ¶█_**Assigning AgentSurface checkpoint and planning tests**_█# Tool call ¶█//Locating activation candidate cache█grep(pattern=\"cachedReadyIds =|cachedLiveIds =\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#D27D]█658: let updateNoticesPending = true;█*659: let cachedReadyIds = [];█*660: let cachedLiveIds = [];█661:█662: let sid;█663: let token;█...█858: const ids = candidates.map((candidate) => candidate.id).sort();█*859: if (type === \"ready_agent\") cachedReadyIds = ids;█*860: else cachedLiveIds = ids;█861: return candidates;█862: }█863:\u000f█</out>█# Assistant ¶█_**Editing targeted code lines**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#D27D]\\nSWAP 859.=860:\\n+\\t\\t\\tif (type === \\\"ready_agent\\\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\\n+\\t\\t\\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#17B7]█820: async function compatibleCandidates(type, ctx) {█857: const candidates = detailed.filter(Boolean);█858: const ids = candidates.map((candidate) => candidate.id).sort();█859: if (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);█860: else cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);█861: return candidates;█862: }\u000f█</out>█# Assistant ¶█_**Refactoring listener generation and session start**_█# Tool call ¶█//Reading extension lifecycle after activation additions█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1480-1785\")█<out>█\u000e[omp-spt.mjs#17B7]█516:export function createOmpSpt(overrides = {}) {█...█650: return function ompSpt(pi) {█...█1464: async function rejectItem(item, reason, error) {█...█1478: if (!stopping) {█1479: desiredState = \"idle\";█1480: try {█1481: await setState(\"idle\");█1482: } catch (stateError) {█1483: await failClosed(█1484: \"omp-spt could not restore idle state after a failed submission\",█1485: stateError,█1486: );█1487: }█1488: }█1489: }█1490:█1491: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1492: async function dispatchNext() {█1493: if (stopping || agentActive || dispatching || current || queue.length === 0) return;█1494: dispatching = true;█1495: const item = queue.shift();█1496: current = item;█1497: try {█1498: try {█1499: desiredState = \"busy\";█1500: await setState(\"busy\");█1501: } catch (error) {█1502: await rejectItem(item, \"could not accept your message\", error);█1503: return;█1504: }█1505: if (stopping) return;█1506: if (agentActive) {█1507: if (current === item) current = undefined;█1508: queue.unshift(item);█1509: return;█1510: }█1511: item.stub = senderStub(item.from ?? \"unknown\");█[...8794ch elided...] );█1756: } catch (error) {█1757: if (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);█1758: }█1759: });█1760:█1761: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1762: pi.on(\"agent_end\", (event) => {█1763: turnCompletionPromise ??= completeTurn(event);█1764: return turnCompletionPromise;█1765: });█1766:█1767: pi.on(\"session_stop\", async (event) => {█1768: turnCompletionPromise ??= completeTurn(event);█1769: await turnCompletionPromise;█1770: });█1771:█1772: pi.on(\"session_shutdown\", async (_event, ctx) => {█1773: runtimeCtx ??= ctx;█1774: ui?.setStatus(\"omp-spt\", undefined);█1775: await shutdownWithinBudget(\"OMP session shut down before your message could complete\");█1776: });█1777: };█1778:}█1779:█1780:export default createOmpSpt();█1781:\u000f█</out>█# Assistant ¶█_**Replacing session_start block**█**Implementing dispatch function error handling**█**Handling multi-target dispatch statuses**█**Refining update and startup flow**█**Adding timestamps to user messages**█**Ensuring idle state before shutdown**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#17B7]\\nSWAP.BLK 1646:\\n+\\t\\tpi.on(\\\"session_start\\\", async (_event, ctx) => {\\n+\\t\\t\\truntimeCtx = ctx;\\n+\\t\\t\\tui = ctx.ui;\\n+\\t\\t\\tsid = ctx.sessionManager.getSessionId();\\n+\\t\\t\\tif (!initialId) return;\\n+\\t\\t\\tawait activateEndpoint(initialId, undef [...1028ch elided...] rrent.settling && !current.activeInjected) {\\n+\\t\\t\\t\\tmessages = injectEnvelope(messages, current);\\n+\\t\\t\\t}\\n+\\t\\t\\tif (messages !== event.messages) return { messages };\\n+\\t\\t});\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#4F98]█SWAP.BLK 1646 -> resolved lines 1646-1689 (44 lines)█SWAP.BLK 1692 -> resolved lines 1692-1698 (7 lines)█SWAP.BLK 1708 -> resolved lines 1708-1712 (5 lines)█1646: pi.on(\"session_start\", async (_event, ctx) => {█1648: ui = ctx.ui;█1649: sid = ctx.sessionManager.getSessionId();█1650: if (!initialId) return;█1651: await activateEndpoint(initialId, undefined, ctx, { fatal: true });█1652: });█1653:█1654: // [impl->REQ-OMP-SESSION-IMMUTABLE]█1655: const blockSessionChange = (description, ctx) => {█1656: if (!activated && !token) return;█1657: ctx.ui.notify(█1658: `omp-spt blocked the in-TUI ${description}; end this SPT session first`,█1660: );█1662: };█1670:█1671: // [impl->REQ-OMP-MESSAGE-CONTEXT]█1672: // [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]█1673: pi.on(\"context\", (event) => {█1674: let messages = event.messages;█1675: if (█...█1695: messages = injectEnvelope(messages, current);█1696: }█1697: if (messages !== event.messages) return { messages };█1698: });\u000f█</out>█# Assistant ¶█_**Inserting before_agent_start and shortform functions**_█# Tool call ¶█//Reading lifecycle insertion point█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1640-1775\")█<out>█\u000e[omp-spt.mjs#4F98]█516:export function createOmpSpt(overrides = {}) {█...█650: return function ompSpt(pi) {█...█1551: function startListener() {█...█1638: child.on(\"close\", (code, signal) => {█1639: const status = signal ? `signal ${signal}` : code;█1640: died(new Error(`spt api listen exited ${status}`), true);█1641: });█1642: ui?.setStatus(\"omp-spt\", `spt:${id}`);█1643: }█1644:█1645: // [impl->REQ-OMP-NATIVE-TUI]█1646: pi.on(\"session_start\", async (_event, ctx) => {█1647: runtimeCtx = ctx;█1648: ui = ctx.ui;█1649: sid = ctx.sessionManager.getSessionId();█1650: if (!initialId) return;█1651: await activateEndpoint(initialId, undefined, ctx, { fatal: true });█1652: });█1653:█1654: // [impl->REQ-OMP-SESSION-IMMUTABLE]█1655: const blockSessionChange = (description, ctx) => {█1656: if (!activated && !token) return;█1657: ctx.ui.notify(█1658: `omp-spt blocked the in-TUI ${description}; end this SPT session first`,█1659: \"warning\",█1660: );█1661: return { cancel: true };█1662: };█1663:█1664: pi.on(\"session_before_switch\", (event, ctx) =>█1665: blockSessionChange(`${event.reason} session switch`, ctx),█1666: );█1667: pi.on(\"session_before_branch\" [...2240ch elided...] );█1742: } catch (error) {█1743: if (!stopping) await failClosed(\"omp-spt could not mark the endpoint busy\", error);█1744: }█1745: });█1746:█1747: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1748: pi.on(\"agent_end\", (event) => {█1749: turnCompletionPromise ??= completeTurn(event);█1750: return turnCompletionPromise;█1751: });█1752:█1753: pi.on(\"session_stop\", async (event) => {█1754: turnCompletionPromise ??= completeTurn(event);█1755: await turnCompletionPromise;█1756: });█1757:█1758: pi.on(\"session_shutdown\", async (_event, ctx) => {█1759: runtimeCtx ??= ctx;█1760: ui?.setStatus(\"omp-spt\", undefined);█1761: await shutdownWithinBudget(\"OMP session shut down before your message could complete\");█1762: });█1763: };█1764:}█1765:█1766:export default createOmpSpt();█1767:\u000f█</out>█# Assistant ¶█_**Planning agent handler registration**█**Handling shortform dispatch failures**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#4F98]\\nINS.POST 1698:\\n+\\t\\t// [impl->REQ-PARITY-STARTUP-BRIEF]\\n+\\t\\t// [impl->REQ-PARITY-TARGETED-HINTS]\\n+\\t\\t// [impl->REQ-PARITY-UPDATE-NOTICE]\\n+\\t\\tpi.on(\\\"before_agent_start\\\", async (event) => {\\n+\\t\\t\\tif (!activated || !id || stopping) return [...3180ch elided...] or) {\\n+\\t\\t\\t\\tif (stopping) return;\\n+\\t\\t\\t\\tawait failClosed(\\\"omp-spt could not mark the endpoint idle\\\", error);\\n+\\t\\t\\t\\treturn;\\n+\\t\\t\\t}\\n+\\t\\t\\tscheduleDispatch();\\n+\\t\\t}\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#F56A]█SWAP.BLK 1700 -> resolved lines 1700-1733 (34 lines)█1673: pi.on(\"context\", (event) => {█1697: if (messages !== event.messages) return { messages };█1698: });█1699: // [impl->REQ-PARITY-STARTUP-BRIEF]█1700: // [impl->REQ-PARITY-TARGETED-HINTS]█...█1719: };█1720: });█1721:█1722: // [impl->REQ-PARITY-PEER-SHORTFORM]█1723: async function dispatchShortforms(messages, afterUserMessage) {█...█1757:█1758: // [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]█1759: async function completeTurn(event) {█1760: agentActive = false;█1761: desiredState = \"idle\";█1762: if (stopping) return;█1763: const messages = event.messages ?? [];█1764: const completed = current;█1765: if (completed?.submitted && !completed.settled) {█1766: const reply = extractReply(messages, completed.stub);█1767: try {█1768: await settleItem(█1771: );█1772: } catch (error) {█1779: }█1780: }█1781: await dispatchShortforms(messages, completed?.stub);█1782: if (current === completed) {█1783: current = undefined;█1785: }█1794: }\u000f█</out>█# Assistant ¶█_**Confirming SWAP.BLK line adjustments**_█# Tool call ¶█//Checking extension state usage█grep(pattern=\"listenerGeneration|activationType|updateNoticesPending|cachedReadyIds\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#F56A]█652: const initialId = id;█*653: let activationType;█654: let activationPromise;█655: let activated = false;█656: let startupBriefPending = false;█657: let updateNoticesPromise = Promise.resolve([]);█*658: let updateNoticesPending = true;█*659: let cachedReadyIds = [];█660: let cachedLiveIds = [];█661:█662: let sid;█...█670: let bindPromise;█*671: let listenerGeneration = 0;█672: let agentActive = false;█673: let desiredState = \"idle\";█674: let dispatching = false;█...█808: function beginUpdateProbe() {█*809: updateNoticesPending = true;█810: updateNoticesPromise = checkUpdates█811: ? detectUpdateNotices().catch((error) => {█812: pi.logger.debug(\"omp-spt update probe skipped\", {█...█858: const ids = candidates.map((candidate) => candidate.id).sort();█*859: if (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);█860: else cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);█861: return candidates;█862: }█...█986: id = nextId;█*987: activationType = type;█988: let bound = false;█989: const operation = (async () => {█990: const bindArgs = [█...█103 [...76ch elided...] dPromise = undefined;█1039: token = undefined;█1040: return false;█...█1073: description: \"Activate this OMP session as a ready SPT endpoint\",█*1074: getArgumentCompletions: commandCompletions(cachedReadyIds, false),█1075: handler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),█1076: });█1077:█...█1098: }█*1099: if (activationType === \"ready_agent\") {█1100: return {█1101: content: [█1102: {█...█1710: if (hints.length > 0) additions.push(`OMP SPT targeted hints:\\n- ${hints.join(\"\\n- \")}`);█*1711: if (updateNoticesPending) {█*1712: updateNoticesPending = false;█1713: const notices = await updateNoticesPromise;█1714: if (notices.length > 0) additions.push(`OMP SPT updates:\\n- ${notices.join(\"\\n- \")}`);█1715: }\u000f█</out>█# Assistant ¶█_**Removing listenerGeneration and updating tag line**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#F56A]\\nDEL 671.=671\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#C069]█669: let dispatchTimer;█670: let bindPromise;█671: let agentActive = false;█672: let desiredState = \"idle\";\u000f█</out>█# Assistant ¶█_**Checking syntax with Node.js**_█# Tool call ¶█//Checking extension syntax█bash(command=\"node --check adapter/strings/omp-spt.mjs\", cwd=\".\", timeout=30)█<out>█\u000e(no output)█Wall time: 0.19 seconds\u000f█</out>█# Assistant ¶█_**Extending tests harness options and imports**█**Verifying activation and shutdown lifecycle handling**_█# Tool call ¶█//Regrounding extension test harness█read(path=\"tests/omp-extension.mjs\", selector=\"1-215\")█<out>█\u000e[omp-extension.mjs#8FB4]█1:import assert from \"node:assert/strict\";█2:import { EventEmitter } from \"node:events\";█3:import {█4: createOmpSpt,█5: decodeBody,█6: drainEvents,█7: extractReply,█8: runSpt,█9:} from \"../adapter/strings/omp-spt.mjs\";█10:█11:const flush = () => new Promise((resolve) => setImmediate(resolve));█12:function deferred() {█13: let resolve;█14: let reject;█15: const promise = new Promise((resolvePromise, rejectPromise) => {█16: resolve = resolvePromise;█17: reject = rejectPromise;█18: });█19: return { promise, reject, resolve };█20:}█21:█22:class FakeStream extends EventEmitter {█23: setEncoding(encoding) {█24: this.encoding = encoding;█25: }█26:█27: end(input) {█28: this.input = input;█29: if (this.onEnd?.(input) === false) return;█30: this.emit(\"finish\");█31: }█32:}█33:█34:class FakeChild extends EventEmitter {█35: constructor(options = {}) {█36: super();█37: this.stdin = new FakeStream();█38: this.stdout = new FakeStream();█39: this.stderr = new FakeStream();█40: this.exitCode = null;█41: this.signalCode = null;█42: this.kills = 0;█43: this.killSignals = [];█44: this.onKill = options.onKill;█45: }█46:█47: close(code = 0, signal = null) {█48: th [...4068ch elided...] ? []) {█186: const returned = await handler({ type: name, ...event }, ctx);█187: if (returned !== undefined) result = returned;█188: }█189: return result;█190: }█191:█192: return {█193: calls,█194: children,█195: clock,█196: ctx,█197: debug,█198: emit,█199: errors,█200: handlers,█201: notifications,█202: statuses,█203: submitted,█204: get shutdowns() {█205: return shutdowns;█206: },█207: };█208:}█209:█210:function commandCalls(harness, command) {█211: return harness.calls.filter((call) => call.args[0] === command);█212:}█213:█214:function stateCalls(harness) {█215: return harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");█216:}█217:█218:async function testParsingAndReplies() {█...█278:}█[Showing lines 1-218 of 1378. Use :219 to continue]\u000f█</out>█# Assistant ¶█_**Refactoring imports and command helpers**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[tests/omp-extension.mjs#8FB4]\\nINS.POST 7:\\n+\\tparsePeerShortforms,\\nINS.POST 102:\\n+\\tconst commands = new Map();\\n+\\tconst tools = new Map();\\n+\\tconst sentMessages = [];\\n+\\tconst selections = [];\\n+\\tconst confirmations = [];\\n+\\tconst inputs = [];\\n+\\tconst compactions = [];\\ [...1705ch elided...] ,\\nINS.POST 192:\\n+\\t\\tcommands,\\n+\\t\\tconfirmations,\\n+\\t\\tcompactions,\\nINS.POST 198:\\n+\\t\\tinputs,\\nINS.POST 201:\\n+\\t\\tselections,\\n+\\t\\tsentMessages,\\nINS.POST 203:\\n+\\t\\ttools,\\n*** End Patch\\n\")█<out>█\u000e[tests/omp-extension.mjs#835A]█3:import {█6: drainEvents,█7: extractReply,█8: parsePeerShortforms,█9: runSpt,█10:} from \"../adapter/strings/omp-spt.mjs\";█102: const errors = [];█103: const debug = [];█104: const commands = new Map();█105: const tools = new Map();█...█109: const inputs = [];█110: const compactions = [];█111: const clock = new FakeClock();█112: let shutdowns = 0;█113:█114: const fakeSchema = {█115: describe() {█...█129: };█130:█131: const ui = {█132: notify(message, type) {█134: },█135: setStatus(key, text) {█136: statuses.push({ key, text });█137: },█138: async select(title, values) {█139: selections.push({ title, values });█...█148: return options.onInput?.(title, placeholder) ?? options.inputResults?.shift();█149: },█150: };█151: const ctx = {█152: ui,█153: hasUI: options.hasUI ?? true,█154: cwd: options.cwd ?? \"C:\\\\work\\\\project\",█...█157: return options.onCompact?.(compactionOptions);█158: },█159: sessionManager: { getSessionId: () => options.sessionId ?? \"session-1\" },█160: shutdown() {█162: },█163: };█164: const pi = {█165: zod: { z },█166: logger: {█167: error(message, details) {█169: },█173: },█174: on(name, handler) {█177: hand [...255ch elided...] ;█213: const extension = createOmpSpt({█214: env: {█215: SPT_ENDPOINT_ID: Object.hasOwn(options, \"id\") ? options.id : \"omp-agent\",█216: OMP_SPT_SUBNET: options.subnet,█217: OMP_SPT_SPT_BIN: \"spt-test\",█218: },█219: checkUpdates: options.checkUpdates ?? false,█220: fetchLatestAdapterVersion: options.fetchLatestAdapterVersion,█221: acceptedBytesLimit: options.acceptedBytesLimit,█222: acceptedQueueLimit: options.acceptedQueueLimit,█236: });█247:█248: return {█249: commands,█250: confirmations,█251: compactions,█252: calls,█253: children,█256: debug,█257: emit,█258: inputs,█259: errors,█260: handlers,█261: notifications,█262: selections,█263: sentMessages,█264: statuses,█265: submitted,█266: tools,█267: get shutdowns() {█268: return shutdowns;█269: },█270: };\u000f█</out>█# Assistant ¶█_**Verifying context retention in return values**_█# Tool call ¶█//Checking harness return shape█read(path=\"tests/omp-extension.mjs\", selector=\"230-275\")█<out>█\u000e[omp-extension.mjs#835A]█95:function createHarness(options = {}) {█...█213: const extension = createOmpSpt({█...█229: killForceMs: options.killForceMs ?? 4,█230: killGraceMs: options.killGraceMs ?? 3,█231: listenerBufferLimit: options.listenerBufferLimit,█232: runSptCommand,█233: spawnProcess,█234: setTimeout: clock.setTimeout.bind(clock),█235: clearTimeout: clock.clearTimeout.bind(clock),█236: });█237: extension(pi);█238:█239: async function emit(name, event = {}) {█240: let result;█241: for (const handler of handlers.get(name) ?? []) {█242: const returned = await handler({ type: name, ...event }, ctx);█243: if (returned !== undefined) result = returned;█244: }█245: return result;█246: }█247:█248: return {█249: commands,█250: confirmations,█251: compactions,█252: calls,█253: children,█254: clock,█255: ctx,█256: debug,█257: emit,█258: inputs,█259: errors,█260: handlers,█261: notifications,█262: selections,█263: sentMessages,█264: statuses,█265: submitted,█266: tools,█267: get shutdowns() {█268: return shutdowns;█269: },█270: };█271:}█272:█273:function commandCalls(harness, command) {█274: return harness.calls.filter((call) => call.args[0] === command);█275:}█276:█277:function stateCalls(harness) {█278: return harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");█279:}█[Showing lines 229-278 of 1441. Use :279 to continue]\u000f█</out>█# Assistant ¶█_**Running focused tests on failures**_█# Tool call ¶█//Running extension tests█bash(command=\"node tests/omp-extension.mjs\", cwd=\".\", timeout=120)█<out>█\u000enode:internal/modules/run_main:107█triggerUncaughtException(█^█AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:█+ actual - expected█[█'session_start',█'session_before_switch',█'session_before_branch',█'context',█+ 'before_agent_start',█'agent_start',█'agent_end',█'session_stop',█'session_shutdown'█]█at testLifecycleCustodyAndContext (file:///C:/Users/decid/Documents/projects/omp-spt/tests/omp-extension.mjs:349:9)█at file:///C:/Users/decid/Documents/projects/omp-spt/tests/omp-extension.mjs:1423:7 {█generatedMessage: true,█code: 'ERR_ASSERTION',█actual: [█'session_start',█'session_before_switch',█'session_before_branch',█'context',█'before_agent_start',█'agent_start',█'agent_end',█'session_stop',█'session_shutdown'█],█expected: [█'session_start',█'session_before_switch',█'session_before_branch',█'context',█'agent_start',█'agent_end',█'session_stop',█'session_shutdown'█],█operator: 'deepStrictEqual',█diff: 'simple'█}█Node.js v25.8.2█Wall time: 0.06 seconds█Command exited with code 1\u000f█</out>█# Tool call ¶█//Reading lifecycle handler assertion█read(path=\"tests/omp-extension.mjs\", selector=\"335-365\")█<out>█\u000e[omp-extension.mjs#835A]█281:async function testParsingAndReplies() {█...█331: assert.equal(█332: extractReply(█333: [█334: { role: \"assistant\", content: \"stale answer\" },█335: { role: \"user\", content: '<msg from=\"doyle\"/>' },█336: ],█337: '<msg from=\"doyle\"/>',█338: ),█339: \"\",█340: );█341:}█342:█343:// [unit->REQ-OMP-EXTENSION-CUSTODY]█344:// [unit->REQ-OMP-SESSION-IMMUTABLE]█345:// [unit->REQ-OMP-MESSAGE-CONTEXT]█346:// [unit->REQ-OMP-NATIVE-TUI]█347:async function testLifecycleCustodyAndContext() {█348: const harness = createHarness({ subnet: \"mesh-a\" });█349: assert.deepEqual([...harness.handlers.keys()], [█350: \"session_start\",█351: \"session_before_switch\",█352: \"session_before_branch\",█353: \"context\",█354: \"agent_start\",█355: \"agent_end\",█356: \"session_stop\",█357: \"session_shutdown\",█358: ]);█359:█360: await harness.emit(\"session_start\");█361: assert.deepEqual(harness.calls[0], {█362: args: [█363: \"api\",█364: \"--adapter\",█365: \"omp-spt\",█366: \"bind\",█367: \"omp-agent\",█368: \"--set-session-id\",█...█372: ],█...█374: });█...█486:}█[Showing lines 334-368 of 1441. Use :369 to continue]\u000f█</out>█# Tool call ¶█edit(input=\"*** Begin Patch\\n[tests/omp-extension.mjs#835A]\\nINS.POST 353:\\n+\\t\\t\\\"before_agent_start\\\",\\n*** End Patch\\n\")█<out>█\u000e[tests/omp-extension.mjs#3EE9]█352: \"session_before_branch\",█353: \"context\",█354: \"before_agent_start\",█355: \"agent_start\",█356: \"agent_end\",\u000f█</out>█# Tool call ¶█//Rerunning extension tests█bash(command=\"node tests/omp-extension.mjs\", cwd=\".\", timeout=120)█<out>█\u000eOMP-EXTENSION OK█Wall time: 0.07 seconds\u000f█</out>█# Assistant ¶█_**Planning focused acceptance tests**█**Detailing ready selection and error path tests**█**Refining subnet and checkpoint patterns**█**Designing cancellation and failure recovery tests**█**Verifying multi-target send statuses**█**Identifying production bugs and fixing prompt regex**_█# Tool call ¶█//Locating targeted hint patterns█grep(pattern=\"spt\\\\\\\\s\\\\+\\\\)\\\\?subnet|checkpoint\\\\\\\\b\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#C069]█290: if (█*291: /\\b(?:spt\\s+)?subnet\\b/i.test(text) ||█292: /\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)█293: ) {█294: hints.push(\"Run `spt how-to subnet` for private-network onboarding.\");█...█296: if (█*297: /\\bcheckpoint\\b/i.test(text) ||█298: /\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||█299: /\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)█300: ) {\u000f█</out>█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#C069]\\nSWAP 291.=292:\\n+\\t\\t/\\\\bspt\\\\s+(?:how-to\\\\s+)?subnet\\\\b/i.test(text) ||\\n+\\t\\t/\\\\bsubnet\\\\s+(?:status|create|join|code|onboarding|setup)\\\\b/i.test(text) ||\\n+\\t\\t/\\\\b(?:pair|join|connect)\\\\s+(?:these\\\\s+|two\\\\s+)?(?:machines|nodes)\\\\b/i.test(tex [...77ch elided...] t\\t/\\\\b(?:make|take|create|use|run|perform|need|want)\\\\b.{0,20}\\\\bcheckpoint\\\\b/i.test(text) ||\\n+\\t\\t/\\\\bcheckpoint\\\\s+(?:my|this|the)\\\\s+(?:context|session|work)\\\\b/i.test(text) ||\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#F43A]█282: if (█287: ) {█289: }█290: if (█291: /\\bspt\\s+(?:how-to\\s+)?subnet\\b/i.test(text) ||█292: /\\bsubnet\\s+(?:status|create|join|code|onboarding|setup)\\b/i.test(text) ||█293: /\\b(?:pair|join|connect)\\s+(?:these\\s+|two\\s+)?(?:machines|nodes)\\b/i.test(text)█294: ) {█296: }█297: if (█298: /(?:^|\\s)\\/checkpoint(?:\\s|$)/i.test(text) ||█299: /\\b(?:make|take|create|use|run|perform|need|want)\\b.{0,20}\\bcheckpoint\\b/i.test(text) ||█300: /\\bcheckpoint\\s+(?:my|this|the)\\s+(?:context|session|work)\\b/i.test(text) ||█301: /\\bcommune\\s+(?:across|to\\s+(?:the\\s+)?next\\s+session)\\b/i.test(text) ||█302: /\\b(?:reset|compact)\\s+(?:my\\s+|the\\s+)?(?:working\\s+)?context\\b/i.test(text)█303: ) {█305: }\u000f█</out>█# Assistant ¶█_**Planning test insertion before runner**_█# Tool call ¶█//Reading updated test tail█read(path=\"tests/omp-extension.mjs\", selector=\"1370-1460\")█<out>█\u000e[omp-extension.mjs#3EE9]█1227:async function testShutdownFallbackStaysBelowHostCap() {█...█1369: assert.deepEqual(█1370: commandCalls(inFlightHarness, \"send\").map((call) => call.args[1]),█1371: [\"in-flight\", \"in-flight\"],█1372: );█1373: assert.match(commandCalls(inFlightHarness, \"send\")[1].input, /OMP session shut down/);█1374: assert.equal(█1375: inFlightHarness.calls.filter((call) => call.args[3] === \"session-end\").length,█1376: 1,█1377: );█1378: assert.equal(inFlightHarness.shutdowns, 0);█1379: assert.deepEqual(inFlightHarness.clock.delays(), []);█1380: inFlightOutcome.resolve();█1381: await flush();█1382: assert.equal(commandCalls(inFlightHarness, \"send\").length, 2);█1383:█1384: const hardCapHarness = createHarness({█1385: shutdownBudgetMs: 1_800,█1386: shutdownCommandTimeoutMs: 5_000,█1387: killForceMs: 100,█1388: killGraceMs: 100,█1389: onRun(call) {█1390: if (call.args[0] === \"send\") return never;█1391: },█1392: });█1393: await hardCapHarness.emit(\"session_start\");█1394: await hardCapHarness.emit(\"agent_start\");█1395: hardCapHarness.children[0].stdout.emit(█1396: \"data\",█1397: '<EVENT type=\"msg\" from=\"hard-cap\">work</EVENT>',█1398: );█1399: await flush();█1400: c [...923ch elided...] Serialization();█1426:await testOutcomeSendRetriesAndExhaustion();█1427:await testSubmissionFailureAdvancesQueue();█1428:await testFailedIdleRecoveryFailsClosed();█1429:await testListenerRestartExhaustion();█1430:await testListenerStableIntervalResetsRetries();█1431:await testFatalTeardownAwaitsInFlightOutcome();█1432:await testSessionEndRetriesAfterTransientFailure();█1433:await testHumanBusyFailureFailsClosed();█1434:await testShutdownReapsAndFailsQueuedCustody();█1435:await testListenerTerminationEscalatesAndReaps();█1436:await testProtocolCorruptionFailsClosed();█1437:await testInboundQueueOverflowReturnsAcceptedCustody();█1438:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();█1439:await testShutdownFallbackStaysBelowHostCap();█1440:█1441:console.log(\"OMP-EXTENSION OK\");█1442:\u000f█</out>█# Assistant ¶█_**Inserting test helpers and verifying session behavior**█**Refining onRun argument filtering and bind logic**█**Updating startup argument handling and version probing**█**Tracing agent shutdown sequence**█**Differentiating shutdown event modes**█**Testing argument completion fallback**█**Adding comprehensive tests**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[tests/omp-extension.mjs#3EE9]\\nINS.PRE 1422:\\n+// [unit->REQ-PARITY-READY-ACTIVATION]\\n+// [unit->REQ-PARITY-LIVE-ACTIVATION]\\n+async function testNativeActivationCommandsAndErrors() {\\n+\\tconst inert = createHarness({ id: null });\\n+\\tassert.deepEqual([...inert.commands.keys()], [...18295ch elided...] , /native compaction cancelled/);\\n+\\tassert.deepEqual(failed.sentMessages, [], \\\"a failed reset must never queue a false wake\\\");\\n+\\tawait failed.emit(\\\"session_shutdown\\\");\\n+}\\n+\\n*** End Patch\\n\")█<out>█\u000e[tests/omp-extension.mjs#9217]█1227:async function testShutdownFallbackStaysBelowHostCap() {█1420:}█1421:█1422:// [unit->REQ-PARITY-READY-ACTIVATION]█1423:// [unit->REQ-PARITY-LIVE-ACTIVATION]█...█1907:}█1908:█1909:await testParsingAndReplies();█1910:await testRunSptRejectsStdinErrorsAndHungCommands();\u000f█</out>█# Assistant ¶█_**Adding runner calls before existing code**_█# Tool call ¶█//Reading expanded test runner█read(path=\"tests/omp-extension.mjs\", selector=\"1895-1945\")█<out>█\u000e[omp-extension.mjs#9217]█1859:async function testNativeCheckpointTool() {█...█1894: const failed = createHarness({█1895: onCompact() {█1896: throw new Error(\"native compaction cancelled\");█1897: },█1898: });█1899: await failed.emit(\"session_start\");█1900: const failure = await failed.tools█1901: .get(\"spt_checkpoint\")█1902: .execute(\"tool-3\", {}, undefined, undefined, failed.ctx);█1903: assert.equal(failure.isError, true);█1904: assert.match(failure.content[0].text, /native compaction cancelled/);█1905: assert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");█1906: await failed.emit(\"session_shutdown\");█1907:}█1908:█1909:await testParsingAndReplies();█1910:await testRunSptRejectsStdinErrorsAndHungCommands();█1911:await testLifecycleCustodyAndContext();█1912:await testDeferredBindLifecycleSerialization();█1913:await testOutcomeSendRetriesAndExhaustion();█1914:await testSubmissionFailureAdvancesQueue();█1915:await testFailedIdleRecoveryFailsClosed();█1916:await testListenerRestartExhaustion();█1917:await testListenerStableIntervalResetsRetries();█1918:await testFatalTeardownAwaitsInFlightOutcome();█1919:await testSessionEndRetriesAfterTransientFailure();█1920:await testHumanBusyFailureFailsClosed();█1921:await testShutdownReapsAndFailsQueuedCustody();█1922:await testListenerTerminationEscalatesAndReaps();█1923:await testProtocolCorruptionFailsClosed();█1924:await testInboundQueueOverflowReturnsAcceptedCustody();█1925:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();█1926:await testShutdownFallbackStaysBelowHostCap();█1927:█1928:console.log(\"OMP-EXTENSION OK\");█1929:\u000f█</out>█# Assistant ¶█_**Planning insertion of calls post-parsing**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[tests/omp-extension.mjs#9217]\\nINS.POST 1926:\\n+await testNativeActivationCommandsAndErrors();\\n+await testNativeActivationSelectionAndCompletion();\\n+await testExplicitLiveAutoResume();\\n+await testStartupBriefHintsAndUpdateNotices();\\n+await testActiveTurnBoundaryDeliveryAndFallback();\\n+await testAbnormalTurnsRestoreReceivability();\\n+await testPeerShortformParsingAndDispatch();\\n+await testNativeCheckpointTool();\\n*** End Patch\\n\")█<out>█\u000e[tests/omp-extension.mjs#00DB]█1925:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();█1926:await testShutdownFallbackStaysBelowHostCap();█1927:await testNativeActivationCommandsAndErrors();█1928:await testNativeActivationSelectionAndCompletion();█...█1933:await testPeerShortformParsingAndDispatch();█1934:await testNativeCheckpointTool();█1935:█1936:console.log(\"OMP-EXTENSION OK\");\u000f█</out>█# Assistant ¶█_**Running test suite**_█# Tool call ¶█//Running expanded extension tests█bash(command=\"node tests/omp-extension.mjs\", cwd=\".\", timeout=180)█<out>█\u000eOMP-EXTENSION OK█Wall time: 0.11 seconds\u000f█</out>█# Assistant ¶█_**Verifying test coverage completeness**█**Analyzing event boundary handling for tool calls**█**Exploring message injection timing during tool calls**█**Clarifying tool_call event handler sequencing**█**Optimizing concurrent command dispatching**█**Implementing concurrent queue dispatching**█**Assessing GitHub release access and checkpointing**█**Sending final contract**_█# Tool call ¶█//Confirming checkpoint wake contract█irc(op=\"send\", to=\"AgentSurface\", message=\"Checkpoint seam landed as tool `spt_checkpoint({wake?})`: requires active live endpoint, calls `ctx.compact(...)`, then `pi.sendMessage` with `{deliverAs:'nextTurn', triggerTurn:true}` (not followUp-the public OMP docs guarantee hidden post-teardown continuation for nextTurn). It returns observable ok/error and never wakes after compaction failure. Please align skill wording/tests.\", replyTo=null, await=false, from=null, timeoutMs=null, peek=null)█<out>█\u000eDelivered to 1 peer(s):█- AgentSurface: injected\u000f█</out>█# Assistant ¶█_**Planning manual code review with subagent**█**Assigning focused code reviewer**_█# Tool call ¶█//Reviewing extension changes█task(context=\"# Goal\\nReview the omp-spt native extension capability-parity implementation for correctness against focused acceptance.\\n# Constraints\\nRead-only review. Public OMP/SPT surfaces only; never inspect spt-core source. Do not run formatters, project-wide tests, or edit files.\\n# Contract\\nNative /read [...127ch elided...] ith ordered fallback; abnormal turns settle custody and restore idle; exact plain @<target[,target] body @> dispatch; no background poll; startup/hints/update injection; checkpoint tool compact+wake.\", tasks=[{\"assignment\":\"# Target\\nReview only adapter/strings/omp-spt.mjs and tests/omp-extension.mjs, focusing on the newly added parity behavior and interactions with pre-existing custody/shutdown paths.\\n# Change\\nIdentify concrete correctness bugs, race/deadlock risks, public OMP API misuse, requirement [...173ch elided...] n only actionable findings; state PASS if no findings. Do not run project-wide commands.\",\"id\":\"ExtensionReview\",\"description\":\"Review native extension parity\",\"role\":\"Native OMP Extension Reviewer\"}], agent=\"reviewer\")█<out>█\u000e<task-result id=\"NativeExtension.ExtensionReview\" agent=\"reviewer\" status=\"completed\" duration=\"20m26s\">█<meta lines=\"97\" size=\"8.3KB\" />█<preview full-output=\"agent://NativeExtension.ExtensionReview\">█{█\"findings\": [█{█\"title\": \"Correlate replies without the ephemeral context stub\",█\"body\": \"OMP's public `context` contract modifies only the provider-bound message clone; it does not persist the synthetic `<msg ...>` user message into `session_stop.messages` or `agent_end.messages`. For every item accepted by the new active-turn branch, `completed.stub` is therefore absent here, so `extractReply` returns empty and the sender receives \\\"turn ended without an assistant response\\\" even when the model produced a reply. `tests/omp-extension.mjs:1739` hides this by constructing `agent_end` from `boundary.messages`, which real OMP does not do. Record an assistant-message baseline when accepting the item and correlate the later assistant independently of the synthetic stub, then make the test pass realistic persisted messages.\",█\"priority\": 1,█\"confidence\": 0.99,█\"file_path\": \"adapter/strings/omp-spt.mjs\",█\"line_start\": 1767,█\"line_end\": 1772█[...3193ch elided...] line_end\": 1753█},█{█\"title\": \"Preserve Linux path identity during auto-resume\",█\"body\": \"`normalizePath` lowercases every path and strips every trailing slash. On supported Linux hosts, `/work/Foo` and `/work/foo` are different projects but compare equal, while the root path `/` normalizes to an empty string and disables the CWD filter entirely. `/live --auto` can consequently rank and confirm the most recent identity from another project as \\\"compatible.\\\" Resolve and compare paths with platform-appropriate case semantics, and preserve filesystem roots when removing trailing separators.\",█\"priority\": 2,█\"confidence\": 0.99,█\"file_path\": \"adapter/strings/omp-spt.mjs\",█\"line_start\": 614,█\"line_end\": 618█},█{█</preview>█</task-result>\u000f█</out>█# Assistant ¶█_**Fetching full reviewer output**_█# Tool call ¶█//Reading full extension review█read(path=\"agent://NativeExtension.ExtensionReview\", selector=\"1-220\")█<out>█\u000e{█\"findings\": [█{█\"title\": \"Correlate replies without the ephemeral context stub\",█\"body\": \"OMP's public `context` contract modifies only the provider-bound message clone; it does not persist the synthetic `<msg ...>` user message into `session_stop.messages` or `agent_end.messages`. For every item accepted by the new active-turn branch, `completed.stub` is therefore absent here, so `extractReply` returns empty and the sender receives \\\"turn ended without an assistant response\\\" even when the model produced a reply. `tests/omp-extension.mjs:1739` hides this by constructing `agent_end` from `boundary.messages`, which real OMP does not do. Record an assistant-message baseline when accepting the item and correlate the later assistant independently of the synthetic stub, then make the test pass realistic persisted messages.\",█\"priority\": 1,█\"confidence\": 0.99,█\"file_path\": \"adapter/strings/omp-spt.mjs\",█\"line_start\": 1767,█\"line_end\": 1772█},█{█\"title\": \"Re-inject active-turn messages on every provider context\",█\"body\": \"Setting `activeInjected` makes all later `context` events skip the item. Because OMP does not persi [...6522ch elided...] urn a deferred promise from `onCompact`, start `tool.execute` without awaiting it, assert `sentMessages` is empty while compaction is pending, then resolve the gate and verify exactly one wake.\",█\"priority\": 2,█\"confidence\": 0.99,█\"file_path\": \"tests/omp-extension.mjs\",█\"line_start\": 1863,█\"line_end\": 1872█}█],█\"overall_correctness\": \"incorrect\",█\"explanation\": \"The patch does not satisfy active-turn delivery and custody: OMP context replacements are nonpersistent, so accepted messages disappear after the first provider call and their replies are miscorrelated. Peer shortform completion also introduces handler-timeout and shutdown races, with additional auto-resume, checkpoint-role, Markdown parsing, and acceptance-test gaps.\",█\"confidence\": 0.99█}\u000f█</out>█# Assistant ¶█_**Planning assistant baseline capture**█**Designing assistant reply extraction helper**█**Implementing assistant count baseline reset and tracking**█**Clarifying reply handling logic**█**Refining baseline reset order**█**Reordering dispatch and timeout handling**█**Enforcing consistent command timeouts**█**Designing cross-platform path normalization**█**Implementing activation type resolution and masking logic**█**Designing comprehensive Markdown code masking**█**Refining backtick span masking with exact run matching**█**Defining poll detection logic**█**Enhancing poll detection and shutdown tests**█**Planning deferred implementation for parallelism**█**Reading lines for mask function**_█# Tool call ¶█//Reading shortform parser implementation█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"160-245\")█<out>█\u000e[omp-spt.mjs#F43A]█154:function senderStub(sender) {█155: const escaped = sender█...█159: .replaceAll(\">\", \"&gt;\");█160: return `<msg from=\"${escaped}\"/>`;█161:}█162:█163:function injectEnvelope(messages, item) {█164: const index = messages.findLastIndex(█165: (message) => message?.role === \"user\" && messageText(message) === item.stub,█166: );█167: if (index < 0) return messages;█168: const original = messages[index];█169: const content =█170: typeof original.content === \"string\"█171: ? `${original.content}\\n\\n${item.envelope}`█172: : [...(original.content ?? []), { type: \"text\", text: `\\n\\n${item.envelope}` }];█173: const injected = [...messages];█174: injected[index] = { ...original, content };█175: return injected;█176:}█177:█178:function maskMarkdownCode(text) {█179: const lines = String(text).split(/(\\r?\\n)/);█180: let fenceCharacter;█181: let fenceLength = 0;█182: return lines█183: .map((line) => {█184: if (/^\\r?\\n$/.test(line)) return line;█185: const fence = /^[ \\t]*(`{3,}|~{3,})/.exec(line);█186: if (fence) {█187: const character = fence[1][0];█188: if (!fenceCharacter) {█189: fenceCharacter = character;█190: fenceLength = fence[1].length;█191: [...1148ch elided...] f prose.matchAll(pattern)) {█224: const inner = match[1];█225: const separator = inner.search(/\\s/);█226: if (separator <= 0) continue;█227: const targetList = inner.slice(0, separator);█228: const body = inner.slice(separator).trim();█229: if (!/^[A-Za-z0-9_-]+(?:,[A-Za-z0-9_-]+)*$/.test(targetList) || !body) continue;█230: shortforms.push({█231: targets: targetList.split(\",\"),█232: body,█233: index: match.index,█234: raw: match[0],█235: });█236: }█237: return shortforms;█238:}█239:█240:function parseJson(raw, label) {█241: try {█242: return JSON.parse(raw);█243: } catch (error) {█244: throw new Error(`${label} returned invalid JSON: ${errorSummary(error)}`);█245: }█246:}█247:█248:function parseVersion(raw) {█...█251:}█[Showing lines 159-248 of 1830. Use :249 to continue]\u000f█</out>█# Assistant ¶█_**Replacing code block**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#F43A]\\nSWAP.BLK 178:\\n+function maskMarkdownCode(text) {\\n+\\tconst source = String(text);\\n+\\tconst masked = source.split(\\\"\\\");\\n+\\tlet fenceCharacter;\\n+\\tlet fenceLength = 0;\\n+\\tlet lineStart = 0;\\n+\\twhile (lineStart < source.length) {\\n+\\t\\tconst [...1702ch elided...] ) {\\n+\\t\\t\\tif (source[index] !== \\\"\\\\r\\\" && source[index] !== \\\"\\\\n\\\") masked[index] = \\\" \\\";\\n+\\t\\t}\\n+\\t\\tcursor = closing + runLength - 1;\\n+\\t}\\n+\\treturn masked.join(\\\"\\\");\\n+}\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#9F38]█SWAP.BLK 178 -> resolved lines 178-215 (38 lines)█177:█178:function m\u000easkMarkdownCode(text) {█179: const source = String(text);█180: const masked = source.split(\"\");█181: let fenceCharacter;█182: let fenceLength = 0;█183: let lineStart = 0;█184: while (lineStart < source.length) {█...█199: } else {█200: maskLine = true;█201: }█202: }█203: if (maskLine) {█204: for (let index = lineStart; index < lineEnd; index += 1) {█205: if (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";█206: }█207: }█208: lineStart = lineEnd;█...█231: }█232: return masked.join(\"\");█233:}█234:\u000f█</out>█# Assistant ¶█_**Refining fence detection and tag masking**_█# Tool call ¶█//Locating path normalization█grep(pattern=\"function normalizePath\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#9F38]█631:█*632: function normalizePath(value) {█633: return String(value ?? \"\")█634: .replaceAll(\"\\\\\", \"/\")█635: .replace(/\\/+$/, \"\")\u000f█</out>█# Tool call ¶█//Reading path helper█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"628-645\")█<out>█\u000e[omp-spt.mjs#9F38]█624: const commandCompletions = (cachedIds, includeAuto) => (prefix) => {█...█626: const matches = values█627: .filter((value) => value.startsWith(prefix.trim()))█628: .map((value) => ({ value, label: value }));█629: return matches.length > 0 ? matches : null;█630: };█631:█632: function normalizePath(value) {█633: return String(value ?? \"\")█634: .replaceAll(\"\\\\\", \"/\")█635: .replace(/\\/+$/, \"\")█636: .toLowerCase();█637: }█638:█639: function latestDigestTimestamp(digest) {█640: let latest = Number.NEGATIVE_INFINITY;█641: for (const turn of digest?.turns ?? []) {█642: for (const entry of turn?.entries ?? []) {█643: for (const value of Object.values(entry ?? {})) {█644: const parsed = Date.parse(value?.ts ?? \"\");█645: if (Number.isFinite(parsed)) latest = Math.max(latest, parsed);█646: }█647: }█648: }█...█650: }█[Showing lines 627-648 of 1848. Use :649 to continue]\u000f█</out>█# Assistant ¶█_**Refining path normalization logic**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#9F38]\\nSWAP.BLK 632:\\n+\\tfunction normalizePath(value) {\\n+\\t\\tlet normalized = String(value ?? \\\"\\\").replaceAll(\\\"\\\\\\\\\\\", \\\"/\\\");\\n+\\t\\twhile (\\n+\\t\\t\\tnormalized.endsWith(\\\"/\\\") &&\\n+\\t\\t\\tnormalized.length > 1 &&\\n+\\t\\t\\t!/^[A-Za-z]:\\\\/$/.test(normalized)\\n+\\t\\t) {\\n+\\t\\t\\tnormalized = normalized.slice(0, -1);\\n+\\t\\t}\\n+\\t\\treturn process.platform === \\\"win32\\\" ? normalized.toLowerCase() : normalized;\\n+\\t}\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#5F60]█SWAP.BLK 632 -> resolved lines 632-637 (6 lines)█631:█632: function normalizePath(value) {█633: let normalized = String(value ?? \"\").replaceAll(\"\\\\\", \"/\");█634: while (█...█640: }█641: return process.platform === \"win32\" ? normalized.toLowerCase() : normalized;█642: }█643:\u000f█</out>█# Assistant ¶█_**Adding platform override for Linux testing**_█# Tool call ¶█//Reading constructor platform location█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"535-555\")█<out>█\u000e[omp-spt.mjs#5F60]█409:export function runSpt(args, input, overrides = {}) {█...█425: return new Promise((resolve, reject) => {█...█534: });█535:}█536:█537:export function createOmpSpt(overrides = {}) {█538: const spawnProcess = overrides.spawnProcess ?? spawn;█539: const setTimer = overrides.setTimeout ?? globalThis.setTimeout;█540: const clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;█541: const env = overrides.env ?? process.env;█542: const killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;█543: const killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;█544: const customRunSptCommand = overrides.runSptCommand;█545: const commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;█546: const runSptCommand =█547: customRunSptCommand ??█548: ((args, input, options = {}) =>█549: runSpt(args, input, {█550: clearTimeout: clearTimer,█551: commandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,█552: env,█553: killForceMs,█554: killGraceMs,█555: setTimeout: setTimer,█556: signal: options.signal,█557: spawnProcess,█558: }));█...█1850:}█[Showing lines 534-558 of 1853. Use :559 to continue]\u000f█</out>█# Assistant ¶█_**Adding platform swap functionality**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#5F60]\\nINS.POST 541:\\n+\\tconst platform = overrides.platform ?? process.platform;\\nSWAP 641.=641:\\n+\\t\\treturn platform === \\\"win32\\\" ? normalized.toLowerCase() : normalized;\\n*** End Patch\\n\")█<out>█\u000eThis edit anchors to lines 641 of adapter/strings/omp-spt.mjs that [adapter/strings/omp-spt.mjs#5F60] never displayed (it showed a partial range, a search hit, or a folded summary). Actual file content at those lines:█641: return process.platform === \"win32\" ? normalized.toLowerCase() : normalized;█Verify the content matches what you intend to touch, then re-issue the edit with the same [path#tag] header - a straight retry now succeeds without a re-read. If the content does NOT match, fix your line numbers.\u000f█</out>█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#5F60]\\nINS.POST 541:\\n+\\tconst platform = overrides.platform ?? process.platform;\\nSWAP 641.=641:\\n+\\t\\treturn platform === \\\"win32\\\" ? normalized.toLowerCase() : normalized;\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#0778]█540: const clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;█541: const env = overrides.env ?? process.env;█542: const platform = overrides.platform ?? process.platform;█543: const killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;█544: const killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;█633: function normalizePath(value) {█635: while (█639: ) {█640: normalized = normalized.slice(0, -1);█641: }█642: return platform === \"win32\" ? normalized.toLowerCase() : normalized;█643: }█644:\u000f█</out>█# Assistant ¶█_**Adding assistant count functions**_█# Tool call ¶█//Reading reply extraction helpers█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"110-150\")█<out>█\u000e[omp-spt.mjs#0778]█46:export function drainEvents(raw, options = {}) {█...█51: while (true) {█...█109: if (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };█110: }█111:}█112:█113:function messageText(message) {█114: if (typeof message?.content === \"string\") return message.content;█115: return (message?.content ?? [])█116: .filter((part) => part?.type === \"text\" && typeof part.text === \"string\")█117: .map((part) => part.text)█118: .join(\"\");█119:}█120:█121:export function extractReply(messages, afterUserMessage) {█122: const allMessages = messages ?? [];█123: let start = 0;█124: if (afterUserMessage !== undefined) {█125: const userIndex = allMessages.findLastIndex((message) => {█126: if (message?.role !== \"user\") return false;█127: const text = messageText(message);█128: return text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);█129: });█130: if (userIndex < 0) return \"\";█131: start = userIndex + 1;█132: }█133: const assistant = allMessages█134: .slice(start)█135: .reverse()█136: .find((message) => message?.role === \"assistant\");█137: return assistant ? messageText(assistant) : \"\";█138:}█139:█140:function firstLine(text) {█141: return text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";█142:}█143:█144:function errorSummary(error) {█145: const detail = error instanceof Error ? error.message : String(error);█146: return firstLine(detail).trim() || \"unknown error\";█147:}█148:█149:function failureMessage(reason, error) {█150: const detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;█151: return `[omp-spt] ${reason}${detail}`;█152:}█153:█[Showing lines 109-153 of 1854. Use :154 to continue]\u000f█</out>█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#0778]\\nINS.POST 138:\\n+function assistantMessageCount(messages) {\\n+\\treturn (messages ?? []).reduce(\\n+\\t\\t(count, message) => count + (message?.role === \\\"assistant\\\" ? 1 : 0),\\n+\\t\\t0,\\n+\\t);\\n+}\\n+\\n+function extractReplyAfterAssistantCount(messages [...27ch elided...] istants = (messages ?? []).filter((message) => message?.role === \\\"assistant\\\");\\n+\\tif (assistants.length <= baseline) return \\\"\\\";\\n+\\treturn messageText(assistants.at(-1));\\n+}\\n+\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#31C9]█121:export function extractReply(messages, afterUserMessage) {█137: return assistant ? messageText(assistant) : \"\";█138:}█139:function assistantMessageCount(messages) {█140: return (messages ?? []).reduce(█...█143: );█144:}█145:█146:function extractReplyAfterAssistantCount(messages, baseline) {█147: const assistants = (messages ?? []).filter((message) => message?.role === \"assistant\");█...█151:█152:█153:function firstLine(text) {█154: return text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";█155:}\u000f█</out>█# Assistant ¶█_**Adding need state variables**_█# Tool call ¶█//Locating turn state█grep(pattern=\"turnCompletionPromise\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#31C9]█713: let dispatching = false;█*714: let turnCompletionPromise;█715: let listenerTerminationPromise;█716: let shutdownMode = false;█717: let shutdownDeadlineExpired = false;█...█1836: if (stopping) return;█*1837: turnCompletionPromise = undefined;█1838: agentActive = true;█1839: desiredState = \"busy\";█1840: try {█...█1848: pi.on(\"agent_end\", (event) => {█*1849: turnCompletionPromise ??= completeTurn(event);█*1850: return turnCompletionPromise;█1851: });█1852:█1853: pi.on(\"session_stop\", async (event) => {█*1854: turnCompletionPromise ??= completeTurn(event);█*1855: await turnCompletionPromise;█1856: });█1857:█1858: pi.on(\"session_shutdown\", async (_event, ctx) => {\u000f█</out>█# Assistant ¶█_**Adding state management**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#31C9]\\nINS.POST 714:\\n+\\t\\tlet turnAssistantBaseline;\\n+\\t\\tlet knownAssistantCount = 0;\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#0137]█713: let dispatching = false;█714: let turnCompletionPromise;█715: let turnAssistantBaseline;█716: let knownAssistantCount = 0;█717: let listenerTerminationPromise;█718: let shutdownMode = false;\u000f█</out>█# Tool call ¶█//Reading active context and completion█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1720-1865\")█<out>█\u000e[omp-spt.mjs#0137]█550:export function createOmpSpt(overrides = {}) {█...█690: return function ompSpt(pi) {█...█1714: pi.on(\"context\", (event) => {█...█1716: if (█1717: agentActive &&█...█1719: !dispatching &&█1720: queue.length > 0█1721: ) {█1722: const item = queue.shift();█1723: item.stub = senderStub(item.from ?? \"unknown\");█1724: item.submitted = true;█1725: item.activeInjected = true;█1726: current = item;█1727: messages = [█1728: ...messages,█1729: {█1730: role: \"user\",█1731: content: `${item.stub}\\n\\n${item.envelope}`,█1732: },█1733: ];█1734: }█1735: if (current?.submitted && !current.settling && !current.activeInjected) {█1736: messages = injectEnvelope(messages, current);█1737: }█1738: if (messages !== event.messages) return { messages };█1739: });█1740: // [impl->REQ-PARITY-STARTUP-BRIEF]█1741: // [impl->REQ-PARITY-TARGETED-HINTS]█1742: // [impl->REQ-PARITY-UPDATE-NOTICE]█1743: pi.on(\"before_agent_start\", async (event) => {█1744: if (!activated || !id || stopping) return;█1745: const additions = [];█1746: if (startupBriefPending) {█1747: startupBriefPending = false;█1748: additions.push(startupB [...3379ch elided...] await failClosed(\"omp-spt could not mark the endpoint busy\", error);█1846: }█1847: });█1848:█1849: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1850: pi.on(\"agent_end\", (event) => {█1851: turnCompletionPromise ??= completeTurn(event);█1852: return turnCompletionPromise;█1853: });█1854:█1855: pi.on(\"session_stop\", async (event) => {█1856: turnCompletionPromise ??= completeTurn(event);█1857: await turnCompletionPromise;█1858: });█1859:█1860: pi.on(\"session_shutdown\", async (_event, ctx) => {█1861: runtimeCtx ??= ctx;█1862: ui?.setStatus(\"omp-spt\", undefined);█1863: await shutdownWithinBudget(\"OMP session shut down before your message could complete\");█1864: });█1865: };█1866:}█1867:█1868:export default createOmpSpt();█[Showing lines 1719-1868 of 1869. Use :1869 to continue]\u000f█</out>█# Assistant ¶█_**Reviewing code at line 1708**_█# Tool call ¶█//Reading context handler start█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1704-1742\")█<out>█\u000e[omp-spt.mjs#0137]█1696: const blockSessionChange = (description, ctx) => {█...█1703: };█1704:█1705: pi.on(\"session_before_switch\", (event, ctx) =>█1706: blockSessionChange(`${event.reason} session switch`, ctx),█1707: );█1708: pi.on(\"session_before_branch\", (_event, ctx) =>█1709: blockSessionChange(\"session branch\", ctx),█1710: );█1711:█1712: // [impl->REQ-OMP-MESSAGE-CONTEXT]█1713: // [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]█1714: pi.on(\"context\", (event) => {█1715: let messages = event.messages;█1716: if (█1717: agentActive &&█1718: !current &&█1719: !dispatching &&█1720: queue.length > 0█1721: ) {█1722: const item = queue.shift();█1723: item.stub = senderStub(item.from ?? \"unknown\");█1724: item.submitted = true;█1725: item.activeInjected = true;█1726: current = item;█1727: messages = [█1728: ...messages,█1729: {█1730: role: \"user\",█1731: content: `${item.stub}\\n\\n${item.envelope}`,█1732: },█1733: ];█1734: }█1735: if (current?.submitted && !current.settling && !current.activeInjected) {█1736: messages = injectEnvelope(messages, current);█1737: }█1738: if (messages !== event.messages) return { messages };█1739: });█1740: // [impl->REQ-PARITY-STARTUP-BRIEF]█1741: // [impl->REQ-PARITY-TARGETED-HINTS]█1742: // [impl->REQ-PARITY-UPDATE-NOTICE]█1743: pi.on(\"before_agent_start\", async (event) => {█1744: if (!activated || !id || stopping) return;█1745: const additions = [];█...█1761: });█[Showing lines 1703-1745 of 1869. Use :1746 to continue]\u000f█</out>","textHead":"# User ¶█Complete the assignment below, thoroughly:█# Target█Core native extension adapter/strings/omp-spt.mjs and its focused tests in tests/omp-extension.mjs; manifest only if required. Coordinate with AgentSurface before overlapping edits.█# Change█Implement extension-native /ready and /live commands, native selection/confirmation where supported, extension-owned binding/listener convergence, explicit live auto-resume, safe-boundary active-turn injection before next tool/model continuation with ordered fallback, abnormal-turn custody settlement and receivability restoration, and @<...@> assistant-output dispatch. Preserve existing immutable binding, bounded custody, fail-closed recovery, and Worker exclusion. Activate/tag corresponding requirements.█# Acceptance█Deterministic tests cover ready/live happy/error paths, no silent identity guessing, auto-resume confirmation, active-turn boundary injection/order/fallback, cancellation/interruption/failure recovery, shortform parsing/multi-target/status/failure/non-trigger text, and no agent-managed background poll. Skip project-wide commands.█# Assistant ¶█_**Planning coordinated core edits**_█# Tool call ¶█//Coordinating extension files█irc(op=\"send\", to=\"AgentSurface\", message=\"I own strings/omp-spt.mjs and tests/omp-extension.mjs for native /ready,/live, active-turn injection, and @<...@> dispatch. Are you editing either? Please avoid these files or tell me overlap now.\", replyTo=null, await=false, from=null, timeoutMs=null, peek=null)█<out>█\u000eDelivered to 1 peer(s):█- AgentSurface: injected\u000f█</out>█# Assistant ¶█_**Starting targeted repository exploration**_█# Tool call ¶█//Mapping project root█read(path=\".\", selector=null)█<out>█\u000e.█- .claude/ 1h ago█- CONTEXT.md 7.7KB 5h ago█- SCOPE.md 4.7KB 5h ago█- traceable-reqs.toml 8.2KB 5h ago█- .spt/ 20h ago█- omp-spt-env-v1/ 4m ago█- emphasys-signoff.md 1.5KB 20h ago█- emphasys-commune.md 10.4KB 22h ago█- .gitignore 993B 20h ago█- OMP-ADAPTER-PLAN.md 8.2KB 21h ago█- CHANGELOG.md 52.4KB 21h ago█- README.md 4.4KB 21h ago█- DUPLICATE-HISTORY-PLAN.md 1.4KB 21h ago█- tests/ 22h ago█- manifest-shortcut.sh 13.2KB 21h ago█- omp-extension.mjs 44.0KB 21h ago█- native-launch-manifest.sh 2.2KB 22h ago█- release-acquire.sh 4.4KB 22h ago█- manifest-schema.sh 3.3KB 1d ago█- adapter-archive.sh 7.4KB 1d ago█- ci-gates.sh 878B 1d ago█- omp-spt-v0.2.0 0B 22h ago█- docs/ [...2286ch elided...] 9.2KB 6d ago█- PEROS-PLAN.md 2.7KB 6d ago█- HANDOFF.md 8.5KB 6d ago█- MANIFEST-PARITY-PLAN.md 9.9KB 6d ago█- MDBOOK-PLAN.md 2.6KB 6d ago█- NEXT-WORKLOAD-PLAN.md 12.0KB 6d ago█- DIGEST-FETCHER-PLAN.md 3.1KB 6d ago█- ECHO-COMMUNE-PLAN.md 3.1KB 6d ago█- CLAUDE.md 286B 6d ago█- CPLUGS-PREP-PLAN.md 2.7KB 6d ago█- CHECKPOINT-CLEAR-RACE-PLAN.md 5.6KB 6d ago█- CHECKPOINT-COMMUNE-PLAN.md 11.1KB 6d ago█- CI-ACCEPTANCE-PLAN.md 3.2KB 6d ago█- BUGS-v091.md 6.1KB 6d ago█- .gitattributes 917B 6d ago█- AGENTS.md 4.4KB 6d ago\u000f█</out>█# Tool call ¶█//Locating adapter commands█grep(pattern=\"ready|live|custod|inject|@<|binding|background poll|turn\", path=\"strings/omp-spt.mjs\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000ePath not found: strings/omp-spt.mjs\u000f█</out>█# Tool call ¶█//Locating extension tests█grep(pattern=\"ready|live|custod|inject|@<|binding|background poll|turn\", path=\"tests/omp-extension.mjs\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e[tests/omp-extension.mjs#8FB4]█18: });█*19: return { promise, reject, resolve };█20:}█21:█22:class FakeStream extends EventEmitter {█...█28: this.input = input;█*29: if (this.onEnd?.(input) === false) return;█30: this.emit(\"finish\");█31: }█32:}█...█56: const handled = this.onKill?.(signal, this);█*57: if (handled !== undefined) return handled;█58: this.close(null, signal);█*59: return true;█60: }█61:}█62:█...█71: this.timers.set(handle, { fn, delay });█*72: return handle;█73: }█74:█75: clearTimeout(handle) {█...█79: delays() {█*80: return [...this.timers.values()].map(({ delay }) => delay);█81: }█82:█83: async runNext(expectedDelay) {█...█143: const overridden = await options.onRun?.(call);█*144: if (overridden !== undefined) return overridden;█145: if (args[0] === \"api\" && args[3] === \"bind\") {█*146: return options.bindOutput ?? \"BOUND endpoint token=token-123\";█147: }█*148: return \"\";█149: };█150: const spawnProcess = (binary, args, spawnOptions) => {█151: const child = new FakeChild();█...█156: children.push(child);█*157: return child;█158: };█159: const extension = createOmpSpt({█160: env: {█...█185: for (const handler of ha [...7936ch elided...] onRun(call) {█*1326: if (call.args[0] === \"send\") return never;█1327: },█1328: });█1329: await hardCapHarness.emit(\"session_start\");█...█1359:await testRunSptRejectsStdinErrorsAndHungCommands();█*1360:await testLifecycleCustodyAndContext();█1361:await testDeferredBindLifecycleSerialization();█1362:await testOutcomeSendRetriesAndExhaustion();█1363:await testSubmissionFailureAdvancesQueue();█...█1369:await testHumanBusyFailureFailsClosed();█*1370:await testShutdownReapsAndFailsQueuedCustody();█1371:await testListenerTerminationEscalatesAndReaps();█1372:await testProtocolCorruptionFailsClosed();█*1373:await testInboundQueueOverflowReturnsAcceptedCustody();█1374:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();█1375:await testShutdownFallbackStaysBelowHostCap();█1376:\u000f█</out>█# Tool call ¶█//Finding requirement artifacts█glob(path=\".planning/**/*;docs/**/*;requirements/**/*\", hidden=true, gitignore=true, limit=300)█<out>█\u000e# docs/█PARITY.md█CI.md█RELEASE-RUNBOOK.md█DOCS-STRATEGY.md█KNOWN-HAZARDS.md█OMP-BRIDGE-FIELD-ISSUES.md█OMP-OPENROUTER.md█SPT-CORE-FINDINGS.md█TRACEABILITY.md█SKILL-AUTHORING.md█## adr/█0018-checkpoint-resets-context-natively.md█0017-active-turn-delivery-uses-safe-boundaries.md█0016-agent-capabilities-split-by-native-seam.md█0015-extension-owned-session-activation.md█0014-release-tags-use-semver-form.md█0010-native-delivery-self-heals-or-closes.md█0006-one-command-update-and-consolidated-binary.md█0005-name-unification.md█0004-checkpoint-via-self-send-loopback.md█0003-psyche-is-a-constrained-auto-approving-companion.md█0002-hook-wiring-hand-written-hooks-json-shells-spt-api.md█0001-distribution-splits-by-volatility.md█0009-all-endpoints-use-native-omp.md█0013-release-gate-stops-at-the-adapter-boundary.md█0008-omp-native-product-boundary.md█0012-continuity-drops-live-under-spt.md█0011-endpoint-session-binding-is-immutable.md█0007-native-omp-tui-hosts-spt-extension.md█0000-template.md█## formats/█adr-format.md█context-format.md█Skipped missing paths: .planning/**/*, requirements/**/*\u000f█</out>█# Assistant ¶█_**Searching for correct file path**_█# Tool call ¶█//Locating adapter internals█grep(pattern=\"ready|live|custod|inject|@<|binding|background poll|turn\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#CA60]█5:export function decodeBody(body) {█*6: return body█7: .replaceAll(\"<br>\", \"\\n\")█8: .replaceAll(\"&lt;\", \"<\")█9: .replaceAll(\"&gt;\", \">\")█...█16: error.code = \"SPT_PROTOCOL_ERROR\";█*17: return error;█18:}█19:█20:function parseEventTag(tag) {█*21: if (!tag.startsWith(\"<EVENT\")) return { error: protocolError(\"invalid opening tag\") };█22: let cursor = \"<EVENT\".length;█23: const attributes = Object.create(null);█24: while (cursor < tag.length) {█25: if (!/\\s/.test(tag[cursor])) {█*26: return { error: protocolError(\"malformed EVENT attributes\") };█27: }█28: while (cursor < tag.length && /\\s/.test(tag[cursor])) cursor += 1;█29: if (cursor === tag.length) break;█30: const match = /^([A-Za-z_:][A-Za-z0-9_.:-]*)=\"([^\"<>]*)\"/.exec(tag.slice(cursor));█*31: if (!match) return { error: protocolError(\"malformed EVENT attributes\") };█32: const [, name, value] = match;█33: if (Object.hasOwn(attributes, name)) {█*34: return { error: protocolError(`duplicate EVENT ${name} attribute`) };█35: }█36: attributes[name] = value;█37: cursor += match[0].length;█38: }█*39: if (!attributes.type) return { error: protocolError(\"missing EV [...17422ch elided...] if (stopping) return;█1120: await failClosed(\"omp-spt could not mark the endpoint idle\", error);█*1121: return;█1122: }█1123: scheduleDispatch();█1124: }█...█1126: pi.on(\"agent_start\", async () => {█*1127: if (stopping) return;█*1128: turnCompletionPromise = undefined;█1129: agentActive = true;█1130: desiredState = \"busy\";█1131: try {█...█1137:█*1138: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1139: pi.on(\"agent_end\", (event) => {█*1140: turnCompletionPromise ??= completeTurn(event);█*1141: return turnCompletionPromise;█1142: });█1143:█1144: pi.on(\"session_stop\", async (event) => {█*1145: turnCompletionPromise ??= completeTurn(event);█*1146: await turnCompletionPromise;█1147: });█1148:█1149: pi.on(\"session_shutdown\", async (_event, ctx) => {\u000f█</out>█# Tool call ¶█//Reading adapter manifest█read(path=\"adapter/omp-spt.toml\", selector=\"1-240\")█<out>█\u000e[omp-spt.toml#72C0]█1:# omp-spt - Oh My Pi harness adapter for spt-core.█2:#█3:# Native OMP owns every hosted terminal. The adapter binary is a launch,█4:# digest/history, Psyche, and echo-commune helper; OMP's packaged extension owns█5:# bind, delivery, activity state, reply, and shutdown inside the native TUI.█6:# This manifest is authored only against the published spt-core manifest and█7:# CLI contracts. See OMP-ADAPTER-PLAN.md and ADRs 0008-0013.█8:█9:[adapter]█10:name = \"omp-spt\"█11:kind = \"harness\"█12:version = \"0.2.1\"█13:# v0.31.0 added identity-preserving `api listen --session-id`, which keeps the█14:# listener on the native OMP session already recorded by the extension's bind.█15:min_spt_core_version = \"0.31.0\"█16:# [impl->REQ-OMP-READY-LIVE]█17:hostable_types = [\"LiveAgent\", \"ReadyAgent\"]█18:# Only the genuine OMP host process may resolve to this adapter.█19:host_binaries = [\"omp\"]█20:shortcut_basename = \"omp\"█21:█22:# Update through this repository's GitHub release. The packaged fat archive█23:# contains both supported target binaries plus the shared native extension.█24:# [impl->REQ-DIST-ADAPTER-RELEASE]█25:[update]█26:avenue = \"gh_release\"█27:repo = \"BigscreenVR/omp-s [...3718ch elided...] cal launch snapshot above is the█105:# smallest non-secret substitute; no API key, token, or credential is persisted.█106:█107:# The native extension uses the endpoint id injected by spt-core when binding the OMP session.█108:[env.SPT_ENDPOINT_ID]█109:direction = \"inject\"█110:value = \"{id}\"█111:█112:# Message delivery is extension-owned; no hook or PTY-translation surface is█113:# declared by the native adapter.█114:█115:# The fetcher locates one OMP session JSONL and emits the published digest█116:# record stream.█117:# [impl->REQ-DIST-DIGEST-EXTRACTOR]█118:[digest]█119:strategy = \"fetcher\"█120:extractor = \"omp-spt digest-omp --session {session_id} --project-dir \\\"{cwd}\\\"\"█121:arg_truncation = 240█122:sprint_collapse = true█123:█124:█125:[strings]█126:adapter_label = \"oh-my-pi (spt)\"█127:\u000f█</out>█# Tool call ¶█//Reading active delivery ADR█read(path=\"docs/adr/0017-active-turn-delivery-uses-safe-boundaries.md\", selector=\"1-240\")█<out>█\u000e[0017-active-turn-delivery-uses-safe-boundaries.md#F530]█1:---█2:status: accepted█3:---█4:█5:# Active-turn delivery uses safe boundaries█6:█7:A peer message accepted during an active OMP turn remains in the extension's ordered custody and is injected at the first proven boundary before the next tool or model continuation; if the turn exposes no injectable boundary, the message becomes ordinary next-turn delivery. Always waiting for the next turn was rejected because it leaves live agents unreachable during long work, while arbitrary event injection and forced interruption were rejected because they make model context, tool intent, and exactly-once correlation unpredictable.█8:\u000f█</out>█# Tool call ¶█//Reading activation ADR█read(path=\"docs/adr/0015-extension-owned-session-activation.md\", selector=\"1-240\")█<out>█\u000e[0015-extension-owned-session-activation.md#95AE]█1:---█2:status: accepted█3:---█4:█5:# Extension-owned session activation█6:█7:An ordinary OMP session may become a ready OMP endpoint or live OMP endpoint through extension-native `/ready` and `/live` commands, with argument completion or native selection dialogs and explicit live auto-resume. The packaged OMP SPT extension-not the model or an agent-started background process-binds the current OMP session and owns the authenticated listener, converging immediately on the existing custody, activity, recovery, reply, and shutdown path; after activation, the endpoint/session binding remains immutable. Model-executed activation skills were rejected because listener ownership and endpoint identity are lifecycle infrastructure, while a menu-only flow was rejected because commands provide the discoverable, scriptable agent-facing surface.█8:\u000f█</out>█# Tool call ¶█//Finding extension requirements█grep(pattern=\"READY|LIVE|ACTIVE|SHORTFORM|OUTPUT|DISPATCH|AUTO.RESUME|CUSTODY|LISTENER|BIND\", path=\"traceable-reqs.toml\", selector=null, case=false, gitignore=true, skip=null)█<out>█\u000e[traceable-reqs.toml#9F61]█10: \"docs/adr/0009-all-endpoints-use-native-omp.md\",█*11: \"docs/adr/0010-native-delivery-self-heals-or-closes.md\",█*12: \"docs/adr/0011-endpoint-session-binding-is-immutable.md\",█*13: \"docs/adr/0012-continuity-drops-live-under-spt.md\",█14: \"docs/adr/0013-release-gate-stops-at-the-adapter-boundary.md\",█15: \"adapter/omp-spt.toml\",█16: \"adapter/strings/omp-spt.mjs\",█...█46:█*47:# Intentionally inactive until an actual release runs the ADR-0013 acceptance gate. Deterministic█*48:# fake-process launch evidence must never satisfy this live endpoint requirement.█49:[[requirements]]█*50:id = \"REQ-OMP-LIVE-RELEASE-GATE\"█*51:title = \"Pending live gate: a real OMP release must satisfy the ADR-0013 endpoint acceptance criteria\"█52:required_stages = []█53:█54:[[requirements]]█...█59:[[requirements]]█*60:id = \"REQ-OMP-EXTENSION-CUSTODY\"█*61:title = \"The ","textTail":"\u000easkMarkdownCode(text) {█179: const source = String(text);█180: const masked = source.split(\"\");█181: let fenceCharacter;█182: let fenceLength = 0;█183: let lineStart = 0;█184: while (lineStart < source.length) {█...█199: } else {█200: maskLine = true;█201: }█202: }█203: if (maskLine) {█204: for (let index = lineStart; index < lineEnd; index += 1) {█205: if (source[index] !== \"\\r\" && source[index] !== \"\\n\") masked[index] = \" \";█206: }█207: }█208: lineStart = lineEnd;█...█231: }█232: return masked.join(\"\");█233:}█234:\u000f█</out>█# Assistant ¶█_**Refining fence detection and tag masking**_█# Tool call ¶█//Locating path normalization█grep(pattern=\"function normalizePath\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#9F38]█631:█*632: function normalizePath(value) {█633: return String(value ?? \"\")█634: .replaceAll(\"\\\\\", \"/\")█635: .replace(/\\/+$/, \"\")\u000f█</out>█# Tool call ¶█//Reading path helper█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"628-645\")█<out>█\u000e[omp-spt.mjs#9F38]█624: const commandCompletions = (cachedIds, includeAuto) => (prefix) => {█...█626: const matches = values█627: .filter((value) => value.startsWith(prefix.trim()))█628: .map((value) => ({ value, label: value }));█629: return matches.length > 0 ? matches : null;█630: };█631:█632: function normalizePath(value) {█633: return String(value ?? \"\")█634: .replaceAll(\"\\\\\", \"/\")█635: .replace(/\\/+$/, \"\")█636: .toLowerCase();█637: }█638:█639: function latestDigestTimestamp(digest) {█640: let latest = Number.NEGATIVE_INFINITY;█641: for (const turn of digest?.turns ?? []) {█642: for (const entry of turn?.entries ?? []) {█643: for (const value of Object.values(entry ?? {})) {█644: const parsed = Date.parse(value?.ts ?? \"\");█645: if (Number.isFinite(parsed)) latest = Math.max(latest, parsed);█646: }█647: }█648: }█...█650: }█[Showing lines 627-648 of 1848. Use :649 to continue]\u000f█</out>█# Assistant ¶█_**Refining path normalization logic**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#9F38]\\nSWAP.BLK 632:\\n+\\tfunction normalizePath(value) {\\n+\\t\\tlet normalized = String(value ?? \\\"\\\").replaceAll(\\\"\\\\\\\\\\\", \\\"/\\\");\\n+\\t\\twhile (\\n+\\t\\t\\tnormalized.endsWith(\\\"/\\\") &&\\n+\\t\\t\\tnormalized.length > 1 &&\\n+\\t\\t\\t!/^[A-Za-z]:\\\\/$/.test(normalized)\\n+\\t\\t) {\\n+\\t\\t\\tnormalized = normalized.slice(0, -1);\\n+\\t\\t}\\n+\\t\\treturn process.platform === \\\"win32\\\" ? normalized.toLowerCase() : normalized;\\n+\\t}\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#5F60]█SWAP.BLK 632 -> resolved lines 632-637 (6 lines)█631:█632: function normalizePath(value) {█633: let normalized = String(value ?? \"\").replaceAll(\"\\\\\", \"/\");█634: while (█...█640: }█641: return process.platform === \"win32\" ? normalized.toLowerCase() : normalized;█642: }█643:\u000f█</out>█# Assistant ¶█_**Adding platform override for Linux testing**_█# Tool call ¶█//Reading constructor platform location█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"535-555\")█<out>█\u000e[omp-spt.mjs#5F60]█409:export function runSpt(args, input, overrides = {}) {█...█425: return new Promise((resolve, reject) => {█...█534: });█535:}█536:█537:export function createOmpSpt(overrides = {}) {█538: const spawnProcess = overrides.spawnProcess ?? spawn;█539: const setTimer = overrides.setTimeout ?? globalThis.setTimeout;█540: const clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;█541: const env = overrides.env ?? process.env;█542: const killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;█543: const killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;█544: const customRunSptCommand = overrides.runSptCommand;█545: const commandTimeoutMs = overrides.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;█546: const runSptCommand =█547: customRunSptCommand ??█548: ((args, input, options = {}) =>█549: runSpt(args, input, {█550: clearTimeout: clearTimer,█551: commandTimeoutMs: options.timeoutMs ?? commandTimeoutMs,█552: env,█553: killForceMs,█554: killGraceMs,█555: setTimeout: setTimer,█556: signal: options.signal,█557: spawnProcess,█558: }));█...█1850:}█[Showing lines 534-558 of 1853. Use :559 to continue]\u000f█</out>█# Assistant ¶█_**Adding platform swap functionality**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#5F60]\\nINS.POST 541:\\n+\\tconst platform = overrides.platform ?? process.platform;\\nSWAP 641.=641:\\n+\\t\\treturn platform === \\\"win32\\\" ? normalized.toLowerCase() : normalized;\\n*** End Patch\\n\")█<out>█\u000eThis edit anchors to lines 641 of adapter/strings/omp-spt.mjs that [adapter/strings/omp-spt.mjs#5F60] never displayed (it showed a partial range, a search hit, or a folded summary). Actual file content at those lines:█641: return process.platform === \"win32\" ? normalized.toLowerCase() : normalized;█Verify the content matches what you intend to touch, then re-issue the edit with the same [path#tag] header - a straight retry now succeeds without a re-read. If the content does NOT match, fix your line numbers.\u000f█</out>█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#5F60]\\nINS.POST 541:\\n+\\tconst platform = overrides.platform ?? process.platform;\\nSWAP 641.=641:\\n+\\t\\treturn platform === \\\"win32\\\" ? normalized.toLowerCase() : normalized;\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#0778]█540: const clearTimer = overrides.clearTimeout ?? globalThis.clearTimeout;█541: const env = overrides.env ?? process.env;█542: const platform = overrides.platform ?? process.platform;█543: const killGraceMs = overrides.killGraceMs ?? DEFAULT_KILL_GRACE_MS;█544: const killForceMs = overrides.killForceMs ?? DEFAULT_KILL_FORCE_MS;█633: function normalizePath(value) {█635: while (█639: ) {█640: normalized = normalized.slice(0, -1);█641: }█642: return platform === \"win32\" ? normalized.toLowerCase() : normalized;█643: }█644:\u000f█</out>█# Assistant ¶█_**Adding assistant count functions**_█# Tool call ¶█//Reading reply extraction helpers█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"110-150\")█<out>█\u000e[omp-spt.mjs#0778]█46:export function drainEvents(raw, options = {}) {█...█51: while (true) {█...█109: if (events.length >= maxEvents) return { events, rest: raw.slice(cursor) };█110: }█111:}█112:█113:function messageText(message) {█114: if (typeof message?.content === \"string\") return message.content;█115: return (message?.content ?? [])█116: .filter((part) => part?.type === \"text\" && typeof part.text === \"string\")█117: .map((part) => part.text)█118: .join(\"\");█119:}█120:█121:export function extractReply(messages, afterUserMessage) {█122: const allMessages = messages ?? [];█123: let start = 0;█124: if (afterUserMessage !== undefined) {█125: const userIndex = allMessages.findLastIndex((message) => {█126: if (message?.role !== \"user\") return false;█127: const text = messageText(message);█128: return text === afterUserMessage || text.startsWith(`${afterUserMessage}\\n\\n<EVENT`);█129: });█130: if (userIndex < 0) return \"\";█131: start = userIndex + 1;█132: }█133: const assistant = allMessages█134: .slice(start)█135: .reverse()█136: .find((message) => message?.role === \"assistant\");█137: return assistant ? messageText(assistant) : \"\";█138:}█139:█140:function firstLine(text) {█141: return text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";█142:}█143:█144:function errorSummary(error) {█145: const detail = error instanceof Error ? error.message : String(error);█146: return firstLine(detail).trim() || \"unknown error\";█147:}█148:█149:function failureMessage(reason, error) {█150: const detail = error === undefined ? \"\" : `: ${errorSummary(error)}`;█151: return `[omp-spt] ${reason}${detail}`;█152:}█153:█[Showing lines 109-153 of 1854. Use :154 to continue]\u000f█</out>█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#0778]\\nINS.POST 138:\\n+function assistantMessageCount(messages) {\\n+\\treturn (messages ?? []).reduce(\\n+\\t\\t(count, message) => count + (message?.role === \\\"assistant\\\" ? 1 : 0),\\n+\\t\\t0,\\n+\\t);\\n+}\\n+\\n+function extractReplyAfterAssistantCount(messages [...27ch elided...] istants = (messages ?? []).filter((message) => message?.role === \\\"assistant\\\");\\n+\\tif (assistants.length <= baseline) return \\\"\\\";\\n+\\treturn messageText(assistants.at(-1));\\n+}\\n+\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#31C9]█121:export function extractReply(messages, afterUserMessage) {█137: return assistant ? messageText(assistant) : \"\";█138:}█139:function assistantMessageCount(messages) {█140: return (messages ?? []).reduce(█...█143: );█144:}█145:█146:function extractReplyAfterAssistantCount(messages, baseline) {█147: const assistants = (messages ?? []).filter((message) => message?.role === \"assistant\");█...█151:█152:█153:function firstLine(text) {█154: return text.split(/\\r?\\n/).find((line) => line.trim()) ?? \"\";█155:}\u000f█</out>█# Assistant ¶█_**Adding need state variables**_█# Tool call ¶█//Locating turn state█grep(pattern=\"turnCompletionPromise\", path=\"adapter/strings/omp-spt.mjs\", selector=null, case=true, gitignore=true, skip=null)█<out>█\u000e[adapter/strings/omp-spt.mjs#31C9]█713: let dispatching = false;█*714: let turnCompletionPromise;█715: let listenerTerminationPromise;█716: let shutdownMode = false;█717: let shutdownDeadlineExpired = false;█...█1836: if (stopping) return;█*1837: turnCompletionPromise = undefined;█1838: agentActive = true;█1839: desiredState = \"busy\";█1840: try {█...█1848: pi.on(\"agent_end\", (event) => {█*1849: turnCompletionPromise ??= completeTurn(event);█*1850: return turnCompletionPromise;█1851: });█1852:█1853: pi.on(\"session_stop\", async (event) => {█*1854: turnCompletionPromise ??= completeTurn(event);█*1855: await turnCompletionPromise;█1856: });█1857:█1858: pi.on(\"session_shutdown\", async (_event, ctx) => {\u000f█</out>█# Assistant ¶█_**Adding state management**_█# Tool call ¶█edit(input=\"*** Begin Patch\\n[adapter/strings/omp-spt.mjs#31C9]\\nINS.POST 714:\\n+\\t\\tlet turnAssistantBaseline;\\n+\\t\\tlet knownAssistantCount = 0;\\n*** End Patch\\n\")█<out>█\u000e[adapter/strings/omp-spt.mjs#0137]█713: let dispatching = false;█714: let turnCompletionPromise;█715: let turnAssistantBaseline;█716: let knownAssistantCount = 0;█717: let listenerTerminationPromise;█718: let shutdownMode = false;\u000f█</out>█# Tool call ¶█//Reading active context and completion█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1720-1865\")█<out>█\u000e[omp-spt.mjs#0137]█550:export function createOmpSpt(overrides = {}) {█...█690: return function ompSpt(pi) {█...█1714: pi.on(\"context\", (event) => {█...█1716: if (█1717: agentActive &&█...█1719: !dispatching &&█1720: queue.length > 0█1721: ) {█1722: const item = queue.shift();█1723: item.stub = senderStub(item.from ?? \"unknown\");█1724: item.submitted = true;█1725: item.activeInjected = true;█1726: current = item;█1727: messages = [█1728: ...messages,█1729: {█1730: role: \"user\",█1731: content: `${item.stub}\\n\\n${item.envelope}`,█1732: },█1733: ];█1734: }█1735: if (current?.submitted && !current.settling && !current.activeInjected) {█1736: messages = injectEnvelope(messages, current);█1737: }█1738: if (messages !== event.messages) return { messages };█1739: });█1740: // [impl->REQ-PARITY-STARTUP-BRIEF]█1741: // [impl->REQ-PARITY-TARGETED-HINTS]█1742: // [impl->REQ-PARITY-UPDATE-NOTICE]█1743: pi.on(\"before_agent_start\", async (event) => {█1744: if (!activated || !id || stopping) return;█1745: const additions = [];█1746: if (startupBriefPending) {█1747: startupBriefPending = false;█1748: additions.push(startupB [...3379ch elided...] await failClosed(\"omp-spt could not mark the endpoint busy\", error);█1846: }█1847: });█1848:█1849: // [impl->REQ-OMP-EXTENSION-CUSTODY]█1850: pi.on(\"agent_end\", (event) => {█1851: turnCompletionPromise ??= completeTurn(event);█1852: return turnCompletionPromise;█1853: });█1854:█1855: pi.on(\"session_stop\", async (event) => {█1856: turnCompletionPromise ??= completeTurn(event);█1857: await turnCompletionPromise;█1858: });█1859:█1860: pi.on(\"session_shutdown\", async (_event, ctx) => {█1861: runtimeCtx ??= ctx;█1862: ui?.setStatus(\"omp-spt\", undefined);█1863: await shutdownWithinBudget(\"OMP session shut down before your message could complete\");█1864: });█1865: };█1866:}█1867:█1868:export default createOmpSpt();█[Showing lines 1719-1868 of 1869. Use :1869 to continue]\u000f█</out>█# Assistant ¶█_**Reviewing code at line 1708**_█# Tool call ¶█//Reading context handler start█read(path=\"adapter/strings/omp-spt.mjs\", selector=\"1704-1742\")█<out>█\u000e[omp-spt.mjs#0137]█1696: const blockSessionChange = (description, ctx) => {█...█1703: };█1704:█1705: pi.on(\"session_before_switch\", (event, ctx) =>█1706: blockSessionChange(`${event.reason} session switch`, ctx),█1707: );█1708: pi.on(\"session_before_branch\", (_event, ctx) =>█1709: blockSessionChange(\"session branch\", ctx),█1710: );█1711:█1712: // [impl->REQ-OMP-MESSAGE-CONTEXT]█1713: // [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]█1714: pi.on(\"context\", (event) => {█1715: let messages = event.messages;█1716: if (█1717: agentActive &&█1718: !current &&█1719: !dispatching &&█1720: queue.length > 0█1721: ) {█1722: const item = queue.shift();█1723: item.stub = senderStub(item.from ?? \"unknown\");█1724: item.submitted = true;█1725: item.activeInjected = true;█1726: current = item;█1727: messages = [█1728: ...messages,█1729: {█1730: role: \"user\",█1731: content: `${item.stub}\\n\\n${item.envelope}`,█1732: },█1733: ];█1734: }█1735: if (current?.submitted && !current.settling && !current.activeInjected) {█1736: messages = injectEnvelope(messages, current);█1737: }█1738: if (messages !== event.messages) return { messages };█1739: });█1740: // [impl->REQ-PARITY-STARTUP-BRIEF]█1741: // [impl->REQ-PARITY-TARGETED-HINTS]█1742: // [impl->REQ-PARITY-UPDATE-NOTICE]█1743: pi.on(\"before_agent_start\", async (event) => {█1744: if (!activated || !id || stopping) return;█1745: const additions = [];█...█1761: });█[Showing lines 1703-1745 of 1869. Use :1746 to continue]\u000f█</out>"}}}
{"type":"message","id":"f90e9084","parentId":"6e4df01b","timestamp":"2026-07-16T09:05:12.917Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding helper to detect agent-managed polling**"},{"type":"toolCall","id":"call_sE7XUkadOYopbQILgcl19gcE|fc_09ab79121c733b56016a589ec880bc8199a24d8f0e47c037a1","name":"read","arguments":{"i":"Reading test call helpers","path":"tests/omp-extension.mjs","selector":"270-290"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":86735,"output":152,"cacheRead":0,"cacheWrite":0,"totalTokens":86887,"reasoningTokens":115,"cost":{"input":0.43367500000000003,"output":0.00456,"cacheRead":0,"cacheWrite":0,"total":0.43823500000000004}},"stopReason":"toolUse","timestamp":1784192701632,"responseId":"resp_09ab79121c733b56016a589ebe8f708199ad399c62a3856883","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589ec3000481998f4cce70a347e447","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ7INorXtvrNJMvExs8sPPfkhbIE52rWBxKPX2OSJqXcxfie0l45E0V15jaq-5zC6GQK7quKH8ssFcgKN3ea6Y51fYVc30mlR3iTDPy7q6t64Q9i-PE3bDjjS2HQEmXb3KxgrZED6RCQAQRP4A_bgGc93AEETuwD4rqPvo72cfMVwrfXZfDe_PjQxxkTbXU35kH3z2LKHuawwyyNrKaEqxZ7gZJuHtKjU3j0fnrDqNvo4Nvb0Rk7TcKC729lazf8eEXOEW52LjllURRW1_LzfzA-LIMwprbK1aKvnMmk9tJOJTmgCIO11NYII4WjsbQt9_Qn5pbvAoF7HQmoAoR-yH4Zwdel1bu54Vp1Pfj4kbeETxNAWJzRU9lENHwgmUjaXgvwMHQzWZFDxkvxPnP_rr0MmSlfFNFy_EMBlS5QuDRGlHj3W8SXg_MbfvP20MZA3Cm9W9CcJ1eDa8RsCs2uMl1ZJuKUo9W1EoWkV837vRXhbrpOKTf09nRFwk_Kw2MMWQtDwzN772DqsYSJpLvp74Z45b3ed1wMTcKosR15epzDzZDf9FCmFcUk75PcFEk5c8CnOcCZ1PxEMtd9EqaV_az4yp6m9JsUEmNZecRBPe97VT2Ar3jGVLGMQqV4XxmBaGc9KwULAeG16F2czHSLXT3du3Gm3FEZ4unuVWZzCaqpsDTv7czFwTt-sIhwWe0GspEMQsmq9tXNwKOwrZcEE1eNFQyeac8Q1b_duDTxoby_XAizvTUXxUwQuhcizwyDgGNteYxT4axR--xnQNc6yyefXJ5KyMLIMvkMOJhBHNiAFSRlkdO04exCOJ4L_9FAQBPNPV10t7yZpCvbp1APQVLInFrGY6NFElwbnKqhoEu9osAfTpTEzj-clCLGxeyGm8Kca93lkerlRJMUynfzTbFPocaaDzbSBiQpTzscOh3dxUG-LVgH88ESYEv6WgZQLo7Pxo2MWyPPnc39QUOrVrJW_od7UOeZ7M2vsBCcjWDO2fgmVpPzzmX40ByvuA8MLJt6MaqYUusAczUq_OTawkbrbC5RoCLiyguy7JjACIdvJ6em7i_tebOFg-WVCgHyOJlJmogwpWz0mf2TIDApF2CD5SS7W5oPlmJ31wkfnUv8xiEw54CjsHDYX7pjjjS0X5_5-E6k2UDkv2hTumcg41p42y6uIe0KtoReDy57p05yNBBUK8F-hx0c7lhBmhcX9XXo7x-MoCmE2LLl8nnH_fjt0x21HF8aGGEDto2JonPZHkpY4gwJGsDQFxvMNNmLxHmdadl23JPFf5likfzea0ITsmX9i0U1uiy3e0CA0HmyON3d_CGVdq_wFLja5ghO08t-sC7YfU-kovnBpC4vl5d8_g2ii7qG7SYgvz4lipaC4Smj0aeflq0-9hnfcLLwqMlPGVu_zvrC6I9jLpiMzrjXrnv8jvF-y5vOMOGDCQHbB-fGQbQNwFRlxgkDQvEsPn2wQFNxbtIAenrHScFvch_Y3imcZAO91vkt1o4MUZ7pN75cxefTvgbzWa_a8VOIIBCF86xQpSjc7rrGxnaptv4mql-H44I-n24UrSwJBEe57CCP-pyKhDLk6EW4l_Oyfy1Y6MM1Inmc39fdMZNqPJ55o83EDkOtMwg9lIveSF5CYZrrH6X9DYZWeHXDxklwFriJ1URNzObw0nlokyhwfSTPdQ==","summary":[{"type":"summary_text","text":"**Adding helper to detect agent-managed polling**"}]},{"id":"fc_09ab79121c733b56016a589ec880bc8199a24d8f0e47c037a1","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading test call helpers\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"270-290\"}","call_id":"call_sE7XUkadOYopbQILgcl19gcE","name":"read"}]},"duration":11283.659599999897,"ttft":5344.670500000007,"contextSnapshot":{"promptTokens":86735,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_sE7XUkadOYopbQILgcl19gcE|fc_09ab79121c733b56016a589ec880bc8199a24d8f0e47c037a1","toolName":"read","startedAt":"2026-07-16T09:05:12.917Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading test call helpers"},"id":"81726fed","parentId":"f90e9084","timestamp":"2026-07-16T09:05:12.917Z"}
{"type":"message","id":"a7b5694d","parentId":"81726fed","timestamp":"2026-07-16T09:05:12.935Z","message":{"role":"toolResult","toolCallId":"call_sE7XUkadOYopbQILgcl19gcE|fc_09ab79121c733b56016a589ec880bc8199a24d8f0e47c037a1","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#9A9B]\n95:function createHarness(options = {}) {\n…\n251:\treturn {\n…\n269:\t\ttools,\n270:\t\tget shutdowns() {\n271:\t\t\treturn shutdowns;\n272:\t\t},\n273:\t};\n274:}\n275:\n276:function commandCalls(harness, command) {\n277:\treturn harness.calls.filter((call) => call.args[0] === command);\n278:}\n279:\n280:function stateCalls(harness) {\n281:\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n282:}\n283:\n284:async function testParsingAndReplies() {\n285:\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\n286:\n287:\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\n288:\tconst partial = drainEvents(`noise${partialEnvelope}`);\n289:\tassert.deepEqual(partial.events, []);\n290:\tassert.equal(partial.rest, partialEnvelope);\n291:\n292:\tconst envelope = `${partial.rest}rld</EVENT>`;\n293:\tconst complete = drainEvents(`${envelope}<EVENT type=\"notify\">skip</EVENT>`);\n…\n344:}\n\n[Showing lines 269-293 of 1991. Use :294 to continue]"}],"details":{"truncation":{"content":"\t\ttools,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r\n\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\r\n\r\n\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\r\n\tconst partial = drainEvents(`noise${partialEnvelope}`);\r\n\tassert.deepEqual(partial.events, []);\r\n\tassert.equal(partial.rest, partialEnvelope);\r\n\r\n\tconst envelope = `${partial.rest}rld</EVENT>`;\r\n\tconst complete = drainEvents(`${envelope}<EVENT type=\"notify\">skip</EVENT>`);\r","truncated":true,"truncatedBy":"lines","totalLines":1723,"totalBytes":799,"outputLines":25,"outputBytes":799,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"function createHarness(options = {}) {\n…\n\treturn {\n…\n\t\ttools,\r\n\t\tget shutdowns() {\r\n\t\t\treturn shutdowns;\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction commandCalls(harness, command) {\r\n\treturn harness.calls.filter((call) => call.args[0] === command);\r\n}\r\n\r\nfunction stateCalls(harness) {\r\n\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\r\n}\r\n\r\nasync function testParsingAndReplies() {\r\n\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\r\n\r\n\tconst partialEnvelope = '<EVENT type=\"msg\" from=\"doyle\">hello<br>wo';\r\n\tconst partial = drainEvents(`noise${partialEnvelope}`);\r\n\tassert.deepEqual(partial.events, []);\r\n\tassert.equal(partial.rest, partialEnvelope);\r\n\r\n\tconst envelope = `${partial.rest}rld</EVENT>`;\r\n\tconst complete = drainEvents(`${envelope}<EVENT type=\"notify\">skip</EVENT>`);\r\n…\n}","startLine":95,"lineNumbers":[95,null,251,null,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,null,344]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1991,"totalBytes":799,"outputLines":25,"outputBytes":799,"shownRange":{"start":269,"end":293},"nextOffset":294}}},"isError":false,"timestamp":1784192712934}}
{"type":"message","id":"985f15bb","parentId":"a7b5694d","timestamp":"2026-07-16T09:05:26.547Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding helper and replacing check**"},{"type":"toolCall","id":"call_KRmgQTTOmKvf2KTnd2ibJQiu|ctc_09ab79121c733b56016a589ecf365481999552b1755f9425dc","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#9A9B]\nINS.POST 282:\n+function assertNoAgentManagedPoll(harness) {\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args.includes(\"poll\")) &&\n+\t\t\t!harness.children.some((child) => child.args.includes(\"poll\")),\n+\t\t\"extension activation and delivery must never launch an agent-managed background poll\",\n+\t);\n+}\n+\nSWAP 1769.=1772:\n+\tassertNoAgentManagedPoll(harness);\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6816,"output":141,"cacheRead":80384,"cacheWrite":0,"totalTokens":87341,"reasoningTokens":10,"cost":{"input":0.034080000000000006,"output":0.00423,"cacheRead":0.040192,"cacheWrite":0,"total":0.078502}},"stopReason":"toolUse","timestamp":1784192712941,"responseId":"resp_09ab79121c733b56016a589ec972b08199903913f723148450","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589ece9a108199882dd876c64f59ef","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ7P1w2ZHvr6SGld3fif5hIwHBe5W4QEoD_pn7sQubBVDUAg4im9GgC5yi0XJbPnJF9hhdGDWMU4LaItTKvUWTDCoKNgBTzXXkDC7AcPJa6EJwu4wqwJf0t21KpcWYQwjOk7C9NC7YD8PXleFH11nyIXO9L0HFt0-6cGdr2D6zYA-EgevqF-U5JhOeShwOy5H1c4XcvbTd3ozV9gdJL_Qiv0GnHLBVNQC2pp0d3aCVsFRPIYMLcUdXPhyoxfFj2v4aEdmoT2XqjXnTHpGjfRZRsuc_xE5go8W9no9AQ-wuIdEpd9-f6eaEfrPw7DMOl4k33MeBtwxb13XMZ39DrZoyvoSg2-I_166dio-t4b-u0JrTZ2UzugP2w4k_znuZR00gNzx7JGDAdFmt7zI204OP0KYoJHy10q_g1mZDkYad8-7DSRrhDWrJK-QRU0D32Y-b6chE35X43wobEGxsF7P8iEnRULJa5HaE5ilbfGblLVTF2hnFqkIizfr9bCqPl-67KZxZPdeEBw6HP9fvs4ys4oSgpCecXrPyMkHjh9Waypdk6hQXjSQ3gSlw4EuyyERIJdR72Dxw17VwroXoFBSU_O78Y3Qyo_I9aEz6Le51_b7w7wkeD64Zr2skRF3go3HaXR09eSlyIwtFvNzhTUfw7bV7XxK8oA7jSM-fWePyVcbPDsd8Plgfkq6Vx4T7F1fIOII74CNMHh1FYv_d23QVcsbjJ86k1eS0oAV2KdVOOTbwrO-__klioNvVzKpI0kn_yCMb64ZgXaPY_8xhR7k4IPFn5YyyIsfujqc_RFooeZz0VE8LfhoW0zuS9BJbaxx_i82xX_xvjnxGjFK61yazNjkCEP_53XggeeTleQEA-BeVNnonWd6FgtwUQoSz_TbGZ1O7bMZq-QDBnhMemBCvs_j7KlVSI70ziDaLqtByz_5-xR7op9pYNBUTBKgE1PH9tjULsDUYKacBK9-dq5GRrPEQ==","summary":[{"type":"summary_text","text":"**Adding helper and replacing check**"}]},{"id":"ctc_09ab79121c733b56016a589ecf365481999552b1755f9425dc","type":"custom_tool_call","status":"completed","call_id":"call_KRmgQTTOmKvf2KTnd2ibJQiu","input":"*** Begin Patch\n[tests/omp-extension.mjs#9A9B]\nINS.POST 282:\n+function assertNoAgentManagedPoll(harness) {\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args.includes(\"poll\")) &&\n+\t\t\t!harness.children.some((child) => child.args.includes(\"poll\")),\n+\t\t\"extension activation and delivery must never launch an agent-managed background poll\",\n+\t);\n+}\n+\nSWAP 1769.=1772:\n+\tassertNoAgentManagedPoll(harness);\n*** End Patch\n","name":"edit"}]},"duration":13494.1277999999,"ttft":5639.735900000203,"contextSnapshot":{"promptTokens":87200,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_KRmgQTTOmKvf2KTnd2ibJQiu|ctc_09ab79121c733b56016a589ecf365481999552b1755f9425dc","toolName":"edit","startedAt":"2026-07-16T09:05:26.548Z"},"id":"7a2d8962","parentId":"985f15bb","timestamp":"2026-07-16T09:05:26.548Z"}
{"type":"message","id":"42c049d1","parentId":"7a2d8962","timestamp":"2026-07-16T09:05:26.553Z","message":{"role":"toolResult","toolCallId":"call_KRmgQTTOmKvf2KTnd2ibJQiu|ctc_09ab79121c733b56016a589ecf365481999552b1755f9425dc","toolName":"edit","content":[{"type":"text","text":"This edit anchors to lines 1769-1772 of tests/omp-extension.mjs that [tests/omp-extension.mjs#9A9B] never displayed (it showed a partial range, a search hit, or a folded summary). Actual file content at those lines:\n  1769:\tassert.ok(\n  1770:\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n  1771:\t\t\"active-turn delivery must use the extension listener, never a background poll\",\n  1772:\t);\nVerify the content matches what you intend to touch, then re-issue the edit with the same [path#tag] header — a straight retry now succeeds without a re-read. If the content does NOT match, fix your line numbers."}],"details":{},"isError":true,"timestamp":1784192726552}}
{"type":"message","id":"8a741dcf","parentId":"42c049d1","timestamp":"2026-07-16T09:05:34.053Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":""},{"type":"toolCall","id":"call_G4LkWJNlCXpsrDQaeqsaMUjA|ctc_09ab79121c733b56016a589eda55a88199846802e14855f7f2","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#9A9B]\nINS.POST 282:\n+function assertNoAgentManagedPoll(harness) {\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args.includes(\"poll\")) &&\n+\t\t\t!harness.children.some((child) => child.args.includes(\"poll\")),\n+\t\t\"extension activation and delivery must never launch an agent-managed background poll\",\n+\t);\n+}\n+\nSWAP 1769.=1772:\n+\tassertNoAgentManagedPoll(harness);\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7134,"output":137,"cacheRead":80384,"cacheWrite":0,"totalTokens":87655,"reasoningTokens":6,"cost":{"input":0.03567,"output":0.00411,"cacheRead":0.040192,"cacheWrite":0,"total":0.079972}},"stopReason":"toolUse","timestamp":1784192726558,"responseId":"resp_09ab79121c733b56016a589ed6d5348199bf1829a08fbbbcf7","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589ed9e78c8199b859542630fcdee8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ7axVdiWKzLdCmgeHZ2I-hDF8EPWnYV9A5oG-AumOk7_K5f3eLPVCDuHYZiyoyYjIccXUWgW4AUPoACeXL0I_EVQLMfeP_WGYdtVo53pJehE2fhOm7ZgwyG_ovcLsZwKPZ57F0g_j-HjaumD_BWrN3T6oDxTXJh5hqQj8B3FyM1hOvnkWHrvHr6MkjQlhxkpidFIYcp_zJ1MsyvxZkg4nMwFOxOsNunQ8hafAQsl7XV5cLkvv1YQrZbviI1giMNZx5z8YF9Oth1ph3jGzTpZEmoaKSkt92bgfLxtuYyAUdra-p8lBotHNDL7fE1U9N61TbBdZqktKjEw8u8kPx3cmXx1rzENrUzen1r592zpZmzCo5xO7pUwAAFXr4KW7cjyXIm5Bm9CVSDgwlikSRElM_LYOx3m2uk0mg7qSMmpibc_UQbZ2AB_Pv12xJ1g-i2PIUYUThnjwotA5MD0WbZO6yTYwlO76aVGBGKMQGYjznu3ut7lKZ3suvCRTMIIYTf2Qt_ucJlSG5ec7iAloeh70q4AUZ2aO9fmMYMnIAUCpcV1sK7Ysi3Xj_7Yw13UkkaB-17GPcRtcuk2zpEIDX4SQozrBrPJv-478ZJ1mv0WAi5fpQdQCU_RPVW3Kk0IMT2v0oXWtRbRUXDTiC3atNkrQX0lFIHNalQ4KEEg2cOwrzRnC5Fgy7f0bigsvvLSG951LIFm3kiuIn0g0F679vqklj8fI27hshM2m55Cxzm11QvWj0PTnZcfSTTTrXmNMsA9e-MZi36DFdskf8kIe_6NRr9Ye1VS7G4jhmWrEkrIZusyAouhHPFFDX9ny4gyDJOkECkWTNKVbdL4OqyhowT8eba9jzLat2TFv0HqmMPHcE_3eiGlAi3VzYkmEcrCwbWLRxcmDkGLFYr1RnNmjkQhKPLTXioQnG7P6mwKN4inKupw6g=","summary":[]},{"id":"ctc_09ab79121c733b56016a589eda55a88199846802e14855f7f2","type":"custom_tool_call","status":"completed","call_id":"call_G4LkWJNlCXpsrDQaeqsaMUjA","input":"*** Begin Patch\n[tests/omp-extension.mjs#9A9B]\nINS.POST 282:\n+function assertNoAgentManagedPoll(harness) {\n+\tassert.ok(\n+\t\t!harness.calls.some((call) => call.args.includes(\"poll\")) &&\n+\t\t\t!harness.children.some((child) => child.args.includes(\"poll\")),\n+\t\t\"extension activation and delivery must never launch an agent-managed background poll\",\n+\t);\n+}\n+\nSWAP 1769.=1772:\n+\tassertNoAgentManagedPoll(harness);\n*** End Patch\n","name":"edit"}]},"duration":7495.580899999943,"ttft":3321.896999999881,"contextSnapshot":{"promptTokens":87518,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_G4LkWJNlCXpsrDQaeqsaMUjA|ctc_09ab79121c733b56016a589eda55a88199846802e14855f7f2","toolName":"edit","startedAt":"2026-07-16T09:05:34.054Z"},"id":"0f90a372","parentId":"8a741dcf","timestamp":"2026-07-16T09:05:34.054Z"}
{"type":"message","id":"7dfcc5e5","parentId":"0f90a372","timestamp":"2026-07-16T09:05:34.093Z","message":{"role":"toolResult","toolCallId":"call_G4LkWJNlCXpsrDQaeqsaMUjA|ctc_09ab79121c733b56016a589eda55a88199846802e14855f7f2","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#FF87]\n280:function stateCalls(harness) {\n281:\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n282:}\n283:function assertNoAgentManagedPoll(harness) {\n284:\tassert.ok(\n…\n288:\t);\n289:}\n290:\n291:\n292:async function testParsingAndReplies() {\n293:\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\n\n352:}\n\n1730:async function testActiveTurnBoundaryDeliveryAndFallback() {\n\n1772:\tassert.deepEqual(\n\n1775:\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\n1776:\t);\n1777:\tassertNoAgentManagedPoll(harness);\n1778:\tawait harness.emit(\"session_shutdown\");\n1779:}"}],"details":{"diff":" 280|function stateCalls(harness) {\n 281|\treturn harness.calls.filter((call) => call.args[0] === \"api\" && call.args[3] === \"state\");\n 282|}\n+283|function assertNoAgentManagedPoll(harness) {\n+284|\tassert.ok(\n+285|\t\t!harness.calls.some((call) => call.args.includes(\"poll\")) &&\n+286|\t\t\t!harness.children.some((child) => child.args.includes(\"poll\")),\n+287|\t\t\"extension activation and delivery must never launch an agent-managed background poll\",\n+288|\t);\n+289|}\n 283|\n+291|\n 284|async function testParsingAndReplies() {\n 285|\tassert.equal(decodeBody('a&lt;b&gt;<br>&quot;c&quot; &amp; &amp;lt;'), 'a<b>\\n\"c\" & &lt;');\n\n 344|}\n\n 1722|async function testActiveTurnBoundaryDeliveryAndFallback() {\n\n 1764|\tassert.deepEqual(\n\n 1767|\t\t\"a later accepted message must preserve order and fall back to an ordinary next turn\",\n 1768|\t);\n-1769|\tassert.ok(\n-1770|\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n-1771|\t\t\"active-turn delivery must use the extension listener, never a background poll\",\n-1772|\t);\n+1777|\tassertNoAgentManagedPoll(harness);\n 1773|\tawait harness.emit(\"session_shutdown\");\n 1774|}","firstChangedLine":282,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192734093}}
{"type":"message","id":"b94e1c7f","parentId":"7dfcc5e5","timestamp":"2026-07-16T09:05:41.267Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Preparing robust activation tests**"},{"type":"toolCall","id":"call_ZucoKGi0EZj41aOFZD8WyGVa|fc_09ab79121c733b56016a589ee3e6708199be0ca4a9cf8ebe15","name":"read","arguments":{"i":"Reading activation command tests","path":"tests/omp-extension.mjs","selector":"1435-1640"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7486,"output":73,"cacheRead":80384,"cacheWrite":0,"totalTokens":87943,"reasoningTokens":34,"cost":{"input":0.037430000000000005,"output":0.00219,"cacheRead":0.040192,"cacheWrite":0,"total":0.079812}},"stopReason":"toolUse","timestamp":1784192734098,"responseId":"resp_09ab79121c733b56016a589ede88bc8199bc1a344cce9b7a1e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589ee234c0819986779a42e0d840c4","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ7jYhSVyguzyXorcFDUnvMtoYUrjzYlSQxepyJiJELzpTlJYbmW5CxFpvxsqx7ViVfzIYeiT87C7zEd0f4pg8tEGKtCeUNIFbnchmPo4ExHevRoSE3iUTzdqeTFPG9000-poVXNA-Oe-ynXqBSYv26of7P1eBqYLeh2BT4SYw5qNjCxxeRVXYeQgARChLa9Bx9rm6C8Ag7RAqN-0Re3vC-0HqtQGGihqfJ4MeaxpU-z78jfgl67mCb6JSzdqn8DJIileTXNqn6EGP6tWHjDUxhNqsd0WPF49CkdWyN4KvQBwD7oSolaH8HcSPFS7TdYyNXUjTfKyMclHF7xwLm4VQSa2rCSleqNE3S0dOTpSbflrgWIdscA-TPItSJ5T2-UXa_QYLGDiHICOMBpS0nHTWlhzMCVgiGu68fKb_jSfFfQDGtUH6RVDs-7eZkPpsV2ZkZg-2WGdtU6VBZcRx3azCmQBzdEREtsLI_TXZx-87X8UjiKQcoLi2EkOifq0PrQXjN-59fD02hCmuHcfp0soGDTcd3JES0oLddRUPwyfOVny2YVwyBjAXvz2a9CG9Yu6eJ4W6a2rb0rWnNLtNjKVfcMCpXYref-85zLcXiUftRCSqWqCpG1tg88MtpE7e-mvQpFRzTNVFQQVV2dj9JzkhIq1tShpF130ZAgb749BLXwsWmyOZSy2rQJE6YhoDRQ8IKRHs7Q4z92SE1qeadgTRppTLBy0yKwaCO_IxXVveDwONbZWZTamdG9ag3LKZEagJkT7t-EiCUNNTmSV6snSPP84qc1WHlaDU3Q6C3wbULY0f1TnG5lwYZy2ON9bq9K3uzzAtzo2iZEJW0n1-CqbDfRCHRroyGP5kVl5g5fNGyHswoBWQfIowSB5uVrCbGwGoS51DMZADU3HlKPcL4_6MXTgTtILp8fqa_V5u-z9OdmVMEE-92MB5_k3qFr0WmtitUsxqtZhlMXBJPNl5a8yNrTrjVBj4LoRYIxlSypFM5LBIVfIt2ZcJa1ggiGJsj_sZmd9_Js6PuGRlSr7aRQluWLiYyoxAbBczsQjPkFqKLCgIK1KJhNmA06hxOj1LV_2IW39g81elyyNmfBncUqNjBogx7IT477iaCxlvQQrEGwkZ4=","summary":[{"type":"summary_text","text":"**Preparing robust activation tests**"}]},{"id":"fc_09ab79121c733b56016a589ee3e6708199be0ca4a9cf8ebe15","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading activation command tests\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1435-1640\"}","call_id":"call_ZucoKGi0EZj41aOFZD8WyGVa","name":"read"}]},"duration":7169.044300000183,"ttft":4090.6202000002377,"contextSnapshot":{"promptTokens":87870,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ZucoKGi0EZj41aOFZD8WyGVa|fc_09ab79121c733b56016a589ee3e6708199be0ca4a9cf8ebe15","toolName":"read","startedAt":"2026-07-16T09:05:41.267Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading activation command tests"},"id":"ae2d7e67","parentId":"b94e1c7f","timestamp":"2026-07-16T09:05:41.268Z"}
{"type":"message","id":"44cf1b75","parentId":"ae2d7e67","timestamp":"2026-07-16T09:05:41.287Z","message":{"role":"toolResult","toolCallId":"call_ZucoKGi0EZj41aOFZD8WyGVa|fc_09ab79121c733b56016a589ee3e6708199be0ca4a9cf8ebe15","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#FF87]\n1434:// [unit->REQ-PARITY-LIVE-ACTIVATION]\n1435:async function testNativeActivationCommandsAndErrors() {\n1436:\tconst inert = createHarness({ id: null });\n1437:\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\n1438:\tassert.ok(inert.tools.has(\"spt_checkpoint\"));\n1439:\tawait inert.emit(\"session_start\");\n1440:\tassert.deepEqual(inert.calls, [], \"an ordinary OMP session must remain lifecycle-inert\");\n1441:\tassert.equal(\n1442:\t\tawait inert.emit(\"session_before_switch\", { reason: \"new\" }),\n1443:\t\tundefined,\n1444:\t\t\"an unbound extension must not block native session changes\",\n1445:\t);\n1446:\n1447:\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\n1448:\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");\n1449:\tassert.deepEqual(readyBind.args, [\n1450:\t\t\"api\",\n1451:\t\t\"--adapter\",\n1452:\t\t\"omp-spt\",\n1453:\t\t\"bind\",\n1454:\t\t\"ready-one\",\n1455:\t\t\"--set-session-id\",\n1456:\t\t\"session-1\",\n1457:\t\t\"--type\",\n1458:\t\t\"ready_agent\",\n1459:\t]);\n1460:\tassert.deepEqual(inert.children[0].args, [\n1461:\t\t\"api\",\n1462:\t\t\"--adapter\",\n1463:\t\t\"omp-spt\",\n1464:\t\t\"listen\",\n1465:\t\t\"ready-one\",\n1466:\t\t\"--session-id\",\n1467:\t\t\"session-1\",\n1468:\t]);\n1469:\tassert.ok(\n1470:\t\tinert.notifications.some(({ message, type }) =>\n1471:\t\t\ttype === \"info\" && message.includes(\"ready endpoint ready-one\"),\n1472:\t\t),\n1473:\t);\n1474:\tawait inert.commands.get(\"live\").handler(\"other-id\", inert.ctx);\n1475:\tassert.equal(inert.calls.filter((call) => call.args[3] === \"bind\").length, 1);\n1476:\tassert.ok(\n1477:\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\n1478:\t);\n1479:\tawait inert.emit(\"session_shutdown\");\n1480:\n1481:\tlet bindAttempts = 0;\n1482:\tconst retryable = createHarness({\n1483:\t\tid: null,\n1484:\t\tonRun(call) {\n1485:\t\t\tif (call.args[3] === \"bind\") {\n1486:\t\t\t\tbindAttempts += 1;\n1487:\t\t\t\tif (bindAttempts === 1) throw new Error(\"identity already active\");\n1488:\t\t\t}\n1489:\t\t},\n1490:\t});\n1491:\tawait retryable.emit(\"session_start\");\n1492:\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n1493:\tassert.equal(retryable.children.length, 0);\n1494:\tassert.equal(retryable.shutdowns, 0, \"a pre-token command error must keep ordinary OMP usable\");\n1495:\tassert.ok(\n1496:\t\tretryable.notifications.some(({ message }) => message.includes(\"identity already active\")),\n1497:\t);\n1498:\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\n1499:\tassert.equal(retryable.children.length, 1, \"a corrected activation may retry after a bind error\");\n1500:\tassert.ok(\n1501:\t\tretryable.calls\n1502:\t\t\t.findLast((call) => call.args[3] === \"bind\")\n1503:\t\t\t.args.includes(\"live_agent\"),\n1504:\t);\n1505:\tawait retryable.emit(\"session_shutdown\");\n1506:\n1507:\tconst headless = createHarness({ id: null, hasUI: false });\n1508:\tawait headless.emit(\"session_start\");\n1509:\tawait headless.commands.get(\"ready\").handler(\"\", headless.ctx);\n1510:\tassert.deepEqual(headless.calls, []);\n1511:\tassert.ok(\n1512:\t\theadless.notifications.some(({ message }) => message.includes(\"requires an endpoint id\")),\n1513:\t\t\"ordinary activation must never guess an identity when native selection is unavailable\",\n1514:\t);\n1515:\tawait headless.emit(\"session_shutdown\");\n1516:}\n1517:\n1518:// [unit->REQ-PARITY-READY-ACTIVATION]\n1519:async function testNativeActivationSelectionAndCompletion() {\n1520:\tconst harness = createHarness({\n1521:\t\tid: null,\n1522:\t\tselectResults: [\"ready-old\"],\n1523:\t\tonRun(call) {\n1524:\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\n1525:\t\t\t\treturn JSON.stringify({\n1526:\t\t\t\t\tlocal: [\n1527:\t\t\t\t\t\t{ id: \"ready-old\", state: \"ready_agent\", alive: false },\n1528:\t\t\t\t\t\t{ id: \"ready-busy\", state: \"ready_agent\", alive: true },\n1529:\t\t\t\t\t\t{ id: \"live-old\", state: \"live_agent\", alive: false },\n1530:\t\t\t\t\t],\n1531:\t\t\t\t});\n1532:\t\t\t}\n1533:\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n1534:\t\t\t\treturn JSON.stringify({\n1535:\t\t\t\t\tid: call.args[3],\n1536:\t\t\t\t\tadapter: \"omp-spt\",\n1537:\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n1538:\t\t\t\t});\n1539:\t\t\t}\n1540:\t\t},\n1541:\t});\n1542:\tawait harness.emit(\"session_start\");\n1543:\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\n1544:\tassert.deepEqual(harness.selections[0].values, [\n1545:\t\t\"ready-old\",\n1546:\t\t\"Create a new endpoint id\",\n1547:\t]);\n1548:\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], \"ready-old\");\n1549:\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\n1550:\t\t{ value: \"ready-old\", label: \"ready-old\" },\n1551:\t]);\n1552:\tassert.ok(\n1553:\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n1554:\t\t\"selection and activation must not start an agent-managed background poll\",\n1555:\t);\n1556:\tawait harness.emit(\"session_shutdown\");\n1557:}\n1558:\n1559:// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n1560:async function testExplicitLiveAutoResume() {\n1561:\tconst activity = {\n1562:\t\told: \"2026-07-10T00:00:00.000Z\",\n1563:\t\tnewest: \"2026-07-15T00:00:00.000Z\",\n1564:\t};\n1565:\tconst harness = createHarness({\n1566:\t\tid: null,\n1567:\t\tconfirmResults: [true],\n1568:\t\tonRun(call) {\n1569:\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n1570:\t\t\t\treturn JSON.stringify({\n1571:\t\t\t\t\tlocal: [\n1572:\t\t\t\t\t\t{ id: \"old\", state: \"live_agent\", alive: false },\n1573:\t\t\t\t\t\t{ id: \"newest\", state: \"live_agent\", alive: false },\n1574:\t\t\t\t\t\t{ id: \"active\", state: \"live_agent\", alive: true },\n1575:\t\t\t\t\t\t{ id: \"foreign\", state: \"live_agent\", alive: false },\n1576:\t\t\t\t\t],\n1577:\t\t\t\t});\n1578:\t\t\t}\n1579:\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n1580:\t\t\t\treturn JSON.stringify({\n1581:\t\t\t\t\tid: call.args[3],\n1582:\t\t\t\t\tadapter: call.args[3] === \"foreign\" ? \"claude-spt\" : \"omp-spt\",\n1583:\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n1584:\t\t\t\t});\n1585:\t\t\t}\n1586:\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n1587:\t\t\t\tconst id = call.args[3];\n1588:\t\t\t\treturn JSON.stringify({\n1589:\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: activity[id], text: id } }] }],\n1590:\t\t\t\t});\n1591:\t\t\t}\n1592:\t\t},\n1593:\t});\n1594:\tawait harness.emit(\"session_start\");\n1595:\tassert.deepEqual(harness.commands.get(\"live\").getArgumentCompletions(\"--\"), [\n1596:\t\t{ value: \"--auto\", label: \"--auto\" },\n1597:\t]);\n1598:\tawait harness.commands.get(\"live\").handler(\"--auto\", harness.ctx);\n1599:\tassert.match(harness.confirmations[0].message, /newest.*most recently active/s);\n1600:\tconst bind = harness.calls.find((call) => call.args[3] === \"bind\");\n1601:\tassert.equal(bind.args[4], \"newest\");\n1602:\tassert.ok(bind.args.includes(\"live_agent\"));\n1603:\tassert.ok(\n1604:\t\t!harness.calls.some(\n1605:\t\t\t(call) => call.args[2] === \"digest\" && [\"active\", \"foreign\"].includes(call.args[3]),\n1606:\t\t),\n1607:\t\t\"auto-resume must inspect only inactive compatible identities\",\n1608:\t);\n1609:\tawait harness.emit(\"session_shutdown\");\n1610:\n1611:\tconst declined = createHarness({\n1612:\t\tid: null,\n1613:\t\tconfirmResults: [false],\n1614:\t\tonRun(call) {\n1615:\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\n1616:\t\t\t\treturn JSON.stringify({\n1617:\t\t\t\t\tlocal: [{ id: \"prior\", state: \"live_agent\", alive: false }],\n1618:\t\t\t\t});\n1619:\t\t\t}\n1620:\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n1621:\t\t\t\treturn JSON.stringify({\n1622:\t\t\t\t\tid: \"prior\",\n1623:\t\t\t\t\tadapter: \"omp-spt\",\n1624:\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\n1625:\t\t\t\t});\n1626:\t\t\t}\n1627:\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\n1628:\t\t\t\treturn JSON.stringify({\n1629:\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: \"2026-07-15T01:00:00.000Z\" } }] }],\n1630:\t\t\t\t});\n1631:\t\t\t}\n1632:\t\t},\n1633:\t});\n1634:\tawait declined.emit(\"session_start\");\n1635:\tawait declined.commands.get(\"live\").handler(\"--auto\", declined.ctx);\n1636:\tassert.equal(declined.calls.filter((call) => call.args[3] === \"bind\").length, 0);\n1637:\tawait declined.emit(\"session_shutdown\");\n1638:}\n1639:\n1640:// [unit->REQ-PARITY-STARTUP-BRIEF]\n1641:// [unit->REQ-PARITY-TARGETED-HINTS]\n1642:// [unit->REQ-PARITY-UPDATE-NOTICE]\n1643:async function testStartupBriefHintsAndUpdateNotices() {\n…\n1726:}\n\n[Showing lines 1434-1643 of 1996. Use :1644 to continue]"}],"details":{"truncation":{"content":"// [unit->REQ-PARITY-LIVE-ACTIVATION]\r\nasync function testNativeActivationCommandsAndErrors() {\r\n\tconst inert = createHarness({ id: null });\r\n\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\r\n\tassert.ok(inert.tools.has(\"spt_checkpoint\"));\r\n\tawait inert.emit(\"session_start\");\r\n\tassert.deepEqual(inert.calls, [], \"an ordinary OMP session must remain lifecycle-inert\");\r\n\tassert.equal(\r\n\t\tawait inert.emit(\"session_before_switch\", { reason: \"new\" }),\r\n\t\tundefined,\r\n\t\t\"an unbound extension must not block native session changes\",\r\n\t);\r\n\r\n\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\r\n\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");\r\n\tassert.deepEqual(readyBind.args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"bind\",\r\n\t\t\"ready-one\",\r\n\t\t\"--set-session-id\",\r\n\t\t\"session-1\",\r\n\t\t\"--type\",\r\n\t\t\"ready_agent\",\r\n\t]);\r\n\tassert.deepEqual(inert.children[0].args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"listen\",\r\n\t\t\"ready-one\",\r\n\t\t\"--session-id\",\r\n\t\t\"session-1\",\r\n\t]);\r\n\tassert.ok(\r\n\t\tinert.notifications.some(({ message, type }) =>\r\n\t\t\ttype === \"info\" && message.includes(\"ready endpoint ready-one\"),\r\n\t\t),\r\n\t);\r\n\tawait inert.commands.get(\"live\").handler(\"other-id\", inert.ctx);\r\n\tassert.equal(inert.calls.filter((call) => call.args[3] === \"bind\").length, 1);\r\n\tassert.ok(\r\n\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\r\n\t);\r\n\tawait inert.emit(\"session_shutdown\");\r\n\r\n\tlet bindAttempts = 0;\r\n\tconst retryable = createHarness({\r\n\t\tid: null,\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[3] === \"bind\") {\r\n\t\t\t\tbindAttempts += 1;\r\n\t\t\t\tif (bindAttempts === 1) throw new Error(\"identity already active\");\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait retryable.emit(\"session_start\");\r\n\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\r\n\tassert.equal(retryable.children.length, 0);\r\n\tassert.equal(retryable.shutdowns, 0, \"a pre-token command error must keep ordinary OMP usable\");\r\n\tassert.ok(\r\n\t\tretryable.notifications.some(({ message }) => message.includes(\"identity already active\")),\r\n\t);\r\n\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\r\n\tassert.equal(retryable.children.length, 1, \"a corrected activation may retry after a bind error\");\r\n\tassert.ok(\r\n\t\tretryable.calls\r\n\t\t\t.findLast((call) => call.args[3] === \"bind\")\r\n\t\t\t.args.includes(\"live_agent\"),\r\n\t);\r\n\tawait retryable.emit(\"session_shutdown\");\r\n\r\n\tconst headless = createHarness({ id: null, hasUI: false });\r\n\tawait headless.emit(\"session_start\");\r\n\tawait headless.commands.get(\"ready\").handler(\"\", headless.ctx);\r\n\tassert.deepEqual(headless.calls, []);\r\n\tassert.ok(\r\n\t\theadless.notifications.some(({ message }) => message.includes(\"requires an endpoint id\")),\r\n\t\t\"ordinary activation must never guess an identity when native selection is unavailable\",\r\n\t);\r\n\tawait headless.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-READY-ACTIVATION]\r\nasync function testNativeActivationSelectionAndCompletion() {\r\n\tconst harness = createHarness({\r\n\t\tid: null,\r\n\t\tselectResults: [\"ready-old\"],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tlocal: [\r\n\t\t\t\t\t\t{ id: \"ready-old\", state: \"ready_agent\", alive: false },\r\n\t\t\t\t\t\t{ id: \"ready-busy\", state: \"ready_agent\", alive: true },\r\n\t\t\t\t\t\t{ id: \"live-old\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tid: call.args[3],\r\n\t\t\t\t\tadapter: \"omp-spt\",\r\n\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\r\n\tassert.deepEqual(harness.selections[0].values, [\r\n\t\t\"ready-old\",\r\n\t\t\"Create a new endpoint id\",\r\n\t]);\r\n\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], \"ready-old\");\r\n\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\r\n\t\t{ value: \"ready-old\", label: \"ready-old\" },\r\n\t]);\r\n\tassert.ok(\r\n\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\r\n\t\t\"selection and activation must not start an agent-managed background poll\",\r\n\t);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\r\nasync function testExplicitLiveAutoResume() {\r\n\tconst activity = {\r\n\t\told: \"2026-07-10T00:00:00.000Z\",\r\n\t\tnewest: \"2026-07-15T00:00:00.000Z\",\r\n\t};\r\n\tconst harness = createHarness({\r\n\t\tid: null,\r\n\t\tconfirmResults: [true],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tlocal: [\r\n\t\t\t\t\t\t{ id: \"old\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t\t{ id: \"newest\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t\t{ id: \"active\", state: \"live_agent\", alive: true },\r\n\t\t\t\t\t\t{ id: \"foreign\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tid: call.args[3],\r\n\t\t\t\t\tadapter: call.args[3] === \"foreign\" ? \"claude-spt\" : \"omp-spt\",\r\n\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\r\n\t\t\t\tconst id = call.args[3];\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: activity[id], text: id } }] }],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tassert.deepEqual(harness.commands.get(\"live\").getArgumentCompletions(\"--\"), [\r\n\t\t{ value: \"--auto\", label: \"--auto\" },\r\n\t]);\r\n\tawait harness.commands.get(\"live\").handler(\"--auto\", harness.ctx);\r\n\tassert.match(harness.confirmations[0].message, /newest.*most recently active/s);\r\n\tconst bind = harness.calls.find((call) => call.args[3] === \"bind\");\r\n\tassert.equal(bind.args[4], \"newest\");\r\n\tassert.ok(bind.args.includes(\"live_agent\"));\r\n\tassert.ok(\r\n\t\t!harness.calls.some(\r\n\t\t\t(call) => call.args[2] === \"digest\" && [\"active\", \"foreign\"].includes(call.args[3]),\r\n\t\t),\r\n\t\t\"auto-resume must inspect only inactive compatible identities\",\r\n\t);\r\n\tawait harness.emit(\"session_shutdown\");\r\n\r\n\tconst declined = createHarness({\r\n\t\tid: null,\r\n\t\tconfirmResults: [false],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tlocal: [{ id: \"prior\", state: \"live_agent\", alive: false }],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tid: \"prior\",\r\n\t\t\t\t\tadapter: \"omp-spt\",\r\n\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: \"2026-07-15T01:00:00.000Z\" } }] }],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait declined.emit(\"session_start\");\r\n\tawait declined.commands.get(\"live\").handler(\"--auto\", declined.ctx);\r\n\tassert.equal(declined.calls.filter((call) => call.args[3] === \"bind\").length, 0);\r\n\tawait declined.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-STARTUP-BRIEF]\r\n// [unit->REQ-PARITY-TARGETED-HINTS]\r\n// [unit->REQ-PARITY-UPDATE-NOTICE]\r\nasync function testStartupBriefHintsAndUpdateNotices() {\r","truncated":true,"truncatedBy":"lines","totalLines":563,"totalBytes":7219,"outputLines":210,"outputBytes":7219,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"// [unit->REQ-PARITY-LIVE-ACTIVATION]\r\nasync function testNativeActivationCommandsAndErrors() {\r\n\tconst inert = createHarness({ id: null });\r\n\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\r\n\tassert.ok(inert.tools.has(\"spt_checkpoint\"));\r\n\tawait inert.emit(\"session_start\");\r\n\tassert.deepEqual(inert.calls, [], \"an ordinary OMP session must remain lifecycle-inert\");\r\n\tassert.equal(\r\n\t\tawait inert.emit(\"session_before_switch\", { reason: \"new\" }),\r\n\t\tundefined,\r\n\t\t\"an unbound extension must not block native session changes\",\r\n\t);\r\n\r\n\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\r\n\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");\r\n\tassert.deepEqual(readyBind.args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"bind\",\r\n\t\t\"ready-one\",\r\n\t\t\"--set-session-id\",\r\n\t\t\"session-1\",\r\n\t\t\"--type\",\r\n\t\t\"ready_agent\",\r\n\t]);\r\n\tassert.deepEqual(inert.children[0].args, [\r\n\t\t\"api\",\r\n\t\t\"--adapter\",\r\n\t\t\"omp-spt\",\r\n\t\t\"listen\",\r\n\t\t\"ready-one\",\r\n\t\t\"--session-id\",\r\n\t\t\"session-1\",\r\n\t]);\r\n\tassert.ok(\r\n\t\tinert.notifications.some(({ message, type }) =>\r\n\t\t\ttype === \"info\" && message.includes(\"ready endpoint ready-one\"),\r\n\t\t),\r\n\t);\r\n\tawait inert.commands.get(\"live\").handler(\"other-id\", inert.ctx);\r\n\tassert.equal(inert.calls.filter((call) => call.args[3] === \"bind\").length, 1);\r\n\tassert.ok(\r\n\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\r\n\t);\r\n\tawait inert.emit(\"session_shutdown\");\r\n\r\n\tlet bindAttempts = 0;\r\n\tconst retryable = createHarness({\r\n\t\tid: null,\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[3] === \"bind\") {\r\n\t\t\t\tbindAttempts += 1;\r\n\t\t\t\tif (bindAttempts === 1) throw new Error(\"identity already active\");\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait retryable.emit(\"session_start\");\r\n\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\r\n\tassert.equal(retryable.children.length, 0);\r\n\tassert.equal(retryable.shutdowns, 0, \"a pre-token command error must keep ordinary OMP usable\");\r\n\tassert.ok(\r\n\t\tretryable.notifications.some(({ message }) => message.includes(\"identity already active\")),\r\n\t);\r\n\tawait retryable.commands.get(\"live\").handler(\"retry-live\", retryable.ctx);\r\n\tassert.equal(retryable.children.length, 1, \"a corrected activation may retry after a bind error\");\r\n\tassert.ok(\r\n\t\tretryable.calls\r\n\t\t\t.findLast((call) => call.args[3] === \"bind\")\r\n\t\t\t.args.includes(\"live_agent\"),\r\n\t);\r\n\tawait retryable.emit(\"session_shutdown\");\r\n\r\n\tconst headless = createHarness({ id: null, hasUI: false });\r\n\tawait headless.emit(\"session_start\");\r\n\tawait headless.commands.get(\"ready\").handler(\"\", headless.ctx);\r\n\tassert.deepEqual(headless.calls, []);\r\n\tassert.ok(\r\n\t\theadless.notifications.some(({ message }) => message.includes(\"requires an endpoint id\")),\r\n\t\t\"ordinary activation must never guess an identity when native selection is unavailable\",\r\n\t);\r\n\tawait headless.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-READY-ACTIVATION]\r\nasync function testNativeActivationSelectionAndCompletion() {\r\n\tconst harness = createHarness({\r\n\t\tid: null,\r\n\t\tselectResults: [\"ready-old\"],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tlocal: [\r\n\t\t\t\t\t\t{ id: \"ready-old\", state: \"ready_agent\", alive: false },\r\n\t\t\t\t\t\t{ id: \"ready-busy\", state: \"ready_agent\", alive: true },\r\n\t\t\t\t\t\t{ id: \"live-old\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tid: call.args[3],\r\n\t\t\t\t\tadapter: \"omp-spt\",\r\n\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\r\n\tassert.deepEqual(harness.selections[0].values, [\r\n\t\t\"ready-old\",\r\n\t\t\"Create a new endpoint id\",\r\n\t]);\r\n\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], \"ready-old\");\r\n\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\r\n\t\t{ value: \"ready-old\", label: \"ready-old\" },\r\n\t]);\r\n\tassert.ok(\r\n\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\r\n\t\t\"selection and activation must not start an agent-managed background poll\",\r\n\t);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\r\nasync function testExplicitLiveAutoResume() {\r\n\tconst activity = {\r\n\t\told: \"2026-07-10T00:00:00.000Z\",\r\n\t\tnewest: \"2026-07-15T00:00:00.000Z\",\r\n\t};\r\n\tconst harness = createHarness({\r\n\t\tid: null,\r\n\t\tconfirmResults: [true],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tlocal: [\r\n\t\t\t\t\t\t{ id: \"old\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t\t{ id: \"newest\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t\t{ id: \"active\", state: \"live_agent\", alive: true },\r\n\t\t\t\t\t\t{ id: \"foreign\", state: \"live_agent\", alive: false },\r\n\t\t\t\t\t],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tid: call.args[3],\r\n\t\t\t\t\tadapter: call.args[3] === \"foreign\" ? \"claude-spt\" : \"omp-spt\",\r\n\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\r\n\t\t\t\tconst id = call.args[3];\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: activity[id], text: id } }] }],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tassert.deepEqual(harness.commands.get(\"live\").getArgumentCompletions(\"--\"), [\r\n\t\t{ value: \"--auto\", label: \"--auto\" },\r\n\t]);\r\n\tawait harness.commands.get(\"live\").handler(\"--auto\", harness.ctx);\r\n\tassert.match(harness.confirmations[0].message, /newest.*most recently active/s);\r\n\tconst bind = harness.calls.find((call) => call.args[3] === \"bind\");\r\n\tassert.equal(bind.args[4], \"newest\");\r\n\tassert.ok(bind.args.includes(\"live_agent\"));\r\n\tassert.ok(\r\n\t\t!harness.calls.some(\r\n\t\t\t(call) => call.args[2] === \"digest\" && [\"active\", \"foreign\"].includes(call.args[3]),\r\n\t\t),\r\n\t\t\"auto-resume must inspect only inactive compatible identities\",\r\n\t);\r\n\tawait harness.emit(\"session_shutdown\");\r\n\r\n\tconst declined = createHarness({\r\n\t\tid: null,\r\n\t\tconfirmResults: [false],\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\" && call.args[2] === \"list\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tlocal: [{ id: \"prior\", state: \"live_agent\", alive: false }],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tid: \"prior\",\r\n\t\t\t\t\tadapter: \"omp-spt\",\r\n\t\t\t\t\tcwd: \"C:\\\\work\\\\project\",\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"digest\") {\r\n\t\t\t\treturn JSON.stringify({\r\n\t\t\t\t\tturns: [{ entries: [{ Agent: { ts: \"2026-07-15T01:00:00.000Z\" } }] }],\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait declined.emit(\"session_start\");\r\n\tawait declined.commands.get(\"live\").handler(\"--auto\", declined.ctx);\r\n\tassert.equal(declined.calls.filter((call) => call.args[3] === \"bind\").length, 0);\r\n\tawait declined.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-STARTUP-BRIEF]\r\n// [unit->REQ-PARITY-TARGETED-HINTS]\r\n// [unit->REQ-PARITY-UPDATE-NOTICE]\r\nasync function testStartupBriefHintsAndUpdateNotices() {\r\n…\n}","startLine":1434,"lineNumbers":[1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,null,1726]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1996,"totalBytes":7219,"outputLines":210,"outputBytes":7219,"shownRange":{"start":1434,"end":1643},"nextOffset":1644}}},"isError":false,"timestamp":1784192741286}}
{"type":"message","id":"b18932b7","parentId":"44cf1b75","timestamp":"2026-07-16T09:05:50.422Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning Linux path tests and error handling**"},{"type":"toolCall","id":"call_Tz8sJGxNhj9LdaW5nK2VyyDK|fc_09ab79121c733b56016a589eece830819985b365ef4aa66aa1","name":"read","arguments":{"i":"Reading activation parser and selection","path":"adapter/strings/omp-spt.mjs","selector":"830-1128"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":9175,"output":135,"cacheRead":81408,"cacheWrite":0,"totalTokens":90718,"reasoningTokens":93,"cost":{"input":0.045875000000000006,"output":0.00405,"cacheRead":0.040704,"cacheWrite":0,"total":0.090629}},"stopReason":"toolUse","timestamp":1784192741294,"responseId":"resp_09ab79121c733b56016a589ee5c7388199bed27e323672b107","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589ee8c41c8199a3691e44f72149e2","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ7sUNeDbi35DMxyD6iECupPc9ExV-ji83E34nB0EjEUb15ip7ReIut6e90xzYvjdK9FZcDyINeGQCLr5dP_exKmM9Wz9jMZs-OJJIOlYsOm_UAqL6Z5roYiBmNHU9w2skQf6vFV03YDMPbPmYoBYe2lIVhAnJObJBo6GeB3bx_bvJbuKBHdwC4bGsEcSiKqTRAWf5ahZxM3QxtiMOzgPTe_P823lHX6PzkJL63BMFGqj-HW1shHtzRdvJ9Zc_NSxLIh91xuvgkXm-L0HRvpKYcb15uc0ExquzudI9-K7bMPyiIuM8ROdz6slgOy9vWWlq93-Pt-DsX24eindCPTXByaRI0w0h78SBqsYnCNzBiaBZDV_HShv5aM5f320zXzANtgb-A9NdTfyIaih0tac1Q-_oz05b1lr-jnETjodN_RNCE4cNRueCYexbdLnF2xyYmHoFLXsxYer3pF46KMCMt5s_qZ-at4T6mv-5kXctcMojz2QxnXUBbpPft7-B25hj5WVIIgXNimsNVq1STNVQ0hJ5oy-dIqAZqFmXcnHxrEQVSYmFDc9hReCOCqA5aFpF7dPVzEiFPT0UJHtgNYZlE1LPzml5Bcpmda4FbsiDL_vl5WNj6B3vT75BEVsnSuy0fJyWL3FdmE--PajAZfTFvLRmv9gdDH-ZfvJoC7ycILXQkSQKWFS119S85iLisPjHcf0s2W98z-NWj-tMBaWaoenV2-c7bRF2aW8Nkx9L5iSab42UdqOh9wF1jSXnX93kUlxdF-bC6LxDm-YqkhFJkW-AR47BQnp2G0I8Hi56ko5aX9AiWkXgd1QoVjqfE-12HhiQ8ZkBGjDwamHdxwgxct4DPdUVHme5FyweusWFleMOS_v-CXE8xuqdmxE5t_3IBpQ9O2wpsR3hHQYCAioqq7gJSKshm5N-PgjhnCa69sn3qiSQjRF_Ia6HMYFkMzN6ckIJE9Hg9-_W56MKlCtiWMQwzcJUfUUnIsj9PkP0Hdf-G3g5aCh2YwjAhg38LSMnoqbjrCo72J9VXkwm8o0lo3B_ymJyBnjObH4LHtpdnXsPftK1Z79JhDFz-WNwTxgb58bXQSGE6byAXpOQ01rQpCWSRP5zVQwLtnSq2XCZZm4pHrFjIQfvkqOaZ_U7uWyRLnDzE93JLzFGO35epZnm1PzM3kqOIo02YMReLrXlkCCUd5-4LB48TmLofSY8S5H0bScxrNMGBKzQ_RpEw5NDBh8mH1YzZhjxyCPS4q3LO_W0N7ZNkJwCaVl7ZJ7Nn7ZhKFbCBctGuV5rWUHlBbsGJGtQjRhvPuCnKXquCYfdW_QNRdICDKlKcUlQpsfcZR_eor67HnWABNdWP_IifyDmKK3SSIEoS-7aD4W7Hb5TqgfMK_LnDqqc3Db-mx3UyVXbpnTBHFBd5CorZ8VeSNwnhxb_ot46F9Wu61hXe-ki7nSqk7TbehIa4mAtVzavsm-dQvsVoYjW-vMJ8mJMnWzROGs-FHewjcxb9K9cEQErLbQrii-iurLs90TGqA7JKjkGpA","summary":[{"type":"summary_text","text":"**Planning Linux path tests and error handling**"}]},{"id":"fc_09ab79121c733b56016a589eece830819985b365ef4aa66aa1","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading activation parser and selection\",\"path\":\"adapter/strings/omp-spt.mjs\",\"selector\":\"830-1128\"}","call_id":"call_Tz8sJGxNhj9LdaW5nK2VyyDK","name":"read"}]},"duration":9122.07509999955,"ttft":3452.36549999984,"contextSnapshot":{"promptTokens":90583,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Tz8sJGxNhj9LdaW5nK2VyyDK|fc_09ab79121c733b56016a589eece830819985b365ef4aa66aa1","toolName":"read","startedAt":"2026-07-16T09:05:50.422Z","args":{"path":"adapter/strings/omp-spt.mjs"},"intent":"Reading activation parser and selection"},"id":"fbaa281a","parentId":"b18932b7","timestamp":"2026-07-16T09:05:50.422Z"}
{"type":"message","id":"06aad4b7","parentId":"fbaa281a","timestamp":"2026-07-16T09:05:50.437Z","message":{"role":"toolResult","toolCallId":"call_Tz8sJGxNhj9LdaW5nK2VyyDK|fc_09ab79121c733b56016a589eece830819985b365ef4aa66aa1","toolName":"read","content":[{"type":"text","text":"[omp-spt.mjs#9CB1]\n806:\t\tasync function detectUpdateNotices() {\n…\n816:\t\t\tif (\n…\n819:\t\t\t) {\n…\n821:\t\t\t\tif (current) {\n822:\t\t\t\t\ttry {\n…\n829:\t\t\t\t\t} catch (error) {\n830:\t\t\t\t\t\tpi.logger.debug(\"omp-spt update notification probe skipped\", {\n831:\t\t\t\t\t\t\terror: errorSummary(error),\n832:\t\t\t\t\t\t});\n833:\t\t\t\t\t}\n834:\t\t\t\t}\n835:\t\t\t}\n836:\n837:\t\t\tif (\n838:\t\t\t\tadapterVersionResult.status === \"fulfilled\" &&\n839:\t\t\t\tlatestAdapterResult.status === \"fulfilled\"\n840:\t\t\t) {\n841:\t\t\t\tconst current = parseVersion(adapterVersionResult.value);\n842:\t\t\t\tconst latest = parseVersion(latestAdapterResult.value);\n843:\t\t\t\tif (current && latest && compareVersions(latest, current) > 0) {\n844:\t\t\t\t\tnotices.push(\n845:\t\t\t\t\t\t`omp-spt ${formatVersion(latest)} is available; run \\`spt adapter update omp-spt\\`, then restart this endpoint.`,\n846:\t\t\t\t\t);\n847:\t\t\t\t}\n848:\t\t\t}\n849:\t\t\treturn notices;\n850:\t\t}\n851:\n852:\t\tfunction beginUpdateProbe() {\n853:\t\t\tupdateNoticesPending = true;\n854:\t\t\tupdateNoticesPromise = checkUpdates\n855:\t\t\t\t? detectUpdateNotices().catch((error) => {\n856:\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\n857:\t\t\t\t\t\t\terror: errorSummary(error),\n858:\t\t\t\t\t\t});\n859:\t\t\t\t\t\treturn [];\n860:\t\t\t\t\t})\n861:\t\t\t\t: Promise.resolve([]);\n862:\t\t}\n863:\n864:\t\tasync function compatibleCandidates(type, ctx) {\n865:\t\t\tconst listing = parseJson(\n866:\t\t\t\tawait runCommand([\"--json\", \"endpoint\", \"list\", \"--show-all\"]),\n867:\t\t\t\t\"spt endpoint list\",\n868:\t\t\t);\n869:\t\t\tconst local = (listing.local ?? []).filter(\n870:\t\t\t\t(candidate) =>\n871:\t\t\t\t\tcandidate?.state === type &&\n872:\t\t\t\t\tcandidate?.alive !== true &&\n873:\t\t\t\t\tendpointIdPattern.test(candidate?.id ?? \"\"),\n874:\t\t\t);\n875:\t\t\tconst currentDirectory = normalizePath(ctx.cwd);\n876:\t\t\tconst detailed = await Promise.all(\n877:\t\t\t\tlocal.map(async (candidate) => {\n878:\t\t\t\t\ttry {\n879:\t\t\t\t\t\tconst info = parseJson(\n880:\t\t\t\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", candidate.id]),\n881:\t\t\t\t\t\t\t`spt api endpoint-info ${candidate.id}`,\n882:\t\t\t\t\t\t);\n883:\t\t\t\t\t\tif (String(info.adapter ?? \"\").split(\":\")[0] !== ADAPTER) return undefined;\n884:\t\t\t\t\t\tif (\n885:\t\t\t\t\t\t\tcurrentDirectory &&\n886:\t\t\t\t\t\t\tinfo.cwd &&\n887:\t\t\t\t\t\t\tnormalizePath(info.cwd) !== currentDirectory\n888:\t\t\t\t\t\t) {\n889:\t\t\t\t\t\t\treturn undefined;\n890:\t\t\t\t\t\t}\n891:\t\t\t\t\t\treturn { id: candidate.id, info };\n892:\t\t\t\t\t} catch (error) {\n893:\t\t\t\t\t\tpi.logger.debug(\"omp-spt activation candidate skipped\", {\n894:\t\t\t\t\t\t\tid: candidate.id,\n895:\t\t\t\t\t\t\terror: errorSummary(error),\n896:\t\t\t\t\t\t});\n897:\t\t\t\t\t\treturn undefined;\n898:\t\t\t\t\t}\n899:\t\t\t\t}),\n900:\t\t\t);\n901:\t\t\tconst candidates = detailed.filter(Boolean);\n902:\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\n903:\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\n904:\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\n905:\t\t\treturn candidates;\n906:\t\t}\n907:\n908:\t\tasync function chooseIdentity(type, ctx) {\n909:\t\t\tif (!ctx.hasUI) {\n910:\t\t\t\tctx.ui.notify(\n911:\t\t\t\t\t`/${type === \"live_agent\" ? \"live\" : \"ready\"} requires an endpoint id when native selection is unavailable`,\n912:\t\t\t\t\t\"error\",\n913:\t\t\t\t);\n914:\t\t\t\treturn undefined;\n915:\t\t\t}\n916:\t\t\tlet candidates;\n917:\t\t\ttry {\n918:\t\t\t\tcandidates = await compatibleCandidates(type, ctx);\n919:\t\t\t} catch (error) {\n920:\t\t\t\tlogError(\"omp-spt could not list compatible endpoint identities\", error);\n921:\t\t\t\treturn undefined;\n922:\t\t\t}\n923:\t\t\tconst createLabel = \"Create a new endpoint id\";\n924:\t\t\tconst selected =\n925:\t\t\t\tcandidates.length > 0\n926:\t\t\t\t\t? await ctx.ui.select(\n927:\t\t\t\t\t\t\t`Select ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint`,\n928:\t\t\t\t\t\t\t[...candidates.map((candidate) => candidate.id), createLabel],\n929:\t\t\t\t\t\t)\n930:\t\t\t\t\t: createLabel;\n931:\t\t\tif (!selected) return undefined;\n932:\t\t\tif (selected !== createLabel) return selected;\n933:\t\t\treturn (await ctx.ui.input(\"New SPT endpoint id\", \"letters, numbers, - or _\"))?.trim();\n934:\t\t}\n935:\n936:\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\n937:\t\tasync function chooseAutoResume(ctx) {\n938:\t\t\tif (!ctx.hasUI) {\n939:\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\n940:\t\t\t\treturn undefined;\n941:\t\t\t}\n942:\t\t\tlet candidates;\n943:\t\t\ttry {\n944:\t\t\t\tcandidates = await compatibleCandidates(\"live_agent\", ctx);\n945:\t\t\t} catch (error) {\n946:\t\t\t\tlogError(\"omp-spt could not list live auto-resume candidates\", error);\n947:\t\t\t\treturn undefined;\n948:\t\t\t}\n949:\t\t\tconst recent = (\n950:\t\t\t\tawait Promise.all(\n951:\t\t\t\t\tcandidates.map(async (candidate) => {\n952:\t\t\t\t\t\ttry {\n953:\t\t\t\t\t\t\tconst digest = parseJson(\n954:\t\t\t\t\t\t\t\tawait runCommand([\n955:\t\t\t\t\t\t\t\t\t\"--json\",\n956:\t\t\t\t\t\t\t\t\t\"endpoint\",\n957:\t\t\t\t\t\t\t\t\t\"digest\",\n958:\t\t\t\t\t\t\t\t\tcandidate.id,\n959:\t\t\t\t\t\t\t\t\t\"--last\",\n960:\t\t\t\t\t\t\t\t\t\"1\",\n961:\t\t\t\t\t\t\t\t]),\n962:\t\t\t\t\t\t\t\t`spt endpoint digest ${candidate.id}`,\n963:\t\t\t\t\t\t\t);\n964:\t\t\t\t\t\t\treturn {\n965:\t\t\t\t\t\t\t\t...candidate,\n966:\t\t\t\t\t\t\t\tlastActiveAt: latestDigestTimestamp(digest),\n967:\t\t\t\t\t\t\t};\n968:\t\t\t\t\t\t} catch {\n969:\t\t\t\t\t\t\treturn { ...candidate, lastActiveAt: Number.NEGATIVE_INFINITY };\n970:\t\t\t\t\t\t}\n971:\t\t\t\t\t}),\n972:\t\t\t\t)\n973:\t\t\t).filter((candidate) => Number.isFinite(candidate.lastActiveAt));\n974:\t\t\trecent.sort(\n975:\t\t\t\t(left, right) =>\n976:\t\t\t\t\tright.lastActiveAt - left.lastActiveAt || left.id.localeCompare(right.id),\n977:\t\t\t);\n978:\t\t\tif (recent.length === 0) {\n979:\t\t\t\tctx.ui.notify(\n980:\t\t\t\t\t\"No compatible prior omp-spt live identity has recorded activity; use `/live <id>`\",\n981:\t\t\t\t\t\"error\",\n982:\t\t\t\t);\n983:\t\t\t\treturn undefined;\n984:\t\t\t}\n985:\t\t\tlet candidate = recent[0];\n986:\t\t\tconst ties = recent.filter((item) => item.lastActiveAt === candidate.lastActiveAt);\n987:\t\t\tif (ties.length > 1) {\n988:\t\t\t\tconst selected = await ctx.ui.select(\n989:\t\t\t\t\t\"Select equally recent live endpoint\",\n990:\t\t\t\t\tties.map((item) => item.id),\n991:\t\t\t\t);\n992:\t\t\t\tif (!selected) return undefined;\n993:\t\t\t\tcandidate = ties.find((item) => item.id === selected);\n994:\t\t\t}\n995:\t\t\tconst confirmed = await ctx.ui.confirm(\n996:\t\t\t\t\"Resume live endpoint?\",\n997:\t\t\t\t`${candidate.id} was the most recently active compatible live endpoint (${new Date(\n998:\t\t\t\t\tcandidate.lastActiveAt,\n999:\t\t\t\t).toISOString()}). Bind this OMP session to it?`,\n1000:\t\t\t);\n1001:\t\t\treturn confirmed ? candidate.id : undefined;\n1002:\t\t}\n1003:\n1004:\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\n1005:\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\n1006:\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n1007:\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\n1008:\t\t\t\tctx.ui.notify(\n1009:\t\t\t\t\t\"SPT endpoint ids may contain only letters, numbers, `-`, and `_`\",\n1010:\t\t\t\t\t\"error\",\n1011:\t\t\t\t);\n1012:\t\t\t\treturn false;\n1013:\t\t\t}\n1014:\t\t\tif (activated || token) {\n1015:\t\t\t\tctx.ui.notify(\n1016:\t\t\t\t\t`This OMP session is immutably bound to ${id}; stop it before activating another identity`,\n1017:\t\t\t\t\t\"warning\",\n1018:\t\t\t\t);\n1019:\t\t\t\treturn false;\n1020:\t\t\t}\n1021:\t\t\tif (stopping) {\n1022:\t\t\t\tctx.ui.notify(\"This OMP session is already shutting down\", \"error\");\n1023:\t\t\t\treturn false;\n1024:\t\t\t}\n1025:\t\t\tif (activationPromise) return activationPromise;\n1026:\n1027:\t\t\truntimeCtx = ctx;\n1028:\t\t\tui = ctx.ui;\n1029:\t\t\tsid = ctx.sessionManager.getSessionId();\n1030:\t\t\tid = nextId;\n1031:\t\t\tactivationType = type;\n1032:\t\t\tlet bound = false;\n1033:\t\t\tconst operation = (async () => {\n1034:\t\t\t\tconst bindArgs = [\n1035:\t\t\t\t\t\"api\",\n1036:\t\t\t\t\t\"--adapter\",\n1037:\t\t\t\t\tADAPTER,\n1038:\t\t\t\t\t\"bind\",\n1039:\t\t\t\t\tid,\n1040:\t\t\t\t\t\"--set-session-id\",\n1041:\t\t\t\t\tsid,\n1042:\t\t\t\t];\n1043:\t\t\t\tif (type) bindArgs.push(\"--type\", type);\n1044:\t\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\n1045:\t\t\t\tbindPromise = (async () => {\n1046:\t\t\t\t\tconst response = await runCommand(bindArgs);\n1047:\t\t\t\t\ttoken = response.match(/\\btoken=([^\\s]+)/)?.[1];\n1048:\t\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\n1049:\t\t\t\t\tbound = true;\n1050:\t\t\t\t})();\n1051:\t\t\t\ttry {\n1052:\t\t\t\t\tawait bindPromise;\n1053:\t\t\t\t\tawait syncDesiredState();\n1054:\t\t\t\t\tif (stopping) {\n1055:\t\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\n1056:\t\t\t\t\t\treturn false;\n1057:\t\t\t\t\t}\n1058:\t\t\t\t\tactivated = true;\n1059:\t\t\t\t\tstartupBriefPending = true;\n1060:\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\n1061:\t\t\t\t\tstartListener();\n1062:\t\t\t\t\tbeginUpdateProbe();\n1063:\t\t\t\t\tif (options.announce) {\n1064:\t\t\t\t\t\tui.notify(\n1065:\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\n1066:\t\t\t\t\t\t\t\"info\",\n1067:\t\t\t\t\t\t);\n1068:\t\t\t\t\t}\n1069:\t\t\t\t\treturn true;\n1070:\t\t\t\t} catch (error) {\n1071:\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\n1072:\t\t\t\t\tif (options.fatal || bound) {\n1073:\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\n1074:\t\t\t\t\t\treturn false;\n1075:\t\t\t\t\t}\n1076:\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\n1077:\t\t\t\t\t\terror: errorSummary(error),\n1078:\t\t\t\t\t});\n1079:\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\n1080:\t\t\t\t\tid = undefined;\n1081:\t\t\t\t\tactivationType = undefined;\n1082:\t\t\t\t\tbindPromise = undefined;\n1083:\t\t\t\t\ttoken = undefined;\n1084:\t\t\t\t\treturn false;\n1085:\t\t\t\t}\n1086:\t\t\t})();\n1087:\t\t\tactivationPromise = operation;\n1088:\t\t\ttry {\n1089:\t\t\t\treturn await operation;\n1090:\t\t\t} finally {\n1091:\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\n1092:\t\t\t}\n1093:\t\t}\n1094:\n1095:\t\tasync function handleActivationCommand(type, args, ctx) {\n1096:\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\n1097:\t\t\tconst trimmed = args.trim();\n1098:\t\t\tlet nextId;\n1099:\t\t\tif (trimmed === \"--auto\") {\n1100:\t\t\t\tif (type !== \"live_agent\") {\n1101:\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\n1102:\t\t\t\t\treturn;\n1103:\t\t\t\t}\n1104:\t\t\t\tnextId = await chooseAutoResume(ctx);\n1105:\t\t\t} else if (!trimmed) {\n1106:\t\t\t\tnextId = await chooseIdentity(type, ctx);\n1107:\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\n1108:\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\n1109:\t\t\t\treturn;\n1110:\t\t\t} else {\n1111:\t\t\t\tnextId = trimmed;\n1112:\t\t\t}\n1113:\t\t\tif (!nextId) return;\n1114:\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\n1115:\t\t}\n1116:\t\tpi.registerCommand(\"ready\", {\n1117:\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\n1118:\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\n1119:\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\n1120:\t\t});\n1121:\n1122:\t\tpi.registerCommand(\"live\", {\n1123:\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\n1124:\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\n1125:\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\n1126:\t\t});\n1127:\t\tasync function resolveActivationType() {\n1128:\t\t\tif (activationType) return activationType;\n1129:\t\t\tconst info = parseJson(\n1130:\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", id]),\n1131:\t\t\t\t`spt api endpoint-info ${id}`,\n1132:\t\t\t);\n…\n1138:\t\t}\n\n[Showing lines 829-1131 of 1915. Use :1132 to continue]"}],"details":{"truncation":{"content":"\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tpi.logger.debug(\"omp-spt update notification probe skipped\", {\r\n\t\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (\r\n\t\t\t\tadapterVersionResult.status === \"fulfilled\" &&\r\n\t\t\t\tlatestAdapterResult.status === \"fulfilled\"\r\n\t\t\t) {\r\n\t\t\t\tconst current = parseVersion(adapterVersionResult.value);\r\n\t\t\t\tconst latest = parseVersion(latestAdapterResult.value);\r\n\t\t\t\tif (current && latest && compareVersions(latest, current) > 0) {\r\n\t\t\t\t\tnotices.push(\r\n\t\t\t\t\t\t`omp-spt ${formatVersion(latest)} is available; run \\`spt adapter update omp-spt\\`, then restart this endpoint.`,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn notices;\r\n\t\t}\r\n\r\n\t\tfunction beginUpdateProbe() {\r\n\t\t\tupdateNoticesPending = true;\r\n\t\t\tupdateNoticesPromise = checkUpdates\r\n\t\t\t\t? detectUpdateNotices().catch((error) => {\r\n\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\r\n\t\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\treturn [];\r\n\t\t\t\t\t})\r\n\t\t\t\t: Promise.resolve([]);\r\n\t\t}\r\n\r\n\t\tasync function compatibleCandidates(type, ctx) {\r\n\t\t\tconst listing = parseJson(\r\n\t\t\t\tawait runCommand([\"--json\", \"endpoint\", \"list\", \"--show-all\"]),\r\n\t\t\t\t\"spt endpoint list\",\r\n\t\t\t);\r\n\t\t\tconst local = (listing.local ?? []).filter(\r\n\t\t\t\t(candidate) =>\r\n\t\t\t\t\tcandidate?.state === type &&\r\n\t\t\t\t\tcandidate?.alive !== true &&\r\n\t\t\t\t\tendpointIdPattern.test(candidate?.id ?? \"\"),\r\n\t\t\t);\r\n\t\t\tconst currentDirectory = normalizePath(ctx.cwd);\r\n\t\t\tconst detailed = await Promise.all(\r\n\t\t\t\tlocal.map(async (candidate) => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst info = parseJson(\r\n\t\t\t\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", candidate.id]),\r\n\t\t\t\t\t\t\t`spt api endpoint-info ${candidate.id}`,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tif (String(info.adapter ?? \"\").split(\":\")[0] !== ADAPTER) return undefined;\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tcurrentDirectory &&\r\n\t\t\t\t\t\t\tinfo.cwd &&\r\n\t\t\t\t\t\t\tnormalizePath(info.cwd) !== currentDirectory\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\treturn undefined;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn { id: candidate.id, info };\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tpi.logger.debug(\"omp-spt activation candidate skipped\", {\r\n\t\t\t\t\t\t\tid: candidate.id,\r\n\t\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\treturn undefined;\r\n\t\t\t\t\t}\r\n\t\t\t\t}),\r\n\t\t\t);\r\n\t\t\tconst candidates = detailed.filter(Boolean);\r\n\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\r\n\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\r\n\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\r\n\t\t\treturn candidates;\r\n\t\t}\r\n\r\n\t\tasync function chooseIdentity(type, ctx) {\r\n\t\t\tif (!ctx.hasUI) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t`/${type === \"live_agent\" ? \"live\" : \"ready\"} requires an endpoint id when native selection is unavailable`,\r\n\t\t\t\t\t\"error\",\r\n\t\t\t\t);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tlet candidates;\r\n\t\t\ttry {\r\n\t\t\t\tcandidates = await compatibleCandidates(type, ctx);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not list compatible endpoint identities\", error);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tconst createLabel = \"Create a new endpoint id\";\r\n\t\t\tconst selected =\r\n\t\t\t\tcandidates.length > 0\r\n\t\t\t\t\t? await ctx.ui.select(\r\n\t\t\t\t\t\t\t`Select ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint`,\r\n\t\t\t\t\t\t\t[...candidates.map((candidate) => candidate.id), createLabel],\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t: createLabel;\r\n\t\t\tif (!selected) return undefined;\r\n\t\t\tif (selected !== createLabel) return selected;\r\n\t\t\treturn (await ctx.ui.input(\"New SPT endpoint id\", \"letters, numbers, - or _\"))?.trim();\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\r\n\t\tasync function chooseAutoResume(ctx) {\r\n\t\t\tif (!ctx.hasUI) {\r\n\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tlet candidates;\r\n\t\t\ttry {\r\n\t\t\t\tcandidates = await compatibleCandidates(\"live_agent\", ctx);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not list live auto-resume candidates\", error);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tconst recent = (\r\n\t\t\t\tawait Promise.all(\r\n\t\t\t\t\tcandidates.map(async (candidate) => {\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tconst digest = parseJson(\r\n\t\t\t\t\t\t\t\tawait runCommand([\r\n\t\t\t\t\t\t\t\t\t\"--json\",\r\n\t\t\t\t\t\t\t\t\t\"endpoint\",\r\n\t\t\t\t\t\t\t\t\t\"digest\",\r\n\t\t\t\t\t\t\t\t\tcandidate.id,\r\n\t\t\t\t\t\t\t\t\t\"--last\",\r\n\t\t\t\t\t\t\t\t\t\"1\",\r\n\t\t\t\t\t\t\t\t]),\r\n\t\t\t\t\t\t\t\t`spt endpoint digest ${candidate.id}`,\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t\t...candidate,\r\n\t\t\t\t\t\t\t\tlastActiveAt: latestDigestTimestamp(digest),\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t} catch {\r\n\t\t\t\t\t\t\treturn { ...candidate, lastActiveAt: Number.NEGATIVE_INFINITY };\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}),\r\n\t\t\t\t)\r\n\t\t\t).filter((candidate) => Number.isFinite(candidate.lastActiveAt));\r\n\t\t\trecent.sort(\r\n\t\t\t\t(left, right) =>\r\n\t\t\t\t\tright.lastActiveAt - left.lastActiveAt || left.id.localeCompare(right.id),\r\n\t\t\t);\r\n\t\t\tif (recent.length === 0) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t\"No compatible prior omp-spt live identity has recorded activity; use `/live <id>`\",\r\n\t\t\t\t\t\"error\",\r\n\t\t\t\t);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tlet candidate = recent[0];\r\n\t\t\tconst ties = recent.filter((item) => item.lastActiveAt === candidate.lastActiveAt);\r\n\t\t\tif (ties.length > 1) {\r\n\t\t\t\tconst selected = await ctx.ui.select(\r\n\t\t\t\t\t\"Select equally recent live endpoint\",\r\n\t\t\t\t\tties.map((item) => item.id),\r\n\t\t\t\t);\r\n\t\t\t\tif (!selected) return undefined;\r\n\t\t\t\tcandidate = ties.find((item) => item.id === selected);\r\n\t\t\t}\r\n\t\t\tconst confirmed = await ctx.ui.confirm(\r\n\t\t\t\t\"Resume live endpoint?\",\r\n\t\t\t\t`${candidate.id} was the most recently active compatible live endpoint (${new Date(\r\n\t\t\t\t\tcandidate.lastActiveAt,\r\n\t\t\t\t).toISOString()}). Bind this OMP session to it?`,\r\n\t\t\t);\r\n\t\t\treturn confirmed ? candidate.id : undefined;\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\r\n\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\r\n\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\r\n\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t\"SPT endpoint ids may contain only letters, numbers, `-`, and `_`\",\r\n\t\t\t\t\t\"error\",\r\n\t\t\t\t);\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tif (activated || token) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t`This OMP session is immutably bound to ${id}; stop it before activating another identity`,\r\n\t\t\t\t\t\"warning\",\r\n\t\t\t\t);\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tif (stopping) {\r\n\t\t\t\tctx.ui.notify(\"This OMP session is already shutting down\", \"error\");\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tif (activationPromise) return activationPromise;\r\n\r\n\t\t\truntimeCtx = ctx;\r\n\t\t\tui = ctx.ui;\r\n\t\t\tsid = ctx.sessionManager.getSessionId();\r\n\t\t\tid = nextId;\r\n\t\t\tactivationType = type;\r\n\t\t\tlet bound = false;\r\n\t\t\tconst operation = (async () => {\r\n\t\t\t\tconst bindArgs = [\r\n\t\t\t\t\t\"api\",\r\n\t\t\t\t\t\"--adapter\",\r\n\t\t\t\t\tADAPTER,\r\n\t\t\t\t\t\"bind\",\r\n\t\t\t\t\tid,\r\n\t\t\t\t\t\"--set-session-id\",\r\n\t\t\t\t\tsid,\r\n\t\t\t\t];\r\n\t\t\t\tif (type) bindArgs.push(\"--type\", type);\r\n\t\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\r\n\t\t\t\tbindPromise = (async () => {\r\n\t\t\t\t\tconst response = await runCommand(bindArgs);\r\n\t\t\t\t\ttoken = response.match(/\\btoken=([^\\s]+)/)?.[1];\r\n\t\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\r\n\t\t\t\t\tbound = true;\r\n\t\t\t\t})();\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait bindPromise;\r\n\t\t\t\t\tawait syncDesiredState();\r\n\t\t\t\t\tif (stopping) {\r\n\t\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tactivated = true;\r\n\t\t\t\t\tstartupBriefPending = true;\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t\t\t\tstartListener();\r\n\t\t\t\t\tbeginUpdateProbe();\r\n\t\t\t\t\tif (options.announce) {\r\n\t\t\t\t\t\tui.notify(\r\n\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\r\n\t\t\t\t\t\t\t\"info\",\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\t\tif (options.fatal || bound) {\r\n\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\r\n\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t});\r\n\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\r\n\t\t\t\t\tid = undefined;\r\n\t\t\t\t\tactivationType = undefined;\r\n\t\t\t\t\tbindPromise = undefined;\r\n\t\t\t\t\ttoken = undefined;\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t})();\r\n\t\t\tactivationPromise = operation;\r\n\t\t\ttry {\r\n\t\t\t\treturn await operation;\r\n\t\t\t} finally {\r\n\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tasync function handleActivationCommand(type, args, ctx) {\r\n\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\r\n\t\t\tconst trimmed = args.trim();\r\n\t\t\tlet nextId;\r\n\t\t\tif (trimmed === \"--auto\") {\r\n\t\t\t\tif (type !== \"live_agent\") {\r\n\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tnextId = await chooseAutoResume(ctx);\r\n\t\t\t} else if (!trimmed) {\r\n\t\t\t\tnextId = await chooseIdentity(type, ctx);\r\n\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\r\n\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\r\n\t\t\t\treturn;\r\n\t\t\t} else {\r\n\t\t\t\tnextId = trimmed;\r\n\t\t\t}\r\n\t\t\tif (!nextId) return;\r\n\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\r\n\t\t}\r\n\t\tpi.registerCommand(\"ready\", {\r\n\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\r\n\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\r\n\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\r\n\t\t});\r\n\r\n\t\tpi.registerCommand(\"live\", {\r\n\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\r\n\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\r\n\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\r\n\t\t});\r\n\t\tasync function resolveActivationType() {\r\n\t\t\tif (activationType) return activationType;\r\n\t\t\tconst info = parseJson(\r\n\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", id]),\r\n\t\t\t\t`spt api endpoint-info ${id}`,\r","truncated":true,"truncatedBy":"lines","totalLines":1087,"totalBytes":9729,"outputLines":303,"outputBytes":9729,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"\t\tasync function detectUpdateNotices() {\n…\n\t\t\tif (\n…\n\t\t\t) {\n…\n\t\t\t\tif (current) {\n\t\t\t\t\ttry {\n…\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tpi.logger.debug(\"omp-spt update notification probe skipped\", {\r\n\t\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (\r\n\t\t\t\tadapterVersionResult.status === \"fulfilled\" &&\r\n\t\t\t\tlatestAdapterResult.status === \"fulfilled\"\r\n\t\t\t) {\r\n\t\t\t\tconst current = parseVersion(adapterVersionResult.value);\r\n\t\t\t\tconst latest = parseVersion(latestAdapterResult.value);\r\n\t\t\t\tif (current && latest && compareVersions(latest, current) > 0) {\r\n\t\t\t\t\tnotices.push(\r\n\t\t\t\t\t\t`omp-spt ${formatVersion(latest)} is available; run \\`spt adapter update omp-spt\\`, then restart this endpoint.`,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn notices;\r\n\t\t}\r\n\r\n\t\tfunction beginUpdateProbe() {\r\n\t\t\tupdateNoticesPending = true;\r\n\t\t\tupdateNoticesPromise = checkUpdates\r\n\t\t\t\t? detectUpdateNotices().catch((error) => {\r\n\t\t\t\t\t\tpi.logger.debug(\"omp-spt update probe skipped\", {\r\n\t\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\treturn [];\r\n\t\t\t\t\t})\r\n\t\t\t\t: Promise.resolve([]);\r\n\t\t}\r\n\r\n\t\tasync function compatibleCandidates(type, ctx) {\r\n\t\t\tconst listing = parseJson(\r\n\t\t\t\tawait runCommand([\"--json\", \"endpoint\", \"list\", \"--show-all\"]),\r\n\t\t\t\t\"spt endpoint list\",\r\n\t\t\t);\r\n\t\t\tconst local = (listing.local ?? []).filter(\r\n\t\t\t\t(candidate) =>\r\n\t\t\t\t\tcandidate?.state === type &&\r\n\t\t\t\t\tcandidate?.alive !== true &&\r\n\t\t\t\t\tendpointIdPattern.test(candidate?.id ?? \"\"),\r\n\t\t\t);\r\n\t\t\tconst currentDirectory = normalizePath(ctx.cwd);\r\n\t\t\tconst detailed = await Promise.all(\r\n\t\t\t\tlocal.map(async (candidate) => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tconst info = parseJson(\r\n\t\t\t\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", candidate.id]),\r\n\t\t\t\t\t\t\t`spt api endpoint-info ${candidate.id}`,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tif (String(info.adapter ?? \"\").split(\":\")[0] !== ADAPTER) return undefined;\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tcurrentDirectory &&\r\n\t\t\t\t\t\t\tinfo.cwd &&\r\n\t\t\t\t\t\t\tnormalizePath(info.cwd) !== currentDirectory\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\treturn undefined;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn { id: candidate.id, info };\r\n\t\t\t\t\t} catch (error) {\r\n\t\t\t\t\t\tpi.logger.debug(\"omp-spt activation candidate skipped\", {\r\n\t\t\t\t\t\t\tid: candidate.id,\r\n\t\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\treturn undefined;\r\n\t\t\t\t\t}\r\n\t\t\t\t}),\r\n\t\t\t);\r\n\t\t\tconst candidates = detailed.filter(Boolean);\r\n\t\t\tconst ids = candidates.map((candidate) => candidate.id).sort();\r\n\t\t\tif (type === \"ready_agent\") cachedReadyIds.splice(0, cachedReadyIds.length, ...ids);\r\n\t\t\telse cachedLiveIds.splice(0, cachedLiveIds.length, ...ids);\r\n\t\t\treturn candidates;\r\n\t\t}\r\n\r\n\t\tasync function chooseIdentity(type, ctx) {\r\n\t\t\tif (!ctx.hasUI) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t`/${type === \"live_agent\" ? \"live\" : \"ready\"} requires an endpoint id when native selection is unavailable`,\r\n\t\t\t\t\t\"error\",\r\n\t\t\t\t);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tlet candidates;\r\n\t\t\ttry {\r\n\t\t\t\tcandidates = await compatibleCandidates(type, ctx);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not list compatible endpoint identities\", error);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tconst createLabel = \"Create a new endpoint id\";\r\n\t\t\tconst selected =\r\n\t\t\t\tcandidates.length > 0\r\n\t\t\t\t\t? await ctx.ui.select(\r\n\t\t\t\t\t\t\t`Select ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint`,\r\n\t\t\t\t\t\t\t[...candidates.map((candidate) => candidate.id), createLabel],\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t: createLabel;\r\n\t\t\tif (!selected) return undefined;\r\n\t\t\tif (selected !== createLabel) return selected;\r\n\t\t\treturn (await ctx.ui.input(\"New SPT endpoint id\", \"letters, numbers, - or _\"))?.trim();\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\r\n\t\tasync function chooseAutoResume(ctx) {\r\n\t\t\tif (!ctx.hasUI) {\r\n\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tlet candidates;\r\n\t\t\ttry {\r\n\t\t\t\tcandidates = await compatibleCandidates(\"live_agent\", ctx);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tlogError(\"omp-spt could not list live auto-resume candidates\", error);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tconst recent = (\r\n\t\t\t\tawait Promise.all(\r\n\t\t\t\t\tcandidates.map(async (candidate) => {\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tconst digest = parseJson(\r\n\t\t\t\t\t\t\t\tawait runCommand([\r\n\t\t\t\t\t\t\t\t\t\"--json\",\r\n\t\t\t\t\t\t\t\t\t\"endpoint\",\r\n\t\t\t\t\t\t\t\t\t\"digest\",\r\n\t\t\t\t\t\t\t\t\tcandidate.id,\r\n\t\t\t\t\t\t\t\t\t\"--last\",\r\n\t\t\t\t\t\t\t\t\t\"1\",\r\n\t\t\t\t\t\t\t\t]),\r\n\t\t\t\t\t\t\t\t`spt endpoint digest ${candidate.id}`,\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t\t...candidate,\r\n\t\t\t\t\t\t\t\tlastActiveAt: latestDigestTimestamp(digest),\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t} catch {\r\n\t\t\t\t\t\t\treturn { ...candidate, lastActiveAt: Number.NEGATIVE_INFINITY };\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}),\r\n\t\t\t\t)\r\n\t\t\t).filter((candidate) => Number.isFinite(candidate.lastActiveAt));\r\n\t\t\trecent.sort(\r\n\t\t\t\t(left, right) =>\r\n\t\t\t\t\tright.lastActiveAt - left.lastActiveAt || left.id.localeCompare(right.id),\r\n\t\t\t);\r\n\t\t\tif (recent.length === 0) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t\"No compatible prior omp-spt live identity has recorded activity; use `/live <id>`\",\r\n\t\t\t\t\t\"error\",\r\n\t\t\t\t);\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t\tlet candidate = recent[0];\r\n\t\t\tconst ties = recent.filter((item) => item.lastActiveAt === candidate.lastActiveAt);\r\n\t\t\tif (ties.length > 1) {\r\n\t\t\t\tconst selected = await ctx.ui.select(\r\n\t\t\t\t\t\"Select equally recent live endpoint\",\r\n\t\t\t\t\tties.map((item) => item.id),\r\n\t\t\t\t);\r\n\t\t\t\tif (!selected) return undefined;\r\n\t\t\t\tcandidate = ties.find((item) => item.id === selected);\r\n\t\t\t}\r\n\t\t\tconst confirmed = await ctx.ui.confirm(\r\n\t\t\t\t\"Resume live endpoint?\",\r\n\t\t\t\t`${candidate.id} was the most recently active compatible live endpoint (${new Date(\r\n\t\t\t\t\tcandidate.lastActiveAt,\r\n\t\t\t\t).toISOString()}). Bind this OMP session to it?`,\r\n\t\t\t);\r\n\t\t\treturn confirmed ? candidate.id : undefined;\r\n\t\t}\r\n\r\n\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\r\n\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\r\n\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\r\n\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t\"SPT endpoint ids may contain only letters, numbers, `-`, and `_`\",\r\n\t\t\t\t\t\"error\",\r\n\t\t\t\t);\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tif (activated || token) {\r\n\t\t\t\tctx.ui.notify(\r\n\t\t\t\t\t`This OMP session is immutably bound to ${id}; stop it before activating another identity`,\r\n\t\t\t\t\t\"warning\",\r\n\t\t\t\t);\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tif (stopping) {\r\n\t\t\t\tctx.ui.notify(\"This OMP session is already shutting down\", \"error\");\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tif (activationPromise) return activationPromise;\r\n\r\n\t\t\truntimeCtx = ctx;\r\n\t\t\tui = ctx.ui;\r\n\t\t\tsid = ctx.sessionManager.getSessionId();\r\n\t\t\tid = nextId;\r\n\t\t\tactivationType = type;\r\n\t\t\tlet bound = false;\r\n\t\t\tconst operation = (async () => {\r\n\t\t\t\tconst bindArgs = [\r\n\t\t\t\t\t\"api\",\r\n\t\t\t\t\t\"--adapter\",\r\n\t\t\t\t\tADAPTER,\r\n\t\t\t\t\t\"bind\",\r\n\t\t\t\t\tid,\r\n\t\t\t\t\t\"--set-session-id\",\r\n\t\t\t\t\tsid,\r\n\t\t\t\t];\r\n\t\t\t\tif (type) bindArgs.push(\"--type\", type);\r\n\t\t\t\tif (env.OMP_SPT_SUBNET) bindArgs.push(\"--subnet\", env.OMP_SPT_SUBNET);\r\n\t\t\t\tbindPromise = (async () => {\r\n\t\t\t\t\tconst response = await runCommand(bindArgs);\r\n\t\t\t\t\ttoken = response.match(/\\btoken=([^\\s]+)/)?.[1];\r\n\t\t\t\t\tif (!token) throw new Error(\"spt bind response did not include token=<value>\");\r\n\t\t\t\t\tbound = true;\r\n\t\t\t\t})();\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait bindPromise;\r\n\t\t\t\t\tawait syncDesiredState();\r\n\t\t\t\t\tif (stopping) {\r\n\t\t\t\t\t\tawait teardownSession(\"OMP session shut down before initialization completed\");\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tactivated = true;\r\n\t\t\t\t\tstartupBriefPending = true;\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", `spt:${id}`);\r\n\t\t\t\t\tstartListener();\r\n\t\t\t\t\tbeginUpdateProbe();\r\n\t\t\t\t\tif (options.announce) {\r\n\t\t\t\t\t\tui.notify(\r\n\t\t\t\t\t\t\t`OMP session activated as ${type === \"live_agent\" ? \"live\" : \"ready\"} endpoint ${id}`,\r\n\t\t\t\t\t\t\t\"info\",\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tui.setStatus(\"omp-spt\", \"spt bind failed\");\r\n\t\t\t\t\tif (options.fatal || bound) {\r\n\t\t\t\t\t\tawait failClosed(`omp-spt could not bind ${id}`, error);\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpi.logger.error(`omp-spt could not bind ${id}`, {\r\n\t\t\t\t\t\terror: errorSummary(error),\r\n\t\t\t\t\t});\r\n\t\t\t\t\tui.notify(`omp-spt could not bind ${id}: ${errorSummary(error)}`, \"error\");\r\n\t\t\t\t\tid = undefined;\r\n\t\t\t\t\tactivationType = undefined;\r\n\t\t\t\t\tbindPromise = undefined;\r\n\t\t\t\t\ttoken = undefined;\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t})();\r\n\t\t\tactivationPromise = operation;\r\n\t\t\ttry {\r\n\t\t\t\treturn await operation;\r\n\t\t\t} finally {\r\n\t\t\t\tif (!activated && activationPromise === operation) activationPromise = undefined;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tasync function handleActivationCommand(type, args, ctx) {\r\n\t\t\tconst command = type === \"live_agent\" ? \"live\" : \"ready\";\r\n\t\t\tconst trimmed = args.trim();\r\n\t\t\tlet nextId;\r\n\t\t\tif (trimmed === \"--auto\") {\r\n\t\t\t\tif (type !== \"live_agent\") {\r\n\t\t\t\t\tctx.ui.notify(\"`--auto` is supported only by `/live`\", \"error\");\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tnextId = await chooseAutoResume(ctx);\r\n\t\t\t} else if (!trimmed) {\r\n\t\t\t\tnextId = await chooseIdentity(type, ctx);\r\n\t\t\t} else if (/\\s/.test(trimmed) || trimmed.startsWith(\"-\")) {\r\n\t\t\t\tctx.ui.notify(`Usage: /${command} <endpoint-id>${command === \"live\" ? \" | --auto\" : \"\"}`, \"error\");\r\n\t\t\t\treturn;\r\n\t\t\t} else {\r\n\t\t\t\tnextId = trimmed;\r\n\t\t\t}\r\n\t\t\tif (!nextId) return;\r\n\t\t\tawait activateEndpoint(nextId, type, ctx, { announce: true });\r\n\t\t}\r\n\t\tpi.registerCommand(\"ready\", {\r\n\t\t\tdescription: \"Activate this OMP session as a ready SPT endpoint\",\r\n\t\t\tgetArgumentCompletions: commandCompletions(cachedReadyIds, false),\r\n\t\t\thandler: (args, ctx) => handleActivationCommand(\"ready_agent\", args, ctx),\r\n\t\t});\r\n\r\n\t\tpi.registerCommand(\"live\", {\r\n\t\t\tdescription: \"Activate this OMP session as a live SPT endpoint\",\r\n\t\t\tgetArgumentCompletions: commandCompletions(cachedLiveIds, true),\r\n\t\t\thandler: (args, ctx) => handleActivationCommand(\"live_agent\", args, ctx),\r\n\t\t});\r\n\t\tasync function resolveActivationType() {\r\n\t\t\tif (activationType) return activationType;\r\n\t\t\tconst info = parseJson(\r\n\t\t\t\tawait runCommand([\"--json\", \"api\", \"endpoint-info\", id]),\r\n\t\t\t\t`spt api endpoint-info ${id}`,\r\n\t\t\t);\n…\n\t\t}","startLine":806,"lineNumbers":[806,null,816,null,819,null,821,822,null,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,null,1138]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\adapter\\strings\\omp-spt.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1915,"totalBytes":9729,"outputLines":303,"outputBytes":9729,"shownRange":{"start":829,"end":1131},"nextOffset":1132}}},"isError":false,"timestamp":1784192750436}}
{"type":"message","id":"61e01618","parentId":"06aad4b7","timestamp":"2026-07-16T09:06:08.540Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Resolving endpoint activation and platform normalization bug**\n\n**Enhancing platform-aware path candidate tests**"},{"type":"toolCall","id":"call_yzrt17LyoudTeMo5TowTTSQh|fc_09ab79121c733b56016a589efe79f48199b07bf18011bf5545","name":"read","arguments":{"i":"Reading shortform and abnormal tests","path":"tests/omp-extension.mjs","selector":"1780-1875"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":10544,"output":494,"cacheRead":83456,"cacheWrite":0,"totalTokens":94494,"reasoningTokens":453,"cost":{"input":0.05272,"output":0.01482,"cacheRead":0.041728,"cacheWrite":0,"total":0.109268}},"stopReason":"toolUse","timestamp":1784192750457,"responseId":"resp_09ab79121c733b56016a589eeeccd081999c610758aa6e794c","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589ef1d0c4819991df3b4a8e65529d","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ7-MGikNRkeX8nf2HSesfw3S-z_MwijMpT5QKLI9-cZ86aq_1HseFeRq_sXSoTVVwDsIdELfh_5RfUJ3YzeUbH6w_T7WffS9KMVIuXPpoLPJzC0VhPESlwTP7Y33WmSwwC3F2w2-_5IC2-kSW7dR8IGsA2DxDMGmpVjnfxkM8hGxqcwX0oxibvXv7b3-2ua6yKVVklV8Iq9axD5c-L7qSiWVmLKTlpgpdpYX8WqhcS9765qZe9U8cHq96lscHKRbKOaMnj2TY6ZvKLT8BU1u6g4kpoyTALNdrtEONaxcWudTdYA2z9zdcu4qNNZMHKwNR9QgNI3BeW0ZVKivtAV71buxISnziV_O4G2jwH1XtxByxoVSQ64aDf9GpNEh_kiOSq_AJb6YG7bIAiMJBK2z8nNa8bpZp8reEnuWHkd-vK1ApErRhrxHkOZiDRxhyAZHQ8cp3OBWyySFRQ9MNfxnSRgKHDT1Ty9psHauMC9eYTgMqk8vE0flMGaOuFcPbU3ilexOGC5O8HZMs8odtOKrrPiBLwLaJxyf6wqkcok-PNtWLtB5XTxfSus982w_h-Xb9uFgvEW10plQoEJuCjed5X0-meLwyle0ZSHw5OZC3rwUoR5nImc03Je79ibBZcEgmZpVrK4O1KDCwXO-m393kJaB65QhDp0NVhFlFJ-t5sYT3JG06A3DrYQzSxYVA4ociCej8b_T-uJGEBUBl_hk_8R2KBEAXH2QHxlNhnXZCRRDB5bHMTOQWaYJ3J2UT-2HgiL7x0rgMvGZVULb9BVEvkGmhEodP4MV2FqB1lNmiJSJ5Th_HgpEqa8tuJYF7yNr1zvkDBoHNssvBiMzYmv3HUWWmHguWLNZlbOXJxs6iYoRp4GCj7C0jQ-fY79AeWiCG2w9igYtUWFntxuL0l62MKWh3pz3zJEF1qVhY31Qn-1DyIIzHw_v8pHrQtpiMMydA55VPJMoCGcA7LwwPmssnWE-YsJimePav2Gu0snmg1oRz786-Eg0Klbf5PpL-tSTJXZdygg1A5D-x1WiuMH2SUMSYOS_zQ1q285d-6sP5r63zViFxbuBoY53XijQyAeGp-tV2dm3tLjvXUzbrXMuQLPXI4TRjDQaKZoKbp8OeqaeVaZQJCZAkTZ2HHyFXOoVl2xqqgx5g2USaLtrHi6zDhbLwVoJ6P6_2pFwtIjSdf1W5EYdc5lwailux_AC8pWCWC_5NMs8taAFdwsEM3H1xLp89Jr1A94_yjrBdos4OdwbVaXPnjVeK8RWGDwzQuk6agiz8SKX63B5W0nDbGUSfSh0XC1xlzcW2IaOexvVvypL2odcB_2U1j7BSXeV-_7IuwF187tEo8Zt1nAal7imRLp_FElVmMPqy-7_aq8YU3N49AJLOFP4dCadr9tlPp4EpEL3BPCwGQJi7lZrlR7WB7Rnzmyu6xswWxAT8xM3hKniapqUgLfsKEUWbIQsdroMLvAP9vLKjQoDtdZ6y2JvfbHuZ8DycKKUs9JZbeu2cvTZqmF5kM1bUW02hYq9QUzXIdTXWUV8fawiQk6i7EMnbJk8l-XmZUCuFbxpZ6er-KP7iLCVWh_HJ86d1UtOABQXTgU40733nhTfMpXswhwOXS6A6Jvgl03FdOOna8CUhFG5TU0ko6eysL-1QSiJihhCeOwh6eygsqh56jyKO-TdS9pTHapxGPB-T2x2Fia3fGBAE4apEmxTGwyhn7sAxDDW9uOxEFwXkCObqIE7ztD-6YjCoTt94XJ-rVrEuynQiFKNCiukAiYKtKExxi9YglVGkcPE7LbCTaXjxqrVrJ8yiAy9ryQ8eiiy3SsK3Aluxl9hwbSAm_NSEm99y4rpv3OyeHPCiMI8bJCdsXTU9PHV86EvjLYX2c2c-BK7jum3dwR5ZEOHqs2HZEEc251wq0ozmt6KkmiEUOoUU3hBWkx7VvmMjs5cXe72qcJSQ85Xi9u6Z65nZGSNVKe3NSkUWPWmm7xOM83J4vOTUR1eAfZDNVNmkrrdDsgMOPmMwmFAtTktIMK1kdVlrHcI-4qZ_0ZtsXnaLIyta7gG01FL46Cyuhynbjl9XNXREBVcN82xOI9R9q5RpppgMG4EvyCWDkVv4Dzm3z9Sm6r4NHV8XA7O8mapykA7Cu7ubN0JDubUIXyQRK5L_K7KFRTBRmkw0FVfw-OpyQ4v0cMYMUAWcjloWMAEopfQYRvuh1-468T-iUOm3tc9ThfHyabe9IEIGa-zjRJcWsQnDOKXfKFvB3KlgRNUoCfKpMx3UNYXIsEFr2zZuBvr5fZP3lXuPgYObqdRV9wa-XUayDrUkKfjxPiYnyS-RKPa99w8TL6zPrJ5GHiQx_Gv6P6ecAq_iInsvIXL9aH0GKzbU82KDRKIEbxqjkeytKpw_MibT_fp-EjT4HQ63uX7mmB8cPhQtEhiMkYg7hqMDTJ5xwNRPNyaCRnAK63C8Xdqolu8T87DUSZCtbEUZJIiOcqneLS8Tbb6jtntczC_WaVmP4QqgxoEY-3hU1_sgeRkx7UFjmSifogYRhGyEaOksdc7FfbcXfGFg5tVdiMI8ZTVg0AYmz4NDhngCat6rW_IvSmdUmQVuUjynZjwlBvpj5r0KA_Qnvf2xz34hO37QeuOWYaN751OdTcT4X3fD8yXuqtM5e0JI3CgYWG2dlT4OJIwTCZmKvFBJRDe0GlD8kdX5JpdbH0E6GiBKCnKASkBB31CkqhQZbC-rAXcXrXpzHSex2rjEOaEf5pzE1r_EzkuDMvJO64YTdWjSNhAC1qlr3_dW0g9tobKFbZ8SgTu3i8nTVdNakEOM-auPmYDuWgfYtM79iGB-3ujXUT04b83cBAxmxg1PwVc9gG2VdnScJ8GoBiU5SjHaFgZYCcTtcxFldK7k09f-42A2vBCNi0yUEmS8zu6n47LeWK9MGIcwNHDxzN0Ajz33q1kkRQOnYajod43QRei_z0z7rtDpNw59ziobFdG-TrHoVN6AvFdMYeKOH_W4J3d0d8KgZU1xgUj3Pz8epWOVNXfSLwlDa0uiLhKl_fnSDY37ricnsGcEF6-2PTWhQq8YGH0T71SYExSLZ-enjxBkhRDX646QdG6ooIl9HkZcCghvWw9FAAIYFkK77KPr1MTrV9EVCm86hDXxW42FpGvbSDEsFbJGEEhHLLYypqJbNqJj1oVTBT4ZjE0YAYHA0vYXkxY0Z9yEFK5FH66edR4r2aSD6vk4Bw3M0lY8SjRBoTdGsLObn1T2PYekLq51m7xvyevvB051uZIOHsfqhZXPA2B2iMzOUN1HeUY-5l2-KX121J8nDMxc7Y-NNB8JEZpJOpjCneFw5r8fQ-ASr-CYTYeyeFXRrnvk7MqxpCVOwHpOWByVNrP-TTUjJ_DvCRsyUahzAq1JOEMZhanF5_K31a_A9rYwm8b00pJaYpReDeb7Azd2ay6cOEa_g98zBNbfAqzRdgRjJLXgN8lmNV0nfYLwMRd09v86sT9yr3UO0almUU2i4ZTcPZLPU8VFbVoPhUMJRfTHydBq90x8ES7xTypWwqghRh7mpA92rFVi_rTXd-PA42bH6uHaJpodP2k9QORtquDkdPPML_k-FedOyKWTPg3taFKYs6lP4i_nq4ejNoojW9ium2qcrjsr5QI5tHaUurBm404M9eKH5HPTioeuchZ6N03uZRQIXBzItnDIelxyfLi5QdEDr1247-1oe_lc54-KF25MSdjjTjhEpSydIlXCiypsuVcAIrfYZaw11l-qmmvXpV8luo6vFaxSudtrAJbRm04Qjqbx8gXg8Oc9UNos_Pm9ev5vO3I_M-Jb4IWxakzXaXJxlH1uTbFnOO4u9mE_kBcibGpvcQpQQ4IJdrh98T_kfR96y3TVr96h2rOAKtI3qrvP6TIj-8n5THHudWNtzj_iVtdKBWVrAc7j_SWtGVuxSDGeG5AW8WmTp-4Xs=","summary":[{"type":"summary_text","text":"**Resolving endpoint activation and platform normalization bug**"},{"type":"summary_text","text":"**Enhancing platform-aware path candidate tests**"}]},{"id":"fc_09ab79121c733b56016a589efe79f48199b07bf18011bf5545","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading shortform and abnormal tests\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1780-1875\"}","call_id":"call_yzrt17LyoudTeMo5TowTTSQh","name":"read"}]},"duration":18082.689299999736,"ttft":3382.000800000038,"contextSnapshot":{"promptTokens":94000,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_yzrt17LyoudTeMo5TowTTSQh|fc_09ab79121c733b56016a589efe79f48199b07bf18011bf5545","toolName":"read","startedAt":"2026-07-16T09:06:08.540Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading shortform and abnormal tests"},"id":"a250c3e3","parentId":"61e01618","timestamp":"2026-07-16T09:06:08.540Z"}
{"type":"message","id":"a4aac945","parentId":"a250c3e3","timestamp":"2026-07-16T09:06:08.559Z","message":{"role":"toolResult","toolCallId":"call_yzrt17LyoudTeMo5TowTTSQh|fc_09ab79121c733b56016a589efe79f48199b07bf18011bf5545","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#FF87]\n1730:async function testActiveTurnBoundaryDeliveryAndFallback() {\n…\n1779:}\n1780:\n1781:// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n1782:async function testAbnormalTurnsRestoreReceivability() {\n1783:\tfor (const [label, completionEvent] of [\n1784:\t\t[\"cancelled\", \"session_stop\"],\n1785:\t\t[\"interrupted\", \"session_stop\"],\n1786:\t\t[\"failed\", \"agent_end\"],\n1787:\t]) {\n1788:\t\tconst harness = createHarness();\n1789:\t\tawait harness.emit(\"session_start\");\n1790:\t\tawait harness.emit(\"agent_start\");\n1791:\t\tharness.children[0].stdout.emit(\n1792:\t\t\t\"data\",\n1793:\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\n1794:\t\t);\n1795:\t\tawait flush();\n1796:\t\tconst boundary = await harness.emit(\"context\", {\n1797:\t\t\tmessages: [{ role: \"user\", content: \"active work\" }],\n1798:\t\t});\n1799:\t\tawait harness.emit(completionEvent, { messages: boundary.messages });\n1800:\t\tconst outcome = commandCalls(harness, \"send\")[0];\n1801:\t\tassert.equal(outcome.args[1], label);\n1802:\t\tassert.match(outcome.input, /turn ended without an assistant response/);\n1803:\t\tassert.equal(stateCalls(harness).at(-1).args[4], \"idle\");\n1804:\n1805:\t\tharness.children[0].stdout.emit(\n1806:\t\t\t\"data\",\n1807:\t\t\t`<EVENT type=\"msg\" from=\"${label}-next\">next</EVENT>`,\n1808:\t\t);\n1809:\t\tawait flush();\n1810:\t\tassert.deepEqual(harness.submitted, [`<msg from=\"${label}-next\"/>`]);\n1811:\t\tawait harness.emit(\"session_shutdown\");\n1812:\t}\n1813:}\n1814:\n1815:// [unit->REQ-PARITY-PEER-SHORTFORM]\n1816:async function testPeerShortformParsingAndDispatch() {\n1817:\tassert.deepEqual(\n1818:\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\n1819:\t\t\t({ targets, body }) => ({ targets, body }),\n1820:\t\t),\n1821:\t\t[\n1822:\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\n1823:\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\n1824:\t\t],\n1825:\t);\n1826:\tassert.deepEqual(\n1827:\t\tparsePeerShortforms(\n1828:\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\n1829:\t\t),\n1830:\t\t[],\n1831:\t);\n1832:\n1833:\tconst harness = createHarness({\n1834:\t\tonRun(call) {\n1835:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\n1836:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\n1837:\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\n1838:\t\t\t}\n1839:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\n1840:\t\t},\n1841:\t});\n1842:\tawait harness.emit(\"session_start\");\n1843:\tawait harness.emit(\"agent_start\");\n1844:\tawait harness.emit(\"agent_end\", {\n1845:\t\tmessages: [\n1846:\t\t\t{\n1847:\t\t\t\trole: \"assistant\",\n1848:\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n1849:\t\t\t},\n1850:\t\t],\n1851:\t});\n1852:\tassert.deepEqual(\n1853:\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\n1854:\t\t[\n1855:\t\t\t[\"alpha\", \"ship the patch\"],\n1856:\t\t\t[\"beta\", \"ship the patch\"],\n1857:\t\t\t[\"gamma\", \"inspect release\"],\n1858:\t\t],\n1859:\t);\n1860:\tassert.equal(harness.sentMessages.length, 1);\n1861:\tassert.deepEqual(harness.sentMessages[0].delivery, {\n1862:\t\tdeliverAs: \"nextTurn\",\n1863:\t\ttriggerTurn: true,\n1864:\t});\n1865:\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\n1866:\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\n1867:\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\n1868:\n1869:\tawait harness.emit(\"agent_start\");\n1870:\tawait harness.emit(\"agent_end\", {\n1871:\t\tmessages: [\n1872:\t\t\t{\n1873:\t\t\t\trole: \"assistant\",\n1874:\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n1875:\t\t\t},\n1876:\t\t],\n1877:\t});\n1878:\tassert.equal(commandCalls(harness, \"send\").length, 3);\n…\n1881:}\n\n[Showing lines 1779-1878 of 1996. Use :1879 to continue]"}],"details":{"truncation":{"content":"}\r\n\r\n// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\nasync function testAbnormalTurnsRestoreReceivability() {\r\n\tfor (const [label, completionEvent] of [\r\n\t\t[\"cancelled\", \"session_stop\"],\r\n\t\t[\"interrupted\", \"session_stop\"],\r\n\t\t[\"failed\", \"agent_end\"],\r\n\t]) {\r\n\t\tconst harness = createHarness();\r\n\t\tawait harness.emit(\"session_start\");\r\n\t\tawait harness.emit(\"agent_start\");\r\n\t\tharness.children[0].stdout.emit(\r\n\t\t\t\"data\",\r\n\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\r\n\t\t);\r\n\t\tawait flush();\r\n\t\tconst boundary = await harness.emit(\"context\", {\r\n\t\t\tmessages: [{ role: \"user\", content: \"active work\" }],\r\n\t\t});\r\n\t\tawait harness.emit(completionEvent, { messages: boundary.messages });\r\n\t\tconst outcome = commandCalls(harness, \"send\")[0];\r\n\t\tassert.equal(outcome.args[1], label);\r\n\t\tassert.match(outcome.input, /turn ended without an assistant response/);\r\n\t\tassert.equal(stateCalls(harness).at(-1).args[4], \"idle\");\r\n\r\n\t\tharness.children[0].stdout.emit(\r\n\t\t\t\"data\",\r\n\t\t\t`<EVENT type=\"msg\" from=\"${label}-next\">next</EVENT>`,\r\n\t\t);\r\n\t\tawait flush();\r\n\t\tassert.deepEqual(harness.submitted, [`<msg from=\"${label}-next\"/>`]);\r\n\t\tawait harness.emit(\"session_shutdown\");\r\n\t}\r\n}\r\n\r\n// [unit->REQ-PARITY-PEER-SHORTFORM]\r\nasync function testPeerShortformParsingAndDispatch() {\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\r\n\t\t\t({ targets, body }) => ({ targets, body }),\r\n\t\t),\r\n\t\t[\r\n\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\r\n\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\r\n\t\t],\r\n\t);\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\r\n\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\r\n\t\t),\r\n\t\t[],\r\n\t);\r\n\r\n\tconst harness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\r\n\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.deepEqual(\r\n\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\r\n\t\t[\r\n\t\t\t[\"alpha\", \"ship the patch\"],\r\n\t\t\t[\"beta\", \"ship the patch\"],\r\n\t\t\t[\"gamma\", \"inspect release\"],\r\n\t\t],\r\n\t);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tassert.deepEqual(harness.sentMessages[0].delivery, {\r\n\t\tdeliverAs: \"nextTurn\",\r\n\t\ttriggerTurn: true,\r\n\t});\r\n\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\r\n\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\r\n\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\r\n\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\").length, 3);\r","truncated":true,"truncatedBy":"lines","totalLines":218,"totalBytes":3213,"outputLines":100,"outputBytes":3213,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"async function testActiveTurnBoundaryDeliveryAndFallback() {\n…\n}\r\n\r\n// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\r\nasync function testAbnormalTurnsRestoreReceivability() {\r\n\tfor (const [label, completionEvent] of [\r\n\t\t[\"cancelled\", \"session_stop\"],\r\n\t\t[\"interrupted\", \"session_stop\"],\r\n\t\t[\"failed\", \"agent_end\"],\r\n\t]) {\r\n\t\tconst harness = createHarness();\r\n\t\tawait harness.emit(\"session_start\");\r\n\t\tawait harness.emit(\"agent_start\");\r\n\t\tharness.children[0].stdout.emit(\r\n\t\t\t\"data\",\r\n\t\t\t`<EVENT type=\"msg\" from=\"${label}\">work</EVENT>`,\r\n\t\t);\r\n\t\tawait flush();\r\n\t\tconst boundary = await harness.emit(\"context\", {\r\n\t\t\tmessages: [{ role: \"user\", content: \"active work\" }],\r\n\t\t});\r\n\t\tawait harness.emit(completionEvent, { messages: boundary.messages });\r\n\t\tconst outcome = commandCalls(harness, \"send\")[0];\r\n\t\tassert.equal(outcome.args[1], label);\r\n\t\tassert.match(outcome.input, /turn ended without an assistant response/);\r\n\t\tassert.equal(stateCalls(harness).at(-1).args[4], \"idle\");\r\n\r\n\t\tharness.children[0].stdout.emit(\r\n\t\t\t\"data\",\r\n\t\t\t`<EVENT type=\"msg\" from=\"${label}-next\">next</EVENT>`,\r\n\t\t);\r\n\t\tawait flush();\r\n\t\tassert.deepEqual(harness.submitted, [`<msg from=\"${label}-next\"/>`]);\r\n\t\tawait harness.emit(\"session_shutdown\");\r\n\t}\r\n}\r\n\r\n// [unit->REQ-PARITY-PEER-SHORTFORM]\r\nasync function testPeerShortformParsingAndDispatch() {\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\r\n\t\t\t({ targets, body }) => ({ targets, body }),\r\n\t\t),\r\n\t\t[\r\n\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\r\n\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\r\n\t\t],\r\n\t);\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\r\n\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\r\n\t\t),\r\n\t\t[],\r\n\t);\r\n\r\n\tconst harness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\r\n\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.deepEqual(\r\n\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\r\n\t\t[\r\n\t\t\t[\"alpha\", \"ship the patch\"],\r\n\t\t\t[\"beta\", \"ship the patch\"],\r\n\t\t\t[\"gamma\", \"inspect release\"],\r\n\t\t],\r\n\t);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tassert.deepEqual(harness.sentMessages[0].delivery, {\r\n\t\tdeliverAs: \"nextTurn\",\r\n\t\ttriggerTurn: true,\r\n\t});\r\n\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\r\n\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\r\n\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\r\n\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\").length, 3);\r\n…\n}","startLine":1730,"lineNumbers":[1730,null,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,null,1881]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":1996,"totalBytes":3213,"outputLines":100,"outputBytes":3213,"shownRange":{"start":1779,"end":1878},"nextOffset":1879}}},"isError":false,"timestamp":1784192768558}}
{"type":"message","id":"b211425d","parentId":"a4aac945","timestamp":"2026-07-16T09:06:33.727Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Updating test harness for message parsing**\n\n**Extending tests for failure and shutdown cases**\n\n**Refining shutdown handling with concurrent teardown**"},{"type":"toolCall","id":"call_oEhIQD631IwvstrPqUkfT6RK|fc_09ab79121c733b56016a589f1831008199ba0586dab97030a3","name":"read","arguments":{"i":"Reading current test runner tail","path":"tests/omp-extension.mjs","selector":"1950-2015"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":8214,"output":542,"cacheRead":87552,"cacheWrite":0,"totalTokens":96308,"reasoningTokens":502,"cost":{"input":0.04107,"output":0.01626,"cacheRead":0.043775999999999995,"cacheWrite":0,"total":0.101106}},"stopReason":"toolUse","timestamp":1784192768566,"responseId":"resp_09ab79121c733b56016a589f00f5908199b91257bbff134b58","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f0936848199b2a7e5bd1def6cba","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ8Y03pJ1Td1CFGSbP-c_WQ-CSsbrAsqDrowtFqogGfxpl0MdazSzj2YLFNZUwVcevR_veAOmvyeQhRnIlAbK0fD-pihM_lacc-ft2I3_gHXzSvUdRHaBWKyXRih0XFUMeT5rM69puMlRHa6YwS_1WpTgiEHsUMQuiXkcY3C5QYnQJb3GWkLGfiphot74fekOc74hwEtjMnxIku_lE49d7gAi5aqST_6ZqGdLcj0WBvTV0-fEMHFXYsXTr_kPa31SPIbbHI5Zsobt5VL2YVqE_Qrr7HEJ1WlZnS3UG0aWKLHKo1ySlRdf6qWjKrSsmpD1r1zAV76ax3qeKCZ715Pl929J9p-62g-9dA4Vau4YExuVNQsiB8TTmb8i1qtVDSDQvf083jH4yyU1bAZwmfbKXBmIwU-RYllAlQozmhw48oJzEGyDqiqfigpleqS8z2QClMdQclWLh5XinAtsnK4SMoZjTaj-fsM8iiRdS0itmzMAtd3fjTXpo5l40D50DFckP-AK4k1m_kjNiNJtNPCa5TE9WN3rPPmqG7c0WRgK0nffLzQWgpSglgPU691KrvgpDHWtWCdLnjty48Xe2WlD6fgZOX7cJuE1mivuw9ZuyGs9FP2oX2GDwDU_Fe-zDa-P0ob2D3nieaTWB4JI9ym99slFcbXG4R3d_7DfmWsusVj5BILQ4JCEkrMdopoYJ24YPa8OCfKgqgDj7UBGocjW81E-I7dTxn7GMnapyx9YQck4S6luuQD-FFkzeZJ8-LNJPrAuLOgkINjp6u0UsNSniu2auxu5rN-4zaxqpcKhuZ-0AOLMrBuFWRzGG_YG-PDSy2XPiz9r8TZBJND5yuAMx8e0cB1BapMRIQttCJjE3pseaPTwHiciv8oW1ok1j2F5kIh1nx6xFicV_sT2MpG-5MxonCDlgola4PUF4fbJYyj15z33zFdMQpKZ89CmBDNtTEjYYJkGTAy8zXC_QD05mmSx7AO37tJWSD_DVxJ8mwx0v6RuWrQDz9CVS2e2_hT45fBhL3bF9ZXKLyXS7k9vUfE6nO0Vi9fy2AAQNfvLI-7LHidQToV-vO1OLfw0RN6Njx7B3yuDQCgf-h6yd_KiUOKHFEWuKiNJh2nY3SH9oxCH5gR0d4RwHZR2Se-khazq-m3zRo_OD_tozNMPoqirEQ2RRFIyniDqP2g6m2jjx6s6FPupmBWqrCro1RZvDf5w2mhpW2b7Wg4kSB74Z4YLgJ1k6QF0SLZRoZkAiRa5L5yRTgoVczawRUzROVVTzYNxnTxyM1loTpTl3mQn7DpsC8Mr97Sjqb7DIDCGzD5suddLD-NnFm_FNBUYThJ4HhTHhIQzjUQS7H7sH7LkntCXeipy7HFnwzb1dnjxj_Yfrm3yCoOaDAcqBssQxCKZqlZp2X9f02quWI16qGg6fLZfXtFqqCd43coi5Fhlm7My6PpsYIOtmzV6lqjp1iPStbZy1g7vY8BxFKW29V41hrCf6yqW9F3bwAsO8qtxq2KBtebmMk6FvhDVEi0-qFw9ro29T4iXoXHKte7KgS749HL8Ii0eNydAissAZzRrAc7DlJafD0xt-zJ3fH0rtiRH6cYP10Oy_dy-Nx3dEKYRrwp0stz53o_CwBetGOxGQH5Wm1zRc4z78MvmCI86QHkDGrd8MlNNIuZ3HXOagk63r5MJisnvnGwb_Qa6kK0Q6bIHktkhv0lxNbTIvaS_SsXzyzSaQeg1_vrUvxyliT2hfIxQi8FwzSfeqFxsoS6LzRsVZv2NWtoahfOmJUy3DAQJrUXKh5YXIHnOURFZ9X6r6BdeRRMAdYXU1dpAbx11xB83-PKgmB6zG8gNnV4MzDTTKfF_VWZBzKD60bJ3oZNq9drhu4qRhgi9kLFEqzt-BpIh5O7huyc07cd2ksUWm7mvlO57zD2rO1vkLAdxZviP0zJMuf4jiFhhgJJYkZopXCAUZ_pD60MR2F3diuQboNOK83oJ0cuSfVsccR4QKT3yim8j8RNo_WTygTgcx1pnpKW2p5ZDeCtwcsHJpegBes3iy5c-Jc7jzATTmBPk2LJ7QfFIb3XoaTwstyFeQ0uBatqGQlSOc1tWkqzGeJL2C0vdFgsk651ZVy6mBrlyj1qc7JiYBwdv8nb67cam_ZB8X1b_Vmx4udKZPJ63tq1tja6jEuHPfPoWGpetQ4xHCbJqINWs7ugnSWYWV0zhXDEcGjPqxKWqgogaV8KXWNnxlWIP4R4lWSHpxDAIksZpALUKNe_xslCKlJKFy9-7Xes3f3oN7FXgrx07eGyT8JoTB7FjCjr7xOfW9htKyMqWwsG1_PF13__nz8kl5IdL3t_8vLLIZnSRJSCo3_-b-AJ96b1Sg6GaQlpJMMVcYiXAttG_g1Pgn9ByK2YSuD4FiXhecRs4ZJf7HpmnPCa2V3MO3urrBCMKsof_B55_1rjOJn15Qf76985dWvISZBUjQvNza-XbfTdRMujDjBgTm-Trr1OmsyiXpsZ7YuRodpKgsU3IoNRRR-o_O5fKEUUoTAzqMyhOzozEJFhWeIPCSxewqP_6DnYao_kn_pzX5UQI0WIdkWIidCYuLrAWE_8-F70Go8q4NLI6C_XumPrCv_qkG3PuoB_xKhUoD8R72-9f5ac5EQKq4GhwRkARSDA91qJWCoEY8F1u-QqE1Y48eelQma1c0euEdUTOhiOBwCzLLV2I4iJSVBUwx1Z6cpzI23c-K4vYldC5QG3wUQtuGuzHwUVo9IjE44DK_TWQGNpdG5GbTU7Mx2KEsc8ipiTNcZx334BhqQ2uk4QsvHP72tyCnA6gzaK1WALMWc8oaeCIOn3QotSD2hfpPT9G0iK-KP7EdroQhbG8w4-v40FrCZ2couS2GkHab2-vjps0A-VOBMnE0IAPwCIs9HFw8A5ajL8WVhfddpi1W7YpHPy0nS_zvsLVf_4-THzomJYaqHeMWrWFIARAN2PBpCSBaqRFQkizdOeSXOdzKFxPEKTS1Eq0wnsojvPJxA7NXof_O_VCAn4ox-Hl7uHP7O3P3p3leTUwI7u8RL4FMs0LJ-2z5rkxFMbwn8pE_tip7Lg8MS85e59YJp_-Cek2HUZMqCOvCKHI50Mg4Ki62mFlsEECZ7Tg7-uLcdiGqa7pKbN1t3PjHzMF5SKEXnJwOy-flHjbJdU7NuBYidQFQAGRC5Pn5aa2NE3TIIq7kePpuNhNHlTs4FZ8g294hJ3j6TjyLK0hTkINyBeb1aCn4VB0i85gxds7NqGUw02b1dWLAV67Ce_ByrXRV6smTEYl87RxYQAtsgjNalRuF2YVz8vW90JPwgwxCS0jxHj9xUZ6ePtM_IyPklMzqUQ6Th2Wj3YKK1KA7U8XBI-aqGLhnO_cpDiaEUexn-8-N_XoTLxKOdI8e1XHqTRcsPdYkk8g-x4UAs1kt_M81IgyzxNXTCsF9UFzI51DnBsxExe654Cc2tbGIOxTOTGyFsdmaFXXNH2ZNDLDKFdS7rSzRpAop1G_PbtcGJdl2PwFKj29QS7Kn251BvIeqaX-RD2G4XgKaIErDMUUJk06CDfCPxzMEutd3iE1mYDreaq3BW3NKaQsbBOHKH35lfyuorQTKcBKsLLP5yuE0BxcWb0OSRlv_uxhBsAM6cHMxm3GxaCPPQJGmU2CmvIlgeTqgi5Aoue-IJ9JnoSg-OGy-iCoC-TboSUF2BYO4GIB0223u6M8lGFEV10E0hm8SVOZDYSVQGNSrXw2U9p4-fc03hylL7NGLIGX9Pp1ck1hu1-kyPMXdeuRLErukOcHQMQiDyB8jGFXYGiLmC6fMStgsvE09WbA1X_Ittt9Ud7G_5Zuop6nMbI4vNAWm8zmQ-kZINjhfyo5tqw426Ild8qAK5Z65mf0DHDSlWYITUbWaTtcmi9Ru6SZ8j__Rl3PwB7nxNE5DloHG4FTiQdWPbnuC0oUXnNqMvNWIg22sESa4XXMduSTXWJODGQFnrJMBDuidgBa1fljpvO-rN22OZQbB2Dbs0sDl7r3bv_whqaBSNDPVrhMR-ADp8bK8ZuBNievwGyH7vgC_smdhKJsww_UFv-QZ53wiAiq2VGR4K2Q56orVQ1lu0fkRHwj9DSpli_CI-iaKaz7qbhFRKMDUNzKspAKHPzanU4CS7qkzcG4KTyU7jI-BPC14uXEXCXNzgTVsasFJZHo5Od7BtryotV_KS-Xfi3T6SkCvOI4HfT0B6BSkZO6bubLBWt7jUJtuPArZqUs-guNMJDO88tooLwvmAau1pHnzu0B5ZZWdY15RimpQ2UY0wvrAKcwEKaTu3tcTEPRMbaUHMAIbJTDPVLBd5IdJAPww-ZsqjcMBVhNRserb5zxaqs3PRWEA273GOj8FdOHRi1sNrhrdgTx2ZybMrKdfdDWqOVXUK-OS2KouV5cPkuXhFPotlgoz6UTYoKwlCwc22lJIcrKHjnc3wTwiqBBrMzv73XZ3gl97euSaqx6aWAFq5O","summary":[{"type":"summary_text","text":"**Updating test harness for message parsing**"},{"type":"summary_text","text":"**Extending tests for failure and shutdown cases**"},{"type":"summary_text","text":"**Refining shutdown handling with concurrent teardown**"}]},{"id":"fc_09ab79121c733b56016a589f1831008199ba0586dab97030a3","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading current test runner tail\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1950-2015\"}","call_id":"call_oEhIQD631IwvstrPqUkfT6RK","name":"read"}]},"duration":25160.74450000003,"ttft":8626.374000000302,"contextSnapshot":{"promptTokens":95766,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_oEhIQD631IwvstrPqUkfT6RK|fc_09ab79121c733b56016a589f1831008199ba0586dab97030a3","toolName":"read","startedAt":"2026-07-16T09:06:33.727Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading current test runner tail"},"id":"63316ab8","parentId":"b211425d","timestamp":"2026-07-16T09:06:33.727Z"}
{"type":"message","id":"75e463ff","parentId":"63316ab8","timestamp":"2026-07-16T09:06:33.743Z","message":{"role":"toolResult","toolCallId":"call_oEhIQD631IwvstrPqUkfT6RK|fc_09ab79121c733b56016a589f1831008199ba0586dab97030a3","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#FF87]\n1884:async function testNativeCheckpointTool() {\n…\n1948:\tconst failed = createHarness({\n1949:\t\tonCompact() {\n1950:\t\t\tthrow new Error(\"native compaction cancelled\");\n1951:\t\t},\n1952:\t\tonRun(call) {\n1953:\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n1954:\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n1955:\t\t\t}\n1956:\t\t},\n1957:\t});\n1958:\tawait failed.emit(\"session_start\");\n1959:\tconst failure = await failed.tools\n1960:\t\t.get(\"spt_checkpoint\")\n1961:\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\n1962:\tassert.equal(failure.isError, true);\n1963:\tassert.match(failure.content[0].text, /native compaction cancelled/);\n1964:\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\n1965:\tawait failed.emit(\"session_shutdown\");\n1966:}\n1967:\n1968:await testParsingAndReplies();\n1969:await testRunSptRejectsStdinErrorsAndHungCommands();\n1970:await testLifecycleCustodyAndContext();\n1971:await testDeferredBindLifecycleSerialization();\n1972:await testOutcomeSendRetriesAndExhaustion();\n1973:await testSubmissionFailureAdvancesQueue();\n1974:await testFailedIdleRecoveryFailsClosed();\n1975:await testListenerRestartExhaustion();\n1976:await testListenerStableIntervalResetsRetries();\n1977:await testFatalTeardownAwaitsInFlightOutcome();\n1978:await testSessionEndRetriesAfterTransientFailure();\n1979:await testHumanBusyFailureFailsClosed();\n1980:await testShutdownReapsAndFailsQueuedCustody();\n1981:await testListenerTerminationEscalatesAndReaps();\n1982:await testProtocolCorruptionFailsClosed();\n1983:await testInboundQueueOverflowReturnsAcceptedCustody();\n1984:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n1985:await testShutdownFallbackStaysBelowHostCap();\n1986:await testNativeActivationCommandsAndErrors();\n1987:await testNativeActivationSelectionAndCompletion();\n1988:await testExplicitLiveAutoResume();\n1989:await testStartupBriefHintsAndUpdateNotices();\n1990:await testActiveTurnBoundaryDeliveryAndFallback();\n1991:await testAbnormalTurnsRestoreReceivability();\n1992:await testPeerShortformParsingAndDispatch();\n1993:await testNativeCheckpointTool();\n1994:\n1995:console.log(\"OMP-EXTENSION OK\");\n1996:"}],"details":{"displayContent":{"text":"async function testNativeCheckpointTool() {\n…\n\tconst failed = createHarness({\n\t\tonCompact() {\r\n\t\t\tthrow new Error(\"native compaction cancelled\");\r\n\t\t},\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\r\n\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait failed.emit(\"session_start\");\r\n\tconst failure = await failed.tools\r\n\t\t.get(\"spt_checkpoint\")\r\n\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\r\n\tassert.equal(failure.isError, true);\r\n\tassert.match(failure.content[0].text, /native compaction cancelled/);\r\n\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\r\n\tawait failed.emit(\"session_shutdown\");\r\n}\r\n\r\nawait testParsingAndReplies();\r\nawait testRunSptRejectsStdinErrorsAndHungCommands();\r\nawait testLifecycleCustodyAndContext();\r\nawait testDeferredBindLifecycleSerialization();\r\nawait testOutcomeSendRetriesAndExhaustion();\r\nawait testSubmissionFailureAdvancesQueue();\r\nawait testFailedIdleRecoveryFailsClosed();\r\nawait testListenerRestartExhaustion();\r\nawait testListenerStableIntervalResetsRetries();\r\nawait testFatalTeardownAwaitsInFlightOutcome();\r\nawait testSessionEndRetriesAfterTransientFailure();\r\nawait testHumanBusyFailureFailsClosed();\r\nawait testShutdownReapsAndFailsQueuedCustody();\r\nawait testListenerTerminationEscalatesAndReaps();\r\nawait testProtocolCorruptionFailsClosed();\r\nawait testInboundQueueOverflowReturnsAcceptedCustody();\r\nawait testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\r\nawait testShutdownFallbackStaysBelowHostCap();\r\nawait testNativeActivationCommandsAndErrors();\r\nawait testNativeActivationSelectionAndCompletion();\r\nawait testExplicitLiveAutoResume();\r\nawait testStartupBriefHintsAndUpdateNotices();\r\nawait testActiveTurnBoundaryDeliveryAndFallback();\r\nawait testAbnormalTurnsRestoreReceivability();\r\nawait testPeerShortformParsingAndDispatch();\r\nawait testNativeCheckpointTool();\r\n\r\nconsole.log(\"OMP-EXTENSION OK\");\r\n","startLine":1884,"lineNumbers":[1884,null,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"}}},"isError":false,"timestamp":1784192793743}}
{"type":"message","id":"0bbccea6","parentId":"75e463ff","timestamp":"2026-07-16T09:06:53.250Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Inserting function after selection block**\n\n**Adding case-insensitive assertion for Windows**"},{"type":"toolCall","id":"call_Edjfz8wI9fJx9NUDBIMLic5C|ctc_09ab79121c733b56016a589f240b5881999220794ef518b761","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#FF87]\nINS.POST 1478:\n+\tassertNoAgentManagedPoll(inert);\nSWAP 1552.=1555:\n+\tassertNoAgentManagedPoll(harness);\nINS.POST 1557:\n+async function testPlatformAwareActivationCandidatePaths() {\n+\tconst createLinuxHarness = (cwd, candidateCwd, newId) =>\n+\t\tcreateHarness({\n+\t\t\tid: null,\n+\t\t\tplatform: \"linux\",\n+\t\t\tcwd,\n+\t\t\tinputResults: [newId],\n+\t\t\tonRun(call) {\n+\t\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\n+\t\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\t\tlocal: [{ id: \"wrong-path\", state: \"ready_agent\", alive: false }],\n+\t\t\t\t\t});\n+\t\t\t\t}\n+\t\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\t\tid: \"wrong-path\",\n+\t\t\t\t\t\tadapter: \"omp-spt\",\n+\t\t\t\t\t\tcwd: candidateCwd,\n+\t\t\t\t\t});\n+\t\t\t\t}\n+\t\t\t},\n+\t\t});\n+\n+\tfor (const [cwd, candidateCwd, newId] of [\n+\t\t[\"/Work/Project\", \"/work/project\", \"case-sensitive\"],\n+\t\t[\"/\", \"/different\", \"root-scoped\"],\n+\t]) {\n+\t\tconst harness = createLinuxHarness(cwd, candidateCwd, newId);\n+\t\tawait harness.emit(\"session_start\");\n+\t\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\n+\t\tassert.deepEqual(harness.selections, [], \"an incompatible path must not be selectable\");\n+\t\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], newId);\n+\t\tassertNoAgentManagedPoll(harness);\n+\t\tawait harness.emit(\"session_shutdown\");\n+\t}\n+}\n+\nINS.POST 1608:\n+\tassertNoAgentManagedPoll(harness);\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7296,"output":653,"cacheRead":89600,"cacheWrite":0,"totalTokens":97549,"reasoningTokens":203,"cost":{"input":0.036480000000000005,"output":0.01959,"cacheRead":0.0448,"cacheWrite":0,"total":0.10087000000000002}},"stopReason":"toolUse","timestamp":1784192793758,"responseId":"resp_09ab79121c733b56016a589f1a47ec819982a55fdbb7aac846","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f1e21cc8199a447c8303fed017e","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ8kf6FXr9MLWZ2qHCeLOAceBGFCuP3ia23L53YSoJ3Q-Go1Cwtr8E5obe_aHSjVoQ4ss6w5KKhjb2gZdUQ6_hQsphT_sRew-HmAdoa-r0b9iqi3kcS5pTWzA6KqSlxtXhErLthflr66fm2uqBJAGieq_6otqAp1jCdJEsiq9PXIn-vwiRpurr8SKUn9huw0uWQR6o8HLdqAnXZRoa-FyXDzTSc4jbwYSFRsyQRvcPVThv9u7VfngMXvlmwqscCNfuD2C05aaUseFvOosYOKrJu2t6Q5neRI5eAUOX8rTOPFAXExTBaeA6LJqoVpqCL3E-ZrHLNWtc1kQ7dlVuD0W4hOm4AGXdIXtsSny3mcbDv4mcOGQCApWAgx4M6k59kSkNdwSJdSUoGNFXGk8ncVguG9dzFBGPqTpa88X1uKbgfbp4efWLv0sC-isnhLkmMGC16fz2wi8x7-nhSgCGc9xxGzBT6mYUxUroe38rRCcMg7y7hFwr4Yykl_mXSzAha43d4zrJs1y_xGUilK6vSTUp4aSEFT3zj3N9TABXxHXD9ATKZKIVVOi6DAAYleV8imSa24T39WrSX_69q6mNPjoLtT24Usy9HM6Wiyb3NKSJo9cfCc60aoVkYUzWpg7_sKYisVCkdsFJj6A7uKgPBtnWnS6ASVd2QG9a0_tlqZv8SGRUIe3DYwtB2_fPxiMl7MWOPiG0_R5vz4GMC8URQ9I8ILhqerhzjEGiuLgS0n-XSv2Yczf81qm1pY-MIx-idzCXKt8q2a0aZ3qDJheLme8Z1pnxdDLw63kaeF3CZ4UxsJkX3oP17txI1TU3hpWKFPz4quTX7SNBQghCIosTbHjzFsB0ihm__SDAZgqu2homlWcW8FwXbL9QwRWFIvr9eoJw80zDh9qY_dHNOwb5sn4aLPi60sJG6dFxnIfhuQXAlFmpgszHjZI29GmtUg_gmJfVuuetDTRkv3f4kOmcS6EuBhHMcLggyoGCHDLf6pQDEX0Ih4U0l5EXCcVyaX44XBaqhs80Ya6tK_Nl6lwNfsaStD1AQZNpdLzty0JBeMSoL_MNybaRF6iivcBiukhqO5sfWfdchu1xy7l9pRaRFat_JJMLv5hkh13mVTK-0Ota2JgLjVbTL1iTSGtHjPDWw9fdKAu50nwNSAV15HQJZGiTHNpjI6VPt9fiy0JHrCSMWdHuRec-iYbMZZSudTBSN6WoTmmCWPur2A_N1R-ne1O8EjWr8IuJmj80Uq8nByuYH2N5gNcJvp2FxqkA0rdnKXqb8vkOdzb-rlqro64lXgOGy4jje3c-uf1RoJcXE9xZrwaqwZptJl8ixOY56uuX-cIceeQ9REBCXNgVCDkUbp_khNYQYpRbrTbOb09vkP_yBpr9MehP4BkpW0YB0qQlB980EjEZvxd1OQfRlTPysy0ABrdqc6BhXJCohbTFJA0sM_PIGA6MOraiOpxjoVxgjN3VnWjWyghXJOAspmk8SNlECMhHyN128R402tjgI43d1fdX14gz3fH0zSFrhPZFm7fqT_76_oAZC5tfoxiMcEHhgwj08tU1Ft6_PvxxBO-LC3xM2K7lWyCamwcoJbeRbKgLL7-KoxHsFfsArowN9rZQgkKkT7wAAOcAVHxQ9Z0877eJACJD-Xg_9D5HY1kKh6uxxO0CqWUyDTjB1U14ktJ8dTtOYpwMrQHUhSlL24Rl9P8OUEL9xCVpbljaLm7V1Mdc_fozUsEc-5z6e62Z0cEi2rTbz7oGV5lGzlgI__MG2ed_6Bvho1qlVcqkEzUUFceMiErZiqnwhEX1HORDSqMJWMbLJBUO6KG-S3IBUWI8XqvZNd31wt5SUtx_WRF54ioEa3F8oa5Lb9ubOiUAm9inJuIjnXQiRS_Z5tior1Q1Q6c3p5e4jNo69N4OaPK7B3rL4VPGF4ia6ehvQh_kQxwkLOa3hddUDaphHZixXo8AQwKZkgYmIq_LY-xjVN0vIWExV4E8px7-CJ6z-6kfujMPw7Uwh-H9cUO0iQ-2xr6lHdi1pb9WEgKFIzcxR2hi01n5hK-F-vIzeilnnPGsehlm1t6Pt4e1Qap6jtr4c3lc6eXK0gnG_e_NiqReXr8Cud6Yp3vwqjDdxkuaXLucRCL6FbeIBxPCTDP5DRMYgM06CMovMk2TWVGXXbr5AmcLba-dBRbvQWCkFRStS_hTGKm7xx8A==","summary":[{"type":"summary_text","text":"**Inserting function after selection block**"},{"type":"summary_text","text":"**Adding case-insensitive assertion for Windows**"}]},{"id":"ctc_09ab79121c733b56016a589f240b5881999220794ef518b761","type":"custom_tool_call","status":"completed","call_id":"call_Edjfz8wI9fJx9NUDBIMLic5C","input":"*** Begin Patch\n[tests/omp-extension.mjs#FF87]\nINS.POST 1478:\n+\tassertNoAgentManagedPoll(inert);\nSWAP 1552.=1555:\n+\tassertNoAgentManagedPoll(harness);\nINS.POST 1557:\n+async function testPlatformAwareActivationCandidatePaths() {\n+\tconst createLinuxHarness = (cwd, candidateCwd, newId) =>\n+\t\tcreateHarness({\n+\t\t\tid: null,\n+\t\t\tplatform: \"linux\",\n+\t\t\tcwd,\n+\t\t\tinputResults: [newId],\n+\t\t\tonRun(call) {\n+\t\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\n+\t\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\t\tlocal: [{ id: \"wrong-path\", state: \"ready_agent\", alive: false }],\n+\t\t\t\t\t});\n+\t\t\t\t}\n+\t\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+\t\t\t\t\treturn JSON.stringify({\n+\t\t\t\t\t\tid: \"wrong-path\",\n+\t\t\t\t\t\tadapter: \"omp-spt\",\n+\t\t\t\t\t\tcwd: candidateCwd,\n+\t\t\t\t\t});\n+\t\t\t\t}\n+\t\t\t},\n+\t\t});\n+\n+\tfor (const [cwd, candidateCwd, newId] of [\n+\t\t[\"/Work/Project\", \"/work/project\", \"case-sensitive\"],\n+\t\t[\"/\", \"/different\", \"root-scoped\"],\n+\t]) {\n+\t\tconst harness = createLinuxHarness(cwd, candidateCwd, newId);\n+\t\tawait harness.emit(\"session_start\");\n+\t\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\n+\t\tassert.deepEqual(harness.selections, [], \"an incompatible path must not be selectable\");\n+\t\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], newId);\n+\t\tassertNoAgentManagedPoll(harness);\n+\t\tawait harness.emit(\"session_shutdown\");\n+\t}\n+}\n+\nINS.POST 1608:\n+\tassertNoAgentManagedPoll(harness);\n*** End Patch\n","name":"edit"}]},"duration":19491.981800000183,"ttft":4351.268400000408,"contextSnapshot":{"promptTokens":96896,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Edjfz8wI9fJx9NUDBIMLic5C|ctc_09ab79121c733b56016a589f240b5881999220794ef518b761","toolName":"edit","startedAt":"2026-07-16T09:06:53.251Z"},"id":"1eaefd6b","parentId":"0bbccea6","timestamp":"2026-07-16T09:06:53.251Z"}
{"type":"message","id":"2d2b3caa","parentId":"1eaefd6b","timestamp":"2026-07-16T09:06:53.281Z","message":{"role":"toolResult","toolCallId":"call_Edjfz8wI9fJx9NUDBIMLic5C|ctc_09ab79121c733b56016a589f240b5881999220794ef518b761","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#7169]\n1476:\tassert.ok(\n1477:\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\n1478:\t);\n1479:\tassertNoAgentManagedPoll(inert);\n1480:\tawait inert.emit(\"session_shutdown\");\n1481:\n\n1520:async function testNativeActivationSelectionAndCompletion() {\n\n1550:\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\n1551:\t\t{ value: \"ready-old\", label: \"ready-old\" },\n1552:\t]);\n1553:\tassertNoAgentManagedPoll(harness);\n1554:\tawait harness.emit(\"session_shutdown\");\n1555:}\n1556:async function testPlatformAwareActivationCandidatePaths() {\n1557:\tconst createLinuxHarness = (cwd, candidateCwd, newId) =>\n…\n1576:\t\t\t},\n1577:\t\t});\n1578:\n1579:\tfor (const [cwd, candidateCwd, newId] of [\n1580:\t\t[\"/Work/Project\", \"/work/project\", \"case-sensitive\"],\n…\n1592:\n1593:\n1594:// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n1595:async function testExplicitLiveAutoResume() {\n\n1638:\tassert.ok(\n\n1642:\t\t\"auto-resume must inspect only inactive compatible identities\",\n1643:\t);\n1644:\tassertNoAgentManagedPoll(harness);\n1645:\tawait harness.emit(\"session_shutdown\");\n1646:\n\n1674:}"}],"details":{"diff":" 1476|\tassert.ok(\n 1477|\t\tinert.notifications.some(({ message }) => message.includes(\"immutably bound to ready-one\")),\n 1478|\t);\n+1479|\tassertNoAgentManagedPoll(inert);\n 1479|\tawait inert.emit(\"session_shutdown\");\n 1480|\n\n 1519|async function testNativeActivationSelectionAndCompletion() {\n\n 1549|\tassert.deepEqual(harness.commands.get(\"ready\").getArgumentCompletions(\"ready-\"), [\n 1550|\t\t{ value: \"ready-old\", label: \"ready-old\" },\n 1551|\t]);\n-1552|\tassert.ok(\n-1553|\t\t!harness.calls.some((call) => call.args[3] === \"poll\"),\n-1554|\t\t\"selection and activation must not start an agent-managed background poll\",\n-1555|\t);\n+1553|\tassertNoAgentManagedPoll(harness);\n 1556|\tawait harness.emit(\"session_shutdown\");\n 1557|}\n+1556|async function testPlatformAwareActivationCandidatePaths() {\n+1557|\tconst createLinuxHarness = (cwd, candidateCwd, newId) =>\n+1558|\t\tcreateHarness({\n+1559|\t\t\tid: null,\n+1560|\t\t\tplatform: \"linux\",\n+1561|\t\t\tcwd,\n+1562|\t\t\tinputResults: [newId],\n+1563|\t\t\tonRun(call) {\n+1564|\t\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"endpoint\") {\n+1565|\t\t\t\t\treturn JSON.stringify({\n+1566|\t\t\t\t\t\tlocal: [{ id: \"wrong-path\", state: \"ready_agent\", alive: false }],\n+1567|\t\t\t\t\t});\n+1568|\t\t\t\t}\n+1569|\t\t\t\tif (call.args[0] === \"--json\" && call.args[1] === \"api\") {\n+1570|\t\t\t\t\treturn JSON.stringify({\n+1571|\t\t\t\t\t\tid: \"wrong-path\",\n+1572|\t\t\t\t\t\tadapter: \"omp-spt\",\n+1573|\t\t\t\t\t\tcwd: candidateCwd,\n+1574|\t\t\t\t\t});\n+1575|\t\t\t\t}\n+1576|\t\t\t},\n+1577|\t\t});\n 1558|\n+1579|\tfor (const [cwd, candidateCwd, newId] of [\n+1580|\t\t[\"/Work/Project\", \"/work/project\", \"case-sensitive\"],\n+1581|\t\t[\"/\", \"/different\", \"root-scoped\"],\n+1582|\t]) {\n+1583|\t\tconst harness = createLinuxHarness(cwd, candidateCwd, newId);\n+1584|\t\tawait harness.emit(\"session_start\");\n+1585|\t\tawait harness.commands.get(\"ready\").handler(\"\", harness.ctx);\n+1586|\t\tassert.deepEqual(harness.selections, [], \"an incompatible path must not be selectable\");\n+1587|\t\tassert.equal(harness.calls.find((call) => call.args[3] === \"bind\").args[4], newId);\n+1588|\t\tassertNoAgentManagedPoll(harness);\n+1589|\t\tawait harness.emit(\"session_shutdown\");\n+1590|\t}\n+1591|}\n+1592|\n+1593|\n 1559|// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n 1560|async function testExplicitLiveAutoResume() {\n\n 1603|\tassert.ok(\n\n 1607|\t\t\"auto-resume must inspect only inactive compatible identities\",\n 1608|\t);\n+1644|\tassertNoAgentManagedPoll(harness);\n 1609|\tawait harness.emit(\"session_shutdown\");\n 1610|\n\n 1638|}","firstChangedLine":1478,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192813280}}
{"type":"message","id":"042842ce","parentId":"2d2b3caa","timestamp":"2026-07-16T09:07:06.296Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding command parse error handling**"},{"type":"toolCall","id":"call_9bvXyNGLNGTMRmLtsO4y9bWH|ctc_09ab79121c733b56016a589f36e6cc8199a542b3c75cd3009f","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#7169]\nINS.PRE 1447:\n+\tawait inert.commands.get(\"ready\").handler(\"--auto\", inert.ctx);\n+\tawait inert.commands.get(\"live\").handler(\"two identities\", inert.ctx);\n+\tassert.deepEqual(inert.calls, [], \"invalid activation syntax must not bind or guess\");\n+\tassert.ok(\n+\t\tinert.notifications.some(({ message }) => message.includes(\"supported only by `/live`\")),\n+\t);\n+\tassert.ok(inert.notifications.some(({ message }) => message.includes(\"Usage: /live\")));\n+\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7265,"output":243,"cacheRead":90624,"cacheWrite":0,"totalTokens":98132,"reasoningTokens":108,"cost":{"input":0.036325,"output":0.0072900000000000005,"cacheRead":0.045312,"cacheWrite":0,"total":0.088927}},"stopReason":"toolUse","timestamp":1784192813294,"responseId":"resp_09ab79121c733b56016a589f2d9adc81998213f9712b00ce4c","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f3484708199b18fd877f5b1071b","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ82XRvK1JLF70vQo0Y7EGk_kCNFV-UI7GmW50MRDv6TiMUspQOJjDPM9ejKClyIxORwK81jXiIZEVHdbNA14HE6CINAMO_fTh_WmyI20EQhrKHLlKUysxZPfmvqDaSZag7EWWDDCqeE7DbN43OEc_O2Vdg6KTO4ahVHGrlW6BVwL2CVm4arVXq0cSN8FwbJzamTMQV9hzu0jlaVN4nfyobXHf_qolBGBQ6lCr7a_4Z2miFm0Cb3wE9R8-fjKGFKHCvB2dCgJujiuRcLInO1DMs3IkSBz8WXwpzhIfyX0YnYVISJi1jqSdSHk52iNLS3rw_X_Gvsjjn0UE82oVPVUVvcOoWqLTl-Pb4UQpNdTLfiuCN0_K425maSI4kzZOMHNVaOrY_AzpEZSOlgzFYKheYo6HdL6UoQ5r2ivYOfIxn22hBA87MHfC-plAxtQUbd-5BlS_216he943iDjoO4AyxWuJ3yKZLaVcuYxgL40TAqLM96AYxJX5TQGC8vVMJT-tuYZp_oBfDULl4E8-kJTa-lwZ6HxFzuOK5K-taPJauTOoR1KwkJG12DZDcSC8Y3FX-irmpnSVmVNrtrzTUO_i1ZLGXROi3K-Zp9ZgY6zbqUAg46z1ux-va5z60yqvmIJJ7ZWFEq9cmWoZhDvKOhJ4HbPpBaEbUHUIyfIKQOW-nsOvUvbwnK4GB7E7l5g8kAT6a-EWNKxXqoKPhVAJ0M_EydTk6NW80h9w5eUIpZOakWBrG1gNjtLzZaaOKf7f6mrrRpDRQUWpAuMc-tHohOT2iL4mufeapybmrUJJCouq5az7IOzZzlPoTFLQrMC8vXEmQWDXYzz4o_FOxr0w5GIGOmfYQIhHilbIpIDhwC1aWHDLmFXBGi341B0rjBP6sMcScqbZeDo4aXMc6CRIoCDLQXx0w3zYoAtu84IkyLVLnzP_rtFBxza92O9bvZKXUop0JLZdhEtiggXs9PZ3eqMvgpJtsOGVkJUzth4KqRZaSMIyFabZf-emOcvmSZRO3TovVSbRPQH5Q8s2sdJ-V5WrgKPBoKNK0Rzmc7HvJA5Hr81ZoelHv1JagQhCyDHouqfh1UJo6l5ylOmMvoiirB6Y1NIQkEkDXgrLBGzj4SbRL4hmAPlgjJF5DMRmJhl8l9et1sVhyOO_i8iWKepnpoBE-ihAuQXCl_OwSUnqddC9dn1U3vova4Tt5ktmf9EVgyyMQ0tMU1BhtNWtIwwvUbJ-_oVtwFXgpK0h2NfQ15oEjqprzkaVAPwr3AV7yNXj-RDEAT1O55eRzZnoXBB9EV6doSW3EBjChSHkrvHiJeGUx6J9IB_1gag6mjD9JI4bW0qrgUm2zQ9cxKAxa0Dc-Ke-MPEp2ZBiJG3wSbJ06SnGmBb1_HVpjiBJy1_maqGdUNGw_g1I5cDIAh_a9SlrZXLJ04FDzc-ml9AKsHgFH57a3-R1FIzTipTsYpbJHVcDuvfhNcu6IivkO1cjapv4-HWXFJokLDEYP22CkHcjiV-q8ox1lnisiG3-VhCD2VBxaVZEP_Ke0fSUHOpBo0CKwI_8GR2gv1u1N1imThWu5TouLM21U=","summary":[{"type":"summary_text","text":"**Adding command parse error handling**"}]},{"id":"ctc_09ab79121c733b56016a589f36e6cc8199a542b3c75cd3009f","type":"custom_tool_call","status":"completed","call_id":"call_9bvXyNGLNGTMRmLtsO4y9bWH","input":"*** Begin Patch\n[tests/omp-extension.mjs#7169]\nINS.PRE 1447:\n+\tawait inert.commands.get(\"ready\").handler(\"--auto\", inert.ctx);\n+\tawait inert.commands.get(\"live\").handler(\"two identities\", inert.ctx);\n+\tassert.deepEqual(inert.calls, [], \"invalid activation syntax must not bind or guess\");\n+\tassert.ok(\n+\t\tinert.notifications.some(({ message }) => message.includes(\"supported only by `/live`\")),\n+\t);\n+\tassert.ok(inert.notifications.some(({ message }) => message.includes(\"Usage: /live\")));\n+\n*** End Patch\n","name":"edit"}]},"duration":13002.177099999972,"ttft":7198.5597000001,"contextSnapshot":{"promptTokens":97889,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_9bvXyNGLNGTMRmLtsO4y9bWH|ctc_09ab79121c733b56016a589f36e6cc8199a542b3c75cd3009f","toolName":"edit","startedAt":"2026-07-16T09:07:06.297Z"},"id":"a041dbb3","parentId":"042842ce","timestamp":"2026-07-16T09:07:06.297Z"}
{"type":"message","id":"a9b58786","parentId":"a041dbb3","timestamp":"2026-07-16T09:07:06.331Z","message":{"role":"toolResult","toolCallId":"call_9bvXyNGLNGTMRmLtsO4y9bWH|ctc_09ab79121c733b56016a589f36e6cc8199a542b3c75cd3009f","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#4F06]\n1441:\tassert.equal(\n\n1445:\t);\n1446:\n1447:\tawait inert.commands.get(\"ready\").handler(\"--auto\", inert.ctx);\n1448:\tawait inert.commands.get(\"live\").handler(\"two identities\", inert.ctx);\n…\n1453:\tassert.ok(inert.notifications.some(({ message }) => message.includes(\"Usage: /live\")));\n1454:\n1455:\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\n1456:\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");"}],"details":{"diff":" 1441|\tassert.equal(\n\n 1445|\t);\n 1446|\n+1447|\tawait inert.commands.get(\"ready\").handler(\"--auto\", inert.ctx);\n+1448|\tawait inert.commands.get(\"live\").handler(\"two identities\", inert.ctx);\n+1449|\tassert.deepEqual(inert.calls, [], \"invalid activation syntax must not bind or guess\");\n+1450|\tassert.ok(\n+1451|\t\tinert.notifications.some(({ message }) => message.includes(\"supported only by `/live`\")),\n+1452|\t);\n+1453|\tassert.ok(inert.notifications.some(({ message }) => message.includes(\"Usage: /live\")));\n+1454|\n 1447|\tawait inert.commands.get(\"ready\").handler(\"ready-one\", inert.ctx);\n 1448|\tconst readyBind = inert.calls.find((call) => call.args[3] === \"bind\");","firstChangedLine":1447,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192826331}}
{"type":"message","id":"e0729d1d","parentId":"a9b58786","timestamp":"2026-07-16T09:07:16.173Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Adding assertion options and adjusting candidate handling**"},{"type":"toolCall","id":"call_oSrfRVR0cm942rq7l54CwS2R|fc_09ab79121c733b56016a589f41733c8199b6a3a12629d82dad","name":"read","arguments":{"i":"Regrounding shortform test","path":"tests/omp-extension.mjs","selector":"1860-1945"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6621,"output":105,"cacheRead":91648,"cacheWrite":0,"totalTokens":98374,"reasoningTokens":64,"cost":{"input":0.033105,"output":0.00315,"cacheRead":0.045824,"cacheWrite":0,"total":0.082079}},"stopReason":"toolUse","timestamp":1784192826348,"responseId":"resp_09ab79121c733b56016a589f3ad17481999bdedd7434accdfa","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f3ed58c8199a2293a62ca97f67a","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ9BBSXNnfueh70TBKJ2Lq_o9JUiqRZWXFOMHN4HUPICz_YOP9VQRg72qaF2oMhSDTfWmSk4_d8tEic8HXhTWW-XikP9AQtidzbzVFhR4oiATFzqCzFVmRTfQh4MY9wlbv8Jbo6O9cCr5CUaZBh7bN8MroSVtTL5VSvHO_jEOHq6KJPBQrxNBvqDK0RZ-IjNce50N70HmXN7TmbSiuNO3sLbL9IV-iuxta9EAfYlDkB7nEbVKfFYOXXsBgtpps3auSqOOgC0b4A4B6wVcGvZjgbJYQHvR_aMDYHKHm7eIYTKcCpJxevCoAt3_PgfmbX-868g2BOxLNwN6iXECS6xdqECKjsEBbzzAJwIFQaeSQjgZxJvBSavCrWc0v-ca8FbdQpicHJMFWfvhOyXRqrUE_-CyWaY-U7sDstVfVEHi-xjmSTr7un2tx9ObYyqB5s_4KwxXhPVHP_ITR0OtJKS9TDSVqJ92hzpWNVq2VRUc1Q1Hhbw6CyiJc9u67XbZ5kUIP6ziquEORgJU1UYr7Z66WduGuL0L0dHhqXd-7IZX-OtEVgpM2CrIHitL6_mEOvEggLmvwZJsGfGj_-6FtHTSKmu7Nz9tbrwaPIcuikVcaF1-JPbB1TmS0oPIqqW6Bsd_Ju1rII9chD_lR-awEE3zsQzffS-v_KPTbkukST9axqqCkilRiw2wyW1XAla6HZKQHqk_b-ANfg313RMLyzogoiQSoYMmfTXqcsn0jL6-RK7HL0sRM7khSxnMG5M0YxhvVdAyVKz4SCMd81OCX6j8NYldXCWcvvzgdrD6ihCm1bBTggspZZT4SJm06TjDltZ4cxK01ccCbxXmgT0Gai6tpYXeHdEWQpy9Yl4UdeK6BXF9Kboli8Eyn-bQnBLahbimu_sXCc2Zc5GbkLFf93BzCU-DHCBXudXSwkYgyehW85KtsqGlZ-PVOzjrXLy3vIf3KM3wot7YEHHtKxpLhuBF--CH7vOGryHLkK8yIIRGRoeCDhSnuql9faqMYusgTVkLi16QjH70pcdwdRCRzN5rFUtoqprDjcW8X8W8JIkV_NF21egyCdE9rKbg1vXfWm3DVacFEAwooY2vpFpX1D-va_0xz5R5MJywSf4HJ6mntjq2cwJwumgIQIoPM22N_hupELlvQlIVXVkS-dt9JV0kwEHWPmJijEvjkPq8QsRzAy-9r8aSocImG_fYukR5s8oYIG0fjKuIdTZlii65EuLOjEM04XL51GG0YwAnVcpBVbJaQrXL3C8nGvDq-bpH_IQ9EfOqzDUD60W5lO4C6yQ6OV5Uv1_NYe5xtR6rsMb136zF1gn4Z8z_Bvsu_CxRVjTl4R2LuE1Q7HI82cwyGyIVQW3rf4l_URjDA_jn2lyHrpE1t8sFk_N1P2oCjNtOk4vsGje","summary":[{"type":"summary_text","text":"**Adding assertion options and adjusting candidate handling**"}]},{"id":"fc_09ab79121c733b56016a589f41733c8199b6a3a12629d82dad","type":"function_call","status":"completed","arguments":"{\"i\":\"Regrounding shortform test\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"1860-1945\"}","call_id":"call_oSrfRVR0cm942rq7l54CwS2R","name":"read"}]},"duration":9822.951899999753,"ttft":4460.582899999805,"contextSnapshot":{"promptTokens":98269,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_oSrfRVR0cm942rq7l54CwS2R|fc_09ab79121c733b56016a589f41733c8199b6a3a12629d82dad","toolName":"read","startedAt":"2026-07-16T09:07:16.174Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Regrounding shortform test"},"id":"a2491e1b","parentId":"e0729d1d","timestamp":"2026-07-16T09:07:16.174Z"}
{"type":"message","id":"dafbae68","parentId":"a2491e1b","timestamp":"2026-07-16T09:07:16.195Z","message":{"role":"toolResult","toolCallId":"call_oSrfRVR0cm942rq7l54CwS2R|fc_09ab79121c733b56016a589f41733c8199b6a3a12629d82dad","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#4F06]\n1859:// [unit->REQ-PARITY-PEER-SHORTFORM]\n1860:async function testPeerShortformParsingAndDispatch() {\n1861:\tassert.deepEqual(\n1862:\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\n1863:\t\t\t({ targets, body }) => ({ targets, body }),\n1864:\t\t),\n1865:\t\t[\n1866:\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\n1867:\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\n1868:\t\t],\n1869:\t);\n1870:\tassert.deepEqual(\n1871:\t\tparsePeerShortforms(\n1872:\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\n1873:\t\t),\n1874:\t\t[],\n1875:\t);\n1876:\n1877:\tconst harness = createHarness({\n1878:\t\tonRun(call) {\n1879:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\n1880:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\n1881:\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\n1882:\t\t\t}\n1883:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\n1884:\t\t},\n1885:\t});\n1886:\tawait harness.emit(\"session_start\");\n1887:\tawait harness.emit(\"agent_start\");\n1888:\tawait harness.emit(\"agent_end\", {\n1889:\t\tmessages: [\n1890:\t\t\t{\n1891:\t\t\t\trole: \"assistant\",\n1892:\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n1893:\t\t\t},\n1894:\t\t],\n1895:\t});\n1896:\tassert.deepEqual(\n1897:\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\n1898:\t\t[\n1899:\t\t\t[\"alpha\", \"ship the patch\"],\n1900:\t\t\t[\"beta\", \"ship the patch\"],\n1901:\t\t\t[\"gamma\", \"inspect release\"],\n1902:\t\t],\n1903:\t);\n1904:\tassert.equal(harness.sentMessages.length, 1);\n1905:\tassert.deepEqual(harness.sentMessages[0].delivery, {\n1906:\t\tdeliverAs: \"nextTurn\",\n1907:\t\ttriggerTurn: true,\n1908:\t});\n1909:\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\n1910:\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\n1911:\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\n1912:\n1913:\tawait harness.emit(\"agent_start\");\n1914:\tawait harness.emit(\"agent_end\", {\n1915:\t\tmessages: [\n1916:\t\t\t{\n1917:\t\t\t\trole: \"assistant\",\n1918:\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n1919:\t\t\t},\n1920:\t\t],\n1921:\t});\n1922:\tassert.equal(commandCalls(harness, \"send\").length, 3);\n1923:\tassert.equal(harness.sentMessages.length, 1);\n1924:\tawait harness.emit(\"session_shutdown\");\n1925:}\n1926:\n1927:// [unit->REQ-PARITY-CHECKPOINT]\n1928:async function testNativeCheckpointTool() {\n1929:\tconst compactGate = deferred();\n1930:\tconst harness = createHarness({\n1931:\t\tonCompact() {\n1932:\t\t\treturn compactGate.promise;\n1933:\t\t},\n1934:\t\tonRun(call) {\n1935:\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\n1936:\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\n1937:\t\t\t}\n1938:\t\t},\n1939:\t});\n1940:\tawait harness.emit(\"session_start\");\n1941:\tconst tool = harness.tools.get(\"spt_checkpoint\");\n1942:\tconst checkpoint = tool.execute(\n1943:\t\t\"tool-1\",\n1944:\t\t{ wake: \"Continue release preparation.\" },\n1945:\t\tundefined,\n1946:\t\tundefined,\n1947:\t\tharness.ctx,\n1948:\t);\n…\n2010:}\n\n[Showing lines 1859-1948 of 2040. Use :1949 to continue]"}],"details":{"truncation":{"content":"// [unit->REQ-PARITY-PEER-SHORTFORM]\r\nasync function testPeerShortformParsingAndDispatch() {\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\r\n\t\t\t({ targets, body }) => ({ targets, body }),\r\n\t\t),\r\n\t\t[\r\n\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\r\n\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\r\n\t\t],\r\n\t);\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\r\n\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\r\n\t\t),\r\n\t\t[],\r\n\t);\r\n\r\n\tconst harness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\r\n\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.deepEqual(\r\n\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\r\n\t\t[\r\n\t\t\t[\"alpha\", \"ship the patch\"],\r\n\t\t\t[\"beta\", \"ship the patch\"],\r\n\t\t\t[\"gamma\", \"inspect release\"],\r\n\t\t],\r\n\t);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tassert.deepEqual(harness.sentMessages[0].delivery, {\r\n\t\tdeliverAs: \"nextTurn\",\r\n\t\ttriggerTurn: true,\r\n\t});\r\n\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\r\n\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\r\n\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\r\n\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\").length, 3);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-CHECKPOINT]\r\nasync function testNativeCheckpointTool() {\r\n\tconst compactGate = deferred();\r\n\tconst harness = createHarness({\r\n\t\tonCompact() {\r\n\t\t\treturn compactGate.promise;\r\n\t\t},\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\r\n\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tconst tool = harness.tools.get(\"spt_checkpoint\");\r\n\tconst checkpoint = tool.execute(\r\n\t\t\"tool-1\",\r\n\t\t{ wake: \"Continue release preparation.\" },\r\n\t\tundefined,\r\n\t\tundefined,\r\n\t\tharness.ctx,\r\n\t);\r","truncated":true,"truncatedBy":"lines","totalLines":182,"totalBytes":2732,"outputLines":90,"outputBytes":2732,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"// [unit->REQ-PARITY-PEER-SHORTFORM]\r\nasync function testPeerShortformParsingAndDispatch() {\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map(\r\n\t\t\t({ targets, body }) => ({ targets, body }),\r\n\t\t),\r\n\t\t[\r\n\t\t\t{ targets: [\"alpha\", \"beta\"], body: \"hello there\" },\r\n\t\t\t{ targets: [\"gamma\"], body: \"second\\nline\" },\r\n\t\t],\r\n\t);\r\n\tassert.deepEqual(\r\n\t\tparsePeerShortforms(\r\n\t\t\t\"ordinary @alice; `@<quoted nope @>`\\n```\\n@<fenced nope @>\\n```\\n@<bad, target nope @>\",\r\n\t\t),\r\n\t\t[],\r\n\t);\r\n\r\n\tconst harness = createHarness({\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\r\n\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\r\n\t\t\t}\r\n\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"gamma\") return \"QUEUED:gamma\";\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.deepEqual(\r\n\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\r\n\t\t[\r\n\t\t\t[\"alpha\", \"ship the patch\"],\r\n\t\t\t[\"beta\", \"ship the patch\"],\r\n\t\t\t[\"gamma\", \"inspect release\"],\r\n\t\t],\r\n\t);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tassert.deepEqual(harness.sentMessages[0].delivery, {\r\n\t\tdeliverAs: \"nextTurn\",\r\n\t\ttriggerTurn: true,\r\n\t});\r\n\tassert.match(harness.sentMessages[0].message.content, /alpha: SENT:alpha/);\r\n\tassert.match(harness.sentMessages[0].message.content, /beta: failed \\(NO_PERCH:beta\\)/);\r\n\tassert.match(harness.sentMessages[0].message.content, /gamma: QUEUED:gamma/);\r\n\r\n\tawait harness.emit(\"agent_start\");\r\n\tawait harness.emit(\"agent_end\", {\r\n\t\tmessages: [\r\n\t\t\t{\r\n\t\t\t\trole: \"assistant\",\r\n\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\r\n\t\t\t},\r\n\t\t],\r\n\t});\r\n\tassert.equal(commandCalls(harness, \"send\").length, 3);\r\n\tassert.equal(harness.sentMessages.length, 1);\r\n\tawait harness.emit(\"session_shutdown\");\r\n}\r\n\r\n// [unit->REQ-PARITY-CHECKPOINT]\r\nasync function testNativeCheckpointTool() {\r\n\tconst compactGate = deferred();\r\n\tconst harness = createHarness({\r\n\t\tonCompact() {\r\n\t\t\treturn compactGate.promise;\r\n\t\t},\r\n\t\tonRun(call) {\r\n\t\t\tif (call.args[0] === \"--json\" && call.args[2] === \"endpoint-info\") {\r\n\t\t\t\treturn JSON.stringify({ endpoint_type: \"live_agent\" });\r\n\t\t\t}\r\n\t\t},\r\n\t});\r\n\tawait harness.emit(\"session_start\");\r\n\tconst tool = harness.tools.get(\"spt_checkpoint\");\r\n\tconst checkpoint = tool.execute(\r\n\t\t\"tool-1\",\r\n\t\t{ wake: \"Continue release preparation.\" },\r\n\t\tundefined,\r\n\t\tundefined,\r\n\t\tharness.ctx,\r\n\t);\r\n…\n}","startLine":1859,"lineNumbers":[1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,null,2010]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":2040,"totalBytes":2732,"outputLines":90,"outputBytes":2732,"shownRange":{"start":1859,"end":1948},"nextOffset":1949}}},"isError":false,"timestamp":1784192836195}}
{"type":"message","id":"fd514a96","parentId":"dafbae68","timestamp":"2026-07-16T09:07:43.307Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Updating second event transcript structure**\n\n**Testing shutdown and concurrency behavior**\n\n**Verifying promise.all invokes all commands**"},{"type":"toolCall","id":"call_fhLYEjTkTEHfrcKnpe8AefKL|ctc_09ab79121c733b56016a589f5734d48199b1501fe3c3f5a3e9","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#4F06]\nINS.PRE 1877:\n+\tconst alphaGate = deferred();\nSWAP 1879.=1879:\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return alphaGate.promise;\nSWAP 1888.=1888:\n+\tconst completion = harness.emit(\"agent_end\", {\nINS.POST 1895:\n+\tawait flush();\n+\tassert.equal(\n+\t\tcommandCalls(harness, \"send\").length,\n+\t\t3,\n+\t\t\"multi-target peer dispatch must not serialize independent recipients\",\n+\t);\n+\talphaGate.resolve(\"SENT:alpha\");\n+\tawait completion;\nINS.POST 1903:\n+\tassert.ok(\n+\t\tcommandCalls(harness, \"send\").every((call) => call.options.timeoutMs === 5_000),\n+\t\t\"peer sends must be bounded independently of the ordinary command timeout\",\n+\t);\nSWAP 1915.=1920:\n+\t\tmessages: [\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n+\t\t\t},\n+\t\t\t{ role: \"user\", content: \"@<alpha user prose must not dispatch @>\" },\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n+\t\t\t},\n+\t\t],\nINS.PRE 1925:\n+\n+\tconst pending = deferred();\n+\tconst interrupted = createHarness({\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"send\") return pending.promise;\n+\t\t},\n+\t});\n+\tawait interrupted.emit(\"session_start\");\n+\tawait interrupted.emit(\"agent_start\");\n+\tconst interruptedCompletion = interrupted.emit(\"agent_end\", {\n+\t\tmessages: [{ role: \"assistant\", content: \"@<slow-target wait for release @>\" }],\n+\t});\n+\tawait flush();\n+\tassert.equal(commandCalls(interrupted, \"send\").length, 1);\n+\tconst shutdown = interrupted.emit(\"session_shutdown\");\n+\tawait flush();\n+\tpending.resolve(\"SENT:slow-target\");\n+\tawait Promise.all([interruptedCompletion, shutdown]);\n+\tassert.deepEqual(\n+\t\tinterrupted.sentMessages,\n+\t\t[],\n+\t\t\"shutdown during peer dispatch must not queue a false continuation\",\n+\t);\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7809,"output":963,"cacheRead":91648,"cacheWrite":0,"totalTokens":100420,"reasoningTokens":430,"cost":{"input":0.039045,"output":0.02889,"cacheRead":0.045824,"cacheWrite":0,"total":0.113759}},"stopReason":"toolUse","timestamp":1784192836201,"responseId":"resp_09ab79121c733b56016a589f44a2a88199be6cbe9b216b8f67","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f49c8388199a98316120014c259","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ9X0bK4dgrE5t5dNiMAiv8m4r_qePKdTCE-lD3iSAWlWJIiNkJHLiho_xYi68Atj7jtBX1ZC-XwdRxPvfGaxUsRkxl7NZASKDLDZ04NdJsbBrMrFXA9o2ndqa4-1ZRnk0oEFpo9wNv5zLmAWxXtcSPL0uuR3JVj1jR8cd8DtnWdQH5W401k47a7pAp4zR7oFPQUOeGQRqPenWE9ixJc8cj-6C_sRvd5az9VIfRT5kcISLcDq3cYFEx1iPgFhFCheI0kD7qxiya5kJk1LdDGwEn1WLKX7Luf82g0aLYgodgRSTcSpILpDpYnrQkTmak8XvEq6WwjlUyYLvKu-Wr7Cfaz9H0XP2cnxK3ISPWaK-66HpmIMKGTv0sUqjY7mrQmOjhunO0QpzKzdJ1ZAc-yBoQ-b0HSw_NcK6jf2emvRxdoKlCyLNJ47aR034GO5rr3Qj4M9ahfG_CCbmHkInR-pFYEU0yhmA_nys09YIdxyNBAtVuy7W-qWPp0fdEdwlJXb6Sfl0eDOtdCAemFGodLFR_Raf2_Pb83pJtOSHKljCXO_dThxFOlFhw-TVWGaMkyEGxZ3ipRRFIVZ9QVaY8RAK4XY3Lk0Gt7Rv1IDhS5VoKEs0TtOBnq2SKNXnTGIee6D5ZXtC9KAMb9QCdkzYB9qR4z5B8nnZ3THUWs62BHByxdbRQO_4j9L4dON56wJ8-cWxqyhNjr93ovRBjsGc9R6EX2dWFqrgltCFpqUYigP0IzDyXdt5hoU9ZMyJV6RYRg1C0tJqr9dqi2L_A0oJCMBzyBvKyZ3z7CAFHpKmiEjVPmUKcfrJMw4WeSEz8RFWbXk2RNaKQ4E3rVP7rtOJE-ubSI71GSn-UdiyRjHQBiXkca6b4zp05crcUKxj633Oeanr3hsXVK4SiU2Num5Vcjd0OcUyKMGZBlihYBgWY-Q1pKAoxM3xsvMFtUnElbOn6mPSpQy3klJBVUE1vlMv9xUGLUO5EpfBeZqZz53n3KtBvrjSPne6SweJW8CfgZ9VSQNWuSelW_KLQ99zH8Ya71CrtnWPGLG27ZHzVPsOSk-8194I50i3Hy82qvilnXRhQVPqXCIp5V_0howB6yVmQlK20_b1p0bcojj6e4b5ELkhk_pD6RZa7kq8kwJwzjv2NrakMrL7f2CqjFXTPRbpas-q3LIDQbBzQNYG0EHVftCGpimwqsVPqu3M7z6_KMW88gLt2nRM0JTALy7ECd6iORpbVK_jF8BP8U-9f4q5V5vw0ZAnBbOyq7wBU4nXuJ1tgnJY0i3BQhIJvavShCG2Jd_n3lRhszeT2A0hj5G1SvMzsvRZ78U6n5GoxJlZOJ7qjYkZhlrrZuMHq5A2coIe3GXg7vJn8dq_Z7qpQgrnFfMfBBiuckdoNvQdXcEO7Na-td473QsDgYPn2kDVFwKRpGaQzU7pLKDuGv5XnRzBr0eR08zPD3f5C2wmainAsWFx3STao2Cf4M3nNRnFTEpa6zbbQ2svMoQCpkhKf8OdHMSuLVNuh3PEH6OLldQNfwjsIZTFnaUth0tcUctPd0P50pudVF1n0pzpbsYk5bs9UkrTc8NpfYV4teXzxunW_yKVcbOYrrBaps2nnu5d8yyKauwxhfi_9Ls3srACWD5oetaZ7KRFJZLf0f9ueMqz6BWKnp4WJcrwdFph4FPpz0Y8WG9ESqd7sUnyr4T4OGClq_zX3aaQopdwwaMfkSZk-2wfiQkXg1vEpucgxcLw65rcyXK2ZEFpN4fBGdDzCcfuER9kh3OCJ_ZtQzRxxQdOzwnKkMJcrKn1ig0KhSbThbMLaU-PK4fx8zM11vrXyaUBSs1_ESxyArY8GsV5A1cedCIUl8KW1nnLvyveRoln2W3rYphLdb5WlgG0fJ51cBPb_qEejiX0L5ctG0i0tQcXnlSj-pQ-o94utFUraS3qG88nbjbHXYXXq0xyREhmitZxwIF72rkQF_WngROuZ1ZVj0kHhPTIJyIW010i9wM46y_gm5NA0glmzh4hphNyOOeIPqs0plz3bTqNh3m2SSfk9MT5ZBINbAYyme-zgw6_5dU-X5JxpyoJXRq4Tr7r5xNtdOodGwpfUDdM3HNoAQshRER9IOzMYxpDto8ITY4Yldqrc-X-Hi1Qb-cvg2VLi2HmoUBf_bN6EBp37xiUaPEAYw2BWn-jkMR8A-Y0eNI9XzO3CpO2_C9MQtQfWBit-CyvJvk5rG55QPsM08ALSMXq100Go9L9nF_627Kv34DbIQnRqj2poTPRGW5hmHbPxTHSFOltNbNzoxjDN0sTHEE2UTKUPN9BK5AjmUpiX3Y2j3PT0H9dVk9ALmvflBIBqY6-ExucgYO-YeLqB-t6-j3qJcMN50pkO81Pbhk6eNmSxIIcRnIjKXD0_IS-tGGnf8_FfWzi-Z8rUcb7eu81d9KrtQl3FpBG5mNk9KTgN66BrX8j2New7_kYds5Gu4LAwmAnf9QPcl0N-P_UKC6-ud9Dcc9uyr8qV7Vh9UsyhOFYsJIa_lkgiTHLsEL5EMJ4sGRkiCJ9i5NCU29c2HO15gg0pLrgKZ4KR8hYiX6D3ZO0GhX8E37F9eiFOpPMRUBzqVJS8RgaKwsXoGhR1Xn-Pst66Sey3rsF8XsvEfThwXWTUHRVUv4ENUWQiYnkKQSD6V3kvDihz5OH8xsVpwD7JEx3_DGVY1Ey6azh4Fxf-joK4h6D8LqiRsRDXM_dBM8oFd0gQPf6aLgoe6MX2wHITHpHTyZui3eNCd8AMretEBL6Hkuys1gpVTenI8Xco9iGJy0fM9SvVUle3QGP-TKSrqZv8q_qwegWGST4gFRZGwIHYJURgl9qPfzVEXT9hyUCEoZu9H_tJ2PXijAFL9HbNqWv52xvNCpx51PkpfIS01kiwV3IgmL9rXT8TSlrLmE-u4BkfT7W2S4IU6d5uaEr1FSEBZurDJAaehYyXIFP-IL6enKNnUXio4uk8a7ZDPSI1YSQC3sk7SAInfglP1r-eYiBt3xVLNKKYgCOC80CpCNMsW96vSd8pYh7zMmooBfcFbF9PYaijTAvcLdUL4-HkluQQKZzazrqGq1sapgEpUW8gUN_1erzGS6JFR2kgmAYer726vmE_FDGy87OKIz0wibJ_XYks-II-ir0iH2XfPdYGSgc6V5txGGcPJ9Au_ucUpf4ESt6XvaZeXVHMxQ96-JpRHZAF5bfOcJxumls20WoCPdz7Si832zaw_X3YWUkiZAJdwRMwbnrt2LqmA7W4Q4B3NQmfWWIq8BNJ88d9bP85zFT4V8HO-k1wKaCykrsLS2ge6oYMupVL6ey0FrQGVjtRyAlXETWOk1NPiW7SQKTxDpGt_L9a3nVieBBd_uhcmjo3rRwi3bYtx8TKpUwqCIcqjYGoRU-w72IFW3rA0bvlqfVOlhf8RgMhENzId7-5H-CkPqDxdAG3SsRP_i-ShrnRpmY9BTwA1V9bo0XBLl4dRD3SOBsM_L0du5w1x78iJyTRFF0h55xpKG8RhQOaOZv4ZZLY9yKdTT3Bvq9s9prWtB83GGbIjpofTfTOpGepQReeHjsK3kiyjmnFEc2Pmw9bGiD8IrTD0x0FeGk1Vjpl3wCcWAFfdAi5sCEsvNw9LwmDk6wBww38SnHVOWEYtv25RC17g6_le07oAcY8SyTdvlYYz9O_KoXhetzB6WbNE2ZmdprgkyNV1-YMin6FmwE8V3hxsZ-JffjlgQQK1P3BbhoEgIu7v4Q==","summary":[{"type":"summary_text","text":"**Updating second event transcript structure**"},{"type":"summary_text","text":"**Testing shutdown and concurrency behavior**"},{"type":"summary_text","text":"**Verifying promise.all invokes all commands**"}]},{"id":"ctc_09ab79121c733b56016a589f5734d48199b1501fe3c3f5a3e9","type":"custom_tool_call","status":"completed","call_id":"call_fhLYEjTkTEHfrcKnpe8AefKL","input":"*** Begin Patch\n[tests/omp-extension.mjs#4F06]\nINS.PRE 1877:\n+\tconst alphaGate = deferred();\nSWAP 1879.=1879:\n+\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return alphaGate.promise;\nSWAP 1888.=1888:\n+\tconst completion = harness.emit(\"agent_end\", {\nINS.POST 1895:\n+\tawait flush();\n+\tassert.equal(\n+\t\tcommandCalls(harness, \"send\").length,\n+\t\t3,\n+\t\t\"multi-target peer dispatch must not serialize independent recipients\",\n+\t);\n+\talphaGate.resolve(\"SENT:alpha\");\n+\tawait completion;\nINS.POST 1903:\n+\tassert.ok(\n+\t\tcommandCalls(harness, \"send\").every((call) => call.options.timeoutMs === 5_000),\n+\t\t\"peer sends must be bounded independently of the ordinary command timeout\",\n+\t);\nSWAP 1915.=1920:\n+\t\tmessages: [\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n+\t\t\t},\n+\t\t\t{ role: \"user\", content: \"@<alpha user prose must not dispatch @>\" },\n+\t\t\t{\n+\t\t\t\trole: \"assistant\",\n+\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n+\t\t\t},\n+\t\t],\nINS.PRE 1925:\n+\n+\tconst pending = deferred();\n+\tconst interrupted = createHarness({\n+\t\tonRun(call) {\n+\t\t\tif (call.args[0] === \"send\") return pending.promise;\n+\t\t},\n+\t});\n+\tawait interrupted.emit(\"session_start\");\n+\tawait interrupted.emit(\"agent_start\");\n+\tconst interruptedCompletion = interrupted.emit(\"agent_end\", {\n+\t\tmessages: [{ role: \"assistant\", content: \"@<slow-target wait for release @>\" }],\n+\t});\n+\tawait flush();\n+\tassert.equal(commandCalls(interrupted, \"send\").length, 1);\n+\tconst shutdown = interrupted.emit(\"session_shutdown\");\n+\tawait flush();\n+\tpending.resolve(\"SENT:slow-target\");\n+\tawait Promise.all([interruptedCompletion, shutdown]);\n+\tassert.deepEqual(\n+\t\tinterrupted.sentMessages,\n+\t\t[],\n+\t\t\"shutdown during peer dispatch must not queue a false continuation\",\n+\t);\n*** End Patch\n","name":"edit"}]},"duration":27105.238399999216,"ttft":5556.641799999401,"contextSnapshot":{"promptTokens":99457,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_fhLYEjTkTEHfrcKnpe8AefKL|ctc_09ab79121c733b56016a589f5734d48199b1501fe3c3f5a3e9","toolName":"edit","startedAt":"2026-07-16T09:07:43.308Z"},"id":"dd71943c","parentId":"fd514a96","timestamp":"2026-07-16T09:07:43.308Z"}
{"type":"message","id":"0f271efa","parentId":"dd71943c","timestamp":"2026-07-16T09:07:43.341Z","message":{"role":"toolResult","toolCallId":"call_fhLYEjTkTEHfrcKnpe8AefKL|ctc_09ab79121c733b56016a589f5734d48199b1501fe3c3f5a3e9","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#5905]\n1860:async function testPeerShortformParsingAndDispatch() {\n\n1870:\tassert.deepEqual(\n\n1875:\t);\n1876:\n1877:\tconst alphaGate = deferred();\n1878:\tconst harness = createHarness({\n1879:\t\tonRun(call) {\n1880:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return alphaGate.promise;\n1881:\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\n1882:\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\n1883:\t\t\t}\n\n1885:\t\t},\n1886:\t});\n1887:\tawait harness.emit(\"session_start\");\n1888:\tawait harness.emit(\"agent_start\");\n1889:\tconst completion = harness.emit(\"agent_end\", {\n1890:\t\tmessages: [\n1891:\t\t\t{\n\n1894:\t\t\t},\n1895:\t\t],\n1896:\t});\n1897:\tawait flush();\n1898:\tassert.equal(\n…\n1903:\talphaGate.resolve(\"SENT:alpha\");\n1904:\tawait completion;\n1905:\tassert.deepEqual(\n1906:\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\n1907:\t\t[\n\n1911:\t\t],\n1912:\t);\n1913:\tassert.ok(\n1914:\t\tcommandCalls(harness, \"send\").every((call) => call.options.timeoutMs === 5_000),\n1915:\t\t\"peer sends must be bounded independently of the ordinary command timeout\",\n1916:\t);\n1917:\tassert.equal(harness.sentMessages.length, 1);\n1918:\tassert.deepEqual(harness.sentMessages[0].delivery, {\n\n1921:\t});\n\n1929:\t\t\t{\n1930:\t\t\t\trole: \"assistant\",\n1931:\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n1932:\t\t\t},\n1933:\t\t\t{ role: \"user\", content: \"@<alpha user prose must not dispatch @>\" },\n1934:\t\t\t{\n1935:\t\t\t\trole: \"assistant\",\n1936:\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n1937:\t\t\t},\n1941:\tassert.equal(harness.sentMessages.length, 1);\n1942:\tawait harness.emit(\"session_shutdown\");\n1943:\n1944:\tconst pending = deferred();\n…\n1964:\t\t\"shutdown during peer dispatch must not queue a false continuation\",\n1965:\t);\n1966:}\n1967:"}],"details":{"diff":" 1860|async function testPeerShortformParsingAndDispatch() {\n\n 1870|\tassert.deepEqual(\n\n 1875|\t);\n 1876|\n+1877|\tconst alphaGate = deferred();\n 1877|\tconst harness = createHarness({\n 1878|\t\tonRun(call) {\n-1879|\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return \"SENT:alpha\";\n+1880|\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"alpha\") return alphaGate.promise;\n 1880|\t\t\tif (call.args[0] === \"send\" && call.args[1] === \"beta\") {\n 1881|\t\t\t\tthrow new Error(\"NO_PERCH:beta\");\n 1882|\t\t\t}\n\n 1884|\t\t},\n 1885|\t});\n 1886|\tawait harness.emit(\"session_start\");\n 1887|\tawait harness.emit(\"agent_start\");\n-1888|\tawait harness.emit(\"agent_end\", {\n+1889|\tconst completion = harness.emit(\"agent_end\", {\n 1889|\t\tmessages: [\n 1890|\t\t\t{\n\n 1893|\t\t\t},\n 1894|\t\t],\n 1895|\t});\n+1897|\tawait flush();\n+1898|\tassert.equal(\n+1899|\t\tcommandCalls(harness, \"send\").length,\n+1900|\t\t3,\n+1901|\t\t\"multi-target peer dispatch must not serialize independent recipients\",\n+1902|\t);\n+1903|\talphaGate.resolve(\"SENT:alpha\");\n+1904|\tawait completion;\n 1896|\tassert.deepEqual(\n 1897|\t\tcommandCalls(harness, \"send\").map((call) => [call.args[1], call.input]),\n 1898|\t\t[\n\n 1902|\t\t],\n 1903|\t);\n+1913|\tassert.ok(\n+1914|\t\tcommandCalls(harness, \"send\").every((call) => call.options.timeoutMs === 5_000),\n+1915|\t\t\"peer sends must be bounded independently of the ordinary command timeout\",\n+1916|\t);\n 1904|\tassert.equal(harness.sentMessages.length, 1);\n 1905|\tassert.deepEqual(harness.sentMessages[0].delivery, {\n\n 1908|\t});\n\n 1916|\t\t\t{\n 1917|\t\t\t\trole: \"assistant\",\n+1931|\t\t\t\tcontent: \"@<alpha,beta ship the patch @>\\nDone.\\n@<gamma inspect release @>\",\n+1932|\t\t\t},\n+1933|\t\t\t{ role: \"user\", content: \"@<alpha user prose must not dispatch @>\" },\n+1934|\t\t\t{\n+1935|\t\t\t\trole: \"assistant\",\n 1918|\t\t\t\tcontent: \"Mention @alpha and quote `@<alpha no @>` without side effects.\",\n 1919|\t\t\t},\n 1923|\tassert.equal(harness.sentMessages.length, 1);\n 1924|\tawait harness.emit(\"session_shutdown\");\n+1943|\n+1944|\tconst pending = deferred();\n+1945|\tconst interrupted = createHarness({\n+1946|\t\tonRun(call) {\n+1947|\t\t\tif (call.args[0] === \"send\") return pending.promise;\n+1948|\t\t},\n+1949|\t});\n+1950|\tawait interrupted.emit(\"session_start\");\n+1951|\tawait interrupted.emit(\"agent_start\");\n+1952|\tconst interruptedCompletion = interrupted.emit(\"agent_end\", {\n+1953|\t\tmessages: [{ role: \"assistant\", content: \"@<slow-target wait for release @>\" }],\n+1954|\t});\n+1955|\tawait flush();\n+1956|\tassert.equal(commandCalls(interrupted, \"send\").length, 1);\n+1957|\tconst shutdown = interrupted.emit(\"session_shutdown\");\n+1958|\tawait flush();\n+1959|\tpending.resolve(\"SENT:slow-target\");\n+1960|\tawait Promise.all([interruptedCompletion, shutdown]);\n+1961|\tassert.deepEqual(\n+1962|\t\tinterrupted.sentMessages,\n+1963|\t\t[],\n+1964|\t\t\"shutdown during peer dispatch must not queue a false continuation\",\n+1965|\t);\n 1925|}\n 1926|","firstChangedLine":1877,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192863341}}
{"type":"message","id":"a07acce1","parentId":"0f271efa","timestamp":"2026-07-16T09:07:51.650Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Verifying event emission completeness**"},{"type":"toolCall","id":"call_TbfcVbmxeG5JdE37DgpWulRu|fc_09ab79121c733b56016a589f661cdc8199a7fc75fe1bd312d9","name":"read","arguments":{"i":"Reading updated test runner","path":"tests/omp-extension.mjs","selector":"2045-2085"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":8330,"output":72,"cacheRead":92672,"cacheWrite":0,"totalTokens":101074,"reasoningTokens":33,"cost":{"input":0.041650000000000006,"output":0.00216,"cacheRead":0.046335999999999995,"cacheWrite":0,"total":0.090146}},"stopReason":"toolUse","timestamp":1784192863905,"responseId":"resp_09ab79121c733b56016a589f60525c819995c70b5fcb9e785a","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f645a808199a93994ef3a8be17f","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ9mE2tKpiwbvw7ncQGTMYu34wXbCQS-iCA7_V76P1xFxWVgfn027NtXmXGpVqi1uA-eyEFOnz3aI4JT0EM3w_4PFXSnB4bgcxhClqZ-MXtLNHKkN-FYfc10b9pcSlE_36uR2lFq9LJ7VjPH4Mr1d1tqowDewMuB9odhwrWrUaNMLZf-FqUJLnLOViygfkKBmkPYUolALvkSG1Uq1aJg4Wg4oXG0ogA89I9DkSs-TF2mOEuF5ZUYxcVbgyp7Cs6jlu2q8YPi9yBL7hPR0JGXoOkwpt_KBLBskvaSZvP1J3QC8QbCiqLg19L0XOGscmSDtXaOwvPZtRrDqrTvZiRVDkdQV4jMEbGnxX8kHI_4GmINoN1j20FUVRYoNE0atohlpyiH-oEs9G3QL-aQxQ8XA1BQCnMCQaiUFEujeru872OUhr_kl2sHbnUrXRcFi9qLXm6IYpJ8LFl36OgKvGUK2HxD0P8Lu07BsaW7ZvEOW8x47LgCRgfXSpnMgPetUw1bcYfGM_bnpb7_8k3GVqzILrxOaJyXqu_JwS014MXq_xXdwlngsMI4uyuCn4VUrZMSMtglw6fbJJFjxKrzqRwmtCrMTQOHhEeSjBCaqMzzjGnyrWFdZ6a8fdGADaZzpnVFZNp5ka5tRPee6k4n8If32JkVjFIkghmP5PxrQPeEA8w451jMPppCtFxBeMMCAP_RvnNBq0wQH5OQOgzm9MJgDdUdnKoAg04Dj9968ReTrcX-VTQfxdQhiZsexiLYceCWZCZ8PDGlgE7i3r4eElmadFb6QSrXf2PDCphtEfDo0sn8JYPjiYkmLTC6XAf88XB4IZ891--rvAhswNSP0mbZO-8o4aNDsyGsfBLJ_Gq14TjNvRU_eCeboJZvBfvLanvC_B2XwJaAR-nxNpgmDFcgEh4S-fo7uIAXSQBiaqdauFd1c0dMGYo8e3I1ljJQpsccDppFa7Hs95IK2mMFe4TNNV2tm6q1s3lyiZW7-EXHLbRIJXVa_iPyYCjv0Wlp3imeL7pQM81dTxa5urCucvuXW1866ksxvwb3b4MQKVl1MMBnkS4FA2qbFzSy3jcfAzttHFEM2aP3QyGmaYmp0sB0uqZ42Efc1Pf7p0seVE0mBKbQKlc=","summary":[{"type":"summary_text","text":"**Verifying event emission completeness**"}]},{"id":"fc_09ab79121c733b56016a589f661cdc8199a7fc75fe1bd312d9","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading updated test runner\",\"path\":\"tests/omp-extension.mjs\",\"selector\":\"2045-2085\"}","call_id":"call_TbfcVbmxeG5JdE37DgpWulRu","name":"read"}]},"duration":7743.87239999976,"ttft":4424.093700000085,"contextSnapshot":{"promptTokens":101002,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_TbfcVbmxeG5JdE37DgpWulRu|fc_09ab79121c733b56016a589f661cdc8199a7fc75fe1bd312d9","toolName":"read","startedAt":"2026-07-16T09:07:51.650Z","args":{"path":"tests/omp-extension.mjs"},"intent":"Reading updated test runner"},"id":"a34d3e92","parentId":"a07acce1","timestamp":"2026-07-16T09:07:51.650Z"}
{"type":"message","id":"468bcaf6","parentId":"a34d3e92","timestamp":"2026-07-16T09:07:51.668Z","message":{"role":"toolResult","toolCallId":"call_TbfcVbmxeG5JdE37DgpWulRu|fc_09ab79121c733b56016a589f661cdc8199a7fc75fe1bd312d9","toolName":"read","content":[{"type":"text","text":"[omp-extension.mjs#5905]\n1969:async function testNativeCheckpointTool() {\n…\n2044:\tconst failure = await failed.tools\n2045:\t\t.get(\"spt_checkpoint\")\n2046:\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\n2047:\tassert.equal(failure.isError, true);\n2048:\tassert.match(failure.content[0].text, /native compaction cancelled/);\n2049:\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\n2050:\tawait failed.emit(\"session_shutdown\");\n2051:}\n2052:\n2053:await testParsingAndReplies();\n2054:await testRunSptRejectsStdinErrorsAndHungCommands();\n2055:await testLifecycleCustodyAndContext();\n2056:await testDeferredBindLifecycleSerialization();\n2057:await testOutcomeSendRetriesAndExhaustion();\n2058:await testSubmissionFailureAdvancesQueue();\n2059:await testFailedIdleRecoveryFailsClosed();\n2060:await testListenerRestartExhaustion();\n2061:await testListenerStableIntervalResetsRetries();\n2062:await testFatalTeardownAwaitsInFlightOutcome();\n2063:await testSessionEndRetriesAfterTransientFailure();\n2064:await testHumanBusyFailureFailsClosed();\n2065:await testShutdownReapsAndFailsQueuedCustody();\n2066:await testListenerTerminationEscalatesAndReaps();\n2067:await testProtocolCorruptionFailsClosed();\n2068:await testInboundQueueOverflowReturnsAcceptedCustody();\n2069:await testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\n2070:await testShutdownFallbackStaysBelowHostCap();\n2071:await testNativeActivationCommandsAndErrors();\n2072:await testNativeActivationSelectionAndCompletion();\n2073:await testExplicitLiveAutoResume();\n2074:await testStartupBriefHintsAndUpdateNotices();\n2075:await testActiveTurnBoundaryDeliveryAndFallback();\n2076:await testAbnormalTurnsRestoreReceivability();\n2077:await testPeerShortformParsingAndDispatch();\n2078:await testNativeCheckpointTool();\n2079:\n2080:console.log(\"OMP-EXTENSION OK\");\n2081:"}],"details":{"displayContent":{"text":"async function testNativeCheckpointTool() {\n…\n\tconst failure = await failed.tools\r\n\t\t.get(\"spt_checkpoint\")\r\n\t\t.execute(\"tool-3\", {}, undefined, undefined, failed.ctx);\r\n\tassert.equal(failure.isError, true);\r\n\tassert.match(failure.content[0].text, /native compaction cancelled/);\r\n\tassert.deepEqual(failed.sentMessages, [], \"a failed reset must never queue a false wake\");\r\n\tawait failed.emit(\"session_shutdown\");\r\n}\r\n\r\nawait testParsingAndReplies();\r\nawait testRunSptRejectsStdinErrorsAndHungCommands();\r\nawait testLifecycleCustodyAndContext();\r\nawait testDeferredBindLifecycleSerialization();\r\nawait testOutcomeSendRetriesAndExhaustion();\r\nawait testSubmissionFailureAdvancesQueue();\r\nawait testFailedIdleRecoveryFailsClosed();\r\nawait testListenerRestartExhaustion();\r\nawait testListenerStableIntervalResetsRetries();\r\nawait testFatalTeardownAwaitsInFlightOutcome();\r\nawait testSessionEndRetriesAfterTransientFailure();\r\nawait testHumanBusyFailureFailsClosed();\r\nawait testShutdownReapsAndFailsQueuedCustody();\r\nawait testListenerTerminationEscalatesAndReaps();\r\nawait testProtocolCorruptionFailsClosed();\r\nawait testInboundQueueOverflowReturnsAcceptedCustody();\r\nawait testSessionStopAwaitsOutcomeWithoutEndingEndpoint();\r\nawait testShutdownFallbackStaysBelowHostCap();\r\nawait testNativeActivationCommandsAndErrors();\r\nawait testNativeActivationSelectionAndCompletion();\r\nawait testExplicitLiveAutoResume();\r\nawait testStartupBriefHintsAndUpdateNotices();\r\nawait testActiveTurnBoundaryDeliveryAndFallback();\r\nawait testAbnormalTurnsRestoreReceivability();\r\nawait testPeerShortformParsingAndDispatch();\r\nawait testNativeCheckpointTool();\r\n\r\nconsole.log(\"OMP-EXTENSION OK\");\r\n","startLine":1969,"lineNumbers":[1969,null,2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,2079,2080,2081]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\tests\\omp-extension.mjs"}}},"isError":false,"timestamp":1784192871667}}
{"type":"message","id":"9b489edf","parentId":"468bcaf6","timestamp":"2026-07-16T09:08:01.555Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Inserting function call**"},{"type":"toolCall","id":"call_pKJPywauwOnbFpZviLtqVeGZ|ctc_09ab79121c733b56016a589f6fc2d8819987ef9f84b6a34cb2","name":"edit","arguments":{"input":"*** Begin Patch\n[tests/omp-extension.mjs#5905]\nINS.POST 2072:\n+await testPlatformAwareActivationCandidatePaths();\n*** End Patch\n"},"customWireName":"edit"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6827,"output":53,"cacheRead":94720,"cacheWrite":0,"totalTokens":101600,"reasoningTokens":7,"cost":{"input":0.034135000000000006,"output":0.00159,"cacheRead":0.04736,"cacheWrite":0,"total":0.083085}},"stopReason":"toolUse","timestamp":1784192871675,"responseId":"resp_09ab79121c733b56016a589f6aba6c8199adc6cd64233ba43a","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f6f4f0c819989f69887567b235f","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ9vK4cHLhtRF746lqFWcY_o4rh2bdhr1BvSJxEvMPewPD9BGgF37p5n4CASeAvE784Uoyk1aEk2or36uqNIH_-O2a13ZBkTYF02zADgoHr76IKP14p1waKKzDfE_lRF-s4eabpqxueVNenf-gr9kVuImrL8XZ91SNgcHYgvgFvp0wRKJNGJHgsXyxCPt9x_bhZoKNp6WCI1RV1BETzfCC60EPcYUCgxmFINDRarZ30Y0xbl27RN3gwDluylzy2SghHcQF8c8HgE7eDcsMpXQ1imlCNqt2xetG5OzPIgR3O1jJVoIdPCyeeyeFEFIOdCNdH5x-jFF3bS2w8M7Y1VIdWw1xjeyrTMWbz4WcGvpLwd7UxNwxSLR9G9n3lGvlkoB7vK6QhJ9P9m6cD6wava-t9w0vgAlgvyEzxcGJBKTvIsbaTnYfJN_nZpVJyeq1TnlU-Z_WskgcfmxYUj1wWiz-qAI-OPArkU3SU4G9Qy4czI4cbFJowA7-LmhE2ucPM_vNLXNujidv90psXGU1CJOb2QPl0KkaI7iHKIaBQacDL5A0mLCGxD6iAeU7aVaUnIpWRGa0ZpeWOtcrAIyAJE48QzXZmNBDdxf9v6oLDibGicrbrLU8ayhenWWzhz1LYrWww_HhUSigMgB8FD9UCn1WAxs85wKHj2Wt1mCxr9GmOg-SGci5QhQMit167CPtY3oLv6z1nmM2zdfKn-H6F0K3u_IuPH4T2A20cu4BTLtXM_oAbjzcq53OspT8q5x6tOtflkTqnWj-4yjPAHEhdFebBnEKnma9-1fBtg-PPHZXhT_tOVQJD-ZHnleK0EyLbx0cquhbUxjpDxz9PzDION0YS_MIWZenS_ge9xD1GLZe7GrCNg5T6nOGMicqFPC6Ykh7yTSt1Eo4V1RtKt517Pyr0x0y4WzMFHE9Ssu9P37FkoP_0=","summary":[{"type":"summary_text","text":"**Inserting function call**"}]},{"id":"ctc_09ab79121c733b56016a589f6fc2d8819987ef9f84b6a34cb2","type":"custom_tool_call","status":"completed","call_id":"call_pKJPywauwOnbFpZviLtqVeGZ","input":"*** Begin Patch\n[tests/omp-extension.mjs#5905]\nINS.POST 2072:\n+await testPlatformAwareActivationCandidatePaths();\n*** End Patch\n","name":"edit"}]},"duration":9879.563900000416,"ttft":7608.757400000468,"contextSnapshot":{"promptTokens":101547,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_pKJPywauwOnbFpZviLtqVeGZ|ctc_09ab79121c733b56016a589f6fc2d8819987ef9f84b6a34cb2","toolName":"edit","startedAt":"2026-07-16T09:08:01.556Z"},"id":"75b7cb5e","parentId":"9b489edf","timestamp":"2026-07-16T09:08:01.556Z"}
{"type":"message","id":"b0e9ed08","parentId":"75b7cb5e","timestamp":"2026-07-16T09:08:01.594Z","message":{"role":"toolResult","toolCallId":"call_pKJPywauwOnbFpZviLtqVeGZ|ctc_09ab79121c733b56016a589f6fc2d8819987ef9f84b6a34cb2","toolName":"edit","content":[{"type":"text","text":"[tests/omp-extension.mjs#535B]\n2071:await testNativeActivationCommandsAndErrors();\n2072:await testNativeActivationSelectionAndCompletion();\n2073:await testPlatformAwareActivationCandidatePaths();\n2074:await testExplicitLiveAutoResume();\n2075:await testStartupBriefHintsAndUpdateNotices();"}],"details":{"diff":" 2071|await testNativeActivationCommandsAndErrors();\n 2072|await testNativeActivationSelectionAndCompletion();\n+2073|await testPlatformAwareActivationCandidatePaths();\n 2073|await testExplicitLiveAutoResume();\n 2074|await testStartupBriefHintsAndUpdateNotices();","firstChangedLine":2072,"op":"update","path":"tests/omp-extension.mjs","snapshotsPruned":true},"isError":false,"timestamp":1784192881594}}
{"type":"message","id":"5d47cd7c","parentId":"b0e9ed08","timestamp":"2026-07-16T09:08:10.214Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Running test suite**"},{"type":"toolCall","id":"call_3ZLT8Gg3YBJYBXSxhU9v2x2O|fc_09ab79121c733b56016a589f78ac648199a794a5852253ee14","name":"bash","arguments":{"i":"Running strengthened extension tests","command":"node tests/omp-extension.mjs","cwd":".","timeout":180}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6957,"output":48,"cacheRead":94720,"cacheWrite":0,"totalTokens":101725,"reasoningTokens":7,"cost":{"input":0.034785,"output":0.00144,"cacheRead":0.04736,"cacheWrite":0,"total":0.08358499999999999}},"stopReason":"toolUse","timestamp":1784192881604,"responseId":"resp_09ab79121c733b56016a589f71ef8c81998248086537e36f00","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f781a688199915de4f7c69caab5","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ94R83ICJzf-yxa6FE_iYrZuUGoTMZAgQvk_qnFwY1X3f8zakMa59Kxd1OQmEwHb8TmWUOQPjLlVixsxO9H3WL3wVGiiZ_k3qGxSaBNyNXk7RydZVuz_SV52js-ZMk51ZcZ_FnyE3-XNtQ14FIb1vLGoi9_Djko68A19gLrFFsOPMibZJiTO8nR8rXn6wViJR3KrtCzQOfV8thUeWutAuDNbzw1goJ-NvkDu52ARyUVM_QAatbwSl-UJVFZ9V8bbM81NR89bZdhg3PQZZArd18ZKcn9AHO95JdI-iSGBDWbRfoNG6jgiFc2r24iip0hVM_lmgve733zNiAun1xZNZubfUxYDHh7B99Zwe49o9K6-XjOdAfTQuc62heP4jFQJ0UoZuKaKf4zGPRgA9yWkqePE6pKxKxQoe97p2wbjRCsG7s3gqS71aR4tr5-T5sRu7PQQRwVGoltDAJStRBXJamPjUy1OgCzVJDhgtbKepVciWYBVUOlhhbc4ScKxhJleUQ4Ib0dYh-08SxQF-Wcr4tFQPLMS-TvCWP1RtgHCn42-JRvnRSUs0g_srR8-_v3vkOwSQ-WBVTclr2Glhi4m-ONeTfe9VmRa28LtcaCSqMTyNLiiVG4sEM5ro-m2eBFcr7A_YvThhVXqiVQTus5EfCL6AUYx9D7GEx2c7EGokR_waHbIF-416E_yMn7l3JE-Mn7x15CZotaULAsvRIC_cuqIpDrfSLD4IQTxDc8FsXxe_Fw0Mvu-2fUbae-L_2ZCxvst0CtVGxS3IPXx5NmmAwJeYF-cbWoI2i6E96w-mSm5PcyqrECHYeRhyJHUcpmzcMOFf5EJFDFOBzBXNCHjKcagDKNNjU3ezj5prM2rksGPMLMomJK-fCCqjXSDgI3tn4Mte_8CjTMazMPbkxmNThQbvnUxNUfdc1ShS4XJJT3LlE=","summary":[{"type":"summary_text","text":"**Running test suite**"}]},{"id":"fc_09ab79121c733b56016a589f78ac648199a794a5852253ee14","type":"function_call","status":"completed","arguments":"{\"i\":\"Running strengthened extension tests\",\"command\":\"node tests/omp-extension.mjs\",\"cwd\":\".\",\"timeout\":180}","call_id":"call_3ZLT8Gg3YBJYBXSxhU9v2x2O","name":"bash"}]},"duration":8609.128500000574,"ttft":6474.097699999809,"contextSnapshot":{"promptTokens":101677,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_3ZLT8Gg3YBJYBXSxhU9v2x2O|fc_09ab79121c733b56016a589f78ac648199a794a5852253ee14","toolName":"bash","startedAt":"2026-07-16T09:08:10.214Z","args":{"command":"node tests/omp-extension.mjs"},"intent":"Running strengthened extension tests"},"id":"9aaebe45","parentId":"5d47cd7c","timestamp":"2026-07-16T09:08:10.214Z"}
{"type":"message","id":"08057363","parentId":"9aaebe45","timestamp":"2026-07-16T09:08:10.297Z","message":{"role":"toolResult","toolCallId":"call_3ZLT8Gg3YBJYBXSxhU9v2x2O|fc_09ab79121c733b56016a589f78ac648199a794a5852253ee14","toolName":"bash","content":[{"type":"text","text":"OMP-EXTENSION OK\n\n\nWall time: 0.08 seconds"}],"details":{"timeoutSeconds":180,"wallTimeMs":81.52259999979287},"isError":false,"timestamp":1784192890296}}
{"type":"message","id":"1b1c57ac","parentId":"08057363","timestamp":"2026-07-16T09:08:24.830Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Reviewing requirement tag usage**\n\n**Inspecting message inbox**"},{"type":"toolCall","id":"call_pdqaFOWix3EBkPF6DpBoZT1U|fc_09ab79121c733b56016a589f84f094819990c03db0091a443a","name":"irc","arguments":{"i":"Reporting review fixes","op":"send","to":"Main","message":"Core extension + focused tests now pass after review fixes. Fixed ephemeral safe-boundary reinjection/correlation via assistant baselines, platform-aware path matching (Linux case/root tests), checkpoint type verification for launch-time ReadyAgent plus awaited compaction, and bounded concurrent shortform sends with shutdown suppression. node tests/omp-extension.mjs => OMP-EXTENSION OK. Please activate corresponding registry stages you own.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7030,"output":275,"cacheRead":94720,"cacheWrite":0,"totalTokens":102025,"reasoningTokens":140,"cost":{"input":0.03515,"output":0.00825,"cacheRead":0.04736,"cacheWrite":0,"total":0.09076000000000001}},"stopReason":"toolUse","timestamp":1784192890337,"responseId":"resp_09ab79121c733b56016a589f7aa4c881999ae180958d283f3e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f7f1b6081999efcdd9724491ec5","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ-EFTERXM_y08QbvOhaCtaYZuH82p84jp7tnCqiNkXaPRfER8mzgkKp5qjFPjzj5CSfM2FBrxq8UcKDlYLmVziBJOKVurMdg8aoXIXnHklWr8MXxAoQvmn37Or_dSs6FbG24lM_e9xY-4higHMzLPbSTBw7-9gzdvuiTzYRXkViSDxObzAVlubG4BUzS_Oi5KjX1-GIuwGsZtaMduIqKoKFbKtofeWtKVJ5-8AQKmz5wqWGGh0UmNAySBoFcVTFG8iK6uQBiKC7Lfof4sUKykReW42bGEtlBWJXe4lCmBWU-RTjqSbu_3rKsoaFJ4JJ6kk-Olq0zppH-z9h15M7_RVxho-wJF33iFZ3VooOkA4DySaDaDjFmpYhuK0oO3jvtylzq_ZOL7cChvzobaFZTsMchK8JOeYrLpMrTPQMG02bJsmJjWV_vThnTBYHs37bPKIGQ3_LcDxPSBTdse_QQa9hr9QAHDZsw1xLm9qoJK3bf362k5fXzqUCimELEAPIii8hSi4pYRinEgZ6reIaHesTQC4-rzlygHHNjasqkchzxlp23mcxe9URY-TmL1TXbyaVbwp87JLvjwJAxhetr6sNHxvWYm1Wy5f3X7L3Ja8ISXz8ftYAO2bJ_9TMC35B-aaI6ZgncZ9qPr0dSGjWVbwFkLfZDXwhutrPF_2S5neh5cZOrWTXtwFBuTW0kX2derEO0Wp7AMmJpq6vVykOaYr4NYihTa1ptrJ46TDZvmCLH4WBeAe04o2usIaKssQL50l-rVoru1p2kt_ls4pZmtReVpe4PfQqrYa1_RtdxjO4ipM7vRINhwxZJEka0NdBbpdWnxNMDCdG7Stb0d3aTr5cxh9g6--PMvjqgGMxEe-MCAS9EWBhjaY2jpfxH6DfYTIDlRZr9zoaI0tJvzbzXcDhESA3oZnkNUljHTgt41JapFwU2UQ75ojPs8XXUocsHup_Up3bzgdrn90ETq3kJ10d8BMyCicPylEc-YCrXVn8t7K2FEf012vFwwLg2wDqU3OroeYXIyxCZD3go9p_XyIb6bof7NtQXbWfFa8xGtkma54Hwby0IpW46nZRPtc0Ec6Bx6W3ODZJjOT1uDc7ySDygHNE4n7BhSBNJ0FF3zoLBmfRUY6wRDQcPh_fW2RGTcKVrzp_Aaz3CE6c66WiI61Kk-1RndyeZMu4LeY2Nh0ra7UF_onL4n0kKCWI39LZ7kx3MdtFy0Bw-uQQWqdV71kuSwnOz7dFfsG7_GFnCcS_BkBP4E0RZtUnKNZX5p0vVFxpspL9ilkN8dUeZX_0aMy98uUk3aoUg4ZkdnXPb5JEENcKQp1RSGRQ07_0I0WkJeIyS0Wf5fY5WgdI9l6C9AbPBYzCcLFt1L_I_iwv-CxcZpVHvMyyt3XQXO2C1HU1SZtLi4lSH8zrYFLVBX966HfPz311WKm7pD3-GuKkAAH_mCJE5Oa5dUXzCZdEbwR6NrZOFvGWL5ZylrTD4r74u6zkaV-LupoqfNdV_bBTGK1_l4R7B1FRBoPgsz2viIGLEhcFGxE6aNC1_ygJLaMG2e6ipT5KPKYTn_9C6uAXjOZMtUJraHEGzWhoGL0EIoQ7_eqNNBEoQKoslnbgbtIiNnh9qlzUcVFkjawMF01N0OD5qw5Ngh0lARSlyUatmG1REwxJ0FAjtOfCZTFrRdU16P2zACV9FlJkJsS-FkxEA5C1nxN27EMx0DTx9m6DxfKexUy5c4vrxyhGS7mDv9k2XrAKNwlO0CNQBZTegyHl_lqEmFy8_2QRAO5Q-lPF1FlTDvEv_mLePB2-5-VKOstxl2SAUSShe4MeneeYCiEVlDkG_ocuSKO9tBoBBee00QaWlJOO5592ZDH3HJNBFgJhUzIrB07FbTQJpC5_gflwCAOlB0An_fvBAX1L6Pnp1rHPDRNFzNgILFt2oRP2i5FEo3z7Lg==","summary":[{"type":"summary_text","text":"**Reviewing requirement tag usage**"},{"type":"summary_text","text":"**Inspecting message inbox**"}]},{"id":"fc_09ab79121c733b56016a589f84f094819990c03db0091a443a","type":"function_call","status":"completed","arguments":"{\"i\":\"Reporting review fixes\",\"op\":\"send\",\"to\":\"Main\",\"message\":\"Core extension + focused tests now pass after review fixes. Fixed ephemeral safe-boundary reinjection/correlation via assistant baselines, platform-aware path matching (Linux case/root tests), checkpoint type verification for launch-time ReadyAgent plus awaited compaction, and bounded concurrent shortform sends with shutdown suppression. node tests/omp-extension.mjs => OMP-EXTENSION OK. Please activate corresponding registry stages you own.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_pdqaFOWix3EBkPF6DpBoZT1U","name":"irc"}]},"duration":14491.511100000702,"ttft":4744.924000000581,"contextSnapshot":{"promptTokens":101750,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_pdqaFOWix3EBkPF6DpBoZT1U|fc_09ab79121c733b56016a589f84f094819990c03db0091a443a","toolName":"irc","startedAt":"2026-07-16T09:08:24.830Z","intent":"Reporting review fixes"},"id":"3a66cc61","parentId":"1b1c57ac","timestamp":"2026-07-16T09:08:24.830Z"}
{"type":"message","id":"c838a91a","parentId":"3a66cc61","timestamp":"2026-07-16T09:08:24.831Z","message":{"role":"toolResult","toolCallId":"call_pdqaFOWix3EBkPF6DpBoZT1U|fc_09ab79121c733b56016a589f84f094819990c03db0091a443a","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- Main: injected"}],"details":{"op":"send","from":"NativeExtension","to":"Main","receipts":[{"to":"Main","outcome":"injected"}]},"isError":false,"timestamp":1784192904830}}
{"type":"message","id":"f41e1fe7","parentId":"c838a91a","timestamp":"2026-07-16T09:08:38.688Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Clarifying audit and review process**\n\n**Planning tests for custom runCommand timeout**"},{"type":"toolCall","id":"call_45g8vLhHjuoB63Ou0ycFU6Yt|fc_09ab79121c733b56016a589f944af88199b04155bb70a2bb27","name":"irc","arguments":{"i":"Checking coordination replies","op":"inbox","to":null,"message":null,"replyTo":null,"await":null,"from":null,"timeoutMs":null,"peek":false}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7327,"output":275,"cacheRead":94720,"cacheWrite":0,"totalTokens":102322,"reasoningTokens":218,"cost":{"input":0.036635,"output":0.00825,"cacheRead":0.04736,"cacheWrite":0,"total":0.092245}},"stopReason":"toolUse","timestamp":1784192904837,"responseId":"resp_09ab79121c733b56016a589f8944c48199a97a95b011fe8a0a","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f8c3f8081998db858558d928431","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ-Ur5fvl3gl4AxZgGIG8BNhwQy6WrioI73lXDOa1WzbTLD04btycBgv1sAQJZgXBW53CJr68TVOZbtaU9MR29AB-NcDvTqsqsl-1vvxeRKvALmoHiPEb8e16H1U1nd2wGpqz3XUOy0cg4RgafgXz7gbV1kRlxh5f5U7ICCgOhVBwj4Ruuawm10ynL6OF_a0AX1dnOZt41KEcl88l5H-qCvkqdMRDH45YvJ7QlI7rhjfMqCR1Qv_awqUhCnAs3rBhuO00p4CQRiOx8VmDIlHHgwhFbLDYjUbKXeyj7klO1kXQfHfFWgTNRIceCZGwK5NKm6K9B036vfDYIq0ejDOnzkPKTTfQDePnnMYvhD3irUiz8EgVa9RGR0dd1CEZ0OsjkkPgeEBco1YQxUVhW9uyeeVXO51mI1iqAeUxkzb7o65FmMDoSVjBQJYyfpy8DBtXzhLX-gzHQjU9y5dzmKGdXLO1S_tIQVZxtu5Z7fQOfra5RwhF_tuMzDFTUVHANzz-PNxCY9434-gwYtCWzONMFwLQ6M9rIjocJ2FYhqVoNPOAKex_yJZ0_FxjosP1F45LKLehINoqsNnDGvp5knhkNGXvNkQMYYoT7IdMeDzyP-9SXk1hN9jsyRIzSX1UwgpPdXZe2KzzIDyBZl3mlVfng0va5nPZ1Kyx14zSN_KsSgGFqACdIYh4cyH0p-v4jnyU8kd3iIr8sfa3d_6jbrNIOO0AUiyVpbVNv2GC-w_Cc9ec_zB2QeQwhuwunFBmWwh1bZunOyu_ISytqg39K3Bd7yMlGrfWDc35G7Es2k9eSU1FZh1UJheXQZYEPjaqCIj6W2FC0stNfmFmfyHvc1P-CswGLFHdqn5uyLD5iznXWPQ_4B1NGLtwpHNZBiI9x5Fvh6Sc-oGltnYHQAZ0XDFPBvAC1EohqPaz5_g8VRi-bZlkZq8lU0whPvItxE_NxGyYGeMP4mYBTHTmopTV6dPaiLAeYDGcDGeO2XCTP0pI5o_e1TAaUCohgwQwwRsRDAwFhDfY9CUD4dMubxa0KjJdAh_2iZS4bEZXebkNQs8jPWMH7ZPAbXNRIWee3H1j5-qOSLZ28Ql9Zs17F-AiApR2ME4A5U3e0R7LkRgFWyl4DHW9AGf0M14WGvNBET5SG7992pvlW2AhLv3J-ysPP6DBg7U6lOK7LVhb45qwbUiLB42SQfm_tEyDqzRJR7ItyoZstNv4BVw8-ASpnTGqDL5F1f2M5_iwZY9eDgVE0l7aF8BQp8oa8MagIorLtI6s4vVFWJK1AnVZ-Gb2vE8ioifKLidROTFXkAkU-akwPuHiiIPNezy8OCe_09Dx0bKzaxnwXNvrGOb35Yb_RNjQqspNwAkTQk9h2G2xj9w2-y6RSVd8CuhuXewHZ6zqUZtJxRHWo6gqbQTAVrCg_q5qJ9nci9DLkXMhysp3Wr6GXyeApcHZXcFI_0S2To_DUaqUmrJ735w7NWVeZqfRZjTyjjYJK4VWqbSE-jg3K30p1Lzvy3lQsobdtlyc93T5mxkI20BstrbCLFFm3Ozx6p3J3lm4uF9Anm2lfeD-nVEu9sjIIxzxiB7keB64F8r74e5FDE9qOLrLvYgxeNnmp7AUTMJnbuzHGXhZmHMbwgACWajPiWUZ9YFlZrdxsPmT1SR0mp2C-GsbAbpY9Ft_Sf2gOh2HvAkX2qkfO_F8NSGa8LhTJJ2RmgJbftlqntPMC6AydQL99YfXiumvlt6oZaNbiuPQWecxV5lRHAlAQ223zl58ze-EBJbGVAbHG6njgldCOsUw-PtHX_NYdpx-5AmvsUDPViEP0r-OTqbxiPbu5pIxh8JhSDJT95vpolYrcFlqE1RlZavk1lAiH7-dePpa4tIHqGviJRCb0A2PBVZpy5L3cmQ-KxhSGz42H2Rsmd-hbYA8J-F8PIg4LHtmJmcs2rhwrRkBd-snghDlsyK-abse2pFNMsBLGh9soeqQ0Bz01pDxlFamjWN1CLS-rsAme2oNsJ5ftScPSgd_DERuxV08PptN5RliomfqyILXrt4aX29-wIixsGpGZVFaYLp0Iz8_RR98dWPMIracTrZW934EM8OYdwhPKNZmHKjLpzo6-8YoTCkGNuZlL0E5c3jimaQPEHZbmWjLww37iyF42JgIgLb3dLAN2qJ9qudkNcWMButKgpwIEocMkc3KE69jMF1sgtnz81p8dNCdKTqEx_d-0bvPpD9PzJyUF2DNmhgsrsPEcw52U9yVum0BzfZDep9NpJVe3rbv64Ivx0umL-07RC596twsN7Oz05n5jGZ3TzrxM6mcCK_bG9iEok1Y98lWX6iFNBRz5wmSJw296O2TM7Bz2UIET1sNc7GdoBkRT_cdyYwp5-f_TVnbCO7EItUIwrQlqkNEl4_vrdaoheSjZZAVuzxCFzMwADjiSS7FeDd9N9s","summary":[{"type":"summary_text","text":"**Clarifying audit and review process**"},{"type":"summary_text","text":"**Planning tests for custom runCommand timeout**"}]},{"id":"fc_09ab79121c733b56016a589f944af88199b04155bb70a2bb27","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking coordination replies\",\"op\":\"inbox\",\"to\":null,\"message\":null,\"replyTo\":null,\"await\":null,\"from\":null,\"timeoutMs\":null,\"peek\":false}","call_id":"call_45g8vLhHjuoB63Ou0ycFU6Yt","name":"irc"}]},"duration":13837.531799999997,"ttft":3385.2615999998525,"contextSnapshot":{"promptTokens":102047,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_45g8vLhHjuoB63Ou0ycFU6Yt|fc_09ab79121c733b56016a589f944af88199b04155bb70a2bb27","toolName":"irc","startedAt":"2026-07-16T09:08:38.688Z","intent":"Checking coordination replies"},"id":"1678214c","parentId":"f41e1fe7","timestamp":"2026-07-16T09:08:38.688Z"}
{"type":"message","id":"4cef2c38","parentId":"1678214c","timestamp":"2026-07-16T09:08:38.689Z","message":{"role":"toolResult","toolCallId":"call_45g8vLhHjuoB63Ou0ycFU6Yt|fc_09ab79121c733b56016a589f944af88199b04155bb70a2bb27","toolName":"irc","content":[{"type":"text","text":"Inbox empty."}],"details":{"op":"inbox","from":"NativeExtension","inbox":[]},"isError":false,"useless":true,"timestamp":1784192918688}}
{"type":"message","id":"a87074e2","parentId":"4cef2c38","timestamp":"2026-07-16T09:08:38.690Z","message":{"role":"user","content":"Your current interruptible wait was interrupted because an IRC message arrived from your parent agent `Main`.\n\nParent IRC message:\n\nPlease activate every corresponding REQ-PARITY/REQ-HAZARD stage actually supplied and ensure adjacent evidence tags in extension/tests/docs, then run traceable-reqs check before yielding. Main should not guess stage coverage.","attribution":"agent","timestamp":1784192914895,"steering":true}}
{"type":"message","id":"f3163d59","parentId":"a87074e2","timestamp":"2026-07-16T09:08:47.783Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Inspecting registry requirements and documentation**"},{"type":"toolCall","id":"call_ykhPWPH8wzBXEMAX9pRcJuxn|fc_09ab79121c733b56016a589f9e8fb481998a32609108c5f9b2","name":"read","arguments":{"i":"Reading parity requirements","path":"traceable-reqs.toml","selector":"110-205"}},{"type":"toolCall","id":"call_ruUOP89B6pb3AsdmwOHgCucZ|fc_09ab79121c733b56016a589f9e8fc481999a7b9f2f4b0bb9e0","name":"grep","arguments":{"i":"Locating evidence tags","pattern":"REQ-PARITY-(READY|LIVE|SAFE|STARTUP|TARGETED|UPDATE|PEER)|REQ-HAZARD-ABNORMAL","path":"docs;adapter/strings/omp-spt.mjs;tests/omp-extension.mjs","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_vBeY1i871C9WjTzsyFn5lL49|fc_09ab79121c733b56016a589f9e8fcc8199a57ed3951f758725","name":"bash","arguments":{"i":"Checking traceability CLI","command":"traceable-reqs --help","cwd":".","timeout":30}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6722,"output":198,"cacheRead":95744,"cacheWrite":0,"totalTokens":102664,"reasoningTokens":22,"cost":{"input":0.03361,"output":0.00594,"cacheRead":0.047872,"cacheWrite":0,"total":0.087422}},"stopReason":"toolUse","timestamp":1784192918707,"responseId":"resp_09ab79121c733b56016a589f971b188199a8254305be04efdb","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589f9a967c8199932fd4358df3a1f5","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ-enR6bzRNga70N-q8YzNNjPUy_RfnBUJlRfknnyY0f9RwMILEATCpwxCm7jrfuimTief_LsHu8M-LSv23U_PaFn0_ouu_b6qlFF8-G6mkReucD9kL2cSFTvHlqCTyYo_9Pk1KVmfy5an5sTHgdqOlqoGN2IG6WNqLgDDi0-JVN-8mf0rndQlF2UOx-AONAtnBwMJma-zurecwIXP_-dM4OhvmhRDoOgJb15ztc0VK1zk7cYt0yjsJaC4PCuvYg7CRtyISKBkbVIyW_JzdzZj4629Vyt9iRdqpKMKY1Wd-r6Hj_2uyXSpeK0x6iZ1eb-dLPUIepo3CSKg9V35cniISB-lLG8IEI3XgGwyGKuLT5W4iCxnZA-8zyIHQSerq0GJzkGiBf29FdxHajWLGYcptmQOifRR-vLylHdfqWBpK3h7y8BS2qlGRVHLmz3Up-99KBEt6-YF14qPRuwBxVHNDGH-jaSg_7Qwux2fTdpN48TjVH-dG9kvqhjfyYGcHvnLHZt4Y4Hibyn6oIKEZPMaPCDK06Ijfh9rSpOT5X7YzXMDL8jsUhMJSqlaA2ENo9vGgd3IJ5oR1tGLWgGt5EUeDHh6ORchhSZ24J2GsCvdk9trKnQGf-PmE61jDHzTaxkfD2lpPaZCiZFmXHFDFD9k71BpdwIN1nB9yWzGtrJ5wZxGXSKoAKojP2L6FxXgXoNLmnCN885QAjXfpRIxi6__K0tGLfl2JHiOkqoYMb3jzEF45RYvEFjHvtiAiJyZ6vb7WRuoNRdU59UxFdQG9gynVjtWLQAlF-okUXPW__5kRzC5gzvkA1xGV98J2fglDLZ2EDEDmvuWsyAQ8Oquzhlk7gDDRGgWDJKpBjioiUQOcYs_eX2ZfpEXg0B9GaJiZJbuMP6OdJ8p_ZxVmAVN03VYuqhjUFYXqMv6zsy9W05UijWxDsuELHjc5Som89YEQ-CzTbVbMjawNbMuh4dnOdb4NBDpI-uTJDvfOtOSm2Pt4tDL2mI-dW2B7f8Owm1v9dRelshtfqh9v43RFLwGjvBSMsTKNbMCVJ50sRkD3JKWv6d2D1N0x2CF1gIxjHHLDOL8Gc","summary":[{"type":"summary_text","text":"**Inspecting registry requirements and documentation**"}]},{"id":"fc_09ab79121c733b56016a589f9e8fb481998a32609108c5f9b2","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading parity requirements\",\"path\":\"traceable-reqs.toml\",\"selector\":\"110-205\"}","call_id":"call_ykhPWPH8wzBXEMAX9pRcJuxn","name":"read"},{"id":"fc_09ab79121c733b56016a589f9e8fc481999a7b9f2f4b0bb9e0","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating evidence tags\",\"pattern\":\"REQ-PARITY-(READY|LIVE|SAFE|STARTUP|TARGETED|UPDATE|PEER)|REQ-HAZARD-ABNORMAL\",\"path\":\"docs;adapter/strings/omp-spt.mjs;tests/omp-extension.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_ruUOP89B6pb3AsdmwOHgCucZ","name":"grep"},{"id":"fc_09ab79121c733b56016a589f9e8fcc8199a57ed3951f758725","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking traceability CLI\",\"command\":\"traceable-reqs --help\",\"cwd\":\".\",\"timeout\":30}","call_id":"call_vBeY1i871C9WjTzsyFn5lL49","name":"bash"}]},"duration":9074.88850000035,"ttft":3860.105100000277,"contextSnapshot":{"promptTokens":102466,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ykhPWPH8wzBXEMAX9pRcJuxn|fc_09ab79121c733b56016a589f9e8fb481998a32609108c5f9b2","toolName":"read","startedAt":"2026-07-16T09:08:47.784Z","args":{"path":"traceable-reqs.toml"},"intent":"Reading parity requirements"},"id":"e7b966ee","parentId":"f3163d59","timestamp":"2026-07-16T09:08:47.784Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ruUOP89B6pb3AsdmwOHgCucZ|fc_09ab79121c733b56016a589f9e8fc481999a7b9f2f4b0bb9e0","toolName":"grep","startedAt":"2026-07-16T09:08:47.784Z","args":{"path":"docs;adapter/strings/omp-spt.mjs;tests/omp-extension.mjs"},"intent":"Locating evidence tags"},"id":"7fce9bed","parentId":"e7b966ee","timestamp":"2026-07-16T09:08:47.784Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_vBeY1i871C9WjTzsyFn5lL49|fc_09ab79121c733b56016a589f9e8fcc8199a57ed3951f758725","toolName":"bash","startedAt":"2026-07-16T09:08:47.784Z","args":{"command":"traceable-reqs --help"},"intent":"Checking traceability CLI"},"id":"80243f65","parentId":"7fce9bed","timestamp":"2026-07-16T09:08:47.784Z"}
{"type":"message","id":"f91f7a74","parentId":"80243f65","timestamp":"2026-07-16T09:08:47.796Z","message":{"role":"toolResult","toolCallId":"call_ykhPWPH8wzBXEMAX9pRcJuxn|fc_09ab79121c733b56016a589f9e8fb481998a32609108c5f9b2","toolName":"read","content":[{"type":"text","text":"[traceable-reqs.toml#5D79]\n107:[[requirements]]\n…\n109:title = \"Each LiveAgent Psyche event runs as one bounded OMP turn with file-backed context and explicit reseed signaling\"\n110:required_stages = [\"doc\", \"impl\", \"unit\"]\n111:\n112:[[requirements]]\n113:id = \"REQ-HISTORY-FETCHER\"\n114:title = \"The history fetcher locates exactly one OMP session and streams its JSONL bytes verbatim\"\n115:required_stages = [\"doc\", \"impl\", \"unit\"]\n116:\n117:[[requirements]]\n118:id = \"REQ-DIST-DIGEST-EXTRACTOR\"\n119:title = \"The OMP digest fetcher maps native session JSONL into the published harness-neutral digest record stream\"\n120:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n121:\n122:[[requirements]]\n123:id = \"REQ-SESSION-ECHO-COMMUNE\"\n124:title = \"The bounded echo-commune role summarizes one OMP session and reports real OMP failures without latching on a locate miss\"\n125:required_stages = [\"doc\", \"impl\", \"unit\"]\n126:\n127:[[requirements]]\n128:id = \"REQ-DIST-MANIFEST-SCHEMA\"\n129:title = \"The omp-spt manifest validates offline against spt-core's published manifest schema\"\n130:required_stages = [\"doc\", \"impl\", \"unit\"]\n131:\n132:[[requirements]]\n133:id = \"REQ-DIST-ADAPTER-RELEASE\"\n134:title = \"One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\"\n135:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n136:\n137:[[requirements]]\n138:id = \"REQ-DIST-BINARY-CONSOLIDATE\"\n139:title = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\n140:required_stages = [\"impl\", \"unit\"]\n141:\n142:[[requirements]]\n143:id = \"REQ-PARITY-READY-ACTIVATION\"\n144:title = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\n145:required_stages = [\"doc\", \"impl\", \"unit\"]\n146:\n147:[[requirements]]\n148:id = \"REQ-PARITY-LIVE-ACTIVATION\"\n149:title = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\n150:required_stages = [\"doc\", \"impl\", \"unit\"]\n151:\n152:[[requirements]]\n153:id = \"REQ-PARITY-LIVE-AUTO-RESUME\"\n154:title = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\n155:required_stages = [\"doc\", \"impl\", \"unit\"]\n156:\n157:[[requirements]]\n158:id = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\n159:title = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\n160:required_stages = [\"doc\", \"impl\", \"unit\"]\n161:\n162:[[requirements]]\n163:id = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\n164:title = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\n165:required_stages = [\"doc\", \"impl\", \"unit\"]\n166:\n167:[[requirements]]\n168:id = \"REQ-PARITY-STARTUP-BRIEF\"\n169:title = \"Activated OMP sessions receive concise identity, roster, messaging, continuity, lifecycle, subnet, and version guidance\"\n170:required_stages = [\"doc\", \"impl\", \"unit\"]\n171:\n172:[[requirements]]\n173:id = \"REQ-PARITY-TARGETED-HINTS\"\n174:title = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\n175:required_stages = [\"doc\", \"impl\", \"unit\"]\n176:\n177:[[requirements]]\n178:id = \"REQ-PARITY-UPDATE-NOTICE\"\n179:title = \"An activated session receives an actionable notice when its spt-core or omp-spt version trails a compatible release\"\n180:required_stages = [\"doc\", \"impl\", \"unit\"]\n181:\n182:[[requirements]]\n183:id = \"REQ-PARITY-COMMUNE-SKILL\"\n184:title = \"A packaged OMP plugin skill authors endpoint-qualified commune continuity drops\"\n185:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n186:\n187:[[requirements]]\n188:id = \"REQ-PARITY-CHECKPOINT\"\n189:title = \"Commune checkpoint mode saves continuity, resets OMP context natively, and wakes the same endpoint without operator intervention\"\n190:required_stages = [\"doc\", \"impl\", \"unit\"]\n191:\n192:[[requirements]]\n193:id = \"REQ-PARITY-SIGNOFF-SKILL\"\n194:title = \"A packaged OMP plugin skill authors final signoff continuity and gracefully shuts down the endpoint\"\n195:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n196:\n197:[[requirements]]\n198:id = \"REQ-PARITY-ROLE-SKILL\"\n199:title = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\n200:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n201:\n202:[[requirements]]\n203:id = \"REQ-PARITY-SETUP\"\n204:title = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\n205:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n206:\n207:[[requirements]]\n208:id = \"REQ-PARITY-PEER-SHORTFORM\"\n…\n211:\n\n[Showing lines 109-208 of 231. Use :209 to continue]"}],"details":{"truncation":{"content":"title = \"Each LiveAgent Psyche event runs as one bounded OMP turn with file-backed context and explicit reseed signaling\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-HISTORY-FETCHER\"\ntitle = \"The history fetcher locates exactly one OMP session and streams its JSONL bytes verbatim\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-DIST-DIGEST-EXTRACTOR\"\ntitle = \"The OMP digest fetcher maps native session JSONL into the published harness-neutral digest record stream\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-SESSION-ECHO-COMMUNE\"\ntitle = \"The bounded echo-commune role summarizes one OMP session and reports real OMP failures without latching on a locate miss\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-DIST-MANIFEST-SCHEMA\"\ntitle = \"The omp-spt manifest validates offline against spt-core's published manifest schema\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-DIST-ADAPTER-RELEASE\"\ntitle = \"One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-DIST-BINARY-CONSOLIDATE\"\ntitle = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\nrequired_stages = [\"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-READY-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-AUTO-RESUME\"\ntitle = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\ntitle = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\ntitle = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-STARTUP-BRIEF\"\ntitle = \"Activated OMP sessions receive concise identity, roster, messaging, continuity, lifecycle, subnet, and version guidance\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-TARGETED-HINTS\"\ntitle = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-UPDATE-NOTICE\"\ntitle = \"An activated session receives an actionable notice when its spt-core or omp-spt version trails a compatible release\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-COMMUNE-SKILL\"\ntitle = \"A packaged OMP plugin skill authors endpoint-qualified commune continuity drops\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-CHECKPOINT\"\ntitle = \"Commune checkpoint mode saves continuity, resets OMP context natively, and wakes the same endpoint without operator intervention\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-SIGNOFF-SKILL\"\ntitle = \"A packaged OMP plugin skill authors final signoff continuity and gracefully shuts down the endpoint\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-ROLE-SKILL\"\ntitle = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-SETUP\"\ntitle = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-PEER-SHORTFORM\"","truncated":true,"truncatedBy":"lines","totalLines":123,"totalBytes":4313,"outputLines":100,"outputBytes":4313,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"[[requirements]]\n…\ntitle = \"Each LiveAgent Psyche event runs as one bounded OMP turn with file-backed context and explicit reseed signaling\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-HISTORY-FETCHER\"\ntitle = \"The history fetcher locates exactly one OMP session and streams its JSONL bytes verbatim\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-DIST-DIGEST-EXTRACTOR\"\ntitle = \"The OMP digest fetcher maps native session JSONL into the published harness-neutral digest record stream\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-SESSION-ECHO-COMMUNE\"\ntitle = \"The bounded echo-commune role summarizes one OMP session and reports real OMP failures without latching on a locate miss\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-DIST-MANIFEST-SCHEMA\"\ntitle = \"The omp-spt manifest validates offline against spt-core's published manifest schema\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-DIST-ADAPTER-RELEASE\"\ntitle = \"One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-DIST-BINARY-CONSOLIDATE\"\ntitle = \"One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\"\nrequired_stages = [\"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-READY-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-ACTIVATION\"\ntitle = \"An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-LIVE-AUTO-RESUME\"\ntitle = \"Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-SAFE-BOUNDARY-DELIVERY\"\ntitle = \"Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY\"\ntitle = \"Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-STARTUP-BRIEF\"\ntitle = \"Activated OMP sessions receive concise identity, roster, messaging, continuity, lifecycle, subnet, and version guidance\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-TARGETED-HINTS\"\ntitle = \"Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-UPDATE-NOTICE\"\ntitle = \"An activated session receives an actionable notice when its spt-core or omp-spt version trails a compatible release\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-COMMUNE-SKILL\"\ntitle = \"A packaged OMP plugin skill authors endpoint-qualified commune continuity drops\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-CHECKPOINT\"\ntitle = \"Commune checkpoint mode saves continuity, resets OMP context natively, and wakes the same endpoint without operator intervention\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-PARITY-SIGNOFF-SKILL\"\ntitle = \"A packaged OMP plugin skill authors final signoff continuity and gracefully shuts down the endpoint\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-ROLE-SKILL\"\ntitle = \"A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-SETUP\"\ntitle = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-PEER-SHORTFORM\"\n…\n","startLine":107,"lineNumbers":[107,null,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,null,211]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\traceable-reqs.toml"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":231,"totalBytes":4313,"outputLines":100,"outputBytes":4313,"shownRange":{"start":109,"end":208},"nextOffset":209}}},"isError":false,"timestamp":1784192927795}}
{"type":"message","id":"a14de443","parentId":"f91f7a74","timestamp":"2026-07-16T09:08:47.816Z","message":{"role":"toolResult","toolCallId":"call_vBeY1i871C9WjTzsyFn5lL49|fc_09ab79121c733b56016a589f9e8fcc8199a57ed3951f758725","toolName":"bash","content":[{"type":"text","text":"Trace requirements via [stage->REQ-ID] tags\n\nUsage: traceable-reqs.exe <COMMAND>\n\nCommands:\n  list    \n  trace   \n  check   \n  lint    \n  review  \n  help    Print this message or the help of the given subcommand(s)\n\nOptions:\n  -h, --help     Print help\n  -V, --version  Print version\n\n\nWall time: 0.03 seconds"}],"details":{"timeoutSeconds":30,"wallTimeMs":31.57730000000447},"isError":false,"timestamp":1784192927815}}
{"type":"message","id":"c5cb5c98","parentId":"a14de443","timestamp":"2026-07-16T09:08:47.972Z","message":{"role":"toolResult","toolCallId":"call_ruUOP89B6pb3AsdmwOHgCucZ|fc_09ab79121c733b56016a589f9e8fc481999a7b9f2f4b0bb9e0","toolName":"grep","content":[{"type":"text","text":"# docs/\n## PARITY.md#2CFD\n 24:\n*25:<!-- [doc->REQ-PARITY-READY-ACTIVATION] -->\n*26:<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n*27:<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\n 28:Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n 29:commands with argument completion or native selection dialogs. Explicit live\n 30:auto-resume selects the most-recent compatible live identity; ordinary\n...\n 33:\n*34:<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\n 35:Messages accepted during an active OMP turn enter at the first proven boundary\n 36:before the next tool or model continuation. Custody and arrival order remain\n 37:intact; a turn with no injectable boundary falls back to ordinary next-turn\n...\n 39:\n*40:<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\n 41:Cancelled, interrupted, and failed turns settle affected custody and restore\n 42:receivability automatically. Only exhausted listener recovery closes the\n 43:endpoint.\n 44:\n*45:<!-- [doc->REQ-PARITY-STARTUP-BRIEF] -->\n*46:<!-- [doc->REQ-PARITY-TARGETED-HINTS] -->\n*47:<!-- [doc->REQ-PARITY-UPDATE-NOTICE] -->\n 48:Activated sessions receive a concise startup brief for identity, roster,\n 49:messaging, continuity, lifecycle, subnet, version, and update operations.\n 50:Targeted hints cover clear live-activation, identity, messaging, subnet, and\n...\n 68:\n*69:<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\n 70:Assistant output may dispatch the explicit cross-harness peer-message shortform\n 71:`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\n 72:Normal outbound messaging, roster, stop/shutdown, version, and subnet commands\n\n# adapter/strings/\n## omp-spt.mjs#9CB1\n 247:\n*248:// [impl->REQ-PARITY-PEER-SHORTFORM]\n 249:export function parsePeerShortforms(text) {\n 250:\tconst source = String(text ?? \"\");\n 251:\tconst prose = maskMarkdownCode(source);\n...\n 804:\t\t}\n*805:\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n 806:\t\tasync function detectUpdateNotices() {\n 807:\t\t\tconst [coreVersionResult, notificationsResult, adapterVersionResult, latestAdapterResult] =\n 808:\t\t\t\tawait Promise.allSettled([\n...\n 935:\n*936:\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\n 937:\t\tasync function chooseAutoResume(ctx) {\n 938:\t\t\tif (!ctx.hasUI) {\n 939:\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\n...\n 1003:\n*1004:\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\n*1005:\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\n 1006:\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n 1007:\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\n 1008:\t\t\t\tctx.ui.notify(\n...\n 1744:\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n*1745:\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n 1746:\t\tpi.on(\"context\", (event) => {\n 1747:\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n 1748:\t\t\tturnAssistantBaseline ??= assistantBaseline;\n...\n 1779:\t\t});\n*1780:\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n*1781:\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n*1782:\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n 1783:\t\tpi.on(\"before_agent_start\", async (event) => {\n 1784:\t\t\tif (!activated || !id || stopping) return;\n 1785:\t\t\tconst additions = [];\n...\n 1802:\n*1803:\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n 1804:\t\tasync function dispatchShortforms(assistantOutput) {\n 1805:\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n 1806:\t\t\tif (shortforms.length === 0 || stopping) return;\n...\n 1839:\n*1840:\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n 1841:\t\tasync function completeTurn(event) {\n 1842:\t\t\tagentActive = false;\n 1843:\t\t\tdesiredState = \"idle\";\n\n# tests/\n## omp-extension.mjs#535B\n 1432:\n*1433:// [unit->REQ-PARITY-READY-ACTIVATION]\n*1434:// [unit->REQ-PARITY-LIVE-ACTIVATION]\n 1435:async function testNativeActivationCommandsAndErrors() {\n 1436:\tconst inert = createHarness({ id: null });\n 1437:\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\n...\n 1526:\n*1527:// [unit->REQ-PARITY-READY-ACTIVATION]\n 1528:async function testNativeActivationSelectionAndCompletion() {\n 1529:\tconst harness = createHarness({\n 1530:\t\tid: null,\n...\n 1601:\n*1602:// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n 1603:async function testExplicitLiveAutoResume() {\n 1604:\tconst activity = {\n 1605:\t\told: \"2026-07-10T00:00:00.000Z\",\n...\n 1683:\n*1684:// [unit->REQ-PARITY-STARTUP-BRIEF]\n*1685:// [unit->REQ-PARITY-TARGETED-HINTS]\n*1686:// [unit->REQ-PARITY-UPDATE-NOTICE]\n 1687:async function testStartupBriefHintsAndUpdateNotices() {\n 1688:\tconst harness = createHarness({\n 1689:\t\tcheckUpdates: true,\n...\n 1771:\n*1772:// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n*1773:// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n 1774:async function testActiveTurnBoundaryDeliveryAndFallback() {\n 1775:\tconst harness = createHarness();\n 1776:\tawait harness.emit(\"session_start\");\n...\n 1824:\n*1825:// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n 1826:async function testAbnormalTurnsRestoreReceivability() {\n 1827:\tfor (const [label, completionEvent] of [\n 1828:\t\t[\"cancelled\", \"session_stop\"],\n...\n 1858:\n*1859:// [unit->REQ-PARITY-PEER-SHORTFORM]\n 1860:async function testPeerShortformParsingAndDispatch() {\n 1861:\tassert.deepEqual(\n 1862:\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map("}],"details":{"scopePath":"docs, adapter/strings/omp-spt.mjs, tests/omp-extension.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":31,"fileCount":3,"files":["docs/PARITY.md","adapter/strings/omp-spt.mjs","tests/omp-extension.mjs"],"fileMatches":[{"path":"docs/PARITY.md","count":9},{"path":"adapter/strings/omp-spt.mjs","count":11},{"path":"tests/omp-extension.mjs","count":11}],"truncated":false,"displayContent":"# docs/\n## PARITY.md#2CFD\n 24│\n*25│<!-- [doc->REQ-PARITY-READY-ACTIVATION] -->\n*26│<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n*27│<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\n 28│Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n 29│commands with argument completion or native selection dialogs. Explicit live\n 30│auto-resume selects the most-recent compatible live identity; ordinary\n   │...\n 33│\n*34│<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\n 35│Messages accepted during an active OMP turn enter at the first proven boundary\n 36│before the next tool or model continuation. Custody and arrival order remain\n 37│intact; a turn with no injectable boundary falls back to ordinary next-turn\n   │...\n 39│\n*40│<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\n 41│Cancelled, interrupted, and failed turns settle affected custody and restore\n 42│receivability automatically. Only exhausted listener recovery closes the\n 43│endpoint.\n 44│\n*45│<!-- [doc->REQ-PARITY-STARTUP-BRIEF] -->\n*46│<!-- [doc->REQ-PARITY-TARGETED-HINTS] -->\n*47│<!-- [doc->REQ-PARITY-UPDATE-NOTICE] -->\n 48│Activated sessions receive a concise startup brief for identity, roster,\n 49│messaging, continuity, lifecycle, subnet, version, and update operations.\n 50│Targeted hints cover clear live-activation, identity, messaging, subnet, and\n   │...\n 68│\n*69│<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\n 70│Assistant output may dispatch the explicit cross-harness peer-message shortform\n 71│`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\n 72│Normal outbound messaging, roster, stop/shutdown, version, and subnet commands\n\n# adapter/strings/\n## omp-spt.mjs#9CB1\n  247│\n *248│// [impl->REQ-PARITY-PEER-SHORTFORM]\n  249│export function parsePeerShortforms(text) {\n  250│\tconst source = String(text ?? \"\");\n  251│\tconst prose = maskMarkdownCode(source);\n     │...\n  804│\t\t}\n *805│\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n  806│\t\tasync function detectUpdateNotices() {\n  807│\t\t\tconst [coreVersionResult, notificationsResult, adapterVersionResult, latestAdapterResult] =\n  808│\t\t\t\tawait Promise.allSettled([\n     │...\n  935│\n *936│\t\t// [impl->REQ-PARITY-LIVE-AUTO-RESUME]\n  937│\t\tasync function chooseAutoResume(ctx) {\n  938│\t\t\tif (!ctx.hasUI) {\n  939│\t\t\t\tctx.ui.notify(\"`/live --auto` requires native confirmation UI\", \"error\");\n     │...\n 1003│\n*1004│\t\t// [impl->REQ-PARITY-READY-ACTIVATION]\n*1005│\t\t// [impl->REQ-PARITY-LIVE-ACTIVATION]\n 1006│\t\tasync function activateEndpoint(nextId, type, ctx, options = {}) {\n 1007│\t\t\tif (!endpointIdPattern.test(nextId ?? \"\")) {\n 1008│\t\t\t\tctx.ui.notify(\n     │...\n 1744│\t\t// [impl->REQ-OMP-MESSAGE-CONTEXT]\n*1745│\t\t// [impl->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n 1746│\t\tpi.on(\"context\", (event) => {\n 1747│\t\t\tconst assistantBaseline = assistantMessageCount(event.messages);\n 1748│\t\t\tturnAssistantBaseline ??= assistantBaseline;\n     │...\n 1779│\t\t});\n*1780│\t\t// [impl->REQ-PARITY-STARTUP-BRIEF]\n*1781│\t\t// [impl->REQ-PARITY-TARGETED-HINTS]\n*1782│\t\t// [impl->REQ-PARITY-UPDATE-NOTICE]\n 1783│\t\tpi.on(\"before_agent_start\", async (event) => {\n 1784│\t\t\tif (!activated || !id || stopping) return;\n 1785│\t\t\tconst additions = [];\n     │...\n 1802│\n*1803│\t\t// [impl->REQ-PARITY-PEER-SHORTFORM]\n 1804│\t\tasync function dispatchShortforms(assistantOutput) {\n 1805│\t\t\tconst shortforms = parsePeerShortforms(assistantOutput);\n 1806│\t\t\tif (shortforms.length === 0 || stopping) return;\n     │...\n 1839│\n*1840│\t\t// [impl->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n 1841│\t\tasync function completeTurn(event) {\n 1842│\t\t\tagentActive = false;\n 1843│\t\t\tdesiredState = \"idle\";\n\n# tests/\n## omp-extension.mjs#535B\n 1432│\n*1433│// [unit->REQ-PARITY-READY-ACTIVATION]\n*1434│// [unit->REQ-PARITY-LIVE-ACTIVATION]\n 1435│async function testNativeActivationCommandsAndErrors() {\n 1436│\tconst inert = createHarness({ id: null });\n 1437│\tassert.deepEqual([...inert.commands.keys()], [\"ready\", \"live\"]);\n     │...\n 1526│\n*1527│// [unit->REQ-PARITY-READY-ACTIVATION]\n 1528│async function testNativeActivationSelectionAndCompletion() {\n 1529│\tconst harness = createHarness({\n 1530│\t\tid: null,\n     │...\n 1601│\n*1602│// [unit->REQ-PARITY-LIVE-AUTO-RESUME]\n 1603│async function testExplicitLiveAutoResume() {\n 1604│\tconst activity = {\n 1605│\t\told: \"2026-07-10T00:00:00.000Z\",\n     │...\n 1683│\n*1684│// [unit->REQ-PARITY-STARTUP-BRIEF]\n*1685│// [unit->REQ-PARITY-TARGETED-HINTS]\n*1686│// [unit->REQ-PARITY-UPDATE-NOTICE]\n 1687│async function testStartupBriefHintsAndUpdateNotices() {\n 1688│\tconst harness = createHarness({\n 1689│\t\tcheckUpdates: true,\n     │...\n 1771│\n*1772│// [unit->REQ-PARITY-SAFE-BOUNDARY-DELIVERY]\n*1773│// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n 1774│async function testActiveTurnBoundaryDeliveryAndFallback() {\n 1775│\tconst harness = createHarness();\n 1776│\tawait harness.emit(\"session_start\");\n     │...\n 1824│\n*1825│// [unit->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY]\n 1826│async function testAbnormalTurnsRestoreReceivability() {\n 1827│\tfor (const [label, completionEvent] of [\n 1828│\t\t[\"cancelled\", \"session_stop\"],\n     │...\n 1858│\n*1859│// [unit->REQ-PARITY-PEER-SHORTFORM]\n 1860│async function testPeerShortformParsingAndDispatch() {\n 1861│\tassert.deepEqual(\n 1862│\t\tparsePeerShortforms(\"Before @<alpha,beta hello there @> after @<gamma second\\nline @>\").map("},"isError":false,"timestamp":1784192927972}}
{"type":"message","id":"8d50fc2f","parentId":"c5cb5c98","timestamp":"2026-07-16T09:09:02.276Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning to read from line 208 onward**"},{"type":"toolCall","id":"call_cvWd8nN0G6B7I2dHDZPc6YzF|fc_09ab79121c733b56016a589fa7703481998f14584d6abb87d3","name":"read","arguments":{"i":"Reading final parity requirements","path":"traceable-reqs.toml","selector":"203-231"}},{"type":"toolCall","id":"call_oZavPbkIrTjet8v0tW82LaiP|fc_09ab79121c733b56016a589fa7704c81998734b6f766d52cb3","name":"grep","arguments":{"i":"Locating checkpoint evidence","pattern":"REQ-PARITY-CHECKPOINT","path":"docs;adapter/strings/omp-spt.mjs;tests/omp-extension.mjs","selector":null,"case":true,"gitignore":true,"skip":null}},{"type":"toolCall","id":"call_3A57DevcHPt7XigO7YQUhA2g|fc_09ab79121c733b56016a589fa7718c8199844dd2e13881c356","name":"grep","arguments":{"i":"Locating ADR requirement tags","pattern":"doc->REQ-PARITY|doc->REQ-HAZARD","path":"docs/adr","selector":null,"case":true,"gitignore":true,"skip":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":9966,"output":195,"cacheRead":95744,"cacheWrite":0,"totalTokens":105905,"reasoningTokens":18,"cost":{"input":0.049830000000000006,"output":0.00585,"cacheRead":0.047872,"cacheWrite":0,"total":0.103552}},"stopReason":"toolUse","timestamp":1784192928026,"responseId":"resp_09ab79121c733b56016a589fa0543c8199b8e4a1f0bfb1f842","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589fa3c05081999ed386ecd7292822","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ-nHLd7EL0OX0pMDkaVEMzJUcRrmohrZStn8_kJ-GLgdvnI-M377hTca866jPdqwHREOzVz9sZLsAz7nmf0oXzhj4FJ3fetDRLce4lyIa01qMWbTrIw1IRoZL48KGVTM56WsW6DpRVkD_7uz2hLQXe2VhoHbtAJdJEC8Z1y_2_zVn0aMlcg-8vzBYBz3Z2qTq-NkIAzoXRd9YUQ7CG1xxjqDJSA8ngheuANsKD5O7g8CE3ntW5O8_b4Ftopea84xhswpg5iCHG9D-BKlKLCBDwr6P_tj32EiXTnWm73MVo4A8OLu4WZby0Fk1mOjGf5b0_7nSCzy6cwLomEuhOfDEZmLVa0dckhAode50imzQbwtk2Ep9-5ntNhEAuY8KBTugoitetq4ZV_nclrMokKrmtLQauAOyPkQMtz5o_ea1rldTtZdHvpzdxSZk2qHSDOpiVI241lmv3LgbhjKYYydVoeMVOqkuxinVMcmajYz4-LaI65bbEF6RhuSZXFMQShKljSean2REjc8vkrdU0zUcJrvHGQ0lvf06IBIK309nq24fS7-3V03Io2x8QOjakCp4Xn5dwUopu6FQcLAfkqxehSd1BAurz09SFpVLCrRSFnfNFQxpLtD9TUWm9vV5-oaWvRF-gbkGGHGIE7myhMYojWN72bh0Hh2R2FHjSVvw-dG9x4vp9lPJhpKzx9yNu9xaOSvUjiFQfmsI8DDxvoIQ_2_RX1EpEDE3rgdyAoFYj57XEkkjaoqfPRt5K12wk0f2F63wzs19HjQI2MNYoZ-vDUGtRbSph5Dt5aC1N-axI4eydFYLw1VAwPdpKlpWdZB5LsVar1zQaterK-Chydr9j_NLX2E0pAI24-lpxg0COwzD3DIJdbXMBISdKtzTEdkOzDk0KMLIiIgJL9mGhdSZnHWTKAOTwRrcDag9jzSV4YJfQef0vgFeA7uAKgLQVVJVNmQkj8o_hPiNQylUZ3uJMm79L1kjdjKZEdoonzl5pUE8TU0PETKUs8-VqYDjhJa7fC","summary":[{"type":"summary_text","text":"**Planning to read from line 208 onward**"}]},{"id":"fc_09ab79121c733b56016a589fa7703481998f14584d6abb87d3","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading final parity requirements\",\"path\":\"traceable-reqs.toml\",\"selector\":\"203-231\"}","call_id":"call_cvWd8nN0G6B7I2dHDZPc6YzF","name":"read"},{"id":"fc_09ab79121c733b56016a589fa7704c81998734b6f766d52cb3","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating checkpoint evidence\",\"pattern\":\"REQ-PARITY-CHECKPOINT\",\"path\":\"docs;adapter/strings/omp-spt.mjs;tests/omp-extension.mjs\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_oZavPbkIrTjet8v0tW82LaiP","name":"grep"},{"id":"fc_09ab79121c733b56016a589fa7718c8199844dd2e13881c356","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating ADR requirement tags\",\"pattern\":\"doc->REQ-PARITY|doc->REQ-HAZARD\",\"path\":\"docs/adr\",\"selector\":null,\"case\":true,\"gitignore\":true,\"skip\":null}","call_id":"call_3A57DevcHPt7XigO7YQUhA2g","name":"grep"}]},"duration":14249.570599999279,"ttft":3700.8268999997526,"contextSnapshot":{"promptTokens":105710,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_cvWd8nN0G6B7I2dHDZPc6YzF|fc_09ab79121c733b56016a589fa7703481998f14584d6abb87d3","toolName":"read","startedAt":"2026-07-16T09:09:02.276Z","args":{"path":"traceable-reqs.toml"},"intent":"Reading final parity requirements"},"id":"3aa7ad40","parentId":"8d50fc2f","timestamp":"2026-07-16T09:09:02.276Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_oZavPbkIrTjet8v0tW82LaiP|fc_09ab79121c733b56016a589fa7704c81998734b6f766d52cb3","toolName":"grep","startedAt":"2026-07-16T09:09:02.277Z","args":{"path":"docs;adapter/strings/omp-spt.mjs;tests/omp-extension.mjs"},"intent":"Locating checkpoint evidence"},"id":"7f411981","parentId":"3aa7ad40","timestamp":"2026-07-16T09:09:02.277Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_3A57DevcHPt7XigO7YQUhA2g|fc_09ab79121c733b56016a589fa7718c8199844dd2e13881c356","toolName":"grep","startedAt":"2026-07-16T09:09:02.277Z","args":{"path":"docs/adr"},"intent":"Locating ADR requirement tags"},"id":"57f9a6d5","parentId":"7f411981","timestamp":"2026-07-16T09:09:02.277Z"}
{"type":"message","id":"f15604d3","parentId":"57f9a6d5","timestamp":"2026-07-16T09:09:02.281Z","message":{"role":"toolResult","toolCallId":"call_cvWd8nN0G6B7I2dHDZPc6YzF|fc_09ab79121c733b56016a589fa7703481998f14584d6abb87d3","toolName":"read","content":[{"type":"text","text":"[traceable-reqs.toml#5D79]\n202:[[requirements]]\n203:id = \"REQ-PARITY-SETUP\"\n204:title = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\n205:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n206:\n207:[[requirements]]\n208:id = \"REQ-PARITY-PEER-SHORTFORM\"\n209:title = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"\n210:required_stages = [\"doc\", \"impl\", \"unit\"]\n211:\n212:[[requirements]]\n213:id = \"REQ-DIST-LINUX-MUSL\"\n214:title = \"The release ships and natively accepts a static x86_64 Linux musl helper compatibility tier\"\n215:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n216:\n217:[[requirements]]\n218:id = \"REQ-DIST-VERSION-CONSISTENCY\"\n219:title = \"Manifest version is canonical and release gates reject disagreement in helper, changelog, and versioned public documentation\"\n220:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n221:\n222:[[requirements]]\n223:id = \"REQ-DOCS-PUBLISH-GATE\"\n224:title = \"Local deterministic docs drift checks gate changes and the same checks gate GitHub Pages publication\"\n225:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n226:\n227:[[requirements]]\n228:id = \"REQ-DIST-RELEASE-EVIDENCE\"\n229:title = \"Every supported target retains a machine-readable release record covering source identity, digests, acquisition, and native acceptance\"\n230:required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n231:"}],"details":{"displayContent":{"text":"[[requirements]]\nid = \"REQ-PARITY-SETUP\"\ntitle = \"Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-PARITY-PEER-SHORTFORM\"\ntitle = \"OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\"\nrequired_stages = [\"doc\", \"impl\", \"unit\"]\n\n[[requirements]]\nid = \"REQ-DIST-LINUX-MUSL\"\ntitle = \"The release ships and natively accepts a static x86_64 Linux musl helper compatibility tier\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-DIST-VERSION-CONSISTENCY\"\ntitle = \"Manifest version is canonical and release gates reject disagreement in helper, changelog, and versioned public documentation\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-DOCS-PUBLISH-GATE\"\ntitle = \"Local deterministic docs drift checks gate changes and the same checks gate GitHub Pages publication\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n\n[[requirements]]\nid = \"REQ-DIST-RELEASE-EVIDENCE\"\ntitle = \"Every supported target retains a machine-readable release record covering source identity, digests, acquisition, and native acceptance\"\nrequired_stages = [\"doc\", \"impl\", \"unit\", \"int\"]\n","startLine":202,"lineNumbers":[202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\traceable-reqs.toml"}}},"isError":false,"timestamp":1784192942280}}
{"type":"message","id":"175a621c","parentId":"f15604d3","timestamp":"2026-07-16T09:09:02.281Z","message":{"role":"toolResult","toolCallId":"call_3A57DevcHPt7XigO7YQUhA2g|fc_09ab79121c733b56016a589fa7718c8199844dd2e13881c356","toolName":"grep","content":[{"type":"text","text":"# docs/adr/\n## 0003-psyche-is-a-constrained-auto-approving-companion.md#3886\n 1:<!-- [doc->REQ-SKILL-LIVE] -->\n*2:<!-- [doc->REQ-HAZARD-PSYCHE-PERMS-DEADLOCK] -->\n 3:# The Psyche runs as a constrained, auto-approving companion (legacy owl parity)\n 4:\n 5:## Status"}],"details":{"scopePath":"docs/adr","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\docs\\adr","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":1,"fileCount":1,"files":["docs/adr/0003-psyche-is-a-constrained-auto-approving-companion.md"],"fileMatches":[{"path":"docs/adr/0003-psyche-is-a-constrained-auto-approving-companion.md","count":1}],"truncated":false,"displayContent":"# docs/adr/\n## 0003-psyche-is-a-constrained-auto-approving-companion.md#3886\n 1│<!-- [doc->REQ-SKILL-LIVE] -->\n*2│<!-- [doc->REQ-HAZARD-PSYCHE-PERMS-DEADLOCK] -->\n 3│# The Psyche runs as a constrained, auto-approving companion (legacy owl parity)\n 4│\n 5│## Status"},"isError":false,"timestamp":1784192942281}}
{"type":"message","id":"6d6e85e0","parentId":"175a621c","timestamp":"2026-07-16T09:09:02.284Z","message":{"role":"toolResult","toolCallId":"call_oZavPbkIrTjet8v0tW82LaiP|fc_09ab79121c733b56016a589fa7704c81998734b6f766d52cb3","toolName":"grep","content":[{"type":"text","text":"# docs/\n## PARITY.md#2CFD\n 54:<!-- [doc->REQ-PARITY-COMMUNE-SKILL] -->\n*55:<!-- [doc->REQ-PARITY-CHECKPOINT] -->\n 56:<!-- [doc->REQ-PARITY-SIGNOFF-SKILL] -->\n 57:<!-- [doc->REQ-PARITY-ROLE-SKILL] -->\n 58:Public OMP `omp-plugins` packaging supplies model-driven skills for commune,\n\n# adapter/strings/\n## omp-spt.mjs#9CB1\n 1140:\n*1141:\t\t// [impl->REQ-PARITY-CHECKPOINT]\n 1142:\t\tpi.registerTool({\n 1143:\t\t\tname: \"spt_checkpoint\",\n 1144:\t\t\tlabel: \"SPT Checkpoint\",\n\n# tests/\n## omp-extension.mjs#535B\n 1967:\n*1968:// [unit->REQ-PARITY-CHECKPOINT]\n 1969:async function testNativeCheckpointTool() {\n 1970:\tconst compactGate = deferred();\n 1971:\tconst harness = createHarness({"}],"details":{"scopePath":"docs, adapter/strings/omp-spt.mjs, tests/omp-extension.mjs","searchPath":"C:\\Users\\decid\\Documents\\projects\\omp-spt","cwd":"C:\\Users\\decid\\Documents\\projects\\omp-spt","matchCount":3,"fileCount":3,"files":["docs/PARITY.md","adapter/strings/omp-spt.mjs","tests/omp-extension.mjs"],"fileMatches":[{"path":"docs/PARITY.md","count":1},{"path":"adapter/strings/omp-spt.mjs","count":1},{"path":"tests/omp-extension.mjs","count":1}],"truncated":false,"displayContent":"# docs/\n## PARITY.md#2CFD\n 54│<!-- [doc->REQ-PARITY-COMMUNE-SKILL] -->\n*55│<!-- [doc->REQ-PARITY-CHECKPOINT] -->\n 56│<!-- [doc->REQ-PARITY-SIGNOFF-SKILL] -->\n 57│<!-- [doc->REQ-PARITY-ROLE-SKILL] -->\n 58│Public OMP `omp-plugins` packaging supplies model-driven skills for commune,\n\n# adapter/strings/\n## omp-spt.mjs#9CB1\n 1140│\n*1141│\t\t// [impl->REQ-PARITY-CHECKPOINT]\n 1142│\t\tpi.registerTool({\n 1143│\t\t\tname: \"spt_checkpoint\",\n 1144│\t\t\tlabel: \"SPT Checkpoint\",\n\n# tests/\n## omp-extension.mjs#535B\n 1967│\n*1968│// [unit->REQ-PARITY-CHECKPOINT]\n 1969│async function testNativeCheckpointTool() {\n 1970│\tconst compactGate = deferred();\n 1971│\tconst harness = createHarness({"},"isError":false,"timestamp":1784192942284}}
{"type":"message","id":"97d825af","parentId":"6d6e85e0","timestamp":"2026-07-16T09:09:14.627Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Verifying stage activation parity**"},{"type":"toolCall","id":"call_t2Bcz1KsDSEchYFc08dpHhe3|fc_09ab79121c733b56016a589fb74cbc81999b61af4474db4902","name":"read","arguments":{"i":"Reading parity evidence prose","path":"docs/PARITY.md","selector":"20-80"}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7832,"output":137,"cacheRead":98816,"cacheWrite":0,"totalTokens":106785,"reasoningTokens":101,"cost":{"input":0.03916,"output":0.00411,"cacheRead":0.049408,"cacheWrite":0,"total":0.09267800000000001}},"stopReason":"toolUse","timestamp":1784192942290,"responseId":"resp_09ab79121c733b56016a589faed260819991405197474e2b4b","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589fb2c638819996441d636d1e93a1","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ-3Wyjr2IO47UmYYoDoBW0IdxQb3CJPwZ1KoWw4bLbnjnU1Id6u9ItG0lv2m30jt4fnMP1T92AN6d2eg4kEw6OHU-ame6SKArKhAxjMOkqLwWxpKlObjXmQHKwRln_ON8LiUrMHJ9vhx4jvQHePtN_kb7J9mRcwY5eeK-ThjEoiQU2ChrejGL64fWk_uVkPgn7XxYN-aHvSmIfMiB4QnCWNs3ApUWxYRqpfKsg9GKz3FKaTnEraRNwsMZp324hUQxdLQYj1GTULtRMQ0-NxoTVsY3p800ZyZoRhW9_rnnWoeqysINABj-3skku-9Bd7RzcJmxBeBu_uHA15VvRgrO0dfRCcoWxOwpjUChKFYWIEHnaLKPDtP2nbklvGRoi6ui7LZ77Qtxc-hmu5v-nHz-FewMveZlHoWeMqMws1U4TT6lnPW317xMEsCiTSahQDZzbmeQxRlu296Wc3G7d1K-a1oj9NbERUpngNXV0LeAjiKY-7rre6moXyMip6CINUaCIxer3ZIB7-OceEjIUphYSDoLecnUW6wfvnGvyHIxYk6GKd8JlrDGBllWckds6KFTWKoR0SMZFQxqdkb1mI5sYkI4fU28B-q4bka9zPVd_LL8DwK6UWW5tgJ84zzJFpRb4vzaATkaFnm8dspcT16NzY5T4Dv-M-5wGrw5_I-SKR7aPTV2PJ8HenhSMviTjNgma-F92PZ0DdGpHJBvn4CpvsbC_fu46A2Fqz1goeZkLOAp1pOyy7TVlDJBTzpnma9ZSmHOPa38dN37ghhGs0TFtU_UU8Nd0I13yFdb77SeRDnMUnzkjXf32ZlPnLk71zFspM5Mxr5dUUmijgIag7CFjtR46eqnK04pjhQoi-5WLvw6T4h1oNNYigqXp43eXew3DEeFlxZF2K_3LbWVP0iRGMOk_soBGIrgaa6TeNVo3YEJYfCbavXXYx1q393K6bnfesa143W4Gqcpaif4avU43oNa9zCMgZE1LT0RHGUHZ1Kjbt9wRyolcfKxr9Em1roixOqGt9V9Psq6txI6yXj4ioaESZvTi1EtSiLJpCdbujfIJiVbx4xSyJsktQlk-BJLgQFzsOKt9BFBoKI8-nEAfB_FcmwTGNyXGCZ-KB2V9MMNtDEqwhRWTHK2IF8MfJwp8hPyGH2bka-TJ7iHSF6SqaO7OVEWq1o_XyTOvdeKwmbmdIwFzUzVEG99V6bYEdz_aNl0qMdrbSs-QcVNu_QdWSUQHmkKGZqyLR805_hwTTLvokYGj9UVyKDtLvurevqkUDVyTAvQWdi99x7uJO80kpVbiBppq2ErUx6BcIY7SNjjlt8PZESkgFFxSTv5KZ6W26Qf10fyUZNSXkVYDTxFvAdlTuujLNr59XBuwpu15S_c67WjNqaY81PklHbFgtjjEgofesz3ToVV8gm3HZGUEv6YvvyiKovz8auNW7TAWe0KAg_Anm2H4HhZ1dW8Qn7WF25UAcZTFyiK0Wo7mf74QQcI9BCX_LLQZNxDF-LtbMu5XSRgR1q0puv77KLzPVn0L3s6xk9SZthjKhpK_j7TDt8hmxiPcKf-O1nJ9vOWO-agpDRmkgoMVYGqQQfkL0WHqM7K5TeK1SrorI68szR-PNZA==","summary":[{"type":"summary_text","text":"**Verifying stage activation parity**"}]},{"id":"fc_09ab79121c733b56016a589fb74cbc81999b61af4474db4902","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading parity evidence prose\",\"path\":\"docs/PARITY.md\",\"selector\":\"20-80\"}","call_id":"call_t2Bcz1KsDSEchYFc08dpHhe3","name":"read"}]},"duration":12336.457500000484,"ttft":4458.651000000536,"contextSnapshot":{"promptTokens":106648,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_t2Bcz1KsDSEchYFc08dpHhe3|fc_09ab79121c733b56016a589fb74cbc81999b61af4474db4902","toolName":"read","startedAt":"2026-07-16T09:09:14.627Z","args":{"path":"docs/PARITY.md"},"intent":"Reading parity evidence prose"},"id":"9fa5cf52","parentId":"97d825af","timestamp":"2026-07-16T09:09:14.627Z"}
{"type":"message","id":"a29101de","parentId":"9fa5cf52","timestamp":"2026-07-16T09:09:14.631Z","message":{"role":"toolResult","toolCallId":"call_t2Bcz1KsDSEchYFc08dpHhe3|fc_09ab79121c733b56016a589fb74cbc81999b61af4474db4902","toolName":"read","content":[{"type":"text","text":"[PARITY.md#2CFD]\n9:## Proven shared endpoint surface\n…\n18:OMP keeps its stronger native invariants: immutable endpoint/session binding,\n19:one bounded custody queue, finite listener recovery, fail-closed exhaustion,\n20:real OMP executable validation, and explicit failures rather than silent empty\n21:outcomes. Capability parity does not weaken those guarantees.\n22:\n23:## Agent-facing parity decisions\n24:\n25:<!-- [doc->REQ-PARITY-READY-ACTIVATION] -->\n26:<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n27:<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\n28:Ordinary OMP sessions gain extension-native `/ready` and `/live` activation\n29:commands with argument completion or native selection dialogs. Explicit live\n30:auto-resume selects the most-recent compatible live identity; ordinary\n31:activation never guesses silently. The extension binds the current session and\n32:owns the authenticated listener, after which binding is immutable.\n33:\n34:<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\n35:Messages accepted during an active OMP turn enter at the first proven boundary\n36:before the next tool or model continuation. Custody and arrival order remain\n37:intact; a turn with no injectable boundary falls back to ordinary next-turn\n38:delivery rather than interruption.\n39:\n40:<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\n41:Cancelled, interrupted, and failed turns settle affected custody and restore\n42:receivability automatically. Only exhausted listener recovery closes the\n43:endpoint.\n44:\n45:<!-- [doc->REQ-PARITY-STARTUP-BRIEF] -->\n46:<!-- [doc->REQ-PARITY-TARGETED-HINTS] -->\n47:<!-- [doc->REQ-PARITY-UPDATE-NOTICE] -->\n48:Activated sessions receive a concise startup brief for identity, roster,\n49:messaging, continuity, lifecycle, subnet, version, and update operations.\n50:Targeted hints cover clear live-activation, identity, messaging, subnet, and\n51:checkpoint intent. Available compatible spt-core or adapter updates produce an\n52:actionable notice.\n53:\n54:<!-- [doc->REQ-PARITY-COMMUNE-SKILL] -->\n55:<!-- [doc->REQ-PARITY-CHECKPOINT] -->\n56:<!-- [doc->REQ-PARITY-SIGNOFF-SKILL] -->\n57:<!-- [doc->REQ-PARITY-ROLE-SKILL] -->\n58:Public OMP `omp-plugins` packaging supplies model-driven skills for commune,\n59:signoff, and durable-role inspection/editing. Commune checkpoint mode saves\n60:continuity, resets OMP context through native session APIs, and wakes the same\n61:endpoint without operator intervention.\n62:\n63:<!-- [doc->REQ-PARITY-SETUP] -->\n64:Setup is hybrid: an extension-native command owns deterministic probes and\n65:activation, while a packaged skill owns diagnosis, repair strategy, published\n66:installer use, subnet onboarding, and explicit operator handoffs for\n67:authentication or elevation.\n68:\n69:<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\n70:Assistant output may dispatch the explicit cross-harness peer-message shortform\n71:`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\n72:Normal outbound messaging, roster, stop/shutdown, version, and subnet commands\n73:are taught through setup or startup context rather than duplicated as skills.\n74:\n75:OMP's native provider/profile routing satisfies alternate provider, account,\n76:and model routing parity; no `omp-spt:<profile>` analogue of Claude's CCS\n77:overlay is required.\n78:\n79:## Release-target parity\n80:\n81:<!-- [doc->REQ-DIST-LINUX-MUSL] -->\n82:The supported target set is Windows x86-64 MSVC, GNU Linux x86-64, and a static\n83:Linux x86-64 musl helper compatibility tier for OMP-capable hosts where the GNU\n…\n86:OMP itself is unavailable.\n…\n104:\n\n[Showing lines 19-83 of 129. Use :84 to continue]"}],"details":{"truncation":{"content":"one bounded custody queue, finite listener recovery, fail-closed exhaustion,\nreal OMP executable validation, and explicit failures rather than silent empty\noutcomes. Capability parity does not weaken those guarantees.\n\n## Agent-facing parity decisions\n\n<!-- [doc->REQ-PARITY-READY-ACTIVATION] -->\n<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\nOrdinary OMP sessions gain extension-native `/ready` and `/live` activation\ncommands with argument completion or native selection dialogs. Explicit live\nauto-resume selects the most-recent compatible live identity; ordinary\nactivation never guesses silently. The extension binds the current session and\nowns the authenticated listener, after which binding is immutable.\n\n<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\nMessages accepted during an active OMP turn enter at the first proven boundary\nbefore the next tool or model continuation. Custody and arrival order remain\nintact; a turn with no injectable boundary falls back to ordinary next-turn\ndelivery rather than interruption.\n\n<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\nCancelled, interrupted, and failed turns settle affected custody and restore\nreceivability automatically. Only exhausted listener recovery closes the\nendpoint.\n\n<!-- [doc->REQ-PARITY-STARTUP-BRIEF] -->\n<!-- [doc->REQ-PARITY-TARGETED-HINTS] -->\n<!-- [doc->REQ-PARITY-UPDATE-NOTICE] -->\nActivated sessions receive a concise startup brief for identity, roster,\nmessaging, continuity, lifecycle, subnet, version, and update operations.\nTargeted hints cover clear live-activation, identity, messaging, subnet, and\ncheckpoint intent. Available compatible spt-core or adapter updates produce an\nactionable notice.\n\n<!-- [doc->REQ-PARITY-COMMUNE-SKILL] -->\n<!-- [doc->REQ-PARITY-CHECKPOINT] -->\n<!-- [doc->REQ-PARITY-SIGNOFF-SKILL] -->\n<!-- [doc->REQ-PARITY-ROLE-SKILL] -->\nPublic OMP `omp-plugins` packaging supplies model-driven skills for commune,\nsignoff, and durable-role inspection/editing. Commune checkpoint mode saves\ncontinuity, resets OMP context through native session APIs, and wakes the same\nendpoint without operator intervention.\n\n<!-- [doc->REQ-PARITY-SETUP] -->\nSetup is hybrid: an extension-native command owns deterministic probes and\nactivation, while a packaged skill owns diagnosis, repair strategy, published\ninstaller use, subnet onboarding, and explicit operator handoffs for\nauthentication or elevation.\n\n<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\nAssistant output may dispatch the explicit cross-harness peer-message shortform\n`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\nNormal outbound messaging, roster, stop/shutdown, version, and subnet commands\nare taught through setup or startup context rather than duplicated as skills.\n\nOMP's native provider/profile routing satisfies alternate provider, account,\nand model routing parity; no `omp-spt:<profile>` analogue of Claude's CCS\noverlay is required.\n\n## Release-target parity\n\n<!-- [doc->REQ-DIST-LINUX-MUSL] -->\nThe supported target set is Windows x86-64 MSVC, GNU Linux x86-64, and a static\nLinux x86-64 musl helper compatibility tier for OMP-capable hosts where the GNU","truncated":true,"truncatedBy":"lines","totalLines":111,"totalBytes":3201,"outputLines":65,"outputBytes":3201,"lastLinePartial":false,"firstLineExceedsLimit":false},"displayContent":{"text":"## Proven shared endpoint surface\n…\nOMP keeps its stronger native invariants: immutable endpoint/session binding,\none bounded custody queue, finite listener recovery, fail-closed exhaustion,\nreal OMP executable validation, and explicit failures rather than silent empty\noutcomes. Capability parity does not weaken those guarantees.\n\n## Agent-facing parity decisions\n\n<!-- [doc->REQ-PARITY-READY-ACTIVATION] -->\n<!-- [doc->REQ-PARITY-LIVE-ACTIVATION] -->\n<!-- [doc->REQ-PARITY-LIVE-AUTO-RESUME] -->\nOrdinary OMP sessions gain extension-native `/ready` and `/live` activation\ncommands with argument completion or native selection dialogs. Explicit live\nauto-resume selects the most-recent compatible live identity; ordinary\nactivation never guesses silently. The extension binds the current session and\nowns the authenticated listener, after which binding is immutable.\n\n<!-- [doc->REQ-PARITY-SAFE-BOUNDARY-DELIVERY] -->\nMessages accepted during an active OMP turn enter at the first proven boundary\nbefore the next tool or model continuation. Custody and arrival order remain\nintact; a turn with no injectable boundary falls back to ordinary next-turn\ndelivery rather than interruption.\n\n<!-- [doc->REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY] -->\nCancelled, interrupted, and failed turns settle affected custody and restore\nreceivability automatically. Only exhausted listener recovery closes the\nendpoint.\n\n<!-- [doc->REQ-PARITY-STARTUP-BRIEF] -->\n<!-- [doc->REQ-PARITY-TARGETED-HINTS] -->\n<!-- [doc->REQ-PARITY-UPDATE-NOTICE] -->\nActivated sessions receive a concise startup brief for identity, roster,\nmessaging, continuity, lifecycle, subnet, version, and update operations.\nTargeted hints cover clear live-activation, identity, messaging, subnet, and\ncheckpoint intent. Available compatible spt-core or adapter updates produce an\nactionable notice.\n\n<!-- [doc->REQ-PARITY-COMMUNE-SKILL] -->\n<!-- [doc->REQ-PARITY-CHECKPOINT] -->\n<!-- [doc->REQ-PARITY-SIGNOFF-SKILL] -->\n<!-- [doc->REQ-PARITY-ROLE-SKILL] -->\nPublic OMP `omp-plugins` packaging supplies model-driven skills for commune,\nsignoff, and durable-role inspection/editing. Commune checkpoint mode saves\ncontinuity, resets OMP context through native session APIs, and wakes the same\nendpoint without operator intervention.\n\n<!-- [doc->REQ-PARITY-SETUP] -->\nSetup is hybrid: an extension-native command owns deterministic probes and\nactivation, while a packaged skill owns diagnosis, repair strategy, published\ninstaller use, subnet onboarding, and explicit operator handoffs for\nauthentication or elevation.\n\n<!-- [doc->REQ-PARITY-PEER-SHORTFORM] -->\nAssistant output may dispatch the explicit cross-harness peer-message shortform\n`@<target[,target] message @>`. Ordinary `@` mentions have no side effect.\nNormal outbound messaging, roster, stop/shutdown, version, and subnet commands\nare taught through setup or startup context rather than duplicated as skills.\n\nOMP's native provider/profile routing satisfies alternate provider, account,\nand model routing parity; no `omp-spt:<profile>` analogue of Claude's CCS\noverlay is required.\n\n## Release-target parity\n\n<!-- [doc->REQ-DIST-LINUX-MUSL] -->\nThe supported target set is Windows x86-64 MSVC, GNU Linux x86-64, and a static\nLinux x86-64 musl helper compatibility tier for OMP-capable hosts where the GNU\n…\nOMP itself is unavailable.\n…\n","startLine":9,"lineNumbers":[9,null,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,null,86,null,104]},"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\omp-spt\\docs\\PARITY.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":129,"totalBytes":3201,"outputLines":65,"outputBytes":3201,"shownRange":{"start":19,"end":83},"nextOffset":84}}},"isError":false,"timestamp":1784192954630}}
{"type":"message","id":"d3acbe8c","parentId":"a29101de","timestamp":"2026-07-16T09:09:24.530Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Verifying required stages before running traceable check**"},{"type":"toolCall","id":"call_vXB4p4bM5bpaV7213NcV9RyV|fc_09ab79121c733b56016a589fc19e3481999278afc129b4ff9a","name":"bash","arguments":{"i":"Checking requirement traceability","command":"traceable-reqs check","cwd":".","timeout":120}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7878,"output":84,"cacheRead":99840,"cacheWrite":0,"totalTokens":107802,"reasoningTokens":44,"cost":{"input":0.03939,"output":0.00252,"cacheRead":0.04992,"cacheWrite":0,"total":0.09183}},"stopReason":"toolUse","timestamp":1784192954650,"responseId":"resp_09ab79121c733b56016a589fbb0c8c819981c3797a5ee47b62","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589fc06c208199972a753e3d99ea4e","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ_B5uHhGUK3RQGAwWXCoPDiNXalMTYz0ve-XMDMsG8jDskQQQ5ofwOoLKeQkzBiyp6VwjhtYx6xrbkxsbRnZcBSSoXdX6OHnh6Z3riyR-K_4bQk69r5MSW85enPFuXhKaPs6zihbS14FyVgrTeJC7rFe63f4PVaNytYeX9JTRlBAsAoagpgsVgFD8LHb9w8WWKEh6sg1rAVe_WQmgD3XvziylBfFVow5OoY5v07n3mpXm2NiqwcoNGQYAMsU99xB0g-tSo-uk5znPZFZ7sgepITO_zVmW-HFFjT2-IgbGtJqRUa1X8rCSEIC134kof6jsR3djf-7BU645SjLp6iCv7z3j60kz8qOoUxbFo1yYHdZhYBLj4CRv7gFHWIYXH_AvNNIBU3ARLDo6xLsRIbwtaj49DNoPEzlMeoiW_P5CR6nWOxaoWq5cDlKIJN6yzrbXiIEOtk7v6tLbncDvKXMjyfeLy5yVcBzuYGho1x6qA8QO6oFBXOoQ_Re42A3QFdOVCw3S8ogYxYZbugU38n2FP4NQQ_hwSt9X-kGq0mlXL18uodiuSWGIPQJtcUtvLTCItUbm_5DlYHhIA9YHlYv8r1TBMHbZupoi7TZH2XjL1Ov007fDVhhBxkxZi1hTD1lZnzo21PdE88Lvn0WwmAQQXdBkk0EEPxiZBc2bdw66AoL6aPKbw69pQn813KTnrAnOBdjJWEcZgi_ZmR3Q3nIMF4gJK6-pFYZ09Smid3rdoAyKCXG2CQNj9NLvT-9b96XzKn8xzUQbWm6INh9TpDiP9tbu1gjk-zvOB3OU9kYfXNT-Yml_eeP3kEZX7lDw0nuVLlJ4XrgEhlPGXuc18OZJ53GNcdntgKf0ee0THvjV1_zbZ1aojoVXjxC5QXX7ikxkdynbUEW5cYFTX8xlPTMXLT91uIOhXYspS3qyW_3DkE4Oac_HH5WBsu1UOS6DGylhlvUm0OoYFCE2FEa7w2WXAHmxtUCejftCIumG7tiYRcd_gN4QG0ZiqenmA4clyAkScUocqGBH1pBLWIUn0ecb9MeZ0iwFK2gjTLYCpU_pznupeR13RwpdDbas0jZ-hLko29KVlejCur--CEbfrUq40hqDsQ4yGcH3-N1Gw26AUo4uXG9Ef-k-uHtxgy7B_6Bp2w3vCNqq35ID2FAGSov7Dk_jlhNOOr2DZvP1I32iCp3IM=","summary":[{"type":"summary_text","text":"**Verifying required stages before running traceable check**"}]},{"id":"fc_09ab79121c733b56016a589fc19e3481999278afc129b4ff9a","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking requirement traceability\",\"command\":\"traceable-reqs check\",\"cwd\":\".\",\"timeout\":120}","call_id":"call_vXB4p4bM5bpaV7213NcV9RyV","name":"bash"}]},"duration":9878.555600000545,"ttft":5773.0864000003785,"contextSnapshot":{"promptTokens":107718,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_vXB4p4bM5bpaV7213NcV9RyV|fc_09ab79121c733b56016a589fc19e3481999278afc129b4ff9a","toolName":"bash","startedAt":"2026-07-16T09:09:24.530Z","args":{"command":"traceable-reqs check"},"intent":"Checking requirement traceability"},"id":"6da7ac31","parentId":"d3acbe8c","timestamp":"2026-07-16T09:09:24.530Z"}
{"type":"message","id":"542ed651","parentId":"6da7ac31","timestamp":"2026-07-16T09:09:24.816Z","message":{"role":"toolResult","toolCallId":"call_vXB4p4bM5bpaV7213NcV9RyV|fc_09ab79121c733b56016a589fc19e3481999278afc129b4ff9a","toolName":"bash","content":[{"type":"text","text":"34 requirements: 34 complete, 0 incomplete, 0 findings\n  [OK] REQ-DIST-ADAPTER-RELEASE  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       One multi-platform adapter.spt ships the manifest, native OMP extension, and omp-spt binary through BigscreenVR/omp-spt releases\n  [OK] REQ-DIST-BINARY-CONSOLIDATE  required: [impl, unit]  stages: -doc +impl +unit -int\n       One omp-spt helper binary dispatches only the retained OMP-native launch, digest, history, Psyche, and echo-commune roles\n  [OK] REQ-DIST-DIGEST-EXTRACTOR  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       The OMP digest fetcher maps native session JSONL into the published harness-neutral digest record stream\n  [OK] REQ-DIST-LINUX-MUSL  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       The release ships and natively accepts a static x86_64 Linux musl helper compatibility tier\n  [OK] REQ-DIST-MANIFEST-SCHEMA  required: [doc, impl, unit]  stages: +doc +impl +unit +int\n       The omp-spt manifest validates offline against spt-core's published manifest schema\n  [OK] REQ-DIST-RELEASE-EVIDENCE  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       Every supported target retains a machine-readable release record covering source identity, digests, acquisition, and native acceptance\n  [OK] REQ-DIST-VERSION-CONSISTENCY  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       Manifest version is canonical and release gates reject disagreement in helper, changelog, and versioned public documentation\n  [OK] REQ-DOCS-PUBLISH-GATE  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       Local deterministic docs drift checks gate changes and the same checks gate GitHub Pages publication\n  [OK] REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Cancellation, interruption, and failed OMP turns settle affected custody and restore endpoint receivability\n  [OK] REQ-HISTORY-FETCHER  required: [doc, impl, unit]  stages: +doc +impl +unit +int\n       The history fetcher locates exactly one OMP session and streams its JSONL bytes verbatim\n  [OK] REQ-OMP-CONTINUITY-DROPS  required: [doc, unit]  stages: +doc -impl +unit -int\n       Commune and signoff drops resolve project-locally under .spt on the published v0.29.0 endpoint-cwd contract\n  [OK] REQ-OMP-EXECUTABLE-RESOLUTION  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       Fresh, resumed, and daemon-driven OMP turns resolve and validate Oh My Pi, reject executable collisions, and fail loudly\n  [OK] REQ-OMP-EXTENSION-CUSTODY  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       The OMP extension serializes accepted deliveries and preserves sender custody through a correlated reply or explicit failure\n  [OK] REQ-OMP-LISTENER-FAIL-CLOSED  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Unexpected listener exit retries within a finite budget and then performs SPT session-end plus OMP shutdown\n  [OK] REQ-OMP-LIVE-RELEASE-GATE  required: []  stages: -doc -impl -unit -int\n       Pending live gate: a real OMP release must satisfy the ADR-0013 endpoint acceptance criteria\n  [OK] REQ-OMP-MESSAGE-CONTEXT  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Each peer delivery opens one ordinary OMP turn containing a message stub and the complete SPT event context\n  [OK] REQ-OMP-NATIVE-TUI  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       The hosted launch contract hands validated OMP its packaged extension as the broker PTY process\n  [OK] REQ-OMP-READY-LIVE  required: [doc, unit]  stages: +doc -impl +unit -int\n       The adapter advertises exactly ReadyAgent and LiveAgent endpoint types on the same native OMP hosting path\n  [OK] REQ-OMP-SESSION-IMMUTABLE  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       One endpoint owns one OMP session for its lifetime and blocks every in-TUI session-changing action\n  [OK] REQ-PARITY-CHECKPOINT  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Commune checkpoint mode saves continuity, resets OMP context natively, and wakes the same endpoint without operator intervention\n  [OK] REQ-PARITY-COMMUNE-SKILL  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       A packaged OMP plugin skill authors endpoint-qualified commune continuity drops\n  [OK] REQ-PARITY-LIVE-ACTIVATION  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       An extension-native command binds an ordinary OMP session as a live endpoint with durable Psyche continuity\n  [OK] REQ-PARITY-LIVE-AUTO-RESUME  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Explicit live auto-resume selects the most-recent compatible live identity without silently guessing on ordinary activation\n  [OK] REQ-PARITY-PEER-SHORTFORM  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       OMP dispatches explicit @<target message @> assistant output through public SPT messaging with observable results\n  [OK] REQ-PARITY-READY-ACTIVATION  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       An extension-native command binds an ordinary OMP session as a ready endpoint while the extension owns its listener\n  [OK] REQ-PARITY-ROLE-SKILL  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       A packaged OMP plugin skill reads and edits the durable role through directives or an interactive draft\n  [OK] REQ-PARITY-SAFE-BOUNDARY-DELIVERY  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Accepted peer messages enter an active OMP turn before its next tool or model continuation, with ordered next-turn fallback\n  [OK] REQ-PARITY-SETUP  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       Hybrid extension command and packaged skill diagnose and complete OMP SPT setup with explicit operator handoffs\n  [OK] REQ-PARITY-SIGNOFF-SKILL  required: [doc, impl, unit, int]  stages: +doc +impl +unit +int\n       A packaged OMP plugin skill authors final signoff continuity and gracefully shuts down the endpoint\n  [OK] REQ-PARITY-STARTUP-BRIEF  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Activated OMP sessions receive concise identity, roster, messaging, continuity, lifecycle, subnet, and version guidance\n  [OK] REQ-PARITY-TARGETED-HINTS  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Clear user intent for live activation, identity, messaging, subnet, or checkpointing receives a concise targeted hint\n  [OK] REQ-PARITY-UPDATE-NOTICE  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       An activated session receives an actionable notice when its spt-core or omp-spt version trails a compatible release\n  [OK] REQ-PSYCHE-EPHEMERAL-SHIM  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       Each LiveAgent Psyche event runs as one bounded OMP turn with file-backed context and explicit reseed signaling\n  [OK] REQ-SESSION-ECHO-COMMUNE  required: [doc, impl, unit]  stages: +doc +impl +unit -int\n       The bounded echo-commune role summarizes one OMP session and reports real OMP failures without latching on a locate miss\n\n\nWall time: 0.29 seconds"}],"details":{"timeoutSeconds":120,"wallTimeMs":285.3024000003934},"isError":false,"timestamp":1784192964815}}
{"type":"message","id":"d3d3de86","parentId":"542ed651","timestamp":"2026-07-16T09:09:34.678Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Confirming trace activation and planning no-op**"},{"type":"toolCall","id":"call_SIbnql00jAyAhgf6Z6HlFkPp|fc_09ab79121c733b56016a589fccf0708199a3d4733ae01590ca","name":"irc","arguments":{"i":"Reporting traceability pass","op":"send","to":"Main","message":"Verified required_stages are active for READY/LIVE/LIVE-AUTO/SAFE-BOUNDARY/ABNORMAL-TURN/STARTUP/HINTS/UPDATE/CHECKPOINT/PEER-SHORTFORM. Adjacent doc/impl/unit tags exist in docs/PARITY.md, adapter/strings/omp-spt.mjs, and tests/omp-extension.mjs. `traceable-reqs check` => 34 complete, 0 incomplete, 0 findings.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":8978,"output":205,"cacheRead":100864,"cacheWrite":0,"totalTokens":110047,"reasoningTokens":54,"cost":{"input":0.044890000000000006,"output":0.00615,"cacheRead":0.050432,"cacheWrite":0,"total":0.101472}},"stopReason":"toolUse","timestamp":1784192964859,"responseId":"resp_09ab79121c733b56016a589fc529108199b831ff07cc4579a8","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589fc8f32c819985fc17d162e3860d","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ_MKoikKbFmz8bRgy46520gk3rrqncjAgmnAzaZmtkj1ESKvs49iLzL0328tMyjZQ7l4gVx08dh7Ldb4SI8xZS6iT-NMjm4pOPDFP9qPjkoIE-N0-C858934BqOOU6zuBXVZjhHJv2AvRNEO5hkA8TMVECtRTOO1BqSLklECEMK9sL039xq4-g-M3u0YF_KCkD3xV02fqdg7e_Q6Zr5_TbfgiZ7p5vs-P2brDEGniaq0R4oMcOlT3bFmyf2yn7DydgFBWZ0bIg6nmqJYJITRws-RpjgF41EuOtWIzKzd_t8WMlBfwdJo7jFHVOKWgIikkpqYujmaSrT80VI9-iWMipPpunP3jan5uFII6_SbLIWGvuGHMaXhwGjwC7i7ab1_2UBUPO79zEBDtogOOtWsWZLsgjzbEXBHyL-RFXawuaI3GrVZnUQ-jXgQzVCRiVKOo0Lc_ZcVZEJeFrHWUkEHQawvj2qNy_HltlnUCyACh5cFMr6o6WdUcdvRds3GKvSB6pNRCxodP38WsvDoaMXr543WVEXDU-G0ulJ4_R4WXvtGIIIa6uWjZY5F9WVMszzi2sCJCGsMbxDLYy9U-YeR43u3gEnP8_zIrpCazzCbqwfqJshwuayUf492s1gdxPO1R-Vm71vNmXcY2cGZ9s9doccPLK4wK5e2sZQqhxXux3nj-glHw4NYzgphFf3QzA-s1i1bBR1v77uuuE-eaf3kkewl6TA55X567yQCLWRGLD_Rcio2XcJ4nz1Zk4j6N4iOg1dz3UVjcTNKj4eLb-DsztGFEePKJ0S5pWIuY8UFGEf_w6OtzyxsiCAlnaQNEc06jHkfUiaKz4DLIs9jCGAJwlgImlK8THV42L9MBJGbxUlTIQzMgiZmgOnxmezebwLVFvtIyfLduwbMtqNqerkQ-Es8l437dAZBHIRjwoH2T1kKYOuZixF1IYjWNLJuY4Hg47kI_bGDJSyddyAbzJKViejWOywVaOUxMl8Rl1i6SJdpUD6Inrc-LkSGJmfxE7UwtsSUUL9wWncaR27jKQ-_I9O3pLPWkwOWiSZ0xAEyRaVL18NHImZE1GfZazAasUzLgEGoXSplaUrXujg_1WFcibwtvz4_0yubHWpnUxUhKskQnUugVMOzUbotAWMpScm9rjaAJHUq_sInEYJfEFO6athVy3XkH53W0xIbiraHA2IGSHS5sxYbJzu-I0Tm4swmdIHHMoGkWdu8XjO1dmgjBfPOU5rJ03FWUW0UXKW06r4MUE=","summary":[{"type":"summary_text","text":"**Confirming trace activation and planning no-op**"}]},{"id":"fc_09ab79121c733b56016a589fccf0708199a3d4733ae01590ca","type":"function_call","status":"completed","arguments":"{\"i\":\"Reporting traceability pass\",\"op\":\"send\",\"to\":\"Main\",\"message\":\"Verified required_stages are active for READY/LIVE/LIVE-AUTO/SAFE-BOUNDARY/ABNORMAL-TURN/STARTUP/HINTS/UPDATE/CHECKPOINT/PEER-SHORTFORM. Adjacent doc/impl/unit tags exist in docs/PARITY.md, adapter/strings/omp-spt.mjs, and tests/omp-extension.mjs. `traceable-reqs check` => 34 complete, 0 incomplete, 0 findings.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_SIbnql00jAyAhgf6Z6HlFkPp","name":"irc"}]},"duration":9817.432799999602,"ttft":4066.746299999766,"contextSnapshot":{"promptTokens":109842,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_SIbnql00jAyAhgf6Z6HlFkPp|fc_09ab79121c733b56016a589fccf0708199a3d4733ae01590ca","toolName":"irc","startedAt":"2026-07-16T09:09:34.678Z","intent":"Reporting traceability pass"},"id":"95c17b13","parentId":"d3d3de86","timestamp":"2026-07-16T09:09:34.678Z"}
{"type":"message","id":"73a6ec17","parentId":"95c17b13","timestamp":"2026-07-16T09:09:34.679Z","message":{"role":"toolResult","toolCallId":"call_SIbnql00jAyAhgf6Z6HlFkPp|fc_09ab79121c733b56016a589fccf0708199a3d4733ae01590ca","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- Main: injected"}],"details":{"op":"send","from":"NativeExtension","to":"Main","receipts":[{"to":"Main","outcome":"injected"}]},"isError":false,"timestamp":1784192974678}}
{"type":"message","id":"b876da49","parentId":"73a6ec17","timestamp":"2026-07-16T09:09:43.937Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning test rerun after registry changes**"},{"type":"toolCall","id":"call_Xm8aUVvWx52S1r9B2dKg92Ps|fc_09ab79121c733b56016a589fd5b4e48199ae84cc43a337a92f","name":"bash","arguments":{"i":"Rechecking final focused suite","command":"node tests/omp-extension.mjs","cwd":".","timeout":180}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7157,"output":139,"cacheRead":102912,"cacheWrite":0,"totalTokens":110208,"reasoningTokens":97,"cost":{"input":0.035785000000000004,"output":0.00417,"cacheRead":0.051455999999999995,"cacheWrite":0,"total":0.09141099999999999}},"stopReason":"toolUse","timestamp":1784192974692,"responseId":"resp_09ab79121c733b56016a589fcf2a10819988e6c92a5d83c4dd","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589fd2f2e8819984525205928cb2e8","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ_VnbuQXF_QoInVa0du9c938bSCJP_yjkXVVcnvue6Qnhh-VhYjzUA7MG3jfyphxJm0weX6o2e3_zcpY4pgkNOYMjpDylBufhtIIWDEEcLg3My1NzYwxhCKW2yJfVfvelm2mgIdtMQBmmszR4vp8YkcTb9ThqipduqjP0QiYFyGbQVHtASDbalcKtNRFQBQJgqi_1Fha725A5fIUlY7OH9ia3xLrD31NmAFii3ubyOzr9MyEy1QH2hr8pkCgFtzgqMSVHACb84hx9EzD9AObQIU5efX7GIo7ZLfud9KQEpw8_Il_gx_UtWks3GuPofG_UOTDpmGsdJPhsoNKrtud88iJLK8VhCTdd1HSv8TnsI7Ta2B8bEZziagXFGGrPr4bbIS4rCyqKLxzxRC6HahbbwF41681QAgYOWFCTIfUR1fwPj-ZSv9_iSAb80vNmfnNM3yCCkoH_PBxVP3EN1NMIRRyjIdrQkU5soilmTilBefMTI2B_5vE4AEv25WAxYh727LvfR26gj44-v5ptS-3jnTdu5NO5KSp6W7xbXIJ7E9jYonEpu2paBM54Ls0MWyW6Lfw2vGOM0NaZBeiAN_tbS7f9aOHsMQJ8vcr2Zmm1ro2GC6ajAZhu2ZxW47V1YrUC0MnOXDXT9qpJbf8gAlpwjTcDA4fforAn8aWQPa-esGYa00orqdqCS5rMXu_XfLuEgSkmQ_3qhVJCpaQFgtcMu7X4mcqkjwzTPcCcq3Ef1XUWfYfVdRaE4PJ9u7RUqvkXSUvtQlliaEt5Uq3ujI-Ljm4H6ihVj-uB6mniq-NxA1_VCpEFY5NQiIi-pM_Gwx1fL7VW6kiuLbkqC8lfCpcHSlavJbMOZzujRSXJDatmgpeAVhF7vlzsb_BRAOzAkFqTXpx_k_e4O3k8xgVRRdDWZSZK1pTKjBYxdpUPpybnggt01UFYjZ_NG-rwstkkBLz-0tLBaXP_drESeLD9j-H3gvQHEGWYF0sbwanNF5onnkhbPFHaeJCEAXMdteowOzic94CuoSBZzLN7lAVl61vw7HHgXgzW-Y0EY_874SdYThqE-RDpUpBwxI044J7kAgfOIYEHpbvJt_4ddwAsrJ6IdLGx4eWRnuMEoHRRejQzrzRx09_mDmKwFRHYs6cjZTZB8prODtlcUBdQne4bG472Y5S0-WoOOuKECYF4jp1P5St7OD3gVLpfzQ0T_I-ZQnewZp44gy7bkCZqlGnDttRI-BiRtUyiSdqCD9pdjP3D9a-lquGQu9n5evktOFOKy0vI0-Iz91YqXI5yFFgkSuTMYzRVBp3CmriUUNAXP1rQ49c_7BNk-31rUKX2UWq7tUZJoaXcbdqGdIYoDWsw3iKt-XUt14LKM9dyxjV7MLQ-lCS_FZClXk9ZC_C8mp8HBVb9nvmAP1hgTWwgXZ31vzy3I0dPvqL7Wfj8GXXuYphBC-iJBz5-Eh5t594b3TUmllZjx1KvSu3F4A4Qa2mykH_vTSQ6NSOoEsLRIgTBoW6AvYVgJ32Y31FA6QmFiOJg4SjKJBo56PbDOYIaeohFQluBmu7g==","summary":[{"type":"summary_text","text":"**Planning test rerun after registry changes**"}]},{"id":"fc_09ab79121c733b56016a589fd5b4e48199ae84cc43a337a92f","type":"function_call","status":"completed","arguments":"{\"i\":\"Rechecking final focused suite\",\"command\":\"node tests/omp-extension.mjs\",\"cwd\":\".\",\"timeout\":180}","call_id":"call_Xm8aUVvWx52S1r9B2dKg92Ps","name":"bash"}]},"duration":9243.94039999973,"ttft":4234.724099999294,"contextSnapshot":{"promptTokens":110069,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Xm8aUVvWx52S1r9B2dKg92Ps|fc_09ab79121c733b56016a589fd5b4e48199ae84cc43a337a92f","toolName":"bash","startedAt":"2026-07-16T09:09:43.937Z","args":{"command":"node tests/omp-extension.mjs"},"intent":"Rechecking final focused suite"},"id":"4e3ccaec","parentId":"b876da49","timestamp":"2026-07-16T09:09:43.937Z"}
{"type":"message","id":"b44d557f","parentId":"4e3ccaec","timestamp":"2026-07-16T09:09:44.127Z","message":{"role":"toolResult","toolCallId":"call_Xm8aUVvWx52S1r9B2dKg92Ps|fc_09ab79121c733b56016a589fd5b4e48199ae84cc43a337a92f","toolName":"bash","content":[{"type":"text","text":"OMP-EXTENSION OK\n\n\nWall time: 0.19 seconds"}],"details":{"timeoutSeconds":180,"wallTimeMs":188.82880000025034},"isError":false,"timestamp":1784192984126}}
{"type":"message","id":"f124f142","parentId":"b44d557f","timestamp":"2026-07-16T09:10:00.637Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Planning trace check and doc tag review**\n\n**Preparing structured summary for user**"},{"type":"toolCall","id":"call_fYTOd1DKL8uRgBXx7yQqLkRE|fc_09ab79121c733b56016a589fe031108199947fc431975aaf1f","name":"yield","arguments":{"result":{"data":{"status":"complete","changed":["adapter/strings/omp-spt.mjs","tests/omp-extension.mjs"],"implemented":["Extension-native /ready and /live activation with native selection, explicit confirmed --auto resume, immutable extension-owned bind/listen lifecycle, and no background poll","Active-turn peer delivery re-injected at each provider context boundary, assistant-baseline reply correlation independent of ephemeral context, ordered next-turn fallback, and abnormal-turn custody/idle recovery","Assistant-output @<target[,target] message @> parsing with Markdown-code exclusion, concurrent bounded public SPT sends, ordered observable statuses, and shutdown-safe suppression","Native checkpoint compaction/wake ordering with launch-time endpoint-type verification","Platform-aware activation identity compatibility preserving Linux case and filesystem roots"],"verification":["node tests/omp-extension.mjs => OMP-EXTENSION OK","traceable-reqs check => 34 complete, 0 incomplete, 0 findings"],"traceability":["Verified active doc/impl/unit stages and adjacent evidence tags for REQ-PARITY-READY-ACTIVATION, REQ-PARITY-LIVE-ACTIVATION, REQ-PARITY-LIVE-AUTO-RESUME, REQ-PARITY-SAFE-BOUNDARY-DELIVERY, REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY, REQ-PARITY-STARTUP-BRIEF, REQ-PARITY-TARGETED-HINTS, REQ-PARITY-UPDATE-NOTICE, REQ-PARITY-CHECKPOINT, and REQ-PARITY-PEER-SHORTFORM"]}}}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6297,"output":529,"cacheRead":103936,"cacheWrite":0,"totalTokens":110762,"reasoningTokens":177,"cost":{"input":0.031485000000000006,"output":0.01587,"cacheRead":0.051968,"cacheWrite":0,"total":0.09932300000000001}},"stopReason":"toolUse","timestamp":1784192984172,"responseId":"resp_09ab79121c733b56016a589fd87630819996defba7075a0b2d","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_09ab79121c733b56016a589fdc3f108199a71b0da5de19f8d6","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWJ_gsQZr6gzpJyLbjZjIWR4hXkj_wdl0S8dG0mUDEiFb9uELDKQkRM5YHFMWXRrrPregbHd4VAa-S7QpGeWmJY5ZlobgqOxkyC4MJ6hUIKLSX9ZzXZ_4_UH_WYMjg0ZFGSRm1S3J8Vo6keEc9l5zdh6hm3Q2Va0LPnt0QkP8djhKR2JA4kmokBIvT07FiFvp3QC62a4fRwnOiT0mUEuFcuN_PzVTSLxoHNtrBQ7ESw90fhinQALnlNGXK6K-Cey3-hi1IiXdkzg8N5TwK5G8cLvxMrq0TuTouMU6XGECFgb1WQo8GUds5mH5ws6w44uJhG_tPwotTOIRZIH5YSnmLdZD6irP3QyuqoktuCcx-5dwvrHZ_YgOpFKq5D7SgQJdZA7gLmNqmYh503J08TPj3zG9x8kF-3Py0JbQ6X9vuDxD-jaBdF0x0U1h2EyYXuKWoPmys2sW_EDszTuPyzwinYzHxxq2fvrb-XrvliWaAPOWEpZrlPpSnbuDm7hUQKR6K9GUred7ijoBdWvQeneLxuLHC7OD0uPoRdtd-S-HhY0ARCDl8IjFn33zvM8PLhbWFap9GVfU_ffDLfkSxUQZ5jY_yCUJOVAft2S6fSD7vz3QQd5IHpsRWN1vvLTB5i2Qqw6pELVWdNhkLXTRENBfA2DZI6GeP25aSd0q77JP3xyQ1u79Mv3SJw19GkUaL086iAEB0fGF1rr2DLJQmKnY4XsKPhQ3Q2GiVVfphjeCpsRrPsLNa2wmikCixmMwi2sW3l3FuwxQP5joomkM0aL7VTpcjxCX5qXORB4VXLIJHr2xh0uDtRcCJHPiRn5Eos-CGPDgdMDczjnxzFwTtyx-7Ky5wYjVLSjndh0dvGOCZK5lLlrpKiKoeOoYSZe2ShcJA1YaZtULbLnESuAHGOzFSPA8-Z2ZtB522xdVyWx7548sKEanqhbfSz6Nzw2HqJVmXTHhayQsieDnhTq6C2O6VXOM7uPvSC0Vai8-2zSiz7tflYsXiErkvacKbN0IwIidIP4OJqEMNv4F01LJ2-oSfrcHej7WRIEQJOWZdD9NUOcor1CufhO3AhOXHUmwTNtoc9raYwQwR-2DGfnLOb8_afIADFETDg_h6DU4BMyoLuObmb2kB37oXXiU06Fa0wzMOgeQOz8y2D5bwyzNMrg_aBlPqzxXPyV2otXWXfaZ_m738ku6x1xlVJLFz3LHtRsLDA3N8wzJyqfPgDyuL2fRwoARWGh_nJtnTqPjevIqUYeTqVI_UDFze_K2J1anyb-rdiQbYyo0wxlAQWTnmVLm7GJ1JM9nZBQeALFP07yUD13OFX3w17tgHBVhjmWfZOi-r5FfWZ6u3mBJ0WrtIh4VFfAK3SqdjFL_AuFD_3ZwTAHRZRDRaBNzY1jFw5n3R8CXp-TY1p4VjzVvaKXDxS1cwRJR77PDcrh9NpnR4nAZhzND297yU6oj1nHou2ZaArI1zHQkoDZ4pc8lvIqTQB3hWE982Wx5Uhr52VCG6UncgmmfKkgZwITkkH1jX6_sWYmWRfU4viUFiGFkB3IqCXUv8kMPFdYSgcFPh1PJD1WYmdfZkpqEoX-HrMsJmb0QjEWAseBox7qevGhf0iD-7DMWWuzM4SXtS9aejpiJx8lpDZfPvTOX-ROHW_JrWb51fqw8D6YpeomGLeLFgGuPMc8ZGJYUHtNi55QVlAldHKGwpPBzvcQjBkEreqRaQ51t0PNu32Uit9mLfcFcB8hfXg85B7xLccH8sB2Vl4mv6xdcDk3XkLZCBKYZCv2FEhNSJhLtqSNUo8HB3R5LCSUAr7jRBLFjf-oW7EKEROOjyy_QJa9qGDu0labIx1SQT4iBcAIolBb3hRDQvWW9_G1KygKiOkJpqh-6pjl752vWnWU3HpXv8CN5yeeUYr-SfGriEKQ1WRuPY5LGMGCQVL_Eq8phNgmL5XSaPUGaKjfjlHk6C0auwTI42eN1IhHMqwRRC-MiX3HfIMgme-76AFDkuKbzMbehtbbKUeQ7hXM66U30uNNW7E_RHEMgwDSZ50L4p5izL-QtXFFhP1Ptto8wc3l3nINaOw==","summary":[{"type":"summary_text","text":"**Planning trace check and doc tag review**"},{"type":"summary_text","text":"**Preparing structured summary for user**"}]},{"id":"fc_09ab79121c733b56016a589fe031108199947fc431975aaf1f","type":"function_call","status":"completed","arguments":"{\"result\":{\"data\":{\"status\":\"complete\",\"changed\":[\"adapter/strings/omp-spt.mjs\",\"tests/omp-extension.mjs\"],\"implemented\":[\"Extension-native /ready and /live activation with native selection, explicit confirmed --auto resume, immutable extension-owned bind/listen lifecycle, and no background poll\",\"Active-turn peer delivery re-injected at each provider context boundary, assistant-baseline reply correlation independent of ephemeral context, ordered next-turn fallback, and abnormal-turn custody/idle recovery\",\"Assistant-output @<target[,target] message @> parsing with Markdown-code exclusion, concurrent bounded public SPT sends, ordered observable statuses, and shutdown-safe suppression\",\"Native checkpoint compaction/wake ordering with launch-time endpoint-type verification\",\"Platform-aware activation identity compatibility preserving Linux case and filesystem roots\"],\"verification\":[\"node tests/omp-extension.mjs => OMP-EXTENSION OK\",\"traceable-reqs check => 34 complete, 0 incomplete, 0 findings\"],\"traceability\":[\"Verified active doc/impl/unit stages and adjacent evidence tags for REQ-PARITY-READY-ACTIVATION, REQ-PARITY-LIVE-ACTIVATION, REQ-PARITY-LIVE-AUTO-RESUME, REQ-PARITY-SAFE-BOUNDARY-DELIVERY, REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY, REQ-PARITY-STARTUP-BRIEF, REQ-PARITY-TARGETED-HINTS, REQ-PARITY-UPDATE-NOTICE, REQ-PARITY-CHECKPOINT, and REQ-PARITY-PEER-SHORTFORM\"]}}}","call_id":"call_fYTOd1DKL8uRgBXx7yQqLkRE","name":"yield"}]},"duration":16463.95610000007,"ttft":4048.9895000001416,"contextSnapshot":{"promptTokens":110233,"nonMessageTokens":26155}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_fYTOd1DKL8uRgBXx7yQqLkRE|fc_09ab79121c733b56016a589fe031108199947fc431975aaf1f","toolName":"yield","startedAt":"2026-07-16T09:10:00.637Z"},"id":"fb3a38b7","parentId":"f124f142","timestamp":"2026-07-16T09:10:00.637Z"}
{"type":"message","id":"a956d393","parentId":"fb3a38b7","timestamp":"2026-07-16T09:10:00.638Z","message":{"role":"toolResult","toolCallId":"call_fYTOd1DKL8uRgBXx7yQqLkRE|fc_09ab79121c733b56016a589fe031108199947fc431975aaf1f","toolName":"yield","content":[{"type":"text","text":"Result submitted."}],"details":{"data":{"status":"complete","changed":["adapter/strings/omp-spt.mjs","tests/omp-extension.mjs"],"implemented":["Extension-native /ready and /live activation with native selection, explicit confirmed --auto resume, immutable extension-owned bind/listen lifecycle, and no background poll","Active-turn peer delivery re-injected at each provider context boundary, assistant-baseline reply correlation independent of ephemeral context, ordered next-turn fallback, and abnormal-turn custody/idle recovery","Assistant-output @<target[,target] message @> parsing with Markdown-code exclusion, concurrent bounded public SPT sends, ordered observable statuses, and shutdown-safe suppression","Native checkpoint compaction/wake ordering with launch-time endpoint-type verification","Platform-aware activation identity compatibility preserving Linux case and filesystem roots"],"verification":["node tests/omp-extension.mjs => OMP-EXTENSION OK","traceable-reqs check => 34 complete, 0 incomplete, 0 findings"],"traceability":["Verified active doc/impl/unit stages and adjacent evidence tags for REQ-PARITY-READY-ACTIVATION, REQ-PARITY-LIVE-ACTIVATION, REQ-PARITY-LIVE-AUTO-RESUME, REQ-PARITY-SAFE-BOUNDARY-DELIVERY, REQ-HAZARD-ABNORMAL-TURN-RECEIVABILITY, REQ-PARITY-STARTUP-BRIEF, REQ-PARITY-TARGETED-HINTS, REQ-PARITY-UPDATE-NOTICE, REQ-PARITY-CHECKPOINT, and REQ-PARITY-PEER-SHORTFORM"]},"status":"success"},"isError":false,"timestamp":1784193000637}}
{"type":"message","id":"4c69e3de","parentId":"a956d393","timestamp":"2026-07-16T09:10:00.657Z","message":{"role":"assistant","content":[],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0,"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"total":0}},"stopReason":"aborted","errorMessage":"Request was aborted","errorId":134221824,"timestamp":1784193000652}}
{"type":"custom","customType":"session_exit","data":{"reason":"dispose","kind":"normal","recordedAt":"2026-07-16T09:17:00.669Z"},"id":"9b868818","parentId":"4c69e3de","timestamp":"2026-07-16T09:17:00.669Z"}
{"type":"custom_message","customType":"irc:incoming","content":"<irc>\nIncoming IRC message from agent `FixExtensionReview`:\n\nI’m editing omp-spt.mjs + extension tests for completion stop reasons, shortform cap, activation race, update probe. Are you still touching those files?\nIf a response is expected, reply with the `irc` tool (`op: \"send\"`, `to: \"FixExtensionReview\"`) — you may finish your current step first. Nobody replies on your behalf.\n</irc>","display":true,"details":{"id":"1531e3c324db79dc","from":"FixExtensionReview","message":"I’m editing omp-spt.mjs + extension tests for completion stop reasons, shortform cap, activation race, update probe. Are you still touching those files?"},"attribution":"agent","id":"47b90dd0","parentId":"9b868818","timestamp":"2026-07-16T09:54:53.753Z"}
{"type":"message","id":"55b587cf","parentId":"47b90dd0","timestamp":"2026-07-16T09:55:04.387Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Confirming task completion with changes summary**"},{"type":"toolCall","id":"call_4S32Hbj6TwwVbtMK3HqtEfOV|fc_0f2355a59a2a33ce016a58aa759540819ab51d401bc43c3437","name":"irc","arguments":{"i":"Releasing extension file ownership","op":"send","to":"FixExtensionReview","message":"I’m done touching both files. My final changes include assistant-baseline reply correlation, repeated ephemeral context reinjection, platform-aware candidate paths, launch-time checkpoint type verification, and bounded concurrent shortform sends using `shortformCommandTimeoutMs`. Focused suite and traceable check pass; proceed and preserve those behaviors/tests.","replyTo":null,"await":false,"from":null,"timeoutMs":null,"peek":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":111074,"output":155,"cacheRead":0,"cacheWrite":0,"totalTokens":111229,"reasoningTokens":33,"cost":{"input":0.55537,"output":0.0046500000000000005,"cacheRead":0,"cacheWrite":0,"total":0.5600200000000001}},"stopReason":"toolUse","timestamp":1784195693760,"responseId":"resp_0f2355a59a2a33ce016a58aa6e81ac819aaafc05737b15435e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0f2355a59a2a33ce016a58aa745bdc819a8968a8c0900522ef","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWKp1TnjVd4zPXSVQRj4snHmw4QOZpygZVpJGraWwfMQ-fyu7VmcR7z4d1mma055DFLlk7Cswuba-7d_EGVXcp155lRm5xUgEZMM4Kz_x51GagdJtcoLdvKV-NPujozy-L8V1JfvbUYhmfOACehTH00RoqHpiVUNuo2UHWSShLZI-bqarUseDgVr0oL2QStZ1mchWE8gJOapmZPKLJR4-TnUo-i_kcfbEcJgLw_RnZ3sLzdJe1TnhETnHRc0VEY5SUlcKUg9fmqr_8kherBSDhOREdsHSfGdlEgkvNWKEV-cKHHKsBZBj_n_RW1Dsa2jLsIXQB6f9aA19Dh-wTE2D94zuh4sh2RuIFh7LVIT4-QUrr7S0O5-5iy5uxZzRoZokKmEl1X_emDeBNJFj-epPafyWnKKDeOy52Z-nWslP5xpvNe2UTpJIAhtRbXG9ANKWI7gsXfiXeLHB8cZPklO3gmhEj6cECQY_j1SbRl4DaHBcd6RnGBzrCPUUkPHY6IxNdX3OQMpfwOHEDryYqE3bHvmm0A7EyGV2LiFryS1PTozMT8fm35lzb1q1-6zmoB8-eM6y875RrME1B30uTDK92nwN9cjUlGaVzu4CYk06zd1fY-MmnXfKHcEZYNZ1eCFop3aROPrv-1UbWcHYV5l0fWHY0VyaLL9hjP_oTKwjuthUmavJwpmGWyd5wJhxjt3SraSn8Xx4VrTplmYu3P9NN6PGrVrXvc3-QVL05wDxnGSAOiJ3TH-R-6jG6ocqzRIy1EItaFeuwJUWKqBhUjbhPDdNF5hEGvDLGNglAXoVdvyMYZBal9HkJsnHs6QN0B1hGXyY7d_U-SU09tT-njN59kg5GDEU501E_ONzyRlFLK3jo4-0RdeWdRFY67s1m0iqiDRy8HY1A5E_ZacaEB2BiRpiFjJRhB8zclROM-s4LjmnUatZvcERQqVmsldqUm0lKCQVdBWq608bW9gllZ4eBM8vhTNQIC7g1sR7XR5WvAXRHGlwklhwBBd5CDDgvBJmQchXbtHvGTOBsl8McFpfY337YJQQrg1PCOLm39-PPlHf5bbv_RQwUjkfYnCTMHMDX2XWleGwYuGjZ9RkHWrLr4o1SmnouqmYE0dIxH6TvEzCJJ0=","summary":[{"type":"summary_text","text":"**Confirming task completion with changes summary**"}]},{"id":"fc_0f2355a59a2a33ce016a58aa759540819ab51d401bc43c3437","type":"function_call","status":"completed","arguments":"{\"i\":\"Releasing extension file ownership\",\"op\":\"send\",\"to\":\"FixExtensionReview\",\"message\":\"I’m done touching both files. My final changes include assistant-baseline reply correlation, repeated ephemeral context reinjection, platform-aware candidate paths, launch-time checkpoint type verification, and bounded concurrent shortform sends using `shortformCommandTimeoutMs`. Focused suite and traceable check pass; proceed and preserve those behaviors/tests.\",\"replyTo\":null,\"await\":false,\"from\":null,\"timeoutMs\":null,\"peek\":null}","call_id":"call_4S32Hbj6TwwVbtMK3HqtEfOV","name":"irc"}]},"duration":10626.009000000544,"ttft":6572.993000000715,"contextSnapshot":{"promptTokens":111074,"nonMessageTokens":26371}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_4S32Hbj6TwwVbtMK3HqtEfOV|fc_0f2355a59a2a33ce016a58aa759540819ab51d401bc43c3437","toolName":"irc","startedAt":"2026-07-16T09:55:04.387Z","intent":"Releasing extension file ownership"},"id":"073be826","parentId":"55b587cf","timestamp":"2026-07-16T09:55:04.387Z"}
{"type":"message","id":"455da27a","parentId":"073be826","timestamp":"2026-07-16T09:55:04.387Z","message":{"role":"toolResult","toolCallId":"call_4S32Hbj6TwwVbtMK3HqtEfOV|fc_0f2355a59a2a33ce016a58aa759540819ab51d401bc43c3437","toolName":"irc","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- FixExtensionReview: injected"}],"details":{"op":"send","from":"NativeExtension","to":"FixExtensionReview","receipts":[{"to":"FixExtensionReview","outcome":"injected"}]},"isError":false,"timestamp":1784195704387}}
{"type":"message","id":"33739a7e","parentId":"455da27a","timestamp":"2026-07-16T09:55:13.986Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Assessing need for additional yield**"},{"type":"toolCall","id":"call_HA3zLuFdIeuEwbJuf0BLNdHr|fc_0f2355a59a2a33ce016a58aa804ea0819abf6139dcfef72444","name":"yield","arguments":{"result":{"data":{"status":"complete","coordination":"Released adapter/extension-test ownership to FixExtensionReview with the completed behavior and verification constraints."}}}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":7317,"output":155,"cacheRead":103936,"cacheWrite":0,"totalTokens":111408,"reasoningTokens":108,"cost":{"input":0.036585000000000006,"output":0.0046500000000000005,"cacheRead":0.051968,"cacheWrite":0,"total":0.09320300000000001}},"stopReason":"toolUse","timestamp":1784195704404,"responseId":"resp_0f2355a59a2a33ce016a58aa796bc0819ab73298fa7b1c31fe","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_0f2355a59a2a33ce016a58aa7c7958819ab6148401820dbdcd","type":"reasoning","content":[],"encrypted_content":"gAAAAABqWKqAL_kWiSCGMHtZEXjOmF2C-j9tBv3V_qbIY-gCy_LTwsnwEMypRTHYiMw1iVNX60-fvA6ZysslXTOX8eWWD1mEia9j00pT3V3bMQbKjBb6EhL5D9HojVSLsus9Uj3bVdFb4QtbKewyWVK3NGqlUR4iq9w9gJgFRkC6uWdEt1EPPrGj3bqAO8HNjF2ox3x4F_p077MST0_N3YHzxRiQeqfom-PDFvsGPa2bU-oNp-jV7P0JcTPgTvilRHP3YXc8Jgmni1R86ESnKocog367_85iAYqBy_Ps2BsDzww8btmAlqJmGGAj4ArI10_7T6CFh44PTPXFt04jgrdQlPmS4S952zDR793KYDT0r_lTF3mb5IbSvYbjieFNGobLW_0p1GqyJ5A13TnIQQuWcPu8vLpUbsz42VIn9AeUt9I-vE7gJkTH2crvKSo4gpte99b8HUGBN12XACmfC4lTrDLtGjDUHIZBTjtQ8yp-lGlM5jbPjCgymUVUOjlFolRpSLf49jCiOzS56Au8aHTj3oSwMEuLt5KdVv7--x5EwLyRkZkgWunrX0ocfBxX-sYxWyKLFJByDhG4NJBWZZ-ExXBP54weuPBxJJSqm3bzq4tqMcS_J6gu8I9rr737oGYOAOAKkcBJsx-YVw13TXXkAfiKq_4p5uERX1D1YS6ytT0wne1Y26nRpOEZ5a8YiORw7xJahrSVR9JLnV5hhAvH2ta4mwqRtuWkgGqbY0PuaRi587j3stMhNtR-tm2PS8Bnce9r4GeQYyxy0bi0szIXJTAgE88BqWAFUd68mPO3Ee3PjRssSsx_sNmCE4JiLV8IV1EMZEGWGfOL3zRnE5B19nCrqtqIox4S6DG-OJKH5IwJjff-Py1yPWPPudhYrj_IJkbItmRjQ4MyxsNc0rm9Z2UI8BRfU9tKbfojFSCNIjN1Fi9vtJpwo4a8r2df_bI36t-15IlHnZQNlJ3nEw1ckj07EjYZpukSOM6SIct7s4vO98ObkupaA_fuI8U26x5vQwsGAvoJitXrp4yqT-o_0kwgQbACy14dfIlSZxFuuqpeY8DP2fB8HyvHOSEGZHgn3SNUm7r4SE8QcfOvWr3qXKJSj18va_qBxfpliuZDX0oVnAZbUaKlyF3NmSnh1QR3kedxAI9YO5OkOXRIQyLp3H5NdECP4unflEvzBzWfKMltNiKfDsuQsc78snxpwW1dQRBTuVW-o1nxOY8zXQ77WAf4vHCyUWBRSrtu2NAC3VtIv_hXRsW9dAJxWm2Kh3WdbsFq6sRHv4pC2UdFeX-Dr7P8uEg9ZRE0-IgMpVMrQpd5IrP6zp06D5duQYEjLqu1BjSYZtdqGFC5MYWGmCIM_WH7QYsRrYwLviFGAMfFGfWFG1sakbYTXGdCI8e0KOGWwhpgaaqO57PttyBMRcEE-obF5wapYsfIyN5_BpbA9caDc1I5b_KHrS5FBewcakqq0-wFt8-3LIe8Yt2LJWnmPzWAY-qN9s98sj7TyJf5UOFKfjhZqhlkXTPTI95yC_vjZ92vRz2XgPGVsdwF6PpEDKgOzkcM8oF0VRG0G85Xc_COgZsnidtnNpYrHN4o7OgATDo2NalIueES1Edi90-9YHG-P7xCMvCVbXdwybuE2WErKTxo1oC8rN0uThyxU_vWWzhC5iXQOGazx8Aty2cPo5uJQII8JQ==","summary":[{"type":"summary_text","text":"**Assessing need for additional yield**"}]},{"id":"fc_0f2355a59a2a33ce016a58aa804ea0819abf6139dcfef72444","type":"function_call","status":"completed","arguments":"{\"result\":{\"data\":{\"status\":\"complete\",\"coordination\":\"Released adapter/extension-test ownership to FixExtensionReview with the completed behavior and verification constraints.\"}}}","call_id":"call_HA3zLuFdIeuEwbJuf0BLNdHr","name":"yield"}]},"duration":9580.844200000167,"ttft":4036.216599999927,"contextSnapshot":{"promptTokens":111253,"nonMessageTokens":26371}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_HA3zLuFdIeuEwbJuf0BLNdHr|fc_0f2355a59a2a33ce016a58aa804ea0819abf6139dcfef72444","toolName":"yield","startedAt":"2026-07-16T09:55:13.986Z"},"id":"c561e557","parentId":"33739a7e","timestamp":"2026-07-16T09:55:13.986Z"}
{"type":"message","id":"67d790a7","parentId":"c561e557","timestamp":"2026-07-16T09:55:13.987Z","message":{"role":"toolResult","toolCallId":"call_HA3zLuFdIeuEwbJuf0BLNdHr|fc_0f2355a59a2a33ce016a58aa804ea0819abf6139dcfef72444","toolName":"yield","content":[{"type":"text","text":"Result submitted."}],"details":{"data":{"status":"complete","coordination":"Released adapter/extension-test ownership to FixExtensionReview with the completed behavior and verification constraints."},"status":"success"},"isError":false,"timestamp":1784195713986}}
{"type":"message","id":"c8b42cb6","parentId":"67d790a7","timestamp":"2026-07-16T09:55:21.217Z","message":{"role":"assistant","content":[{"type":"text","text":"","textSignature":"{\"v\":1,\"id\":\"msg_0f2355a59a2a33ce016a58aa881754819a9aaf8de7e5e9b92e\",\"phase\":\"final_answer\"}"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-5.6-sol","usage":{"input":6462,"output":4,"cacheRead":104960,"cacheWrite":0,"totalTokens":111426,"cost":{"input":0.032310000000000005,"output":0.00012,"cacheRead":0.05248,"cacheWrite":0,"total":0.08491000000000001}},"stopReason":"stop","timestamp":1784195713991,"responseId":"resp_0f2355a59a2a33ce016a58aa82e5dc819a88ff51c95cbc99ab","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"msg_0f2355a59a2a33ce016a58aa881754819a9aaf8de7e5e9b92e","type":"message","status":"completed","content":[{"type":"output_text","annotations":[],"logprobs":[],"text":""}],"phase":"final_answer","role":"assistant"}]},"duration":7225.731200000271,"ttft":6067.3908999999985,"contextSnapshot":{"promptTokens":111422,"nonMessageTokens":26371}}}
{"type":"custom","customType":"session_exit","data":{"reason":"dispose","kind":"normal","recordedAt":"2026-07-16T10:02:21.224Z"},"id":"584a155b","parentId":"c8b42cb6","timestamp":"2026-07-16T10:02:21.224Z"}
