Status
FRESH-AGENT AUTHORING PROOF COMPLETE — PR #519 merged; next gate is local source-built Runtime registration against the real CUPS Adapter, then release and Room acceptance.
Related:
Decision to freeze
Free4Chat Runtime should not become a hardware integration host.
Canonical boundary:
Room
↓
Free4Chat Core / Runtime
↓
Local Capability Adapter Protocol
↓
Adapter
↓
vendor API / Home Assistant / IPP / BLE / serial / USB / LAN / SDK / whatever
The key rule is:
Runtime knows capabilities, not integrations.
More explicitly:
Runtime owns capability transport, authority, bounds and lifecycle. Adapter owns integration, vendor protocol, local configuration and credentials.
A Xiaomi token, Home Assistant token, printer password, BLE pairing key, MQTT credential, serial configuration or vendor account must not become a Free4Chat Runtime credential/configuration type merely because an Adapter needs it.
Why this is needed
#512 proves a bounded semantic capability can be projected from a participant-local Runtime into a Room:
Human deterministic invocation
┐
├→ daemon-owned semantic controller → local fixture
Agent ┘
The current fixture-specific HTTP adapter was intentionally useful for the proof. It must not become the long-term extension model.
Without a strict external Adapter boundary, normal product evolution would pull integrations into Runtime:
Runtime
├─ Xiaomi / MiOT
├─ Home Assistant
├─ Epson / IPP / CUPS
├─ BLE
├─ MQTT
├─ serial / USB
├─ vendor SDKs
└─ vendor-specific credential/config lifecycle
That is explicitly rejected.
Product model
Runtime responsibilities
Runtime may own only the generic machinery necessary to safely project local semantic capabilities into a Room:
- Adapter registration / deregistration;
- bounded descriptor validation;
list / describe / observe / invoke dispatch;
- Room authorization;
- request correlation / timeout / cancellation;
- process/local-IPC lifecycle if Runtime supervises an Adapter;
- health / unavailable state;
- Room / Runtime teardown cleanup;
- protection against endpoint/config/credential leakage into Room/Harness surfaces.
Runtime does not understand the underlying device/service.
Adapter responsibilities
An Adapter owns everything integration-specific:
- device/service discovery;
- vendor protocol;
- vendor OAuth/login;
- vendor tokens / passwords / API keys;
- local endpoint / LAN address;
- BLE / serial / USB / IPP / MQTT / HTTP / SDK use;
- vendor-specific retries and connection behavior;
- conversion from messy local integration state into the bounded semantic capability contract.
Credentials stay in Adapter-owned/local-system storage, for example:
- macOS Keychain;
- Home Assistant's own credential/config store;
- Adapter-local config;
- environment variables;
- an already-authenticated vendor CLI/session;
- another local secret mechanism selected by that integration.
Free4Chat does not define a universal vendor credential schema or credential vault.
Agent role
Agents are first-class Adapter authors/operators.
A setup Agent may, subject to existing local Harness/operator approval policy:
inspect local environment
→ research an existing integration/protocol
→ search for an official/community Free4Chat-compatible Adapter
→ install/use that Adapter
OR
→ generate a small Adapter locally
→ configure vendor login locally
→ test describe/observe/invoke
→ ask Human to approve registration/publication
The Runtime must not require Free4Chat to know the vendor or device model.
An Agent-generated Adapter is allowed to solve an integration Free4Chat has never heard of.
Room messages themselves never grant the Agent new local filesystem/network/USB/secret authority.
Adapter sources are intentionally open
Free4Chat should define the protocol, not a closed integration catalogue.
A compatible Adapter may be:
- generated on demand by an Agent;
- maintained by the user;
- published by the Free4Chat project as a reference/curated Adapter;
- published by a device vendor;
- found in an open-source repository;
- provided by the community;
- a thin wrapper over an existing local system such as Home Assistant or CUPS.
No central Adapter marketplace/registry is required for this issue.
The Agent may discover compatible Adapters using ordinary local/web research and then validate them against the protocol.
Protocol surface
Keep the first external contract extremely small.
Conceptually:
list? // optional if one process exposes several capabilities
describe
observe
invoke
health
The semantic Room-facing model remains bounded:
capabilityId
title
version
observe availability
closed typed actions
bounded result
Do not put integration concepts into the protocol:
- URL / HTTP path;
- MQTT topic;
- serial port;
- BLE characteristic;
- vendor token;
- Home Assistant entity internals;
- printer model;
- device driver type.
Transport
Prefer the simplest local process/IPC transport that allows an Agent to implement an Adapter in any common language.
Candidate V1:
Runtime
↕ stdio JSON messages / JSON-RPC-like request-response
Adapter process
This is a candidate, not a reason to invent a large SDK.
Evaluate stdio against a Unix-socket/local-IPC alternative and choose the smallest contract with:
- request correlation;
- bounded frames;
- timeout/cancellation;
- no network listener required;
- easy Python/Node/Go implementation;
- explicit process lifecycle;
- deterministic tests.
Avoid making generic loopback HTTP proxying the canonical Runtime abstraction.
Trust / approval split
Two separate approvals must remain distinguishable:
1. Local Adapter execution
Human/operator approves running/installing Adapter code
This is local-code authority governed by normal Harness/OS/operator policy.
2. Room capability publication/control
Human explicitly enables the Adapter's bounded capability for this Room
Running an Adapter does not automatically publish it to Rooms.
Publishing a capability does not authorize arbitrary Adapter code or local network access.
For Agent-generated temporary Adapters, prefer Room/session-bounded lifecycle where practical:
Agent generates Adapter
→ Human approves local execution
→ Runtime validates descriptor
→ Human approves Room projection
→ Room / registration ends
→ ephemeral Adapter can be stopped/removed
Do not require ephemeral lifecycle for every user-installed Adapter; long-lived local Adapter processes are also valid.
Secret boundary
Normal Runtime / Room / Harness-visible surfaces must never contain Adapter integration secrets.
Explicitly keep outside Free4Chat capability projection:
- vendor credentials;
- OAuth refresh/access tokens;
- local endpoint URLs/IP addresses unless independently required for local debugging;
- device pairing keys;
- Adapter internal config;
- arbitrary environment values;
- vendor request/response auth material.
Runtime may know how to launch/connect to an Adapter process, but should not parse, own or persist the Adapter's vendor credentials.
Avoid putting secret values in argv.
Official support policy
Free4Chat Core should provide:
- the Adapter Protocol specification;
- a tiny validator/test harness for Adapter authors/Agents;
- Runtime registration/lifecycle support;
- at most a small number of reference Adapters/examples when useful.
Reference Adapters must remain outside the Runtime core dependency graph.
A future Home Assistant or CUPS example may be valuable because it demonstrates broad reuse, but it is not part of defining this protocol.
Phase 0 / V1 proof
Phase 0 result: PR #516 merged at 520e3f379f0373b1ca3890b16f1e824f7e1a6259. The retained baseline is supervised stdio NDJSON, protocolVersion 1, list / describe / observe / invoke, an external Python reference Adapter, and a conformance validator. Production Runtime migration remains the next step.
Do not start with Xiaomi-specific code.
First prove the boundary by extracting/replacing the current fixture-specific Runtime integration with one external Adapter process implementing the protocol.
Suggested proof:
existing localhost fixture
↑
Agent/user-written external Adapter
↑
generic Adapter Protocol
↑
Runtime
↑
Room #512 capability RPC
Acceptance should prove that the Runtime does not change when the Adapter implementation is replaced.
Then Lab #215 can use the same protocol for one real device/service.
Acceptance
Protocol
Runtime boundary
Agent authoring
Reuse proof
After V1, Lab #215 should be able to choose any convenient real target — for example Home Assistant→Xiaomi light or IPP/CUPS→printer — by changing only the Adapter side.
Non-goals
- Xiaomi / MiOT integration in Runtime;
- Home Assistant client in Runtime;
- Epson / CUPS / IPP integration in Runtime;
- BLE/MQTT/serial/USB stacks in Runtime;
- vendor credential manager;
- universal secret vault;
- device driver catalogue;
- global Adapter registry;
- marketplace;
- package manager;
- automatic installation of untrusted Adapter code;
- arbitrary local network proxy;
- Generated Task App unrestricted LAN access;
- permanent device cloud;
- broad plugin SDK beyond the minimum protocol.
Design test
For every proposed Runtime addition ask:
Is this required to securely project a bounded local semantic capability into a Room, or is this integration logic that belongs in the Adapter?
If the latter, keep it outside Runtime.
Status
FRESH-AGENT AUTHORING PROOF COMPLETE — PR #519 merged; next gate is local source-built Runtime registration against the real CUPS Adapter, then release and Room acceptance.
Related:
Decision to freeze
Free4Chat Runtime should not become a hardware integration host.
Canonical boundary:
The key rule is:
More explicitly:
A Xiaomi token, Home Assistant token, printer password, BLE pairing key, MQTT credential, serial configuration or vendor account must not become a Free4Chat Runtime credential/configuration type merely because an Adapter needs it.
Why this is needed
#512 proves a bounded semantic capability can be projected from a participant-local Runtime into a Room:
The current fixture-specific HTTP adapter was intentionally useful for the proof. It must not become the long-term extension model.
Without a strict external Adapter boundary, normal product evolution would pull integrations into Runtime:
That is explicitly rejected.
Product model
Runtime responsibilities
Runtime may own only the generic machinery necessary to safely project local semantic capabilities into a Room:
list / describe / observe / invokedispatch;Runtime does not understand the underlying device/service.
Adapter responsibilities
An Adapter owns everything integration-specific:
Credentials stay in Adapter-owned/local-system storage, for example:
Free4Chat does not define a universal vendor credential schema or credential vault.
Agent role
Agents are first-class Adapter authors/operators.
A setup Agent may, subject to existing local Harness/operator approval policy:
The Runtime must not require Free4Chat to know the vendor or device model.
An Agent-generated Adapter is allowed to solve an integration Free4Chat has never heard of.
Room messages themselves never grant the Agent new local filesystem/network/USB/secret authority.
Adapter sources are intentionally open
Free4Chat should define the protocol, not a closed integration catalogue.
A compatible Adapter may be:
No central Adapter marketplace/registry is required for this issue.
The Agent may discover compatible Adapters using ordinary local/web research and then validate them against the protocol.
Protocol surface
Keep the first external contract extremely small.
Conceptually:
The semantic Room-facing model remains bounded:
Do not put integration concepts into the protocol:
Transport
Prefer the simplest local process/IPC transport that allows an Agent to implement an Adapter in any common language.
Candidate V1:
This is a candidate, not a reason to invent a large SDK.
Evaluate stdio against a Unix-socket/local-IPC alternative and choose the smallest contract with:
Avoid making generic loopback HTTP proxying the canonical Runtime abstraction.
Trust / approval split
Two separate approvals must remain distinguishable:
1. Local Adapter execution
This is local-code authority governed by normal Harness/OS/operator policy.
2. Room capability publication/control
Running an Adapter does not automatically publish it to Rooms.
Publishing a capability does not authorize arbitrary Adapter code or local network access.
For Agent-generated temporary Adapters, prefer Room/session-bounded lifecycle where practical:
Do not require ephemeral lifecycle for every user-installed Adapter; long-lived local Adapter processes are also valid.
Secret boundary
Normal Runtime / Room / Harness-visible surfaces must never contain Adapter integration secrets.
Explicitly keep outside Free4Chat capability projection:
Runtime may know how to launch/connect to an Adapter process, but should not parse, own or persist the Adapter's vendor credentials.
Avoid putting secret values in argv.
Official support policy
Free4Chat Core should provide:
Reference Adapters must remain outside the Runtime core dependency graph.
A future Home Assistant or CUPS example may be valuable because it demonstrates broad reuse, but it is not part of defining this protocol.
Phase 0 / V1 proof
Phase 0 result: PR #516 merged at
520e3f379f0373b1ca3890b16f1e824f7e1a6259. The retained baseline is supervised stdio NDJSON, protocolVersion 1,list / describe / observe / invoke, an external Python reference Adapter, and a conformance validator. Production Runtime migration remains the next step.Do not start with Xiaomi-specific code.
First prove the boundary by extracting/replacing the current fixture-specific Runtime integration with one external Adapter process implementing the protocol.
Suggested proof:
Acceptance should prove that the Runtime does not change when the Adapter implementation is replaced.
Then Lab #215 can use the same protocol for one real device/service.
Acceptance
Protocol
unavailable;Runtime boundary
Agent authoring
Reuse proof
After V1, Lab #215 should be able to choose any convenient real target — for example Home Assistant→Xiaomi light or IPP/CUPS→printer — by changing only the Adapter side.
Non-goals
Design test
For every proposed Runtime addition ask:
If the latter, keep it outside Runtime.