Skip to content

Ship code-managed email templates as one reviewed draft PR #498

Closed

Description

@Silthus

Ship

Turn the integration branch spec/code-managed-templates into one reviewed draft PR on PostHog/posthog, per SHIP.md "Ship ticket". It covers Spec: code-managed email templates tickets #487–#492.

wayfinder:ship

Activity

  1. Silthus commented on Oct 16, 2026

    @Silthus
    OwnerAuthor

    Integration branch spec/code-managed-templates is created on the fork from a5dbb10460b, the reviewed head of the #486 migration PR PostHog/posthog#118769. The ship PR stacks on that PR.

  2. self-assigned this
    on Oct 17, 2026
  3. Silthus commented on Oct 17, 2026

    @Silthus
    OwnerAuthor

    Runtime: T3 child task
    Task: node:delegated-task:command%3Amcp%3A955e36b3-3986-469c-b816-09cf656780af%3Adelegate-task%3Awf-email-ship-498-1
    Cast: Opus 5.5, high. Cap 300 minutes. Ships spec/code-managed-templates at 7845707ba33, stacked on PostHog#118769. CodeRabbit is retired in this repo, so no slot is held.

  4. Silthus commented on Oct 17, 2026

    @Silthus
    OwnerAuthor

    Resolution

    PR: PostHog/posthog#118924 (draft), branch Silthus:spec/code-managed-templates, stacked on #118769 (review starts after a5dbb10460b).
    Reviewed head: 07d7e0ee544c7ea081a14d5d7001611b31a68e66. fleet proof gate exits 0 on it.

    What shipped

    Review

    qa-swarm, because the diff touches auth and API scopes, the save-and-sync transaction and public API contracts.

    Round HEAD Lanes Items Fixed Follow-up Rejected
    1 (full) e52feb3ccd9 GPT-6.1 Sol high: correctness, risk, design, systems, author perspective (review-hog-perspective-michael); Opus 5.5 high: fresh eyes, UI 20 13 4 3
    2 (fixes) 0c4ce8e83bb same 7 lenses on the fix diff 7 7 0 0
    Final read 07d7e0ee544 GPT-6.1 Sol high 0 – – –

    Fixed, among others: uploads checked workflow editor access only after the unchanged/superseded answers (a member without access could rewrite the source); a stale stored hash made the SDK loop on template_outdated; welcome\n passed key validation; two tickets each built a single-field PATCH matcher, a refusal exception and a usage-capture wrapper (now one each); editor saves sent key: null and failed after an adoption elsewhere; preview links replaced the preview; long keys clipped; Bitbucket and GitLab-subgroup source links were wrong. Risk lens graded the PR high (the unflagged save path plus public contracts), so a shadow diff was owed and ran.

    Explicit danger checks

    Proof (HEAD 07d7e0ee544)

    • Live run: Django from the branch on a scratch database, phs_ and personal keys, CDP stubbed at its HTTP boundary. Upload created/unchanged/updated, old hash 202 + template_superseded, made-up hash 409 with nothing queued, welcome\n 400, automatic upload superseded, a stale stored hash repaired by the next upload, edit 403 immutable, release, re-upload, adoption with a newline key 400. The earlier run on e52feb3ccd9 also covered a template written by master code (adopt, upload updated with the same id and workflow, send by key) and the flag-off 404s.
    • Shadow diff: base 3aa9e5a742e vs HEAD over 14 ordinary template edits, flag on and off: normalized responses identical, same workflow versions. Rerun on the final head: diff empty.
    • UI: Storybook renders on HEAD: a 90-character key truncates with an ellipsis and keeps its copy button at 560px; a target="_self" link in the preview opens a new tab and the preview stays; Duplicate shows a loading state while its request runs.
    • Delivery into the dev mail catcher: reused from Email templates: one send route that names the template in the body, with a content hash #488 and Email templates: adopt an existing template by giving it a key #490 (send path unchanged since).
    • Prod shape: gap, accepted under the standing instruction (production read access from 2026-11-02).
    • Local gate on HEAD: messaging backend 385 passed, mypy clean, frontend tsgo clean, TemplateLibrary + git parser jest 83 passed, MCP typecheck and tool snapshots, tach, product:lint, pre-push ci:preflight --strict 0 failures.

    Calls made (🤖, also in the PR's Decisions block)

    • Kept the spec as one PR (SHIP.md), although it is far over 400 production lines.
    • Repaired a stale hash at the upload boundary instead of hashing live on every send.
    • Declared the release (managed_by: gui) in the PATCH schema but kept it out of the MCP update tool, so agents can't unlock a template.
    • Moved the shared transactional email API pieces into their own module in this PR (the template view drops from 1,097 to under 900 lines).
    • Left the asset URL rewrite command outside the shared save path: recording only its hash would describe content the workflow does not send.
    • Rejected: why/fix/docs_url on existing send error codes (spec keeps their bodies); asserting the payload at the mocked CDP boundary is the observable output, not a change detector.
    • Graded the merge risk high; judged cross-version not owed; accepted the prod-shape gap under the standing instruction.
    • CodeRabbit is retired in this repo, so it was skipped.

    Follow-ups

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

wayfinder:shipReviewed draft delivery of an integration branch

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions