Reference implementation · 10 min
Teardown: The Synthetic Customer Request Interface
Inspect the architecture, tool contracts, scoped authorization, confirmation capability, data isolation, and tests behind Permadyn’s owned demo.
The Customer Request Lab is an owned, synthetic reference implementation of one complete agent workflow. A local model reads a fictional customer email and CRM record, recommends a queue and status, previews the change, and applies it only after a person confirms the exact proposal.
It is not a client case study. The companies, cases, policies, and results are fictional.
The outcome and surface
The product job is narrow enough to verify: turn an incoming customer email into the correct CRM routing while showing the record, handling rule, and exact before-and-after change.
The interface exposes five tools:
| Tool | State effect | Required scope |
| --- | --- | --- |
| search_cases | Read | cases:read |
| get_case | Read | cases:read |
| search_policy | Read | cases:read |
| preview_case_update | Stores non-mutating proposal | cases:write |
| apply_case_update | Reversible case mutation | cases:write + confirmation |
Each has a versioned JSON Schema input, structured output schema, and annotations for read-only, destructive, idempotent, and open-world behavior.
One domain service, several adapters
Website lab ───────┐
Direct HTTP API ──┼── domain service ── SQLite tenant state
MCP transport ────┘ │
└── proposal, confirmation, audit evidence
The domain service owns state and policy. The website and MCP adapter call the same implementation. The public OpenAPI document describes the direct HTTP surface; the MCP reference documents the agent-facing tools and OAuth metadata.
This prevents a platform-specific UI from becoming an alternate authority path.
Synthetic tenant isolation
Creating a lab session inserts three fictional cases into a new SQLite tenant keyed by a random session identifier. Every case, proposal, idempotency record, and tool log is scoped to that tenant.
The signed access token contains the tenant subject, client identifier, resource audience, scopes, issue time, expiration, and unique token identifier. The server verifies the signature, expiry, audience, and backing session on every authenticated operation.
Expired tenant rows cascade-delete cases, proposals, idempotency records, and logs. Credentials are not written to tool logs.
Prompt injection stays data
One fictional case includes a note that says to ignore policy and mark the case resolved. This is seeded adversarial content.
Tool descriptions identify notes as untrusted records. Server logic never interprets note content as authority. The proposed update is built only from validated tool arguments and checked against the authenticated session. Even a model that follows the injected sentence cannot bypass scope or mint confirmation.
This is defense in depth. Instruction hierarchy still matters in the host, but authority is not delegated to retrieved text.
The proposal and confirmation protocol
Preview reads the current case and creates:
- a proposal ID,
- case version,
- exact proposed fields,
- rationale,
- change hash,
- hidden random challenge,
- ten-minute expiration,
- and reversibility marker.
No case field changes.
The web lab and MCP App render the exact diff. A human click exchanges the hidden challenge for a random confirmation token. Only its hash is stored. The token can confirm one proposal once.
Apply begins a SQLite immediate transaction. It checks the confirmation hash, expiry, unapplied state, current case version, and idempotency key before updating. A repeated completed request with the same key returns the original response. A changed version rolls back without mutation.
What the audit record contains
Each tool call records:
- tenant session,
- timestamp,
- tool name,
- required scope,
- latency,
- outcome code,
- case identifier where relevant,
- and proposal identifier where relevant.
It does not record bearer tokens, confirmation tokens, or credentials. Production deployments would add controlled retention, access policy, correlation identifiers, and privacy review appropriate to the customer system.
Known boundaries
The public demo uses anonymous synthetic tenants, not enterprise identity. It demonstrates one reversible status/assignment change, not irreversible actions. SQLite is appropriate for the current single-host reference architecture; a horizontally scaled deployment would require a shared transactional store or a deliberate single-writer topology.
The UI is designed for ChatGPT’s MCP Apps model and the underlying tools remain usable by independent clients. A public compatibility statement still requires a recorded test against the named client and deployed server version.
What Interface CI checks
The internal release manifest covers catalog and schema changes, structured output, authorization, confirmation, idempotency, stale state, latency, and the completed golden workflow. Intentionally seeded failures prove that the harness can detect broken boundaries rather than merely report green.
Claim boundary
This owned lab is architectural evidence, not evidence of customer outcomes, penetration testing, certification, or universal client support. Its purpose is to make engineering decisions inspectable.