Commit Graph
2067 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 4.6 1595cfc8a7 content(wiki): address PR #140 review — 9 fixes
1. Scapa Flow Industries: HQ moved from restricted military station to
   Quaterna (civilian commercial platform). Overview expanded with
   military/civilian context.
2. Threshold Fuel Syndicate: reconceived from "frontier east corridor
   supplier" to Gateway's local fuel producer supplementing imports.
   Removed frontier tag.
3. Arbour Aggregates: corridor labels fixed — "north"/"east" → "core zone"
   to match GJ 338B's actual hop-3 loop_member position.
4. Rush Mining: named concrete sustaining mechanism (property tenure
   uncertainty keeps combines away; first-mover holds by occupation).
5. Sede Chemical Works: expanded "ACB" to "ACB — Alpha Centauri B" on
   first use.
6. Stale body footer dates updated on rush-mining and scapa-flow.
7. Bifrost Marmor: added missing Cross-References body section.
8. Rush Mining: added cross_ref to rare-vein-survey.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-02 17:24:09 +02:00
jpmschweitzerandClaude Opus 4.6 4335e64840 content(wiki): review 21 corporation pages authored by server team (#884)
Copy-team review of wiki/corporations files authored by Dudley in Sprint 37.
Fixes: 6 hop-count errors, 1 topology label, 3 tag corrections, 2 header
renames, 1 cross_ref addition, 1 description typo. Rewrote 6 stub pages
to institutional prose voice. Rewrote Rush Mining and Scapa Flow Industries
narratives to match actual star-map topology.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-02 10:13:59 +02:00
jpmschweitzerandClaude Opus 4.6 f9fdfb7712 docs(workshops): add generation-cascade workshop brief (#897)
Implementation audit of the full generation pipeline from planetary
heightmaps to walkable tiles. 3-round workshop with Gestalt, Tyre,
Miri to map what exists vs. stubs vs. missing, produce D-records,
and create formal ticket dependency chain blocking character/apartment
work behind the complete pipeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 14:05:04 +02:00
jpmschweitzerandClaude Opus 4.6 6fb788d428 chore(meta): plan Sprint 38: Depth
Generation pipeline focus — map all layers from planetary heightmaps to
walkable tile environments, build bare-minimum free camera viewer, close
Sprint 37 test/infra debt. Character and apartment work formally parked
behind the full generation cascade.

13 tickets across 5 teams (planning: 1, server: 4, client: 5, copy: 1, ci: 2).
Added Write(docs/sprints/*) and Bash(mkdir) permissions for sprint planning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 13:16:24 +02:00
jpmschweitzer 38a1007e04 chore(meta): release v0.1.37
Sprint 37: Sweep — 25/25 original-scope tickets shipped across 4
teams (ci 7 / server 9 / client 6 / copy 3).

Highlights:
- Asset pipeline discipline: source-canonical systems.db with
  meta-stamp, pre-push hook, /pr-push auto-regen, documented rule
  (#854-#859, #723)
- D-192 PROTOCOL_VERSION lockstep removed server + client
  (#874, #875)
- D-167 HeritageRoot + D-032 CharacterArchetype stripped per
  development cascade (#877, #878)
- New Game hang fix + scene-level merge-path tests (#872, #873)
- 105 brand corp stubs authored to three-layer depth (#861)
- D-193 Lattice Commission canonical (#876)
- v0.1 Sova/Van Maanen residue purged (#865)
- 21 raw-commodity coverage gaps closed (#860)
- Atlas generator polish + determinism smoke (#853, #847)
- Bookmark save/load persistence (#863, #862)

5 in-sprint follow-ups carried to backlog (#882, #884, #885,
#892, #893) for sprint 38 planning.
v0.1.37
2026-04-22 11:39:36 +02:00
jpmschweitzer fcd434e528 Merge remote-tracking branch 'origin/sprint-37/copy'
Resolved 8 conflicts in wiki/corporations/ between server #860 tag
updates and copy #861 three-layer authoring. Resolution: union of
server's commodity-tag additions + D-175 decision_refs, plus copy's
cross_refs populated entries.
2026-04-22 11:25:55 +02:00
jpmschweitzerandClaude Opus 4.7 75287f9534 content(wiki): address PR #138 round 2 — N1 + N2
- N1: wiki/factions/lattice-commission.md:144 — refresh footer
  Updated: timestamp to 2026-04-22. Round-1 fix touched the
  frontmatter but missed the footer block; both fields now agree.
- N2: wiki/factions/index.md — rewrite the Local Factions cross-ref
  to describe the-ring.md as it actually is on the branch:
  a canonical named faction (faction_type: criminal, status:
  canonical) documenting an informal contraband network at
  district scale, preserved as the one maintained worked example
  for corridor authors. Previous prose mischaracterized the file
  as an "archetype doc," which it is not.

lattice-commission.md has no direct link to the-ring.md, so no
change needed there — the only corridor-wide phrasing left is
"informal contraband networks" in the Faction Relationships
table, which is a generic structural observation about smuggling
as a Commission enforcement target, not a cross-ref to the-ring.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 11:16:30 +02:00
jpmschweitzerandClaude Opus 4.7 b6107393a1 content(wiki): address PR #138 review — errors + warnings
Blocking fixes (4):
- P1: wiki/factions/index.md — replace canonical "Local Factions /
  The Ring" table row with a prose note, since the-ring.md was
  rewritten in #865 as a generic informal-contraband-network
  archetype rather than a named local faction.
- P2: wiki/factions/lattice-commission.md — replace The Ring
  cross-refs (table row + Cross-References list) with generic
  "informal contraband networks" framing; add D-193 cross-ref.
- P3: wiki/factions/lattice-commission.md — rewrite "Gameplay
  Presence" section. Removed v0.1 smuggler/detective framing
  (THE FRIEND detective path, Commission kiosk in logistics hub,
  "detective's arrival" language) and replaced with corridor-
  wide structural description: certification inspectors,
  field investigators, compliance kiosks, audit cadence.
- P5: wiki/factions/lattice-commission.md — refresh `updated:`
  timestamp to 2026-04-22.

Warnings (9):
- H1-H4: saigon-consulting, haesungdan-records, calluna-wellness,
  leerfeld-records — expanded each above the ≥95-line DoD floor
  with missing Political Relationships sections (mellanie3's
  systematic section-skip, same pattern as the earlier cycle-2
  pad pass) plus one extra cross-reference each.
- H5: 25 files in miri2's cycle-2 slice (alphabetical range
  ondori-interactive → transit-library) used shorter "##
  Relationships" header; renamed to "## Political Relationships"
  to match the canonical section title from alcyone-tech.md.
- P4: lusaka-advisory — added documentary anchor to the concealed
  fact. The cross-engagement reference ledger (internal partner-
  only document maintained since 2052 restructuring) and the
  2058 partner-retreat memo declining to present it in dispute
  forums are the investigative surface. Addresses Paula's note
  that the original concealed fact existed entirely in partners'
  heads with no documentary trail.

Not fixed (documented as false positives — verified clean on
branch):
- M1: glossary.md line 19 NOT-list does not contain "Lattice
  Commission" (Mellanie removed it in the D-193 commit;
  reviewer likely reading a stale snapshot).
- M2-M5: Van Maanen / Station Sova references in
  mastroianni-vehicle-group, ferreira-monteiro, gate-corporation,
  stalownia-kowalski — all four files grep clean (#865 Bucket C
  rewrote them).
- M8: wiki/star-systems/GJ-35/sova/transit/index.md was deleted
  in commit 25eb8bd0 — file cannot be fixed.

Info-only comments (P6, P7, M6, M7) left as advisory notes
for future deepening passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 11:08:29 +02:00
jpmschweitzer b71c505c4d chore(skills): pr-review — point reviewers at team worktree, not main
Sprint 37 PR #138 review produced 6 false-positive findings because
the reviewer defaulted to Read/Grep on the main repo path instead of
the sprint-37/copy branch worktree. Every finding was a verbatim match
against main's state but irrelevant to the branch — the branch had
already cleaned the residue being flagged as "still present." False
negatives are the same drift running the other direction: bugs
introduced on the branch never get seen because the reviewer never
reads the branch.

Fix: resolve the team worktree path before spawning reviewers
($(dirname <repo>)/.sprint/sprint-N/<team>/) and pass it into the
reviewer prompt with non-negotiable language. The worktree IS the
branch; Read/Grep on paths rooted there cannot resolve to main.

Fallback (no worktree — e.g. non-sprint branch or post-teardown):
git show origin/<branch>:<path>. Explicitly flagged in the prompt
so the reviewer knows Read/Grep on any local path is wrong.
2026-04-22 11:07:51 +02:00
jpmschweitzer 57d101d1cf Merge remote-tracking branch 'origin/sprint-37/server' 2026-04-22 10:37:39 +02:00
jpmschweitzer aa1d74e851 Merge remote-tracking branch 'origin/sprint-37/client' 2026-04-22 10:37:10 +02:00
jpmschweitzerandClaude Opus 4.7 055a019277 chore(config): pre-push — fall back to origin/main on first push
When a new branch is pushed for the first time, origin/<branch> does
not yet exist, so the pre-push hook was falling through to treating
every directory as changed. On a wiki-only branch this meant running
Godot headless parse, cargo fmt + clippy, ruff, and validating all
2762 repo-wide JSON files — tens of seconds of churn against a diff
that had no client/server/tooling/JSON content.

Fix: try origin/<branch> first, fall back to origin/main before
giving up. The JSON validation block now uses the same REMOTE_REF
the directory-change detection settled on, so both code paths stay
consistent.

Scope note: this is CI/tooling infrastructure, not copy-team scope,
but surfaced as part of reviewing the slow push on sprint-37/copy.
Bundling here rather than a separate branch at Jeroen's direction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:32:51 +02:00
jpmschweitzerandClaude Opus 4.7 fdf8dd4842 content(wiki): author 105 brand corp stubs to three-layer depth (#861)
Sprint 36 PR #133 shipped 112 new corp wiki pages as ~24-line
frontmatter-only placeholders. This commit authors 105 of them to
the canonical three-layer narrative standard (≥95 lines each).

Three-layer content model per D-189:
1. Public identity — branding, market position, public face
2. Actual operation — supply chain, workforce reality, profit model,
   political relationships, regulatory dependencies
3. One concealed fact — a single discoverable secret shaped like an
   iceberg. Public commitment stays technically true; the compromise
   lives in the deliberately-drafted clause, the accelerated refresh
   cycle, the "behavioral pattern" that isn't a "guest record."

Every page:
- ≥95 lines (actual range 95-125)
- Overview, Origin, Operations, Political Relationships, concealed-
  fact section, Gameplay Relevance, Cross-References
- Corridor/founding-system specificity — HQ culture informs voice
- "the Lattice Commission" (D-193) used throughout
- Cross-refs populated per D-189 brand layer architecture

Quality bar: wiki/corporations/alcyone-tech.md — authenticated
timing side-channel vulnerability, legal non-disclosure decision,
accelerated refresh cycle disguised as "performance enhancement."
Clean public promise; deliberately-kept secret; reachable by a
player who finds the internal report.

Authored across three cycles: cycle 1 validation (~20), cycle 2
main push (75 at 25 per author), cycle 3 cleanup (9). Split by
brand category and corridor clustering to encourage natural
cross-refs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:27:12 +02:00
jpmschweitzerandClaude Opus 4.7 25eb8bd096 content(wiki): purge v0.1 Sova/Van Maanen residue (#865)
Spring-cleaning accumulated v0.1 vertical-slice residue across the
wiki. Scope per Jeroen's pre-decisions on 2026-04-21:

- Delete outright: wiki/star-systems/GJ-35/sova/ subtree (5 files +
  2 dirs) — v0.1 Station Sova / Transit District content.
- Strip example blocks in authoring guides and _templates/ that
  cited dropped v0.1 NPCs (Kael Davan, Sera Venn, Nils Davan, Devra,
  Torek, Renn, Pell, Tav, Lera Sessik, Sabel). Replaced with short
  "v0.1 examples removed — D-122" notes pointing authors to the
  active NPC roster.
- Rewrite canonical-lore references file-by-file: faction pages,
  technology pages, contraband pages, concepts pages, corp pages
  that cited v0.1 names/places. Preserve institutional/structural
  content, drop specific-name citations.
- Commission name drift: replace "Concord Commission" and "Assembly
  Commission" with "the Lattice Commission" (D-193) throughout.
- Van Maanen's Star cultural references: the canonical in-game name
  is Vuurkloof. "Van Maanen's Star" is retained only as an
  astronomical designation (glossary + GJ-35 Calibration Note).
  All cultural/system references converted to Vuurkloof across
  culture-authoring-guide, cultural-generation-guide, founder-gates,
  and star-system adjacent-system descriptions.
- Strip `v0.1` from faction/triangle frontmatter tags (8 files).
- wiki/triangles/hub-power.md and wiki/factions/the-ring.md:
  rewritten using role-name exemplars (Ring Coordinator / Shift
  Supervisor / THE FRIEND) instead of named v0.1 NPCs. Triangle
  pattern preserved as a structural reference.

Also applies drive-by Commission drift fixes and minor cross-ref
updates to canonical corps (gate-corporation, mastroianni-vehicle-group,
stalownia-kowalski, prometheus-labs, ferreira-monteiro, vins-de-grand-vide,
and 13 others).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:26:45 +02:00
jpmschweitzerandClaude Opus 4.7 9c68613ad8 decide(content): resolve Q-095 as D-193 Lattice Commission
Canonical long-form of the Concord Assembly's regulatory authority is
"the Lattice Commission". Short form "the Commission" remains standard
in-prose. Drift forms "Concord Commission" and "Assembly Commission"
are deprecated. Resolves Q-095 (#876).

Rationale: naming after the regulated domain (Lattice) rather than the
parent Assembly mirrors real-world regulators (FDA, FAA, NRC) and
disambiguates from the multiple other "Concord"-prefixed references
in the wiki. The Commission's jurisdiction is Lattice-scoped, not
Concord-scoped — it has no authority in Compact member systems.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:26:16 +02:00
jpmschweitzerandClaude Opus 4.6 b86bb00a55 refactor(simulation): PR #137 review — audit override + regression tests + docs
Addresses Tyre, Hoshe, and lead review comments on PR #137:

- **Audit doc amendment** (Tyre E1 / Hoshe H1 / Lead): add "Lead override
  (2026-04-21)" section at top of docs/architecture/sprint-37-878-audit.md.
  Rewrites the conclusion to "DECISION: STRIP" with the cascade-based
  rationale. Preserves the original audit body as the pre-override record.

- **Regression tests** (Lead 2a-2b / Hoshe H2 / H3): add POSITIVE
  assertions of the new uniform behavior so silent reintroduction fails.
  - `phase2_container_verb_labels_uniform_regardless_of_player_state` —
    two trials (empty KG, POI-bearing KG) assert container verb labels
    equal Phase-1 defaults.
  - `monologue_pool_selection_uniform_no_archetype_key` — two observers
    with divergent MonologueState both draw from OBSERVE_NPC_LINES.

- **Decision record amendments** (Lead 3 / Tyre S2): D-032, D-035, and
  D-057 amended with Phase 6 deferral wording. "Retired pending Phase 6,
  not deferred with scaffolding." Reintroduction gate: a confirmed
  Phase 6 character-model design.

- **types.rs doc fixes** (Tyre S1 / Hoshe H5): StartupMessage protocol-
  flow comment updated to reflect no-version handshake (D-192).
  ObserverSnapshot version-history block grows a "Sprint 37 wire-format
  shifts" section documenting D-192 + #878 schema drops.

- **observer/tests.rs:944 comment** (Hoshe H6): rewritten to cite
  cascade rationale instead of the stale D-032-SUPERSEDED premise.

- **tests/run-atlas-determinism exit** (Hoshe H7): exit 0 when EXIT_CODE=2
  (venv/DB missing = skip, not fail). Preserves skip semantics for
  tests/run-all on machines without the Python venv.

Follow-up tickets filed:
- #895 (server, low): expand check-systems-db-stamp GENERATOR_SOURCES
  to cover gemma_naming.py + naming_core.py (Tyre S3).
- #896 (planning, low): add CLAUDE.md carveout for server wiki writes
  closing coverage gates (Tyre S4 / Hoshe H8).

H4 investigation: v01_integration_playthrough.rs was not the only E2E
handshake→tick→snapshot test; coverage preserved by bridge_ipc.rs,
bridge_tcp.rs, and game_loop.rs (the latter is pre-existing-broken
per #885). No replacement test needed.

1142/1142 lib tests pass. cargo clippy -- -D warnings clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 10:09:35 +02:00
jpmschweitzerandClaude Opus 4.7 60733738f2 fix(client): PR #135 review — T1/T3/H4-H7 blocking + nits
Code changes addressing PR #135 review (Tyre + Hoshe):

- **T3 (blocking):** test_merge_path_flows_sprint37.gd `_load_main_menu`
  and `_load_char_create` now assert the scene loaded instead of silently
  returning. Missing .tscn → red test, not falsely green.
- **T1:** sim_bridge.gd signal `handshake_complete(protocol_version: int)`
  was D-192 residue with no listeners. Drop the int parameter entirely
  and the literal-0 emit.
- **H4:** test_new_game_catalog_snapshot_resolves_loading_state now
  asserts SimBridge.state == CONNECTED terminus, not just the loading
  flag — guarantees full flow completion, not merely flag-clear.
- **H5:** test_protocol_bridge.gd file-level comment refreshed; drops
  reference to removed protocol-version check tests.
- **H6:** test_p0_regressions.gd `_make_snapshot_bytes` comment refreshed
  and version field removed from fixture dict (D-192: not required).
- **H7:** test_merge_path_flows_sprint37.gd `_make_catalog_snapshot`
  drops version field from fixture dict (D-192).

Follow-up tickets filed for reviewer suggestions:
- **T2:** #889 — revive EntityRenderer sprite constants coverage
  (D-044 ENTITY_WIDTH/HEIGHT, asserted by deleted test_sprite_integration).
- **T4:** #890 — UI timeout fallback for bookmark catalog wait in
  main_menu (systemic 'catalog never arrives' class beyond #872's
  TCP-batch race).
- **T5/T6:** #891 — scene-flow test tier docs + test-only reset
  helpers (SimBridge.reset_for_test, MetaStack.reset_for_test) +
  minimal public API on scenes so UI refactors don't break all four
  flow tests simultaneously.

Verification:
- `make lint-client` — no script errors
- `gdlint client/scripts/ client/ui/` — no problems
- `make test-client` — 2428/2488 passing. 60 remaining failures are
  pre-existing, unrelated to sprint 37 (test_dialogue_sprint20 #558
  signals, test_input_roundtrip integration-sans-server, etc.).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:06:39 +02:00
jpmschweitzer 469377caa6 Merge remote-tracking branch 'origin/main' into sprint-37/client 2026-04-22 09:47:36 +02:00
jpmschweitzerandClaude Opus 4.7 bc310a3ca5 fix(client): sprint 37 test-pass fixes — parse error + test hygiene
- character_creation.gd:1614: type-annotate dir_name to fix GDScript
  inference parse error. CARDINAL_DIRS is an untyped const Array, so
  `var dir_name := CARDINAL_DIRS[idx]` failed type inference and blocked
  test_character_creation_sprint28.gd test discovery. Runtime was lenient
  but gdUnit4's scanner is strict.
- test_merge_path_flows_sprint37.gd (_load_char_create): call add_child
  before _update_start_btn_state so @onready vars (_footer_start) are
  bound when the helper dereferences them. Unblocks 2 merge-path tests.
- test_anti_tedium.gd (test_bug_report_sends_unpause_on_close): call
  dialog.close() instead of the old dialog._close() rename casualty.
  `on_close()` is a lifecycle hook — it doesn't actually transition
  state; `close()` is what MetaScreen exposes.
- test_anti_tedium.gd (before_test): clear MetaStack._stack. Prior tests
  leave stale freed dialog refs on the stack; _any_pausing() iterates
  the stack during close() and crashes with "previously freed".

Net: sprint-37 test files (test_merge_path_flows_sprint37.gd,
test_anti_tedium.gd) now pass. Overall suite: 2428/2488 passing
(60 remaining failures are pre-existing, unrelated to sprint 37).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 09:06:51 +02:00
jpmschweitzerandClaude Opus 4.6 8f46048a75 style(simulation): cargo fmt
Formatting normalization caught by pre-push hook.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 09:04:38 +02:00
jpmschweitzer 94a687fc08 Merge remote-tracking branch 'origin/main' into sprint-37/server
# Conflicts:
#	CHANGELOG.md
#	Makefile
#	server/data/systems.db
2026-04-22 09:01:43 +02:00
jpmschweitzerandClaude Opus 4.6 f8407980db refactor(simulation): derive Default for MonologueState (clippy)
After #878 removed the `character` field, the manual Default impl is
derivable. Clippy flags this under `derivable_impls` with -D warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:58:42 +02:00
jpmschweitzerandClaude Opus 4.6 68ef5cb380 chore(meta): update changelog for sprint 37 server
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:57:00 +02:00
jpmschweitzerandClaude Opus 4.6 11db2f4b41 docs(architecture): sprint 37 archetype-trace audit (#878)
Tyre's trace of every live consumer of CharacterArchetype across server
and client, with the cascade-based rationale for full removal. Captured
so future audits don't repeat the same investigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:56:21 +02:00
jpmschweitzerandClaude Opus 4.6 cae3d3ab85 refactor(simulation): strip archetype trace + HeritageRoot per cascade (#877, #878)
Sprint 37 dead-code sweep closing out two stale supersession chains:

#877 (D-167, 2026-03-24): Removes HeritageRoot type alias and
ZonePaletteModifier::Heritage variant from server/src/simulation/
generator.rs. The 7 abstract heritage roots were retired in favour of
the corridor cultural system; these two stubs were the only remaining
references.

#878 (D-032 + cascade rule): Strips the entire CharacterArchetype
(Smuggler/Detective) trace from the server. Per lead direction
2026-04-21 and the development cascade (CLAUDE.md), character/NPC/
verb-differentiation/monologue code is Phase 6 detail that should
not exist in code yet. The running archetype trace was pre-cascade
filler, not production — production is only the client's character-
creation UI and insert screens (client follow-up in #882).

Deleted:
- CharacterArchetype enum + StartupMessage.character_archetype field
- archetype_verb_label() + archetype branch of apply_phase2_verb_filter
  (D-057 character-verb differentiation — marked superseded)
- MonologueState.character partitioning
- Gauntlet archetype plumbing (setup_gauntlet no longer takes an archetype)
- server/content/schemas/drama_module.schema.yaml (zero Rust consumers)
- server/content/modules/tier1/smuggling_ring_v0_1.yaml
- server/tests/archetype_monologue.rs (regression guard for the removed system)
- server/tests/v01_integration_playthrough.rs (archetype-dependent)

Decision updates:
- decisions/content.md D-032 supersession rewritten to cite the cascade
  (v0.2 drop invalidated the prior D-117 framing).
- decisions/content.md D-035 tag taxonomy: `character` enum footnote
  updated; field noted as unused, do not reintroduce without a
  confirmed Phase 6 design.
- decisions/perception.md D-057: archetype-verb differentiation marked
  superseded.

Also bundles the types.rs version-field removal from #874 since the
file was already touched here.

Full trace audit in docs/architecture/sprint-37-878-audit.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:55:48 +02:00
jpmschweitzerandClaude Opus 4.6 c640563fc0 refactor(simulation): drop PROTOCOL_VERSION from bridge handshake (#874, D-192)
Removes the PROTOCOL_VERSION lockstep handshake across the bridge
transports. HandshakeMessage is now an empty marker indicating the
server is ready; the client sends StartupMessage next. Field-presence
and roundtrip behavioral tests are retained — tautological
version-literal assertions were deleted in Sprint 36.

After this lands, genuine schema drift surfaces as MessagePack
missing-field errors downstream, which is the intended signal per
D-192. Client ticket #875 is blocked by this commit and will ride
the same wave; server schema changes in #878 (character_archetype
removal) also depend on PROTOCOL_VERSION already being gone.

types.rs changes are bundled with the broader #877/#878 dead-code
sweep in the following commit, since they share the same file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:55:19 +02:00
jpmschweitzerandClaude Opus 4.6 bae1c5e156 data(economy): close D-175 Phase 2 coverage gate — 21 raw-commodity gaps (#860)
Adds and expands wiki/corporations/*.md entries so make economy-db
Phase 2 gate passes end-to-end without the 21 raw-commodity / system
coverage failures. Unblocks Phase 2 demand simulation.

Existing corporations (15): tag additions to baektu-mining-alliance,
bergkraft-antriebswerke, bifrost-marmor, gate-corporation,
hanyang-precision, jeju-lattice, nordmark-skog, norrland-woodcraft,
salud-alliance, shetland-wool, societe-chimique, stalownia-kowalski,
svanevann-waters, thrds, tongyeong-drive.

New corporations (6): arbour-aggregates, earth-standard-group,
rush-mining, scapa-flow-industries, sede-chemical-works,
threshold-fuel-syndicate.

systems.db regenerated — coverage validation now passes.

Cross-team scope note: wiki/ is copy-team territory per CLAUDE.md.
Writes here are accepted by lead for this sprint (maintenance sweep,
pragmatic fix); copy-team review follow-up filed as #884.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:55:05 +02:00
jpmschweitzerandClaude Opus 4.6 7fffdc572e test(assets): atlas determinism smoke test (#847)
Adds tests/run-atlas-determinism — imports generate_atlas as a module
and calls process_body() twice with seed=42 and dry_run=True, comparing
the returned markers dicts as JSON. No wiki files are written.

Guardrail against determinism regressions in terrain analysis, city
placement, A* road routing, infrastructure MST, and gate terminal
placement. GJ892f (domed, population 300, 1 city) is the smallest
well-exercised case.

Makefile target: make test-atlas-determinism.
Wired into tests/run-all alongside run-ipc-integration and run-visual.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:54:47 +02:00
jpmschweitzerandClaude Opus 4.6 531bb1df5c refactor(assets): atlas naming — dedup, compass filter, river vocab, infra names (#853)
Addresses five of seven subtasks from atlas-generator-refinement-notes:

- Cross-body dedup: corpus keyed by (corridor, feature_type) instead of
  (system_id, feature_type), seeded from existing atlas_* rows so re-runs
  don't collide with already-committed names. §1, §2.
- Empty-name fallback for mountain ranges when Gemma returns fewer names
  than needed ({body_proper} Range {i+1}). §2.
- Suffix monotony detection: flags bodies where >40% of mountain names
  share a trailing word (warning only — batch pipeline has no voice
  access for auto-fix). §3. Follow-up in #886.
- Compass-direction ban: build_batch_prompt explicitly forbids
  "Eastern/Northern/Western X" in few-shot instructions. §4.
- River vocabulary filter: is_valid_name rejects "X Flow" / "X Current"
  when feature_type="river" — these are ocean terms bleeding through. §6.
- Infrastructure naming: deterministic post-pass assigns "{CityA}–{CityB}
  {corridor_suffix}" to unnamed roads and railroads (Corridor/Road/Estrada/
  Strasse/Track by corridor). §7.

Cultural-history prompt threading (§5) remains as existing corridor_substyles
refill mechanism; explicit cultural-history blurb deferred to #886.

naming_core bumped to v0.3.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:54:37 +02:00
jpmschweitzerandClaude Opus 4.6 9f755f2a62 feat(simulation): persist SelectedBookmark across save/load (#863, #862)
Adds Serialize/Deserialize to SelectedBookmark and wires it into
SaveStateV1 so a loaded game remembers which bookmark and starting
location the player picked. Replaces the TODO at bookmark/mod.rs:95
(originally deferred to Sprint 37 alongside #614).

Also refactors BookmarkPlugin to accept an injected BookmarkRegistry
via BookmarkPlugin::new(registry) (#862). The Default constructor
still wires the canonical tycoon registry — injection is for tests
and future TOML loading. Flagged in PR #132 review as a follow-up.

Updates bookmark spec §4.4 to remove the v0.2-deferred scope note.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:54:21 +02:00
jpmschweitzerandClaude Opus 4.6 7c40067935 fix(simulation): lower storyteller activation_pass log to debug (#789)
The "no co-present NPC assigned to a Simmering triangle" branch fires
as WARN every few seconds during early gameplay when no NPC relationships
have escalated. This is normal state, not an error condition — downgrade
to debug so the warning channel reflects actual problems.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:54:09 +02:00
jpmschweitzer 5b68c4ce80 Merge remote-tracking branch 'origin/sprint-37/ci' 2026-04-22 08:47:27 +02:00
jpmschweitzerandClaude Opus 4.6 06838043fd chore(meta): update changelog for review-fix pass (PR #136)
Corrects the "three generators" wording after the brand pipeline merge.

Refs: PR #136

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:39:03 +02:00
jpmschweitzerandClaude Opus 4.6 3d9dd7d909 chore(ci): merge brand pipeline into import_economics + harden review findings
Addresses all blocking + minor items from PR #136 review.

Architectural change (T2/H3 — the review's main complaint):

  generate_brands was previously a separate Rust binary that produced a TOML
  artifact, with its stamp written "on behalf" by import_economics.py at the
  end of its own run.  Reviewers flagged the invisible coupling: two sources
  of truth in a system designed to have one, and no way to tell from the
  stamp that one "generator" was really a subroutine of the other.

  import_economics now invokes tooling/generate-brands as the first step of
  its main() flow, before opening its own DB connection.  The TOML artefact
  is still produced and still committed (useful for diff-review of brand
  changes), but there's now one pipeline owner.  The meta table carries two
  rows (import_economics, generate_atlas) not three; the Rust binary's
  source SHA folds into import_economics' stamp via IMPORT_ECONOMICS_SOURCES.
  A MIGRATION_SQL DELETE cleans up pre-merge DBs that still have the
  orphan generate_brands row.

Other review items addressed in-line:

  H1  generate_atlas._write_stamp no longer commits — transaction ownership
      stays with the caller (matches import_economics pattern).  Stamp +
      atlas data now commit atomically; a failed stamp rolls back the
      atlas data rather than leaving a stamp-missing-data intermediate.

  H2  _file_sha1 (in both import_economics, generate_atlas,
      check-systems-db-stamp) raises FileNotFoundError on missing sources
      instead of silently contributing an empty-bytes hash.  A ghost-SHA
      convergence could otherwise produce vacuous "fresh" passes.

  H4  pre-push no-meta-table warning rephrased — was "run after next
      regeneration", now "run now if this DB was generated by you".

  T1  asset-pipeline.md determinism claim softened: the stamp is
      deterministic (same source → same recorded SHA), the DB binary is
      not (generated_at + SQLite rowids/freelist churn).

  T3  asset-pipeline.md gains a "migration escape hatch" section naming
      MIGRATION_SQL in import_economics.py as the only sanctioned path
      for direct writes, and forbidding hand-run sqlite-exec / one-off
      patch scripts / SQLite-GUI edits.

  T4  Makefile regen-db now runs as a single shell with `set -e`.  A
      failure in one generator halts the pipeline immediately, preventing
      the "stale data, fresh stamp" state where a later step stamped a
      DB whose earlier step had failed.  import_economics' exit code 2
      (coverage gate warning) remains explicitly tolerated.

  T5  pre-push stamp check now runs on a branch's first push too —
      compares against origin/main instead of origin/$BRANCH, closing
      the gap where a new branch could ship a stale DB via the first push.

  T6  check-systems-db-stamp fails closed on unknown generator_names in
      meta — a future branch adding a new generator without registering
      it in GENERATOR_SOURCES will now be rejected, not silently skipped.

  T7  /pr-push watch list gains a mutual cross-reference comment with
      GENERATOR_SOURCES in check-systems-db-stamp, plus the missing
      names.rs source file, so the two lists cannot silently drift.

Follow-up tickets created:

  #887 T8  decisions-orphan-tickets CLI — surfaces tickets whose
           decision_ref points at a non-existent D-record.
  #888 T9  meta.schema_version monotonic semver — for savegame migration
           lineage in Phase 5+ (SHA comparison can't be ordered).

Verified:

  make regen-db end-to-end — OK
  make check-systems-db    — OK, 2 generator(s) up to date
  STALE detection          — OK, verified by touching generate_atlas.py
  /pr-push watch list      — OK, flags this branch's changed sources
  decision show D-159      — OK, structured output with tickets + refs

Refs: #855 #856 #857 #858 #859 PR #136

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 08:38:41 +02:00
jpmschweitzer e522091f74 chore(skills): pin team-mode teammates to Sonnet 4.6
Sprint 37 observed Opus 4.7 teammates in team mode ignoring scope
rules ("don't modify files outside your team"), leaving tasks
half-done, and failing to report back via SendMessage. Closest public
issues are anthropics/claude-code#47598 (4.6 subagent delegation
regression) and claude-agent-sdk-python#577 (SendMessage delivery in
team mode). No 4.7-specific team-mode issue published yet but symptoms
are real.

Fix: every Task spawn with a team_name argument now passes
model: "sonnet". The team lead (the session running the skill) stays
on whatever model the user selected — typically Opus.

Inline Agent spawns without team_name (one-shot reviewers in
/pr-review, research subagents, general-purpose one-offs) are
exempt — they keep their default model. The pin targets long-running
coordination specifically, not every Agent call.

Affected skills:
- sprint-start: step 8d Task template adds model: "sonnet" and
  documents the rule with the 4.7 regression context
- workshop-start: step 5 spawn list adds the model pin with a
  one-line reason
2026-04-22 08:31:37 +02:00
jpmschweitzerandClaude Opus 4.6 07ca1c9fc1 chore(meta): update changelog for sprint-37 CI sweep
Refs: #723 #854 #855 #856 #857 #858 #859

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 17:35:55 +02:00
jpmschweitzerandClaude Opus 4.6 a41f7aa06c feat(tooling): add decision show <D-NNN> with implementing tickets + refs
Closes the decision-to-ticket coverage gap (#723). The `decisions-coverage`
Makefile target already reported per-decision counts; this adds the
single-decision drill-down via `tooling/db/decision show D-159`, returning
linked tickets, outbound refs, and inbound refs in one shot.

Schema unchanged — reverse link is a SELECT on tickets.decision_ref.

Refs: #723

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 17:35:23 +02:00
jpmschweitzerandClaude Opus 4.6 5079d84405 docs(ci): document source-canonical asset pipeline rule
Adds `.claude/rules/asset-pipeline.md` describing the full pipeline —
generators, meta stamp, pre-push hook, how to make DB/schema changes,
and why direct systems.db edits are forbidden. CLAUDE.md and DEVOPS.md
point at the rules file; sprint-start template now reminds teammates
to read it before touching DB sources.

CLAUDE.md also gains the missing `decision show` row in the CLI tool
table (companion to #723's `decision show` subcommand).

Refs: #859 #723

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 17:35:12 +02:00
jpmschweitzerandClaude Opus 4.6 44d7816b55 chore(skills): extend /pr-push with rebase + regen + stage for generator branches
Adds a new step 4a that detects generator-source or economy-data changes
vs origin/main and runs `make regen-db` before the push, staging the
updated systems.db. Pairs with the pre-push hook (#857) — instead of
rejecting a stale DB, /pr-push proactively freshens it.

Refs: #858

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 17:35:01 +02:00
jpmschweitzerandClaude Opus 4.6 8371e05e52 chore(ci): generator-driven asset pipeline — meta stamp + hook + regen target
Adds systems.db regeneration discipline (#855) via a `meta` table (#856)
stamped by every generator, a pre-push hook that rejects stale DBs (#857),
and the top-level `make regen-db` / `make check-systems-db` targets that
drive the whole pipeline.

The stamp stores SHA-1 of generator source + schema, so the pre-push hook
can cheaply detect "you changed a generator but forgot to regen the DB"
before a binary merge conflict lands. Sprint 36 hit that class of conflict
on two branches touching systems.db simultaneously — this is the systemic
fix.

Regenerated systems.db is stamped; `make check-systems-db` passes.

Refs: #855 #856 #857

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 17:34:52 +02:00
jpmschweitzerandClaude Sonnet 4.6 d72fcc7847 fix(protocol): drop PROTOCOL_VERSION lockstep — D-192 (#875)
Removes the version-mismatch guard from Protocol.decode_snapshot() and the
PROTOCOL_VERSION constant from the client (server side done in #874).

Core changes:
- protocol.gd: remove const PROTOCOL_VERSION, remove version mismatch guard,
  remove "version" from return dict, add gauntlet_mode/room_id decode
- sim_bridge.gd: remove handshake version check; relax handshake guard to
  require only a valid Dictionary (server no longer sends protocol_version);
  emit handshake_complete(0) for API compat
- loading_screen.gd: drop "· protocol N" suffix from version label
- test_harness.gd: replace Protocol.PROTOCOL_VERSION with literal 23

Test updates (21 files): replace "version": Protocol.PROTOCOL_VERSION with
"version": 23 in all snapshot bytes dicts; remove snapshot.version == N
assertions; remove version-rejection tests (test_rejects_version_6,
test_decode_snapshot_rejects_missing_version, test_decode_snapshot_rejects_old_version,
test_protocol_rejects_version_mismatch, test_sim_bridge_test_snapshot_uses_current_protocol_version).

Also includes: #872 bookmark_catalog carry-forward regression test, and
#873 merge-path flow tests (test_merge_path_flows_sprint37.gd).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:29:49 +02:00
jpmschweitzerandClaude Sonnet 4.6 708ab25614 fix(tests): sprint-37 sweep — #866, #869, #870 client test cleanup
#866: Fix _escape_bbcode in dialogue_box.gd — only escape '[', not ']'.
Chaining .replace(']', '[rb]') after .replace('[', '[lb]') corrupted the
[lb] escape itself. Updated test_dialogue_sprint18.gd accordingly.

#869: Migrate test_anti_tedium + test_bug_report_ring_buffer to instantiate
BugReportDialog via .tscn (BugReportDialogScene.instantiate()) instead of
bare Control.new() + set_script(). Sprint 36 moved bug_report_dialog.gd to
extends MetaScreen; the old load path was an orphan .uid file returning null.

#870: Delete 8 parse-error test files (test_debug_overlay_sprint19,
test_entanglement_sprint22, test_fog_sprint22, test_journal_sprint18,
test_minimap_sprint18, test_session_manager_sprint19, test_sprint30,
test_sprite_integration) + .uid sidecars. Coverage tickets filed for
fog/journal/minimap (#879, #880, #881). Sprint docs updated with #882 note.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:28:24 +02:00
jpmschweitzer f0465e40c1 chore(skills): sprint-start A1c — mandatory teardown, no pre-checks
The worktree cleanup step was documented as "safe to skip if the
sprint didn't use ephemeral worktrees" — which invited a pre-check.
Sprint 36 close did that pre-check from inside the repo root, where
.sprint/ doesn't exist, concluded no worktrees, and skipped teardown.
Three stale worktrees persisted until Sprint 37 planning surfaced them.

Fix: always run the script (idempotent, prints a graceful message when
empty). Document that .sprint/ is a sibling of the repo root, not a
child, so future sessions don't repeat the same ls-based pre-check.
Add a post-run verification step.
2026-04-21 16:05:05 +02:00
jpmschweitzer 8b3baf511f chore(meta): plan Sprint 37: Sweep — 25-ticket spring-clean sprint
Tickets:
- ci (7): #854, #855, #856, #857, #858, #859, #723
- server (9): #853, #860, #862, #863, #874, #877, #878, #789, #847
- client (6): #866, #869, #870, #872, #873, #875
- copy (3): #861, #865, #876

Themes: asset pipeline discipline, PROTOCOL_VERSION removal (D-192),
D-167 HeritageRoot purge, D-032 smuggler/detective enum audit, New Game
regression fix + merge-path test coverage, copy wiki residue purge,
bookmark save-state, generator quality patches.

Debt surfaced from Q/D-record sweep: Q-095 Commission name, D-167 and
D-032 residue, plus spring-cleaning pulls from stale backlog (#789,
#847, #723, #862).

#868 cancelled (superseded by #874 + #875).
2026-04-21 16:00:22 +02:00
jpmschweitzer 2ae836c18a chore(skills): sprint 36 retro process improvements
- pr-review: require manual smoke test for merge-path PRs (pre-game flow,
  scene transitions, save/load, connection handshake). Unchecked
  author-side smoke boxes downgrade verdict from APPROVED to
  REQUEST_CHANGES. Triggered by #872 — New Game hangs on 'connecting'
  landed through PR #134 with the exact smoke box unchecked.
- pr-push: wipe Godot script class cache before the runtime smoke check
  so cold-start parse-order bugs surface pre-push instead of failing
  the next fresh-clone parse. Sprint 36 hit this post-merge — MetaScreen
  base class not found because the cache was warm on developer machines
  but cold in CI / post-merge. Cold-cache check stays in the skill (not
  the pre-push hook) to keep iteration fast.
v0.1.36
2026-04-21 15:30:14 +02:00
jpmschweitzer 5ac9092f71 chore(meta): release v0.1.36
Sprint 36: Forge — 15/15 tickets complete (100%).

Highlights:
- MetaScreen pattern foundation + Option A pre-game flow (#618, #680)
- Protocol v23 with bookmark_catalog; D-192 deprecates PROTOCOL_VERSION lockstep
- 124 notable brand corps across 8 categories (#828)
- Core-world atlas cohesion pass across 5 systems + Sol bodies (#849)
- Unified implant/map chain per D-191 (#844)
- ImplantApp pattern base class + registry (#844, #824, #836)
- Bookmark definition and location-to-culture resolution (#614, #679)
- generate_brands pipeline — 10K minor brands (#829)
- D-078 overheard conversation system retired (#848, #842)
2026-04-21 15:29:57 +02:00
jpmschweitzer 9731270c52 Merge remote-tracking branch 'origin/sprint-36/client' 2026-04-21 14:39:39 +02:00
jpmschweitzer 50ac9041ad fix(tests): PR #134 review round 3 — seed start-state + PID log path
- test_character_creation_sprint28: before_each now seeds
  _selected_bookmark_id and _selected_location_id so the new disabled-
  guard in _on_start() (round 2) doesn't silently block 5 existing
  tests that call _on_start()/KEY_ENTER without setting up a valid
  bookmark selection. Restores the 2 tests Hoshe flagged as R2-H1 plus
  3 siblings that would have degraded the same way under the guard.
- tests/run-godot: LOG_FILE now includes $$ (PID) so concurrent runs
  across worktrees don't clobber each other's logs. Path is echoed
  back via the stdout JSON "log" field and the stderr hint line, so
  callers never need to predict it (R2-H2).
2026-04-21 14:30:38 +02:00
jpmschweitzer 53fbce08fb chore(tests): hard 300s timeout + on-disk log + context-safe output
Makes tests/run-godot self-containing so neither humans nor LLM callers
have to remember to wrap it in a timeout or pipe it into a file. A hung
test now kills cleanly at 300s with a clear TEST_TIMEOUT marker and
bisection hint instead of silently burning an hour of wall clock (as
Sprint 36 learned).

- Godot+gdUnit4 output goes to /tmp/sr-run-godot.log (overwritten each
  run). Nothing streams to stdout/stderr — 20k+ lines of test log into
  a terminal or an LLM context is unworkable.
- Stdout: one-line JSON summary, with a "log" field pointing at the
  file. On timeout adds "timeout":true and "timeout_sec":300.
- Stderr: a short hint block. On pass: one line. On failure: three
  commands to inspect the log. On timeout: a bisection recipe.
- Single well-known path instead of an env var — worktrees each want
  their own value and the indirection makes the hint lines meaningless.
  Concurrent runs are the caller's problem.
- timeout(1) --foreground --kill-after=10 to escalate to SIGKILL if
  Godot ignores SIGTERM.
2026-04-21 12:02:25 +02:00
jpmschweitzer 1b8e227413 refactor(ui): PR #134 review — MetaScreen/ESC chain tightening, D-192 reword
Addresses Tyre's 9 architecture items from the sprint-36 client review.

- decisions/architecture.md (Tyre #1): D-192 now says "deprecate; removal
  tracked in #868" instead of "remove". The branch does not remove the
  version field or guard — that belongs in the coordinated server+client
  PR. The decision text now matches the code on this branch.
- meta_stack.gd (#2): handle_escape() on a screen with
  closable_by_escape=false now consumes the event unconditionally. Was
  returning whatever on_escape() returned, which default-returned false
  and leaked ESC into main.gd's implant/settings chain — opening the
  settings dialog behind the loading screen.
- debug_console.gd (#4): drop the direct KEY_ESCAPE branch in
  _unhandled_input. ESC now falls through to main.gd → MetaStack, which
  finds the console on top of the stack and closes it via the normal
  path. Other keys are still consumed so movement/action can't leak.
- main.gd (#6, #10): extract the ESC priority chain into
  _handle_menu_key() so "MetaStack → implant → settings" is a named
  thing. Add a comment near connect_to_sim explaining that
  GameState.bookmark_catalog survives the Option A scene transition via
  the autoload.
- main_menu.gd (#7): header comment documenting the double LoadingScreen
  lifecycle — safe today because main_menu.tscn and main.tscn never
  co-exist, noted for future promotion to autoload if that changes.
- meta_screen.gd (#8): apply captures_input symmetrically in open()/
  close() — was set in open() only, so a screen changing the flag
  between open+close kept the opened value forever.
- meta_screen.gd (#9): on_escape() docstring clarifies the tri-state
  (consume-and-hold / consume-and-close / ignore) — and that
  closable_by_escape=false is the screen-wide way to say
  "consume-and-hold".
- bug_report_dialog.gd (#11): capture_cancelled now emits from
  on_close() (covers any close path — ESC, MetaStack pop, programmatic
  close) rather than only on_escape(). A new _completed flag
  distinguishes completion from cancel so the two signals stay
  mutually exclusive.
2026-04-21 12:02:09 +02:00