Journey Substrate Stage (optional)
Connect the deployed app to the owner's substrate so functions get ctx.substrate injected at cold start. Skip if the user has no AI-agent / memory use case.
When to use
Invoke automatically when the journey orchestrator's cursor reaches substrate. The row is optional in the checklist; skip silently if the user declines.
Procedure
Refresh docs. Call
butterbase_docswithtopic: "substrate". If the plan mentions AI memory / agent state / cross-session knowledge, also WebFetchhttps://docs.butterbase.ai/substrate. Skip ifdocs/butterbase/03b-docs-cache.mdalready coverssubstrate.Confirm. Ask the user:
"Connect
<app_id>to your substrate? This lets the app's functions read/write your agent memory viactx.substrate. You can disable later. (yes / skip)"Default: skip.
On skip: mark the row
- [x] substrate (skipped — no agent memory needed)indocs/butterbase/00-state.md. Writedocs/butterbase/04b-substrate.mdwith one line:Skipped on <date>.Return.On yes: a. If
platform_users.substrate_provisioned_atis NULL for the caller, callPOST /v1/me/substrate/provisionfirst (or invoke whatever MCP wrapper exists — checkbutterbase_docstopicsubstrate). b. Link the app. Use whichever surface you have:- MCP:
manage_appwith{ action: "link_substrate", app_id: "<app_id>" }. - CLI:
butterbase apps link-substrate <app_id>. - REST (curl):
POST /v1/me/apps/<app_id>/substrate-linkwith empty body andAuthorization: Bearer <bb_sk_*>for the app owner. The route enforces caller == app owner and setsapps.substrate_user_idto the caller's id. c. Verify:manage_appwith{ action: "get_config", app_id: "<app_id>" }and assertsubstrate_user_idis non-null. d. Smoke: invoke any HTTP function the app already has and checkctx.substrateis defined (if the function logs it). If no function exists yet, skip the smoke and note in the artifact.
- MCP:
Write artifact.
docs/butterbase/04b-substrate.md:--- linked_at: <ISO> app_id: <id> substrate_user_id: <id> --- # Substrate Linkage - App linked at <ISO> - Substrate user ID: <id> - Smoke: <pass / skipped — no function yet>Update state. Tick the
substraterow in00-state.md.
Anti-patterns
- ❌ Auto-linking without asking. Substrate is a privacy-sensitive surface.
- ❌ Linking before the app has any function deployed. Wait until
journey-functionshas run. - ❌ Forgetting to handle the "substrate not yet provisioned" case. Lazy provisioning is by design.
Source: butterbase-ai/butterbase-plugin — distributed by TomeVault.