Both wrappers previously silently treated --help as a SQL comment and
returned empty result JSON. They now intercept --help/-h before
delegating to the Python connector and print proper usage text with
the correct JSON key names (affected_rows, not rows_affected).
ticket, sprint, and decision already supported --help — no change.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two related quality fixes observed mid-run on Sirius + ACB + Ran:
1) Cosmopolitan corridor palettes. The six corridor inflection labels
were single-culture dominant ("administrative English / Gateway-era",
"British / Australian / Irish", "Korean/Japanese/Taiwanese", etc).
Gemma 2 2B interpreted these as "produce ONLY in this register" and
every core body came out anglophone, every east_reach body came out
East Asian. The real Earth diaspora in the setting is cosmopolitan —
a British surveyor on an east_reach moon still names a river after
their aunt in Dorset. The labels now spell out the dominant register
AND explicitly invite cross-cultural variety so Gemma samples from
the full few-shot pool instead of collapsing to one culture.
2) Per-system gttr context (the big one). The gttr.md files under
wiki/star-systems/<slug>/gttr.md already carry a vivid one-sentence
characterisation of every system — "where the rules live", "forty
years old and still in the draft", "the most connected system in
the Reach", "grandparents owned the land". This is a far stronger
cultural signal than the corridor inflection alone.
New column `star_systems.gttr_hook` stores a pre-extracted 45-word
hook per system. `tooling/db/populate_gttr_hook.py` parses each
gttr.md, regex-matches the first `**NAME**` paragraph, normalises
whitespace, truncates softly at a word cap, and stores it. Covers
all 301 systems (full coverage). Idempotent, safe to re-run after
any wiki update. Explicit transaction wrapper.
gemma_naming.py loads the hook cache at startup via
`load_system_gttr_hooks` and threads `system_hook` plus the system
and body proper names through process_body → name_feature →
_build_prompt. The prompt now carries:
System: <proper_name>. Planet: <body_name>.
About the system: <gttr_hook>
Style: British. Answer: Cooper's Creek
Style: Dutch. Answer: Meijer Beek
...
Real-mode smoke on 10 cases across 4 contrasting systems shows the
hook is doing exactly what it should. Sample output on the same
body_id / local_id pairs:
Tau Ceti (cosmopolitan hub) → Oakham River, Riverwood, Bridle Way
Ran (old-family agricultural) → Hart's Well, Blackwood Ridge
ACB (Lattice Commission seat) → Greenhaven, Rudge Brook
Posto Avançado (PT frontier dead-end) → Rio Preto, Serra de Caxias, Cunha's Cove
Posto Avançado went from "likely-English under the old corridor-only
prompt" to actual Portuguese names with a real Brazilian place stem
(Caxias), because the hook explicitly mentions wave_5 Portuguese
founders and frontier dead-end context. The gttr cultural one-liner
is the single strongest lever available for per-system cohesion —
this was the mono-culture issue observed in the first run, now fixed.
Token cost: ~60-90 extra tokens per prompt (hook + ident line).
Inference slowdown: ~5-10% per call. Acceptable for the quality gain.
Also restores 10 markers.json files that were stale from the aborted
run just killed — they were all core bodies at hop 0-1 which benefit
most from the gttr-context upgrade, so re-running them with the new
prompt is worth the ~3 minutes of re-inference.
New end-to-end pipeline that walks every markers.json in the reach and
fills empty `name` fields using the Gemma 2 voice pipeline via
`sr-voice serve --stdio`. Per D-191 §4: the same Gemma 2 pipeline the
client uses for NPC voicing also produces the atlas content, which is
dual-purposed as a quality test of the LLM plumbing.
Pipeline per body (hop-ordered, core-first):
1. Load markers.json; identify feature records whose `name` is
blank (null or ""). Hand-authored names are never overwritten;
the 6 template bodies and any partial authoring stay put.
2. Look up body context (planet_class, settlement_pattern,
cultural_corridor, population, economic_role) from systems.db.
3. Build a short corridor-aware few-shot prompt per feature type.
Prompts carry 3 concrete `Style: X. Answer: Y` examples so
Gemma 2 2B completes a pattern instead of generating to an
open-ended instruction — this is the single biggest lever
against placeholder echoes on a small model.
4. Stream the prompt into a long-lived sr-voice subprocess, read
the JSONL response, post-process (strip markdown, label
prefixes, brackets, reject 5+ word outputs and placeholder
tokens), check the earth-name blocklist, check per-(corridor,
feature_type) + per-body dedup, check the per-stem cap, retry
up to 3 times with a bumped seed.
5. On persistent failure, fall back to a deterministic palette
generator so every feature ends up with a name.
6. Write markers.json atomically and refresh atlas_* DB rows via
sync_markers_to_db. Commit the DB per body so a crash loses
at most one body of state.
7. Restart the sr-voice subprocess every `--refresh` requests
(default: 200) to prevent KV-cache context bleed.
Core design decisions:
- Determinism: per-(world_seed, body_id, feature_local_id, attempt)
seed so the full run is reproducible.
- Ordering: bodies are processed in ascending `hop_distance_from_gateway`
so core bodies get first pick at every unique Gemma output and
outer sectors fall into the palette fallback when they lose the
dedup race.
- Dedup scope: (cultural_corridor, feature_type) across the run,
PLUS a per-body cross-type set so the same name can't be a river
AND an ocean AND a mountain on the same world. Hand-authored names
are seeded into both sets on load so templates win priority.
- Stem cap: each non-generic root token (e.g. 'Arcturus', 'Meridian')
may appear at most `--stem-cap` times across the full run (default
20), preventing single-word runaway. Fallback names bypass the cap.
- Earth blocklist: 181 curated entries covering major Earth cities,
mountains, rivers, oceans, historical/colonial spellings, and
Greek/Roman mythology that reads too literally. Prefixed variants
('Nouveau Paris', 'New Tokyo') explicitly allowed per the product
intent that Earth-echo names are fine but must not dominate.
Leading 'The ' is stripped before comparison so 'The Great Divide'
also matches.
Operational features:
- `--shard N/M` slices the body list into M partitions for parallel
runs. Two terminals × `--shard 0/2` + `--shard 1/2` fits the
~2.5 GB/instance VRAM footprint twice under the 50% cap on a
16 GB AMD GPU and roughly halves wall time.
- `--log PATH` writes a timestamped tee of every status line to a
file. Default: `.tmp/gemma_naming.shard{N}of{M}.log` when a
non-trivial shard is in use.
- SQLite `PRAGMA journal_mode=WAL` + `busy_timeout=15000` so two
concurrent shards serialize writes without lock errors.
- Per-body progress lines report `body K/N`, `sys K/N`, and
`hop=H` so the user can watch core sectors finish first.
- Each body logs the new names it produced per feature type so the
user can eyeball quality as the run progresses.
- Checkpoint summary every 25 bodies: cumulative names, rate,
ETA — gives the log regular scroll points.
- `--mock` uses `server/sr-voice/mock-stdio.sh` for dry-fire
pipeline validation without a model load (tested end-to-end).
Supporting files:
- `tooling/planet-gen/earth_blocklist.txt` — 181 curated entries.
- `tooling/db/backfill_cultural_corridor.py` — one-off migration
that fills the `cultural_corridor` column on both `star_systems`
and `bodies` from the `geographic_sector` values. Before this
pass, 99.4% of rows (3221/3240) had a NULL cultural_corridor
despite `wiki_sync.py` being aware of the column — the wiki
index.md files only carry the sector header, which was never
propagated to the DB column. Idempotent, safe to re-run after
any wiki_sync rebuild, explicit transaction wrapper with
rollback on failure.
Full batch runtime estimate: ~20 hours single-shard / ~10 hours
double-shard on this hardware. Smoke tests across five hardened
iterations (v1–v5) on GJ71b/c/d/d-1/e confirm the pipeline produces
clean, varied, culturally-coherent names with zero post-processing
residue.
The Qdrant index (commonwealth collection, 475 points) was stale —
pointing at old worktree paths from previous sprints with no
maintenance. Grep covers all current search needs.
Removed: qdrant_connector.py, wrapper scripts (qdrant-search,
qdrant-index, qdrant-health, qdrant-count), /docs-search skill,
Qdrant/Ollama config entries, and all active references in agents,
rules, briefings, DEVOPS, CLAUDE.md, and TEAM.md. The commonwealth
collection was dropped from tower-of-joy:6333.
Historical references in discussion archives and sprint briefings
are preserved as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sprint stop now clears assigned_to on all done tickets in the closing
sprint. Agents don't clean up after themselves — this was causing
5 bookkeeping warnings every sprint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add venv auto-activation to audio_batch, audio_connector,
image_connector, qdrant_connector, and trellis_connector.
Scripts re-exec into .venv/bin/python when invoked outside
the venv, with a friendly error if .venv is missing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create tooling/db/common.py with resolve_db_path(), load_config(),
get_connection(), and ensure_venv(). Update ticket, sprint,
sqlite_connector.py, and decisions_sync.py to import from common
instead of duplicating. Fixes pre-existing NameError in
decisions_sync.py (missing import os). Add pyproject.toml with
ruff config (ruff==0.15.9, CVE-clean) and dev dependencies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Persistent worktrees (server, client, copy, audio, visual, ci, planning,
maintenance) caused agents crossing boundaries, stuck agents leaving
uncommitted work, and index.lock collisions. Replaced with ephemeral
sprint branches (sprint-{N}/{team}) and worktrees created on demand.
Changes:
- New start-sprint script replaces start-session (dynamic tabs per active team)
- Sprint teardown integrated into sprint-start skill (A1c step)
- SR_DB_PATH env var for database access from any directory
- CLAUDE.md team boundaries rewritten (scope-based, not directory-based)
- Agent Rule 0 updated to team scope dirs instead of worktree isolation
- PR review uses git show instead of cross-directory reads
- Briefing template updated for sprint-{N}/{team} branch naming
- Deleted worktree-update skill (obsolete)
- Removed WORKTREE_TEAM env var and cross-directory Read permissions
- All 8 persistent worktrees removed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add session_hash to all API calls (maintains gr.State between
image_to_3d and extract_glb)
- Pass is_multiimage=False at position 2 (9-param image_to_3d)
- Pass output_buf=None at position 0 (3-param extract_glb)
- Document full API parameter reference and failure modes
- Add trellis-batch.sh for gentle sequential batch generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplified image-gen SKILL.md, removed obsolete DDS/style references
(replaced by Gemini API connector). Updated audio_connector, gitignore,
and CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New skill for converting concept images to game-ready .glb models via
Trellis (image-to-3D) and Blender post-processing (scale normalization,
material setup, recolor mask generation).
Connectors: trellis_connector.py (Gradio API), image_connector.py
(Gemini API for concept art).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update wiki_sync.py and process-wiki-system-changes to remove
astronomical_id references. Add migrate-s-to-gj.py migration script.
Update generate-stubs.py and validate-ron for new schema.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New data flow: wiki → star-map.json + SQLite.
- tooling/process-wiki-system-changes: unified script that reads
wiki, updates star-map.json topology, syncs to SQLite
- tooling/db/wiki_sync.py: wiki frontmatter parser + SQLite upsert
- generate-stubs.py: updated for full-frontmatter wiki format
- Removed extract-csv.py (replaced by SQLite queries)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Updated docstrings in sqlite_connector, qdrant_connector,
decisions_sync, schema.sql, and two doc comments in generator.rs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Consolidates all connector scripts under tooling/ per project
structure conventions. Symlink at db/connectors → tooling/db/
preserves backwards compatibility (remove after Sprint 22).
Updated references in CLAUDE.md, Makefile, DEVOPS.md, all skill
files, agent files, rules, schema comments, and Sprint 21
briefings. Python scripts updated with correct SCHEMA_PATH
(now relative to WORKTREE_ROOT/db/schema.sql).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>