You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Docs: change a code-managed template with an agent, PostHog Code or PostHog AI, and where source details come from #507
Cast: Opus 5.5, high
Repository: PostHog/posthog.com
Stack: none; it extends the docs page draft PostHog/posthog.com#21306
Question
Does the transactional email API page explain how to change a code-managed template, by your own agent, by PostHog Code, or by asking PostHog AI or Slack, and where its source details come from?
Delivers end to end.
Section "Change a code-managed template":
"Edit with your agent" (complete the sentence, paste the prompt);
"Run with PostHog Code" (a task opens a pull request);
asking PostHog AI or the Slack bot does the same;
"Copy HTML file" for a template without a file;
nothing changes in PostHog until the next send or upload.
changed the title [-]Docs: edit a code-managed template in PostHog, and the PR error codes[/-][+]Docs: change a code-managed template with your agent, and where source details come from[/+]on Oct 17, 2026
changed the title [-]Docs: change a code-managed template with your agent, and where source details come from[/-][+]Docs: change a code-managed template with an agent, PostHog Code or PostHog AI, and where source details come from[/+]on Oct 17, 2026
Decision (Michael, 2026-10-17): keep the rule.request_change refuses calls from inside a PostHog Code sandbox. PostHog AI and Slack runs come from such a sandbox, so for a code-managed template they do not call it. Instead they hand the person the template link, where "Run with PostHog Code" opens the PR in one click. An agent that can reach the repository still edits the file itself.
Runtime: T3 child task
Task: node:delegated-task:command%3Amcp%3A1b2eaa74-4f92-44bb-9856-6c98e457cb24%3Adelegate-task%3Awf-email-impl-507-1
Cast: Opus 5.5, high.
Shipped: two commits on Silthus:docs/transactional-email-api, the branch of draft PostHog/posthog.com#21306. The PR description is updated. The PR stays a draft.
6aa5dd523 docs(workflows): change a code-managed template, and where its source comes from
3f9db72ad docs(workflows): fix review findings on changing a code-managed template
fleet proof gate passes on 3f9db72ad: live-run evidence at HEAD, HEAD reviewed in final read 4.
What shipped
Change a code-managed template:
Edit with your agent: complete the sentence, copy the prompt. The example prompt is the builder's output for an example.com-style repository. Agents get the same text in change_prompt_starter and change_prompt_context.
Run with PostHog Code: what the task does, the four disabled reasons, and errors in the popover. Also the route POST …/messaging_templates/:id/request_change/, its auth (task:write, editor access to Workflows, no project secret key), the 201 body, and the MCP tool.
Ask PostHog AI or the Slack bot: they run inside PostHog Code, so they can't open a pull request. They give you the template link, and Run with PostHog Code opens it. An agent with a checkout edits the file itself.
Copy the HTML file: for a template without a file. Name the file after the key. The text-part note.
When the change goes live: copying a prompt or a file, or starting a task, changes nothing in PostHog until the app sends or uploads the file.
Where the source details come from: the source option of uploadTemplate(), the GitHub Actions, GitLab CI, Vercel and Railway variables and their order, the full-hash rule for refs, the git checkout fallback, the path rules, and what happens when nothing is found (repository and ref left out, PostHog keeps the stored value).
Seven error anchors, each quoting the server's detail, why and fix verbatim: instruction_missing, template_not_managed_by_code, template_repository_missing, template_repository_unsupported, github_repository_not_connected, posthog_code_not_available (its four reasons as a table), posthog_code_run_failed.
Updated: the immutable fix to the server's new text, and the change request route in invalid_request, not_found, permission_denied, the beta note and "Before you start".
The strings for the change request codes come from the server code by a Python AST pass over template_change_requests.py, template_ownership.py and message_templates.py at 60fb98f06a5.
Red on c86c7a6a9: 25/34. The seven codes have no anchor, and immutable and invalid_request miss the new fix text.
Green on 3f9db72ad: 34/34.
Every docs_url the route emits (…/transactional-email-api#<code>) resolves. A plain navigation to #template_repository_missing lands on the section.
Links: all 59 in-page # links on the rendered page have a target.
Screenshots from the local dev server (GATSBY_MINIMAL=true pnpm start), both sections and an error anchor, light at 1440 px and dark at 820 px, are in the PR body.
Lint: the pre-commit hook (markdownlint, Prettier) passed on both commits. No em or en dashes.
Gaps:
Vale isn't installed on this box.
No production gatsby build, so no markdown twin was generated locally.
No separate mutation run: the dev server's develop process died on a second live reload. The red run already shows the check catching one changed sentence (the old immutable fix).
Review
Fresh Claude subagent, Opus 5.5, high effort, read-only. Recorded with fleet proof review-start and review-finish.
Round 2 on 6aa5dd523: 0 high, 1 medium, 13 low. All held and are fixed in 3f9db72ad.
Medium: an agent that gets the sandbox refusal wasn't told where the template link is. It is the last line of change_prompt_context.
Low: among others, the detection order didn't hold for path, the absolute-path fallback was missing, Copy HTML file has to be named after the key, the "Checking the GitHub connection" reason was missing, and an app that sends by key needs an upload after the merge.
Final read 4 on 3f9db72ad: all resolved, and the five new claims hold against the code. PASS.
Calls made
👤 What do PostHog AI and the Slack bot do for a code-managed template? They hand the person the template link, where Run with PostHog Code opens the pull request. The page never says they open a PR.
🤖 How to quote the change request errorsdetail, why and fix as a list per code, and posthog_code_not_available's four reasons as a table.
🤖 Where the anchor check gets its strings From the server code by AST, so a server text change fails the check.
The MCP tool description of workflows-request-email-template-change still calls it the path for "a chat client with no checkout". From PostHog AI and Slack it answers 403 posthog_code_not_available.
Ship stack B: request a change through PostHog Code #517 (stack B server text): the immutable fix says "The next send uploads it." That misses an app that sends by key, which needs an upload. The prompt builder already makes that split. The page quotes the server, so it changes when the server text changes.
posthog.com's gatsby develop breaks with DEBUG=1 in the environment (webpack inlines process.env.DEBUG in the debug package). Unset it.
It also breaks with a global url.<ssh>.insteadOf https://github.com/ rewrite, because gatsby-source-git compares remote URLs. GIT_CONFIG_GLOBAL=/dev/null for the server process avoids it.
Gaps carried: Vale and a production gatsby build on the page.
Activity
[-]Docs: edit a code-managed template in PostHog, and the PR error codes[/-][+]Docs: change a code-managed template with your agent, and where source details come from[/+][-]Docs: change a code-managed template with your agent, and where source details come from[/-][+]Docs: change a code-managed template with an agent, PostHog Code or PostHog AI, and where source details come from[/+]Silthus commentedon Oct 17, 2026
Decision (Michael, 2026-10-17): keep the rule.
request_changerefuses calls from inside a PostHog Code sandbox. PostHog AI and Slack runs come from such a sandbox, so for a code-managed template they do not call it. Instead they hand the person the template link, where "Run with PostHog Code" opens the PR in one click. An agent that can reach the repository still edits the file itself.Silthus commentedon Oct 17, 2026
Runtime: T3 child task
Task:
node:delegated-task:command%3Amcp%3A1b2eaa74-4f92-44bb-9856-6c98e457cb24%3Adelegate-task%3Awf-email-impl-507-1Cast: Opus 5.5, high.
Silthus commentedon Oct 17, 2026
Note
🤖 Opus 5.5 responding on behalf of Michael
Resolution
Shipped: two commits on
Silthus:docs/transactional-email-api, the branch of draft PostHog/posthog.com#21306. The PR description is updated. The PR stays a draft.6aa5dd523docs(workflows): change a code-managed template, and where its source comes from3f9db72addocs(workflows): fix review findings on changing a code-managed templatefleet proof gatepasses on3f9db72ad: live-run evidence at HEAD, HEAD reviewed in final read 4.What shipped
example.com-style repository. Agents get the same text inchange_prompt_starterandchange_prompt_context.POST …/messaging_templates/:id/request_change/, its auth (task:write, editor access to Workflows, no project secret key), the201body, and the MCP tool.sourceoption ofuploadTemplate(), the GitHub Actions, GitLab CI, Vercel and Railway variables and their order, the full-hash rule for refs, the git checkout fallback, the path rules, and what happens when nothing is found (repository and ref left out, PostHog keeps the stored value).detail,whyandfixverbatim:instruction_missing,template_not_managed_by_code,template_repository_missing,template_repository_unsupported,github_repository_not_connected,posthog_code_not_available(its four reasons as a table),posthog_code_run_failed.immutablefix to the server's new text, and the change request route ininvalid_request,not_found,permission_denied, the beta note and "Before you start".Proof
template_change_requests.py,template_ownership.pyandmessage_templates.pyat60fb98f06a5.immutablefix, which the server replaced.c86c7a6a9:25/34. The seven codes have no anchor, andimmutableandinvalid_requestmiss the new fix text.3f9db72ad:34/34.docs_urlthe route emits (…/transactional-email-api#<code>) resolves. A plain navigation to#template_repository_missinglands on the section.#links on the rendered page have a target.GATSBY_MINIMAL=true pnpm start), both sections and an error anchor, light at 1440 px and dark at 820 px, are in the PR body.gatsby build, so no markdown twin was generated locally.immutablefix).Review
Fresh Claude subagent, Opus 5.5, high effort, read-only. Recorded with
fleet proof review-startandreview-finish.6aa5dd523: 0 high, 1 medium, 13 low. All held and are fixed in3f9db72ad.change_prompt_context.path, the absolute-path fallback was missing, Copy HTML file has to be named after the key, the "Checking the GitHub connection" reason was missing, and an app that sends by key needs an upload after the merge.3f9db72ad: all resolved, and the five new claims hold against the code. PASS.Calls made
detail,whyandfixas a list per code, andposthog_code_not_available's four reasons as a table.spec/template-agent-editat0960e3de116(feat(workflows): edit a code-managed email template with your agent PostHog/posthog#118980, newer than the copy merged into stack B), the button copy fromspec/template-request-changeat60fb98f06a5.Spec and code differences (the page follows the code):
request_changeand share the task linkposthog_code_not_available. They hand over the template link (decision above)sourceuploadTemplate()takes it. The upload after a send uses detection onlyinvalid_requestpast 2,000 characters.posthog_code_not_availableis403with fourwhy/fixpairs, the rest400task:writeand read access to the templatetask:writeand editor access to WorkflowsFollow-ups
workflows-request-email-template-changestill calls it the path for "a chat client with no checkout". From PostHog AI and Slack it answers403 posthog_code_not_available.posthog_code_not_availableneed an update.immutablefix says "The next send uploads it." That misses an app that sends by key, which needs an upload. The prompt builder already makes that split. The page quotes the server, so it changes when the server text changes.gatsby developbreaks withDEBUG=1in the environment (webpack inlinesprocess.env.DEBUGin thedebugpackage). Unset it.url.<ssh>.insteadOf https://github.com/rewrite, becausegatsby-source-gitcompares remote URLs.GIT_CONFIG_GLOBAL=/dev/nullfor the server process avoids it.gatsby buildon the page.Silthus commentedon Oct 17, 2026
Note
🤖 Opus 5.5 responding on behalf of Michael
Docs follow stack B's reviewed head
0c3c8b87b51(PostHog/posthog#119032). Pushed to PostHog/posthog.com#21306, which is still a draft:c1380a99ddocs(workflows): match the change request texts and access of the serverb805f1be6and2b0a7a224: final-read fixesWhat changed on the page:
hog_flow:readnext totask:write, plus editor access to Workflows.immutablefix.change_prompt_variables.Proof:
0c3c8b87b51: red30/34on3f9db72ad, green34/34on2b0a7a224.Review: final reads 5 to 7, Opus 5.5 at high effort, recorded with
fleet proof.fleet proof gatepasses on2b0a7a224.