File-Derived Timestamps for Runes
Expose file-level created and modified timestamps as Markdoc variables so any rune can consume them as attribute defaults, with explicit attribute values taking precedence.
Expose file-level created and modified timestamps as Markdoc variables so any rune can consume them as attribute defaults, with explicit attribute values taking precedence.
Plan runes (and potentially other runes) benefit from knowing when content was created and last modified. The plan-activity rune already derives mtime from git via a standalone scanner (runes/plan/src/scanner.ts), but this is package-specific, runs outside the content pipeline, and only provides modification time — not creation time.
There is no general-purpose mechanism for runes to access file timestamps. Authors who want timestamps must manually maintain them in frontmatter, which is tedious and error-prone.
Inject two new variables into every page's Markdoc transform config:
| Variable | Type | Description |
|---|---|---|
$file.created | string (ISO 8601 date) | When the file was first committed |
$file.modified | string (ISO 8601 date) | When the file was last committed |
These join the existing $page and $frontmatter variables already injected in packages/content/src/site.ts.
A three-tier fallback chain, consistent with the approach already proven in the plan scanner:
created or modified appear in frontmatter, use those values directly. This gives authors full control.git log. This is the expected default for any content in a repository.fs.stat().birthtimeMs / fs.stat().mtimeMs. Only meaningful for local-only content that has never been committed.When none of the above produce a value, the variable is undefined and runes that consume it should handle the absence gracefully (e.g., omit a date display).
Runes opt in by declaring created and/or modified attributes with variable defaults:
{% spec id="SPEC-001" created=$file.created modified=$file.modified %}