PayCargo · AI-Sandbox · Step 6.s

6.sContent CMS — versioned grounding docs (CLAUDE.md / skills.md)

A Console-hosted store of versioned markdown that steers AI calls: per-cartridge CLAUDE.md / skills.md, keyed by (cartridge, scope, name), read at Bedrock-invocation time so an agent follows the platform's current doctrine rather than a stale local copy.
Block: 6.s (Console platform service) · State: Live in AI-Sandbox · Code: shared/modules/content/store.js, console/content.tf, Console frontend/
Shipped
What actually shipped is simpler than the early "forge-sdk-cms" spec (a standalone cartridge with an approval queue, SES sign-off, and a release manifest). The content layer lives in the Console: a versioned-markdown store, edited in the Console's Content CMS pane (and, per cartridge, in that cartridge's own surface), read by cartridge backends and by the Console MCP grounding tools. No separate cartridge, no approval workflow — the admin / cartridge-permission gate is the control.

Contents

  1. Why grounding docs
  2. The data model (series, versions, active pointer)
  3. How cartridges consume it
  4. Where it is edited
  5. The safety fence

1. Why grounding docs

An AI call is only as disciplined as the context it carries. Rather than bake rules into each cartridge's code (where they drift and can't be changed without a deploy), the platform keeps operator-authored CLAUDE.md and skills.md in a versioned store. A cartridge reads the active version at call time and fences it into the system prompt; a scheduled evaluator pulls it over the Console MCP with a hash-check so it only re-downloads what changed. Edit the doctrine once, and every consumer follows it on its next run.

2. The data model

A doc is a series of versions (v1, v2, …) with one active pointer, keyed by (cartridge, scope, name):

Upload appends a new version and activates it by default; the store keeps every version + who saved it + when (shared/modules/content/store.js: getActive, getSeries, upload, activate, remove). The table is <project>-console-content (pk = cartridge, sk = <scope>#<name>#v<n> + a meta row holding the active/latest pointers).

3. How cartridges consume it

Consumption is server-side, not an SDK helper: a cartridge's Lambda stages the content module, reads the active docs for its (cartridge, scope), fences them, and prepends the block to the Bedrock system prompt. squad-assess does this for every assessment gate (cartridge-wide _ first, then the gate's scope). The Console MCP exposes the same store as read tools — grounding_manifest (list with sha256) and grounding_get (fetch one) — so an external evaluator grounds itself the same way.

4. Where it is edited

SurfaceWhoScope of edit
Console → Content CMS paneadminsany cartridge's series
A cartridge's own console (e.g. Foundation Audit's grounding editor)admins / that cart's groupthat cartridge's claude/skills at scope _

Routes follow /api/content/{cart}/{scope}/{name} (list / get / active / upload / activate / delete); the per-cartridge editors are thin wrappers that force their own cartridge id. Uploads run through the Console's safety scanner.

5. The safety fence

Operator guidance is content, not instructions to the platform. shared/modules/content/safety.js fences each doc when it is injected into a system prompt — wrapping it so a grounding doc can steer the task without smuggling directives that override the platform's own controls. Uploads are also scanned; a blocking finding refuses the upload, a warning asks for acknowledgement.

Superseded design

The earlier plan (Doctrine 2.10 / 8.9 "v2 target") described a standalone forge-sdk-cms cartridge with a draft→submit→approve→publish queue, SES sign-off, a releases manifest, and a git mirror. That apparatus was not built — the shipped design keeps the store in the Console, gates edits by permission, and consumes docs directly. The 6.r "SDK-distribution MCP" that would have fronted it is likewise unbuilt; the shipped Console MCP (6.v) is a different, machine-token model.