feat(convert): add task 05 sqlite converter with variant B keys" -m "- convert: convert_sqlite.py builds tribo.db (composite PKs, enforced FKs, Q1-Q7 indexes, track_summary)

- tools: common/track_summary.py fixes the cross-engine steady-state algorithm
- rules: db-sql-schema records the FK enforcement decision and track_summary definition
- specs: 05 aligned with data-naming-units, simtra_profiles added
- docs: FK key-schema study added under docs/research/, README updated
- replace manual CSV reading with CorpusReader for better data handling
- streamline argument parsing and dependency checks using common pipeline functions
- enhance marker writing for task completion tracking
- remove unused regex and validation error classes for cleaner code
This commit is contained in:
administrator
2026-07-11 16:08:29 -04:00
parent 9364808b3d
commit 96ed7bc918
12 changed files with 1294 additions and 240 deletions

59
common/pipeline.py Normal file
View File

@@ -0,0 +1,59 @@
"""Task-orchestration helpers: CLI shape, dependency markers, completion
markers, lab config loading (docs/rules/build-pipeline-tasks.md,
docs/rules/code-python-style.md section 3).
"""
from __future__ import annotations
import argparse
import logging
import sys
from pathlib import Path
import yaml
logger = logging.getLogger(__name__)
REPO_ROOT = Path(__file__).resolve().parent.parent
def parse_task_args(description: str) -> argparse.Namespace:
parser = argparse.ArgumentParser(description=description)
parser.add_argument("--log-level", default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR"])
parser.add_argument("--out-root", type=Path, default=REPO_ROOT / "out", help="artifact tree root (default: ./out)")
args = parser.parse_args()
logging.basicConfig(
level=args.log_level,
stream=sys.stderr,
format="%(asctime)s %(levelname)-7s %(name)s: %(message)s",
)
return args
def check_dependencies(out_root: Path, deps: list[str]) -> None:
for dep in deps:
marker = out_root / ".done" / f"{dep}.ok"
if not marker.exists():
raise FileNotFoundError(f"dependency marker missing: {marker} - run task {dep} first")
def remove_stale_marker(out_root: Path, task_id: str) -> Path:
marker = out_root / ".done" / f"{task_id}.ok"
if marker.exists():
logger.info("re-run: removing stale marker %s", marker)
marker.unlink()
return marker
def write_marker(out_root: Path, task_id: str, entries: dict) -> Path:
marker = out_root / ".done" / f"{task_id}.ok"
lines = [f"task: '{task_id}'", "status: ok"] + [f"{k}: {v}" for k, v in entries.items()]
marker.parent.mkdir(parents=True, exist_ok=True)
with open(marker, "w", encoding="utf-8", newline="\n") as fh:
fh.write("\n".join(lines) + "\n")
return marker
def load_lab_config(out_root: Path) -> dict:
with open(out_root / "config" / "lab_config.yaml", encoding="utf-8") as fh:
return yaml.safe_load(fh)