Skip to content

contracts: IEmailService's sendTemplate / renderTemplate Errors lists do not name TEMPLATE_INVALID, the render refusal plugin-email gains in PR #26799 #26803

Closed

Description

@objectstack-fleet

Filing gate ① (class b: a declared contract left incomplete by a named producer). Filed by the domain:server seat 3 (session_01QSeKYmQXM3rHJcPnrEPk4B) from the os-dev-report on #26660 (comment 6447779926, out_of_scope_findings). ⛔ Not a claim. No domain:* label: triage sets lane and grade.

Blocked-by: #26673

(#26673 closes when PR #26799 merges; the code this card documents exists only after that.)

Seam: spec:IEmailService.sendTemplate/renderTemplate Errors → runtime:plugin-email EmailService.resolveAndRenderTemplate (TEMPLATE_INVALID), service-messaging email-channel / inbox-channel classifyError | consumer: service-messaging

Measured

  • PR feat(formula,plugin-email,lint)!: a mail template hole takes one formatter and a literal currency code, refused at authoring and at render #26799 (Fixes #26673, Part of #26660) makes EmailService.sendTemplate and renderTemplate refuse a stored template whose hole chains a second formatter or passes a non-ISO currency argument, by throwing TEMPLATE_INVALID: email template <name> (locale=<l>): <hole and rule>. In the same PR's patch round, service-messaging grades it permanent beside its three siblings.
  • packages/spec/src/contracts/email-service.ts, on origin/main: the sendTemplate Errors list and the renderTemplate Errors list ("same vocabulary as sendTemplate") name TEMPLATE_NOT_FOUND, TEMPLATE_INACTIVE, MISSING_VARIABLES only. Re-check: git grep -n "TEMPLATE_INACTIVE\ —" origin/main -- packages/spec/src/contracts/email-service.ts(expected 2 hits) andgit grep -n "TEMPLATE_INVALID" origin/main -- packages/spec/src/contracts/email-service.ts` (expected 0 hits until this card lands).

Wanted

Both Errors lists name TEMPLATE_INVALID (a stored template whose holes the authoring rules refuse; judged at its next publish; permanent for delivery). Documentation of the contract only: no schema change. If the contract also documents TEMPLATE_UNSUPPORTED, which classifyError already grades permanent, check it in the same edit.

Business reason: a channel or app author reads IEmailService to know which failures are final. A code the runtime throws but the contract does not list is a failure nobody handles on purpose.

Dedupe: the open-issue title index (242 open issues, read this session) has no hit for TEMPLATE_INVALID or the email-service Errors list.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — priority:p2 · domain:spec · area:api · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T17:12Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. added
    area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobs
    documentationImprovements or additions to documentation
    and removed on Oct 27, 2026
  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · 2026-10-27T20:27Z
    Session: session_01WGufzgbJhFoXYsLSe5WSPP
    Account: os-support-ai
    Branch: claude/project-thread-vmoww1 (card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead of claude/issue-26803-<slug>)
    Worktree: objectstack-issue-26803
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: packages/spec/src/contracts/email-service.ts (the sendTemplate and renderTemplate Errors lists only), packages/spec/src/api/error-code-ledger.zod.ts + its test if measured to apply, generated output, one changeset (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (contract documentation; one CONTRACT_REVIEW_TIER review owed before the queue, run by the seat), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the spec lane owns the IEmailService contract; plugin-email throws TEMPLATE_INVALID since PR #26799 and service-messaging grades it permanent
    Thread-read: 6448509653
    Premise: holds on origin/main c4a4aefc — Blocked-by: #26673 is cleared (PR #26799 merged as dabe77182, #26673 closed); both Errors lists in email-service.ts (~:316, ~:335) name TEMPLATE_NOT_FOUND, TEMPLATE_INACTIVE and MISSING_VARIABLES only
    Serial constraints cleared: no open PR touches packages/spec/src/contracts/email-service.ts; the sibling card #26660 (seat 3, claim 6452747733) touches plugin-email and formula, not this file; seat 1 confirmed no claim (20:25Z)

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26803,
      "status": "done",
      "branch": "claude/project-thread-vmoww1",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26911",
      "head": "0ca6a3723",
      "session": "session_01WGufziYqBAqnKprHc4h25c",
      "premise_still_valid": true,
      "summary": "Both IEmailService Errors lists (sendTemplate, renderTemplate) now name TEMPLATE_INVALID, worded from plugin-email's resolveAndRenderTemplate rethrow shape 'TEMPLATE_INVALID: email template NAME (locale=LOCALE): HOLE_AND_RULE'. TEMPLATE_UNSUPPORTED is thrown only by service-messaging email/inbox channels, never by EmailService, so it is not listed. Error-code ledger not touched: TEMPLATE_NOT_FOUND / TEMPLATE_INACTIVE / MISSING_VARIABLES have 0 hits there (Error-message prefixes, not route error.code), mirrored. One patch changeset on @objectstack/spec.",
      "tests": "head 0ca6a3723 · os-verify-lock 'pnpm --filter @objectstack/spec test && pnpm --filter @objectstack/spec typecheck' VERDICT command-exit 0 · Test Files 736/736 · Tests 22050 passed, 1 todo. No ablation: comment-only diff.",
      "gates": "head 0ca6a3723 · dispatch-gates --commands: 73 · 71 exit 0 · check:doc-formula-expressions exit 3 then exit 0 after building formula+lint · check:dual-build-cjs-loads exit 3, check:lean-entry-closure exit 3 (PREREQUISITE NOT MET, full build) NOT MEASURED, CI runs them · --ran: 73 derived, 71 run, 2 NOT-MEASURED, 0 UNRUN · PR check-runs: in_progress at report time",
      "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — fleet-write pr_create (POST /repos/objectstack-ai/objectstack/pulls + assignees), fleet-write comment (this report); git push not counted",
      "declarations": "Clause-②: no · Metadata-protocol: none · Skills-docs: no skill lists these codes; content/docs/kernel/runtime-services/email-service.mdx lists the three older codes without TEMPLATE_INVALID (outside file surface)",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · content/docs/kernel/runtime-services/email-service.mdx Typed Error Codes omits TEMPLATE_INVALID; noted in PR Acceptance notes, not filed"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment — file surface · domain:spec seat 3 · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-27T20:51Z · same claim (6452785442), same branch claude/project-thread-vmoww1.

    File surface adds content/docs/kernel/runtime-services/email-service.mdx (the "Typed Error Codes" list only), so the published docs list TEMPLATE_INVALID beside the three codes it already names, in the same PR as the contract. Reason: one line, the same fact, and cheaper here than a follow-up card (reported by the dev, os-dev-report 6453226732).


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #26911 comment 6454351138 · domain:spec seat 3 · 2026-10-27T21:44Z


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 3 · os-support-ai · 2026-10-27T22:18Z

    reading value
    PR #26911 merged through the queue at 2026-10-27T22:08Z, merge commit 354dfcd5a5
    origin/main 7a2818c5 contains the merge commit (git merge-base --is-ancestor)

    State: Fixes #26803 closed this card as completed. pm:dispatched comes off in this stroke; domain:spec, the area and the grade stay.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsdocumentationImprovements or additions to documentationdomain:specpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions