Comms surface for the phData work-agent: terminal-direct, and port channel-as-state to a file
The question
Verbatim: "Comms-surface decision for the phData work-agent (terminal-direct vs a channel) — determines whether channel-as-state / open-threads is rebuilt or dropped entirely. Still open in the setup plan."
Context: this is follow-up #4 from [[2026-06-04-harness-patterns-ray-to-phdata-work-agent]], which put "channel-as-state / open-threads" in the NEEDS-REBUILD column with the note that the comms surface itself was undecided. This brief is a decision memo, not a survey.
What we already know (from the vault)
- The question is still open, and it is open by default rather than by deliberation. [[2026-05-30-phdata-work-agent-setup-plan]] still carries
status: plan-pending-gateand its build outline is marked "NOT yet executed." A targeted sweep of the vault found no document after 2026-06-09 reporting that the work-agent was stood up, drafted an email, or was formally dropped. The last live mention is a tracked open item in the 2026-06-09 harness review. Founder attention visibly moved to CAF, KnowBe4, Kwik Trip, and cert study through June and July. Headline: this decision has not been made, but neither has anything else on this project - it stalled at the plan, ~2 months ago. - The setup plan is internally inconsistent on exactly this point, and the conservative reading is the correct one. Its constraint table asserts "Slack was never needed (session-based = work in terminal directly)," but its build outline says "comms surface TBD (Slack was MY assumption, NOT confirmed... ASK before assuming Slack)," and the plan's own provenance note records that "Mac Mini / Slack" were Ray's fabrication, logged as overconfidence incident #7. So the plan leans terminal-direct in one paragraph and calls it open in another. Nothing here may be laundered as a decision.
- The agent's shape already answers most of the question. The founder's stated requirements (his words, 2026-05-30 23:51 ET) are: air-gapped, runs on the work box, NOT always-on, session-launched, passive background help while he does other things in that same session. He is present at the machine for the agent's entire lifetime.
- What is actually DECIDED: air-gap from Ray (founder-confirmed), read + draft only, human-gated send, no public surface. These are live constraints, not proposals.
- The channel option that a reflex would reach for is already forbidden. Routing work-agent output to iMessage or Discord (Ray's stack) would put phData/client-adjacent content on a personal surface, which the air-gap decision rules out directly.
- The perimeter narrows the channel menu hard. Per the same plan's constraint map: Slack, Atlassian/Jira, and Zoom connectors are blocked on the work machine; the Gdrive connector is blocked; auto mode is unavailable; secrets run through LastPass with a CLI that breaks on federated SSO. The load-bearing pattern discovered there is "connectors die, filesystem survives."
- A channel is an egress path, and egress is the governance-sensitive boundary. [[2026-06-01-phdata-dlp-governance-gate-personal-ai-agent]] establishes that the enforceable Workspace controls (app access control, high-risk scope restriction, Context-Aware Access, DLP) bite hardest on egress and third-party app tokens, and that a self-built agent is by definition an unverified app to the tenant. Its recommendation: "the founder should not self-sanction via the filesystem workaround for anything touching client data... the tech is solved; the gate is a conversation."
- Ray's own channel-as-state SOP names its own precondition. [[2026-05-18-open-threads-channel-state-mechanism]] exists because "founder is busy / asleep / context-switched" and asks "sit unanswered indefinitely with no visibility." The 60-minute cooldown, the 9am-9pm window, the 🅿️ parking marker, and the morning-brief resurface are all constructions for an absent human.
What the web says
- Terminal-native is where serious agent work converged in 2026; chat is the delegation surface, not the work surface. Round-ups of CLI coding agents describe the 2026 default as terminal-first (Claude Code, OpenCode, Aider, Goose, Crush), with the summary read that "teams prefer terminal-native agents for actual coding work due to precision and control, while Slack/ChatOps serves more for task delegation and team collaboration" (Terminal Trove comparison, scriptbyai CLI agents, Dave Patten, State of AI Coding Agents 2026).
- The async-notification literature is explicitly about absent humans and long-running work. The patterns catalogued (webhook callbacks, polling, scale-to-zero with webhook rehydration, notification APIs across in-app/email/push/Slack/SMS) are framed around decoupling submission latency from execution latency for tasks the requester walks away from (TianPan, Async Agent Workflows, Augment Code, Sequenzy notification APIs). None of it argues a channel is needed for a co-located operator.
- Claude Code ships first-class local notification without any network surface. I fetched and read the hooks doc this run. The
Notificationhook fires "when Claude Code sends a notification" and supports matchers includingagent_needs_inputandagent_completed;Stopfires "when Claude finishes responding";SessionEndfires "when a session terminates" with matchers forclear,resume,logout,prompt_input_exit,other. The doc gives a worked example that emits a desktop notification via aterminalSequenceescape (OSC 9 / 99 / 777 depending on terminal) (Claude Code hooks docs). - Enterprise chat app installation is admin-gated by design, and the gate is a request workflow, not a config flag. Slack workspace/Grid admins can enable "only allow pre-approved apps," restrict specific apps by
app_id, and manage approvals org-wide (Slack: manage app approval, Slack: org-level app policies, Slack developer docs: managing app approvals). Practically: standing up a personal bot in a governed org is a security-review conversation, which is the same gate the DLP brief already identified.
Convergences and contradictions
- Convergence: every source points at presence as the discriminator. The vault's own SOP says channel-as-state exists for an absent founder. The web's async-notification literature is entirely about absent requesters. The 2026 agent-tooling consensus puts chat on the delegation side and terminal on the work side. The phData agent's founder-stated shape is co-located and session-scoped. All four agree.
- Convergence: the perimeter and the governance posture push the same way. The Slack connector is blocked at the box, enterprise app installs are admin-approved, and the DLP brief's finding is that egress is the enforceable boundary. A channel adds an egress path and an unverified-third-party-app footprint at the exact moment RDCO is trying to keep the sanction conversation simple.
- Contradiction to name honestly: the setup plan already half-asserted the answer without deciding it. Its constraint table treats "work in terminal directly" as settled while its build outline calls it TBD. That inconsistency is why this has drifted. It should be resolved by an explicit decision line in the plan, not by letting the table win silently.
- Tension worth flagging: a channel has one real upside the terminal lacks - observability by the employer. If phData ever sanctions the agent formally, agent output flowing through a corporate-observed channel is easier to defend than output that exists only in a local terminal scrollback. This is the one argument for Option B that is not about convenience. It is not currently load-bearing, because there is no sanction to defend.
Synthesis for RDCO
The two options, stated precisely
Option A - Terminal-direct. The founder interacts with the work-agent in the Claude Code TUI on the work box, during a session he launched. There is no persistent bidirectional messaging surface. The agent's outputs land in the terminal, on the filesystem, and in the Gmail drafts folder. Attention-getting is local (hooks to a desktop/terminal notification). Cross-session continuity is a local file, not a message history.
Option B - A channel. The agent posts into, and reads from, a persistent messaging surface, replicating Ray's channel-as-state and open-threads. Sub-variants:
- B1 Slack. The vault has independent evidence that phData runs Slack internally (a "phData Slack invite" milestone item, a
#CAF-requestsintake channel, a colleague's Slack referenced in July). But the Slack connector is blocked on the work box, and a personal bot requires admin app approval. Available only after a security conversation. - B2 Microsoft Teams. NOT FOUND as phData's internal tool. The only Teams references in the vault are a client's stack (Kwik Trip's M365 estate). Ruled out on absence of evidence, not on merit.
- B3 Email-to-self via the phData Google account. The only channel plausibly available with no new admin approval, because the email MVP already needs Gmail draft access. This is the cheap fallback if presence ever collapses.
- B4 A personal channel (iMessage/Discord, i.e. Ray's stack). Ruled out by a decided constraint - the air-gap. This is the option a reflex reaches for; it is already forbidden.
The criteria that actually discriminate
- Is the human present while the agent works? (decisive) Ray's channel exists to reach an absent founder across an always-on daemon's lifetime. The phData agent has no lifetime outside a session the founder is sitting in. A channel that reaches someone already in the room is pure overhead.
- Is the channel even available under the perimeter? B1 and B2 are blocked or unevidenced. B3 is available. B4 is forbidden. The menu is thinner than "terminal vs Slack" implies.
- Does it add an egress path or an unverified-app footprint? Terminal-direct adds neither. Every channel option except a purely local one adds at least one.
- What does channel-as-state actually buy, and is a channel the only way to buy it? It buys durable open asks across a boundary the human crosses. That need is real for a session-scoped agent (a session ends; the open ask should not evaporate). But it is satisfied by a file. The channel was never the point; the durability was.
- Reversibility. Terminal-direct is a non-decision in cost terms: adopting it forecloses nothing, and B3 remains available later for the price of a script.
The recommendation
Terminal-direct (Option A). Drop channel-as-state as a network mechanism; port only its function to a local file. Drop the open-threads cooldown machinery entirely. Confidence: HIGH.
Confidence is HIGH on the negative half (do not build a channel) because four independent lines - founder-stated agent shape, the perimeter map, the governance posture, and the SOP's own stated precondition - all converge, and because no channel option survives availability screening except the one nobody was proposing. Confidence is MEDIUM-HIGH on the specific substitute stack below, which is a design proposal, not a founder decision.
The substitute stack, all local, all consistent with "connectors die, filesystem survives":
- Attention: a
Notificationhook. Theagent_needs_inputandagent_completedmatchers are exactly the two moments a channel would have carried. The doc'sterminalSequenceexample emits a desktop ping with no network surface at all. On macOS,osascript -e 'display notification'is the more portable path if the work box's terminal does not speak the OSC sequences listed (Terminal.app is not among the terminals the doc names - verify in 30 seconds, do not assume). - Continuity: a local
open-threads.mdin the work-agent workspace, written onSessionEndand read at session start. This is channel-as-state with the channel replaced by a file. Same function - an open ask survives the boundary and gets resurfaced - with none of the egress. - The async outbox already exists and is not a chat surface: the Gmail drafts folder. The MVP is the channel. Drafts accumulate while he does other things and he reviews them on his own clock. That is precisely the asynchrony a chat channel would have been built to provide, and it is already in the plan with human-gated send intact.
Explicitly dropped, not rebuilt: the 60-minute cooldown, the 9am-9pm firing window, the 🅿️ parking marker, the anti-double-fire rule, and the morning-brief resurface. Every one of these is a wall-clock construction for an absent human. Porting them to a co-located session agent would be cargo-culting Ray's shape onto an agent that does not have Ray's problem. This is a clean confirmation of the two-layer model in [[2026-05-10-harness-moat-two-layers-portability]]: the pattern (durable open asks) ports; the mechanism (a channel plus a cooldown) does not.
What would flip this
- The agent's shape changes from session-scoped to background/always-on - e.g. it starts running during meetings or overnight on the work box. Presence collapses, and a notification surface becomes load-bearing. Even then the first move is B3 email-to-self, not Slack: it needs no new approval and rides auth the MVP already requires.
- phData formally sanctions the agent and admin-approves a bot. Then B1 flips from "unavailable" to "available and preferable," because employer-observable output is easier to defend than terminal scrollback. Sanction is the trigger, not convenience.
- He needs to read agent output away from the work box (phone, second machine). That is a genuine channel requirement that no local mechanism satisfies. Nothing in the current requirements implies it.
- The stall breaks in a different direction - if the work-agent gets rebuilt around a different substrate entirely (e.g. inside a sanctioned enterprise agent product rather than personal Claude Code), this whole memo is scoped to the wrong artifact.
UNVERIFIED - what he would need to check
- Whether phData permits employee-created Slack apps at all. UNVERIFIED. Cheapest check: attempt an app install and observe whether Slack presents a "request approval" flow. Confirms the admin posture without asking anyone.
- phData's Google Workspace edition (Business vs Enterprise Standard/Plus). Still unanswered since [[2026-06-01-phdata-dlp-governance-gate-personal-ai-agent]]. Determines whether DLP, Context-Aware Access, and the AI control center are live in the tenant.
- Whether phData has a written AI / shadow-IT / acceptable-use policy naming personal AI tools. NOT FOUND in the vault. This is the policy-only gate that actually decides sanction.
- Whether the work box's terminal emulator supports the OSC notification sequences the hooks doc lists. Trivially checkable;
osascriptis the fallback. - Whether an endpoint-management profile on the managed Mac restricts local notification or scripting APIs. UNVERIFIED and unlikely to bite, but it is the one way Option A's notification leg could fail.
The uncomfortable framing worth saying out loud
The reason this question sat open for two months is not that it is hard. It is that the project it belongs to stopped. The comms-surface decision is a 5-minute call that unblocks nothing, because the thing it would unblock (the email-draft MVP) has not been attempted since 2026-05-31. The honest action is to write the decision line into the setup plan so it stops surfacing as a research question, and then treat "does the phData work-agent get built at all, or was it superseded by the CAF role" as the actual live question. That second question is a founder call, not research.
Why this is in the vault
This closes follow-up #4 from [[2026-06-04-harness-patterns-ray-to-phdata-work-agent]] and supplies the missing decision line for [[2026-05-30-phdata-work-agent-setup-plan]], which currently contradicts itself on the comms surface. It also converts one row of the PORTS-CLEANLY / NEEDS-REBUILD ledger from "TBD" to "DROP the mechanism, PORT the function," which is a reusable rule for the locked-down-corporate-deployment playbook the FDE positioning work depends on: agent comms surface is chosen by operator presence, not by preference - a co-located session agent needs a notification hook and a state file, not a channel.
Open follow-ups
- Does the presence-based rule hold at the boundary case - an agent that is session-scoped but runs long enough that the operator leaves the desk mid-run? That is the regime where a local desktop notification stops being sufficient and B3 starts earning its keep.
- Is employer-observable agent output (a corporate channel) a sanction asset rather than a compliance cost? If a security team is more comfortable with an agent whose output they can see, the channel-vs-terminal calculus inverts for any sanctioned deployment, which matters for productizing the playbook.
- The prior, larger question this brief keeps bumping into: is the phData work-agent still a live project, or was it superseded when the CAF technical-PM role became the main phData surface? Founder call, not researchable.
Related
- [[2026-06-04-harness-patterns-ray-to-phdata-work-agent]] — the parent brief; this closes its open follow-up #4
- [[2026-05-30-phdata-work-agent-setup-plan]] — the plan where the decision is still open and internally inconsistent
- [[2026-05-18-open-threads-channel-state-mechanism]] — Ray's channel-as-state SOP, whose own stated precondition (absent founder) is the discriminator here
- [[2026-06-01-phdata-dlp-governance-gate-personal-ai-agent]] — the governance/egress analysis that rules against adding a channel
- [[2026-05-10-harness-moat-two-layers-portability]] — the two-layer model this decision instantiates (pattern ports, mechanism rebuilds)
- [[2026-06-19-phdata-experiment-fde-positioning-proof-point]] — where this rule feeds the methodology ledger
- [[project_channels_agent_setup]] — Ray's always-on topology, the thing deliberately not ported
Sources
Vault (all also linked above under Related):
~/rdco-vault/06-reference/research/2026-06-04-harness-patterns-ray-to-phdata-work-agent.md~/rdco-vault/08-tooling/2026-05-30-phdata-work-agent-setup-plan.md~/rdco-vault/02-sops/2026-05-18-open-threads-channel-state-mechanism.md~/rdco-vault/06-reference/research/2026-06-01-phdata-dlp-governance-gate-personal-ai-agent.md~/rdco-vault/06-reference/research/2026-06-19-phdata-experiment-fde-positioning-proof-point.md~/rdco-vault/06-reference/research/2026-06-05-compliant-work-agent-productizable.md~/rdco-vault/01-projects/phdata/milestones.md,~/rdco-vault/01-projects/phdata/2026-07-27-caf-technical-architecture-and-backlog.md(evidence phData runs Slack internally)
Web:
- Claude Code hooks reference — fetched and read this run; Notification/Stop/SubagentStop/SessionEnd events, matcher values, desktop-notification example
- Terminal Trove — AI coding agents comparison 2026
- scriptbyai — Best CLI AI coding agents 2026
- Dave Patten — The State of AI Coding Agents (2026)
- TianPan — Async Agent Workflows: Designing for Long-Running Tasks
- Augment Code — How Async AI Agent Workflows Survive Failures
- Sequenzy — Notification APIs for AI agents
- Slack — Manage app approval for your workspace
- Slack — Set organization-level policies for apps on Enterprise Grid
- Slack developer docs — Managing app approvals
Note on sourcing discipline: the Claude Code hooks page and the vault documents cited above were fetched/read directly in this run. The Slack and agent-landscape items are from search-result summaries and linked pages I did not open individually; they are cited as corroborating context, not as primary-text verification.
Follow-ups (gated candidates)
None — no researchable follow-ups survive the gates.
Rejected and why: (a) "stand up the notification hook / open-threads.md substitute" and "write the decision line into the setup plan" are build tasks, not research — they belong on the Notion board; (b) "confirm phData's Slack app-approval posture / Workspace edition / AI policy" are blocked on corporate access we do not have and are listed above as UNVERIFIED checks for the founder, not research questions; (c) the presence-based generalization is already derived in this brief's synthesis and would restate it.