Disclose that an agent is an AI
Declare requires_ai_disclosure in an agent’s PromptPack so the facade tells each client it is talking to an AI, and so the session record shows that it did.
Prerequisites
Section titled “Prerequisites”- A PromptPack you can republish as a new version (published PromptPacks are immutable).
- An agent that serves clients over the WebSocket facade.
- session-api with a Postgres warm store, to keep the delivery record.
- Enterprise with privacy-api, to count missed disclosures.
Declare the obligation
Section titled “Declare the obligation”-
Set
metadata.governance.requires_ai_disclosurein the pack (promptpack-spec RFC 0013):{"id": "customer-support","metadata": {"governance": {"requires_ai_disclosure": true,"intended_purpose": "Answer billing questions for retail customers","accountable_owner": "support-platform@example.com"}}}Value Meaning trueA human counterparty must be told this is an AI. falseThe author considered disclosure and declared none is due, for example a backend agent with no human on the other end. omitted The author declared nothing. -
Publish the pack as a new PromptPack version and point the agent at it. The facade reads the declaration once, at startup.
See PromptPack for the other governance fields.
Check what clients receive
Section titled “Check what clients receive”On connect, the WebSocket facade puts the declaration on the connected frame, before the user has said anything. The same frame carries it when a client resumes a parked session (resumed is then true). A pack that declares nothing sends no ai_disclosure field.
The following frame is illustrative:
{ "type": "connected", "session_id": "3f1c…", "connected": { "capabilities": {}, "ai_disclosure": true }}The dashboard console shows a “You are talking to an AI” alert above the transcript when the value is true.
A client you build yourself must render the notice. It can then send {"type": "disclosure_ack"}; the facade records that as the client-asserted event ai.disclosure.displayed. See the WebSocket protocol reference.
Verify
Section titled “Verify”-
Open a new session with the agent.
-
Forward the group’s session-api Service, mint a token and read the session. The Service is
session-<workspace>-<group>in the workspace namespace. The token needs the audienceomnia-session-api.Terminal window kubectl port-forward -n <workspace-namespace> svc/session-<workspace>-<group> 8080:8080export SA_TOKEN=$(kubectl create token default -n <workspace-namespace> --audience omnia-session-api)curl -sS "http://localhost:8080/api/v1/sessions/<session-id>" \-H "Authorization: Bearer $SA_TOKEN"The response nests the record under
session. The following output is illustrative:{"session": {"aiDisclosure": {"declared": true,"delivered": true,"deliveredAt": "2026-09-03T12:00:00Z","facadeType": "websocket"}}}deliveredAtis absent whendeliveredisfalse, anddeclaredis absent when the pack declared nothing. -
Open the session in the dashboard. The session detail page shows one of these verdicts:
Verdict Meaning Disclosure sent Declared trueand sent.Required, none sent Declared trueand not sent.No disclosure required Declared false.Pack declared nothing Omitted. Not recorded The writer reported no posture.
Custom facades
Section titled “Custom facades”If you wrote your own facade with the pkg/facade SDK, it must honour the declaration.
import sdkfacade "github.com/altairalabs/omnia/pkg/facade"
// Once, at startup.declared := sdkfacade.LoadDisclosure(packPath, log)
// Per session, after the disclosure is written to your transport.d := sdkfacade.Disclosure{ Declared: declared, Delivered: sent, DeliveredAt: sentAt, FacadeType: "my-facade",}d.LogViolation(log, sessionID) // no-op unless declared and not delivered- Set
Deliveredonly after the write succeeds. A frame that failed to send disclosed nothing. - Include the same four fields as
aiDisclosurein the body ofPOST /api/v1/sessionswhen you create the session. session-api stores them at creation. - Call
d.RecordSentto add theai.disclosure.sentevent to the session trace.
Find agents that missed the disclosure
Section titled “Find agents that missed the disclosure”A pack with requires_ai_disclosure: true whose session shows no delivery is a detectable violation. Two places report it.
session-api writes an ai_disclosure_missing event to its audit_log when it creates the session. The event drains to the privacy-api audit hub, keyed by Workspace UID. A delivered disclosure emits no event.
-
Forward the workspace’s privacy-api Service,
privacy-<workspace>, using the token from the Verify step:Terminal window kubectl port-forward -n <workspace-namespace> svc/privacy-<workspace> 8087:8080 -
Read the running count, passing the Workspace UID as
workspace:Terminal window curl -sS "http://localhost:8087/api/v1/privacy/enforcement-stats?workspace=<workspace-uid>" \-H "Authorization: Bearer $SA_TOKEN"The count is
aiDisclosureMissing, next topiiBlocked,redactionsandpolicyDenied.
The facade also logs at default verbosity, so a deployment without session-api still gets a line. The following line is illustrative:
ai disclosure not delivered reason="pack requires disclosure, facade delivered none" declared=true facadeType=custom sessionID=3f1c…Troubleshooting
Section titled “Troubleshooting”The console shows no alert
Section titled “The console shows no alert”The alert appears only when connected.ai_disclosure is true. A false or omitted value renders nothing. Check that the pack you published sets the field to true.