Start with capability discovery
Do not begin by copying the nearest integration. First record what the new host can actually expose:- a stable prompt event and its ordering;
- turn, message, session, workspace, and project identity;
- a transient pre-dispatch injection channel;
- tool and command registration;
- permission requests, confirmation UI, and headless behavior;
- package, plugin, and bundled Skill installation;
- end, compaction, switch, shutdown, and interruption events;
- a CLI/version probe and an activation probe.
GET /v1/capabilities as well. It reports Server features such as memory_extraction, experience_generation, managed_skill_generation, external_skill_registry, Handoff generation, search modes, and context versions. Host capability discovery and Server capability discovery answer different questions; you need both.
If the host has no stable prompt event, no pre-dispatch injection point, or no permission surface, say so. That capability is Unsupported unless you implement another contract with equivalent guarantees. If the host appears to expose it but no real-host test proves the path, mark it Not validated.
Write the adapter contract
Use this vocabulary to force the important decisions into the open:
Automatic recall, capture, and optional flush may fail-open. Explicit durable writes, Review, Handoff commit, and Skill export must report failure. Do not use one policy for both groups.
Minimal usage
Start with one prompt path, one boundary path, and one explicit mutation. Keep every unsupported capability out of the first slice.Execution flow
Keep host glue thin. It should resolve identity, call verified helpers, and translate the result into the host’s native event shape.Reuse current implementation
Reuse code only where its contract already matches the host:- the generated HTTP client and transport models under
powercontext.http; - canonical
PreparedContextand capability models; - Python capture rendering and redaction helpers;
- shared loopback transport vectors;
- Codex and Claude Code prepared-context validation patterns;
- host-specific Scope normalization tests;
- Pi’s pending-position flusher pattern;
- DSH and other generated operation tables;
- Codex and Claude Code managed Skill projections;
- the first-class setup/doctor catalog and common
Diagnosticvalue model.
Scope, injection, capture, and flush
A new host must define these four boundaries together. For Scope, derive identity from stable, authorized project data. Strip credentials from Git remotes. Do not trust a model-suppliedscope_id, and do not reuse session identity as repository identity unless the host contract proves they are the same.
For injection, use a native transient channel before model dispatch. Mark PreparedContext as untrusted historical evidence. A system guide that merely tells the model to search Memory is not proof that recall was injected.
For capture, state exactly which side of the turn is recorded. Filter secret-shaped content before transport and enforce limits in UTF-8 bytes. Keep recall and capture independent so one failure does not erase the other’s valid result.
For flush, retain the Source position by Scope and clear it only when current_cursor >= position. Every retry loop needs a call limit and a wall-clock budget. When the host lacks a reliable boundary event, automatic flush is Unsupported; when the event exists but has not been exercised in the real host, it is Not validated.
Permission and explicit writes
List every mutating operation. Decide whether the host can ask, deny, cancel, or pause in both interactive and headless modes. Then test the exact behavior. A host with no permission API cannot inherit Pi’sconfirmation_required contract or OpenCode’s context.ask() behavior. Either fail closed in adapter-controlled code, expose the operation as read-only, or mark durable mutation Unsupported. “The model should ask first” is not a permission boundary.
Diagnostics must omit prompt content, prepared context, Scope details that can identify a private repository, authorization values, and secret-bearing payloads.
Setup and doctor
Add the host to setup only after installation and activation have separate checks. Setup should be idempotent, preserve foreign same-name files, record ownership for files it manages, use staging for remote refresh, and restore the previous state on failure. A multi-host setup must isolate failures and report each selected row as installed, failed, or skipped. Doctor has three jobs:- find the host executable and report its version evidence;
- verify the installed package or configuration belongs to PowerContext;
- probe activation through the host when the host offers a safe, model-free probe.
powercontext doctor as an integration scan. The general command checks the package and Server; host checks belong in powercontext doctor <host> and the read-only powercontext doctor integrations matrix.
Acceptance tiers
Use these tiers to describe evidence. They are a page-level classification, not names from the current test framework.- Contract/unit: schema, Scope, size, secret, permission, and failure-policy tests.
- Package/load: build, install, import, manifest, command, or plugin registration.
- Service chain: a real PowerContext Server with direct hook/module execution and Source/Memory lineage.
- Real-host E2E: launch the actual host, send a prompt, and observe lifecycle, injection, capture, flush, and permission behavior.
- Live provider journey: run the actual host with its provider/model and retain acceptance evidence.
Negative matrix
At minimum, test these cases:
Add host-specific privacy cases such as private versus group sessions when the host has those concepts.
Managed Skill export
Managed Skill export currently supports only Codex and Claude Code. A bundledproject-context Skill installed with another plugin does not change that matrix.
To add a new export target, implement a projection contract, target enum and OpenAPI surface, ownership rules, validation, rollback, and drift tests. Until that work exists, managed export for the host is Unsupported. If implementation exists but no real install/refresh test has run, use Not validated instead.
Unsupported vs Not validated
Do not merge these labels into “limited support.” One is a product boundary; the other is an evidence gap.
Completion checklist
Treat the integration as complete only when these results are observable:- Host and Server capability discovery are recorded separately.
- Every proposed contract role has inputs, outputs, failure policy, and observable assertions.
- Host version gate or compatibility evidence and an activation probe exist.
- Scope comes from stable authorized identity and strips credentials.
- PreparedContext is validated, transient, and labeled untrusted.
- Capture defines content, Source identity, UTF-8 size limit, and secret policy.
- Flush retains position by Scope and clears only at
current_cursor >= position. - Explicit writes have tested allow, deny, cancel, and no-UI behavior.
- Diagnostics expose no content or credentials.
- Setup preserves foreign config and reports rollback or partial failure.
- Managed Skill export is Unsupported unless a complete projection target exists.
- Real-host E2E covers every Supported lifecycle and permission claim.
- Unsupported and Not validated remain separate in docs, tests, and release notes.

