agentic-app-foundationbreakdown.mdscope.md behind
this batch.David's agentic-interface concept was researched and the architecture settled: the agentic layer
is a separate app (apps/ai, its own Vercel project, eventually ai.sustentus.com), living
on top of and independently from the classic screens, sharing the Clerk session and the workspace
packages. The full plan is phased; Jamie has asked for the smallest batch that produces a real
first win: the app exists in the monorepo, deploys, sits behind sign-in, and a signed-in user
can hold a basic streamed conversation built on the Vercel AI Gateway (AI SDK v6) and the
@sustentus/ui AI primitives. Nothing more: no persona registers, no tenant-data tools, no
conversation persistence, no auth-core lift — those are later batches. Two seams: the app
scaffold (monorepo + deploy + sign-in gate) and the conversational interface on top of it.
Cross-cutting — this batch creates a new application rather than touching a service-journey step.
Feature-role-matrix: none yet (the surface reads no domain entities in this batch). Lands as a
new apps/ai plus small additions to turbo.json, root package.json, the root ESLint config,
and the deployment/CI accounting docs.
apps/ai Next.js app: monorepo wiring, sign-in gate, deployable shell — depends-on: none@sustentus/ui AI components — depends-on: agentic-app-scaffoldA plain chain — stub 2 builds inside the app stub 1 creates.
apps/web — the sign-in gate here is
"authenticated user", nothing finer; role registers and the policy table arrive with the
next batch.ai-platform-enablement/ai-gateway-billing-unlock;
stub 2 is only live-testable once that ships (noted in its stub).ai.sustentus.com domain go-live decision and the Clerk production root-domain
verification — operator actions recorded in the stubs' notes, not feature work._done/agentic-app-scaffold.mdThe approved agentic-layer architecture calls for a separate app beside the platform — living on top of and independently from the classic screens — and no such app exists. Until it does, every agentic feature has nowhere to land: there is no seventh app in the monorepo, no deploy target, and no signed-in surface to build the conversation into.
Create apps/ai, the agentic layer's home, as a minimal but production-shaped Next.js app in the
monorepo: it builds in CI alongside the other apps, runs locally on its own port, deploys as its
own Vercel project, and every route sits behind the shared Clerk sign-in (same production
instance as the platform — a signed-in platform user is signed in here too). The landed surface
is a branded shell page confirming who is signed in; the conversation itself is stub 2. The
classic apps are untouched.
apps/ai builds green in the Quality workflow and has a working local dev command on its
own port, without affecting any existing app's build or dev flow.apps/web) rebuild — nor the reverse.@sustentus/services data access — stub 2 and later.apps/web.ai.sustentus.com production domain cut-over — the app ships on its Vercel domain until
the operator attaches the subdomain.Decisions from the approved architecture report that bind this stub: separate app in the
monorepo, own Vercel project (that boundary later carries the AI Gateway project budget), Clerk
shared-session via the common production instance. Operator preconditions to flag at pickup, not
build work: point the Vercel project at the app's directory, mirror the Clerk env vars, and
verify the Clerk production instance's root domain is sustentus.com before any subdomain
go-live. Note for pickup: a Vercel project named agentic-interface already exists (as does
tenant-management), both rooted at apps/console — a directory not in the repo, so every push
currently errors on them. Settle the app directory name with Jamie/David at pickup (apps/ai vs
apps/console), then re-point or retire those projects so the stray errors stop; this stub
assumes apps/ai until they say otherwise.
Monorepo wiring the repo's conventions require: catalogue versions only, a per-app turbo dev
task (only @sustentus/web#dev exists today), vercel.json with the standard turbo-ignore
command, a root-ESLint block for the new app, and any new env var into turbo.json globalEnv
in the same PR. touches: apps/ai (new), turbo.json, root package.json, eslint.config.ts,
.icm/_shared/ci.md, apps/docs (deployment + repository-structure pages).
_done/agentic-chat-interface.mdOnce the scaffold ships, the agentic app is a shell with nothing to say. The first win the concept needs is the simplest true version of its promise: a signed-in user asks a question and watches a real answer stream back — proving the app, the shared session, the gateway wiring and the shared UI components work together end to end.
A conversation page in apps/agent built from the shared @sustentus/ui AI components (prompt
input, streamed message rendering, thinking shimmer), talking to a streaming chat route in the
same app. The route follows the house agent pattern — an agent defined in
packages/services/src/ai/ with no tools in this stub, addressed through the Vercel AI
Gateway — and requires a signed-in user. Responses render as streamed markdown (no raw HTML, so
no new sanitisation surface). When the gateway declines, the user sees friendly retry copy, never
a provider error. The conversation is ephemeral by design — a refresh starts fresh — and the
route carries a simple per-user rate limit so a single user cannot run up unbounded spend.
Live end-to-end testing depends on ai-platform-enablement/ai-gateway-billing-unlock (cross-batch
— the gateway currently 403s on the free tier); the surface can build and review before it, but
the DoD smoke needs funded credits, so check that stub's state at pickup. Follow the current code
patterns, not the stale skill text: defineAgent in packages/services/src/ai/core/agent.ts
(default model constants live there), createAgentUIStreamResponse route with maxDuration, and
the packages/ui compound/ai primitives; the ai-feature skill predates several of these.
Rate limiting per the platform docs is Vercel WAF / @vercel/firewall checkRateLimit keyed by
the signed-in user — keep it to one rule. Open question for Define: whether the v0 agent gets a
minimal Sustentus-aware system prompt (tone, refusal rules, prompt-injection defences mirroring
the BRD prompt) or ships as a plain assistant — recommend the former, it is a prompt file, not
scope. touches: apps/agent (chat page + route), packages/services/src/ai/ (new agent folder),
turbo.json globalEnv (only if a new env var appears).