Summary
Once a feature is enabled, the host owns a copy of its files (e.g. scripts/agent-comms/ask.sh). There is no mechanism to deliver later changes made to the feature source (features/<name>/) to hosts that already installed it — today the only path is disable-feature.sh + enable-feature.sh (destructive re-copy). This is structural: it applies to every feature, so it belongs one level up (the sync tooling), not inside any feature.
Design reference: RFC #13, Etapa 3
The closed RFC already designed this: "Teach update-from-template.sh about features. Read .features-enabled, sync features/<name>/code/ into scripts/<name>/ for each enabled feature" — making the existing sync channel feature-aware. docs/adding-a-feature.md records the gap as known ("Etapa 3: update-from-template.sh does not yet read .features-enabled..."). This issue is the tracking item that was missing since the RFC closed with Etapa 1.
Motivating case
PR #82 improves features/agent-comms/code/ask.sh (SCHEMA-grounded preamble). Every host that already enabled agent-comms keeps the old behavior indefinitely unless it does the disable+enable dance — which also churns .github/workflows/, CLAUDE.md markers, and any local edits.
Design notes for the implementer
Summary
Once a feature is enabled, the host owns a copy of its files (e.g.
scripts/agent-comms/ask.sh). There is no mechanism to deliver later changes made to the feature source (features/<name>/) to hosts that already installed it — today the only path isdisable-feature.sh+enable-feature.sh(destructive re-copy). This is structural: it applies to every feature, so it belongs one level up (the sync tooling), not inside any feature.Design reference: RFC #13, Etapa 3
The closed RFC already designed this: "Teach
update-from-template.shabout features. Read.features-enabled, syncfeatures/<name>/code/intoscripts/<name>/for each enabled feature" — making the existing sync channel feature-aware.docs/adding-a-feature.mdrecords the gap as known ("Etapa 3: update-from-template.sh does not yet read .features-enabled..."). This issue is the tracking item that was missing since the RFC closed with Etapa 1.Motivating case
PR #82 improves
features/agent-comms/code/ask.sh(SCHEMA-grounded preamble). Every host that already enabled agent-comms keeps the old behavior indefinitely unless it does the disable+enable dance — which also churns.github/workflows/,CLAUDE.mdmarkers, and any local edits.Design notes for the implementer
install_featurerefuses to overwrite existing destinations (install_feature silently overwrites (and disable_feature then deletes) a pre-existing host CI workflow of the same name #68/PR fix(install-feature): refuse to overwrite a pre-existing host CI workflow #70) — correct for installation. Update is the legitimate overwrite case (the host file came from the feature; the template has a newer version). The update path needs the main sync loop's semantics — hash-compare, overwrite when host-unmodified, flag when host-modified — not install's refuse guard.feature.jsonalready carries aversionfield, unused today; a version stamp in.features-enabled(or a per-feature lockfile) may be the cheapest change-detection.