feat: MPS-24 — manual tags are ghost metadata; hide behind a flag

Operator direction: stop hand-attaching tags ('ghost metadata'
invisible to the humans and agents reading the page). Derive tags
from title + description (auto-hydrate + suggest engine) instead.

- New MPS-22-style kill switch: app.features.manual_tags.enabled
  (request.manual_tags_enabled, DEFAULT FALSE, env
  MPS_FEATURES_MANUAL_TAGS_ENABLED, =True in test.ini so the existing
  tag suite keeps passing).
- product_edit.j2: hides the chip editor + comma tags field +
  product_tags.js; shows a 'tags are derived from your title &
  description' note (lists current auto-derived tags read-only).
- shop_tags.j2: hides 'Create a tag' + the per-product apply (focus)
  section; shows a 'How tags work' note. Suggest categories + the
  category overview stay (the blessed linguistic path).
- Endpoints remain functional -> flipping the flag On is instant and
  lossless ('until further notice').
- CLAUDE.md: 'Tag Philosophy' section + manual_tags row in the
  kill-switch matrix. mps-24.md Phase 2.8o.
- Tests: TestManualTagsKillSwitch (fresh app, flag False; mirrors
  TestKillSwitches). 1147 passed; existing tag suite green under
  test.ini (flag True).
This commit is contained in:
russell@unturf.com 2026-05-17 12:08:55 -04:00
parent d6ae00073f
commit 3467909b80
No known key found for this signature in database
7 changed files with 203 additions and 8 deletions

View file

@ -720,6 +720,27 @@ in `~/git/foxhop-pillar/uwsgi/makepostsell/init.sls` for prod). Pattern mirrors
| `app.features.popout_player.enabled` | `request.popout_player_enabled` | True | Working |
| `app.features.karaoke.enabled` | `request.karaoke_enabled` | **False** | Broken (MPS-18) |
| `app.features.torrent.enabled` | `request.torrent_enabled` | **False** | Broken (MPS-19) |
| `app.features.manual_tags.enabled` | `request.manual_tags_enabled` | **False** | Intentional — manual tags are ghost metadata (MPS-24) |
## Tag Philosophy (MPS-24) — derive, don't hand-attach
**Manual tags are "ghost metadata"** — operator-attached labels that
are invisible to the humans and agents actually reading the page, and
that drift out of sync with the words that matter. The blessed model:
**tags are derived linguistically from the title + description** so
humans and agents consume the same signal.
- New products / edited title or description → `auto_hydrate_tags`
files the product into the shop's **existing** categories by content
(additive, idempotent, never creates).
- Growing the category set → the **suggest** engine reads titles +
descriptions and proposes groupings the operator approves.
- `request.manual_tags_enabled` (default **False**) hides the manual
add/apply UI on the product edit page and the bulk tagger; the
Suggest panel and the category overview stay. Flip
`MPS_FEATURES_MANUAL_TAGS_ENABLED=True` to restore manual tagging
"until further notice". Endpoints (`/p/{id}/tags`, bulk create/apply)
remain functional so the flip is instant and lossless.
When a flag is off:
1. Templates wrap UI in `{% if request.X_enabled %}` — section hidden