diff --git a/.claude/agents/clerk.md b/.claude/agents/clerk.md index 63b6469d1..c0c91f6ac 100644 --- a/.claude/agents/clerk.md +++ b/.claude/agents/clerk.md @@ -24,7 +24,7 @@ You check whether a diff is consistent with the project's institutional knowledg **This file is the manual-audit prompt.** Report findings directly, with a citation (D/Q/R-record or ticket) for each. No file writes, no binary gate needed. -**Pre-push hook (separate prompt, dormant by default):** the hook's clerk step only runs with `SR_RUN_CLERK=1` set (disabled otherwise, #965). When enabled, `tooling/clerk-review` spawns `claude -p` with its own inline prompt — not this file — writes findings to `.cache/pre-push-review.md`, and outputs one of `APPROVED` / `REJECTED` / `INCOMPLETE` to stdout. If you're auditing that path, read `tooling/clerk-review` itself; this persona doesn't drive it. +**Pre-push hook (separate prompt, dormant by default):** the hook's clerk step only runs with `SR_RUN_CLERK=1` set (disabled otherwise, #965). When enabled, `reach dev clerk` (`tooling/domains/dev/clerk.py`) spawns `claude -p` with its own inline prompt — not this file — writes findings to `.cache/pre-push-review.md`, and outputs one of `APPROVED` / `REJECTED` / `INCOMPLETE` to stdout. If you are auditing that path, read `tooling/domains/dev/clerk.py` itself; this persona doesn't drive it. ## What you do NOT do diff --git a/.claude/rules/ticket-cli.md b/.claude/rules/ticket-cli.md index 997ef48d3..781e2ab77 100644 --- a/.claude/rules/ticket-cli.md +++ b/.claude/rules/ticket-cli.md @@ -74,7 +74,7 @@ pql plan rebuild # drop + replay changelog from scratch (post-checkout/rew pql decisions claim D "title" # next free id, no side effects (D | Q | R) pql decisions list [--type confirmed|question|rejected] [--domain X] pql decisions show D-010 [--with-tickets] -pql decisions read D-238 # full markdown body +pql decisions show D-238 # includes the full markdown body (there is no `read` verb) pql decisions refs D-010 # cross-references pql decisions sync # parse governance/*.md -> pql.db pql decisions validate # malformed-record gate (pre-commit) diff --git a/.claude/skills/atlas/SKILL.md b/.claude/skills/atlas/SKILL.md index 71594b96a..b91f7d629 100644 --- a/.claude/skills/atlas/SKILL.md +++ b/.claude/skills/atlas/SKILL.md @@ -14,7 +14,8 @@ allowed-tools: Bash, Read, Grep, Glob, Write, Edit, Agent Query and manage celestial bodies (planets, moons, gas giants, asteroid belts, oort clouds) and stations in `server/data/systems.db`. -**CLI binary:** `tooling/atlas` (wraps `cargo run --bin atlas`) +**CLI:** `reach atlas db ` fronts the Rust `atlas` binary (built on demand); +the other `reach atlas …` verbs wrap the proposal workflow (T-1285) **Database:** `server/data/systems.db` (auto-detected from working directory) **All output is JSON on stdout.** @@ -22,28 +23,28 @@ oort clouds) and stations in `server/data/systems.db`. ### Show full system hierarchy ```bash -tooling/atlas show-system "GJ 15A" +reach atlas db show-system "GJ 15A" ``` Returns: system info + all bodies + all stations in the system. ### Show a single body ```bash -tooling/atlas show-body "GJ15Ab" +reach atlas db show-body "GJ15Ab" ``` Returns: body details + stations orbiting that body. ### Show a single station ```bash -tooling/atlas show-station "GJ15Ab-S1" +reach atlas db show-station "GJ15Ab-S1" ``` ### List systems with filters ```bash -tooling/atlas list-systems -tooling/atlas list-systems --sector west_reach -tooling/atlas list-systems --sector west_reach --hop 7 -tooling/atlas list-systems --sector west_reach --unfinished -tooling/atlas list-systems --sector east_reach --finished +reach atlas db list-systems +reach atlas db list-systems --sector west_reach +reach atlas db list-systems --sector west_reach --hop 7 +reach atlas db list-systems --sector west_reach --unfinished +reach atlas db list-systems --sector east_reach --finished ``` Sectors: `north_reach`, `south_reach`, `east_reach`, `west_reach`, `deep_frontier`, `core` Returns: system_id, proper_name, star_type, spectral_class, gate_topology, @@ -51,39 +52,39 @@ geographic_sector, hop_distance, population. Sorted by hop then system_id. ### Unfinished systems (with optional sector filter) ```bash -tooling/atlas unfinished -tooling/atlas unfinished --sector west_reach +reach atlas db unfinished +reach atlas db unfinished --sector west_reach ``` ### Next hop (with optional sector filter) ```bash -tooling/atlas next -tooling/atlas next 7 -tooling/atlas next --sector west_reach -tooling/atlas next 8 --sector west_reach +reach atlas db next +reach atlas db next 7 +reach atlas db next --sector west_reach +reach atlas db next 8 --sector west_reach ``` ### List bodies with filters ```bash -tooling/atlas list-bodies -tooling/atlas list-bodies --system "GJ 15A" -tooling/atlas list-bodies --type planet -tooling/atlas list-bodies --type planet --inhabited -tooling/atlas list-bodies --unnamed +reach atlas db list-bodies +reach atlas db list-bodies --system "GJ 15A" +reach atlas db list-bodies --type planet +reach atlas db list-bodies --type planet --inhabited +reach atlas db list-bodies --unnamed ``` Types: `planet`, `moon`, `gas_giant`, `asteroid_belt`, `oort_cloud` ### List stations with filters ```bash -tooling/atlas list-stations -tooling/atlas list-stations --system "GJ 15A" -tooling/atlas list-stations --type horizon +reach atlas db list-stations +reach atlas db list-stations --system "GJ 15A" +reach atlas db list-stations --type horizon ``` Types: `horizon`, `commercial`, `military`, `research`, `industrial`, `agricultural`, `transit` ### Add a body ```bash -tooling/atlas add-body \ +reach atlas db add-body \ --id "GJ15Ab" \ --system "GJ 15A" \ --type planet \ @@ -99,7 +100,7 @@ tooling/atlas add-body \ ### Add a station ```bash -tooling/atlas add-station \ +reach atlas db add-station \ --id "GJ15Ab-S1" \ --system "GJ 15A" \ --orbits "GJ15Ab" \ @@ -111,13 +112,13 @@ tooling/atlas add-station \ ### Database statistics ```bash -tooling/atlas stats +reach atlas db stats ``` Returns: system count, body count by type, inhabited count, station count by type. ### Corridor status (remaining unfinished systems) ```bash -tooling/atlas corridor-status +reach atlas db corridor-status ``` Shows remaining unfinished systems grouped by geographic sector and hop distance. Supersedes the old bulk-populate classifier pass (removed) — use @@ -125,8 +126,8 @@ the per-system `author` → review → `commit-system` workflow below instead. ### Update a system-level field ```bash -tooling/atlas-update-field "GJ 687" settlement_wave wave_3 -tooling/atlas-update-field "GJ 53A" star_type G +reach atlas update-field "GJ 687" settlement_wave wave_3 +reach atlas update-field "GJ 53A" star_type G ``` Updates a whitelisted field in systems.db. Auto-detects the correct table (`star_systems`, `system_gates`, or `system_history`). Inserts a row in @@ -139,11 +140,14 @@ Whitelisted fields: `star_type`, `spectral_class`, `proper_name`, ### Commit and sync a single system ```bash -tooling/atlas-commit-and-sync "GJ 105A" east_reach +reach atlas commit-and-sync "GJ 105A" --corridor east_reach # stages +reach atlas commit-and-sync "GJ 105A" --corridor east_reach --commit # and commits ``` Full pipeline: verify proposal → wipe existing data (if any) → commit to DB -→ sync wiki → git add + git commit. Second argument is the corridor tag for -the commit message (defaults to `east_reach`). +→ sync wiki → git add. **It stages by default**; `--commit` also makes the git +commit (the old script always committed). It refuses to continue when the +proposal fails verification. `--corridor` tags the commit message (default +`east_reach`). ## Body ID Naming Convention diff --git a/.claude/skills/atlas/references/author-system.md b/.claude/skills/atlas/references/author-system.md index 29af36f87..fa15dc836 100644 --- a/.claude/skills/atlas/references/author-system.md +++ b/.claude/skills/atlas/references/author-system.md @@ -25,7 +25,7 @@ This context feeds all subsequent steps but is NOT written to the JSON. ## Step 2: Astrophysical Skeleton -Run `tooling/atlas author "{system_id}"` to generate the base proposal JSON. +Run `reach atlas db author "{system_id}"` to generate the base proposal JSON. Enrich with realistic body counts per star type: - G/F stars: 8+ planets @@ -83,7 +83,7 @@ Either can flag issues that loop back to Step 3. ## Step 6: Integrity Check ```bash -tooling/atlas-verify docs/atlas/proposals/{id}.json +reach atlas verify docs/atlas/proposals/{id}.json ``` All checks from `references/integrity-check.md` must pass. Fix any @@ -91,21 +91,22 @@ failures before proceeding. ## Step 7: Commit -Use the combined commit-and-sync script: +Use the combined commit-and-sync verb: ```bash -tooling/atlas-commit-and-sync "{system_id}" {corridor_tag} +reach atlas commit-and-sync "{system_id}" --corridor {corridor_tag} --commit ``` This runs: verify → wipe-if-exists → commit-system → sync-wiki → git -add + git commit in one command. The corridor_tag (e.g. `east_reach`) +add, and with `--commit` the git commit too (without it the result is only +staged). It stops if verification fails. The corridor tag (e.g. `east_reach`) is used in the commit message. If system-level DB fields need correction before committing (e.g. `star_type`, `settlement_wave`), use: ```bash -tooling/atlas-update-field "{system_id}" {field} {value} +reach atlas update-field "{system_id}" {field} {value} ``` Post-commit: verify topology section survived sync-wiki. If missing, diff --git a/.claude/skills/atlas/references/integrity-check.md b/.claude/skills/atlas/references/integrity-check.md index 4f90b0c37..ec8950be8 100644 --- a/.claude/skills/atlas/references/integrity-check.md +++ b/.claude/skills/atlas/references/integrity-check.md @@ -2,7 +2,7 @@ Run these checks on the proposal JSON before commit. All must pass. -`tooling/atlas-verify` only ever opens the proposal JSON file — it never opens +`reach atlas verify` only ever opens the proposal JSON file — it never opens `systems.db`. Checks that require comparing against the live database (2, 4) are **not enforced by the script** and must be performed manually or by the authoring agent before commit. @@ -63,7 +63,7 @@ authoring agent before commit. ## Running the Check ```bash -tooling/atlas-verify docs/atlas/proposals/{id}.json +reach atlas verify docs/atlas/proposals/{id}.json ``` Or verify all proposals at once: diff --git a/.claude/skills/wiki/SKILL.md b/.claude/skills/wiki/SKILL.md index 7114abf65..90983c570 100644 --- a/.claude/skills/wiki/SKILL.md +++ b/.claude/skills/wiki/SKILL.md @@ -57,7 +57,7 @@ single direction is "the" direction.) *Body page* (`bodies/{id}/index.md`) — different, and more dangerous: 1. Origin is the bodies catalog in `server/data/systems.db`, authored through the - atlas CLI (`tooling/atlas add-body` / `author-system`), which is + atlas CLI (`reach atlas db add-body` / `author-system`), which is atlas-CLI-owned and survives `make regen-db` (`Skill(atlas)`). 2. `scaffold_bodies.py` reads the system page's Celestial Bodies table, runs `body_definition_parser.py`, and writes the body frontmatter once. Resolution diff --git a/client/project.godot b/client/project.godot index fdbdaea05..04e1db288 100644 --- a/client/project.godot +++ b/client/project.godot @@ -15,9 +15,9 @@ config/name="The Settled Reach" ; truth (CLAUDE.md), this is the copy that survives an export. Godot bakes ; ProjectSettings into the PCK, so `application/config/version` reads the same ; in the editor and in a shipped build, where res://../project.yaml does not -; exist at all (T-1241). Kept honest by `make check-client-version`, which the +; exist at all (T-1241). Kept honest by `reach check client-version`, which the ; pre-push hook runs — do not edit this by hand without moving project.yaml too. -config/version="0.4.13" +config/version="0.4.14" run/main_scene="res://scenes/main_menu.tscn" config/features=PackedStringArray("4.6", "GL Compatibility") config/icon="res://icon.svg" diff --git a/client/scripts/build_version.gd b/client/scripts/build_version.gd index be278dbec..106d5b903 100644 --- a/client/scripts/build_version.gd +++ b/client/scripts/build_version.gd @@ -21,7 +21,7 @@ extends RefCounted ## project.yaml scan lacked. ## ## `project.yaml` remains the source of truth for the version (CLAUDE.md); the -## ProjectSettings entry is a mirror, and `tooling/check-client-version` fails +## ProjectSettings entry is a mirror, and `reach check client-version` fails ## the push if the two drift. const SETTING_KEY: String = "application/config/version" diff --git a/client/tests/test_anti_tedium.gd b/client/tests/test_anti_tedium.gd index 43fc93ec9..9af982386 100644 --- a/client/tests/test_anti_tedium.gd +++ b/client/tests/test_anti_tedium.gd @@ -256,7 +256,7 @@ func test_gauntlet_ui_stays_hidden_after_multiple_snapshots() -> void: # -- GauntletHUD Feature Tests (#496) ---------------------------------------- # Timer lifecycle, personal bests, room change, visibility. -# Spec: sprint-9/client.md #496. Ticket: tooling/db/ticket show 496. +# Spec: sprint-9/client.md #496. Ticket: pql ticket show T-496. func test_format_time_zero() -> void: # Static utility: 0 seconds → "00:00" @@ -482,7 +482,7 @@ func test_gauntlet_snapshot_roundtrip_via_apply() -> void: # -- BugReportDialog Feature Tests (#495) ------------------------------------ # Pause/unpause lifecycle, wire guard, text render, state machine. -# Spec: sprint-9/client.md #495. Ticket: tooling/db/ticket show 495. +# Spec: sprint-9/client.md #495. Ticket: pql ticket show T-495. func test_bug_report_sends_pause_on_open() -> void: # start_capture() must send Pause to the server. diff --git a/client/tests/test_step_canvas_disk_cache.gd b/client/tests/test_step_canvas_disk_cache.gd index 0de2d2dd2..60fcbf884 100644 --- a/client/tests/test_step_canvas_disk_cache.gd +++ b/client/tests/test_step_canvas_disk_cache.gd @@ -406,7 +406,7 @@ func test_baked_version_mirrors_project_yaml() -> void: # Drift guard, dev-only by nature (an export has no project.yaml to compare # against — which is the whole reason the value is baked). project.yaml stays # the source of truth; this catches the bump-one-forget-the-other case from - # inside the suite, as well as from tooling/check-client-version in the hook. + # inside the suite, as well as from `reach check client-version` in the hook. var yaml_path := ProjectSettings.globalize_path("res://") + "/../project.yaml" if not FileAccess.file_exists(yaml_path): return # exported/packaged run — nothing to compare, and nothing to guard diff --git a/client/ui/implant/apps/atlas/step_canvas/step_canvas_colorize.gd b/client/ui/implant/apps/atlas/step_canvas/step_canvas_colorize.gd index 5c15e2270..b28b41db2 100644 --- a/client/ui/implant/apps/atlas/step_canvas/step_canvas_colorize.gd +++ b/client/ui/implant/apps/atlas/step_canvas/step_canvas_colorize.gd @@ -162,7 +162,7 @@ const RELIEF_TEXTURE_FULL_SCALE_Q: int = 60 ## was consumed, but only as a stipple PROBABILITY — so a ridge and a plain ## differed in dot density, which at one pixel per cell reads as noise rather ## than as landform. Measured on the 2026-08-16 cold ladder -## (tooling/atlas-flatness): Region carried 2,923 distinct colours against +## (`reach atlas flatness`): Region carried 2,923 distinct colours against ## Global's 1,581 while holding a quarter of its structure. Colour count went UP ## and legibility went DOWN, which is the signature of texture standing in for ## form. diff --git a/docs/briefings/clerk.md b/docs/briefings/clerk.md index aed461a36..e56f5450b 100644 --- a/docs/briefings/clerk.md +++ b/docs/briefings/clerk.md @@ -23,13 +23,15 @@ Review branch changes before push to catch institutional drift: decision contrad ## Where to Find Decisions -- **Decision index:** `decisions/README.md` — master index of all domain files -- **Domain files:** `decisions/architecture.md`, `decisions/perception.md`, `decisions/content.md`, `decisions/scope.md`, `decisions/economics.md`, `decisions/process.md` -- **Open questions:** `decisions/questions.md`, `decisions/questions-process.md` -- **Rejected proposals:** `decisions/rejected.md` -- **Decision DB table:** +- **Decision index:** `governance/README.md` — the domain guide and the pql-maintained record index +- **Confirmed decisions:** `governance/decisions/.md` — architecture, perception, content, scope, economics, process +- **Open questions:** `governance/questions/.md` +- **Rejected proposals:** `governance/rejected/.md` +- **Queries** (pql; never the `sqlite3` CLI, which crashes in Claude Code): ```bash - tooling/db/sqlite-query "SELECT id, title, status, domain FROM decisions WHERE domain = ''" + pql decisions list --domain + pql decisions list --type question + pql decisions refs D-NNN # what cites a record ``` ## Output diff --git a/docs/briefings/si.md b/docs/briefings/si.md index 273fd59db..7ad210f90 100644 --- a/docs/briefings/si.md +++ b/docs/briefings/si.md @@ -26,14 +26,15 @@ If any of these conditions fail, the ticket is not ready. Flag what is missing a ## Where to Find Decisions -- **Decision index:** `decisions/README.md` — lists all domain files and how to query them -- **Domain files:** `decisions/architecture.md`, `decisions/perception.md`, `decisions/content.md`, `decisions/scope.md`, `decisions/economics.md`, `decisions/process.md` -- **Open questions:** `decisions/questions.md` (Q-NNN), `decisions/questions-process.md` (Q-NNN process) -- **Rejected proposals:** `decisions/rejected.md` (R-NNN) -- **Decision DB queries:** +- **Decision index:** `governance/README.md` — the domain guide and the pql-maintained record index +- **Confirmed decisions (D-NNN):** `governance/decisions/.md` — architecture, perception, content, scope, economics, process +- **Open questions (Q-NNN):** `governance/questions/.md` +- **Rejected proposals (R-NNN):** `governance/rejected/.md` +- **Queries** (pql — the old `tooling/db/decision` CLI was retired in the pql migration): ```bash - tooling/db/decision show D-NNN # Show a specific decision - tooling/db/decision check-dupes "title" # Check for duplicates before creating + pql decisions show D-NNN # one record, with its markdown body + pql decisions list --type question # open questions + pql decisions claim D "title" # next free id, before writing a new one ``` ## Where to Find Workshop Outcomes diff --git a/docs/diagrams/data-flow/wiki-generator-flow.d2 b/docs/diagrams/data-flow/wiki-generator-flow.d2 index 15afd7754..e74c96e72 100644 --- a/docs/diagrams/data-flow/wiki-generator-flow.d2 +++ b/docs/diagrams/data-flow/wiki-generator-flow.d2 @@ -13,7 +13,7 @@ # red = the trap (output that is read back as input) # # Every path here was read in the tool's own source, not inferred. -# tooling/check-dataflow-graph asserts the paths still exist; it CANNOT verify +# `reach check dataflow-graph` asserts the paths still exist; it CANNOT verify # that an edge's MEANING is still true — see D-262. # # View it: clide draw --file docs/diagrams/data-flow/wiki-generator-flow.d2 diff --git a/project.yaml b/project.yaml index 371935e89..83d8defa4 100644 --- a/project.yaml +++ b/project.yaml @@ -67,7 +67,11 @@ name: The Settled Reach # here, not merely stale. # 0.4.13 — stipple contrast (T-1194). Paint only; bumped because the client # step_canvas cluster is in the T-1242 registry. -version: 0.4.13 +# 0.4.14 carries NO canvas-generation change: comment-only edits (retired tool +# paths renamed to their reach verbs, T-1289/T-1253) touched +# server/src/atlas/trait_catalog_reader.rs, canvas_sources.py itself, and two +# client files in the registry. Path-based gate, spent rather than dodged. +version: 0.4.14 repository: settled-reach diff --git a/server/data/systems.db b/server/data/systems.db index f9342276d..364428ee0 100644 Binary files a/server/data/systems.db and b/server/data/systems.db differ diff --git a/server/src/atlas/atlas_data_proxy.rs b/server/src/atlas/atlas_data_proxy.rs index 01222abe8..bd9fcfe80 100644 --- a/server/src/atlas/atlas_data_proxy.rs +++ b/server/src/atlas/atlas_data_proxy.rs @@ -3,7 +3,7 @@ //! //! - **Star map** ([`StarMapRequest`]/[`StarMapResponse`]): a session-scoped, //! non-per-body proxy over the static `client/data/star_map_data.json` -//! dataset (produced by `tooling/generate-star-map-data.py`). Reads the file +//! dataset (produced by `reach atlas map data`). Reads the file //! fresh on every request — no caching, no staleness handling — because the //! client only asks once per session when the Atlas star-map view opens. //! The parsed JSON is passed through as an opaque `serde_json::Value` rather @@ -79,7 +79,7 @@ pub enum StarMapStatus { pub struct StarMapResponse { pub status: StarMapStatus, /// Verbatim parsed JSON (`_meta`, `nodes`, `edges` — see - /// `tooling/generate-star-map-data.py`), re-serialized as MessagePack. + /// `reach atlas map data`), re-serialized as MessagePack. /// `None` unless `status == Ready`. pub data: Option, } diff --git a/server/src/bin/atlas/main.rs b/server/src/bin/atlas/main.rs index a57d9f331..976130781 100644 --- a/server/src/bin/atlas/main.rs +++ b/server/src/bin/atlas/main.rs @@ -3,10 +3,10 @@ //! # Usage //! //! ```sh -//! # Via wrapper script (recommended): -//! tooling/atlas list-bodies --system "GJ 15A" -//! tooling/atlas list-bodies --type planet --inhabited -//! tooling/atlas show-system "GJ 15A" +//! # Via reach (recommended — builds the binary on demand): +//! reach atlas db list-bodies --system "GJ 15A" +//! reach atlas db list-bodies --type planet --inhabited +//! reach atlas db show-system "GJ 15A" //! tooling/atlas show-body "GJ 15Ab" //! tooling/atlas add-body --system "GJ 15A" --type planet --orbit 1 --id "GJ 15Ab" //! tooling/atlas stats diff --git a/server/src/bin/generate_brands/main.rs b/server/src/bin/generate_brands/main.rs index 2510c91e1..85ba4129a 100644 --- a/server/src/bin/generate_brands/main.rs +++ b/server/src/bin/generate_brands/main.rs @@ -511,7 +511,7 @@ fn write_output(path: &PathBuf, products: &[BrandProduct], inputs: &[BrandInput] let mut out = String::new(); out.push_str("# Generated Minor Brand Products — The Settled Reach\n"); out.push_str("# Auto-generated by generate_brands binary. Do not hand-edit.\n"); - out.push_str("# Re-run: tooling/generate-brands\n"); + out.push_str("# Re-run: reach generate brands\n"); out.push_str(&format!( "# Total: {} brand_products, {} brand_inputs\n\n", products.len(), diff --git a/server/src/bin/shared/surname_corpus.rs b/server/src/bin/shared/surname_corpus.rs index b9097674c..f7ca22835 100644 --- a/server/src/bin/shared/surname_corpus.rs +++ b/server/src/bin/shared/surname_corpus.rs @@ -9,7 +9,7 @@ //! `main.rs` — this directory is not a cargo bin target (no `main.rs`). //! //! NOTE: both binaries feed the systems.db meta stamp — this file is part of -//! the `import_economics` source set in `tooling/check-systems-db-stamp` +//! the `import_economics` source set checked by `reach check systems-db-stamp` //! (GENERATOR_SOURCES). Changing any pool requires `make regen-db`. //! Pool contents are surname data drawn from founding cultures in wiki canon; //! ordering is load-bearing (index-based RNG draws), so never reorder. diff --git a/server/src/bin/validate_ron.rs b/server/src/bin/validate_ron.rs index 21b8ad948..3a7a29411 100644 --- a/server/src/bin/validate_ron.rs +++ b/server/src/bin/validate_ron.rs @@ -8,8 +8,8 @@ //! //! ```sh //! # Via wrapper script (recommended): -//! tooling/validate-ron server/content/global/zone-identity-spec.example.ron zone -//! tooling/validate-ron server/content/global/culture-van-maanens-star.example.ron culture +//! reach validate ron server/content/global/zone-identity-spec.example.ron zone +//! reach validate ron server/content/global/culture-van-maanens-star.example.ron culture //! //! # Direct: //! cargo run --bin validate_ron -- diff --git a/server/src/main.rs b/server/src/main.rs index 891f0deac..e1791b5c4 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -230,7 +230,7 @@ fn main() { } // Star-map dataset proxy (T-949a): resolve the repo-root-relative path to - // the client's pre-generated star_map_data.json (tooling/generate-star-map-data.py). + // the client's pre-generated star_map_data.json (`reach atlas map data`). // Read fresh on every request — no caching, see atlas_data_proxy module doc. let star_map_data_path = world_root.join("client/data/star_map_data.json"); if star_map_data_path.exists() { diff --git a/server/src/npc/blueprint.rs b/server/src/npc/blueprint.rs index 42c80d564..3a489d847 100644 --- a/server/src/npc/blueprint.rs +++ b/server/src/npc/blueprint.rs @@ -20,7 +20,7 @@ //! ## Format //! //! RON (Rusty Object Notation) — struct-aware, supports enums and comments. -//! Validate with: `tooling/validate-ron ` +//! Validate with: `reach validate ron ` use rand::Rng; use serde::{Deserialize, Serialize}; @@ -112,7 +112,7 @@ pub struct SocialSiteSpec { /// NPCs per site) — that lives on `LocationSpec.social_sites`. /// /// The Rust struct IS the schema. RON files must match this struct exactly. -/// Validate with: `tooling/validate-ron server/content/global/zone-types/.ron zone_type` +/// Validate with: `reach validate ron server/content/global/zone-types/.ron zone_type` #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ZoneTypeTemplate { /// Canonical zone-type identifier (e.g. `"rural_agricultural"`). diff --git a/server/tests/perf_bench.rs b/server/tests/perf_bench.rs index 6cdfd0247..62d65166c 100644 --- a/server/tests/perf_bench.rs +++ b/server/tests/perf_bench.rs @@ -1,7 +1,7 @@ //! Performance benchmarks: tick timing and memory usage //! //! Run with: cargo test --release --test perf_bench -- --ignored --nocapture -//! Output: PERF_RESULT:{json} lines for tooling/perf-baseline to parse. +//! Output: PERF_RESULT:{json} lines for `reach dev perf` to parse. //! //! Tick budget target: 100ms (D-026) diff --git a/tooling/canvas_sources.py b/tooling/canvas_sources.py index deddaba7d..2da75db1f 100644 --- a/tooling/canvas_sources.py +++ b/tooling/canvas_sources.py @@ -15,7 +15,7 @@ the last only after T-1239 spent eight days diagnosing a map drawn from a canvas whose generating code had been replaced. The failure is invisible to its author: it reproduces only where a warm cache exists, so a cold checkout looks fine. -This module is the registry `tooling/check-canvas-version` intersects against, +This module is the registry `reach check canvas-version` intersects against, kept here rather than inline in the hook for the same reason `tooling/generator_sources.py` exists (T-1067): one list, one place, imported by everything that needs it. diff --git a/tooling/domains/atlas/flatness.py b/tooling/domains/atlas/flatness.py index b477ce936..a816ad8e8 100755 --- a/tooling/domains/atlas/flatness.py +++ b/tooling/domains/atlas/flatness.py @@ -24,8 +24,8 @@ variation a map is actually read for; distinct-count is reported alongside precisely so the two can be seen disagreeing. Usage: - tooling/atlas-flatness .cache/screenshots/atlas_GJ820Bc_land_Region.png [...] - tooling/atlas-flatness --ladder # the standard descent ladder + reach atlas flatness .cache/screenshots/atlas_GJ820Bc_land_Region.png [...] + reach atlas flatness --ladder # the standard descent ladder """ import sys diff --git a/tooling/domains/atlas/proposal_check.py b/tooling/domains/atlas/proposal_check.py index f5fd471fa..fed02fe9c 100755 --- a/tooling/domains/atlas/proposal_check.py +++ b/tooling/domains/atlas/proposal_check.py @@ -2,7 +2,7 @@ """Quick diagnostic for an atlas proposal — shows planet count, body summary, and flags. Usage: - tooling/atlas-check docs/atlas/proposals/GJ1075.json + reach atlas check docs/atlas/proposals/GJ1075.json """ import json from pathlib import Path diff --git a/tooling/domains/atlas/verify.py b/tooling/domains/atlas/verify.py index 2355350db..552ebde76 100755 --- a/tooling/domains/atlas/verify.py +++ b/tooling/domains/atlas/verify.py @@ -2,8 +2,8 @@ """Verify an atlas proposal JSON against integrity checks. Usage: - tooling/atlas-verify docs/atlas/proposals/GJ273.json - tooling/atlas-verify docs/atlas/proposals/*.json + reach atlas verify docs/atlas/proposals/GJ273.json + reach atlas verify docs/atlas/proposals/*.json """ import json from pathlib import Path diff --git a/tooling/domains/visual/blank_check.py b/tooling/domains/visual/blank_check.py index 2563ed8cd..2588cd4b0 100755 --- a/tooling/domains/visual/blank_check.py +++ b/tooling/domains/visual/blank_check.py @@ -33,7 +33,7 @@ on the screen", never "is the world any good". Keep it that way; a check that creeps toward aesthetics will start failing legitimate frames and get muted. Usage: - tooling/visual-blank-check [--max-modal 0.85] [--quiet] + reach visual blank-check [--max-modal 0.85] [--quiet] Exit: 0 = has content, 1 = blank, 2 = error (unreadable/missing). """ diff --git a/tooling/domains/visual/diff.py b/tooling/domains/visual/diff.py index 14087320a..8eabddc23 100755 --- a/tooling/domains/visual/diff.py +++ b/tooling/domains/visual/diff.py @@ -5,7 +5,7 @@ Compares two PNG images per-channel with configurable tolerance. Reads default tolerance from tests/visual.json if available. Usage: - tooling/visual-diff EXPECTED ACTUAL [--tolerance N] [--diff-output PATH] [--config PATH] + reach visual diff EXPECTED ACTUAL [--tolerance N] [--diff-output PATH] [--config PATH] Exit codes: 0 = images match (all pixels within tolerance) diff --git a/tooling/domains/visual/thumbnail.py b/tooling/domains/visual/thumbnail.py index 69e763f3f..c1e5da597 100755 --- a/tooling/domains/visual/thumbnail.py +++ b/tooling/domains/visual/thumbnail.py @@ -4,13 +4,13 @@ Two modes: Grid mode (default): - tooling/visual-thumbnail DIR [--config PATH] + reach visual thumbnail DIR [--config PATH] Reads {flow}_{NNN}.png frames + {flow}_manifest.txt sidecar from DIR, generates a contact sheet grid with timecodes and labels. Output: DIR/{flow}_sheet.png Crop mode: - tooling/visual-thumbnail --crop REGION IMAGE [--config PATH] + reach visual thumbnail --crop REGION IMAGE [--config PATH] Extracts a named region from IMAGE at 1:1 scale. Output: IMAGE_crop_{REGION}.png diff --git a/tooling/scripts/blender/blender_author_boots.py b/tooling/scripts/blender/blender_author_boots.py index a6b8395ce..302914bad 100644 --- a/tooling/scripts/blender/blender_author_boots.py +++ b/tooling/scripts/blender/blender_author_boots.py @@ -70,8 +70,7 @@ stays faithful; the brown/black work-street default lives in the manifest default_tints (sole near-black, upper work brown, laces dark). Usage (boots_modern reference invocation): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_boots.py -- \ + reach blender run blender_author_boots \ client/assets/characters/bodies \ client/assets/characters/clothing/boots_modern \ [--bodies average_m,child,...] [--offset 0.013] [--shaft-frac 0.30] \ diff --git a/tooling/scripts/blender/blender_author_buttondown.py b/tooling/scripts/blender/blender_author_buttondown.py index 52d754ed0..eb996fb52 100644 --- a/tooling/scripts/blender/blender_author_buttondown.py +++ b/tooling/scripts/blender/blender_author_buttondown.py @@ -28,8 +28,7 @@ channel is still authored (costs nothing; enables future brand variants). Run (per-body only — this garment ships the per-body route): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_buttondown.py -- \ + reach blender run blender_author_buttondown \ client/assets/characters/bodies \ client/assets/characters/clothing/buttondown_modern \ [--bodies average_m,child,...] [--offset 0.009] diff --git a/tooling/scripts/blender/blender_author_cargo_pants.py b/tooling/scripts/blender/blender_author_cargo_pants.py index cd7e5b4f8..354ea474f 100644 --- a/tooling/scripts/blender/blender_author_cargo_pants.py +++ b/tooling/scripts/blender/blender_author_cargo_pants.py @@ -38,8 +38,7 @@ boundaries give the waist opening and ankle hems. Regions are painted, not modelled — no 3D pocket geometry (texture carries identity). Usage (cargo_pants reference invocation): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_cargo_pants.py -- \ + reach blender run blender_author_cargo_pants \ client/assets/characters/bodies \ client/assets/characters/clothing/cargo_pants \ [--bodies average_m,child,...] [--offset 0.013] [--hem-frac 1.0] \ diff --git a/tooling/scripts/blender/blender_author_denim_pants.py b/tooling/scripts/blender/blender_author_denim_pants.py index c52544a8a..ef12b4141 100644 --- a/tooling/scripts/blender/blender_author_denim_pants.py +++ b/tooling/scripts/blender/blender_author_denim_pants.py @@ -51,8 +51,7 @@ base.derive_thresholds, so the denim details stay consistent across all 11 bodies. Per-body mode only (offset shells author per body, Q-060). Usage (jeans_modern reference invocation): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_denim_pants.py -- \ + reach blender run blender_author_denim_pants \ client/assets/characters/bodies \ client/assets/characters/clothing/jeans_modern \ [--bodies average_m,child,...] [--offset 0.012] [--hem-frac 1.0] \ diff --git a/tooling/scripts/blender/blender_author_hoodie.py b/tooling/scripts/blender/blender_author_hoodie.py index 44673e2a8..c84ff2db9 100644 --- a/tooling/scripts/blender/blender_author_hoodie.py +++ b/tooling/scripts/blender/blender_author_hoodie.py @@ -27,8 +27,7 @@ Hoodie deltas over the base t-shirt shell: PER-BODY ONLY (Q-060: offset-shells are authored per body, never SD-fit): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_hoodie.py -- \ + reach blender run blender_author_hoodie \ client/assets/characters/bodies client/assets/characters/clothing/hoodie_modern \ [--bodies a,b,c] [--offset M] diff --git a/tooling/scripts/blender/blender_author_jacket_shell.py b/tooling/scripts/blender/blender_author_jacket_shell.py index 7c6a476ad..62ee25167 100644 --- a/tooling/scripts/blender/blender_author_jacket_shell.py +++ b/tooling/scripts/blender/blender_author_jacket_shell.py @@ -35,8 +35,7 @@ cut/paint constants — calibrated to the intended metric sizes on average_m. PER-BODY ONLY: offset-shell garments are authored per body (Q-060 route guidance) — there is no single-reference mode here. - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_jacket_shell.py -- \ + reach blender run blender_author_jacket_shell \ \ [--bodies average_m,child,...] [--offset 0.018] [--wrist-frac 0.85] diff --git a/tooling/scripts/blender/blender_author_joggers.py b/tooling/scripts/blender/blender_author_joggers.py index 78d944ee5..7409e5456 100644 --- a/tooling/scripts/blender/blender_author_joggers.py +++ b/tooling/scripts/blender/blender_author_joggers.py @@ -47,8 +47,7 @@ boundaries give the waist opening and ankle hems for free. Per-body mode only (offset shells author per body, Q-060). Usage (joggers_modern reference invocation): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_joggers.py -- \ + reach blender run blender_author_joggers \ client/assets/characters/bodies \ client/assets/characters/clothing/joggers_modern \ [--bodies average_m,child,...] [--offset 0.014] [--mid-offset 0.010] \ diff --git a/tooling/scripts/blender/blender_author_lower_shell.py b/tooling/scripts/blender/blender_author_lower_shell.py index 633873c66..90966c10b 100644 --- a/tooling/scripts/blender/blender_author_lower_shell.py +++ b/tooling/scripts/blender/blender_author_lower_shell.py @@ -29,8 +29,7 @@ Per-body mode only (route guidance from Q-060 / 216-capture QA evidence: offset-shell garments author per body; weights inherited by construction). Usage: - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_lower_shell.py -- \ + reach blender run blender_author_lower_shell \ \ [--bodies a,b,c] [--offset 0.010] [--leg-frac 1.0] \ [--waistband-frac 1.0] [--cuff-frac 0.0] \ diff --git a/tooling/scripts/blender/blender_author_offset_coverall.py b/tooling/scripts/blender/blender_author_offset_coverall.py index 7d77038b5..21dd28577 100644 --- a/tooling/scripts/blender/blender_author_offset_coverall.py +++ b/tooling/scripts/blender/blender_author_offset_coverall.py @@ -37,8 +37,7 @@ Painted albedo details (flat, toon-friendly; identity lives in the texture): Per-body only (this garment ships per-body per the Q-060 route guidance): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_offset_coverall.py -- \ + reach blender run blender_author_offset_coverall \ [--bodies a,b,c] [--offset 0.012] Writes per body: diff --git a/tooling/scripts/blender/blender_author_offset_shell.py b/tooling/scripts/blender/blender_author_offset_shell.py index f4ed970a1..5b5da3f7a 100644 --- a/tooling/scripts/blender/blender_author_offset_shell.py +++ b/tooling/scripts/blender/blender_author_offset_shell.py @@ -33,8 +33,7 @@ SINGLE-REFERENCE (default) — author on one body (average_m); G1 (blender_batch_fit_skinned.py) SD-fits it to the other body types. Right for derived/hand-authored garments that share one UV layout + one mask. - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_offset_shell.py -- \ + reach blender run blender_author_offset_shell \ /average_m [--offset 0.020] [--sleeve-frac 0.40] Writes: @@ -51,8 +50,7 @@ from each body's OWN bone landmarks using the same proportional ratios (anchored to reproduce the hand-calibrated average_m constants exactly), so regions stay consistent across bodies. - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_offset_shell.py -- \ + reach blender run blender_author_offset_shell \ --per-body \ [--bodies average_m,child,...] [--offset 0.012] [--sleeve-frac 0.40] diff --git a/tooling/scripts/blender/blender_author_offset_shell_legs.py b/tooling/scripts/blender/blender_author_offset_shell_legs.py index 3bb74f167..438ee87bc 100644 --- a/tooling/scripts/blender/blender_author_offset_shell_legs.py +++ b/tooling/scripts/blender/blender_author_offset_shell_legs.py @@ -36,8 +36,7 @@ consistency with torso garments (all UVs outside [0,1] → shader draws nothing) Modes mirror the base script: PER-BODY (preferred for offset shells, Q-060): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_offset_shell_legs.py -- \ + reach blender run blender_author_offset_shell_legs \ --per-body \ [--bodies a,b,c] [--offset 0.012] [--hem-frac 0.78] [--waistband-frac 0.35] @@ -46,8 +45,7 @@ PER-BODY (preferred for offset shells, Q-060): fallback for the compositor). SINGLE-REFERENCE: - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_offset_shell_legs.py -- \ + reach blender run blender_author_offset_shell_legs \ /average_m [--offset 0.020] [...] Decisions: D-162 (clothing pre-fitted per body type), D-251 (in-house wardrobe). diff --git a/tooling/scripts/blender/blender_author_outerwear.py b/tooling/scripts/blender/blender_author_outerwear.py index c256e8c60..36a51a0e0 100644 --- a/tooling/scripts/blender/blender_author_outerwear.py +++ b/tooling/scripts/blender/blender_author_outerwear.py @@ -25,8 +25,7 @@ What it adds over the base t-shirt shell: Per-body only (this family is the poster child for the Q-060 per-body route): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_outerwear.py -- \ + reach blender run blender_author_outerwear \ \ [--bodies a,b,c] [--offset 0.022] [--cuff-keep 0.88] diff --git a/tooling/scripts/blender/blender_author_parka.py b/tooling/scripts/blender/blender_author_parka.py index fe1c5a127..0ae7bd34f 100644 --- a/tooling/scripts/blender/blender_author_parka.py +++ b/tooling/scripts/blender/blender_author_parka.py @@ -36,8 +36,7 @@ top, combining the proven practices of the wave-1 family: Per-body only (Q-060: offset shells author per body, never SD-fit): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_parka.py -- \ + reach blender run blender_author_parka \ client/assets/characters/bodies client/assets/characters/clothing/parka_thrds \ [--bodies a,b,c] [--offset 0.026] [--hem-frac 0.15] diff --git a/tooling/scripts/blender/blender_author_shoes_formal.py b/tooling/scripts/blender/blender_author_shoes_formal.py index 3c72229ba..ff7c009e8 100644 --- a/tooling/scripts/blender/blender_author_shoes_formal.py +++ b/tooling/scripts/blender/blender_author_shoes_formal.py @@ -63,8 +63,7 @@ same proportional-ratio philosophy as base.derive_thresholds. Per-body mode only (offset shells author per body, Q-060). Usage (shoes_formal reference invocation): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_shoes_formal.py -- \ + reach blender run blender_author_shoes_formal \ client/assets/characters/bodies \ client/assets/characters/clothing/shoes_formal \ [--bodies average_m,child,...] [--offset 0.006] [--sole-mm 0.008] \ diff --git a/tooling/scripts/blender/blender_author_slides.py b/tooling/scripts/blender/blender_author_slides.py index 90b0aef7e..665c8fffd 100644 --- a/tooling/scripts/blender/blender_author_slides.py +++ b/tooling/scripts/blender/blender_author_slides.py @@ -52,8 +52,7 @@ torso/leg companion provides, as reusable parameters: never lands on an untinted texel. Usage (per-body only — offset shells author per body, Q-060): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_slides.py -- \ + reach blender run blender_author_slides \ client/assets/characters/bodies \ client/assets/characters/clothing/slides \ [--bodies average_m,child,...] [--offset 0.005] \ diff --git a/tooling/scripts/blender/blender_author_sneakers.py b/tooling/scripts/blender/blender_author_sneakers.py index 31528e68e..394cd9c55 100644 --- a/tooling/scripts/blender/blender_author_sneakers.py +++ b/tooling/scripts/blender/blender_author_sneakers.py @@ -56,8 +56,7 @@ UV space whose islands may overlap; every painted feature is |x|-mirror symmetric, so overlapping texels agree by construction. Usage (sneakers_modern reference invocation): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_sneakers.py -- \ + reach blender run blender_author_sneakers \ client/assets/characters/bodies \ client/assets/characters/clothing/sneakers_modern \ [--bodies average_m,child,...] [--offset 0.009] [--sole-drop 0.015] \ diff --git a/tooling/scripts/blender/blender_author_sweater.py b/tooling/scripts/blender/blender_author_sweater.py index 2e6267edb..31b3cecec 100644 --- a/tooling/scripts/blender/blender_author_sweater.py +++ b/tooling/scripts/blender/blender_author_sweater.py @@ -50,8 +50,7 @@ as reusable parameters: PER-BODY ONLY (Q-060: offset shells are authored per body, never SD-fit): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_sweater.py -- \ + reach blender run blender_author_sweater \ client/assets/characters/bodies \ client/assets/characters/clothing/sweater_modern \ [--bodies average_m,child,...] [--offset 0.014] [--hem-drop 0.30] \ diff --git a/tooling/scripts/blender/blender_author_swim_trunks.py b/tooling/scripts/blender/blender_author_swim_trunks.py index d122f7143..b397e5538 100644 --- a/tooling/scripts/blender/blender_author_swim_trunks.py +++ b/tooling/scripts/blender/blender_author_swim_trunks.py @@ -40,8 +40,7 @@ proportional-ratio philosophy as base.derive_thresholds. Per-body mode only (offset shells author per body, Q-060). Usage (swim_trunks reference invocation): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_swim_trunks.py -- \ + reach blender run blender_author_swim_trunks \ client/assets/characters/bodies \ client/assets/characters/clothing/swim_trunks \ [--bodies average_m,child,...] [--offset 0.012] [--hem-frac 0.60] \ diff --git a/tooling/scripts/blender/blender_author_swimsuit.py b/tooling/scripts/blender/blender_author_swimsuit.py index 2a7f1cd15..dcb29504f 100644 --- a/tooling/scripts/blender/blender_author_swimsuit.py +++ b/tooling/scripts/blender/blender_author_swimsuit.py @@ -45,8 +45,7 @@ logo_uv TEXCOORD_1 layer ships for channel consistency (not logo-capable). Per-body mode only (offset shells author per body, Q-060): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_swimsuit.py -- \ + reach blender run blender_author_swimsuit \ client/assets/characters/bodies \ client/assets/characters/clothing/swimsuit_onepiece \ [--bodies average_m,child,...] [--offset 0.012] diff --git a/tooling/scripts/blender/blender_author_tank_top.py b/tooling/scripts/blender/blender_author_tank_top.py index dbcdb1501..0a0477cde 100644 --- a/tooling/scripts/blender/blender_author_tank_top.py +++ b/tooling/scripts/blender/blender_author_tank_top.py @@ -41,8 +41,7 @@ texture carries identity, flat toon-friendly). Run (per-body only — offset shells author per body, Q-060): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_tank_top.py -- \ + reach blender run blender_author_tank_top \ client/assets/characters/bodies \ client/assets/characters/clothing/tank_top \ [--bodies average_m,child,...] [--offset 0.012] \ diff --git a/tooling/scripts/blender/blender_author_track_jacket.py b/tooling/scripts/blender/blender_author_track_jacket.py index 2140723c1..f561b06a2 100644 --- a/tooling/scripts/blender/blender_author_track_jacket.py +++ b/tooling/scripts/blender/blender_author_track_jacket.py @@ -39,8 +39,7 @@ kit needs beyond that script is delivered as reusable parameters, not hacks: PER-BODY ONLY (Q-060: offset shells are authored per body, never SD-fit): - tooling/blender --background --python \ - tooling/scripts/blender/blender_author_track_jacket.py -- \ + reach blender run blender_author_track_jacket \ client/assets/characters/bodies \ client/assets/characters/clothing/track_jacket \ [--bodies average_m,child,...] [--offset 0.018] [--wrist-keep 0.90] diff --git a/tooling/scripts/blender/blender_batch_fit_skinned.py b/tooling/scripts/blender/blender_batch_fit_skinned.py index 8fa5d8107..9df245411 100644 --- a/tooling/scripts/blender/blender_batch_fit_skinned.py +++ b/tooling/scripts/blender/blender_batch_fit_skinned.py @@ -3,7 +3,7 @@ blender_batch_fit_skinned.py (T-1089 gap G1 — the biggest wardrobe gap) Fit a reference clothing GLB (authored on average_m) to every body type and export ANIMATABLE skinned variants. This supersedes -tooling/blender_surface_deform_batch.py, whose output used export_skins=False +tooling/scripts/blender/blender_surface_deform_batch.py, whose output used export_skins=False (:142) — those variants cannot animate on the shared skeleton, which is how the runtime loads clothing (character_visual.gd:582-594). @@ -15,7 +15,7 @@ It merges three proven codepaths that had never been combined: Surface Deform bind -> apply -> Data Transfer VGROUP_WEIGHTS (POLYINTERP_NEAREST) from the fitted body -> normalize -> retarget the armature modifier to the body's armature -> export_skins=True - * optional Solidify — from tooling/convert_outfit.py (skipped by + * optional Solidify — from blender_convert_outfit.py (skipped by default; offset-shell references are already solidified) Per body type: @@ -25,8 +25,7 @@ Per body type: armature, export a skinned GLB. Run: - tooling/blender --background --python \ - tooling/scripts/blender/blender_batch_fit_skinned.py -- \ + reach blender run blender_batch_fit_skinned \ \ [--only average_m,average_f,...] [--solidify 0.0] [--self-check] diff --git a/tooling/scripts/blender/blender_compare_bones.py b/tooling/scripts/blender/blender_compare_bones.py index 188958a9c..2377ffb35 100644 --- a/tooling/scripts/blender/blender_compare_bones.py +++ b/tooling/scripts/blender/blender_compare_bones.py @@ -1,6 +1,6 @@ """ blender_compare_bones.py -Usage: tooling/blender --background --python tooling/blender_compare_bones.py -- +Usage: reach blender run blender_compare_bones Compares bone names between two GLB/GLTF files. Reports missing or extra bones. """ @@ -21,7 +21,7 @@ def get_bones(path: str) -> set: if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_compare_bones.py -- ") + print("Usage: reach blender run blender_compare_bones ") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_create_clothing_refs.py b/tooling/scripts/blender/blender_create_clothing_refs.py index 96ca225d9..09dd40ee9 100644 --- a/tooling/scripts/blender/blender_create_clothing_refs.py +++ b/tooling/scripts/blender/blender_create_clothing_refs.py @@ -2,7 +2,7 @@ blender_create_clothing_refs.py Usage: - tooling/blender --background --python tooling/blender_create_clothing_refs.py -- \\ + reach blender run blender_create_clothing_refs \\ Creates v0.2 placeholder reference clothing meshes for all 5 initial clothing items. @@ -247,8 +247,7 @@ def create_reference_mesh(item_id, config, bodies_dir, output_dir): if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python " - "tooling/blender_create_clothing_refs.py -- " + print("Usage: reach blender run blender_create_clothing_refs " " ") sys.exit(1) diff --git a/tooling/scripts/blender/blender_extract_armature.py b/tooling/scripts/blender/blender_extract_armature.py index ba52345ba..0c0afc681 100644 --- a/tooling/scripts/blender/blender_extract_armature.py +++ b/tooling/scripts/blender/blender_extract_armature.py @@ -1,6 +1,6 @@ """ blender_extract_armature.py -Usage: tooling/blender --background --python tooling/blender_extract_armature.py -- +Usage: reach blender run blender_extract_armature Loads a Quaternius GLTF file, strips all mesh objects and animation data, and exports only the armature as a GLB skeleton file. @@ -82,7 +82,7 @@ def extract_armature(input_path: str, output_path: str) -> None: if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_extract_armature.py -- ") + print("Usage: reach blender run blender_extract_armature ") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_inspect_body.py b/tooling/scripts/blender/blender_inspect_body.py index 0edf99b15..a6d7d9b37 100644 --- a/tooling/scripts/blender/blender_inspect_body.py +++ b/tooling/scripts/blender/blender_inspect_body.py @@ -1,6 +1,6 @@ """ blender_inspect_body.py -Usage: tooling/blender --background --python tooling/blender_inspect_body.py -- +Usage: reach blender run blender_inspect_body Lists all mesh objects in a FullBody GLTF: names, vertex counts, vertex group counts. """ diff --git a/tooling/scripts/blender/blender_inspect_vgroups.py b/tooling/scripts/blender/blender_inspect_vgroups.py index ce2639920..07d2bee1d 100644 --- a/tooling/scripts/blender/blender_inspect_vgroups.py +++ b/tooling/scripts/blender/blender_inspect_vgroups.py @@ -1,6 +1,6 @@ """ blender_inspect_vgroups.py -Usage: tooling/blender --background --python tooling/blender_inspect_vgroups.py -- +Usage: reach blender run blender_inspect_vgroups Lists vertex groups in a GLTF full-body mesh. Used to verify bone name coverage for the segmentation script. diff --git a/tooling/scripts/blender/blender_list_animations.py b/tooling/scripts/blender/blender_list_animations.py index ab4f17bcb..d10f0d8cb 100644 --- a/tooling/scripts/blender/blender_list_animations.py +++ b/tooling/scripts/blender/blender_list_animations.py @@ -1,6 +1,6 @@ """ blender_list_animations.py -Usage: tooling/blender --background --python tooling/blender_list_animations.py -- +Usage: reach blender run blender_list_animations Lists all animation actions in a GLB file. """ @@ -12,7 +12,7 @@ import bpy if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_list_animations.py -- ") + print("Usage: reach blender run blender_list_animations ") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_list_bones.py b/tooling/scripts/blender/blender_list_bones.py index 7351fb4fe..597962b7e 100644 --- a/tooling/scripts/blender/blender_list_bones.py +++ b/tooling/scripts/blender/blender_list_bones.py @@ -1,6 +1,6 @@ """ blender_list_bones.py -Usage: tooling/blender --background --python tooling/blender_list_bones.py -- +Usage: reach blender run blender_list_bones Lists all bone names in a GLB/GLTF armature, sorted alphabetically. Used to verify bone naming after the January 2026 Quaternius naming update. @@ -13,7 +13,7 @@ import bpy if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_list_bones.py -- ") + print("Usage: reach blender run blender_list_bones ") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_process_bodies.py b/tooling/scripts/blender/blender_process_bodies.py index 3cbfcdcc4..793c8c6f2 100644 --- a/tooling/scripts/blender/blender_process_bodies.py +++ b/tooling/scripts/blender/blender_process_bodies.py @@ -1,6 +1,6 @@ """ blender_process_bodies.py -Usage: tooling/blender --background --python tooling/blender_process_bodies.py -- +Usage: reach blender run blender_process_bodies Drives the full body segmentation pipeline for all 11 body types. Calls blender_segment_body.py logic inline (same Blender session, one pass per body type). @@ -85,7 +85,7 @@ def write_fork_readme(output_dir, body_type, source, scale): if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_process_bodies.py -- ") + print("Usage: reach blender run blender_process_bodies ") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_process_hair.py b/tooling/scripts/blender/blender_process_hair.py index 6ac379f7a..db8233ec9 100644 --- a/tooling/scripts/blender/blender_process_hair.py +++ b/tooling/scripts/blender/blender_process_hair.py @@ -1,6 +1,6 @@ """ blender_process_hair.py -Usage: tooling/blender --background --python tooling/blender_process_hair.py -- +Usage: reach blender run blender_process_hair Converts Quaternius Source tier hairstyle GLTF files (rigged to Head bone) into production GLBs with mask PNG sidecars. @@ -191,7 +191,7 @@ def make_bald_placeholder(glb_path: str) -> None: if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_process_hair.py -- ") + print("Usage: reach blender run blender_process_hair ") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_process_heads.py b/tooling/scripts/blender/blender_process_heads.py index c4e29f7a0..7295c4abe 100644 --- a/tooling/scripts/blender/blender_process_heads.py +++ b/tooling/scripts/blender/blender_process_heads.py @@ -1,6 +1,6 @@ """ blender_process_heads.py -Usage: tooling/blender --background --python tooling/blender_process_heads.py -- +Usage: reach blender run blender_process_heads Processes the 4 Quaternius OnlyHead .blend files into the head template library. @@ -118,7 +118,7 @@ def process_head(blend_path: str, output_dir: str, head_id: str) -> None: if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_process_heads.py -- ") + print("Usage: reach blender run blender_process_heads ") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_rebuild_forks.py b/tooling/scripts/blender/blender_rebuild_forks.py index adcc86759..930258096 100644 --- a/tooling/scripts/blender/blender_rebuild_forks.py +++ b/tooling/scripts/blender/blender_rebuild_forks.py @@ -1,6 +1,6 @@ """ blender_rebuild_forks.py -Usage: tooling/blender --background --python tooling/blender_rebuild_forks.py -- [body_type ...] +Usage: reach blender run blender_rebuild_forks [body_type ...] Rebuilds ONLY the fork body types (thin_m/f, heavy_m/f, child) through the same segmentation pipeline that produced the healthy six (blender_segment_body.py), diff --git a/tooling/scripts/blender/blender_segment_body.py b/tooling/scripts/blender/blender_segment_body.py index 239927081..e61cc2183 100644 --- a/tooling/scripts/blender/blender_segment_body.py +++ b/tooling/scripts/blender/blender_segment_body.py @@ -1,7 +1,7 @@ """ blender_segment_body.py Usage: - tooling/blender --background --python tooling/blender_segment_body.py -- \ + reach blender run blender_segment_body \ [--scale sx sy sz] Segments a Quaternius FullBody GLTF into 18 production GLBs: @@ -461,7 +461,7 @@ def segment_body(gltf_path, output_dir, scale=(1.0, 1.0, 1.0)): if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python tooling/blender_segment_body.py -- [--scale sx sy sz]") + print("Usage: reach blender run blender_segment_body [--scale sx sy sz]") sys.exit(1) args = argv[argv.index("--") + 1:] diff --git a/tooling/scripts/blender/blender_surface_deform_batch.py b/tooling/scripts/blender/blender_surface_deform_batch.py index 009a8a363..20cdcc641 100644 --- a/tooling/scripts/blender/blender_surface_deform_batch.py +++ b/tooling/scripts/blender/blender_surface_deform_batch.py @@ -2,7 +2,7 @@ blender_surface_deform_batch.py Usage: - tooling/blender --background --python tooling/blender_surface_deform_batch.py -- \\ + reach blender run blender_surface_deform_batch \\ Fits a reference clothing GLB (authored on average_m) to all 11 body types via @@ -352,8 +352,7 @@ def process_body_type(body_type, reference_glb, bodies_dir, output_dir): if __name__ == "__main__": argv = sys.argv if "--" not in argv: - print("Usage: tooling/blender --background --python " - "tooling/blender_surface_deform_batch.py -- " + print("Usage: reach blender run blender_surface_deform_batch " " ") sys.exit(1) diff --git a/wiki/authoring/culture-authoring-guide.md b/wiki/authoring/culture-authoring-guide.md index 472645c25..d772962ab 100644 --- a/wiki/authoring/culture-authoring-guide.md +++ b/wiki/authoring/culture-authoring-guide.md @@ -228,7 +228,7 @@ Include this table in a comment block in the RON file header, or maintain it sep ## Step 8: Validate and commit ```bash -tooling/validate-ron content/global/culture-{id}.ron culture +reach validate ron content/global/culture-{id}.ron culture ``` A passing validation confirms: @@ -287,7 +287,7 @@ After validation, the culture profile is ready for Spike 1 prompt testing. Human - [ ] 3-5 voice examples authored, range covered - [ ] At least 1 occasional injection with suppression logic - [ ] Tell-tone table authored (5 TellCategories) -- [ ] `tooling/validate-ron content/global/culture-{id}.ron culture` passes +- [ ] `reach validate ron content/global/culture-{id}.ron culture` passes --- @@ -357,7 +357,7 @@ These seven categories define the interface between primitives (Mellanie, role-a - Not "how does any person do this" but "what is the cultural tell for this culture specifically?" 2. Write the clause as a short trailing phrase (4-8 words). Test: does it read naturally after "moves freight containers ___"? 3. Avoid clauses that are too action-specific — they need to trail any verb, not just one type -4. Run `tooling/validate-ron content/global/culture-{id}.ron culture` to confirm syntax +4. Run `reach validate ron content/global/culture-{id}.ron culture` to confirm syntax **Three-culture contrast for modifiers** (same as voice persona contrast test): @@ -380,6 +380,6 @@ Add these items to the culture profile checklist: - [ ] `behavior_modifiers` array populated with at least 2 clauses per category (14 minimum) - [ ] Each clause tested: grammatically trails "moves freight containers ___" and "checks a manifest ___" - [ ] Three-culture contrast check: modifiers are clearly distinct from Vuurkloof, Vael, and Osse -- [ ] `tooling/validate-ron` still passes after adding modifiers +- [ ] `reach validate ron` still passes after adding modifiers *Addendum: Sprint 26, #634 (composable behavior content). Category vocabulary established jointly by Gestalt (culture modifiers) and Mellanie (behavior primitives). Add new categories only by agreement between both sides — unmatched categories silently fall back to any modifier.* diff --git a/wiki/economics/currency_zones.toml b/wiki/economics/currency_zones.toml index e05cc7877..4e84f4c07 100644 --- a/wiki/economics/currency_zones.toml +++ b/wiki/economics/currency_zones.toml @@ -20,7 +20,7 @@ # Assignment basis: political affiliation, NOT hop distance (D-172). # Hop distance correlates with Compact membership but is not the rule. # -# Pipeline: tooling/economy-db/import_economics.py → set_currency_zones() +# Pipeline: reach ledger import (economy_import/economy.py) → set_currency_zones() # Server ticket: #805 (wires this file into the import function) # # Decisions: D-171 (three-currency system), D-172 (zone initialization), diff --git a/wiki/economics/object_tag_vocabulary.toml b/wiki/economics/object_tag_vocabulary.toml index fd40654f8..752b0a50e 100644 --- a/wiki/economics/object_tag_vocabulary.toml +++ b/wiki/economics/object_tag_vocabulary.toml @@ -21,7 +21,7 @@ # Additions/deprecations: propose a new [tags..] entry here AND # wire it into at least one catalog template's allow_tags/visual_bundle in # the same change -- the two sides move together. Importer validation -# (tooling/economy-db/economy_import/traits.py, V-TT-03/V-TT-04) is the +# (tooling/domains/ledger/economy_import/traits.py, V-TT-03/V-TT-04) is the # mechanical enforcement of that co-maintenance contract: it hard-fails the # import if the catalog references a tag absent from this registry, or if # this registry's fallback graph doesn't resolve to a generic placeholder --