chore(meta): docs/build sweep + tooling test gate (T-1069, T-1066)

- make test-tooling: planet-gen determinism guard + import_economics
  --dry-run, wired into pre-push on TOOLING_CHANGED; ruff widened to
  E4/E7/E9/F/W (90 safe auto-fixes applied; E402/E702/F841 ignored with
  documented counts)
- one-generator reality fixed in DEVOPS.md, asset-pipeline rule, CLAUDE.md
  (import_economics sole generator since #951/D-223); dead check-protocol
  target deleted; DEVOPS hook/config sections rewritten from the actual
  hook sources; team-patterns gate description updated (client+tooling)
- project.yaml: 0.2.0 → 0.4.0 per the 0.{phase}.{n} scheme, description
  refreshed from the v0.1 Sova narration to cascade reality
- stale comment sweep: voxel.rs stub claims (all 8 families implemented),
  cascade.rs TODO recited to T-1044, main.rs D-192 handshake claim,
  relationships.rs/chunk_streaming.rs version targets → phase language
- gitignore: client/settings.db* e2e-run artifacts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 16:22:55 +02:00
co-authored by Claude Fable 5
parent 0bd895fcac
commit 346d87df7a
47 changed files with 280 additions and 180 deletions
+1 -1
View File
@@ -256,7 +256,7 @@ def main():
for node in nodes:
sp = simplify_spectral(node.get("spectral_class", ""))
type_counts[sp] = type_counts.get(sp, 0) + 1
print(f"\nSimplified spectral distribution:")
print("\nSimplified spectral distribution:")
for t in ["G", "K", "M", "F", "unusual"]:
print(f" {t:8s} {type_counts.get(t, 0):3d} ({type_counts.get(t, 0)/len(nodes)*100:.0f}%)")
+2 -2
View File
@@ -266,7 +266,7 @@ if __name__ == "__main__":
print(f"ERROR: Reference body directory not found: {avg_m_dir}")
sys.exit(1)
print(f"\nClothing Reference Mesh Creator (v0.2 placeholder)")
print("\nClothing Reference Mesh Creator (v0.2 placeholder)")
print(f" Bodies dir: {bodies_dir}")
print(f" Output dir: {clothing_output_dir}")
print(f" Reference: {REFERENCE_BODY}")
@@ -280,7 +280,7 @@ if __name__ == "__main__":
# Summary
print(f"\n{'='*60}")
print(f"=== Clothing reference creation complete ===")
print("=== Clothing reference creation complete ===")
ok_items = [k for k, v in results.items() if v]
fail_items = [k for k, v in results.items() if not v]
for item_id in CLOTHING_ITEMS:
+1 -1
View File
@@ -131,7 +131,7 @@ if __name__ == "__main__":
# Summary
print(f"\n{'='*60}")
print(f"=== Body type segmentation complete ===")
print("=== Body type segmentation complete ===")
total_exported = 0
for body_type, exported, skipped, is_fork in results:
flag = " [FORK]" if is_fork else ""
+1 -1
View File
@@ -232,7 +232,7 @@ if __name__ == "__main__":
results.append((tag, key, os.path.getsize(glb_path)))
# bald.glb placeholder
print(f"\n[hair] bald (placeholder)")
print("\n[hair] bald (placeholder)")
bald_path = os.path.join(hair_out, "bald.glb")
make_bald_placeholder(bald_path)
results.append(("hair", "bald", os.path.getsize(bald_path)))
+1 -1
View File
@@ -82,7 +82,7 @@ def process_head(blend_path: str, output_dir: str, head_id: str) -> None:
bpy.ops.object.select_all(action='SELECT')
# Export GLB — embedded textures, no animations
print(f" Exporting GLB...")
print(" Exporting GLB...")
bpy.ops.export_scene.gltf(
filepath=glb_path,
use_selection=True,
+6 -6
View File
@@ -296,7 +296,7 @@ def process_body_type(body_type, reference_glb, bodies_dir, output_dir):
# average_m is a direct copy -- no deform required
if body_type == REFERENCE_BODY:
print(f" Reference body type -- copying reference directly")
print(" Reference body type -- copying reference directly")
shutil.copy2(reference_glb, output_path)
return {"body_type": body_type, "status": "ok", "method": "copy"}
@@ -322,7 +322,7 @@ def process_body_type(body_type, reference_glb, bodies_dir, output_dir):
print(f" Clothing mesh: {len(clothing_obj.data.vertices)} vertices")
# --- Build body surface ---
print(f" Building body surface from segments...")
print(" Building body surface from segments...")
body_surface = build_body_surface(bodies_dir, body_type)
if body_surface is None:
return {"body_type": body_type, "status": "error",
@@ -386,7 +386,7 @@ if __name__ == "__main__":
print(f"\nWARNING: Missing body type directories (will skip): "
f"{', '.join(missing_types)}")
print(f"\nSurface Deform Batch Pipeline")
print("\nSurface Deform Batch Pipeline")
print(f" Reference: {reference_glb}")
print(f" Bodies: {bodies_dir}")
print(f" Output: {output_dir}")
@@ -405,7 +405,7 @@ if __name__ == "__main__":
# Summary
print(f"\n{'='*60}")
print(f"=== Surface Deform batch complete ===")
print("=== Surface Deform batch complete ===")
ok = [r for r in results if r["status"] == "ok"]
errors = [r for r in results if r["status"] == "error"]
skipped = [r for r in results if r["status"] == "skipped"]
@@ -434,8 +434,8 @@ if __name__ == "__main__":
print(f" SKIPPED: {len(skipped)}")
if sw_count > 0:
print(f"\n WARNING: {sw_count} body type(s) used Shrinkwrap fallback.")
print(f" Visually verify these variants at gameplay zoom — Shrinkwrap")
print(f" may produce pinching at extremities on extreme body types.")
print(" Visually verify these variants at gameplay zoom — Shrinkwrap")
print(" may produce pinching at extremities on extreme body types.")
# Write pipeline_log.json for provenance tracking
log_path = os.path.join(output_dir, "pipeline_log.json")
+2 -1
View File
@@ -1,5 +1,6 @@
"""List all objects in a Quaternius .blend file."""
import sys, bpy
import sys
import bpy
if __name__ == "__main__":
argv = sys.argv
+3 -3
View File
@@ -235,14 +235,14 @@ def main():
# Health check if any SAO assets
sao_assets = [a for a in assets if a.get("method") == "sao"]
if sao_assets and not dry_run:
print(f"Checking SAO API health...", file=sys.stderr)
print("Checking SAO API health...", file=sys.stderr)
health_cmd = [sys.executable, os.path.join(script_dir, "audio_connector.py"), "health"]
result = subprocess.run(health_cmd, capture_output=True, text=True)
if result.returncode != 0:
print(json.dumps({"ok": False, "error": "SAO API health check failed",
"details": result.stdout.strip()}))
sys.exit(1)
print(f" SAO API is up.", file=sys.stderr)
print(" SAO API is up.", file=sys.stderr)
total = len(assets)
results = []
@@ -264,7 +264,7 @@ def main():
if skip_existing:
ogg_path = os.path.join(output_dir, filename)
if os.path.exists(ogg_path):
print(f" Skipping — already exists", file=sys.stderr)
print(" Skipping — already exists", file=sys.stderr)
results.append({"id": asset_id, "status": "skipped", "reason": "exists"})
skipped += 1
continue
+1 -1
View File
@@ -135,7 +135,7 @@ def generate(prompt, duration=10.0, steps=100, cfg=7.0, output=None, timeout=600
method="POST"
)
print(f"Submitting generation request...", file=sys.stderr)
print("Submitting generation request...", file=sys.stderr)
print(f" Prompt: {prompt}", file=sys.stderr)
print(f" Duration: {duration}s, Steps: {steps}, CFG: {cfg}", file=sys.stderr)
+1 -1
View File
@@ -112,7 +112,7 @@ def cmd_pipeline(args):
# Step 3: convert
run_ffmpeg(
["-i", normalized, "-c:a", "libvorbis", "-q:a", str(args.quality), output],
f"step 3/3: converting to OGG"
"step 3/3: converting to OGG"
)
# Clean up intermediates
+8 -8
View File
@@ -72,12 +72,12 @@ def main():
"SELECT COUNT(*) FROM bodies WHERE cultural_corridor IS NULL"
).fetchone()[0]
print(f"\n cultural_corridor backfill")
print("\n cultural_corridor backfill")
print(f" DB: {db_path}")
if args.dry_run:
print(f" Mode: DRY RUN")
print(" Mode: DRY RUN")
print()
print(f" Before:")
print(" Before:")
print(f" star_systems.cultural_corridor NULL: {before_systems_null}")
print(f" bodies.cultural_corridor NULL: {before_bodies_null}")
@@ -118,14 +118,14 @@ def main():
if args.dry_run:
conn.rollback()
print()
print(f" Would update:")
print(" Would update:")
print(f" star_systems: {sys_rows_updated}")
print(f" bodies: {body_rows_updated}")
print(f"\n Dry run — no changes written.")
print("\n Dry run — no changes written.")
else:
conn.commit()
print()
print(f" Updated:")
print(" Updated:")
print(f" star_systems: {sys_rows_updated}")
print(f" bodies: {body_rows_updated}")
@@ -137,13 +137,13 @@ def main():
"SELECT COUNT(*) FROM bodies WHERE cultural_corridor IS NULL"
).fetchone()[0]
print()
print(f" After:")
print(" After:")
print(f" star_systems.cultural_corridor NULL: {after_systems_null}")
print(f" bodies.cultural_corridor NULL: {after_bodies_null}")
# Show the distribution so the outcome is visible.
print()
print(f" star_systems.cultural_corridor distribution:")
print(" star_systems.cultural_corridor distribution:")
for corridor, count in conn.execute(
"SELECT cultural_corridor, COUNT(*) FROM star_systems "
"GROUP BY cultural_corridor ORDER BY COUNT(*) DESC"
+1 -1
View File
@@ -139,7 +139,7 @@ def generate(prompt, output=None, aspect_ratio="1:1", image_size=None,
method="POST"
)
print(f"Generating image...", file=sys.stderr)
print("Generating image...", file=sys.stderr)
print(f" Prompt: {prompt}", file=sys.stderr)
if input_image:
print(f" Input image: {input_image}", file=sys.stderr)
+4 -4
View File
@@ -144,11 +144,11 @@ def main():
except sqlite3.OperationalError:
pass # column already exists
print(f"\n populate_gttr_hook.py")
print("\n populate_gttr_hook.py")
print(f" DB: {db_path}")
print(f" max words: {args.max_words}")
if args.dry_run:
print(f" Mode: DRY RUN")
print(" Mode: DRY RUN")
print()
rows = conn.execute(
@@ -202,12 +202,12 @@ def main():
conn.close()
print(f"\n Done:")
print("\n Done:")
print(f" updated: {updated}")
print(f" missing: {missing}")
print(f" unmatched: {unmatched}")
if args.dry_run:
print(f"\n Dry run — no DB writes.")
print("\n Dry run — no DB writes.")
print()
+2 -1
View File
@@ -222,7 +222,8 @@ def generate(image_path, output=None, simplify=0.95, texture_size=1024,
# Generate a session hash — Gradio uses this to maintain gr.State between
# separate API calls. Without it, image_to_3d's output state is lost before
# extract_glb can read it.
import random, string
import random
import string
session = ''.join(random.choices(string.ascii_lowercase + string.digits, k=12))
print(f" Session: {session}", file=sys.stderr)
+9 -4
View File
@@ -5,7 +5,11 @@ Usage: python3 tooling/generate-star-map-svg.py [output.svg]
Default output: docs/diagrams/design/star-map-concentric.svg
"""
import json, sqlite3, math, sys, os
import json
import sqlite3
import math
import sys
import os
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(SCRIPT_DIR)
@@ -238,10 +242,10 @@ grad_r = max(width, height)
start_pct = fade_start / grad_r * 100
end_pct = fade_end / grad_r * 100
svg.append(f'<radialGradient id="fadeEdge" cx="{cx}" cy="{cy}" r="{grad_r}" gradientUnits="userSpaceOnUse">')
svg.append(f' <stop offset="0%" stop-color="#0a0a1a" stop-opacity="0"/>')
svg.append(' <stop offset="0%" stop-color="#0a0a1a" stop-opacity="0"/>')
svg.append(f' <stop offset="{start_pct:.1f}%" stop-color="#0a0a1a" stop-opacity="0"/>')
svg.append(f' <stop offset="{end_pct:.1f}%" stop-color="#0a0a1a" stop-opacity="1"/>')
svg.append(f' <stop offset="100%" stop-color="#0a0a1a" stop-opacity="1"/>')
svg.append(' <stop offset="100%" stop-color="#0a0a1a" stop-opacity="1"/>')
svg.append('</radialGradient>')
svg.append('</defs>')
@@ -338,7 +342,8 @@ print(f'{len(positions)} nodes, {len(starmap["edges"])} edges')
print(f'Hops 0-{FOLD_HOP-1} individual, {FOLD_HOP}+ folded ({len(hop_groups.get(FOLD_HOP, []))} nodes)')
# Also render PNG
import shutil, subprocess
import shutil
import subprocess
png_path = output_path.replace('.svg', '.png')
if shutil.which('magick'):
cmd = ['magick', '-density', '150', '-background', '#0a0a1a', output_path, png_path]
+17 -17
View File
@@ -1171,8 +1171,8 @@ def generate_sector_d2(
lines = []
lines.append(f"# Star Map — {sector_label}")
lines.append(f"# Sector map. Cross-sector connections shown as stub nodes (dashed border).")
lines.append(f"# Node color = settlement wave. Shape = topology type.")
lines.append("# Sector map. Cross-sector connections shown as stub nodes (dashed border).")
lines.append("# Node color = settlement wave. Shape = topology type.")
lines.append("")
lines.append("vars: {")
lines.append(f' bg: "{D2_BG}"')
@@ -1182,7 +1182,7 @@ def generate_sector_d2(
lines.append("")
# Root style
lines.append(f"direction: right")
lines.append("direction: right")
lines.append("")
lines.append(f'style.fill: "{D2_BG}"')
lines.append(f'style.stroke: "{D2_ACC}"')
@@ -1192,7 +1192,7 @@ def generate_sector_d2(
# Legend
lines.append("legend: Legend {")
lines.append(f' style.fill: "{D2_BG}"; style.stroke: "{D2_ACC}"; style.font-color: "{D2_TXT}"')
lines.append(f' style.font-size: 10')
lines.append(' style.font-size: 10')
for wave, stroke in WAVE_STROKE.items():
fill = WAVE_FILL[wave]
w_label = wave.replace("_", " ").title()
@@ -1227,9 +1227,9 @@ def generate_sector_d2(
lines.append(f' style.fill: "{fill}"')
lines.append(f' style.stroke: "{stroke}"')
lines.append(f' style.font-color: "{D2_TXT}"')
lines.append(f' style.font-size: 9')
lines.append(' style.font-size: 9')
if nid == "S-001":
lines.append(f' style.stroke-width: 3')
lines.append(' style.stroke-width: 3')
lines.append("}")
lines.append("")
@@ -1240,12 +1240,12 @@ def generate_sector_d2(
stub_sector_label = SECTOR_LABELS[stub_node["geographic_sector"]]
label = f"{stub_id}\\n[{stub_sector_label}]"
lines.append(f'{d2id}: "{label}" {{')
lines.append(f' shape: rectangle')
lines.append(' shape: rectangle')
lines.append(f' style.fill: "{STUB_FILL}"')
lines.append(f' style.stroke: "{STUB_STROKE}"')
lines.append(f' style.stroke-dash: 5')
lines.append(' style.stroke-dash: 5')
lines.append(f' style.font-color: "{STUB_STROKE}"')
lines.append(f' style.font-size: 9')
lines.append(' style.font-size: 9')
lines.append("}")
lines.append("")
@@ -1281,8 +1281,8 @@ def generate_sector_d2(
if is_cross:
lines.append(f"{edge_line}: {{")
lines.append(f' style.stroke: "{color}"')
lines.append(f' style.stroke-dash: 4')
lines.append(f' style.stroke-width: 1')
lines.append(' style.stroke-dash: 4')
lines.append(' style.stroke-width: 1')
lines.append("}")
else:
lines.append(f"{edge_line}: {{")
@@ -1331,7 +1331,7 @@ def generate_overview_d2(
lines.append(f' acc: "{D2_ACC}"')
lines.append("}")
lines.append("")
lines.append(f'direction: right')
lines.append('direction: right')
lines.append(f'style.fill: "{D2_BG}"')
lines.append(f'style.stroke: "{D2_ACC}"')
lines.append(f'style.font-color: "{D2_TXT}"')
@@ -1354,23 +1354,23 @@ def generate_overview_d2(
fill, stroke = sector_colors[sector]
d2id = sector.replace("_", "")
lines.append(f'{d2id}: "{label}\\n{count} systems · {hubs} hubs" {{')
lines.append(f' shape: rectangle')
lines.append(' shape: rectangle')
lines.append(f' style.fill: "{fill}"')
lines.append(f' style.stroke: "{stroke}"')
lines.append(f' style.font-color: "{D2_TXT}"')
lines.append(f' style.border-radius: 8')
lines.append(' style.border-radius: 8')
lines.append("}")
lines.append("")
# Special Gateway callout
lines.append('gateway_note: "GATEWAY (S-001)\\nDiplomatic Periphery · Core\\nSol aperture: dormant" {')
lines.append(f' shape: hexagon')
lines.append(' shape: hexagon')
lines.append(f' style.fill: "{GATEWAY_FILL}"')
lines.append(f' style.stroke: "{GATEWAY_STROKE}"')
lines.append(f' style.font-color: "{D2_TXT}"')
lines.append(f' style.stroke-width: 3')
lines.append(' style.stroke-width: 3')
lines.append("}")
lines.append(f'gateway_note -> core: "located in" {{')
lines.append('gateway_note -> core: "located in" {')
lines.append(f' style.stroke: "{GATEWAY_STROKE}"; style.stroke-dash: 3')
lines.append("}")
lines.append("")
+1 -1
View File
@@ -154,7 +154,7 @@ def process_file(input_path: str, output_path: str):
count, names = strip_utility_nodes(gltf)
if count == 0:
print(f" No utility nodes found — file unchanged")
print(" No utility nodes found — file unchanged")
if output_path != input_path:
import shutil
shutil.copy2(input_path, output_path)
+2 -2
View File
@@ -97,7 +97,7 @@ def migrate_database(mapping):
print("Database not found, skipping.")
return
print(f"Migrating systems.db...")
print("Migrating systems.db...")
conn = sqlite3.connect(SYSTEMS_DB)
cur = conn.cursor()
@@ -155,7 +155,7 @@ def migrate_database(mapping):
def migrate_wiki_pages(mapping):
"""Replace S-numbers in wiki page headers and topology sections."""
print(f"Migrating wiki pages...")
print("Migrating wiki pages...")
count = 0
# Build reverse: need to match S-numbers in text
+1 -1
View File
@@ -364,7 +364,7 @@ def main() -> None:
if row:
system_id = row["system_id"]
print(f"\nAtlas Cohesion Audit")
print("\nAtlas Cohesion Audit")
print(f" DB: {db}")
if system_id:
print(f" System: {system_id}")
+3 -3
View File
@@ -334,11 +334,11 @@ def main():
total_invalid = 0
error_rate_threshold = 0.50
print(f"\n Planet Generator — Batch Mode")
print("\n Planet Generator — Batch Mode")
print(f" Systems: {len(system_dirs)}")
print(f" Heightmap: {hmap_w}×{hmap_h} Globe: {args.globe_size}×{args.globe_size}")
if args.dry_run:
print(f" Mode: DRY RUN (validation only)")
print(" Mode: DRY RUN (validation only)")
print()
for system_dir in system_dirs:
@@ -545,7 +545,7 @@ def _verify_determinism(wiki_systems: Path, n_samples: int,
print(f" passed: {passed} failed: {failed}")
if failed > 0:
print(f" WARNING: non-deterministic output detected!")
print(" WARNING: non-deterministic output detected!")
if __name__ == "__main__":
@@ -479,12 +479,12 @@ def main() -> None:
print(f"error: {db_path} not found", file=sys.stderr)
sys.exit(1)
print(f"\n Province Boundary Import (#907)")
print("\n Province Boundary Import (#907)")
print(f" DB: {db_path}")
if args.dry_run:
print(f" Mode: DRY RUN (no DB writes)")
print(" Mode: DRY RUN (no DB writes)")
if args.force:
print(f" Force: enabled (will overwrite existing rows)")
print(" Force: enabled (will overwrite existing rows)")
print()
conn = sqlite3.connect(str(db_path))
+3 -1
View File
@@ -861,7 +861,9 @@ def render_globe(
# ---------------------------------------------------------------------------
if __name__ == "__main__":
import sys, os, time
import sys
import os
import time
TEST_BODIES = [
{
+4 -1
View File
@@ -858,7 +858,10 @@ def simulate(body_def: dict) -> dict:
# ---------------------------------------------------------------------------
if __name__ == "__main__":
import sys, json, time, os
import sys
import json
import time
import os
from PIL import Image
if len(sys.argv) < 2:
@@ -81,10 +81,10 @@ def main():
ORDER BY b.system_id, b.body_id
""").fetchall()
print(f"\n terrain_reference population pass")
print("\n terrain_reference population pass")
print(f" DB: {db_path}")
if args.dry_run:
print(f" Mode: DRY RUN")
print(" Mode: DRY RUN")
print(f"\n {len(rows)} bodies with NULL terrain_reference\n")
found = []
@@ -119,12 +119,12 @@ def main():
conn.commit()
print(f"\n Committed {len(found)} terrain_reference updates.")
else:
print(f"\n Dry run — no changes written.")
print("\n Dry run — no changes written.")
conn.close()
# Summary
print(f"\n Summary:")
print("\n Summary:")
print(f" Updated: {len(found)}")
print(f" Missing: {len(missing)}")
print(f" Total: {len(rows)}\n")
@@ -132,7 +132,7 @@ def main():
if missing:
print(f" Action required: generate heightmaps for {len(missing)} bodies "
f"before running the atlas importers (#901).")
print(f" Use: make generate-terrain (or run generate.py per body)\n")
print(" Use: make generate-terrain (or run generate.py per body)\n")
if __name__ == "__main__":
+3 -1
View File
@@ -418,7 +418,9 @@ def render_heightmap(body_def: dict,
# ---------------------------------------------------------------------------
if __name__ == "__main__":
import sys, json, time
import sys
import json
import time
if len(sys.argv) < 2:
print("Usage: python3 render_heightmap.py body_def.json [--large]")
+1 -1
View File
@@ -95,7 +95,7 @@ def build_terrain(body_def: dict) -> dict:
sea_level = 0.0
surface_water = np.zeros((GRID_H, GRID_W), dtype=bool)
print(f" elevation normalised")
print(" elevation normalised")
# ── 2. Temperature ──────────────────────────────────────────────────
temperature_K = temperature_grid_analytical(
+1 -1
View File
@@ -92,7 +92,7 @@ def build_terrain(body_def: dict) -> dict:
# Normalise to [0, 1]
elevation = normalize_01(elevation_m, MARS_MIN_ELEV_M, MARS_MAX_ELEV_M)
print(f" elevation normalised")
print(" elevation normalised")
# ── 2. Temperature ──────────────────────────────────────────────────
# Analytical: equatorial ~210K, polar ~150K, elevation lapse
+1 -1
View File
@@ -70,7 +70,7 @@ def _load_magellan() -> np.ndarray:
print(f" PDS also failed ({e3})")
# All sources failed — fall through to procedural generation
print(f" WARNING: all Magellan sources failed, using procedural")
print(" WARNING: all Magellan sources failed, using procedural")
return None
+3 -3
View File
@@ -190,7 +190,7 @@ def _generate_body(body_def: dict, hmap_w: int, hmap_h: int,
if is_gas:
# Gas giants: no terrain, renderer handles bands procedurally
terrain = {}
print(f" terrain: gas giant (procedural bands)")
print(" terrain: gas giant (procedural bands)")
elif body_id in REAL_DATA_BODIES:
# Real-world data import
module_name = REAL_DATA_BODIES[body_id]
@@ -198,11 +198,11 @@ def _generate_body(body_def: dict, hmap_w: int, hmap_h: int,
importer = _load_importer(module_name)
terrain = importer.build_terrain(body_def)
if download_only:
print(f" download complete, skipping render")
print(" download complete, skipping render")
return
elif body_id in PROCEDURAL_BODIES:
# Fall through to standard procedural simulation
print(f" procedural simulation (irregular body)...")
print(" procedural simulation (irregular body)...")
terrain = simulate(body_def)
else:
print(f" WARNING: no importer for {body_id}, using procedural")
+1 -1
View File
@@ -78,7 +78,7 @@ def main():
all_skips += [(f.split('/main/',1)[-1], s) for s in skips]
if APPLY and rewrites:
open(f, "w", encoding="utf-8").write(new)
print(f"\n--- SKIPPED (not rewritten), grouped by reason ---")
print("\n--- SKIPPED (not rewritten), grouped by reason ---")
by_reason = {}
for rel, (tok, reason) in all_skips:
by_reason.setdefault(reason, []).append(f"{tok} ({os.path.basename(rel)})")
+1 -1
View File
@@ -79,7 +79,7 @@ def main():
print(f" ticket_deps: {len(deps)}")
print(f" ticket_labels: {len(labels)} (existing) + {len(ms_labels)} (milestone-derived)")
print(f" ticket_history: {len(history)}")
print(f" milestone label mapping: " + ", ".join(f"{mid}->{ms_label(mid)}" for mid in milestones))
print(" milestone label mapping: " + ", ".join(f"{mid}->{ms_label(mid)}" for mid in milestones))
print(f" multi/space decision_refs kept verbatim: {len(multi)}")
print(f" comma-team tickets kept verbatim: {comma_team}")
+1 -1
View File
@@ -174,7 +174,7 @@ if __name__ == "__main__":
clothing_dir = sys.argv[1]
print(f"\nClothing Metadata Setup")
print("\nClothing Metadata Setup")
print(f" Output dir: {clothing_dir}")
print(f" Items: {len(CLOTHING_ITEMS)}")
+1 -1
View File
@@ -841,7 +841,7 @@ def main() -> None:
assert gw_node["gate_topology"] == "hub", "Gateway topology changed!"
assert gw_node["aperture_count"] == 5, f"Gateway aperture_count={gw_node['aperture_count']} (should be 5)"
assert len(adj[GATEWAY_ID]) == 4, f"Gateway degree={len(adj[GATEWAY_ID])} (should be 4)"
print(f"\n Gateway constraint check: OK (degree=4, aperture=5, topology=hub)")
print("\n Gateway constraint check: OK (degree=4, aperture=5, topology=hub)")
# ── Verify no aperture violations ────────────────────────────────────────
violations = [
+1 -1
View File
@@ -229,7 +229,7 @@ def main():
print(f"Output directory: {WIKI_DIR}")
# Print a few examples
print(f"\nExample directories:")
print("\nExample directories:")
dirs = sorted(WIKI_DIR.iterdir())[:5]
for d in dirs:
if d.is_dir():