Repository navigation
Conversation
595be9f to
e114ac1
Compare
e114ac1 to
c23734a
Compare
Adds the CreateSessionRequest.agent_definition_name / CreateSessionResponse .resolved_agent_definition_name wire fields, a write-once AgentDefinitionName label on session.Session and sessnap.Snapshot, and verbatim echo on the response. Plumbing only: no catalog restriction, provider/model/limits/ permission-mode resolution, or validation is wired from this field yet — that is later work in docs/acceptance/session-scoped-agent-identity.md. Pins AC2.1 (TestSessionScopedAgentIdentity_Scenario2_PersistsAcrossSnapshotRoundTrip) and AC2.2 (TestSessionScopedAgentIdentity_Scenario2_ResponseEchoesBoundName). Plan / Interface PR: #1815 (merged, a9dfd84) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…l-widening paths Task D of the session-scoped-agent-identity plan (AC3.1, AC3.2). Authority gains an optional, write-once Ceiling capability set, bound once alongside BindAuthority/RestoreLabels and never re-derived. GrantToolAuthority and CompleteWorkspaceEnrollment — the two aggregate methods that can widen a bound session's tools post-bind — now reject any grant that would exceed the Ceiling, making it a Session-aggregate invariant rather than an enumerated adapter-layer guard list. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…atalog (ADR 0353, Task B) CreateSession with agent_definition_name set now builds the session's catalog exclusively from the resolved AgentDef's tools/disallowedTools/mcpServers, mints session.Authority from that same resolved catalog (never the deployment default), and skips Config.MCPBroker attachment entirely — while keeping ordinary main-session guardrails/governance/ask-flow (never the child-shaped headless auto-deny). - internal/app/agentdefs.go: extract resolvedAgentDefCatalog from buildAgentDefEngine (byte-identical for its 3 existing child call sites); add baseSubagentToolsNoFS for the no-fs profile intersection. - internal/app/agentdef_root.go: new buildAgentDefRootEngine (bottoms out in engineDepsForProvider + attachGuardrailReviewer instead of the child-shaped newChildEngineForProvider; mints Authority via mintRootAuthority over the def's own catalog) and agentDefSessionEngineFactory. - internal/app/build.go: wire AgentDefSessionEngine onto server.Config from the same collaborators as SessionEngineWithTools. - internal/adapter/server/service.go: new AgentDefSessionEngineFactory type and Config field, SessionEngineResult.Authority field, agent_definition_name validation (rejects a debug target or client/debug MCP servers), and a dedicated create-path branch that never reaches MCPBroker attachment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Task B (mints session.Authority via mintRootAuthority) and Task D (added Authority.Ceiling + its enforcement in GrantToolAuthority/ CompleteWorkspaceEnrollment) were dispatched concurrently and never wired together: buildAgentDefRootEngine minted an Authority with a nil Ceiling for every real agent-bound session, making the Ceiling mechanism dead code in production even though its unit tests (which set Ceiling by hand) passed. - buildAgentDefRootEngine now sets Ceiling to a full-field copy of the CapabilitySet it just minted, for every agent-bound session (AC3.1). - BindAuthority now rejects a payload whose CapabilitySet.Tools already exceeds its own Ceiling, tools-only (matching GrantToolAuthority / CompleteWorkspaceEnrollment's existing AllowsTool convention, not the fuller CapabilitySet.Contains dimensional check) — hardening flagged by external review, since neither post-bind guard could otherwise repair an already-inconsistent bind. - Extended TestSessionScopedAgentIdentity_Scenario1_AuthorityMintedFromDefCatalog (AC1.9) to also assert Ceiling is set and consistent, and added a mutation-verified rejection subtest to TestSessionScopedAgentIdentity_Scenario3_AuthorityCeilingBoundOnce (AC3.1). Both gaps found by independently re-verifying the codebase (not trusting a report) after an external review flagged the BindAuthority half; the more severe wiring gap was found in the course of checking that specific claim. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ped Role Task E's AC1.7/AC1.8 pinning tests surfaced a real production gap: buildAgentDefRootEngine set Deps.Role to "agent-root:<def>" purely for diagnostic readability, but engine/agent uses Role != "" throughout (loop.go, steer.go, actionreview.go, dispatch.go) as the signal that an engine is a delegated child — gating principal-prompt-provenance trust, review-principal establishment, and external-authorization presentation. Consequence in production: establishReviewPrincipal short-circuited for every agent-bound session, so PrincipalFactsComplete was permanently false, so every "acceptable" contextual-guardrail verdict was rejected as untrustworthy (acceptable_with_incomplete_context) and fell back to "unresolved" — which a headless/non-interactive engine (the Slack-bot deployment this whole feature targets, issue #1053) denies outright. Every guardrail-matched tool call on a real agent-bound session running headless would have been silently blocked, whenever GuardrailsRules matched it. Considered adding an explicit Deps.ChildShaped field decoupled from the display-only Role, set once at the shared child-engine builder (childEngineDeps/childEngineDepsForProvider) and read at all 8 behavior- gating call sites instead of Role. Reverted: several existing engine/agent tests construct a Deps{Role: ...} literal directly (engine-level tests cannot import internal/app's builders) to simulate a child, and lacking the new field they were silently reclassified as root-shaped — one such test then presented an interactive authorization ask nothing resolves, deadlocking `go test ./agent/...` (goroutine dump: askRegistry.await via surfaceAsk/authorizeDecision). That approach's blast radius was broader than it looked. Minimal fix instead: buildAgentDefRootEngine simply never sets Role. Zero changes to engine/agent's core dispatch logic; the bound def's name is already logged once per engine build by agentDefSessionEngineFactory's own diagnostic call, so no observability is lost. This is also more faithful to AC1.6 ("ordinary main-session behavior... in every respect except its tool catalog") than a differentiated Role ever was. The now- unused role parameter is removed from buildAgentDefRootEngine and its three call sites. Verified: fresh `go test -count=1 ./agent/...` (engine module, was hanging to the 600s timeout with the reverted ChildShaped approach, now green in ~5s) and `go test -count=1 ./internal/app/... ./internal/adapter/server/...` — all green; scoped lint clean. Pins AC1.7 (TestSessionScopedAgentIdentity_Scenario1_ContextualGuardrailInspectsEffectivePayload) and AC1.8 (TestSessionScopedAgentIdentity_Scenario1_HookMutationCannotBypassGuardrail). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… (ADR 0353, Task C) Implements ADR 0353's 5-case provider/model pair resolution (resolveAgentDefRootProviderModel) and tighten-only Limits/PermissionMode clamps (tightenLimits, clampPermissionMode) for an agent-bound session, wired into agentDefSessionEngineFactory in place of the placeholder resolveChildProvider call (whose def-wins-over-parent, silent-fallback contract is wrong for case 5 — an unavailable def-pinned provider must fail session creation, never silently fall back). Case 1 delegates to the existing resolveProviderModel for its base-pair computation, per the plan's own implementation guidance; cases 2-5 are fresh logic against the request's own ProviderSelector. Pins AC1.12 (TestSessionScopedAgentIdentity_Scenario1_LimitsTightenOnly), AC1.13 (TestSessionScopedAgentIdentity_Scenario1_PermissionModeClampedNotRaised), AC1.14 (TestSessionScopedAgentIdentity_Scenario1_ProviderModelPairResolution). Plan / Interface PR: #1815 (merged, a9dfd84) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ADR 0353, Task F) SetMode, LoadSessionWithMCP, the needsRehydration()/engineAndEnvironmentFor choke point (StartRunContent, RetryFailedRun, CompactSession, resumeFromAwaiting), rebuildGrantedAuthorizationEngine, and ConnectWorkspaceServices all now refuse an agent-bound session rather than silently rebuilding on the deployment's default catalog, so its tool-scope ceiling survives every rebuild trigger that doesn't know about agent_definition_name. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…coped project memory (ADR 0353, Task G) ForkSession/ClearSession now unconditionally copy the source session's agent_definition_name onto the successor (Profile-style, no override field) and route the successor's engine rebuild through AgentDefSessionEngine rather than the deployment's default catalog factory, skipping Config.MCPBroker attachment for agent-bound successors the same way create-time does (AC2.3, AC2.4). resolveAgentMemoryHead's "project" tier now binds to the caller's own resolved placement root instead of the single process-wide cfg.Workspace, using the root-aware projectIngestionAdmittedForRoot gate — two agent-bound sessions on the same def but different placements (e.g. a fork onto an alternate worktree) no longer share or leak the same project-memory file, and a placement the operator never specifically vetted is never admitted merely because the deployment's global trust flag is true. Under profile: "no-fs" this is a silent no-op, never an error (AC2.5, AC2.6). The session's own placement root reaches AgentDefSessionEngineFactory's closure via a small ContextWithAgentDefSessionRoot/AgentDefSessionRootFromContext context-value pair rather than growing the factory's frozen signature. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…y.Ceiling Aggregate-gates pass after all 7 tasks landed. Two gaps found: 1. task api:update was never run for the two additive engine/session surface changes from earlier tasks (Session.AgentDefinitionName, Authority.Ceiling) — engine/api/session.txt now reflects both; classified Added (minor) in engine/CHANGELOG.md per COMPATIBILITY.md. 2. A second, separate persistence path — eventsource.SessionMeta/Fold, used for durable event-log session reconstruction (distinct from sessnap, which Task A already handled) — never carried AgentDefinitionName at all. TestFoldContractDocMatchesSessionFields (a reflective drift guard) caught this: it fails until a new session.Session field is classified in COMPATIBILITY.md's reconstruction contract. Fixed: SessionMeta gained the field, Fold restores it by direct assignment (mirroring Profile exactly), the one production caller that already threads full session metadata through this path (internal/app/source_evidence.go) now includes it, and COMPATIBILITY.md's contract table + the drift-guard test's field map are both updated. Also regenerated user-docs/reference/grpc-schema.md via `task docs` (buf was missing from this environment; installed via `go install github.com/bufbuild/buf/cmd/buf@latest` for this session) — it had never picked up Task A's agent_definition_name/resolved_agent_definition_name proto fields until now. Verified: full `go test ./...` in both engine/ and root modules green (including TestPublicAPIUnchanged and TestFoldContractDocMatchesSessionFields); `task docs` passes (0 broken links/anchors); scoped lint clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… (ADR 0353) External review found sessnap.Restore and eventsource.Fold could restore a session carrying AgentDefinitionName with no Ceiling. Everything else routes it as agent-bound, yet GrantToolAuthority and CompleteWorkspaceEnrollment treat a nil Ceiling as unrestricted, defeating the non-widenable ceiling. Both restore paths set AgentDefinitionName after binding authority, so a check inside BindAuthority could not see the label. Reorder both to set it first (as the create path already does) and make BindAuthority reject an agent-bound bind without a Ceiling. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…(ADR 0353) createRequest.matches ignored AgentDefinitionName, so a same-owner retry could swap between an agent-bound and an ordinary (or different) session. It also compared raw request limits with persisted limits, which for an agent-bound session are the definition's clamped values, so legitimate retries could be rejected. Compare the binding explicitly and skip the raw-limits comparison for an agent-bound request. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ovider After rebasing onto main, engine construction takes a provider+model pair. buildAgentDefRootEngine was given only a model string, so the pair carried the deployment default provider even when the definition or request selected a different one. Pass the resolved ProviderModelID instead, matching buildAgentDefEngine. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
c23734a to
6065a11
Compare
Resolve root model aliases independently of delegation defaults, preserve effective provider configuration, and reuse owner-scoped context and pinned runtime assets. Enforce successor attenuation, validate factory acknowledgments and restored authority, preserve original retry intent, and close failed-build resources. Complete HTTP/gRPC binding parity, advertise session_agent_definitions, and add integration regressions and owning documentation. Leave the stacked TUI changes untouched. API compatibility: additive optional binding fields and discovery feature; wire major remains 1. Clients relying on binding must require support and verify the echo. Ordinary clients and legacy ordinary sessions remain unchanged. Valid legacy bound records remain readable, but missing retry fingerprints cannot establish explicit-ID retry equality; malformed authority fails closed. Engine additions and behavioral guards are classified separately in the changelog. Validated with full lint, offline and race suites, docs, SDK checks, and the offline demo. Full test suites used serialized tasks and isolated loopback networking to avoid host fixture conflicts. Co-authored-by: Mecatl <noreply@mecatl.dev>
Consolidate catalog cases and broker setup, trim integration permutations already covered by unit matrices, and correct stale binding comments. Preserve distinct lifecycle and transport assertions; no production behavior changes. Co-authored-by: Mecatl <noreply@mecatl.dev>
Resolve the changelog-only conflict by retaining both the agent-bound authority entry and main's scheduling contract entries. Preserve all automatic merge results. Validated the merged backend with task lint, task docs, complete offline and race suites, and the offline demo. Co-authored-by: Mecatl <noreply@mecatl.dev>
|
So, I think the direction makes sense. Asking an agent to “be a reviewer” is easy. Making sure it stays within its permissions when someone forks the session or tries to attach more tools is the useful part here. I’d keep a clear distinction between what this PR enforces inside Mecatl and what we’re proposing in #2121. This PR gives us a session bound to a definition, with an authority ceiling that cannot grow. The broker work would independently enforce the MCP portion of that authority and attribute calls to a particular agent acting for a particular user. I wouldn’t make this PR wait for that whole architecture. My main question is how definition changes interact with session continuity. This PR rebuilds fork/clear successors using the current definition while retaining inherited authority. The identity proposal pins a definition revision to an instance. Those can fit together, but we should be explicit: a successor is a new instance; restoring an existing instance must not silently replace its definition or widen its authority. And an administrator still needs to be able to revoke access. I’m fine with failing closed on restart for this first version. It’s a real usability limitation, especially during rolling upgrades, but I’d rather have an honest limitation than accidentally restore a broader session. We should make the recovery path clear and keep safe continuation as a separate follow-up. For the identity integration, I’d propose treating Concretely, I’d want the integration contract to separate:
When we add the broker, Mecatl would register the instance using a definition reference the broker recognizes. The broker would validate that registration and establish the instance’s permitted MCP operations from admitted definition records. The client or model shouldn’t be able to establish authority by supplying a name, a tool list, or even a digest. A digest identifies content; it doesn’t prove we trust it. That also leaves a separate admission question: is this caller allowed to start a session using this definition? We don’t need to add definition-specific ACLs here, but selecting a known name must not later become an implicit privilege grant. For this PR, I’m suggesting we document that boundary and the successor/restoration rules, not add credentials or a registration API. Then the follow-up in 2121 has a concrete job: define the admitted definition reference, bind it to an instance and owner, and enforce the resulting ceiling at the broker. |
JAORMX
left a comment
There was a problem hiding this comment.
I think the overall approach makes sense, but there’s a definition-scope enforcement issue we should fix before merging: the root authority is minted from a catalog that can include explicitly disallowed tools. I’ve kept the inline comment focused on the implementation and repair, rather than an exploit walkthrough.
The other actionable findings are the child-only Shell trust gate leaking into root construction, explicit auto reasoning effort changing meaning during reconstruction, and a missing exactness assertion on the production-minted ceiling. Those have inline comments with the relevant paths and suggested regression coverage.
This was an eight-reviewer panel covering the agreed spec, Go conventions, test adequacy, security, lifecycle/composition, API compatibility, duplication, and library reuse. Disputed findings received a separate verification pass. No local tests or linters were run; this is static review backed by the existing CI results. I didn’t find a useful duplication or dependency refactor to ask for. The root/child differences mostly deserve to stay explicit.
A few nonblocking follow-ups, rather than requests to expand this PR:
- Clarify that bound-session limit tightening covers turns and tool calls; the requested consecutive-failure limit currently keeps the inherited value. That matches the accepted scope, but the API documentation says “limits” more broadly.
- Add high-level TypeScript binding support as a coordinated follow-up: the typed option, feature requirement, and exact response-echo check should arrive together. Accidental JavaScript forwarding of the currently undeclared option isn’t a supported safe workflow.
- Clarify whether explicit-ID Service retries compare raw omitted mode or mode after deployment defaulting. The fingerprint currently uses the latter. This is the embedding seam, not a public HTTP/gRPC explicit-ID retry issue.
- Consider making definition selection and governance-root inputs explicit in a future factory API cleanup. I don’t think a context-to-request refactor needs to block this PR.
CI is a separate concern: Go race, lint, build, API compatibility, and SDK checks passed. The Studio route-count failure is inherited from the base: the skills-files route added a sixteenth operation without updating the count or declaring the expected transport errors. The execution-provider production-profile check was still running when checked. I’m not requesting changes because of that inherited CI failure.
The intentional exclusions (bound-root delegation, new definition-name ACLs, and direct restart execution) aren’t review blockers, and I’m not pulling the broker or TUI follow-ups into this PR.
| // deployment's build-time default closure (AC1.9). session.SessionKindMain is | ||
| // the only kind an agent-bound session can ever be (AC1.5 rejects the debug | ||
| // combination at the create boundary before this ever runs). | ||
| authority := mintRootAuthority(cat, resources, session.SessionKindMain) |
There was a problem hiding this comment.
Blocking: can we apply the definition’s exclusions to the final assembled catalog before minting authority here? scopedToolNamesMode filters core names, but resolvedAgentDefCatalog subsequently adds MCP tools at agentdefs.go:1142–1151 and automatically adds ShellStatus at 1130–1133, without applying DisallowedTools again. This root then copies those entries into both its grant and ceiling. The delegated path’s separate agentDefinitionAuthorityCeiling filtering does not protect this root path.
Please make the final advertised catalog and minted authority respect the same exclusions, including MCP and automatically added tools, and add negative regression coverage through the real root factory. Normal permission approval must not override an explicit definition exclusion.
| } | ||
|
|
||
| noFS := profile == server.ProfileNoFS | ||
| base := baseSubagentTools(cfg) |
There was a problem hiding this comment.
This base set still carries the read-only child’s Shell trust gate. baseSubagentTools adds Shell through buildSandboxedCommandRunner, which requires TrustProject; the main runner created above does not have that same restriction. An explicitly admitted operator definition requesting Shell therefore loses it on an untrusted checkout, even when an ordinary root has Shell available through its normal permission flow. allowShell=true later cannot put a missing tool back into the base.
Could we derive root Shell availability from the main runner before applying the definition scope, while preserving no-FS and deployment restrictions? A regression using an explicit definition, TrustProject=false, and a configured Ask would pin the distinction between project-content trust and root tool permissions.
| // agent-bound session's create path (AC1.10), so res.MountedClientMCPTools | ||
| // and broker are always empty here. | ||
| authority = res.Authority | ||
| sel = ProviderSelector{ProviderID: res.ProviderID, ModelID: res.ModelID, ReasoningEffort: res.ReasoningEffort} |
There was a problem hiding this comment.
Persisting effective reasoning effort here loses the distinction between explicit auto and an omitted selector when this configuration is reconstructed. With operator effort high, create-time auto correctly resolves to an empty effective value. The runtime-rebuild selector at service.go:6521 later passes that empty value back to resolveSessionEffort, where it means inherit the operator default. It becomes high, and the fixed-configuration check at 6815–6830 rejects the rebuild. This is reachable after a same-process MCP runtime revision change; it does not depend on the intentionally unsupported restart path.
Fork/Clear reconstruct the same empty selector at placement_successor.go:382, but accept and persist the changed effort instead.
When reconstructing an already-bound session’s effective configuration, could we encode stored empty effort as explicit auto, while retaining explicit successor overrides? Please cover both a runtime revision rebuild and Fork/Clear with operator default high and initial request auto.
| t.Fatalf("minted Authority has a nil Ceiling — GrantToolAuthority/CompleteWorkspaceEnrollment would treat this agent-bound session as unrestricted") | ||
| } | ||
| if !authority.Ceiling.Contains(authority.CapabilitySet) { | ||
| t.Fatalf("minted Ceiling does not contain the minted CapabilitySet: ceiling=%v capability=%v", authority.Ceiling.Tools, authority.CapabilitySet.Tools) |
There was a problem hiding this comment.
Could we assert the production-minted ceiling’s exact contents against an independently specified fixture here? Checking expected tools are present and Ceiling.Contains(CapabilitySet) still passes if an undeclared tool is added only to the ceiling. The aggregate grant-rejection tests construct their own ceilings, so they wouldn’t catch that factory regression either.
An exact expected capability/ceiling assertion, followed by an out-of-definition grant attempt that must fail without mutation, would pin the nonwidenable-ceiling contract through the actual construction path. Explicitly denied MCP and automatically added tools would make useful negative controls alongside it.
Summary and stack
Implements session roots bound to named agent definitions: a definition-specific tool catalog and nonwidenable authority ceiling, with ordinary root-session guardrails and approval handling. Motivated by #1053.
Backend PR:
main→ this PR → #2055, the TUI command and picker. This PR contains the server, engine, persistence, protocol, SDK feature vocabulary, documentation, and backend tests—not the/agentUI.Previously agreed design; implementation review remains necessary
This is the implementation of the design and acceptance criteria reviewed under the former ADR/acceptance-plan process, not a new proposal for the feature:
Main has moved. Those approvals establish design intent, not that old implementation recipes or an old review still prove today's code correct. This implementation adapts that intent to current owner-scoped sources, placement and MCP-runtime lifecycles, provider-aware aliases (#2019), and contextual guardrail composition. Historical task letters are not the readiness checklist.
Implemented behavior
agent_definition_nameon gRPC and HTTP creation, withresolved_agent_definition_nameechoed back. Unknown names and incompatible debug/client-MCP combinations are rejected.model_idremains literal. An unavailable explicitly pinned provider still fails creation—this PR does not introduce a different fallback policy.API compatibility
Additive wire change; API major remains 1. Omitted binding fields preserve ordinary-session behavior. The stable
session_agent_definitionsfeature reports protocol support on both transports, independent of whether definitions are configured. Clients relying on binding must require this feature and verify the exact response echo before sending a prompt; an older gRPC server can silently ignore the new field. Existing clients do not need changes. Upgrade the server before relying on binding; no wire-breaking change or major-bump approval is requested.Go and stored-data compatibility are separate: new engine identifiers are classified as Added and authority-enforcement behavior as Changed (pre-v1 minor) in the engine changelog. Ordinary legacy sessions need no migration. Valid legacy agent-bound records without the new retry fingerprint remain readable but cannot prove explicit-ID retry equality. Malformed bound authority is rejected, not reconstructed from today's definition. Metadata readability does not imply permission to resume execution after restart.
Additional due diligence — October 15, 2026
The extra pass checked the implemented behavior again rather than relying on the historical approvals or an earlier end-to-end run.
Automated verification and targeted regression review
Passed locally on the completed implementation and cleanup tree:
task linttask --concurrency 1 test— complete offline suite, including standalone module checkstask --concurrency 1 test:race— complete race suitego run ./cmd/mecademo— observed tool call, permission ask, approval, and resulttask docs; SDK typecheck and focused discovery tests; generated contract/API updates and checks; site buildThe full suites were serialized and used a short temporary root plus isolated loopback networking to avoid occupied host OAuth ports and Unix-socket path limits. Namespace setup capabilities were dropped before the final gate run. Initial environment/timing failures were investigated; tests were not disabled to obtain the passing runs.
Verification ran on the integrated backend-plus-TUI working tree before the stack was separated. After committing the backend changes and updating the TUI stack, the final TUI head
c704ae874was checked to be tree-identical to that tested tree. This is not a claim that the backend-only SHA was separately put through every gate, or that a future merge with newermainhas already been validated. CI remains an independent gate.Agent-assisted spec, standards, test-adequacy, architecture, security, and reuse review was followed by fixes and focused closure checks. Useful committed evidence includes:
The bloat review consolidated repeated catalog/broker setup and trimmed redundant integration permutations while retaining the unit matrices and distinct lifecycle/transport tests. It did not replace integration coverage with helper-only assertions.
Separate manual end-to-end smoke pass
The operator supplied an additional agent-assisted manual-run report from today's working tree. It used locally built
mecated/mecatui, the offline--mock-scriptprovider, temporary HOME/XDG directories and workspace, HTTP/SSE via curl, and a small gRPC client built from generated contracts. It exercised both in-memory and persistent stores, including killing and restarting the persistent server. Authentication was disabled on loopback. No operator credentials, paid providers, or operator state were used. This report was not pinned to an immutable final commit and should not be read as a rerun after every subsequent edit./v1/compatibilityadvertisedsession_agent_definitions.acceptEditsagainstreviewer'splanceiling resolved toplanon both transports. A requested 100-turn limit resolved to 3, confirmed with gRPC GetSession.max_turns.reviewerreturned unknown tool. The same call againstwriter(Read/Write) producedpermission.ask; this observation alone does not claim that the write was approved and completed.agentDefinitionName: HTTP 400. Binding plus debug target: HTTP 400. SetMode on a bound session: InvalidArgument.fastresolved tomock/mock-fast; an unavailableopenaidefinition pin returned InvalidArgument; a bound model-only request retained its literal model ID.The picker/filter and
/agentsmoke observations belong to #2055, not this backend diff.Limits of that evidence and remaining merge work
Not exercised by the manual smoke pass: real LLM behavior with restricted catalogs; authenticated multi-owner transport/deployment behavior (covered at the isolated composition-test layer); the inner agent-bound client-MCP guard on a Unix-socket-only listener; deployed mecak8s/Redis/Kubernetes leases; remote store/definition drivers; TLS/mTLS deployment; microVM/execution-template deployment; or a live TypeScript SDK journey. Mock/fixture coverage and SDK type/discovery checks are not substitutes for those deployment runs. These checks can be done before merge with the appropriate environment; they are not inherently impossible until deployment.
Intentional v1 scope: no delegation from an agent-bound root, no new per-caller definition-name ACL, and no execution resume of a bound session after restart/client-MCP rehydration. Fail-closed restart was an explicit accepted decision; continuation support remains #1796.
Main integration completed after the review. The initial review fetched
mainat7cd9bb0f9. This branch now includesmainatce0f816e0, merged inc4b5b1fe0. The only textual conflict was inengine/CHANGELOG.md; both the agent-authority and scheduling-contract entries were retained unchanged. Localtask lint,task docs, the complete offline and race suites, and the offline demo passed again on the merged backend. The TUI branch was then updated, with its package race suite and scoped lint passing; its diff remains the original 15 TUI files. GitHub reports both branches conflict-free at this update. The earlier manual smoke report was not rerun as part of this conflict resolution. Latest CI and implementation review remain required; these results do not certify future main changes.