worldbox-observer-mod/docs/event-catalog-discovery.md
DazedAnon 2592e947aa feat(saga): make Legacy turning points, not child soup
- Cap ParentChild, skip Cast-echo kin, and summarize large lineages
- Prefer war/bond/role beats with dated prose over raw "Child X" lines
- Gate with saga_legacy_quality (3/3) and document the Legacy contract
2026-07-22 15:03:31 -05:00

246 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Event catalog discovery
Live gap map of AssetManager libraries, mutation hooks, and IdleSpectator event-catalog coverage.
Expansion of [`event-catalog.json`](../IdleSpectator/event-catalog.json) should cite this ledger, not guessed id lists.
Audit date: 2026-07-17.
WorldBox harness refresh: `mutation_discovery`, `domain_event_audit`, `activity_happiness_audit`, `activity_status_audit`, `world_log_audit`, `disaster_war_audit`, `activity_taxonomy_audit` (all PASS).
Artifacts: `IdleSpectator/.harness/` (especially `mutation_*.tsv`, `domain_event_audit.tsv`).
Machine worksheet: [`event-catalog-discovery.tsv`](event-catalog-discovery.tsv).
## Verdict
**Id inventory is complete for every EventCatalog domain.**
Authored 1:1 libraries match live counts with zero missing/orphan ids.
Live+dial libraries are fully seeded.
`mutation_gaps.tsv` is empty (`gaps=0`).
Id inventory and interesting Layer A policy are in good shape as of **0.28.27** (`camera_a_inventory`: **219 A / 924 B** on library+decision domains; decisions **37** camera with phrases).
Remaining feel of thin tips is mostly **soak share / strength vs filler**, not missing catalog rows:
1. Library Labels use display names (Wave 1); keep watching for weak verbs.
2. Ambient CI stays false; Signal predicates own library A (expanded 0.28.27).
3. Building civ complete / wonder A is wired.
4. Meta-trait domains are fail-gated by `domain_event_audit` + `camera_a_inventory_ok`.
Tips here means watch tip / orange reason Labels from interest feeds, not dossier chip hover tooltips.
## How to read priorities
| Priority | Meaning |
|----------|---------|
| P0 | Missing wire or authored sync that drops a real lifecycle beat |
| P1 | Tip/prose quality for already-seeded high-visibility classes |
| P2 | New surfaces or Signal tuning after P0/P1 |
| P3 | Intentional Layer B / covered-by another feed |
## Authored 1:1 domains
Live audits: `missingAuthored=0` / `orphan=0` for all closed libraries.
| Domain | Live | Authored | Catalog mode | Camera policy (approx) | Priority |
|--------|-----:|---------:|--------------|------------------------|----------|
| happiness | 67 | 67 | authored | Signal 49 / Aggregate 13 / Ambient 5 | P3 sync done |
| status | 58 | 58 | authored | CreatesInterest 42; B FX 16 | P3 sync done |
| worldLog | 41 | 41 | authored | CreatesInterest 40 (`auto_tester` B) | P3 sync done |
| plots | 28 | 28 | authored | all A | P3 sync done |
| eras | 11 | 11 | authored | all A | P3 sync done |
| books | 12 | 12 | authored | all A | P3 sync done |
| traits | 116 | 116 | authored | all A | P3 sync done |
| disasters | 17 | 17 | authored | via WorldLog pairs | P3 sync done |
| warTypes | 5 | 5 | authored | dials | P3 sync done |
| relationship | n/a | 11 | authored discrete | all A | P3 sync done |
Happiness Ambient (stay B): `got_poked`, `got_caught`, `paid_tax`, `just_ate`, `just_pooped`.
Status B: recovery_*, egg gain, spell_silence/boost, on_guard, just_ate, afterglow, slowness, cough, shield, dodge, dash, flicked.
## Live + dial domains
Seeded via `LiveLibraryInterest.EnsureSeeded` + JSON `libraries.*` dials.
`authored=1` in `domain_event_audit.tsv` means live-seeded entry exists, not a per-id JSON prose row.
| Domain | Live | Camera A | Dial label template | Notes | Priority |
|--------|-----:|---------:|---------------------|-------|----------|
| decisions | 127 | **16** politics/spectacle | `{a} decides to {action}` | Soft pack/fireworks/asexual/steal demoted B; fluff + intent-genesis B | noise pass 0.28.41 |
| spells | 12 | 6 | `{a} casts {id}` | Signal spectacle only; FX spells B | P3 |
| powers | 339 | **41** | `God power: {id}` | ambient CI=false; widened spectacle + creature powers; UI `_edit` B | P3 expanded 0.28.27 |
| items | 111 | **20** mythril/adamantine | `{a} gains {id}` | steel/silver/bone demoted B | noise pass 0.28.41 |
| genes | 47 | **0** | `{a} gains gene {id}` | all B (gain/remove tips not camera-worthy) | demoted |
| phenotypes | 52 | 0 | `{a} shows {id}` | all B | P3 |
| world_laws | 49 | **7** crisis | `Law changed: {id}` | hunger/army/expansion/UI toggles B | noise pass 0.28.41 |
| subspecies_traits | 204 | **21** | `{a} evolves {id}` | dramatic + mutation/death/blood/horror | P3 expanded 0.28.27 |
| biomes | 29 | 0 | `Biome shifts: {id}` | ambient CI=false | P3 stay B |
| culture_traits | 78 | **8** politics | `{a} culture gains {id}` | lovers/layout/craft B; conscript/xenophobe/expansion A | noise pass 0.28.41 |
| religion_traits | 40 | 6 | `{a} faith gains {id}` | dramatic heuristic | P3 |
| clan_traits | 29 | **0** | `{a} clan gains {id}` | all B (blood/vein soak) | noise pass 0.28.41 |
| language_traits | 26 | **0** | `{a} tongue gains {id}` | all B | noise pass 0.28.41 |
**Library+decision Layer A inventory (0.28.41):** live dump total **125 A / 1018 B** across 13 domains (`camera_a_inventory_ok`). Decisions **16 A**.
### Decision camera classes (0.28.41)
Allow-token Signal after fluff + intent-genesis + soft-noise filter (not 127 ambient).
Authored action phrases required for every A id (`domain_event_audit` decision_prose).
Classes: sexual reproduction / lover / child, army/war/politics, spectacle/dark (`golden_brain`, `make_skeleton`, `soul_harvest`, `possessed`), hive (`create_hive`).
Stay B (soft noise 0.28.41): `family_group`, `fireworks`, `affect_dreams`, `put_out_fire`, `burn_tumors`, `asexual_reproduction`, steal/take city item, `warrior_army_follow_leader`, `warrior_try_join_army_group`.
Stay B (intent-only; camera on outcome feeds): `try_new_plot*`, `try_to_start_new_civilization*`, `build_civ_city*`, `*city_foundation*`, `claim_land*` → real tips from `PlotInterestFeed` / `MetaEventPatches` (`new_city` 86, `new_kingdom` 92).
Also stay B: diet/sleep/random/check ticks, `warrior_train_with_dummy`, boat trade/fish, house/job/tax chores.
Spell Signal: spectacle summons/curses/fire/teleport/meteor; FX silence/shield/cure/grass/vegetation/skeleton stay B.
Power Signal: disasters plus spectacle creature drops (`evil_mage`, `white_mage`, `necromancer`,
`druid`, `plague_doctor`, dragons/demons, …) via live spectacle asset discovery - not B ambient.
## Patch-only / no catalog rows
| Surface | Live / notes | Wire status | Priority |
|---------|--------------|-------------|----------|
| buildings | 618 | consume A; ambient destroy demoted B; **no complete/wonder A** | P0 complete/wonder |
| boats | patch | trade/unload A; load B | P3 |
| combat | policy in `EventCatalog.Combat` | scanner + fight feeds | P3 |
| architecture / city_build_orders | 53 / 3 | covered_by_building_activity | P3 |
| kingdoms_traits | 5 | covered_by_trait_meta_feeds | P3 |
| items_modifiers | 59 | covered_by_item_feed | P3 |
| combat_action_library | 11 | covered_by_spell_combat_feeds | P2 only if distinct beats |
| loyalty / opinion / knowledge / communication / story | 29/24/11/10/1 | covered_by_worldlog_happiness | P3 |
| citizen_job / professions / personalities | 13/5/5 | Activity/dossier labels | P3 |
| tasks_actor | 217 | Activity taxonomy (unmappedTasks=0) | P3 |
| actor_library | 322 | SpeciesDiscovery / voice (taxonomy PASS) | P3 |
| plot_category_library | 9 | categories only | P3 |
WorldLog already covers end beats that inventory once flagged as open wire work:
`alliance_dissolved`, `kingdom_destroyed`, `kingdom_shattered`, `kingdom_fractured`, `city_destroyed`.
Manager `removeObject` is intentionally not event-worthy in `MutationDiscoveryHarness` because those WorldLog rows exist.
## Mutation discovery
| Metric | Value |
|--------|------:|
| managers | 57 |
| managerMethods | 189 |
| actorMethods | 256 |
| beh | 93 |
| libraries | 39 |
| libraryAssets | 2893 |
| gaps | 0 |
`World.era_manager` / `World.earthquake_manager` report `null` on this build (unwired PollState, not gap rows).
Age change remains wired via `WorldAgeManager.startNextAge`.
Ongoing era/earthquake poll is still optional fill (P2), not a missing id catalog row.
Unwired ManagerEnd / Beh rows exist in TSVs but are filtered out of `mutation_gaps` by design (Beh → activity path; `removeObject` → WorldLog).
## Tip quality gap (main expansion lever)
Status (2026-07-22): **class path shipped** - discrete `MakeLabel` resolves `{id}` via
`LibraryAssetNames` when `LibraryKind` is set on live-seeded library rows;
WorldLog `MakeLabel` prefers `world_log_library` translated names, else humanize.
Remaining work is playtest-driven Signal A / weak decision-WorldLog prose only where
soak or camera-A inventory still shows awkward phrases - not mass new JSON libraries.
Status check (2026-07-22): live `library_asset_labels_ok` / `camera_a_inventory_ok` dumps show
**0** snake_case displays and **0** camera-A rows with raw-id displays. No mass prose pass needed
until a soak/camera tip shows a new awkward class.
Previous gap notes (historical):
`EventReason` / discrete `MakeLabel` used to replace `{id}` with the raw asset id.
Status/trait Activity and dossier paths already used locale/`getTranslatedName` helpers.
Examples of weak watch tips today:
- `{a} culture gains xenophobic` instead of a localized culture-trait name
- `{a} forges armor_leather` (wrong verb + raw id)
- `{a} gains gene warfare_3`
- `God power: atomic_bomb` (readable but not localized)
Recommended class fix: resolve `{id}` through live asset display names inside Label builders for library domains (same pattern as status), not thousands of JSON rows.
## Audit hygiene
`DomainEventHarness` diffs culture/religion/clan/language traits into `domain_event_audit.tsv` but omits those diffs from `Passed`.
If meta traits are first-class EventCatalog domains (they are), the pass condition should include them.
## Expansion waves
### Wave 0 - done by this audit
Authored 1:1 sync and live seed inventory: no missing ids.
### Wave 1 (first implementation PR) - tip quality + building complete
Status (2026-07-17): **implemented** in mod `0.28.14`.
1. `LibraryAssetNames` + `EventReason.Library` resolve live display names (localized when available, else humanized).
2. Item verb is `gains` by default; `forges` only for forge/smith/anvil ids. Catalog template `{a} gains {id}`.
3. `Building.completeConstruction` wires Layer A for `Building_Civ` (temple/statue spectacle strength bump).
4. `domain_event_audit` fail-gates culture/religion/clan/language trait diffs; `library_asset_labels_ok` dumps `.harness/library-asset-labels.tsv`.
### Interesting A expansion (Phases 02)
Status (2026-07-17): **implemented** in mod `0.28.27`.
1. `camera_a_inventory_ok` dumps `.harness/camera-a-inventory.tsv` (nested in `domain_event_audit`).
2. Decisions: fluff filter refined; Signal classes for founding/reproduction/pack/spectacle; **37** camera A with authored phrases.
3. Library Signal widened (power/item/gene/worldLaw/subspecies/meta); ambient CI stays false; phenotypes/biomes stay 0 A.
### Wave 2 - Signal / ambient A tuning
Status (2026-07-17): **implemented** in mod `0.28.16`.
1. `ambientCreatesInterest=false` for spell/item/gene/phenotype/worldLaw/subspecies/meta trait dials (Signal predicates / signalIds own Layer A).
2. Spells: `IsSpectacleSpell` keeps summon/meteor/tornado/lightning/teleport/curse/blood/fire as A; silence/shield/cure/grass/vegetation/skeleton stay B.
3. World laws: dramatic class includes hunger/rebellion/disaster/angry (plus war/death/plague).
4. Phenotypes: all B (no Signal predicate).
5. Items: Signal for mythril/adamantine (+ named relic tokens); leather/iron ambient B.
6. JSON loader now ingests culture/religion/clan/language trait dials; default ambient CI is false.
7. Gate: `library_ambient_policy_ok` (nested in `domain_event_audit`).
Era change was already wired (`WorldAgeManager.update` → `startNextAge`).
Earthquake ongoing hold: **implemented** (`Earthquake.startQuake` → `EarthquakeActive` sticky) in `0.28.17`.
### Wave 3 - new surfaces only if playtests demand
Status (2026-07-17): **triaged closed** - no new EventCatalog domains.
| Surface | Live | Decision |
|---------|------|----------|
| combat_action_library (11) | melee/range/spell/dodge/… | Covered by combat scanner + `tryToCastSpell` → spell catalog |
| story / knowledge / communication / loyalty / opinion | small libs | Covered by WorldLog / happiness civic paths |
| personalities / professions | 5 / 5 | Activity/dossier labels only |
| architecture / city_build_orders | build helpers | Building complete / consume path |
Do not mass-author powers/items/buildings into JSON.
## First implementation PR recommendation
**Title focus:** Improve library event tip labels and wire building completion.
**Scope:**
- Display-name resolution for library Labels (class fix)
- Item label template improvement
- Building complete / wonder Layer A path + harness gate
- `domain_event_audit` pass includes culture/religion/clan/language trait diffs
- Refresh this doc + [`world-event-inventory.md`](world-event-inventory.md) counts
**Out of scope for that PR:** mass JSON rows; scoring-model changes; dossier chip tooltips.
## Refresh commands
```bash
./scripts/worldbox-ctl.sh status
./scripts/harness-run.sh --no-launch mutation_discovery
./scripts/harness-run.sh --no-launch domain_event_audit
./scripts/harness-run.sh --no-launch activity_happiness_audit
./scripts/harness-run.sh --no-launch activity_status_audit
./scripts/harness-run.sh --no-launch world_log_audit
./scripts/harness-run.sh --no-launch disaster_war_audit
./scripts/harness-run.sh --no-launch activity_taxonomy_audit
```