The skeleton the reach CLI hangs off. Nothing moves yet: this adds the package, the bounded core/, and explicit setuptools discovery. core/console.py is the single output path, and the split it enforces is the whole design — stdout carries the command's actual output so `reach ... | jq` keeps working, stderr carries the event stream as JSONL. Rendering happens at the sink: a terminal gets human text, anything else gets raw JSONL, so a live view and a job log are one artefact in two presentations. Emitting is optional — the gates emit nothing — and verdict() prints once, last, carrying its remedy as a structured field. core/config.py resolves the repo root from __file__ against a project.yaml sentinel, with an SR_REPO_ROOT override. No subprocess and no git call: this is on the gate path, and cwd is not a reliable signal anyway since a hook runs from the root and an agent call may not. Both paths are validated, because a silent fallback is how you end up editing one checkout and checking another. Discovery is configured explicitly rather than left to flat-layout auto-discovery, which would have had to choose between erroring on the ambiguity and quietly shipping client/ or docs/. Verified: top_level.txt contains exactly "tooling". Verified beyond the happy path — the sentinel rejects SR_REPO_ROOT=/tmp and names both remedies; debug events are suppressed at the default threshold while the verdict is not; stdout stays clean with stderr redirected away; and the three unconditional push-gate checks still pass now that tooling/ is a package, which was the real regression risk. Two findings recorded on the tickets. make setup-venv is stale — it calls .venv/bin/pip, but the venv was created by uv and has no pip, so the recorded procedure and the actual state have already diverged (T-1261 owns the fix). And settled-reach-tooling had never actually been installed: site-packages held the dependencies but no dist-info, which follows from there being no __init__.py to expose. This is the first commit where `import tooling` means anything. .venv/ was only ignored via .git/info/exclude, which is machine-local, so a fresh clone or a new worktree did not ignore it at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
52 lines
2.2 KiB
TOML
52 lines
2.2 KiB
TOML
[project]
|
||
name = "settled-reach-tooling"
|
||
version = "0.1.0"
|
||
requires-python = ">=3.11"
|
||
dependencies = [
|
||
"PyYAML",
|
||
"jsonschema",
|
||
"numpy",
|
||
# scipy 1.17.1 — checked clean against NVD + OSV, no CVEs on record (2026-04-06)
|
||
"scipy==1.17.1",
|
||
# Pillow 12.2.0 — checked clean against NVD + OSV (2026-04-06)
|
||
# CVE-2026-25990 fixed in 12.1.1, CVE-2025-48379 fixed in 11.3.0
|
||
"Pillow==12.2.0",
|
||
]
|
||
|
||
[tool.setuptools.packages.find]
|
||
# Explicit, not flat-layout auto-discovery. The repo root holds client/, server/,
|
||
# docs/, wiki/, db/ and tests/ alongside tooling/, and auto-discovery either
|
||
# errors on the ambiguity or quietly ships something unintended (T-1258).
|
||
#
|
||
# Nothing needs excluding yet: the hyphenated directories (planet-gen,
|
||
# economy-db, garment-fit, pql-migrate) are invisible to package discovery
|
||
# because a hyphen is not a valid Python identifier, and tooling/econ-sim is a
|
||
# Rust crate with no __init__.py. That changes in T-1250, which renames them —
|
||
# at which point they become real packages and this include starts matching them.
|
||
include = ["tooling*"]
|
||
|
||
[project.optional-dependencies]
|
||
dev = [
|
||
# ruff 0.15.9 — checked clean against NVD + OSV, no CVEs on record (2026-04-05)
|
||
"ruff==0.15.9",
|
||
]
|
||
|
||
[tool.ruff]
|
||
line-length = 100
|
||
target-version = "py311"
|
||
|
||
[tool.ruff.lint]
|
||
# Widened from {E9, F401, F811, F821} to the full ruff-default tiers + W (T-1066).
|
||
# E4: import placement/style
|
||
# E7: statement-level pitfalls (== None, bare except, lambda assignment, ...)
|
||
# E9: runtime syntax/encoding errors
|
||
# F: all pyflakes (unused imports/names, undefined names, f-string misuse, ...)
|
||
# W: whitespace + invalid escape sequences (zero violations at adoption)
|
||
select = ["E4", "E7", "E9", "F", "W"]
|
||
# Rules excluded at adoption because the existing violation count was not
|
||
# trivially fixable (T-1066) — re-enable per-rule as the debt is paid down:
|
||
# E402 (43×): module-import-not-at-top — script-style sys.path.insert before import
|
||
# E702 (41×): semicolon-paired assignments, deliberate style in planet-gen noise math
|
||
# F841 (21×): unused locals, mostly in numeric/diagnostic code — needs manual review
|
||
ignore = ["E402", "E702", "F841"]
|