Teach agents to file, type, and template new plans - #182
Conversation
Agents were creating plans unfiled, untyped, and unstructured — because nothing let or told them do otherwise: - POST /api/v1/plans now accepts folder_path/folder_id (filed via Plans::Place in the create transaction) and tags; the plan type's default_tags are applied automatically. - New GET /api/v1/plan_types returns each type with its description, default_tags, and template_content — previously templates were admin-only and applied nowhere. - /agent-instructions: Create Plan now opens with a three-step pre-flight (pick the folder from your library, pick the most specific type, structure content against its template), the example creates filed+typed in one call using a real configured type, and General is reframed as the fallback of last resort. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds structured agent plan creation with folder placement, plan types, templates, and default tags.
Changes:
- Supports filing and tagging plans during creation.
- Adds an authenticated plan-type catalog API.
- Updates agent guidance and request coverage.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
engine/app/controllers/coplan/api/v1/plans_controller.rb |
Adds transactional filing and default tags. |
engine/app/controllers/coplan/api/v1/plan_types_controller.rb |
Exposes plan-type metadata and templates. |
engine/app/views/coplan/agent_instructions/show.text.erb |
Documents structured plan creation. |
engine/config/routes.rb |
Routes the plan-types endpoint. |
spec/requests/api/v1/plans_spec.rb |
Tests filing and tags on creation. |
spec/requests/api/v1/plan_types_spec.rb |
Tests the plan-type catalog. |
spec/requests/agent_instructions_spec.rb |
Tests updated agent guidance. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # folder_path, orphaned folders) for a create that failed. | ||
| if params.key?(:folder_id) || params.key?(:folder_path) | ||
| folder = resolve_folder_params | ||
| raise ActiveRecord::Rollback if performed? # resolve rendered an error |
There was a problem hiding this comment.
🤖 Good catch — fixed in 114c1ed. Plans::Create now emits plan_created via ActiveRecord.after_all_transactions_commit, so a rollback of the wrapping create-and-file transaction no longer leaks the event (outside a transaction it still fires immediately). Covered by new specs: a rolled-back create emits nothing, a successful filed create emits exactly once.
| <%= @curl %> -X POST \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"title": "My Plan", "content": "# My Plan\n\nContent here.", "plan_type": "general"}' \ | ||
| -d '{"title": "My Plan", "content": "# My Plan\n\nContent following the type template.", "plan_type": "<%= example_type&.name || "general" %>", "folder_path": "Team EBT/Q3"}' \ |
There was a problem hiding this comment.
🤖 Fixed in 114c1ed. The example payload is now built in the controller with JSON.generate (so quotes/newlines in a type name are JSON-escaped) and single quotes are escaped as '\'' for the surrounding shell quoting. Regression spec creates a type named Bob's "Special" Doc and asserts the rendered command stays valid.
- Plans::Create now emits plan_created via ActiveRecord.after_all_transactions_commit, so a caller wrapping creation in a larger transaction (the API's create-and-file) can't roll back the plan and still leak the analytics event. - The Create Plan curl example is JSON-serialized and shell-escaped in the controller instead of hand-interpolating the admin-controlled type name into quoted JSON. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Problem
Agents were creating plans unfiled, untyped, and unstructured — and a review of
/agent-instructionsshowed they were behaving exactly as instructed:POST /api/v1/plansdidn't accept a folder at all; filing required an undocumented secondPATCH, and the Create Plan docs never mentioned folders."plan_type": "general".template_contentexisted on plan types (admin-editable) but was returned by no API, applied nowhere, and never mentioned in the instructions. Same fordefault_tags— stored but never applied, despite the docs claiming otherwise.Changes
API
POST /api/v1/plansacceptsfolder_path/folder_id— filed viaPlans::Placeinside the create transaction, so a bad folder param rolls back the whole create instead of leaving an unfiled plan or orphaned folders. Also acceptstags.default_tagsare applied automatically on create, with explicittagsunioned on top.GET /api/v1/plan_typesreturns each type'sname,description,default_tags, andtemplate_contentso agents can review the template before drafting.Agent instructions
"general"; General is reframed as the fallback of last resort.Notes
template_content— worth writing templates for the production plan types in ActiveAdmin after this lands.🤖 Generated with Claude Code