Skip to content

feat(writ): writ's templates end in .tmpl, and .template is left to other tools - #979

Merged
David-Noble-at-work merged 3 commits into
developfrom
feature/974-writ-s-templates-end-in-tmpl
Sep 29, 2026
Merged

David-Noble-at-work merged 3 commits into
developfrom
feature/974-writ-s-templates-end-in-tmpl

Conversation

@David-Noble-at-work

@David-Noble-at-work David-Noble-at-work commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Lane 11 of #949. Ruled 2026-09-29: "Let's do as you propose. .tmpl for writ templates."

  • The suffix — writ renders .tmpl (and .tmpl.sops: decrypt, then render) and links a .template file untouched. pkg/sops finds a document's format past .tmpl.
  • Why — personal's New-LocationConfig fills certificate-request.conf.template with envsubst; writ rendered it into certificate-request.conf, so the script never found it. With this change it deploys as a link under its own name. .tmpl is chezmoi's suffix for writ's behavior; the nginx image's envsubst over *.template is the precedent for leaving .template to other tools.
  • No migration — no layer holds a writ template; the certificate request was the only .template in any layer.
  • Tests — the unit, integration and scenario fixtures say .tmpl; a new row pins foo.template → a link.
  • The writ guide — Templates: the data writ provides, and variables from writ.vars (lower case), from the environment and the command line per the configuration spec, from the file only today (writ's template variables come only from the configuration file: writ.vars is read as a whole map, which the environment never reaches, and no flag sets one #975). Secrets: .sops, not the retired .age, with a table of where sops finds age keys on Linux, macOS and Windows and the variables that add keys. The dead link to the deleted secrets guide is gone from the index and getting-started; "each file becomes a symlink" names its exceptions.
  • Plan — docs/plans/feature/974-writ-s-templates-end-in-tmpl.md. It stays active: its last box, converging DANOBLE-UD24-1 once the pre-release carries this change, can only close after the merge.

Filed on the way: #975, #977 (reproduced by running), #978.

Resolves #974
Resolves David-Noble-at-work/personal#237

Test plan

  • gofmt -l empty; make test (104 packages) and make test-race pass
  • Every ci.yaml gate step: build for every platform, go.mod tidy, make regenerate with no diff, guide frontmatter, vet-all, star lint go, lint-all, star lint shell, the PowerShell gate, make test-scenario
  • Live, this branch's writ in scratch XDG homes with the Home target aimed at scratch: a.conf.tmpl deploys as a rendered copy a.conf; b.conf.template deploys as a link, byte for byte; the host's configuration, layers and home untouched
  • Adversarial review in three lenses: nothing missed in code or tests; four faults in the new guide text, fixed
  • After the pre-release: DANOBLE-UD24-1 deploys the certificate template as a link, the rendered copy is removed, and the deployed New-LocationConfig fills a request

Time

Marker UTC Elapsed
opened (first commit) 2026-09-29T05:14:44Z —
submitted (PR opened) 2026-09-29T15:36:17Z 10.4 h after opened
merged 2026-09-29T15:52:18Z 0.3 h after submitted; 10.6 h in all

Computed by the algorithm of noblefactor-ops#188 at merge.

writ claims every file ending in .template, so personal's envsubst template
for New-LocationConfig is rendered into a copy and the script never finds
it (personal#237). Ruled 2026-09-29: writ's templates end in .tmpl, and
.template is left to other tools.

Claude-Session: https://claude.ai/code/session_01DuNfZFyfxBoD9pdaiDEMrY
…ther tools

writ claimed every file ending in .template: it rendered the file as a Go
template and deployed a copy without the suffix. .template is a generic word
that other tools use for their own templates. personal's New-LocationConfig
fills certificate-request.conf.template with envsubst, and writ rendered it
into certificate-request.conf, so the script never found its file. Ruled
2026-09-29: writ's templates end in .tmpl, chezmoi's suffix for exactly this
behavior, and .template is left to other tools, as the nginx image's envsubst
leaves it.

- The rule (tree.ProcessingPipeline) renders .tmpl and .tmpl.sops, and a
  .template file is linked like any other. pkg/sops finds a document's
  format past .tmpl.
- The tests and the scenario fixture say .tmpl, and a new row pins that
  foo.template deploys as a link. No layer holds a writ template, so no
  layer file is renamed.
- The writ guide's Templates section lists the data writ provides, and says
  variables come from writ.vars, in lower case, and, per the configuration
  spec, from the environment and the command line; writ reads only the file
  today (#975). Its Secrets section describes .sops, not the retired .age,
  with a table of where sops finds age keys on Linux, macOS and Windows and
  the variables that add keys. A dead link to the deleted secrets guide goes
  from the index and from getting-started, and "each file becomes a symlink"
  now names its exceptions.

Found on the way and filed: #975 (template variables come only from the
configuration file), #977 (a secret with no format before .sops deploys as a
JSON wrapper, reproduced by running), #978 (the encryption design's key path
is Linux's only).

Resolves #974
Resolves David-Noble-at-work/personal#237

Claude-Session: https://claude.ai/code/session_01DuNfZFyfxBoD9pdaiDEMrY
@David-Noble-at-work
David-Noble-at-work merged commit e265344 into develop Sep 29, 2026
13 checks passed
@David-Noble-at-work
David-Noble-at-work deleted the feature/974-writ-s-templates-end-in-tmpl branch September 29, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

writ's templates end in .tmpl: .template is a generic word other tools use, and writ renders their files

1 participant