Revert "chore(assets): regen character manifest — was stale since the wardrobe landed"
This reverts commit 04241989b. The premise was wrong: the manifest is not
stale, it is AHEAD of its generator.
Both versions list the same 24 garments. What the regen dropped is the
`style` and `logo_capable` fields that T-1089 added to the manifest schema
but never taught `generate-character-manifest` to emit. So the generator
faithfully reproduces a manifest that is missing half its schema, and
`test_garment_engine_t1089.gd` catches it — which is how this was found, on
the push gate rather than in review.
`make manifest` is therefore a trap for anyone who runs it: it silently
reverts the T-1089 extension. Filed as T-1287.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -120,3 +120,38 @@ worktree refusals — none of them performed. Every assertion was mutation-check
|
||||
|
||||
Gate: `ruff check tooling/` clean, `make test-tooling` PASS (12 checks).', NULL, '2026-09-02 14:54:35', '2026-09-02 14:54:35.578', '2026-09-02 14:54:35.578', NULL, 'e0bd8f1d16b2dc7c7d1b8b1511633cc3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'status', 'backlog', 'done', NULL, '2026-09-02 14:54:37', '2026-09-02 14:54:37.762', '2026-09-02 14:54:37.762', NULL, '5f9240c61aa2bf03924e4edaf4dd6f7c', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G65N2W393K7A4B8JA8FGP22R', 'description', NULL, '`generate-character-manifest` (now `reach generate character-manifest`) emits
|
||||
only `{"slot": ...}` per clothing entry. The committed
|
||||
`client/assets/characters/manifest.json` also carries `style` and
|
||||
`logo_capable`, added to the schema by T-1089 — the generator was never taught
|
||||
to produce them.
|
||||
|
||||
So the artifact is AHEAD of its generator, and `make manifest` silently reverts
|
||||
the T-1089 extension. Confirmed on 2026-09-02: a regen produced the same 24
|
||||
garments with those two fields dropped, and `test_garment_engine_t1089.gd >
|
||||
test_manifest_has_tshirt_with_style_and_logo_flag` failed on the push gate.
|
||||
Reverted in 6024045fc.
|
||||
|
||||
This is the exact failure mode `.claude/rules/asset-pipeline.md` exists to
|
||||
prevent, one directory over: an artifact that cannot be reproduced from its
|
||||
source. The manifest is not covered by that rule (no meta stamp, not
|
||||
systems.db), which is why it drifted unnoticed.
|
||||
|
||||
WHAT TO DECIDE FIRST — where do `style` and `logo_capable` come from? They are
|
||||
not derivable from a filename. Either:
|
||||
(a) a sidecar the generator reads (e.g. the clothing `coverage.json` already
|
||||
beside the assets, or per-garment metadata), or
|
||||
(b) the manifest is genuinely hand-maintained, in which case the generator
|
||||
should MERGE rather than overwrite, and say so.
|
||||
|
||||
(a) is the asset-pipeline-consistent answer. (b) needs the generator to stop
|
||||
claiming to be the source of truth.
|
||||
|
||||
ALSO: `test_garment_engine_t1089.gd:108` reports `Expecting ''modern'' but was
|
||||
''modern''` — the strings print identically, so the assertion is comparing
|
||||
something other than what it displays (String vs StringName, or a trailing
|
||||
character). Worth a look while in there; a failure message that shows two
|
||||
identical values costs whoever hits it real time.
|
||||
|
||||
Acceptance: `reach generate character-manifest` on a clean tree leaves
|
||||
manifest.json byte-identical, and the T-1089 test still passes after it runs.', NULL, '2026-09-02 15:54:41', '2026-09-02 15:54:41.911', '2026-09-02 15:54:41.911', NULL, '1a36359b2986139da3157d2429351f74', 2) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G63FEA51J4JKE3A7473D3QZ0', 'T-1284', '2026-09-02 10:50:23.145', '2026-09-02 10:50:23.145', NULL, '74113524e3a280bd06875305a547349a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G642RKW8PNW7AP9BY9203SPG', 'T-1285', '2026-09-02 12:14:48.290', '2026-09-02 12:14:48.290', NULL, '020f491d1ae8fbde83d2aae0f8325011', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G64ASTXBBHMWMBQSVPM9MK1W', 'T-1286', '2026-09-02 12:49:55.434', '2026-09-02 12:49:55.434', NULL, '7c65442cc261176c9c472fdbd635cc91', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G65N2W393K7A4B8JA8FGP22R', 'T-1287', '2026-09-02 15:54:39.514', '2026-09-02 15:54:39.514', NULL, 'de690eafa611669d722b0ffb850a1d7b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||
|
||||
@@ -229,3 +229,39 @@ worktree refusals — none of them performed. Every assertion was mutation-check
|
||||
unrecognised verdict and blocked the push.
|
||||
|
||||
Gate: `ruff check tooling/` clean, `make test-tooling` PASS (12 checks).', 'done', 'medium', NULL, NULL, 'D-263', '2026-09-02 12:49:55.434', '2026-09-02 14:54:37.762', NULL, '678c0d0578c2255438d2e51829d87a64', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G65N2W393K7A4B8JA8FGP22R', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'make manifest silently drops the T-1089 garment schema fields', NULL, 'backlog', 'medium', NULL, 'client', NULL, '2026-09-02 15:54:39.514', '2026-09-02 15:54:39.514', NULL, 'ddb9c65aa4c4537924de591c4c017051', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06G65N2W393K7A4B8JA8FGP22R', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'make manifest silently drops the T-1089 garment schema fields', '`generate-character-manifest` (now `reach generate character-manifest`) emits
|
||||
only `{"slot": ...}` per clothing entry. The committed
|
||||
`client/assets/characters/manifest.json` also carries `style` and
|
||||
`logo_capable`, added to the schema by T-1089 — the generator was never taught
|
||||
to produce them.
|
||||
|
||||
So the artifact is AHEAD of its generator, and `make manifest` silently reverts
|
||||
the T-1089 extension. Confirmed on 2026-09-02: a regen produced the same 24
|
||||
garments with those two fields dropped, and `test_garment_engine_t1089.gd >
|
||||
test_manifest_has_tshirt_with_style_and_logo_flag` failed on the push gate.
|
||||
Reverted in 6024045fc.
|
||||
|
||||
This is the exact failure mode `.claude/rules/asset-pipeline.md` exists to
|
||||
prevent, one directory over: an artifact that cannot be reproduced from its
|
||||
source. The manifest is not covered by that rule (no meta stamp, not
|
||||
systems.db), which is why it drifted unnoticed.
|
||||
|
||||
WHAT TO DECIDE FIRST — where do `style` and `logo_capable` come from? They are
|
||||
not derivable from a filename. Either:
|
||||
(a) a sidecar the generator reads (e.g. the clothing `coverage.json` already
|
||||
beside the assets, or per-garment metadata), or
|
||||
(b) the manifest is genuinely hand-maintained, in which case the generator
|
||||
should MERGE rather than overwrite, and say so.
|
||||
|
||||
(a) is the asset-pipeline-consistent answer. (b) needs the generator to stop
|
||||
claiming to be the source of truth.
|
||||
|
||||
ALSO: `test_garment_engine_t1089.gd:108` reports `Expecting ''modern'' but was
|
||||
''modern''` — the strings print identically, so the assertion is comparing
|
||||
something other than what it displays (String vs StringName, or a trailing
|
||||
character). Worth a look while in there; a failure message that shows two
|
||||
identical values costs whoever hits it real time.
|
||||
|
||||
Acceptance: `reach generate character-manifest` on a clean tree leaves
|
||||
manifest.json byte-identical, and the T-1089 test still passes after it runs.', 'backlog', 'medium', NULL, 'client', NULL, '2026-09-02 15:54:39.514', '2026-09-02 15:54:41.911', NULL, '2f6393f44525977bfeba1200e8f79561', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||
|
||||
Reference in New Issue
Block a user