agent.run(...) does not establish this
integration.
Explicit native embedding has bounded acceptance for storeless sessions and
completed-turn SQLite close/reopen followed by fresh governed work in actual
separate processes, with
current host grants, a stable configured provider binding and the real File token
owner. Cold acceptance was run directly; publication and CI used their
recorded test inventories. See the
implementation checkpoint
for exact source and evidence scope.Stock CLI, REST, RPC and MCP paths do not acquire governed activation from this
API. The additive
meerkat_rpc::governed_jsonl entry provides a fixed-host,
single-connection profile; it requires default-features = false plus
local-authorization and does not activate ordinary RPC constructors. The
public-entry/notification profile has focused local and published CI acceptance.
Its fixed-host loopback evidence does not establish ordinary-constructor activation.
Console projection is not integrated native-plus-Console proof.
Persistent controller administration, interrupted recovery, human consent and
full surface/platform coverage remain separate work. The shell composition below
covers supported macOS requirements. Provider login and Console access
administration do not grant native operation permission. The measured conditional
fresh-turn means missed the cheap-default target; full-platform and per-operation
p99 acceptance remain open. See the
acceptance scope
for the required coverage. No live-provider coverage is claimed.Install the real owners before sharing the machine
Enablemeerkat-runtime’s local-authorization feature in the matching checkout
or dependency release. Compose NativeGrantWorkConfiguration from these owners:
The policy callbacks read current local owner facts without I/O. Relevant owner
mutations participate in the grant authority’s publication. Preserve correlated
principal/action/resource rules; independent lists must not grant extra pairs.
Arc, cloning it, or
registering sessions. Already shared or populated machines refuse installation.
For persistence, select governed mode during construction as shown below. The
fluent installer does not upgrade a persistent machine. The backend must supply
exclusive execution custody; setup refusal must propagate before publishing a
service or provider-auth handle.
Configure native shell confinement on the factory
For automatically composed shell tools, install the trusted host requirement withAgentFactory::with_shell_confinement. Keep using the native owners above
to authorize each exact shell operation. Confinement controls the process’s
mechanical access after authorization; it does not authenticate input or grant
permission to a command.
This native Rust excerpt assumes existing, canonical absolute paths named
work_root and sessions_path. It grants application filesystem access to the
work tree plus the declared command-runtime baseline and denies IP networking:
Required enforces the complete supported requirement or refuses that launch;
there is no unrestricted fallback. The current backend uses macOS Seatbelt.
Non-macOS hosts, exact IP endpoint grants and required termination of descendants
that escape their process group are unsupported. Invalid requirements or an
unavailable executor also refuse before the requested command runs. Required
launches use the configured cwd and exact explicit environment, with no ambient
environment inheritance. Select a directly executable shell allowed by the
requirement; the example uses /bin/bash to avoid macOS /bin/sh’s mutable
selector outside the work grant. TrustedHost is the default shell compatibility
mode and inherits the host environment. It is independent of local-governed
authorization: installing native grant owners does not select Required, and
selecting Required does not install those owners.
If the application grants only its local tools, disable provider-hosted
capabilities it does not authorize in the existing Config before constructing
the builder. For example, Anthropic web search defaults to enabled on supported
models; the shell E1 fixture uses the explicit disable shown above. It is an
application capability choice rather than a requirement for every shell host.
This selects requested provider capabilities. It does not replace the native
controller or operation owner checks, and a capability kept enabled still needs
its own current authorization.
The macOS e1_policy_control/shell_confinement.rs fixture passed its bounded E1
test with authenticated native ingress, actual grants and model HTTP boundaries,
two authorized shell commands and native audit. The first command enters and
then receives a nonzero exit with stderr for a denied
filesystem write; the outside file remains unchanged, a permitted sibling
executes, and the same run continues to its next model turn. That is returned
shell feedback from an entered process. A backend or launch refusal happens
before the command runs. Shell dispatch preserves its exact mechanical cause as
confinement_refused tool feedback, including foreground, background and monitor
recovery paths. Ordinary IO and custody failures retain their execution error
class. The member upcall bridge preserves the exact confinement cause and
settlement companions in tool feedback; malformed causes become an ordinary
execution failure rather than a fabricated mechanical refusal.
This bounded scenario does not establish restart,
performance acceptance or full surface/platform coverage.
The core pre-tool path also accepts a typed HookEngineError::LaunchRefused
from an injected hook engine. It skips that tool and returns the exact
confinement_refused or ordinary execution_failed feedback; permitted
siblings and the next model turn continue. HookLaunchRefused retains the
attempted tool call ID without emitting hook start or completion events.
An explicit pre-tool hook decision likewise refuses only its attempted call,
using hook_denied feedback with the exact hook ID, point, reason code and
optional JSON payload. An absent payload and a present JSON null remain distinct,
including across the member upcall bridge. The entered deciding hook retains its
start, completion and denial events; its decision is not a launch failure.
This core integration does not yet wire required confinement into the native
command-hook engine or record the refusal in protected audit. Other hook points
still need their own local-refusal integration.
Install a bounded model reviewer for R2 tools
This is an unreleased source preview of the model-review, audit-correlation
and typed reviewer-error APIs. The example is source-checked, not compiled or
qualified end to end. Use a checkout containing those changes; the earlier
acceptance results on this page do not qualify this example.
AgentFactory, before constructing the
FactoryAgentBuilder. Your OperationPolicyOwner still selects the required
LocalPolicyAllowance.review_tier for each exact operation. Installing a model
neither changes that tier nor grants permission. R1 keeps its normal native
authorization checks and makes no reviewer call.
This excerpt uses your configured factory and config. Set reviewer_model
to an explicit model name supported by your configured OpenAI backend, and
reviewer_auth_binding to its existing AuthBindingRef. These are host
configuration, not values taken from the proposed tool call. Reuse the host’s
ApprovalService as approvals.
config.tools.tool_timeouts override.
An allow expires at that same deadline and is checked again at effect entry.
The adapter makes one tool-free request, with no retry or fallback; it does not
accept per-session provider parameter overrides in the reviewer identity.
NativeOperationReviewContextSource reads through the candidate’s retained
native work owner. Each original source read and the reviewer’s own inference
need independent current authorization under that work. The tool’s permission
does not grant either. If those prerequisites also require review, this adapter
refuses rather than approving them recursively. A missing context reader,
denied source or model route, expired deadline, or unsupported reviewed entry
produces local unavailable feedback; there is no transcript or
ungoverned-model fallback.
For an R2 tool, model deny or escalate returns local review_unsatisfied
feedback, and review unavailability returns review_unavailable. The attempted
effect does not run; permitted siblings can continue. An allow still needs the
same candidate and current native permission at entry. Failure to stage the
candidate’s protected audit link prevents reviewer entry. That failure, source
observation failure and reviewer-model observation failure retain the typed
operation_observation_unavailable outcome. The engine preserves completed
sibling results before reporting that infrastructure failure for the affected
attempt. Fresh work requires new native admission. R3 returns
human-consent-required feedback: this adapter provides no automatic human
route, and a model allow cannot satisfy R3.
Custom OperationReviewer and OperationReviewContextSource implementations
return ReviewerFailure::Unavailable for ordinary unavailability and preserve
ReviewerFailure::ObservationUnavailable for protected observation failures.
Existing unit constructors or patterns using ReviewerFailure must migrate to
ReviewerFailure::Unavailable.
The protected input-row audit records the candidate-to-attempt link and each
source/model operation’s authorization observations. It follows the existing
input commit and store durability rules. Optional BoundOperationReview::with_observer
events are live notifications, not durable consent records. Neither those
events nor recovered audit IDs recreate a live allowance, and review approval
is not evidence that the tool executed. See the
review and consent contract
for the boundary and remaining acceptance scope.
Attach and pin the controller before submitting work
Storeless sessions
UseFactoryAgentBuilder and EphemeralSessionService, then
meerkat::surface::materialize_ephemeral_runtime_session to attach the session to
that same machine. Start with InitialTurnPolicy::Defer and
DeferredPromptPolicy::Discard; the first prompt will enter through native
admission.
In-memory persistent sessions
Enable the facade’ssession-store, memory-store and local-authorization
features. The following excerpt assumes owners from above, a configured
FactoryAgentBuilder named builder, a session capacity max_sessions, and
an application-selected PathBuf for the existing reconfigure configuration.
The configuration path is not the session storage location.
PersistentSessionService and the bundle’s same
MeerkatMachine. The service retains the actual session actor; the bundle’s
RuntimeStore holds the committed Session document and store-issued revision.
The native runtime owns accepted inputs, original authority associations and
attached audit, persisted in that same store. These memory stores retain records
for the lifetime of the process; they do not provide restart durability.
SQLite persistent sessions
Local macOS tests passed for actual backend custody, independent-process
exclusion and release, same-file case and symlink aliases, upgrade failures,
and the authenticated native model-tool-model flow with committed Session,
input and protected audit. Same-process completed-turn close/reopen and actor
reconstruction also passed, retaining the current trusted host owners and
proving that stored effects were not replayed. Fresh authenticated work after
reopen also passed with distinct input/run/tool IDs, local denial feedback,
a permitted sibling and protected terminal audit. These results qualify this local
source on the executed filesystem. Published c18’s bounded separate-process
completed-turn case was run directly; its publication and exact-head CI used
their recorded test inventories. Other
platforms, interrupted recovery, persistent administration and performance remain
separate gates.
session-store feature already enables its built-in SQLite stores;
keep local-authorization enabled for governed construction. Use the actual
SQLite session and WholeBlob runtime backends as co-tenants of the same database.
This excerpt assumes an application-selected PathBuf named database_path
and the application’s existing Arc<dyn BlobStore> named blob_store, alongside
owners, builder, max_sessions and reconfigure_config_path from above:
Busy class. Unsupported scope and
operational acquisition failures remain explicit setup refusals. SQLite’s special
:memory: path cannot supply physical file custody and is refused. Use the actual
InMemoryRuntimeStore for a process-local in-memory composition.
Retained native drivers and exported authorization handles retain their same
actual claim. An upgrade from shared to governed custody excludes new admissions
while it releases and reacquires the lifetime lock. Contention restores shared
custody before returning Busy; an uncertain unlock or restoration failure
retains the admission gate and returns Unavailable until the failed claim’s
last owner drops. A failed claim does not become governed authority.
This mechanical owner supplies the construction prerequisite for the existing
ordinary native mixed-turn fixture. It does not establish persistent controller
administration, grant revocation or complete credential removal, which remain
unsupported at their separate native owner seams. The close/reopen
scenario additionally drops the original service and all backend claims before
opening new stores, then reconstructs the actor using the same actual trusted
host owners and the stored Session document. Historical serialized authority
associations remain audit data. They never bootstrap current grant, ingress or
controller authority. The fresh-work test additionally retains the actual host
token vault and verifies its original marked credential through the existing
status owner. Creating an unrelated empty vault requests credential release;
it does not reconstruct the current provider authority. The new input uses
current host grants, ingress authentication and a fresh actor pin, then completes
the native model-tool-model flow with exact audit and no replay of the old work.
The later completed-turn cold-process case uses separate writer and reader
processes with the same SQLite database, a real File token store and stable
host-configured provider binding. The reader restores the marked credential
through the existing lifecycle owner, issues new current grants and pins the
reconstructed actor’s actual client before fresh authenticated work. An attempt
carrying the writer’s old grant association passes current ingress authentication
but is refused by current grant authority before model/tool or durable input
entry. Reader and parent independently verify the original transcript prefix,
input row and protected audit remain unchanged. This qualifies that fixed-bearer,
callback fixture, not interrupted recovery, every credential refresh flow,
persistent administration, performance acceptance or full surface coverage.
The low-level equivalent is
MeerkatMachine::persistent_with_local_grant_authorization(runtime_store, Some(blob_store), owners)?.
Ordinary MeerkatMachine::persistent, persistent_without_blobs, and the
session-store variants of PersistenceBundle::new and its related constructors
also return Result. They request shared custody when the backend supports it;
governed construction requires exclusive custody directly, without dropping and
reacquiring a claim. Ordinary custom backends without custody support remain
usable; governed construction rejects them with UnsupportedScope.
For an existing Rust integration, persistent(store, blob_store) and
persistent_without_blobs(store) now return Result<Self, RuntimeDriverError>.
Handle the result before wrapping the machine in Arc, for example
Arc::new(MeerkatMachine::persistent(store, blob_store)?).
Reuse the bundle’s machine when composing another surface. Built-in mob session
services accept it through acquire_runtime_adapter(Some(machine.clone()))?. A clone of
the same underlying machine owner is valid. A different live owner is refused
with ControllerReadinessFailure::AuthorityChanged, even when it uses the same
store. A store mismatch is UnsupportedScope; custody contention is Busy.
Ok(None) remains an explicit optional-runtime outcome for custom services,
not a substitute for a failed persistent acquisition. Builders and archive paths
propagate acquisition errors before performing their operation.
With the runtime-adapter feature, replace the old MobSessionService::runtime_adapter()
getter with acquire_runtime_adapter(None)?, or pass the intended shared machine
as Some(machine.clone()). The method returns
Result<Option<Arc<MeerkatMachine>>, RuntimeDriverError>. A wrapper must forward
that candidate and result to its underlying service instead of creating another
machine. Both built-in services’ canonical_runtime_adapter() methods now
return Result<Arc<MeerkatMachine>, RuntimeDriverError>.
PersistentSessionService::with_canonical_runtime_adapter remains an infallible
builder binding; acquisition still rejects a retained owner for a foreign store.
Direct acquisition uses RuntimeDriverError::ControllerReadinessUnavailable { reason }; mob composition preserves the reason in
MobError::SessionError(SessionError::RuntimeUnavailable { reason }).
These failures describe runtime readiness, not permission denial.
Exported auth lifecycle and OAuth capabilities retain the acquired backend
custody, including generated/raw lifecycle clones and nested credential or device
poll handles. Dropping only the machine does not make a conflicting governed
owner available while those capabilities survive. This retains backend custody,
not the machine or a runnable controller after restart. Keep using the installed
authority for credential updates; persistent registry replacement is refused,
while requesting the already installed owner is a no-op.
Reserve creation with service.reserve_create_session_admission().await?, then use
meerkat::surface::materialize_session_with_reserved_admission_and_actor_slot
with the same deferred/discard initial-turn options. Its executor factory must
construct meerkat::surface::PersistentRuntimeExecutor::new(service, machine, session_id) and
pass the supplied actor slot to .with_publication_actor_slot(actor_slot).
Clone the same service and machine into that factory and await materialization
before pinning the controller. This executor forwards
store-boundary acknowledgements to the actual persistent service owner.
Do not combine EphemeralSessionService with a persistent machine. In the tested
snapshot, materialize_ephemeral_runtime_session rejects that pairing with a wrapped
SessionError::Unsupported before constructing an actor or registering native
work. Migrating to persistence requires the stock service and executor above;
an ephemeral executor cannot acknowledge the persistent owner’s committed data.
Pin the selected controller
When supplying a registry-selected client override, also setSessionBuildOptions.auth_binding from that client’s actual
ControllerModelSelection::auth_binding(). For a storeless service, obtain the
actor with live_session_actor_witness and its real client with
pin_controller_client_for_actor. For a persistent service, acquire
acquire_live_session_actor_turn_boundary_lease, pin that exact actor with
pin_controller_client_for_actor, then drop the boundary lease before native
submission. A copied model name is not a pinned client.
The selected credential must be usable in this machine’s generated auth owner;
use the normal credential lifecycle, not a fabricated Ready flag.
Remove a permission without removing the controller
For a storeless machine, use the existing native custody accessor before grant revocation. This excerpt assumes the same actualmachine and grants owner,
an authenticated administrative PrincipalRef named administrator, and the
exact issued GrantLineageRef named grant_to_remove. Propagate both typed
custody and grant errors:
GrantRefusal::ControllerInUse means an unfinished controller retains the
grant or one of its ancestors. Separate controller and operation permissions
into appropriately narrowed leaves so removing an operation permission need not
remove the controller. A terminal input can still belong to an unfinished run;
its original contributor continues to protect that controller.
Busy or unsupported custody is public ControllerCustodyRefusal::Unavailable,
without a permission verdict. The published checkpoint supports storeless
administration. Candidate 8fe1abcd5 adds SQLite and InMemory store custody:
the native owner holds the actual store writer and retained original-work
observations through the change. Those new administration paths and their
regressions have not been compiled or executed. Completed-turn reopen alone
does not qualify administrative mutation.
Do not replace the guard with a catalog listing, serialized association or a
caller-owned assertion of no unfinished work. A host sharing grants with another
machine or detached owner must include that additional scope in actual custody.
Explicit credential publication and removal use that administrative custody.
Ordinary credential acquisition, refresh and cached command reads do not scan
historical work. Continue to use the credential owner’s normal API rather than
editing its backing files or reconstructing readiness from stored identity.
The Console Access panel changes Meta’s console ABAC rules; it is not a native
grant editor. Native permission repair belongs to the embedding’s authorized
grant/resource owners. Keep local refusals as affected-call feedback while
permitted work continues; audit availability and launch failures require their
own infrastructure repair. No CLI grant command or universal Console permission
control is supplied by this API.
Append external context under current permissions
These APIs are part of source candidate
8fe1abcd5. The native control path and
its tests have not been compiled or executed. Concrete Mob, LiveResponses and job
producer integration remains in progress; a raw governed notification currently
returns authorization unavailable. This section describes the host contract,
not completed activation of those producers.source annotation, session ID or previous
run is insufficient. The trusted producer supplies a process-only receipt from
its actual owner, alongside ContextControlFacts for the authenticated requester,
executor, realm, source and destination.
Implement AdmittedWorkPolicyOwner::authorize_context_control to validate that
receipt and the current invocation or service mandate. Implement
OperationPolicyOwner::authorize_context_control for the exact source hydration
and destination publication checks. Their defaults return unavailable. Both
participate in the same local publication ordering as other native policy reads.
With the actual receipt and facts already obtained from those owners, submit
through SessionServiceControlExt:
append_authorized_system_context preserves its exact binding.
Reusing the same process control cannot settle another attempt. A fresh attempt
needs a fresh control; the request’s normal idempotency key still detects an
already appended message after current authorization succeeds.
Handle SessionControlError::Authorization by its typed variant. Refused
returns local feedback without appending the content. Unavailable means no
usable authorization was established. ObservationUnavailable is a separate
audit failure and does not prove that an earlier effect never happened. A raw
append_system_context call supplies no authenticated receipt in governed mode.
The Session retains protected control observations with its existing commit.
They do not enter model context or public history, and they cannot authorize a
retry. A persistent service commits the refusal observation before returning it;
a persistence failure remains infrastructure failure. Preserve the actual
result and any settlement error rather than inferring delivery from a log line.
Settle job delivery recipients independently
The recipient APIs and projector integration below are candidate source.
Canonical generated integration is included; executable qualification is pending.
They implement
the local permission and refusal contract,
without establishing authorization for a producer that has not supplied its
actual owner-bound evidence.
JobRuntimeDeliveryApplier derives the complete recipient manifest from the
unchanged committed producer payload, including legacy/default-origin targets.
Each RuntimeDeliveryRecipient binds a subscription ID to its exact subscription
and target. Before any recipient enters, RuntimeDeliveryInbox::bind_recipients
re-reads the committed row and retains the supplied manifest. The producer owns
complete manifest extraction; the generic inbox does not parse opaque payloads
or confer execution authority. Enrollment supports only
JobTerminal and JobNotification; single-target continuations use their own
admission path. Enrollment retains the existing payload and writes authority
envelope v3, which older readers refuse. A runtime authority without recipient
enrollment retains v1, or v2 when it contains whole-row refusals.
Use settle_recipient with the actual local result:
RuntimeDeliveryRecipientOutcome::Appliedrecords successful application.Refusedrecords an actual native permission refusal before entry.OperationAuthorizationUnavailablerecords the native owner’s explicit unavailable-authorization result.
JobDeliveryApplyError::Infrastructure and authorization
ObservationUnavailable leave the recipient pending and the pass blocked.
They are not local permission verdicts, and neither proves that an effect did
not occur. Retry reads retained settlements and skips every settled recipient;
permission repair does not revive a previously refused recipient.
Call finish_recipients only after every bound recipient has settled. The
call advances the ordered cursor and returns RuntimeDeliveryRecipientGroupOutcome.
Read the parent RuntimeDeliveryStatus through delivery_status:
Completed groups remain settled across reopen under the store’s durability
guarantees; retry neither replays successful siblings nor revives refused ones.
RuntimeJobDeliveryDrain::applied contains
rows with established applied results, including already acknowledged effects;
locally_settled contains other completed groups. Paging
counts both lists so a page of local refusals cannot strand later work, while
RuntimeDeliveryPass::applied counts only the applied list. A recipient refusal
does not change the producer job’s completed result.
The sink effect and its settlement commit are separate. A crash or error between
them can leave an uncertain effect with no committed settlement. This API does
not provide effect/commit atomicity or exactly-once execution, and a missing
settlement is not evidence that replay is safe.
Bind the final input to authenticated ingress
Issue the controller and operation grants throughLocalGrantAuthority and
construct the InputAuthorityAssociation for the actual runtime, identities,
mandate, grant references and pinned selection. It remains a claim until the
installed owners validate it.
The following excerpt assumes the host already has those values and pin from
the attached actor. Authenticate requester, ingress_actor, realm and
authentication outside the request body. Set any idempotency key before binding:
AcceptOutcome and optional completion handle. Finalizing this
context does not itself admit work. Do not mutate the bound payload, manufacture
a WorkAuthorizationContext, or reuse one from a prior turn; the native owner
builds it from the admitted contributors.
Serve one fixed governed JSONL connection
Enablemeerkat-rpc with default-features = false and
local-authorization. This profile takes an in-memory PersistenceBundle
constructed with new_with_local_grant_authorization above, a selected
LlmClient, one fixed Config, and a nonempty Vec<ToolDef> of callback tools.
Initialize the selected credential through that bundle’s installed auth lifecycle
before serving. The entry checks that governance is already installed and uses
that same owner; it does not install or upgrade persistent governance.
The retained client does not bypass configuration validation. Its actual
ControllerModelSelection::auth_binding() must name a binding in
config.realm[binding.realm]. Populate that realm’s binding, backend and
auth maps with the corresponding ProviderBindingConfig,
BackendProfileConfig and AuthProfileConfig. The binding must resolve through
resolve_explicit_auth_binding_target to the selected credential identity, and
its provider/backend/auth combination must be supported by
ProviderRuntimeCatalog. Keep the actual endpoint and credential account
consistent with the selected client. The binding realm must equal the connection
realm, and config.agent.model must equal the selected model.
Authenticate the connection in trusted host code. Construct qualified requester,
ingress actor and optional represented-subject identities there, with their realm
and historical authentication evidence. Supply an Arc<InputAssociationProducer>:
it receives the final merged Input, actual runtime ID and pinned
ControllerModelClient, and returns an InputAuthorityAssociation referencing
real issued grants. These are historical claims, not permission or proof of the
semantic provenance of prompt text. The installed native owners still validate
them and current permissions before admission.
This excerpt assumes those host-owned values, the fresh bundle, and one JSONL
reader/writer pair:
mcp_attachment_identity_key_custody: None fits this callback-only recipe. A
host separately commissioned for live MCP attachment supplies Some persistence
from its selected persistent backend’s open_with_refresh_authority(), and
reopens the same backend after a restart. That custody protects attachment
identity only: the governed profile gains no provider or MCP credential from it.
With None, an attachment whose target carries command arguments or URL
credentials is recorded unbound and restores as renewal-required. When
persistence is supplied, failure to create or read its identity key refuses that
attachment admission before anything is recorded or staged, and a restore only
loads the realm’s existing key. Constructing the persistence does not check
filesystem access.
The entry constructs AgentFactory::minimal() internally and owns one private
runtime, config store and callback connection. It installs the host’s catalog once
and supplies the same fixed definitions as inline session tools. Wire requests
cannot replace that registry or choose principals, grants, model or credentials.
Core catalog controls such as tool_catalog_search and tool_catalog_load may
still be advertised. They remain subject to native operation policy and cannot
register tools or expand this fixed callback registry; dynamic tools/register
is unsupported.
After initialization, use session/create with initial_turn: "deferred", then
turn/start. Both accept prompt and optional injected_context; the turn also
identifies its session. The entry merges the deferred seed and contexts before
binding native ingress, retaining the actual actor and controller across an input
permission refusal. The client must handle server tool/execute requests and
return their results on that same connection.
A refused tool operation becomes safe model feedback without entering that
callback; permitted sibling operations can continue. Input refusal, readiness,
infrastructure failure and post-effect settlement remain distinct, as described
below. A later cleanup or settlement failure does not authorize repeating an
effect.
This first slice supports deferred create, turn execution, callback replies and
necessary initialization/cancellation protocol. Dynamic tool registration,
configuration changes, cold/restarted sessions, public history/observation and
MCP setup are outside it. For this uncommissioned recipe the constructor rejects
an MCP-enabled build: it admits one only for a connection commissioned for live
MCP attachment, and setting the identity-key custody does not commission one. It
also rejects configurations enabling skills, hooks, built-in tools, shell, comms,
mobs, scheduling, workgraphs, model fallback or a system-prompt file. Broader
transport, SQLite/recovery, policy-administration and full ADR coverage remain
pending.
The focused fixture requires the non-MCP feature profile:
Acceptance boundary for a Console host adapter
A governed Console submission adapter is still required. A compatible native dependency andlocal-authorization feature are prerequisites; enabling them
or Console access does not commission native owners. Keep the same governed
bundle, session service, machine and attached controller described above.
Implement this handoff with tests in the existing Console send and native ingress
modules, after declaring the missing host adapter with unsupported behavior:
- Thread trusted identity to final admission. Keep
console_send_handler’s authenticatedagent.sendcheck, then carry the host-qualified requester, ingress actor, represented subject and authentication evidence throughdispatch_message_to_resolved_memberto the final member input. The browser cannot supply these facts. Obtain the actual actor’s controller pin and bind the final input usingNativeIngressContext, as inGovernedConnection::bind. Assert the exact runtime, input, identities and pin seen by native owners; mismatched or missing facts must refuse before model or tool entry. - Exercise a real denied operation alongside a permitted sibling. Extend the existing Console send fixture with the commissioned native owners and a loopback model, retaining the fixed JSONL fixture’s real callback, second model-request, transcript and audit assertions. Require zero denied body entries, the permitted result, model-visible refusal and later completion. Transport the actual owner events through SDK and Console projection; decoded synthetic packets alone do not establish this path.
- Preserve acceptance and repair boundaries. Extend the existing send-attempt tests for a native input refusal or readiness failure after Console reservation: settle the reserved interaction without reporting that nothing was accepted. A generic HTTP 403 currently means pre-dispatch rejection to this UI. A lost acknowledgement remains outcome-unknown under the frozen idempotency key. Keep operation refusal separate from input readiness, and outcome-audit failure separate from the actual effect; neither infrastructure failure authorizes replaying an effect. Persistent grant or credential administration remains outside this adapter’s supported scope.
Preserve the result and test the actual effect
An operation-localOperationAuthorizationError::Refused can become safe model
feedback while permitted work continues. Unavailable and
ObservationUnavailable are distinct infrastructure outcomes, not permission
denials. Native input refusal is retained as RuntimeDriverError::InputRefused;
admission readiness is reported separately through
RuntimeDriverError::ControllerReadinessUnavailable. The facade’s
native_admission_error_detail projects these to finite
WireInputAdmissionErrorDetail values: ErrorCode::InputRefused (-32030) or
ErrorCode::InputNotReady (-32031). Preserve that distinction and handle
serialization failure; a readiness result does not prescribe automatic retry.
Session operations that cannot acquire runtime authority instead return
SessionError::RuntimeUnavailable { reason }. Its audience-safe projection uses
ErrorCode::SessionRuntimeUnavailable (-32032, HTTP 503, CLI exit 52), preserving
the typed readiness reason. It is separate from an attempted operation’s local
permission feedback and does not terminate retained work. ErrorCode is publicly
exhaustive, so downstream Rust matches must handle these added variants. This
Rust/JSONL projection does not imply new typed SDK decoders.
Retain settlement_failures alongside the physical result. A diagnostic after a
successful effect does not authorize repeating it. Use native input audit
records for this process-lifetime path. With the persistent composition, the
normal session/input commits retain the original association and ordered audit
alongside the committed transcript. Keep authorization checks local and persist
observations through these existing commit boundaries. This does not prove
crash-safe recovery.
Route controller grant/policy removal and credential maintenance through their
custody-aware owners so unfinished work retains its controller. Persistent
controller/grant administration in candidate 8fe1abcd5 still requires its own
executed acceptance; memory-backed admission does not establish that evidence.
The repository fixture
crates/meerkat-authorization/tests/native_governed_loop/e1_policy_control.rs
shows the complete factory, native admission, loopback HTTP and tool path. Its
E1/E3 cases distinguish refusal before body entry from diagnostics after an
effect. The A2/A3/A8 children cover resource-specific permissions, queued work and
requester revocation. These are deterministic fixtures, not live model or full
ADR acceptance. The e1_policy_control/stock_persistent.rs child exercises the
stock bundle/service/executor with a committed Session document, native input
and audit readback. QJ r3 passed all 11 native cases, including six opt-in cases,
on the tested tree above; candidate and adjacent-owner checks totalled 132
distinct passing tests from 145 executions. This bounded gate includes the
actual stock persistent turn and early rejection of the unsupported mixed
composition. It does not establish release, SQLite, restart, stock transport
activation, full ADR coverage or performance. For an application, require zero
forbidden body entries, one permitted effect, the same admitted run’s feedback
and normal completion.
Read the broader integration contract and
authorization concepts before extending the protected
operation inventory.