01-projects/phdata

Hex deployment matrix — adapters per port, viable combinations, per-target challenges

2026-07-03·project·status: draft-for-founder
phdataagent-brigadecafhexagonal-architecturedeployment

Hex deployment matrix — the five pieces, their adapters, and what actually composes

Requested by founder 2026-07-03 ("enumerate which options we have for deploying each piece, then select which combinations can be deployed together"). Companion to his hexagon diagrams (7/2) and [[2026-07-01-caf-ecosystem-map-and-brigade-restructure-read]]. Vocab: a port is the interface; an adapter implements it against a concrete technology. Driving adapters call into a core; driven adapters are called by it.

First, classify the five pieces

Piece Hex role
Steward Agent A core (hexagon) — drives the rail port, drives the cellar port
Agent Brigade A core (hexagon) — driven by the rail port (pulls tickets), drives the cellar port; public surface = the five standard commands (BRIGADE-INTERFACE.md, PR #9)
Cellar A port + a driven adapter behind it (store of knowledge + artifacts)
Rail A port + a driven adapter behind it (mutable ticket queue w/ lease/ack)
Use Case Website A driving consumer on the manifest slice of the cellar port (reads landed Build Manifests; never writes)

The founder's 7/2 diagram insight holds: cellar (cold) and rail (hot) sit center-touching — in v1 they are literally the same filesystem. In deployment terms that's a co-location choice, not a requirement: they are separate ports and can bind to different adapters, at the cost noted in rule R2.

Packaging vs runtime (founder refinement, 7/3)

The two agents (Steward Agent, Brigade Agent — doc convention per founder 7/3: call them agents; technically they're packaged artifacts, skills shipped in a plugin) don't "deploy" the way the stores do — deploying an agent means installing it into a runtime. That splits what the first draft called "Brigade runtime" into two independent axes:

Axis Options
Packaging (how the code ships) Claude Code plugin (LIVE — skill-agent-brigade) · Cowork org-admin-published skills (the 6/15 second rail) · Snowflake Cortex Code — ⚠️ unevaluated: CoCo is real as a runtime (Gary built the KB4 demo in it) but skills/plugin packaging support is unverified — do not assume
Runtime (where an installed core executes) local Code session · headless claude -p cron · Anthropic cloud scheduled sessions · SPCS container · Cowork

Two consequences:

  1. Steward and Brigade need not share a runtime. That is the rail boundary doing its job: FOH can live in Cowork (where the 60 sales seats are) while the brigade runs headless on a box or in SPCS. The only shared infrastructure is the two ports — rail + cellar. "Same setting" is a convenience of P0/P1, not a property of the architecture.
  2. One plugin can package both cores and be installed asymmetrically — same artifact, different seats. The install-set per runtime is a deployment choice (steward skills only, brigade only, or both), not a packaging fork.

So the profile table's Runtime column reads as "runtime(s) the cores are installed into," and P2-P4 are exactly the profiles where steward and brigade runtimes diverge.

Adapter options per piece

Cellar (driven)

Adapter Status Notes
Local filesystem LIVE (v1, ~/Projects/phdata-private/cellar/) The current everything
Git repo (filesystem + remote) trivial delta Same fs adapter + push; adds history/multi-machine sync; merge model unsolved for concurrent writers
Snowflake stage documented in CELLAR-SPEC/RAIL-SPEC, not built Governed, client-data-gravity; supersedes-chain walk needs LIST + GET porting
Snowflake Cortex Search documented, not built Search-over-cellar, not the store of record — pairs WITH a stage, doesn't replace it
S3 / R2 object store not built; chain-walk port specified in frontend MARKETPLACE.md Needed the moment any serverless/edge runtime must read the cellar

Rail (driven)

Adapter Status Notes
Filesystem dir LIVE (v1) Advisory lease — one walker by convention (RAIL-SPEC is honest about this)
Snowflake table designed in RAIL-SPEC, not built Real atomicity (compare-and-set lease); the client-governed choice
Jira / Linear not built — founder's 7/2 question, deferred then; it belongs here Viable: ticket=issue, lease=assignee+status transition, work-log=comments (append-only ✓), payload=description+attachments. Challenges: markdown fidelity, attachment size caps for context snapshots, webhook-vs-poll, and Gate A needs API-side field mapping. Big win: the org already lives there — steward intake for the sales backlog could BE a Jira intake form
SQS-class queue not built Real queue semantics but tickets are mutable documents, not messages — would still need a document store beside it; probably wrong fit alone

Brigade runtime (where the cores execute)

Adapter Status Notes
Local Claude Code session (interactive) LIVE — every run so far mini or phData laptop
Headless claude -p + cron/LaunchAgent LIVE pattern (RDCO cron suite) service mode's natural home; needs shared-credential refresh discipline (the 6/22 401 outage lesson)
Anthropic cloud scheduled agents public beta, unevaluated for this Credential vaults; no local filesystem → forces object-store cellar/rail adapters
Snowflake SPCS container not built The governed client target; see challenge C1 (egress)
Claude Cowork partially explored (6/15 arch: Cowork-primary for the 60-seat sales org) Skills rail exists (org-admin published); tool access via remote MCP only → see C2

Steward (driving)

Adapter Status Notes
Interactive Code/Cowork session + steward skill skill LIVE (steward SKILL.md) Today's mode; founder-as-requester
Structured intake form → ticket NOT BUILT — the weakest link (step 1 = PARTIAL in the receipts audit) Required before sales-backlog volume; could be a web form, a Jira intake, or a Slack workflow
Slack/Teams bot front-end not built Highest-adoption path for 60 sales users; pairs naturally with runner notifications

Use Case Website (driving consumer) — already enumerated in frontend MARKETPLACE.md

Local dev (cellar adapter, built) AWS Amplify SSR (needs S3-cellar adapter) Cloudflare (needs R2-cellar adapter or static export; snowflake-sdk won't run on Workers) SPCS container (built, the original production target) quick-sites static export (design-noted; needs generateStaticParams + dropping force-dynamic).

Composition rules (what makes a combo viable)

Named profiles (the combos worth deploying)

Steward and brigade runtimes are specified separately (founder 7/3) — they only share the rail

Profile Steward runtime + intake Brigade runtime Cellar Rail Website State
P0 Local dev (today) local Code session, founder/Ray interactive same local Code session filesystem filesystem local dev (cellar adapter) LIVE — the Lenovo run
P1 phData single-operator (the #2 port) interactive Code, phData laptop same session filesystem (from zips) filesystem local dev Zips delivered 7/3 — the stress-test profile
P2 Team internal Jira intake form (+ interactive Code) headless cron on a shared box git-synced filesystem Jira/Linear or filesystem+single-walker Amplify (S3-cellar) Nearest multi-user step; needs intake + one rail decision
P3 Snowflake-native (client-governed) Cowork / web form SPCS container Snowflake stage + Cortex Search Snowflake table SPCS (built) The 321GO/CAF production shape; gated on C1+C2
P4 Cowork sales org Cowork skill (60 seats) cloud scheduled sessions or SPCS — a service loop doesn't belong in an interactive seat Snowflake stage (via remote MCP) Snowflake table (via remote MCP) any Matches 6/15 "Cowork-primary" decision; every port crossing rides ONE remote MCP server

Per-target technical challenges (the founder's "nuanced" list)

Recommended sequence

P1 now (zips in hand) → pick P2's rail (Jira vs single-walker filesystem) after the sales-backlog stress test shows real queue shape → build the S3-cellar adapter when the website needs to leave localhost → P3/P4 as the client/GTM motion demands, gated on C1/C2 spikes.

Open questions for founder

  1. P2 rail: Jira/Linear (org-native, atomic-ish, intake for free) vs stay filesystem single-walker longer? My lean: Jira for the rail + intake, filesystem cellar untouched.
  2. Is the P4 Cowork profile still the 60-seat target post-re-org (AAI/FDE motion), or does the Tiger Team charter change the consumption surface?
  3. Which profile does the KB4 onsite (July 15) demo ride on? P1 is safest; P3 is the story the Snowflake AEs want to see.