Changelog
0.9.0 (2026-09-10)
- fix(scaffold): validate a knob's VALUE, not only its name (#925) (#935)
- fix(session): spend the completion-nudge budget per turn, not per session (#934) (#936)
- fix(plugins): make out-of-tree plugin authoring safe (#917, #918) (#933)
- feat(webhook): secret_algo "token" for plain shared-secret headers (#930) (#932)
- feat(spawn-schema): ratify spawn_payload_schema as a string-shaped boundary (#883) (#931)
- feat(profiles): max_completion_nudges — the nudge budget is the deployment's (#919) (#927)
- fix(enrichment): every dict tool result reaches the enrichment chain (#922) (#924)
- fix(runner-rpc): serialise bytes as base64, not as a Python repr (#920) (#921)
- fix(session): record signal_completion's tool result so a completed session stays revivable (#913) (#915)
- fix: satisfy the two contract guards this branch broke
- feat(resume): both resume verbs carry an attachment (#845) (#914)
- feat(providers): native OpenAI (Chat Completions + Responses API) and Azure OpenAI (#907)
- skill: state the
plugins: []case outright — the wrong rule is in circulation - scaffold: make
--userreal — the listing promised a flag the parser rejected - scaffold:
integration, notinstall— jaato's side of a contract with a tool - scaffold:
dependenciesas a facet of any explain scope, and a doctor check - feat(providers): MiniMax, Kimi and MiMo providers, and the reasoning-replay seam they need (#875)
- scaffold:
installverb — ship the skill with the framework, stamp every copy - template: make output-path routing a profile knob (#900) (#903)
- runner pool: a reservation is not capacity (#898) (#901)
- explain paths: state that config_root is framework-owned (#896) (#897)
- fix(apparmor,template): deny writes to .jaato/templates/ under confinement (#893) (#894)
- feat(runtime_limits): expose tool concurrency as max_parallel_tools (#862)
- feat(web): replace the web-client PoC with jaato-web, a browser client on @jaato/sdk
- fix(sdk,scaffold,lsp): four defects found building a cascade harness on the SDK (#879)
- fix(runner): carry slot-scoped plugin instances across cascade sessions (#890) (#891)
- fix(service_connector): mark call_service results untrusted (#857) (#878)
- feat(permission): the resolved event, the ledger and the session record name who decided (#859) (#876)
- fix(trace): record the resolved tool name beside the hashed wire id (#873) (#874)
- feat(security): scrub secret env vars from model-driven subprocesses by default (#863) (#872)
- fix(media): the spoken transcript rides the final media chunk to the client (#869) (#871)
- docs: AppArmor is not premium, the licence is not MIT, image input is not 4 of 13 providers (#866) (#870)
- fix(gc): evict consumed inbound media, and let GC see media at all (#850) (#853)
- feat(scaffold): the sweep gate as one set, and make its ceiling actually work (#768 #769 #770 #772) (#849)
- fix(session): history replay is gated by what the ACTIVE model can consume (#847) (#848)
- fix(scaffold): the templates take their turn from the SDK facade (#820 #821 #825 #826 #827 #822)
- fix(web_search): file the tool under
web, the category that advertises it (#843) (#844) - fix(daemon): an attachment is content, so a message carrying one is not empty (#838) (#841)
- fix(session): an attachment in the message no longer means "do not stream" (#837) (#840)
- feat(tiers): let a deployment NAME its own tiers (#831) (#839)
- feat(providers): give the framework ears — audio input reaches a model (#830) (#835)
- fix(providers): dispatch inbound attachments on mime instead of assuming image (#829) (#833)
- feat(tiers): a tier that exits on completion, and a final flag that comes from the wire (#828)
- feat(media): deliver binary media chunks, and know when a spoken turn ended (#824)
- feat(tiers): per-tier description + direction-qualified modality roles (#818)
- fix(tests): stop credential tests reading the developer's machine, and printing the key (#721, #734) (#817)
- fix(introspection): make an unknown category_id recoverable in one round-trip (#754) (#816)
- fix(file_edit): name the failure, not just the remedy, on edit errors (#813, #814) (#815)
- fix(sandbox): allow POSIX pseudo-devices, so 2>/dev/null works (#784) (#811)
- fix(background): don't issue a task_id no tool in the session can read (#810)
- fix(file_edit): preserve line endings, honouring the repo's setting (#805) (#809)
- feat(app-identity): let an application name itself, not report as jaato (#808)
- chore: normalise line endings to LF, once, in one commit (#794) (#807)
- feat(events): carry the billed prompt/output split on the wire (#802) (#803)
- fix(tui,permission): make a permission prompt readable, and answerable only as chosen (#796)
- feat(session): a revive wakes from persisted state, not from disk (#787) (#795)
- feat(env): tag every env var with its scope and promote the trace paths (#775) (#793)
- fix(profiles): a child can decline one inherited completion processor (#791) (#792)
- fix(file_edit): reject updateFile with no content instead of truncating (#782) (#788)
- fix(providers): a stream that dies mid-response is not a finished turn (#687) (#786)
- feat(scaffold): explain the user-facing command surface (#715) (#785)
- fix(tui,clarification): answer a batched clarification instead of hanging (#704) (#783)
- fix(openrouter): a bare finish_reason="error" names its cause and retries (#766) (#780)
- fix(plugins): reserve built-in plugin names against entry-point shadowing (#684) (#779)
- fix(egress): loopback is reachable only at the proxy's address:port (#696) (#778)
- fix(sdk,session): a turn boundary is not the session's terminus (#767) (#774)
- fix(providers): one prompt-token convention, converted at the seam (#758) (#763)
- fix(session): a turn cut off at the output cap must be continued, not lost (#749) (#759)
- docs(scaffold): name the profile env: block where authors look (#752) (#760)
- fix(session): a call the severed turn never ran must still be answered (#751) (#757)
- fix(providers): unreadable tool-call arguments must not become a call (#750) (#753)
- fix(providers): a truncated turn must not report as a tool-use turn (#745) (#747)
- fix(security): close the symlink escapes in file tools and search (#669) (#746)
- fix(daemon): refuse a relative path at the process boundary (#742) (#744)
- fix(openrouter): bound a single request with an idle deadline (#732) (#743)
- perf(ci): memoize the whole-tree env scan and fan the suites out (~11min -> ~4min) (#740)
- fix(cache): model tiers × prompt caching — the knobs never arrived, and the cost was invisible (#737)
- fix(cli): segment compound commands in the permission analyzer (#668) (#739)
- docs(scaffold): document what
newproduces (#738) - feat(openrouter): put the session id on the wire so a conversation groups (#733)
- fix(openrouter): read the Retry-After hint OpenRouter puts in the body (#720)
- feat(prompt): narrate tool calls as they happen, and give batching a decision rule (#711)
- fix(providers): rebuild the HTTP client after a connection error (#709)
- feat(plugins): declare the session-persistence contract, and use it for permissions (#708)
- fix(session): a profile-less session got no tools, and the enabling tool was documented as a lookup (#703)
- fix(pool): the pre-warm pool had a floor and no ceiling (#667)
- fix(events): the 64-call-site emit path now says which session it is about (#666)
- test(guards): a guard that cannot detect its own reversion now fails the build (#665)
- fix(memory): list_memory_tags reported an empty store while holding a raw queue (#664)
- fix(scaffold): a sweep job that could not do its work is not a result (#662)
- docs(subagent): the prefetch README documented the behaviour that caused fabrication
- feat(daemon): separate the threads that are blocked from the one that is blocking (#659)
- fix(ci): the complexity ratchet measured build artifacts, so it was green only on CI (#658)
- fix(daemon): the manager lock was held across a round-trip to the loop (#657)
- ci: cyclomatic-complexity ratchet, fixed so it cannot silently skip (#656)
- feat(daemon): a stalled loop now names the thread that HELD it, not just the one that waited (#655)
- feat(events): a stage that was asked twice to signal completion, and never did, says so (#654)
- test(guards): a lazily-discovered cache must never be observable half-built (#653)
- fix(secrets): the resolver registry was published EMPTY before it was filled (#652)
- fix(scaffold): every template now tracks the SDK contract it was written for (#650)
- feat(scaffold): a
sweeparchetype for N independent arms (#649) - fix(runner): a reused pool slot no longer carries the previous session's env (#647)
- fix(history): a history request is answered or refused, never met with silence (#645)
- fix(usage): a provider-reported cost now reaches TurnCompletedEvent (#644)
- fix(session): a terminal event is now the last thing a session emits (#643)
- fix(cascade): an exhausted pool no longer hands back a working-looking handle (#642)
- feat(echo): a provider that costs nothing can still REPORT a spend (#641)
- feat(sdk): one pairing rule, in the layer consumers can import (#640)
- fix(history): the call side carried no identifier, so nothing could be paired (#639)
- fix(daemon): the last silent cache writer, and a property that lied (#638)
- fix(daemon): the context-limit heal path now says what it did (#637)
- fix(delivery): unreachable was five outcomes wearing one word (#634)
- fix(daemon): the loop can no longer deadlock on itself (#633)
- fix(memory): a usage write-back can no longer undo a curator's decision (#632)
- feat(daemon): a stalled event loop now names what it was doing (#631)
- fix(memory): reading the raw queue no longer empties it (#630)
- fix(lifecycle): the transport branch now actually exits — #628 fell through (#629)
- fix: three things that told a caller something false (#628)
- fix(observability): make two shipped fixes readable — #623's witness, and what the outer timeout means (#627)
- fix(session): saves of one session serialize; unrelated sessions do not (#626)
- fix(rpc): a stacked timeout now says WHICH of the two fired (#625)
- feat(runner): give the control plane its own lane (#624)
- fix(delivery): the wind-down stash was a slot, not a queue — #620 regression (#623)
- fix(delivery): make
unreachablesay why — and not render a timeout blank (#622) - docs(delivery): retire the queued caveat that #620 fixed (#621)
- fix(delivery): the session decides whether a turn will drain your message (#620)
- fix(inject): an inject into an idle session was a black hole, and said "ok" (#619)
- diag(sibling): log the busy decision — stale flag and mid-turn look identical (#618)
- fix(cascade): a message queued to a busy peer that went idle was stranded (#617)
- feat: cascade refusals reach observers; explain reports inherited instruction cost (#611)
- feat(scaffold): explain plugin publishes tool PARAMETERS (#615)
- fix(session): an orphaned fragment crashed EVERY drain that had a callback (#616)
- fix(diagnostics): model-loop frames were discarded before an ErrorPayload existed (#614)
- fix(diagnostics): runner-side tracebacks never reached any consumer (#613)
- refactor(delivery): one queue-or-drive decision for every message sender (#612)
- fix(sibling): a cold sibling reported no_such_sibling, not sibling_cold (#610)
- fix(session): attach lost a session its daemon-side plugin wiring (#609)
- fix(executor): two 2-tuple conventions shared one representation (#608)
- feat(session): session.send — nudge a NAMED session without the model (#607)
- feat(subagent): send_to_sibling — cascade messaging with a receipt (#606)
- fix(history): request_history sent tool results as a Python repr, not data (#605)
- fix(security): the untrusted-content mark must survive every ToolResult rebuild (#604)
- feat(protocol): every event says which session it is about (#603)
- fix(rpc): a forwarded executor's (ok, payload) contract must survive the wire (#602)
- fix(plugins): migrate status-error results to the key the checker reads (#601)
- fix(subagent): list_siblings never forwarded — the registry hook was missing (#600)
- feat(subagent): list_siblings — the cascade roster (#599)
- feat(protocol): correlate session.new with the event that answers it (#598)
- fix(session): a sibling-name refusal must reach the client (#596)
- docs(scaffold): there is no jaato.premium_reactors entry-point group (#595)
- fix(session): cascade membership must survive a reload (#594)
- fix(sdk): sibling_name reaches the facade — and peer→sibling for the coordination surface (#593)
- feat(session): peer_name — a cascade-scoped address validated at session.new (#592)
- fix(scaffold):
newmust not blame itself for USER-tier profile errors (#591) - feat(queue): SourceType.PEER, idle-only, and tier membership declared once (#590)
- fix(permission): gate parent-authority answers on the stamped sender, not content (#589)
- feat(budget): create-time budget_control + budget_usage params (#588)
- feat(gc): typed GC lifecycle events on the bus (#587)
- refactor(gc): route every GC pass through one instrumented path (#586)
- fix(budget): surface a ceiling refusal as a terminal, typed event (#584)
- fix(budget): carry the CEILING across a reload, and stop destroying the snapshot (#583)
- A ceiling that fired before a suspend still refuses after the resume
- budget_usage never reached disk: the serializer writes a fixed key list
- Wire budget usage through save/restore so the ceiling actually survives
- Drop a wall-clock floor that measured the runner, not the handshake
- budget_control: usage survives a reload, and an abort has a typed signal
- HOTFIX: bound_model_for_profile was not bound at module scope (#576 broke all profile sessions)
- Tiers-only profiles: fix the remaining producers; make completion latches per-turn
- One definition of "the model a profile binds" (fixes two #574 follow-ons)
- A tiers-only profile can bootstrap a session
- feat(telemetry): include the system prompt in OpenInference input spans
- notebook analyzer: report bare dangerous attributes, anchor relative paths (closes the last 2 xfails)
- disable_colors() now suppresses syntax highlighting too (closes 2 xfails)
- Surface a backgrounded tool's return value on the poll (closes 4 xfails)
- Declare Jinja2 in the
templatesextra (CI could not run the template tests) - Repair the final shared/plugins failures (0 failing, 8 recorded gaps)
- Repair todo/memory/lsp tests; record the disable_colors gap
- Repair shared/plugins/tests (was 4 failing)
- Repair model_provider tests + stop them reading real credentials
- Fix the webhook -> EventBus bridge: capture the bus at subscribe time
- Record: the webhook -> EventBus bridge never publishes
- Repair references merge tests (375 passing; was 5 failing)
- Fix UnboundLocalError that broke inline mermaid rendering
- Repair filesystem_query tests (was 9 failing)
- Repair subagent tests (373 passing; was 13 failing)
- Fix privilege escalation: askPermission granted the whole tool, not the call
- Repair permission tests + record a privilege-escalation defect
- Repair background tests + record a real capability gap (89 pass, 4 xfail)
- Repair file_edit tests (292 passing; was 8 failed + 20 errors)
- Repair 59 stale test doubles in server/tests (0 failing, was 59)
- Make the truthy-but-empty exception mistake hard to write
- Fix the empty () in the push-timeout log; record that the bound is conservative
- cascade.budget.get states its scope in the payload
- Degrade steps apply at most once and in order, per ladder not per tracker
- Budget origin labels now name the MECHANISM, not whose ladder
- Separate budgets: a child that declared one is not clamped by the parent
- Isolated subagent spawns dropped the profile's declared budget
- Subagents never received their own declared budget
- A profileless cascade child inherits the cascade's degrade ladder
- A push timeout means DELAYED, not lost — and the log said otherwise
- scaffold: add --secrets flag; default profiles to env-var credentials
- Cascade degrade notices must be emitted by the daemon, not the session
- Fix: the degrade-push dispatch read a field that does not exist
- Fix: the cascade degrade push blocked the whole SessionManager
- Fix: concurrent create_session issued DUPLICATE session ids
- Slice 3: push a crossed cascade rung to already-running children
- test: pin the cascade observer/attached-client dedup
- Cascade refusal must reach the client, not just the daemon log
- Cascade pool: reconcile against the session tracker, not the event stream
- Fix: a CANCELLED turn's spend reached no TurnCompletedEvent
- IPC verbs for cascade budgets: set / get / clear
- Slice 2: cascade budgets wired — declare, accumulate, clamp at spawn
- Thread spend_total_tokens to the client (UsageBreakdown)
- Fix: spend_* was accumulating on the streaming path only
- Separate per-turn SPEND from end-of-turn context size
- CascadeExhaustedError carries framework-generated evidence
- Add CascadeBudgetPool: the aggregate cascade ceiling (design note §8/b)
- Budget: a refused turn must not emit TurnCompletedEvent
- Budget: enforce the ceiling past the first abort; surface to the client
- Fix: envelope producer never populated budget_control (feature was dead)
- Implement budget_control runtime layer: tracker + brownout degradation
- Implement budget_control config + scaffold discoverability
- telemetry: set_llm_span_attributes hook (prompt→trace linking) + fix flaky budget-gate tests
- feat(session): pre-flight refuse-send gate (PayloadExceedsContextError)
- telemetry: emit user.id for Langfuse User Tracking
- test(apparmor): teach Reg stub the all_plugins() contract
- telemetry: emit trace-level input/output on the turn (AGENT) span
- docs(apparmor): de-brittle plugin-count in composer self-filter comment
- fix(telemetry): POST Langfuse spans to the /v1/traces signal path
- telemetry: propagate session.id to child spans for Langfuse best practices
- test: allowlist JAATO_TELEMETRY_BACKEND in session-env audit
- telemetry: pricing-table cost on spans + dedicated Langfuse backend
- telemetry: stamp provider cost on LLM spans + OTLP protocol selection for Langfuse
- fix(session): close the turn lifecycle on solely-%name--help messages
- fix(apparmor): make .jaato/prompts runner-writable so save/deletePrompt work
- test(apparmor): pin that rendered profiles actually COMPILE, not just render
- Revert "Merge pull request #547 from Jaato-framework-and-examples/claude/deleteprompt-apparmor-delete-grant"
- fix(plugins): repoint environment/calculator off the bare jaato facade import
- fix(prompt_library): grant AppArmor delete on writable prompt/skill tiers
- fix(introspection): guardrail against fabricated tool ids leaking to users
- fix(prompt_library): document the placeholder grammar at both authoring surfaces
- feat(session): surface abnormal finish reasons to clients
- docs(doubleword): correct the catalog auto-detect claim (verified live)
- Add Doubleword provider plugin and service_tier knob
- feat(instructions): granular suppress_base_instructions (disk/constants/security)
- fix(context): return 0 (honest unknown), not hardcoded 1M, when provider unmaterialized
- core: read conversation history from the runner (fix empty transcript on cold WS reattach)
- inline profiles: honor the spec's own name (stop dropping it for "")
- session restore: re-apply the profile's suppress_base_instructions
- test: update session serializer version assertion 2.6 -> 2.7
- session restore: reconstruct inline-profile sessions from a persisted spec
- session_manager: resume WS workspace-pinless sessions via the session-workspace index
- tool_id_map: scrub markdown-escaped tool ids (t_xxxxxxxx)
- prose_tools: drop the example tool id from the injected preamble
- chrome_ai: add reuse_page to anchor onto an existing tab
- chrome_ai: warm the on-device model at connect() to absorb cold-start
- Add direct-provider smoke for the prose_tool_calls quirk
- Add prose_tool_calls quirk: prose-emulated tool calling for tool-less models
- Add chrome_ai model provider: Chrome built-in AI (Gemini Nano) via CDP
- refactor(facade): ship the
jaatoconvenience facade in jaato-sdk (sdk-only client) (#527) - feat(providers): OVHcloud AI Endpoints model provider plugin (#526)
- feat(sdk): public open_event_stream() — synchronous-subscribe event iterator (#524)
- fix(wake): release wake bindings + index entry on session DELETE (orphan fix) (#523)
- feat(scaffold):
explain events/explain event <NAME>— the event protocol (#522) - fix(wake): headless client-tool dispatch — whitelist sync + drive-after-wiring (#521)
- feat(server): durable deferred-turn wake (Option 2 — cold-revive-and-act) (#520)
- feat(server): surface daemon wake endpoint on bind_wake (production routing) (#519)
- feat(server): mode-B wake verify shim — daemon-tier HTTP ingress (PR 2b) (#518)
- feat(server): wake binding registry + bind_wake/unbind_wake (PR 2a, mode-B foundation) (#517)
- feat(server): session.wake — client-agnostic daemon wake primitive (PR 1 core) (#516)
- fix(security): validate session_id to close path-traversal / profile-injection (#502)
- fix(permission): trusted bridge suppresses the prompt, not the hard deny-layers (#501)
- feat(mcp): scrub declared secrets from MCP server subprocess env (#10, MCP half) (#500)
- style(webhook): restore CRLF line endings on 3 test files (#499)
- fix(webhook): fail-closed auth — unsigned routes refused unless explicitly opted in (#498)
- fix(web_fetch): code-gate insecure/no_proxy behind operator opt-in (was prose-only) (#497)
- fix(permission): whitelist glob can't auto-allow unauthorized shell operators (#496)
- security: untrusted-content trust boundary for web_fetch/web_search/MCP (#495)
- docs(env): document env vars via # env: comments (#494)
- ops: env-var discoverability — live overrides at startup/--status + explain-env descriptions (#493)
- Security hardening + per-session egress confinement (proxy + cgroup-nft) (#492)
- fix(cascade): dedup post-bootstrap events for an owner==observer (single IPC connection) (#491)
- fix(tool-results): keep result STRUCTURED; move model-facing steering to ToolResult.model_suffix (#490)
- fix(host-tools): decode client-tool results to native dicts (flat), symmetric with in-process tools (#489)
- fix(permission): exempt framework-reserved tools (incl. signal_completion) from the default evaluator — corrects #487 (#488)
- fix(permission): framework core tools are exempt from a catch-all "default" evaluator (#487)
- fix(secret-uri): fail loud on the single-colon
pass:typo (was leaking as a bearer token) (#486) - fix(providers): surface the profile api_key knob in APIKeyNotFoundError checked-locations (#485)
- fix(providers): verify_auth reads the
configparam, not self._config (in-process crash) (#484) - fix(scaffold): library exception states the fact, not a caller-convention hint (#483)
- fix(plugins): concise WARNING for missing-dependency plugin skip during discovery (#482)
- chore(release): bump jaato-server 0.6.194 → 0.6.195 (scaffold extension seam) (#481)
- feat(scaffold): verb-extension point for external (premium) verbs (#480)
- fix(tools): pip shim + venv-bin exec grant so bare
pip/!pipworks confined (supersedes #478 ensurepip) (#479) - fix(tools): materialize pip in workspace_venv so bare
pip/!piptargets the tool-venv (#478) - feat(notebook): IPython-style per-line !shell escapes (make the tool's own advice work) (#477)
- feat(permission): give evaluator scripts the session's prior-decision journal (EvalContext.execution_log) (#476)
- feat(scaffold): surface + validate non-provider plugin config knobs (permission.evaluators, cli.workspace_venv, …) (#475)
- fix(tools): scope the workspace_venv runner-import bridge to jaato srcs (no base-venv over-share) (#474)
- fix(tools): confined pip for workspace_venv — plugin-scoped distro reads + cli foreground venv activation (#473)
- fix(tools): bridge runner imports into workspace_venv so the notebook kernel can import shared.* (#472)
- feat(tools): workspace_venv knob on cli/interactive_shell/notebook for dynamic tool deps (#471)
- chore(deps): declare wcwidth as a core dependency (#470)
- fix(daemon): orphan-revive recipe loss — persist+restore sandbox_mode (apparmor) AND agent_name (persona/vision) (#469)
- feat(memory): allowed_scopes write-side gate (deployment scope policy) (#468)
- feat(scaffold): reproducible provenance line +
new --transport in_process(#464) - feat(scaffold): --ca for --transport ws — scoped wss:// CA (completes #462 alignment) (#463)
- feat(scaffold): support --transport ws --recoverable -> WSRecoveryClient (#461)
- feat(facade): expose recovery as a facade mode — session(mode=…, recovery=True) (#460)
- fix(introspection): keep discovery tools when real tools exist, drop only for empty wire (ex08 lead hang) (#458)
- fix(introspection): gate discovery GUIDANCE with the tools (ex08 0-tool subagent loop) (#457)
- fix(in-process): completion-nudge gate keys on terminal injects, not is_running (ex08 #5C premature-completion) (#456)
- fix(in-process): drive lead completion nudge + emit SESSION_TERMINATED (ex08 gap #5C/#5D) (#455)
- feat(in-process): auto-continue the lead when a subagent injects (ex08 gap #5B) (#454)
- fix(in-process): bridge subagent events to the facade loop (set subagent ui_hooks) (#453)
- fix(subagent): UnboundLocalError in spawn_subagent (conditional get_workspace_root import) (#452)
- fix(in-process): populate session-context workspace_root/config_root for spawn (#451)
- fix(in-process): parse plugin-entry modifiers ((preload)/tool-scopes) like the daemon (#450)
- feat(in-process): forward client_tools (host tools) through the facade (#449)
- fix(session): gate plugin instructions by plugins, not the dead tools alias (+ in-process None/[] IPC parity) (#448)
- fix(in-process): pin config_root on the embedded runtime (~/.jaato isolation leak) (#447)
- docs+scaffold: multi-transport (in-process / IPC / WebSocket) (#445)
- feat(sdk): WSClient — WebSocket transport for the facade (remote daemon) (#444)
- test(in-process): stream() + multi-turn continuity (PR4) (#443)
- feat(in-process): plugin parity — init full runner-tier ONCE at connect (#442)
- fix(daemon): agent without --profile no longer goes bare (persona dropped) (#441)
- feat(in-process): thread suppress_base_instructions (the base-composition knob) (#440)
- feat(in-process): agent-persona resolution (ex03) + lift resolve_agent to shared (#439)
- feat(in-process): AGENT_COMPLETED emission — completion payload reaches the facade (ex04) (#438)
- feat(in-process): profile resolution + system_instructions/completion schema (PR3) (#437)
- fix(in-process): pass the loaded permission plugin so the session gates (ex07) (#436)
- feat(in-process): plugin-loading + permission-channel wiring (InProcessClient) (#435)
- feat(in-process): InProcessChannel permission bridge (PR2 mechanism) (#433)
- fix(in-process): env_file is a both-modes kwarg, not IPC-only (#431)
- feat(in-process): transport-agnostic jaato.session(mode=...) entry (#430)
- feat(in-process): minimal real ex01 path — cred resolve + verify_auth + configure_tools (PR1.5) (#429)
- feat(in-process): InProcessClient adapter — facade tracer-bullet (PR1) (#428)
- feat(config): public resolve_secret_uri entry point (#427)
- feat(mcp): model-callable mcp_reload tool, gated on .mcp.json existing
- fix(provider): fail loud on an unresolved secret-URI api_key (cascade-of-bugs sibling)
- fix(bus): hoist typed signal_completion payload onto the bus event (cascade handoff)
- fix(runner): drain a USER send that races the turn wind-down (multi-turn deadlock)
- fix(clarification): runner→daemon relay so runner-tier sessions can deliver clarifications
- docs(continuity): memory enrichment is curated-only → curator is REQUIRED
- fix(scaffold): send-and-wait client templates no longer hang on a plain turn
- feat(scaffold): validate tags each finding with its source tier (workspace vs user)
- fix(scaffold): validate — model_tiers satisfies the model requirement (no false missing_model)
- feat(daemon): SessionManager.resume_session — public same-id reload + presentation restore (reliability T2)
- feat(daemon): daemon-wide reactor EventBus — per-session buses sink into one bus reactors subscribe to
- feat(daemon): SessionManager.get_persisted_history — read a persisted session's history without loading it
- fix(bundle_common): discover_bundles DEBUG-skips an EACCES-denied tier root (confined user tier)
- feat(daemon): SessionManager.send_message_to_session — drive a turn on a loaded session (same id)
- feat(scaffold): validate prefetch directives — the validate counterpart to explain prefetch
- docs(scaffold): add
explain prefetch— surface the prefetch-script capability - fix(re-attach): gate session_get_tool_schemas RPC off-loop (re-entrancy regression)
- fix(re-attach): daemon walk ALWAYS excludes runner-tier + off-loop runner-ready re-emit
- fix(lifecycle): prepare_completion accepts dot-notation into free-shape objects + minProperties floor
- fix(re-attach): tool-id emit skips runner-tier plugins on the loop (re-attach stall)
- fix(prompt_library): mtime-gate _discover_prompts (re-attach loop-stall root cause)
- diag(runner): + daemon-side [RPC_DIAG] _in_flight SET + read_loop RESPONSE (id/in_flight_had/client) to pin the reused-transport reply-match miss
- diag(runner): [RPC_DIAG] trace serve-recv / worker ENTER+EXIT to localize the re-attach register stall (THROWAWAY diag branch, not for merge)
- docs(scaffold): document profile inheritance semantics in
explain profile - fix(providers): thread api_params sampling knobs in google_genai/antigravity/github_models/ollama (audit follow-up)
- fix(vllm): thread api_params sampling knobs (temperature/top_p/seed/…) into the request
- fix(runner): gate mid-session client-tool push + send on bootstrap-complete, not rpc-handle-live
- feat(events): bridge gate.released onto the reactor event bus
- fix(restore): resolve config_root on disk-restore so a config_root=None session can't hang the runner
- feat(scaffold): explain paths — the daemon-global vs per-session isolation model
- feat(session): SessionManager.set_session_state_for_session — cross-session state write
- feat(permission): reliability T3 foundation — approved-overrides-escalated
- feat(permission): reliability T1 — deny escalated tools on headless clients
- fix(core): skip conversation replay on attach for chat-type clients
- fix(session): thread attaching client_id into restore-spawn so re-attach re-spawns the runner (#370 follow-up)
- fix(session): close the attach-vs-unload race — the real (a) for the re-attach bug
- fix(core): await runner readiness on send instead of derefing None _runner_rpc (attach race)
- feat(permission): reliability Phase-2 interactive escalation gate (public read-hook)
- fix(scaffold,vllm): stop two validator false positives (api_key credential knob + vllm api_params layer)
- fix(file_edit): _ensure_gitignore must not fight a deliberate .gitignore setup
- fix(provider): scrub tool-hash-ids out of user-facing model narration
- fix(notebook): make kernel preexec_fn fork-safe (hoist ctypes/CDLL out of the fork window)
- fix(notebook): actually use the subprocess kernel (cutover was bypassed) + propagate ContextVar to streaming thread
- fix(notebook): kernel chdir to SESSION workspace via ContextVar; broadcast workspace to all plugins
- feat(notebook): subprocess kernel — PR 3 (lifecycle + cutover to default)
- feat(notebook): subprocess kernel — PR 2 (cross-process tools bridge + permission)
- feat(notebook): subprocess kernel backend — PR 1 (kernel + transport + cwd=workspace)
- fix(client-tools): client/host tools default to 'core' (eager), honor discoverability
- feat(client-tools): mid-session host-tool registration — glue schema to live runner
- fix(model-tiers): cross-provider tier provider got no plugin_configs (no api_key)
- fix(profiles): _merge_profiles dropped model_tiers (inherits/set tiers lost)
- feat(scaffold): explain
tierstopic + model_tiers vision example (V2 tooling) - test(model-tiers): seed _provider_cache/_active_provider_name in the new helper
- feat(model-tiers): V2 cross-provider tiers — swap providers on tier switch
- feat(multimodal): ferry user-message attachments to the runner-tier model
- fix(client-tools): call daemon_plugin_execute with keyword args (execution)
- feat(client-tools): IPC transport support + SDK register_client_tools + host-tools scaffold
- fix(client-tools): seed client_tool_schemas before the runner spawn (#349 race)
- feat(client-tools): inject client-provided tools into the runner-tier model
- feat(tooling): runtime-entity debugging — explain runtime + doctor --session
- fix(runner): seed workspace ContextVar + env so path plugins resolve the session
- feat(scaffold): surface the recoverable client (IPCRecoveryClient)
- feat(session): gate introspection on the presence of something to discover
- feat(scaffold): surface discovery-gated (deferred-unless-preloaded) tools
- feat(tooling): WebSocket awareness in doctor, scaffold, and the client skill
- fix(plugins): memory/references/subagent must not self-disable under confinement
- fix(tests): _verify_connectivity stubs must accept the probe_url arg
- refactor(providers): migrate vllm onto OpenAICompatLocalHostProvider (PR7, final)
- refactor(providers): migrate zhipuai_openai onto OpenAICompatProvider (PR6)
- refactor(providers): migrate lmstudio onto OpenAICompatLocalHostProvider (PR5)
- refactor(providers): migrate triton onto OpenAICompatLocalHostProvider (PR4)
- refactor(providers): OpenAICompatLocalHostProvider base + migrate tensorrt_llm (PR3)
- feat(scaffold): explain surfaces config + profile descriptions (self-contained)
- refactor(providers): migrate nebius onto OpenAICompatProvider + lift api_params (PR2)
- refactor(providers): add OpenAICompatProvider base + migrate nim to it (PR1b)
- refactor(providers): relocate shared OpenAI-compat converters + _lazy to _openai_compat
- test(providers): guard that no unhashed tool name reaches the LLM + Anthropic tool_choice shape
- fix(providers): map name-bearing tool_choice through name_to_id (wire id)
- fix(server): --stop/--status find client-autostarted daemons via the socket
- feat(nebius): cached_tokens measurement + extra_body passthrough (vLLM caching)
- fix(server): raw docstring for check_pipe_exists (silence \p invalid-escape warning)
- feat(sdk): doctor daemon-env report drives off the introspected read-set
- feat(sdk): explain provider resolution order + credential-chain contract
- feat(sdk): client doctor + jaato-scaffold tool + provider knob/quirk contract
- feat(providers): PDF input for Anthropic + Google (fast-follows on the contract rails)
- feat(providers): PDF input support (producer + pdf_input capability + OpenRouter marshalling)
- fix(providers): close remaining capability gaps (google tool-result vision, ollama/zhipuai modality)
- fix(providers): Phase 3 — close high-severity capability gaps (NIM-fleet vision, claude_cli honesty)
- feat(providers): model-provider capability contract + CI conformance guard
- fix(multimodal): make the agentic tool-result image path work for OpenAI-compat
- fix(openrouter): marshal user-message image parts in the wire converter
- fix(providers): marshal image parts in the OpenAI-compat converter
- feat(reliability): compute is_error_result on tool.call_completed
- feat(echo): add deterministic creds-free echo model provider
- fix(ephemeral): terminate single-shot ephemeral on turn.completed
- fix(ephemeral): set config_root on scratch/inline spawn so core plugins expose
- fix(ephemeral): decouple inline display-name from agent resolution + provision scratch workspace
- fix(websocket): drop shadowing local import os in _apparmor_session_hook
- feat(subagent): bridge remote-spawn runner->daemon (restore server= under seat-flip)
- fix(telemetry): implement reset_for_next_session + guard the protocol class
- fix: stamp daemon session_id per-session so memory reads it, not shared registry
- fix(plugins): resolve session per-execution in telepathy/memory (no self leak)
- test(env-audit): sync ALLOWLIST — drop 22 migrated entries, add 4 daemon-tier
- test(session-state): expect serializer schema version 2.4
- test(runtime-limits): add required plugins key + opt-in gate cgroup e2e
- test(signal-completion): seed _accumulated_payload + _provider on stubs
- test(deferred-instructions): set _tool_scopes on the new-built session
- test(budget): set _tier_config on the new-built session stub
- test(visibility-filter): add _apply_tool_scopes to session stub
- test(server-version): pass now-required client_type to IPC client ctors
- test(dynamic-instructions): drop tests for the removed render_completion_artifacts API
- test(enrichment): add reset_for_next_session to stale protocol fixtures
- fix(telepathy): implement ToolPlugin protocol methods so the plugin loads
- fix(apparmor): grant for the loaded runner-tier plugin set, not profile.plugins
- spike: ephemeral remote-spawn via create_headless_session (§7c repair)
- fix(nebius): forward api_params (tool_choice/temperature/...) to chat.completions
- fix(nim): verify_auth must honor the profile-supplied api_key
- fix(nebius): verify_auth must honor the profile-supplied api_key
- feat(providers): Nebius Token Factory provider (serverless, catalog bootstrap)
- feat: config-time vision-tier validation (multimodal PR 4)
- feat: vision tier + content-boundary gate (multimodal PR 3)
- feat(providers): honest vision capability for anthropic/google/antigravity (multimodal PR 2)
- feat(providers): input-modality capability primitive (multimodal PR 1)
- refactor(events): single error-termination chokepoint — structural AgentErrorEvent-before-reason=error invariant
- feat(events): SlotSettledEvent.terminal_reason — fixes slot.settled-vs-recovery double-advance
- refactor(providers): standardize zhipuai context-window resolution (8/8)
- refactor(providers): standardize claude_cli context-window resolution
- refactor(providers): standardize github_models context-window resolution
- refactor(providers): standardize antigravity context-window resolution
- refactor(providers): standardize anthropic + google_genai context-window resolution
- refactor(providers): standardize nim + tensorrt_llm context-window resolution
- feat(events): AgentErrorEvent + on_agent_error recovery contract
- feat(file_edit): correct updateFile anchoring model in the tool contract
- feat(file_edit): allow_full_replace gate + conditional cap-rejection wording
- feat(file_edit): per-profile max_edit_span_chars targeted-edit span cap
- docs: fix three stale framework docstrings (#294/#295/#296)
- refactor(api): rename create_session/configure tools= param to plugins= (deprecated tools= alias)
- fix(result_grep): always emit valid JSON envelope so the full-dict path can't discard filtering
- feat(result_grep): model-directed tool-result grep filtering + greppable_content trait
- fix(providers): emit ALL parallel tool results on the OpenAI-compat wire
- fix(session): gate force_tool_choice stamp on provider honoring the quirk
- fix(cascade): γ'-guard gap pinned discovery slot for minutes (one-slot reuse)
- feat(events): SlotSettledEvent — universal per-cascade-stage handoff signal (replaces SlotReusableEvent)
- feat(events): add agent_id (stage name) to SlotReusableEvent payload
- feat(events): SlotReusableEvent — emit when a pool slot is reusable (cascade warm-reuse)
- fix(lsp): never host a language server in the daemon process (#284 OOM)
- fix(lsp): suppress LSP lifecycle on daemon-side forwarding stub (#284 OOM root cause)
- fix(lsp): kill slot's process-group subtree on teardown (#284 OOM)
- fix(lsp): reap jdtls on slot teardown (atexit + shutdown sentinel)
- fix(lsp): reap orphaned jdtls on connect timeout + raise timeout to 180s
- fix(notebook): strip NUL in apparmor profile parse; clarify gate scope
- security(notebook): fail closed on in-process cell execution
- revert: TEMP instrumentation quadruple (PR-218 / PR-219 / PR-220 / PR-221)
- refactor(session): extract pure tool-result building helpers
- refactor(session): extract tool-result truncation/capping transforms
- refactor(session): extract GC support helpers (span attrs + budget sync)
- refactor(session): extract instruction-budget builder helpers
- fix(gc): also run dedup Phase-0 in the before-send GC path
- refactor(session): extract SessionPersistence collaborator
- feat(gc): wire identical tool-result dedup as session-level GC Phase 0
- refactor(session): extract pure telemetry helpers; drop dead code
- feat(gc): identical tool-result dedup helper (core, tested)
- security(apparmor): loud structured warning + require-confinement gate
- security(cli): fail closed when shlex can't parse a command for sandbox
- security(ipc): default IPC socket mode to 0o660 (owner+group)
- feat(openrouter): flip context-window resolution to auto-detect PRIMARY
- feat(lmstudio): flip context-window resolution to auto-detect PRIMARY
- feat(ollama): tier-1 context-window auto-detect via /api/show
- feat(provider): tier-1 context-window auto-detect from /v1/models (vLLM)
- fix(gc): resolve budget context_limit when lazy provider materializes (#278)
- fix(lsp): spawn language servers with PR_SET_PDEATHSIG=SIGKILL (#280)
- fix(anthropic): accept-and-ignore tool_choice kwarg (provider contract parity)
- feat(gc): GC_DENOM diagnostic — make the budget-GC denominator inspectable
- fix(budget): count the initial wire tool-schema array in the GC denominator
- feat(lifecycle): processor-gated is_complete + server-side auto-finalize
- feat(profile): per-plugin tool allow-list via plugins(...) modifier
- feat(lifecycle): enriched pending-field descriptors for B1 viability
- fix(lifecycle): resolve $ref in prepare_completion validator + pending walker
- fix(lifecycle): adopt Daniel's path-syntax examples in field_path description
- feat(lifecycle): iterate prepare_completion to A2 shape (field_path, value)
- feat(vllm): VLLM_TOOLS_WIRE_DUMP probe — per-tool wire byte sizes
- feat(lifecycle): prepare/query_completion + arg-less signal_completion synthesis
- feat(session): GC_NO_ITEMS_COLLECTED diagnostic with locked-vs-eligible breakdown
- fix(vllm): add force_narration_between_tools to _KNOWN_QUIRKS allow-list
- fix(session): reshape force_narration_between_tools from env var to profile.quirks
- feat(session): JAATO_FORCE_NARRATION_BETWEEN_TOOLS env var + synthetic prompt injection (Probe B)
- feat(providers): parallel_tool_calls profile knob (vllm flat, openrouter api_params)
- feat(gc_budget): preserve narration on orphan-pair removal (Shape D)
- fix(providers): close openai client httpx pool on cancel (Shape B)
- probe(vllm+session): bump cancel-leak traces from self._trace to logger.info
- probe(vllm+session): cancel-leak prod-vs-isolation instrumentation
- feat(providers): explicit response_stream.close() so cancel aborts upstream HTTP
- probe(session+vllm): extend MAYBE_STAMP probe set with consume + complete entry (PR-256)
- probe(session): MAYBE_STAMP_SCAN logger.info at stamp helper entry (PR-255)
- revert: PR-253 post-completion send_message guard (misdiagnosed)
- fix(session): hard-refuse send_message after signal_completion (PR-253)
- fix(stop): reap orphan runners surviving --stop's registry walk
- fix(vllm): hash-translate tool_choice name to match wire tools array
- feat(session+vllm): force_tool_choice_for_lifecycle quirk (Path 1)
- feat(profile+vllm): SubagentProfile.quirks + coerce_typed_tool_args quirk
- feat(smokes): restructure nim/ollama/openrouter/tensorrt_llm to 3-test pattern
- feat(anthropic+github_models+lmstudio/smoke): restructure to 3-test pattern (chat / signal_completion / tools)
- fix(runner): fire post-turn AgentUIHooks for root IPC sessions (Path G)
- feat(vllm/smoke): restructure to 3-test pattern (chat / signal_completion / tools)
- fix(lifecycle): gate signal_completion on completion_payload_schema
- fix(session): terminate turn loop on successful signal_completion
- refactor(plugins): extract share_context to non-core telepathy plugin
- fix(runner): drop falsy
or Nonecoercion on tools list at bootstrap - feat(profile): require explicit plugins: key + fix tools=None expansion bug
- feat(session+todo): gate plan-required todo tools by visibility filter
- refactor(provider): drop hardcoded env defaults across vllm/trtllm/triton
- refactor(provider): generic mid-stream error messages across vllm/trtllm/triton
- feat(provider): add vLLM provider plugin (mirror of tensorrt_llm)
- fix(server): _resolve_profile honors qualified set/name paths
- feat(provider): surface trtllm/triton mid-stream connection drops with engine-config diagnostic
- refactor(provider): github_models smoke — YAML profiles + signal_completion persona + suppress_base
- refactor(provider): ollama smoke — YAML profiles + signal_completion persona + suppress_base
- refactor(provider): anthropic smoke — YAML profiles + signal_completion persona + suppress_base
- refactor(provider): nim smoke — YAML profiles + signal_completion persona + suppress_base
- refactor(provider): lmstudio smoke — YAML profiles + signal_completion persona + suppress_base
- fix(provider): wire max_tokens knob in tensorrt_llm
- refactor(provider): canonical tensorrt_llm smoke — YAML profiles + signal_completion persona + suppress_base
- docs(openrouter): fix stale .json references in README — tree diagram + manual path
- fix(provider): openrouter smoke — YAML profiles, signal_completion persona, max_tokens cap, suppress_base
- fix(runner): propagate suppress_base_instructions + system_instruction_override over the wire
- fix(provider): wire api_params.max_tokens in openrouter
- feat(provider): github_models smoke harness mirroring tensorrt_llm pattern
- feat(provider): anthropic — smoke harness mirroring tensorrt_llm pattern
- feat(provider): nim smoke harness (mirrors tensorrt_llm pattern)
- feat(provider): lmstudio smoke harness (mirrors tensorrt_llm pattern)
- feat(provider): smoke harness for openrouter (mirror of tensorrt_llm)
- feat(provider): ollama smoke harness (mirrors tensorrt_llm pattern)
- refactor(provider): smoke — model in profile, host via workspace .env
- feat(provider): bootstrap.sh — optional --run chat|tools
- refactor(provider): bootstrap.sh — bootstrap-only, no run step
- feat(provider): run_smoke.sh — one-shot bootstrap + run for smoke harness
- fix(provider): smoke harness — ErrorEvent.error + optional --workspace
- fix(provider): drop redundant "permission" entry from tools-smoke profile
- feat(provider): tensorrt_llm tools smoke alongside chat smoke
- feat(provider): tensorrt_llm smoke harness + workspace templates
- feat(lsp): bounded-poll convergence wait for jdtls multi-stage publishDiagnostics
- feat(sdk+core): expose ToolResult.enrichment_metadata on the tool-call ledger
- probe(lsp): TEMP — narrow get_diagnostics await + publishDiagnostics path
- probe(lsp): TEMP instrumentation inside LSPToolPlugin.enrich_tool_result
- probe(core): TEMP instrumentation — narrow enrich subscriber dispatch (B-i/ii/iii/iv)
- probe(core): TEMP instrumentation — narrow enrich_tool_result dispatch gap
- feat(core): Family IV — jdtls state sibling-of-workspace + ${jdtlsStateRoot} template var
- fix(core): replay_messages must call _ensure_provider (lazy-INIT refactor missed)
- cleanup(core): remove SessionManager.ensure_session_loaded — wrong abstraction
- fix(core): SessionState.config_root + RuntimeSessionInfo listing reference
- feat(core): SessionState.profile_name; retire Google-coupled project/location/model
- feat(core): SessionManager.ensure_session_loaded — programmatic rehydration without attach
- feat(core): cascade.cancel(cid) IPC verb + reactor-suppression predicate
- fix(core): promote entry-point Protocol-check trace to WARNING with named missing methods
- feat(core): DaemonForwardingMixin + PLUGIN_TIER="daemon_callable" cross-tier pattern
- fix(core): dedup compares delivery_target_id (raw connection id), not namespaced registration id (#208)
- fix(core): dedup bootstrap-time event delivery when client is both direct-attached and cascade observer (#207)
- fix(core): dedup AgentCreatedEvent on main-agent bootstrap (#206)
- feat(sdk): add session_id field to AgentCreatedEvent (#205)
- feat(template): reject None-valued kind=scalar (close third empty-equivalent state) (#204)
- feat(template): dual-engine (Mustache + Jinja2) required-scalar enforcement at renderTemplateToFile boundary (#203)
- Revert "feat(template): top-level required-scalar enforcement + Spring sentinel parser-protection (#202)"
- feat(template): top-level required-scalar enforcement + Spring sentinel parser-protection (#202)
- feat(render-context): expose session_id with parent-walk resolution (#201)
- feat(template): recursive item_keys traversal at renderTemplateToFile boundary (#200)
- feat(template): helper-exclusivity validation at renderTemplateToFile boundary (A2) (#199)
- fix(bootstrap): emit SessionTerminatedEvent on bootstrap failure (visibility-gap close) (#198)
- fix(memory): source_session wired via config + live registry (PR-196 follow-up) (#197)
- fix(memory): wire set_session(session) so source_session is populated (#196)
- feat(provider): TensorRT-LLM via trtllm-serve (OpenAI-compatible) (#195)
- fix(cascade): bootstrap-time events route to cascade observers (centralized helper) (#194)
- fix(cascade): auto-detach IPC clients from cascade-stamped sessions on terminal events (γ') (#193)
- fix(cascade): stamp cascade_driver_id on Session dataclass (Bug B real root cause) (#192)
- chore(script_loader): probe-symbol-missing → DEBUG, not WARNING (#190)
- fix(bus): bridge SessionTerminatedEvent to EventBus (Bug C) (#189)
- fix(cascade): GC sweep mid-cascade reap (Bug B) (#188)
- feat(processor): ProcessorResult TypedDict + jaato_sdk.cascade_authoring umbrella (#187)
- feat(events): carry error context onto SessionTerminatedEvent (Q2) (#186)
- fix(cascade): default policy unloads on all terminal reasons, not just error (#183)
- hotfix(cascade-as-client): Phase 1.1 — register_in_process_client idempotent on duplicate client_id (#182)
- feat(cascade-as-client): Phase 2 — SDK IPC RPC verbs + disconnect cleanup (#180)
- hotfix(core): emit terminal events on completion-nudge exhaustion (Finding D) (#179)
- feat(cascade-as-client): Phase 1 — daemon-side registry + dispatch + default lifecycle policy (#178)
- hotfix(anthropic): re-raise SDK network-layer exceptions instead of swallowing into TurnResult (#177)
- hotfix(retry): classify anthropic SDK APIConnectionError + APITimeoutError as transient (#175)
- hotfix(runner): session.end clears _session_host + fires close_session hook (#174)
- hotfix(rpc): RunnerRPCClient lives on PoolSlot, reused across cascade sessions (#173)
- hotfix(session_manager): add cascade_driver_id kwarg to create_headless_session (#172)
- hotfix(plugins): inject NO-OP reset_for_next_session into 39 plugins (P0 cascade-sharing regression) (#171)
- feat(cascade-sharing): Phase 4 — LSP plugin lifecycle pin tests (#169)
- feat(cascade-sharing): Phase 3 — per-session apparmor with cross-session transitions (#168)
- feat(cascade-sharing): Phase 2 PR-B — end-to-end IPC + teardown wiring (#167)
- feat(cascade-sharing): Phase 2 PR-A — pool-side slot reuse + session.end RPC (#163)
- feat(cascade-sharing): Phase 1b — reset_for_next_session for 5 review-required plugins (#161)
- feat(cascade-sharing): Phase 1a — reset_for_next_session protocol + 8-plugin audit (#160)
- fix(lsp): add plugin_configs.lsp.apparmor_extra_rules operator knob (profile YAML) (#158)
- fix(lsp): symmetric workspace_path resolution at connect_server (PR-156 follow-up) (#157)
- fix(lsp): auto-inject TMPDIR from -data path to sidestep jdtls eager-tempdir bug (#156)
- fix(lsp): auto-emit apparmor grants for -data / --data-dir paths in .lsp.json args (#155)
- fix(lsp): get_apparmor_rules emits ix grants for configured LSP server binaries (#154)
- fix(lsp): debug_log_path knob + apparmor fragment closes silent-config-cache-reset (#153)
- fix(lsp): port validate_snippet to await_diagnostics (PR-3 follow-up) (#152)
- fix(lsp): bounded-poll for publishDiagnostics via asyncio.Event (#151)
- fix(lsp): expose plugin_configs.lsp.connect_timeout_seconds for heavy-init servers (#150)
- fix(runtime): promote plugin_configs..api_key to ProviderConfig.api_key (#149)
- fix(apparmor): split registry creation so composer can query plugins (#148)
- fix(file_edit): complete apparmor fragment + drop workspace fallback (#147)
- refactor(registry): pre-init framework-key injection layer fix (#146)
- fix(file_edit): export get_apparmor_rules + thread workspace/config_root through plugin_configs (#145)
- fix(file_edit): anchor backups on config_root (corrects PR-143 misdirection) (#144)
- fix(file_edit): anchor backup path on workspace_root, not daemon CWD (#143)
- refactor(completion): unify completion_artifacts + completion_validators into completion_processors (#142)
- fix(profile): env_file overlay in _resolve_profile so JAATO_PROFILE_SET reads (#141)
- fix(provider): expand plugin_configs daemon-side + JAATO_ZHIPUAI_API_KEY env var (#140)
- fix(completion): wire completion_validators (+ artifacts) through runner envelope (#139)
- feat(completion): kb-authored semantic validators for signal_completion (#138)
- feat(tui): render human template names in tool tree (post-#136 follow-up) (#137)
- feat(template): hash template identifiers at LLM boundary (mirror of tool-name hashing)
- feat(openrouter): expose strict_tools profile knob (Approach A)
- docs(signal_completion): correct strict-mode claim + warn about model support
- feat(apparmor): plugin-contribution refactor Phase 5 (helper + contract test)
- feat(apparmor): plugin-contribution refactor Phase 4 (agents + profiles + isolated-subprofile gap)
- feat(signal_completion): expose completion_payload_schema as flat tool args (Option G)
- feat(apparmor): plugin-contribution refactor Phase 3b (gc.json)
- feat(apparmor): plugin-contribution refactor Phase 3 (service_connector + references catalog)
- feat(apparmor): plugin-contribution refactor Phase 2 (memory + prompt_library)
- perf(references): skip embedding provider load when no bundles (Fix A)
- fix(cli): bind module-level logger (PR #124 regression)
- fix(apparmor): propagate JAATO_APPARMOR_COMPLAIN to tool_hat + //child sub-profiles (template v22)
- diag(cli): CLI_SUBPROCESS_ENV log line at Popen call sites
- feat(apparmor): references plugin migration + WS-side wiring (Phase 1, template v21)
- feat(apparmor): plugin-contribution hook (Phase 0, template v20)
- diag(runner_spawn): surface error_type + error on bootstrap-failure WARNING
- diag(apparmor): env-gated complain mode toggle (JAATO_APPARMOR_COMPLAIN)
- diag(model_thread): MODEL_THREAD_TERMINAL_ERROR INFO log at ErrorEvent emit
- fix(provider+model_thread): vendor-correct error text + session-terminal on provider errors
- diag(anthropic-provider): emit PROVIDER_RESPONSE_DUMP on the exception path too
- diag(anthropic-provider): fix response dump attribute name
- diag(anthropic-provider): dump request + response when JAATO_DUMP_PROVIDER_REQUEST set
- fix(runner): disable PR-112 plugin-init gate at the call site (#114)
- fix(introspection): reframe explore-tools guidance from "ALWAYS" to "WHEN REQUIRED" (#113)
- perf(registry): gate plugin initialize() on session-requested set (option C) (#112)
- fix(apparmor): //child fragment-only exec — strip broad ix grants (template v18) (#111)
- fix(subagent): _scan_profiles_dir summary log lists per-pass names only (#110)
- fix(apparmor): grant change_profile -> //child in parent body (template v17) (#109)
- feat(perf): instrument runner-side plugin configure with BootstrapTimer (#108)
- feat(apparmor): per-profile fragment scoping (Piece 1 task-64) (#107)
- fix(apparmor): unify config_root/env_file threading via envelope (closes headless cascade crash) (#106)
- feat(apparmor): profile field + caller-kwarg surface (PR-A back-compat) (#105)
- fix(runner): propagate profile.model_tiers via envelope (enter_tier regression) (#104)
- fix(server): defer session unload to background thread (asyncio-deadlock fix) (#103)
- fix(runner): //child install reads envelope.profile_name (closes pool-slot apparmor escape)
- fix(runner): profile-less envelope falls back to session env (no hardcoded anthropic)
- feat(runner): flip JAATO_RUNNER_POOL_ENABLED default to true + docs (pool PR 5e)
- feat(runner): pool telemetry counters via get_telemetry (pool PR 5d)
- feat(runner): template-ready handshake replaces 2s sleep (pool PR 5c)
- feat(runner): subreaper + template watchdog auto-respawn (pool PR 5b)
- fix(runner): dispatch session.bootstrap on main thread (PR 5a fix)
- feat(runner): per-slot AppArmor self-confine via envelope.profile_name (pool PR 5a)
- fix(runner): daemon-resolved session_env via envelope (fixes PR #91 AppArmor regression)
- feat(runner): relocate workspace .env reading to runner-side bootstrap_session (Shape 3 PR 1)
- feat(runner): route session bootstrap through pre-warm pool + replenishment (pool PR 4)
- feat(runner): pool slot manager + fork-slot RPC (pool PR 3)
- feat(runner): pre-warm template subprocess (pool PR 2)
- fix(session): defer provider INIT to first model use (pre-warm pool PR 1)
- fix(runner-rpc): wire remaining 6 runner-side ServerAgentHooks methods
- fix(runner-rpc): wire on_agent_completed + on_session_quiescent across §7c
- fix(runner): thread agent_id from envelope through create_session
- fix(runner_spawn): build_session_envelope agent_id + completion_payload_schema
- fix(apparmor): write-deny /.jaato/apparmor-fragments/**
- feat(apparmor): workspace-tier fragment discovery
- fix(apparmor): v16 template grants mmap-exec on venv C-extensions
- feat(apparmor): Phase 5 §5.9 — supervisor-declared sub-profile tightening flags
- feat(openrouter): emit X-OpenRouter-Categories for app rankings
- feat(openrouter): cross-model fallbacks, beta headers, routing docs
- feat(openrouter): align streaming with OpenRouter spec
- fix(file_edit): microsecond-resolution backup timestamps + collision counter
- feat(runner-rpc): Phase 5 §5.8 — profile_payload typed validator
- feat(runner): Phase 5 §5.10e — skip //child install for sub-runners
- feat(interactive_shell): Phase 5 §5.10d — PTY spawn transitions into //child
- server: pre-set TMPDIR=/tmp/jaato- for confined runner subprocess
- server: Phase 5 §X — fix runner self-confine read-rule (template v15)
- server: JAATO_CGROUPS_ROOT env var for non-default cgroup parent
- fix(runner): Phase 5 §5.10c peer-review — audible failure on install gap
- feat(cli): Phase 5 §5.10c — cli plugin transitions subprocesses into //child
- feat(apparmor): Phase 5 §5.10a/b — //child sub-profile + transition callback
- feat(cgroups): Phase 5 §5.3 — orphan sub-cgroup reaper at cascade teardown
- feat(session_manager): Phase 5 §5.2 — nesting-visibility instrumentation
- feat(runner): Phase 5 §5.1b — forward RuntimeLimits app fields to mainline runner
- feat(subagent): Phase 5 §5.1 — apply default RuntimeLimits on isolated spawn
- fix(subagent): Phase 4 §4.3 peer-review — remove silent isolation downgrade + test typo + envelope v2
- test: Phase 4 §4.3.8 — isolated-subagent integration test
- feat(subagent): Phase 4 §4.3.7 — SubagentPlugin opt-in routes to isolated spawn
- feat(forward): Phase 4 §4.3.6d — parent-cascade teardown for isolated subagents
- feat(forward): Phase 4 §4.3.6c — session.bootstrap + first-turn prompt dispatch
- feat(forward): Phase 4 §4.3.6b — cross-runner output forwarding scaffolding
- feat(spawn): Phase 4 §4.3.6a — sub-runner subprocess spawn + handle bookkeeping
- feat(cgroups): Phase 4 §4.3.5 — sub-cgroup provisioning + AppArmor rollback
- feat(apparmor): Phase 4 §4.3.4 — sub-AppArmor profile generation
- feat(spawn): Phase 4 §4.3.3 — SessionManager._spawn_isolated_runner helper + handler bridge
- feat(rpc): Phase 4 §4.3.2 — spawn_isolated_runner RPC primitive (stub)
- feat(subagent): Phase 4 §4.3.1 — isolated-subagent opt-in detection (stub)
- permission+prompt_operator: Phase 4 §4.2 — editable_metadata propagation (J.B closure)
- session+runner+core: Phase 4 §4.4 — description-callback bridge (Finding 2 closure)
- permission+prompt_operator: Phase 4 §4.1 — call_id propagation (J.A closure)
- tests: Phase 4 §D regression pins + bump server to 0.6.75
- server: Phase 4 §D — agent_params propagation to runner via BootstrapEnvelope
- tests: Phase 4 §C regression pins — plugin_configs envelope v2 + permission propagation
- server: Phase 4 §C — profile.plugin_configs propagation to runner (envelope v2)
- openrouter: leverage OpenRouter prompt caching
- server: bump version to 0.6.73 for Phase 4 §B env-propagation fix
- tests: Phase 4 §B regression pins — pre-spawn env resolution contract
- server: Phase 4 §B — resolve workspace .env pre-spawn so runner inherits
- core+runner+session_manager: strip Path G cycle 8-10 probes (post-cycle-13 cleanup)
- prompt_operator: Path J fix — emit PermissionInputModeEvent companion alongside PermissionRequestedEvent
- core: Path I fix — emit AgentCreatedEvent daemon-side at bootstrap
- session_manager: Path H fix — defer incremental save off the _emit_to_session critical path
- core+session_manager: Path G+ probes — diagnosis was wrong, gap is downstream of server.emit
- core+runner: Path G instrumentation — 6 DEBUG probes to localize streaming silent failure
- core+runner: Path F fix — bridge runner→daemon AgentUIHooks gap
- core+runner+serializer: Path E fix — close send_message active-turn chain
- runner: Path D fix — mirror daemon _run_load_plugins runner-side
- shared+runner: Path C fix — runner-side runtime.connect() in bootstrap_session
- session_manager: Path B fix — IPC sessions now dispatch session.bootstrap synchronously
- core: post-Step-7 regression fix — defensive snapshot wrap (Path A)
- core: §7c Step 7.3 — respond_to_permission dual-path routing
- runner: §7c Step 7.2 — wire runner-internal RunnerRPCClient onto registry
- core: §7c Step 7.1 — wire PromptOperatorHandler in set_runner_rpc
- core+runner: §7d — runner-subprocess cgroup attach (peer-review v2 obs #2 realized)
- core: §7c step 6.6.4.5e — atomic _jaato field removal (seat-flip moment)
- core: §7c step 6.6.4.5d — daemon-direct JaatoRuntime construction (Path A transitional)
- runner+core: §7c step 6.6.4.5c.5 — session.get_tool_schemas RPC (Path D finale)
- runner+core+command_router: §7c step 6.6.4.5c.4 — session.get_model_completions RPC (2 callsites, scope expanded)
- runner+core: §7c step 6.6.4.5c.3 — session.execute_user_command RPC (Path A per-type reconstruction)
- runner+core: §7c step 6.6.4.5c.2 — session.get_user_commands RPC (dict-shape wire format)
- runner+core+shared: §7c step 6.6.4.5c.1 — session.get_auth_info RPC + JaatoSession public method
- core+session_manager: §7c step 6.6.4.5b — migrate 15 daemon-side reads to existing runner-RPCs
- session_manager+websocket: §7c step 6.6.4.5a — migrate _jaato.get_runtime() reads to direct _runtime
- core: §7c step 6.6.4.4 — narrow WIRING deletions (3 safe-only sites)
- core+runner: §7c step 6.6.4.3b — atomic seat-flip (send_message → runner-RPC + 9-callback collapse + 7-wiring delete + handler install)
- runner+core+shared: §7c step 6.6.4.3a — session.try_completion_nudge RPC + JaatoSession public method
- runner: §7c step 6.6.4.2 — runner-side session-callback notification-emission machinery
- runner+core: §7c step 6.6.4.1 — notification-frame protocol on session.send_message stream channel
- session_manager+core+websocket: §7c step 6.6.3.6 — migrate 17 external get_session() callers + drop public method
- runner+core: §7c step 6.6.3.5 — session.resolve_fork_point RPC
- runner+core: §7c step 6.6.3.4 — session.replay_messages RPC
- runner+core+shared: §7c step 6.6.3.3 — session.set_parallel_tools_override RPC + JaatoSession public method
- runner+core+shared: §7c step 6.6.3.2 — session.snapshot_conversation_budget RPC + JaatoSession public method
- runner+core+shared: §7c step 6.6.3.1 — session.append_history_message RPC + JaatoSession public method
- runner+core: §7c step 6.6.1.3 — session.restore_conversation_budget RPC handler + wrapper
- runner+core: §7c step 6.6.1.2 — session.restore_turn_accounting RPC handler + wrapper
- runner+core: §7c step 6.6.1.1 — session.set_initial_history RPC handler + wrapper
- shared+server: §7c step 6.6.1.0 — add JaatoSession.restore_turn_accounting + restore_conversation_budget; migrate session_manager
- core: §7c step 6.5 — migrate 4 CLEAN introspection sites to self._runtime
- core: §7c step 6.3 — drop 6 of 7 write-both daemon-side legs (set_reference_authorizer split out)
- core: §7c step 6.2 — migrate 6 straightforward get_session() readers
- runner+core: §7c step 6.1 (3/3) — session.inject_prompt RPC handler + wrapper
- runner+core: §7c step 6.1 (2/3) — session.snapshot_instruction_budget RPC handler + wrapper
- runner+core: §7c step 6.1 (1/3) — session.set_reference_authorizer RPC handler + wrapper
- runner: pre-step-6 toolbar-coherence test + step 5 fold-into-step-6 doc revision
- core: §7c step 4 first pass — daemon-side self._runtime field + 5 get_runtime() migrations
- core: §7c step 3b — public get_tool_schemas accessor replaces private session._tools read
- core: §7c step 3a — public JaatoClient.set_agent_identity replaces private-attr reaches
- core: §7c step 2 — WS-side bootstrap parity; extract shared dispatch_bootstrap_envelope helper
- core: §7c step 1 — IPC always bootstraps runner-side session; remove JAATO_RUNNER_HOSTS_SESSION flag
- runner+runner_rpc_client: session.send_message handler + wrapper (Phase 3 §7b.2 — the big one)
- core: post-init terminal_width sync forwards to runner (Phase 3 §7b.1 lifecycle straggler)
- runner: add session.get_context_limit RPC handler + wrapper (Phase 3 §7b.1 precursor)
- docs+core: §7b.1 audit appendix — per-site bucket classification
- core: JaatoServer.stop forwards cancellation to runner-side session (Phase 3 §7b.1)
- core: JaatoServer.clear_history forwards reset to runner-side session (Phase 3 §7b.1 — first stateless migration)
- websocket: always-spawn runner for WS-provisioned sessions (Phase 3 §7a WS counterpart)
- session_manager+runner_spawn: always-spawn the runner (Phase 3 §7a — first seat-flip-proper commit)
- docs+session_manager: address peer-review C1+C2+M1-M4+Mn1 on §3.3c surface
- runner: add session.get_turn_accounting RPC handler + wrapper (Phase 3 §3.3c precursor)
- runner: add session.reset RPC handler + wrapper (Phase 3 §3.3c precursor)
- runner: end-to-end integration test for the §3.3c dispatch surface lifecycle
- runner + core: session.set_presentation_context handler + JaatoServer migration (Phase 3 §3.3c)
- core: JaatoServer.terminal_width setter forwards to runner-side session (Phase 3 §3.3c migration)
- runner: add session.get_all_session_state bulk-snapshot RPC handler (Phase 3 §3.3c precursor)
- runner: add session.set_terminal_width + session.set_streaming_enabled RPC handlers (Phase 3 §3.3c precursors)
- core: JaatoServer.shutdown calls runner-side session.shutdown before transport close (Phase 3 §3.3c migration)
- runner: add session.shutdown RPC handler + wrapper (Phase 3 §3.3c precursor)
- runner/rpc: serialize real Message dataclasses in session.get_history (Phase 3 §3.3c precursor fix)
- runner_rpc_client: expose session-method named-method wrappers (Phase 3 §3.3c precursors)
- runner: add session.get_history + session.get_context_usage RPC handlers (Phase 3 §3.3c precursors)
- runner: add session-state + lifecycle RPC handler batch (Phase 3 §3.3c precursors)
- runner: add session.health_check RPC handler (Phase 3 §3.3c precursor)
- session_manager: defer-and-flush foundation for disk-restored sessions (Phase 3 §3.12 + peer-review M5/N1)
- session_manager: route ephemeral path through unified bootstrap sub-helper (Phase 3 §3.12 ephemeral)
- session_manager: route _load_session_impl through unified bootstrap sub-helper (Phase 3 §3.12 disk-restore)
- session_manager: relocate IPC apparmor hook inline + remove _planned_sandbox_mode (Phase 3 §3.13)
- websocket: convert apparmor pre-init hook to 4-arg + wire runner spawn (Phase 3 §3.12 WS path)
- session_manager: add BootstrapEnvelope + unified _bootstrap_session helper (Phase 3 §3.12.0)
- subagent: add session-termination hook for plugin state cleanup (Phase 3 §3.11 + peer-review M4)
- shared: add atomic_write helper + migrate framework persistence sites (Phase 3 §3.14)
- runner: lift _telemetry off result dict onto envelope.telemetry (Phase 3 §3.15)
- permission: hold _policy_lock across ASK rule-recheck + channel-wait (Phase 3 §3.7 + peer-review M3)
- permission: wire _get_channel() to select RunnerRPCChannel when runner-side (Phase 3 §3.7 deeper)
- permission: add RunnerRPCChannel ASK relay (Phase 3 §3.7 deeper)
- plugins: migrate stateful plugins (permission, references, memory) to RunnerForwardingMixin (Phase 3 §3.7 §3.8 §3.9)
- cli: collapse Phase 2 _execute_via_runner onto RunnerForwardingMixin
- plugins: migrate wave 2 (4 subprocess-spawning plugins) to RunnerForwardingMixin (Phase 3 task 3.5)
- plugins: migrate wave 1 straggler + waves 3 + 4 (12 plugins) to RunnerForwardingMixin (Phase 3 §3.4 §3.6 §3.10)
- plugins: migrate wave 1 (8 pure-FS plugins) to RunnerForwardingMixin (Phase 3 task 3.4)
- shared: RunnerForwardingMixin for runner-tier plugin stubs (Phase 3 §3.4 prerequisite)
- runner: route tool.execute through session host's executor (Phase 3 task 3.3c part 3a)
- server: build + auto-send session envelope from spawn site (Phase 3 task 3.3c part 2)
- runner: session.bootstrap RPC end-to-end (Phase 3 task 3.3c part 1)
- plugins: PLUGIN_TIER annotation + tier-filtered discovery (Phase 3 task 3.3.5)
- runner: runner-side session host scaffolding (Phase 3 task 3.3b)
- shared: SessionInitEnvelope schema + round-trip tests (Phase 3 task 3.3a)
- runner: apparmor.add_reference_fragment RPC primitive (Phase 3 task 3.2.2)
- runner: client.prompt_operator RPC primitive (Phase 3 task 3.2.1)
- runner: bidirectional RPC — runner-side outgoing + daemon-side incoming dispatch (Phase 3 task 3.2)
- server: rename runner_rpc.py → runner_rpc_client.py (Phase 3 task 3.2 prelude)
- runner: tool-result path-redaction sanitize (Phase 3 task 3.1)
- server 0.6.72: clear os.environ workspace keys in run_in_fresh_session_context
- server: move IPC apparmor hook to pre-init + spawn runner inside _create_session_impl (Phase 2 task 2.3 review fix)
- tests: Phase 2 integration + sister tests (Phase 2 task 2.6)
- cli: route _execute through the runner when one is attached (Phase 2 task 2.5)
- server: wire RunnerSpawner + RunnerRPCClient into IPC sessions (Phase 2 task 2.3)
- server: add server/runner/ package skeleton (Phase 2 task 2.2)
- shared: factor framing into shared/framing.py (Phase 2 task 2.4)
- server: remove daemon-thread per-session AppArmor confinement (Phase 2 task 2.1)
- server 0.6.71: fresh contextvars.Context per session-bootstrap (closes long-lived-daemon ContextVar inheritance leak)
- server 0.6.70: O(1) helper-mtime check via name index (closes cascade dispatch lag)
- server 0.6.69: snapshot sys.modules.values() in _module_with_file
- server 0.6.68 fixup: bundle.py inline-import get_config_root
- server: restore mixed line endings in 0.6.68 migrated files
- server 0.6.68: per-task workspace_root / config_root via ContextVar
- server 0.6.67: .env secret URIs + streaming suffix + catalog gate + headless API default
- server 0.6.63: re-apply signal_completion filter in set_presentation_context
- server 0.6.62: gate completion-nudge + executor on signal_completion exposure
- server 0.6.61: hide signal_completion in interactive root sessions
- docs(script_loader): document lock-scope + partial-import corner case
- server 0.6.60: script_loader sys.modules cache invalidation
- server 0.6.59: artifact_tracker + waypoint consume set_workspace_path
- sdk 0.11.0: relocate classify_template_evaluation_kind to SDK boundary
- server 0.6.58: public classify_template_evaluation_kind helper
- server 0.6.57: secret-URI sane on http/https/${VAR} + call_service endpoint-by-name
- server 0.6.56: TemplateIndexEntry.skip_when_flags — config-flag-driven render skip
- server 0.6.55: profile template v13 — narrow per-subpath denies + tool_hat sub-profile
- server 0.6.54: inotify pressure soft-warn for long-lived daemons
- server 0.6.53: framework-subtree carve-outs in .jaato deny rule
- server 0.6.52: profile template v11 — deny .jaato/** writes from confined sessions
- server 0.6.51: surface DynamicInstructionsError + empty headless session_id at log level
- server 0.6.50: confine prefetch — wrap dynamic-instructions in apparmor_confine
- server 0.6.49: pre-initialize hook API; AppArmor profile loads before configure()
- server 0.6.48: dynamic_instructions abort on prefetch failure + ?-modifier opt-in
- server 0.6.47: SafeThreadPoolExecutor with pre-task hooks closes apparmor stuck-worker EACCES gap
- server 0.6.46: nested-iteration item_keys + inherited_from_outer_scope flag
- server 0.6.45: transport-agnostic client-disconnect helper closes IPC inotify leak
- docs/design: payload-schema-conventions — unify spawn + completion
- server 0.6.44: template_evaluation_kind + helper_siblings on parser surface
- server 0.6.43: per-item item_keys coverage validation + source taxonomy
- server 0.6.42: TemplateIndexEntry carries variant_key + variant axis fields
- server 0.6.41: strip Output-directive line from rendered content (companion to 0.6.35 polyglot)
- server 0.6.40: declarative path-routing rules from .jaato/template_routing.yaml
- server 0.6.39: listTemplateVariables honors index entry's output_path_template (index-authoritative)
- server 0.6.38: Mustache parser recognises Handlebars helpers + filters iteration metadata
- server 0.6.37: empty-segment validation for auto-derived output_path
- server 0.6.36: listTemplateVariables merges body + Output-directive variables
- server 0.6.35: polyglot Output-directive extraction + README documents the convention
- server 0.6.34: renderTemplateToFile auto-derives output_path from template directive
- server 0.6.33: serialise pybars3 calls; thread-local stripped-comment-lines
- server 0.6.32: shape validator allows list-of-scalars when item_keys is empty
- server 0.6.31: renderTemplateToFile shape validation (Mustache-only)
- server 0.6.30: listTemplateVariables strips // host-language comment lines
- server 0.6.29: listTemplateVariables — three parser bugfixes (triple-brace + inverted-branch + nested-section attribution)
- server 0.6.28: listTemplateVariables returns structural info (kind + item_keys)
- docs+lifecycle_tools: completion_payload_schema authoring conventions
- server 0.6.27 + sdk 0.10.0: SessionTerminatedEvent + cancellation-aware end_session
- server 0.6.26: template plugin honors config_root (mirror references plugin)
- server 0.6.25: apparmor_confine — defensive unconfined-reset on entry
- server 0.6.24: anthropic + zhipuai profile config namespacing + sampling params wired
- server 0.6.23: openrouter profile config namespacing (api_params/routing/framework_overrides)
- server 0.6.22: profile-level suppress_base_instructions field
- server 0.6.21: openrouter history shape repair for strict upstreams
- server 0.6.20: openrouter provider — strict-upstream tool-def sanitizer + profile-driven sampling params
- server 0.6.17: profile-set selector + audit guard for session-tied env vars
- server 0.6.16: profile-set overlay nests under profiles/
- server 0.6.15: preserve preloaded tools through initialize-time core-tool merge
- server 0.6.14: subagent plugin threads completion_payload_schema + completion_artifacts to runtime.create_session
- server 0.6.13: list_tools soft-nudge for preloaded tools
- server 0.6.12: completion_artifacts gain optional output + description
- server 0.6.11: schema-loaders drop auto-prefix — match script_loader convention
- server 0.6.10: extend spawn_payload_schema validation to headless/IPC sessions
- server 0.6.9: typed spawn_subagent — symmetric to typed signal_completion
- server 0.6.8: subagent profile-set overlay via JAATO_PROFILE_SET env var
- apparmor: correct misleading escape-vector comment + denylist /proc//attr/
- server 0.6.7: subagent spawn passes config_root to _resolve_agent
- server 0.6.6: silent skip for sibling-registry modules in directory discovery
- server 0.6.5: register bundle plugin entry-point
- server 0.6.4: completion-artifacts — output-side body-wired rendering (#52)
- server 0.6.3: fix NameError in subagent agent_params threading
- server 0.6.2: dynamic-instructions step 2 — {{!py:script.py}} with full session wiring (#51)
- test: thread config_root through test_connect_creates_runtime_with_provider
- test: untie test_template_version from a hardcoded number
- server 0.6.1: AppArmor dispatch + subagent profile resolution + completion-nudge guard (#49)
- openrouter_auth README: add profile examples for thinking knobs
- openrouter: support enable_thinking / thinking_budget / thinking_level knobs
- openrouter: support provider-routing dict in profile config
- openrouter: add provider + auth plugin
- openrouter: scaffold provider package (env, errors, converters, auth)
- tests: e2e for runtime_limits profile loading → cgroup wiring
- sdks: align bridged payloads + tests with gap 1-5 wire shapes
- release: coordinated bump for gap 1-5 SDK release
- sdks: protocol-version compat (gap 5)
- sdks: subscribe API, profile picker, inline session spec, cost/usage refactor
- fix: propagate --agent to session._agent_id
- gc: resolve gc.json against workspace, add ~/.jaato fallback
- subagent: register ProfilesEntryHandler — second domain validates the architecture
- bundle: document why 'merge' stays references-specific
- bundle: lift create / delete / reconcile to the top-level command
- bundle: lift pack / unpack to the top-level bundle command
- bundle: introduce top-level 'bundle' command for multi-kind ops
- bundle_common: lift pack/unpack into shared module + v2 multi-kind format
- bundle_common: define BundleEntryHandler protocol + registry
- bundle_common: extract domain-agnostic bundle infra into a shared module
- references: nest 'bundle' as a subcommand of references (not a standalone)
- references: split into 'references' (refs) and 'bundle' (bundles) commands
- references: pack / unpack subcommands for bundle distribution
- references: scope:name bundle ref syntax + cross-tier merge / reconcile
- references: two-tier bundle discovery (workspace + user) with shadow precedence
- Fix AgentCompletedEvent.token_usage shape regression from Phase 0
- Add hide / show-hidden / gitignore-toggle bindings to the workspace panel
- Show .jaato/ in the workspace panel by default
- Phase 1: SDK feature parity — typed WS verbs + JaatoClient methods
- Phase 0: Migrate jaato-sdk events.py from @dataclass to pydantic
- Apply .gitignore filtering to sandbox path tracking
- Surface cgroup OOM-kill events as OTel attributes on tool spans
- Add cgroup.events reader for kernel-killed attribution
- Apply runtime_limits at the interactive_shell spawn layer
- Apply runtime_limits at the subprocess layer (CLI plugin)
- Wire runtime_limits profile field through to per-session cgroups
- Rename SandboxConfig to RuntimeLimits, drop network field
- Add per-session cgroup v2 runtime for resource limits
- SDK file staging: binary-framed StageFilesRequest for WS clients
- references: AppArmor reference fragments for confined WS sessions
- Intercept % --help before model dispatch
- WS auth: default to ~/.jaato/ws.token, auto-create on first run
- Support --help flag for %prompt and /prompt commands
- Update WS transport client reference: add auth mechanism docs
- WS bearer-token auth (Option A): close the open-port default
- notebook: richer SyntaxError diagnostics + quote hint
- permission hook: don't clobber pending-prompt id from parallel auto-decisions
- services check_credentials: route through _resolve_credential too
- services auth: resolve pass://, vault://, etc. alongside env var names
- ParameterLocation: add body, formData, cookie for full OpenAPI coverage
- services: tiered lookup (workspace → user home), mirroring the rest of jaato
- AppArmor: skip for IPC sessions; fix thread restore-to-unconfined
- Rewind-with-hint: recover from max_tokens-truncated tool calls
- Render / in the TUI; drop per-client branching on the server
- References: references merge subcommand for knowledge-bundle consolidation
- References: knowledge bundles with per-bundle sidecars + reconcile
- References: move sidecar row ordering to embedding_config.json
- Surface masked credential-load errors in NIM, Anthropic OAuth, GitHub Models
- Zhipu AI auth: surface masked provider errors instead of "no credentials"
- Enrichment plugins: dedup per-session hints across tool calls
- Table formatter: wrap oversized rows to fit console width
- Cache hit rate: divide by total input, not just new (uncached) input
- Notebook bridge: inherit outer tool approval, no inner permission prompts
- TUI rendering: pass ClientType.value to formatters, not str(enum)
- signal_completion: typed payloads from profile-declared schema
- template: rename writeFileFromTemplate → renderTemplateToFile
- WS session.new: materialise inline staged_files into provisioned workspace
- session.new --no-instructions: partial base suppression (not full override)
- session.new: --instructions override, honest budget, lazy base instructions
- LM Studio: reuse loaded instance + discover live context length
- verify_auth: thread profile plugin_configs into providers; LM Studio drops reachability probe
- Template plugin: tag-coherent prompt/tool-result enrichment
- LM Studio provider + profile→provider config wiring
- AppArmor: allow memories/ folder layout, bump template version for cache invalidation
- Memory storage: split raw queue (folder) from curated store (single file)
- Memory: fetch by IDs + restructure hint to suggest a single call
- Extract tag-coherence matching into shared utility, apply to references
- Memory enrichment hint: show triggering tags only
- Memory indexer: sentence-scoped segments + size cap
- Memory indexer: paragraph-coherence matching for compound tags
- Memory: enrich tool results + index compound tags by sub-tokens
- Code block formatter: emit semantic markup for web clients
- Fix: propagate client_type to lazily-created agent pipelines
- Rename table tags from nb- to j- prefix
- Table formatter: emit semantic markup for non-terminal clients
- Add agent_name parameter to create_headless_session
- AppArmor: allow read access to premium package directory
- Fix: register signal_completion on session directly, not as core tool
- Fix: don't unload session while model thread is still active
- Move signal_completion from plugin to core tool
- Fix: add missing ToolPlugin protocol methods to lifecycle plugin
- Add lifecycle plugin with signal_completion tool
- Fix: WS disconnect crash — _session_manager not on JaatoWSServer
- Extract shared subprocess runner from CLI plugin
- Add {{!command}} command substitution to prompt templates
- Fix: session env race condition between concurrent sessions
- Fix: make tool ID map suffix-transparent for :stream variants
- Permission timeout configurable per-client via ClientConfigRequest
- Bundle tool_id_mappings in SessionInfoEvent for guaranteed delivery
- Remove ID format examples from introspection parameter descriptions
- Fix: re-emit ToolIdRegistry after WS client registers tools
- Introspection: restore name alongside id, strengthen id-only params
- Fix: emit ToolIdRegistry during init AND on reconnect
- Fix: build ToolIdRegistry eagerly from tool schemas, not _reverse
- Fix: emit ToolIdRegistryEvent in emit_current_state only
- Introspection output: remove name field, model sees only IDs
- ToolIdRegistryEvent: server pushes ID→name mapping to clients
- Introspection output: include human-readable names alongside hash IDs
- Replace tool name strings with hash-derived IDs at provider boundary
- Memory plugin: configurable global storage path; auth: bearer debug logging
- SessionManager: add create_headless_session for daemon extensions
- Extract shared script loader from permission evaluator
- Memory indexer: exact-match only + min 2-tag overlap for enrichment
- Global memory tier: cross-session knowledge with quality curation
- Fix: strip auth headers on cross-domain redirects (httpx path)
- snapshot_workspace: remove unnecessary session pause
- AppArmor: actively unconfine thread before framework-level tools
- list_tools: drop category string parameter, index-only
- list_tools: add category_index parameter as integer alternative
- list_tools: build category enum dynamically from registry
- list_tools: show all tools in a category regardless of session profile
- list_tools: name missing plugins in category availability hints
- list_tools: show per-category availability based on session plugins
- list_tools: show registered categories even when no tools are loaded
- Fix UnboundLocalError in list_tools category validation
- list_tools: report unknown categories instead of returning empty list
- WS: read category descriptions from tools.register_client message
- Dynamic tool category descriptions via PluginRegistry
- Fork-replay primitives: 5 general-purpose capabilities for session manipulation
- Expose session fork primitives + registry protocol-mismatch warning
- Reliability: honor plugin_configs.reliability from profile
- Resilience hardening: Tier 3 (external service resilience)
- Resilience hardening: Tier 1 (storage) + Tier 2 (plugin lifecycle)
- Normalize None defaults and Python booleans in prompt substitution
- Apply frontmatter param defaults during prompt substitution
- Pass user-supplied args through %prompt-name expansion
- Fix per-turn placeholder leak in agent system instructions
- Dedup and default-aware missing parameters in prompt_library
- Add telemetry for the GC ↔ cache plugin coordination
- Disable code_block_formatter line truncation by default
- Allow ML model caches (~/.cache/huggingface, ~/.cache/torch) in AppArmor profile
- Allow Claude Code skills and commands dirs in AppArmor profile
- Fix AppArmor confinement leak; harden prompt_library against unreadable sources
- Confine tool execution by default; opt out via TRAIT_FRAMEWORK_LEVEL
- Allow user-global jaato config in AppArmor profile; fix subagent truncation inheritance
- Disable line truncation in code_block_formatter for non-terminal clients
- Allow read access to jaato source tree in AppArmor profile
- Fix sandbox false-positive on WS-provisioned workspaces under ~/.jaato/
- Remove dead aa-exec wrapping path; thread-level confinement is canonical
- Skip aa-exec wrapping when thread-level AppArmor confinement is active
- Allow both /tmp/jaato--* and /tmp/jaato-/* in AppArmor profile
- Fix AppArmor profile blocking agent's own workspace
- Add thread-level AppArmor confinement for in-process file I/O tools
- Add fork_ask, proactive tool result cap, server-side % dispatch, and structured auth errors
- Fix: run GC check between tool calls in agentic mode
- Add diagnostic logging to GC pre-send check
- Fix: read cumulative input_tokens from message_delta per Anthropic spec
- Fix: save_to downloads binary data correctly (raw bytes)
- Fix: enable HTTP redirect following in call_service
- Add save_to parameter to call_service for file downloads
- Include comment in PermissionResolvedEvent for WS clients
- Add ALLOW_COMMENT to permission channels (yc: prefix)
- Add ALLOW_WITH_COMMENT to permission evaluator contract
- Fix: set daemon_session_id before set_agent_context
- Fix: inject session_id into permission context for evaluators
- Fix: store workspace_path in permission plugin for evaluator context
- Fix: use session manager session_id for AppArmor profiles
- Fix: don't create .jaato/sessions at daemon startup from cwd
- Remove debug logging for daemon plugin workspace injection
- Add debug logging for daemon plugin workspace injection
- Fix: inject client workspace into daemon plugins at command execution
- Fix: initialize _workspace_path in init for all auth plugins
- Fix: pass workspace_path to all auth plugins for credential storage
- Add typed ZhipuAIRateLimitError and retry classification
- Fix Z.AI context limits: add glm-5-turbo, update default to 200K
- Fix: inject workspace_path into permission plugin init config
- Fix unreachable code in memory plugin get_config_schema()
- Remove channel_type/channel_config from plugin config schemas
- Migrate plugin config schemas from PluginSetting to JSON Schema
- Add turn_index and model_preamble to evaluator context
- Run evaluators even for pre-approved tools
- Extend permission evaluators with full scoped decisions
- Add runtime-injectable permission evaluators
- Implement profile inheritance with inherits field
- Fix Z.AI model discovery URL and add cross-provider list_provider_models()
- Fix AppArmor profile name mismatch in daemon session hook
- Remove dead auto_approved field from SubagentProfile
- Flush pending client tools after session.attach (not just session.new)
- Propagate daemon session ID into all OTel spans as jaato.session_id
- Add config introspection to GC plugins and expose them on daemon context
- Expose plugin_registry on daemon extension context
- Document get_config_schema() in plugin implementation guide
- Add introspectable plugin settings via PluginSetting and get_config_schema()
- Expose available_plugins on daemon extension context
- Cache entry point lookup in embedding subsystem discovery
- Fix AppArmor session hook: check self._apparmor at execution time
- Fix sandbox_mode: use session hook and run hooks after Session creation
- Add debug logging for sandbox_mode session lookup
- Fix sandbox_mode not appearing in session.info event
- Include sandbox_mode in session.info event
- Fix AppArmor profile loading: use sudo for apparmor_parser
- Fix AppArmor cache permission error and align docs with implementation
- Add TUI installer and restructure dependencies into optional extras
- Extract embedding subsystem behind jaato.embedding entry point protocol
- Complete agent/profile split: SDK, TUI, and deprecation warning
- Split agent (prompt) from profile (runtime config)
- Remove icon and icon_name from profiles
- Add anti-hallucinated-constraints rule to framework instructions
- Preserve running subagents during plugin shutdown/re-init
- Fix client tool execution during WS disconnection
- Stop PARENT messages from interrupting subagent streaming
- Expose EventBus from JaatoServer for daemon extensions
- Pass client_id to WS message handler callbacks
- Add user identity tracking for sessions and WS message handlers
- Include session_id in session hook callback
- Add extensible WS message handler registration
- Emit events.subscribed notification for external event subscriptions
- Add event.external WS handler for client-to-agent event injection
- Include cancellation reason in [Generation cancelled] messages
- Fix session span parenting: all agents share one root session span
- Add session and agent spans for full trace tree hierarchy
- Allow env var references in command sanitizer
- Load template index from disk independently of references plugin
- Use custom_name from spawn_subagent as agent display name
- Add TLS support to WebSocket server
- Fix core executor lookup in all 3 ai_tool_runner code paths
- Fix: look up core tool executors in ai_tool_runner fallback
jaato-server
Jaato Server — LLM tool orchestration runtime and daemon.
See the project README for full documentation.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jaato_server-0.9.0.tar.gz.
File metadata
- Download URL: jaato_server-0.9.0.tar.gz
- Upload date:
- Size: 5.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
770c78b2ee17959297d33d64e7338d61aaa47ecde7ef09ad5bf0d987b8b806d6
|
|
| MD5 |
a06997da412b036ce6574bdd2f71231a
|
|
| BLAKE2b-256 |
10a57e0223ea47ef99b9d1a10002779f21b8e892007b9e8ea509663bd0901bbd
|
Provenance
The following attestation bundles were made for jaato_server-0.9.0.tar.gz:
Publisher:
publish-pypi-server.yml on Jaato-framework-and-examples/jaato
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jaato_server-0.9.0.tar.gz -
Subject digest:
770c78b2ee17959297d33d64e7338d61aaa47ecde7ef09ad5bf0d987b8b806d6 - Sigstore transparency entry: 2779674683
- Sigstore integration time:
-
Permalink:
Jaato-framework-and-examples/jaato@6350219a09f0979097b01cbbd952a269ebb6a2e2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Jaato-framework-and-examples
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi-server.yml@6350219a09f0979097b01cbbd952a269ebb6a2e2 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file jaato_server-0.9.0-py3-none-any.whl.
File metadata
- Download URL: jaato_server-0.9.0-py3-none-any.whl
- Upload date:
- Size: 5.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23d8ccbdf13235ae856901452b76cd5134d62ab958e9b5156a17984ed0870aaa
|
|
| MD5 |
302f75bd25316366e903ec0d2d74c841
|
|
| BLAKE2b-256 |
564e5adefbb28c28f60515f7a03b92b75a5aa4e3e4da6a91c0c0ec96f689500a
|
Provenance
The following attestation bundles were made for jaato_server-0.9.0-py3-none-any.whl:
Publisher:
publish-pypi-server.yml on Jaato-framework-and-examples/jaato
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jaato_server-0.9.0-py3-none-any.whl -
Subject digest:
23d8ccbdf13235ae856901452b76cd5134d62ab958e9b5156a17984ed0870aaa - Sigstore transparency entry: 2779674754
- Sigstore integration time:
-
Permalink:
Jaato-framework-and-examples/jaato@6350219a09f0979097b01cbbd952a269ebb6a2e2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Jaato-framework-and-examples
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi-server.yml@6350219a09f0979097b01cbbd952a269ebb6a2e2 -
Trigger Event:
workflow_dispatch
-
Statement type: