docs(extra_json): policy doc for containers.extra_json evolution

New CODEMAPS/container-extra-json.md documents the contract every
source plugin must follow when reading or writing containers.extra_json.
Closes the open architectural question that was tracked in
WORKLOAD_REFACTOR_TODO.md.

Covers:
- Schema position (column default, four write-path normalization
  sites) and ownership model (per-source row keys, current writers).
- Reader rules: tolerate unknown keys via default json.Unmarshal,
  tolerate decode failure where first-class columns suffice.
- Writer patterns: wholesale-overwrite (image source, single-writer
  short-lived rows) vs preserve-unknown-keys (static source, RMW with
  generic-map round-trip). Preserve-unknown-keys is the recommended
  default for new sources.
- Concurrency: SetMaxOpenConns(1) + WAL gives atomic per-row writes
  and consistent reader snapshots, but does NOT serialize multi-
  goroutine RMW — a per-workload sync.Mutex is required for that
  (fenced by TestSaveState_ConcurrentWritesDoNotLoseUpdates).
- What extra_json is NOT for (workload config, cross-source state,
  queryable data, secrets) and a checklist for adding a new field.
- Pointers to every example in tree: image's containerExtra writer/
  reader, static's saveState round-trip, workload_runtime.go's
  decode-and-tolerate consumer.

WORKLOAD_REFACTOR_TODO Container.extra_json question flipped to DONE.
CODEMAPS/INDEX bumped + entry linked.

Reviewer pass (code-reviewer subagent) caught one HIGH factual error
(wrong cross-source consumer claim) and several MEDIUM/LOW drifts;
all addressed inline before commit.
This commit is contained in:
2026-05-16 22:00:41 +03:00
parent ea55d31177
commit 279f373f80
3 changed files with 115 additions and 7 deletions
+8 -6
View File
@@ -500,13 +500,15 @@ covers the use case — `promote-from` works, the UI shows the relationship.
Probably can leave the legacy `stages` table dropped entirely once cutover
proceeds.
### `Container.extra_json` evolution
### ~~`Container.extra_json` evolution~~ — DONE (2026-05-16)
Currently only the image source uses it (per-face proxy route IDs). If
other sources gain similar needs (compose service health metadata, static
build SHAs), the schema there should stay versionless and additive — every
reader must tolerate unknown keys. Document this in the source plugin
guide alongside the codemap entry.
Both writer patterns now have an active example in-tree (image source
clobbers, static source preserves) and the policy is documented in
[`docs/CODEMAPS/container-extra-json.md`](CODEMAPS/container-extra-json.md):
ownership model, wholesale-overwrite vs preserve-unknown-keys, reader
tolerance for unknown keys + decode failure, the per-workload mutex
requirement for any read-modify-write writer, and a checklist for adding
a new field without breaking older deployers.
## File pointers for the next session