Repro
-
Bootstrap a project with a template that has `when = "once"` on some file:
```toml
template.toml
[[file]]
src = "foo.template"
dst = "foo"
how = "overwrite"
when = "once"
```
-
`kata apply` — `applied.toml` records `[files."foo"]` with `once_applied = true`.
-
Upstream template bumps to a new version that changes `when = "always"`. Bump consumer's `applied.toml` rev (via `kata update`) and re-apply.
-
`kata apply` correctly does re-write the file (good — `when = "always"` is honoured).
-
`applied.toml` ends up with both `once_applied = true` (carried over from step 2) and a fresh `content_hash` from the new write.
Observed
```toml
[files.".github/workflows/release.yml"]
content_hash = "be9919b6b6ba63d777c5c960c667bcb57390f5e6e7a4b5b7eb11103f3216c2a6"
once_applied = true
```
Both markers present. Functionally harmless — verified that subsequent `kata apply`s still re-apply correctly when the upstream template changes (kata picks the right code path based on the current template's `when`, not the stale `once_applied`). But:
- It's misleading on review (code reviewers, including LLM-driven ones, read it as "this file is pinned, future applies will be skipped").
- Once a human edits `applied.toml` to remove the line (or starts from a clean apply), kata never re-adds `once_applied` — verified by `kata apply` on a state with only `content_hash`; the marker stays absent. So kata clearly considers it stale, just doesn't clean it up proactively when the template flips.
Hit in the wild
`yukimemi/pj-rust-workspace` shipped `release.yml.template` at `when = "once"` in v0.2.0 and bumped to `when = "always"` in v0.3.0. Every consumer (kanade, kotonoha, …) that applied v0.2.0 now carries the stale marker. yukimemi/kanade#106 (comment) has the review thread where this surfaced; PR landed with the marker removed manually.
Suggested behaviour
On `kata apply`, after writing a file whose template-side `when = "always"`, also strip any stale `once_applied = true` from that file's `applied.toml` entry. (Effectively: rebuild the entry's metadata to only what `when` currently warrants — `content_hash` for "always", `once_applied` for "once", not both.)
Alternative: log a one-line warning whenever `applied.toml` carries metadata that doesn't match the current template's `when`, so the operator knows to clean up.
Repro
Bootstrap a project with a template that has `when = "once"` on some file:
```toml
template.toml
[[file]]
src = "foo.template"
dst = "foo"
how = "overwrite"
when = "once"
```
`kata apply` — `applied.toml` records `[files."foo"]` with `once_applied = true`.
Upstream template bumps to a new version that changes `when = "always"`. Bump consumer's `applied.toml` rev (via `kata update`) and re-apply.
`kata apply` correctly does re-write the file (good — `when = "always"` is honoured).
`applied.toml` ends up with both `once_applied = true` (carried over from step 2) and a fresh `content_hash` from the new write.
Observed
```toml
[files.".github/workflows/release.yml"]
content_hash = "be9919b6b6ba63d777c5c960c667bcb57390f5e6e7a4b5b7eb11103f3216c2a6"
once_applied = true
```
Both markers present. Functionally harmless — verified that subsequent `kata apply`s still re-apply correctly when the upstream template changes (kata picks the right code path based on the current template's `when`, not the stale `once_applied`). But:
Hit in the wild
`yukimemi/pj-rust-workspace` shipped `release.yml.template` at `when = "once"` in v0.2.0 and bumped to `when = "always"` in v0.3.0. Every consumer (kanade, kotonoha, …) that applied v0.2.0 now carries the stale marker. yukimemi/kanade#106 (comment) has the review thread where this surfaced; PR landed with the marker removed manually.
Suggested behaviour
On `kata apply`, after writing a file whose template-side `when = "always"`, also strip any stale `once_applied = true` from that file's `applied.toml` entry. (Effectively: rebuild the entry's metadata to only what `when` currently warrants — `content_hash` for "always", `once_applied` for "once", not both.)
Alternative: log a one-line warning whenever `applied.toml` carries metadata that doesn't match the current template's `when`, so the operator knows to clean up.