Review: Port template rendering from Jinja2 to ERB for create_note_from_template
Verdict: READY
Scope is solid. File targets verified against committed codebase. Traceability complete (story note exists; arch note missing but pre-existing gap across all rails-api tickets). Single-repo, 3 file targets, 3 ACs — fits a single agent pass well under 5 minutes.
Template Completeness
- [x] Type — Feature
- [x] Lineage — Spike #75 (PR #76) Gap 7
- [x] Repo — ldraney/paldocs
- [x] User Story — present, well-formed
- [x] Context — clear description of silent failure mode
- [x] File Targets — 3 targets listed with descriptions
- [x] Feature Flag — "none" (correct, internal API change)
- [x] Acceptance Criteria — 3 criteria, verifiable
- [x] Test Expectations — 3 unit tests + run command
- [x] Constraints — ERB/Liquid preference, data dict compat, migration path noted
- [x] Checklist — standard PR/test/no-unrelated
- [x] Related — project + spike references
Traceability
- [x] story:consolidation label — present on board item
- [x] story note verified —
story-paldocs-consolidationfound in project-paldocs user-stories section: "absorb pal-e-docs into Rails monolith (schema, API, embeddings)" - [x] arch:rails-api label — present on board item
- [ ] arch note MISSING — no
arch-rails-apinote exists in pal-e-docs. However, this is a pre-existing gap shared across all 6+ board items with thearch:rails-apilabel (items #1568, #1569, #1570, #1599, #1600, #1601, #1602). Not a blocker for this ticket specifically — the arch note should be created as a separate backlog item. - [x] Forgejo issue — https://forgejo.tail5b443a.ts.net/ldraney/paldocs/issues/81, state: open
File Targets
- [x]
app/controllers/api/notes_controller.rb— verified: exists in git HEAD (commit 311f4a4). Containsfrom_templateaction at line 126. Currently copiestemplate.html_contentverbatim;dataparam is permitted intemplate_paramsbut never used. Confirmed silent failure. - [x]
app/services/template_renderer.rb(new) — confirmed does not exist yet.app/services/directory also does not exist. Both need to be created. - [x] Reference:
pal-e-docs/src/pal_e_docs/routes/notes.py— verified: exists at/home/ldraney/pal-e-docs/src/pal_e_docs/routes/notes.py./from-templateendpoint at line 551-585 callsrender_template()service. - [x] Reference:
pal-e-docs/src/pal_e_docs/services/template_renderer.py— verified: complete Jinja2 implementation. Finds code block withlanguage: "jinja2", renders with data dict, raises 3 custom exceptions (TemplateNotFoundError, TemplateBlockNotFoundError, TemplateRenderError).
Repo Placement
OK. Issue filed on ldraney/paldocs, all file targets are in paldocs. Reference files in pal-e-docs are read-only reference, not modified. Single-repo change.
Dependencies
- Depends on sprint:1 item #1567 (API namespace + Notes controller, 12 endpoints) — DONE. The
from_templateaction and route already exist. - Spike #75 (MCP endpoint compatibility) is in_progress — this ticket was identified as Gap 7 from that spike. No hard blocker; spike validates the gap exists but implementation can proceed independently.
- No downstream blockers identified on the board.
Acceptance Criteria
All 3 ACs are verifiable by an agent:
- AC1: POST with data param renders variables — testable via request spec
- AC2: Templates without renderable blocks copy verbatim — testable via request spec (existing test already covers this path)
- AC3: Invalid/missing data keys produce clear error — testable via request spec
Test run command is accurate:
bin/rails test test/requests/api/notes_* test/services/template_renderer_*. Existing spec at spec/requests/api/notes_spec.rb has 2 from_template tests (create success + 404) that will need to be extended.Note: Test command uses
bin/rails test (Minitest path convention) but existing tests are in spec/ (RSpec). Agent should use bundle exec rspec spec/requests/api/notes_spec.rb spec/services/ instead. Minor issue — agent will adapt.Blast Radius
- MCP tool consumers: The
create_note_from_templateMCP tool (used by all Claude agents) currently sends adataJSON string. The pal-e-docs FastAPI server renders it; the paldocs Rails server silently ignores it. After this fix, both servers will render templates. Behavior change is the intended fix. - Existing templates: Templates in pal-e-docs use Jinja2 syntax in code blocks. The issue's constraint section correctly notes the need to handle existing Jinja2 syntax or define a migration path. ERB uses different delimiters (
<%= %>vs{{ }}), so existing templates would need updating if ERB is chosen. Liquid uses{{ }}like Jinja2, which would be more compatible. - Hook reference:
claude-custom/hooks/block-docs-writes.shline 33 referencesmcp__pal-e-docs__create_note_from_template— no change needed, this is a tool name reference not a template format. - Backward compatibility: AC2 covers this — templates without renderable blocks must copy verbatim. This is critical since many templates have no code blocks.
Decomposition Assessment
No decomposition needed.
- 3 file targets in 1 repo — under threshold
- 3 acceptance criteria — under threshold
- Estimated agent work: straightforward port of well-documented Python logic to Ruby equivalent, well under 5 minutes
- Clear reference implementation exists
Recommendation
No action needed. Ticket is READY for implementation.
Advisory notes (non-blocking):
- [SCOPE] Create architecture note
arch-rails-apifor the Rails API component — shared gap across 6+ board items. Should be a separate backlog item, not a blocker for this ticket. - The test run command in the issue uses Minitest conventions but the project uses RSpec. Agent will adapt at implementation time.