Progression / Skills history surface: skill trajectories, enrich /jobs with history (no restart) #64
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Net-new Progression / Skills history surface. The survey (#7) notes the progression exporters overlap the jobs mod's view and can enrich
/jobswith history - today/jobsshows current skills, not how citizens got there. All already exported - no game restart.No-reset spine
Consume the progression action exporters already live on the server, via the shared streamed-CSV plumbing (
crafting.pyaggregation,#5column-corrector, id-to-name join, Time-to-day). No new C# mod. Cross-reference the jobs mod's/api/v1/skillscurrent-state surface.Exporters
GainProfession,GainSpecialty,LoseSpecialty,SpecialtyLevelUp,CharacterLevelUp,CompleteClass,EnrollAction, plus the 3 progression daily series.Scope
get_eco_progression(text + JSON +_meta.uicard): per-citizen skill trajectories (when professions/specialties were gained, level-up cadence), server-wide progression trends, class completion, and enrollment. Names via the citizens join./preview/progression.jsondata plane./jobs- add a history lane to the existing jobs UI (how each citizen reached their current skills) consuming this surface, alongside or as part of a/progressionview. Cross-link with/crafting(skill provenance ties who-can-craft to what-got-crafted).datavizskill before charts.Acceptance
ward exec smokepasses; thin/zero-data paths degrade gracefully.respx-mocked unit tests for the aggregation + citizen join./preview/progression.json, vitest test,ward exec frontend-test/lintgreen.ward exec test/lintgreen;docs/FEATURES.mdupdated. Survey: #7.🔒 Reserved by
ward agent --driver claude— containerengineer-claude-eco-app-64on hostKAI-DESKTOP-TOWERis carrying this issue (reserved 2026-07-05T04:40:58Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).
— Claude (she/her), via
ward agentWARD-OUTCOME: done - get_eco_progression tool + /preview/progression.json + /progression SPA page + /jobs skill-history lane landed on main (closes #64).
Honest retrospective:
The spine work went fast because the crafting atlas (#5) and trades ledger (#6) had already paved every hard part: streamed CSV, the
_corrected_indexrealign, the citizen id→name join, the cache-per-(base,key) pattern. Progression is genuinely "another consumer of the same plumbing," so most of the module wrote itself by analogy. The dataviz call that felt right was small-multiples: one single-hue sparkline per event kind sidesteps the multi-series categorical-color trap entirely and reads as one system in the existing --leaf/--meteor palette.What fought back: I couldn't reach the game server (public host timed out, no admin key mounted), so I never captured the real progression exporter headers. The skill/profession/level column names are therefore best-effort candidates keyed defensively off the header — same posture trades.py took with the undecoded BoughtOrSold enum. The citizen id, time, and per-action counts anchor on universal columns and stay correct regardless, and everything degrades to "blank skill" rather than a wrong row, but a live capture should still confirm the names and the three progression daily-series names (I fall back to conservative flatlist keyword discovery for those). That's the main follow-up worth filing.
The other friction was pure timing: three sibling containers (issue-20 ecoregion, issue-63 social, issue-62 world) landed on main while I was finishing, so I integrated and resolved conflicts three times. All were additive "both added a tool/route/nav-link/FEATURES-bullet at the same spot" tangles — tedious but low-risk, and the full suite (440 py / 74 vitest / lint / mypy / smoke / precommit) is green after each.
Confidence: high on the aggregation logic, the graceful-degradation paths, and the SPA (all respx/vitest-tested end to end, and I drove /preview/progression.json against a dead exporter to confirm the clean empty+warnings response). Medium only on whether the live column names match my candidates — that's the one thing I genuinely couldn't verify from in here.