One Full Message Flow
Connect pipeline, guard, and effect in one scenario so the runtime sequence becomes obvious
This page stops looking at one point in isolation and instead connects three hook types into one runtime path.
Scenario
You have one inbound message and want it to go through three steps:
- enrich it with source and page information
- check whether it was reviewed
- record one observation log
Host code
const enriched = await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).pipeline("chat.enrich_message", {
text: "Please summarize this page",
});
await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).guard("review.require_checked", enriched);
await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).effect("audit.observe", enriched);The corresponding powers
MessageAugmentPower
Owns the pipeline step:
- add fields to the input
ReviewGuardPower
Owns the guard step:
- decide whether the flow may continue
AuditEffectPower
Owns the effect step:
- record what happened
Why these should not be merged into one point
Because they answer three different questions:
pipeline: should the value changeguard: may the flow continueeffect: should something be recorded
Once these are mixed into one point, the runtime meaning usually becomes harder to follow.
Main takeaway
Hooks do not mean "a power decides when it runs."
They mean:
- the host defines the sequence
- powers participate at named points in that sequence