Agent Restructure Options
Repo pass over /Users/andrewchang/work/bedrockv2/agent, focused on the iMessage loop, policy graph, clock, and custom workflows.
The main issue is not just the prompt. The current architecture still makes every mapped PM chat turn a
pm_work_order turn with the maintenance prompt and a global tool registry. If the product direction is "get the PM to talk more so Bedrock learns the company," the iMessage agent should become the user-facing job resolver: it owns when and how to ask the PM questions, while workflows and subsystems queue jobs into it.
Current Shape
doneContext/prompt cleanup landed.
build-context.mjs owns the PM chat message array and loads soul.md, messages.md, and work_orders.md as developer messages.partialPolicy graph exists but is not the live substrate.
core/policy-graph.mjs, schema, visualizer, stepper, and smoke tests exist. The main tool registry does not currently expose find_policy or log_event.partialWorkflow work is split between storage and demo surface.
workflows rows store ordered tool recipes, and workflow-viz.mjs renders a workflow card. I did not find a runtime that executes stored workflow steps.todoNo true heartbeat yet.
startScheduledSender only sweeps already-approved send-later drafts. There is no clock event that asks the agent what it should do now.Findings
The route still frames PM chat as maintenance by default.
factualContext() stamps route: pm_work_order, and every mapped PM turn always gets work_orders.md. So even with a warmer soul.md, the loop's center of gravity is still "resolve this work order."The tone prompt is pointed at low-friction execution.
messages.md says be concise, match brevity, avoid long explanations, and avoid repetitive outreach. That is correct for fast dispatch, but it fights the new "talk more, learn more" direction.The main agent and the worker are the same actor.The iMessage loop interprets the PM, replies, selects tools, drafts tenant/vendor messages, updates issues, and writes memory. That makes it hard to be curious without risking accidental operations.
The policy graph is stronger than the old memory model for operational rules.The event -> policy fold, scope chain, promotion, rollback, visualizer, and manual stepper are the right foundation for "how this company operates." The missing piece is making it first-class in runtime.
New work-order intake bypasses the policy graph.
processNewWorkOrder() enriches the issue, calls read_memory, gets a structured JSON decision, patches the issue, and queues a PM draft. It does not resolve a policy or log a policy event.The eval seams are useful and should be kept.Prompt/tool-call, burst/session, memory, and PMS-adapter eval scopes are already named. The next refactor should add tests in those lanes instead of creating one giant end-to-end suite.
Refactor Options
| Option | What changes | Why it works | Risk |
|---|---|---|---|
| A. Prompt patch | Make messages.md friendlier, add workflow language, expose policy tools, and keep one main loop. |
Fastest path to test the new vibe. | The architecture still says every PM turn is a maintenance turn, and custom workflows remain mostly prompt theater. |
| B. Conversation conductor + job queue + workflow executor | Make iMessage the relationship/learning layer and the only PM touch point. Subsystems queue jobs; the agent asks the user at a reasonable time and routes answers back. | Matches the new product: more conversation and learning, without letting every subsystem independently interrupt the PM. | Needs a new runtime boundary and a few new tools, but can be staged. |
| C. Event-sourced ops platform | Everything becomes an event: iMessage, PMS, clock, tenant/vendor replies, workflow state transitions. A durable planner decides jobs; executors run them. | Most correct long-term for custom workflows, heartbeat, and autonomy. | Bigger rebuild. Easy to stall unless scoped behind one live workflow. |
Recommendation
Take Option B as the next architecture, with a small Option A bridge.
Keep the current loop running, but stop treating the iMessage agent as "the maintenance bot." Recast it as Bedrock's conversational operator and user-facing job resolver: it talks to the PM, learns operating rules, notices opportunities, and handles questions queued by other subsystems.
The clean split is:
Conversation conductor.Owns live iMessage UX, tone, follow-up questions, relationship memory, and deciding whether this turn is chat, learning, maintenance approval, workflow creation, or follow-up.
Agent job queue.Owns all user-facing unresolved jobs: policy graph clarifications, workflow approvals, stale follow-ups, missing data, and sub-agent questions. Other systems enqueue; only the iMessage agent asks.
Policy graph.Owns standing operational rules: when trigger X occurs at scope Y, run workflow Z with bound args. This should replace "memory says maybe send vendor" for decision policy.
Workflow executor.Owns deterministic execution of stored workflow steps, with runtime args, pause points, approvals, retries, and tool scoping.
Heartbeat scheduler.Emits
clock_tick events that build an agenda: stale work orders, pending questions, quiet vendors/tenants, scheduled workflow timers, and user follow-ups.Agent Job Queue
The important edit: the agent is responsible for resolving jobs that require the PM, even when the work originates in another subsystem.
Jobs are not just work orders.A job is any unresolved item requiring the PM: "why Luigi?", "should this become a policy?", "approve this workflow?", "which vendor for this new category?", or "tenant and vendor went quiet."
Subsystems cannot directly talk to the PM.They enqueue
needs_user_input jobs with priority, context, expiry, suggested phrasing, and a continuation target.The iMessage agent chooses timing and packaging.It can merge related asks, wait during active send sequences, avoid awkward random pop-ins, and pick the right tone based on current conversation state.
The answer resolves back to the source.The job queue should carry
source_type, source_id, and resume_payload so the policy graph, workflow runner, or sub-agent can continue deterministically.Practical Sequence
| Step | Change | Why now |
|---|---|---|
| 1 | Add find_policy and log_event to the live registry behind eval mode guards. | Otherwise the policy graph cannot affect agent behavior. |
| 2 | Add a durable agent_jobs queue and a create_user_job tool for subsystems. | This makes the iMessage agent the sole user touch point without blocking policy/workflow work. |
| 3 | Introduce explicit routes: pm_chat, maintenance_reply, workflow_builder, job_resolution, clock_tick. | Prompt changes need architectural support; one always-on maintenance route is the wrong default. |
| 4 | Create conversation.md for the main iMessage personality, and move work-order specifics into a routed lane. | This lets the PM-facing agent be warmer and more inquisitive without weakening dispatch rules. |
| 5 | Build the heartbeat as an event source that reviews queued jobs and operational stale states. | The clock should ask "what deserves attention?" not only "which approved draft is due?" |
| 6 | Add workflow tools: list_workflows, create_workflow, run_workflow, and maybe pause_workflow. | Custom workflows need a real executable surface, not just JSON and a visual card. |
| 7 | Convert new-work-order intake to policy-first decisioning. | New work orders are the perfect first consumer of policy graph + workflow execution. |
| 8 | Add evals for chatty learning, policy lookup/logging, queued job resolution, heartbeat agendas, and workflow creation. | The current eval lanes are a good base; expand them where the architecture changes. |
Questions For Product Direction
These are the decisions I would settle before implementation:
Should Bedrock always end PM turns with an opening?Example: "want me to remember that as the default?" This increases learning, but it changes the feel from assistant to operator-in-training.
What is the default permission model for newly-created workflows?Draft-only, ask once then auto-run, or auto-run after policy confidence? The answer determines workflow state design.
What are the job queue interruption rules?We need defaults for urgent vs normal jobs, batching questions, quiet hours, active send sequences, and whether a pending PM reply blocks lower-priority asks.
Does the iMessage agent sell workflows explicitly?It could say "I can turn this into a standing workflow" and send the visual workflow card, or it could learn silently and only surface when useful.
How chatty is too chatty during real maintenance incidents?We probably need two modes: chatty when learning or reviewing patterns, terse when an urgent operational action is underway.
Bottom Line
Prompt tweaking can help, but it will not fully fix the product mismatch. The next coherent structure is a PM-facing conversation conductor with a durable job queue, plus separate workflow and policy execution layers. That lets Bedrock be friendlier and more curious in iMessage while making operational actions more deterministic, inspectable, and reusable.