97 lines
8.3 KiB
Markdown
97 lines
8.3 KiB
Markdown
# Mos Runtime Portability M1 — Logical Identity and Fencing
|
|
|
|
> **Decision status:** Current implemented decision (M1).
|
|
> **Operational status:** The lease/fencing boundary is implemented and test-covered; connector activation remains held.
|
|
> **Audience:** Mosaic developers, gateway/runtime adapter authors, and security reviewers.
|
|
> **Authority:** This page records the current M1 boundary. The executable source and tests are authoritative for behavior; [`PRD.md`](../../../PRD.md) remains authoritative for requirements.
|
|
|
|
## Decision
|
|
|
|
M1 separates the logical Mosaic agent from any Claude, Pi, Codex, tmux, Matrix, or provider-native session. The core identity is:
|
|
|
|
```text
|
|
(tenant_id, logical_agent_id, binding_id)
|
|
```
|
|
|
|
`logical_agent_id` is a Mosaic logical identifier, not a runtime session identifier. The gateway derives the tenant from authenticated actor scope. The current internal service boundary normalizes the supplied logical-agent identifier and binding; a future public boundary must resolve and authorize those values server-side. Runtime-native session IDs are not part of the lease or execution-grant contract.
|
|
|
|
A connector is a replaceable holder of authority for one logical binding. It is not the logical agent identity.
|
|
|
|
## Durable lease model
|
|
|
|
The additive migration creates `logical_agent_connector_leases` with one unique row per tenant/logical-agent/binding tuple. The current row contains:
|
|
|
|
- an opaque lease UUID;
|
|
- connector ID and normalized allowed scopes;
|
|
- a positive decimal fencing epoch exposed by the application and stored as PostgreSQL `bigint`;
|
|
- acquisition, heartbeat, expiry, release, and update timestamps.
|
|
|
|
Initial acquisition is insert-only. An existing active row yields `lease_held`. An expired or released row yields `takeover_required`; ordinary acquisition does not recover it. An authorized takeover compares and swaps the expected epoch, rotates the lease UUID, and increments the epoch atomically. Heartbeat and release match the full identity, binding, connector, lease UUID, and epoch.
|
|
|
|
### Audit and enforcement precision
|
|
|
|
`connector_lease_audit_log` is an **application-level append-only contract**: the repository has an insert-only audit path and writes credential-safe lifecycle/rejection metadata. The checked-in schema and migration add a table and indexes, but do not add database triggers, permissions, or other database-level protection against `UPDATE` or `DELETE`. M1 therefore does not claim database-enforced immutability; an append-only guarantee at the database security boundary is a later hardening requirement.
|
|
|
|
Likewise, identifier, scope, and epoch normalization is performed at the application boundary by the shared types/coordinator and gateway service. The database enforces column types, non-null fields, the lease primary key, and the unique tenant/logical-agent/binding index, but it does not independently enforce all application formats or semantics such as positive epochs, canonical scope ordering/deduplication, or constrained identifier patterns. Database shape must not be mistaken for a second normalization layer.
|
|
|
|
## Execution grants and TTL boundaries
|
|
|
|
`ConnectorLeaseCoordinator` issues a short-lived internal grant only after rereading the durable current lease. It enforces hard defense-in-depth maxima of five minutes for leases and thirty seconds for grants; constructor options may only tighten those limits. A grant is bound to tenant, logical agent, binding, connector, lease UUID, scope subset, expiry, correlation ID, and epoch.
|
|
|
|
The gateway policy and coordinator have deliberately separate TTL responsibilities:
|
|
|
|
- `ConnectorLeaseService` passes the request's numeric `ttlMs` to policy as `requestedTtlMs` for acquire, takeover, heartbeat, and grant issuance. Identity and scopes are normalized before policy evaluation, but this TTL is a request input, not a coordinator-normalized or effective TTL.
|
|
- Release and read policy checks use `null` because they do not request a TTL.
|
|
- After policy authorization, the coordinator validates the TTL as a positive safe integer and rejects values above the applicable hard cap (`300000ms` for leases or `30000ms` for grants). It does not silently clamp an over-cap value.
|
|
- A policy may impose a stricter duration limit, but it cannot expand the coordinator cap. A policy implementation must validate the requested value itself if its decision depends on a bounded or canonical TTL.
|
|
|
|
Grant validation occurs immediately before adapter invocation and rereads the durable current row. Validation denies:
|
|
|
|
- grants not minted by the current gateway process, including cloned or forged objects;
|
|
- expired grants or leases;
|
|
- released leases;
|
|
- stale epochs or replaced connectors/lease UUIDs;
|
|
- missing, cross-tenant, cross-agent, or cross-binding leases; and
|
|
- scopes not authorized by both the grant and the current lease.
|
|
|
|
A gateway restart intentionally invalidates process-local grant provenance. The durable lease and epoch survive, but a fresh grant is required after current-lease and policy validation.
|
|
|
|
## Adapter boundary and activation state
|
|
|
|
The normalized `ConnectorExecutionContext` and `FencedConnectorAdapter` contract define the future adapter boundary. When a concrete adapter is activated, it must receive the context only after the coordinator's final validation and must propagate the epoch/context to downstream effect boundaries that need to fence races after gateway validation.
|
|
|
|
That contract is **not evidence of an activated adapter**. The current production module registers the lease repository, service, and deny-all policy. The coordinator and gateway integration tests use test adapters, but current production runtime providers and channel paths do not consume `ConnectorExecutionContext` or call `executeGrant`. No concrete Claude, Pi, Codex, Matrix, tmux, provider, or channel connector is activated by M1.
|
|
|
|
`ConnectorLeaseService` is the gateway-owned policy surface. It derives tenant scope from authenticated context, records policy denials, and is internal: no M1 connector-lease HTTP controller or administration endpoint is registered. The default `DenyConnectorLeasePolicy` rejects every lease and grant operation until a separately authorized server-side policy is supplied.
|
|
|
|
## Current implementation evidence
|
|
|
|
The current boundary is represented by the following checked-in surfaces:
|
|
|
|
- Contract and application normalizers: `packages/types/src/agent/connector-lease.dto.ts` and its unit specification.
|
|
- Coordinator, TTL caps, grant provenance, reread, and fencing checks: `packages/agent/src/connector-lease.ts` and its unit tests.
|
|
- Gateway policy, tenant derivation, and default deny wiring: `apps/gateway/src/agent/connector-lease.service.ts` and `agent.module.ts`.
|
|
- Durable repository and compare-and-swap mutations: `apps/gateway/src/agent/connector-lease.repository.ts`.
|
|
- Schema and additive migration artifacts: `packages/db/src/schema.ts` and `packages/db/drizzle/0016_salty_morlocks.sql`.
|
|
- Gateway integration and repository specifications: `apps/gateway/src/agent/connector-lease.integration.test.ts` and `connector-lease.repository.test.ts`.
|
|
|
|
These references establish the implemented boundary; they do not imply that a production database, connector policy, or concrete connector is currently active.
|
|
|
|
## Explicit non-goals
|
|
|
|
M1 does **not** provide or authorize:
|
|
|
|
1. Production connector activation, channel cutover, or cross-harness failover/rollback E2E.
|
|
2. Concrete Claude, Pi, Codex, Matrix, tmux, provider, or channel adapters, or integration of existing runtime providers with this lease context.
|
|
3. A connector-lease HTTP API or caller-controlled tenant authority.
|
|
4. Exactly-once connector receipts, a side-effect journal, checkpoint/handoff payloads, replay deduplication, or recovery semantics for an external effect that may already have happened.
|
|
5. Database-enforced append-only audit rows or database-enforced copies of application identifier/scope/epoch normalization.
|
|
6. A claim that gateway validation alone fences an effect after an adapter has crossed the boundary; downstream adapters and effect journals remain later work.
|
|
|
|
A valid lease or grant is therefore not a claim of exactly-once delivery, production connector readiness, or completed runtime cutover.
|
|
|
|
## Related contract
|
|
|
|
- [M1 connector lease operations — held/non-operative](../../../ADMIN-GUIDE/operations/mos-connector-lease-operations.md)
|
|
- [MOS-PORT requirements](../../../PRD.md#mos-runtime-portability-workstream-mos-port)
|