Skip to content

Support scoped template-type standards and admission validation #1435

Description

@randlee

ATM currently accepts a template registration without metadata.type. Each edited-and-used Jinja template registers a new immutable revision, so correcting one filename or one SHA does not prevent later untyped revisions. Oversight needs predictable query classifications without imposing a universal workflow vocabulary.

Rand requested a maintained list of standard template types and verification that registered templates carry the expected metadata. These types are situational: teams/projects/users must define their own standards without rebuilding ATM or adopting a single global enum.

Observed behavior

On the running atm 1.5.16 / HTTP API 1.7.0, atm templates list --json reported four untyped revisions. Rand supplied these source mappings (paths relative to atm-core):

SHA Source Expected type in this project's standard
5df2a8350ae80b41038852616236470b14ff39efb985da0334ff0832c0594af8 .claude/skills/codex-orchestration/review-template.xml.j2 review-task
b5cb960980db48b63b684855f7017a54e00ee1aae7a19f36a10b7011410305f6 .claude/skills/codex-orchestration/dev-template.xml.j2 dev-task
2ce7130721823ae31be2b7a13df1de1d011f3332e230c1df11734ab9e8a4d54f .claude/skills/codex-orchestration/dev-template.xml.j2 dev-task
c26bae55ef3a24f7b1577de72128ca2a372728c5ac1a7d5be72053d2024b019a .claude/skills/codex-orchestration/qa-template.xml.j2 qa-task

Inspected code: crates/atm-core/src/send/async_persistence.rs::template_admission_parts obtains type from frontmatter.metadata["type"] and warns that an absent type remains valid but untyped. Top-level name is not equivalent to metadata.type.

PR #1434 adds metadata to source/installed templates. It addresses those declarations, not configurable admission policy or historical untyped catalog records. ADR-046 already keeps workflow names generic and snapshots metadata immutably; preserve that design.

Requested capability

Rand's requested minimum is (a) configurable accepted standard template types,
(b) every newly registered template must have a type, and (c) declarations in
YAML template-header metadata. metadata.type already supplies (c); make it
required and validated rather than introducing a parallel type field. Example:

---
name: review-task
metadata:
  type: review-task
  tags: [stage:review]
  workflow:
    scope: {kind: phase, variable: phase}
    stage: review
    state: review-start
    transition: start
---

The type is mandatory; workflow/tag requirements depend on the accepted standard
for that type. Accepted names remain configurable by team/project/user context,
not a universal enum.

  • A configurable, versioned standard of template types and expected metadata scoped to a team/project (with explicit policy selection/precedence). Different teams may use different type names and requirements. No global Rust enum or hard-coded universal allowlist.
  • Policy validation for metadata.type and, where that scoped standard requires them, literal tags, workflow scope/stage/state/transition, and variable bindings. Distinguish an absent type from an unknown type and from inconsistent metadata. Generic templates still require a declared accepted type; workflow metadata may remain optional where that type does not describe a workflow.
  • A deterministic validate/audit CLI/API usable from Git hooks and template workflows: machine-readable findings, template SHA, policy/version/scope, and actionable error codes. Support both proposed template validation and auditing registered revisions, with no LLM involvement.
  • Enforcement that every newly registered/admitted template declares a nonempty type. Validate that value and any additional metadata against the applicable accepted-type standard. A missing/invalid type must fail before catalog/message mutation, with new revisions validated every time. Define behavior when registration has no team context or the same immutable template is used by teams with different policies; do not attach an implicit global meaning to a team-specific type.
  • Defined historical behavior: installing a new compliant SHA does not fix an older untyped SHA. Provide a supported owner-controlled remediation or classification mechanism if historical enforcement is required, with explicit provenance and query semantics. Do not silently rewrite immutable template/message snapshots or retroactively pretend metadata was emitted.

Acceptance cases

  1. Two teams define different valid template vocabularies without a code change; validation applies the selected scoped policy.
  2. An edited template creates a new revision and is revalidated; an untyped revision cannot bypass the mandatory-type rule through an earlier compliant registration.
  3. Missing type, unknown type, inconsistent workflow metadata, and invalid source/query results have distinct structured findings.
  4. Rejected admission leaves catalog/message state unchanged; existing history remains readable and immutable.
  5. Audit covers registered revisions and makes historical coverage gaps visible. Replacing a source template does not silently mark legacy revisions compliant.
  6. Hook callers can check type presence or a selected scoped standard without treating another team's legitimate type as invalid.

Interim consumer work: atm-monitor now maintains a local expected-type/metadata registry and read-only audit skill (atm-template-maintainence). A pre-push gate is being added to check ATM availability/liveness and block on untyped catalog revisions. It does not mutate the ATM database or replace native policy enforcement. This request supplies the supported upstream mechanism rather than embedding one project's classifications into ATM itself.

Source provenance for catalog maintenance

Rand additionally requested recording at least the source filename/path at registration. Today a catalog SHA identifies content but does not locate the producer file; maintenance must search source checkouts, installed copies, worktrees, and historical revisions to reconstruct that association.

  • Capture the source filename/path supplied to template admission and expose it through atm templates list/schema in JSON. Prefer repository-relative path plus repository identity and optional source commit when available; preserve an observed local path for installed templates where no repository context exists.
  • Keep the content SHA as revision identity. A single SHA can be registered from multiple paths or hosts: retain observed source associations rather than treating one absolute path as globally authoritative or changing the SHA for a move.
  • Distinguish recorded provenance from inferred historical mappings. Existing rows may have unknown source; do not invent one. A stored path is a locator hint and may move or disappear; content matching verifies the exact revision.
  • Acceptance: registering identical bytes from two paths retains usable provenance without duplicate content revisions; editing a file produces a new revision linked to its source; CLI/API exposes known and unknown source provenance clearly.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions