thea-software 3.53.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 HLIntel LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: thea-software
3
+ Version: 3.53.0
4
+ Summary: Contract harness for Thea, the engineering layer for AI. The atlas is polyglot; only this harness is Python.
5
+ Project-URL: Homepage, https://github.com/HLIntel/thea-software
6
+ Project-URL: Documentation, https://github.com/HLIntel/thea-software/blob/main/llms.txt
7
+ Project-URL: Issues, https://github.com/HLIntel/thea-software/issues
8
+ Project-URL: Source, https://github.com/HLIntel/thea-software
9
+ Project-URL: Agent entry, https://raw.githubusercontent.com/HLIntel/thea-software/main/.agent/bootstrap.json
10
+ Project-URL: LLM instructions, https://raw.githubusercontent.com/HLIntel/thea-software/main/llms.txt
11
+ Project-URL: Changelog, https://github.com/HLIntel/thea-software/blob/main/docs/VERSIONING.md
12
+ Keywords: engineering-atlas,polyglot,contract-verification,ai-agents,mcp,llm,agent-harness,code-verification,developer-tools,static-analysis,supply-chain-security,claude-code,agents-md
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Software Development :: Quality Assurance
18
+ Classifier: Topic :: Software Development :: Testing
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Requires-Python: >=3.11
21
+ License-File: LICENSE
22
+ Requires-Dist: pyyaml<7,>=6.0.3
23
+ Provides-Extra: quality
24
+ Requires-Dist: ruff>=0.6; extra == "quality"
25
+ Dynamic: license-file
@@ -0,0 +1,198 @@
1
+ <!-- AGENTS: do not read this page breadth-first. Plug in: `python scripts/atlas.py port <file>`,
2
+ or parse .agent/bootstrap.json — one record back. -->
3
+ <p align="center">
4
+ <img src="docs/assets/thea.webp"
5
+ alt="Thea — software development and AI agents, by HLIntel LLC" width="240">
6
+ </p>
7
+
8
+ <h1 align="center"><picture>
9
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/title-dark.svg">
10
+ <img src="docs/assets/title-light.svg" alt="The Heartland Engineering Atlas" width="560">
11
+ </picture></h1>
12
+
13
+ <p align="center">
14
+ A machine-readable rulebook for AI coding agents, and the build checks that enforce it.<br>
15
+ <em>AI proposes a change. The file's own toolchain proves it. The build refuses what skipped a check.</em>
16
+ </p>
17
+
18
+ <p align="center">
19
+ <a href="https://github.com/HLIntel/thea-software/actions/workflows/atlas-ci.yml"><img
20
+ src="https://github.com/HLIntel/thea-software/actions/workflows/atlas-ci.yml/badge.svg?branch=main"
21
+ alt="Atlas CI"></a>
22
+ <a href="https://github.com/HLIntel/thea-software/releases/latest"><img
23
+ src="https://img.shields.io/github/v/tag/HLIntel/thea-software?label=contract"
24
+ alt="contract version"></a>
25
+ <a href="https://scorecard.dev/viewer/?uri=github.com/HLIntel/thea-software"><img
26
+ src="https://api.securityscorecards.dev/projects/github.com/HLIntel/thea-software/badge"
27
+ alt="OpenSSF Scorecard"></a>
28
+ </p>
29
+
30
+ An AI reading this: agents start at [llms.txt](llms.txt), chats at [CHAT.md](CHAT.md).
31
+
32
+ ## What it does
33
+
34
+ Thea tells an AI coding agent which commands prove a change to a file, and fails the build when a
35
+ change skipped them. One declaration, [`atlas.yaml`](atlas.yaml), answers **what proves this change
36
+ is correct?** It never guesses, and refuses ambiguous input.
37
+
38
+ <!-- BEGIN generated: proof-flow (python scripts/atlas.py index --write) -->
39
+ ```mermaid
40
+ ---
41
+ config:
42
+ theme: base
43
+ themeVariables:
44
+ primaryColor: "#ffffff"
45
+ primaryBorderColor: "#2e7d32"
46
+ primaryTextColor: "#1b3a1f"
47
+ lineColor: "#2e7d32"
48
+ clusterBkg: "#eef7ee"
49
+ clusterBorder: "#a5d6a7"
50
+ titleColor: "#1b5e20"
51
+ flowchart:
52
+ subGraphTitleMargin: {top: 8, bottom: 16}
53
+ padding: 14
54
+ ---
55
+ flowchart TB
56
+ accTitle: How Thea proves a change
57
+ accDescr: 7 runtimes ask, atlas.yaml routes to 1 of 36 packs and 64 gates, the same gates run at commit, in CI and in thea verify, anything but PASS is refused, verdicts feed the failure and success ledgers, a trained judge only advises
58
+ subgraph thea [" "]
59
+ direction TB
60
+ subgraph ask [1 · ask: one declaration answers]
61
+ direction LR
62
+ A[7 agent runtimes<br>Claude Code · Codex · Cursor · opencode · Hermes] -->|CLI · MCP · hooks · llms.txt| D[(atlas.yaml<br>82 instruments · 47 invariants)]
63
+ D -->|route| P[36 language packs] --> K[8 change classes] --> G[64 gates]
64
+ end
65
+ subgraph run [2 · prove: the same gates, three places]
66
+ direction LR
67
+ H[git hook · commit] & C[CI · pull request] & R[thea verify · agent] --> V{{exit code<br>PASS · FAIL · NOT RUN}}
68
+ V -->|PASS| M[landed]
69
+ V -->|not PASS| X[refused]
70
+ end
71
+ subgraph learn [3 · learn: every verdict is kept]
72
+ direction LR
73
+ F[107 failure shapes<br>40 success moves] --> N[handed back<br>at the next port]
74
+ F --> J[thea judge · model<br>advises, never decides]
75
+ end
76
+ ask --> run --> learn
77
+ end
78
+ style thea fill:#f6fbf6,stroke:#2e7d32,stroke-width:2px
79
+ classDef stop fill:#fdecea,stroke:#c62828,color:#7f1d1d
80
+ classDef go fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20
81
+ class X stop
82
+ class M go
83
+ ```
84
+ <!-- END generated: proof-flow -->
85
+
86
+ <!-- BEGIN generated: gate-example (python scripts/atlas.py index --write) -->
87
+ ```console
88
+ $ thea gate scripts/doctor.py
89
+ 1. formatter: ruff format --check scripts/doctor.py
90
+ 2. compiler_or_typechecker: python3 -c 'import ast,sys; [ast.parse(open(f, encoding="utf-8").read(), f) for f in sys.argv[1:]]' scripts/doctor.py
91
+ 3. unit_tests: pytest
92
+ ```
93
+ <!-- END generated: gate-example -->
94
+
95
+ **Not** an app framework, a runtime optimizer or a sandbox.
96
+
97
+ ## Quickstart
98
+
99
+ <!-- BEGIN generated: install (python scripts/atlas.py index --write) -->
100
+ ```bash
101
+ git clone --depth 1 --branch v3.53.0 https://github.com/HLIntel/thea-software ~/thea && uv tool install --editable ~/thea && thea doctor
102
+ ```
103
+ <!-- END generated: install -->
104
+
105
+ ```bash
106
+ cd ~/thea
107
+ thea port scripts/doctor.py # route, gates, lessons, next step
108
+ thea gate scripts/doctor.py # the commands that prove a change
109
+ thea verify # every gate; exit 0 only if all PASS
110
+ ```
111
+
112
+ `thea-mcp` serves them read-only. From another repository: [docs/CONSUMING.md](docs/CONSUMING.md).
113
+ Every runtime: [models/README.md](models/README.md).
114
+
115
+ <!-- BEGIN generated: port-example (python scripts/atlas.py index --write) -->
116
+ ```console
117
+ $ thea port scripts/doctor.py --line
118
+ ◉ scripts/doctor.py │ ⠟backend │ python │ ⌂scripts │ ✓3 │ ⚠1 │ → thea gate scripts/doctor.py
119
+ $ thea port scripts --line
120
+ ◎ scripts │ ⠟91 │ ⌂scripts │ → thea brainstorm
121
+ $ thea port . --line
122
+ ○ . │ ⠟118 ⠿4 ⠁3 │ → thea check
123
+ ```
124
+ <!-- END generated: port-example -->
125
+
126
+ ## What it measurably buys
127
+
128
+ Recorded runs, each naming its instrument: evidence for routing and refusals, not for end-to-end
129
+ task success ([limits](docs/CERTIFICATION.md#what-the-numbers-do-not-prove)).
130
+
131
+ <!-- BEGIN generated: measured-benefits (python scripts/atlas.py index --write) -->
132
+ *With Thea*: the model is shown what `thea gate` prints for the file. *Blind*: it gets only the list
133
+ of language names. Token savings are against the usual alternative: pasting in every language's tool list.
134
+
135
+ **On Claude** (76 questions per model, `abtest.py` v3.49.0)
136
+ - **Opus:** 100% right with Thea, 41% blind; reads 90% fewer tokens.
137
+ - **Sonnet:** 100% right with Thea, 39% blind; reads 90% fewer tokens.
138
+ - **Haiku:** 100% right with Thea, 39% blind; reads 91% fewer tokens.
139
+ - **Claude Code start-up:** loads `CLAUDE.md` and its imports, 1,049 tokens.
140
+
141
+ **Beyond routing** (blind → with Thea, `taskbench.py` v2.29.0)
142
+ - **Name a failure from its symptom:** Opus 93% → 100%; Sonnet 57% → 100%; Haiku 64% → 96%.
143
+ - **List the checks a change needs:** Opus 12% → 100%; Sonnet 12% → 100%; Haiku 0% → 100%.
144
+ - **Spot a line the build refuses (yes/no, so a coin flip scores 50%):** Opus 60% → 100%; Sonnet 60% → 100%; Haiku 40% → 100%.
145
+ - *Not measured:* visual design, open-ended strategy, arithmetic — nothing declares a right answer.
146
+
147
+ **Across all 11 models tested** (5 providers, 2,409 questions, `abtest.py` v2.27.0 / v2.28.0 / v3.49.0)
148
+ - **Right answers:** 99% (95% interval 98–99%) with Thea, 59% (95% interval 55–63%) blind; every model 97–100% with Thea. A random guess scores 2.8%.
149
+ - **Tokens:** reads 89% fewer than pasting every tool list, and 51% fewer than asking blind.
150
+
151
+ **The repository itself** (recomputed on every build)
152
+ - **Before routing:** an agent reads 1,729 tokens. The other 194 documents (701 KiB) load only when a route names one.
153
+ - **Coverage:** all 324 language × check pairs answer — 133 with a command, 191 with a declared *no tool*, 0 silently.
154
+ - **Mistakes caught:** 463 kinds are planted in the tests, and each must be refused.
155
+ - **Enforced at commit:** refused 17 of 17 planted breaks in 12 languages; 11 files untested here (`enforce.py`, v3.6.0).
156
+ - **Agent-to-agent handoffs with the right checks** (schema alone → with Thea): Opus 0/6 → 6/6; Sonnet 0/6 → 6/6; Haiku 0/6 → 6/6 (`workflowbench.py`).
157
+ - **Solo commits:** 24/24 clean with or without the hook on these tasks; a planted broken commit is refused.
158
+ - **Agent controls that block, not warn:** narrow_tools, sandbox, budget, approval, effects, audit.
159
+ - **Install:** 8 KiB, 1 module, 1 dependency — 1 in total with its own dependencies.
160
+ <!-- END generated: measured-benefits -->
161
+
162
+ ## For agents
163
+
164
+ - **Plug in** with `thea port <file>`, or parse [.agent/bootstrap.json](.agent/bootstrap.json); load only what it names.
165
+ - **Read machine output, not this page.** Add `--json` to any command: one record per gate, frozen in
166
+ [tools/atlas-output.schema.json](tools/atlas-output.schema.json).
167
+ - **Before a shell command,** `thea shell --json "<cmd>"`: exit 3 means its verdict would be misread.
168
+ - **Land** with `python scripts/branchstate.py --land`; ask `thea landed <branch>` before deleting one.
169
+ - **Judgments** answer on [rules, teacher or a keyless student](systems/AGENT-HARNESS.md#judgment-rungs).
170
+ - **When something breaks,** file it the same turn with the [`thea` skill](skills/thea/SKILL.md).
171
+
172
+ ## Counts, computed
173
+
174
+ Every number on this page is generated from the tree on each build, and `check` fails when one drifts.
175
+
176
+ <!-- BEGIN generated: repository-facts (python scripts/atlas.py index --write) -->
177
+ - **contract version:** 3.53.0 — `VERSION`, asserted at a declared line in 7 other files
178
+ - **tool manifests:** 36 — `languages/<route>/tools.yaml`, validated against `tools/tools.schema.json`
179
+ - **declared tool entries:** 373 — distinct entries per manifest, summed; `packprobe.py` classifies every one
180
+ - **entry kinds:** 5 — `tools/tools.schema.json` `$defs.entry.x-kinds`
181
+ - **verification gate classes:** 8 — `atlas.yaml/verification_policy/profiles`
182
+ - **task profiles:** 14 — `atlas.yaml/task_profiles`
183
+ - **python files in the harness:** 90 — `scripts/*.py`, all linted by ruff
184
+ <!-- END generated: repository-facts -->
185
+
186
+ ## Find your way
187
+
188
+ - **Every document:** [docs index](docs/INDEX.md) · [wiki](wiki/README.md)
189
+ - **Languages:** [atlas](languages/ATLAS.md) · [routing](wiki/CODE-ROUTING.md) · [verification](docs/VERIFY.md)
190
+ - **Agents:** [harness](systems/AGENT-HARNESS.md) · [`.thea`](docs/THEA-LANGUAGE.md) · [runtimes](models/README.md)
191
+ - **Why a rule exists:** `thea why` · `thea failures` · [instruments](docs/INSTRUMENTS.md)
192
+ - **Security:** [policy](SECURITY.md) · [OpenSSF](docs/OPENSSF.md)
193
+
194
+ ## Project
195
+
196
+ The version tracks the **contract**, not the content: [docs/VERSIONING.md](docs/VERSIONING.md).
197
+ Built by **HLIntel LLC**, public on purpose: **no secret, private path or internal host enters
198
+ it** ([ABOUT.md](ABOUT.md)). Contributions pass `thea verify`. [MIT License](LICENSE).
@@ -0,0 +1 @@
1
+ 3.53.0
@@ -0,0 +1,151 @@
1
+ # Thea — Python project declaration.
2
+ #
3
+ # WHY THIS FILE EXISTS (added at contract v1.2.0). `.ruff_cache/` and `.pytest_cache/` were already at the repo
4
+ # root: ruff and pytest have been RUN here for some time while nothing declared them, nothing
5
+ # configured them, and no gate enforced them. That is an undeclared habit, and an undeclared habit
6
+ # is the thing that silently changes. This file declares exactly what is true and REFUSES to
7
+ # declare what is not — because a config that names a gate nobody runs is the same skeleton this
8
+ # repo exists to prevent.
9
+ #
10
+ # MEASURED BEFORE WRITING ANY OF IT (instrument: `ruff check . --show-files`, `ruff format --check`,
11
+ # `python3 -m pytest -q`, all run at v1.2.0):
12
+ # - ruff saw exactly SIX Python files then; re-measured at v1.3.0 after the harness was
13
+ # split into modules, it sees 8. The count is not typed into a document: README's
14
+ # generated facts block computes it from scripts/*.py on every run.
15
+ # - `ruff check .` -> All checks passed, exit 0. Safe to enforce at that version, and enforced since.
16
+ # - `ruff format --check` -> enforced at 3.50.0, after one reviewed reformat; see [tool.ruff.format].
17
+ # - `python3 -m pytest -q` -> "no tests ran". Not adopted; see [tool.pytest] below.
18
+
19
+ # THIS FILE DESCRIBES THE HARNESS, NOT THE REPOSITORY.
20
+ # The atlas is polyglot and is not a Python project; Python is simply what the contract
21
+ # harness happens to be written in. A `pyproject.toml` at the root of a polyglot repository reads
22
+ # as "this is a Python package" to both humans and tooling, so the name says otherwise explicitly.
23
+ # The languages themselves declare their own authority in languages/<lang>/tools.yaml — that is
24
+ # the roster, and it is not Python-shaped. Only the harness CLI installs (see [project.scripts]); the atlas is pointed at.
25
+
26
+ [project]
27
+ name = "thea-software" # 3.53.0: the index name a stranger types; formerly thea-harness
28
+ dynamic = ["version"] # READ FROM VERSION, never typed here: a second declaration goes
29
+ # stale first. The installed version is the release tag the CLI
30
+ # fetches its atlas from when no root is declared.
31
+ description = "Contract harness for Thea, the engineering layer for AI. The atlas is polyglot; only this harness is Python."
32
+ requires-python = ">=3.11"
33
+ dependencies = ["pyyaml>=6.0.3,<7"] # the single runtime dep, mirrored from scripts/requirements.txt
34
+ keywords = ["engineering-atlas", "polyglot", "contract-verification", "ai-agents", "mcp", "llm", "agent-harness",
35
+ "code-verification", "developer-tools", "static-analysis", "supply-chain-security", "claude-code", "agents-md"]
36
+ classifiers = ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License",
37
+ "Programming Language :: Python :: 3", "Topic :: Software Development :: Quality Assurance",
38
+ "Topic :: Software Development :: Testing", "Topic :: Scientific/Engineering :: Artificial Intelligence"]
39
+
40
+ # FOUND FROM AN INSTALL. Before 2.28.0 an installed package named no link at all, so an agent
41
+ # handed only `pip show` had no route back to the atlas, its entry or its instructions.
42
+ [project.urls]
43
+ Homepage = "https://github.com/HLIntel/thea-software"
44
+ Documentation = "https://github.com/HLIntel/thea-software/blob/main/llms.txt"
45
+ Issues = "https://github.com/HLIntel/thea-software/issues"
46
+ Source = "https://github.com/HLIntel/thea-software"
47
+ "Agent entry" = "https://raw.githubusercontent.com/HLIntel/thea-software/main/.agent/bootstrap.json"
48
+ "LLM instructions" = "https://raw.githubusercontent.com/HLIntel/thea-software/main/llms.txt"
49
+ Changelog = "https://github.com/HLIntel/thea-software/blob/main/docs/VERSIONING.md"
50
+
51
+ [project.optional-dependencies]
52
+ quality = ["ruff>=0.6"]
53
+
54
+ # THE HARNESS IS INSTALLABLE; THE ATLAS IS POINTED AT. This is the whole external interface, and
55
+ # the split is deliberate. Shipping the policy content inside the wheel would create a second copy
56
+ # that ages exactly like a vendored tree — so the CLI resolves WHICH atlas it is running against
57
+ # (--atlas-root, THEA_ROOT, or a pinned `atlas: root:` in a consumer's .atlas.yaml) and PRINTS
58
+ # the rule that decided it. An explicit pin and a lucky fall-through are the same answer with very
59
+ # different trust, and `atlas --where` is how a consumer tells them apart.
60
+ [project.scripts]
61
+ thea = "atlas_cli:main"
62
+ thea-mcp = "atlas_cli:mcp_main" # Thea's commands as MCP tools on stdio, read-only
63
+ atlas = "atlas_cli:main" # the pre-3.7 name, still answered
64
+
65
+ [build-system]
66
+ requires = ["setuptools>=77"]
67
+ build-backend = "setuptools.build_meta"
68
+
69
+ [tool.setuptools.dynamic]
70
+ version = {file = "VERSION"}
71
+
72
+ [tool.setuptools]
73
+ package-dir = {"" = "scripts"}
74
+ # WHAT SHIPS: THE LAUNCHER, AND NOTHING THE ATLAS ALREADY HOLDS (3.7.0). Eleven harness modules used
75
+ # to ship, and `atlas check` then died in an install with "No module named 'identity'": the wheel
76
+ # carried a SECOND COPY of the harness, one version old or new against the pinned atlas it ran on,
77
+ # and missing whatever the check needed next. The launcher now resolves the atlas and runs THAT
78
+ # atlas's own scripts/, so a consumer's pinned ref governs the code as well as the data, and there
79
+ # is no roster of shipped modules left to drift. `atlas.py check` refuses any module added here.
80
+ py-modules = ["atlas_cli"]
81
+
82
+ [tool.ruff]
83
+ # benchmarks/agent holds DELIBERATELY broken task fixtures (a planted bug, a planted format fault): an agent
84
+ # is scored on fixing them, so linting them would fail the tree for doing its job.
85
+ extend-exclude = ["benchmarks/agent"]
86
+ # AN EXPLICIT PATH STILL OBEYS THE EXCLUDES (3.50.0): `ruff format scripts/atlasgen.py` reflowed an
87
+ # excluded file past the line cap, because ruff only applies excludes to paths it discovers.
88
+ force-exclude = true
89
+ # The harness and the Python examples. `languages/` holds prose and manifests, not a package.
90
+ include = ["scripts/*.py", "examples/**/*.py"]
91
+ line-length = 120 # matches .editorconfig; column width is a rule of thumb, never a
92
+ # gate — see docs/ENGINEERING-CONCEPTS.md
93
+
94
+ [tool.ruff.lint]
95
+ # ENFORCED, because it passed clean on the real tree at the version it was added (exit 0, zero
96
+ # findings), and the sweep is re-run on every change. A guard that
97
+ # fires on correct code gets disabled, so nothing is enabled here that this repo does not already
98
+ # satisfy. Widen deliberately, one rule family at a time, each with a clean sweep before it lands.
99
+ select = ["E", "F", "I", # pycodestyle errors, pyflakes, import sorting
100
+ # 2.28.0, each measured at ZERO findings first: comprehension idioms, a collapsed nested
101
+ # if, a returned condition, an any/all loop, a ternary over an if-block, and no else
102
+ # after return/raise/continue — guard clauses. PERF401 was measured too and REJECTED:
103
+ # 31 error-collecting loops with no safe fix, whose messages would hide in generators.
104
+ "C4", "SIM102", "SIM103", "SIM108", "SIM110", "RET505", "RET506", "RET508"]
105
+ ignore = ["E501"] # line length is governed by line-length above, not by a lint error
106
+
107
+ [tool.ruff.lint.isort]
108
+ split-on-trailing-comma = false # agrees with format.skip-magic-trailing-comma
109
+
110
+ [tool.ruff.lint.per-file-ignores]
111
+ # E402 is WRONG here, and the exemption carries its reason inline rather than being a snooze button.
112
+ # atlas_test.py must `sys.path.insert(0, ROOT/"scripts")` BEFORE `import atlas`, because the module
113
+ # it tests is not installed — you cannot import from a directory that is not yet on the path. Moving
114
+ # that import to the top, as the rule asks, breaks the harness. Scoped to the one file so the rule
115
+ # keeps protecting every other file.
116
+ "scripts/atlas_test.py" = ["E402"]
117
+ # Same reason, same shape: agent_test.py imports the three agent modules after putting
118
+ # scripts/ on the path, because they are not installed either. Two files, one reason,
119
+ # both scoped — never a repository-wide disable of a rule that is right everywhere else.
120
+ "scripts/agent_test.py" = ["E402"]
121
+
122
+ [tool.ruff.format]
123
+ # ENFORCED: CI runs `ruff format --check .`; the reformat landed as ONE commit, listed in
124
+ # .git-blame-ignore-revs so blame skips it. The exclusions below are files that formatting
125
+ # would push past the code_shape line cap; the cap is never raised, so each leaves this list
126
+ # only when a split brings it back under. The list only shrinks.
127
+ exclude = [
128
+ "scripts/agent_test.py",
129
+ "scripts/agentpolicy.py",
130
+ "scripts/atlas.py",
131
+ "scripts/atlas_guards_test.py",
132
+ "scripts/atlas_rules_test.py",
133
+ "scripts/atlas_test.py",
134
+ "scripts/atlasgen.py",
135
+ "scripts/atlasinv.py",
136
+ "scripts/knowledge.py",
137
+ ]
138
+ quote-style = "double"
139
+ skip-magic-trailing-comma = true
140
+
141
+ # [tool.pytest.ini_options] IS DELIBERATELY ABSENT.
142
+ # A bare `python3 -m pytest -q` here would collect only the planted failing tests under
143
+ # benchmarks/agent/ and read as broken code; the root conftest.py refuses it (exit 4) and names the
144
+ # real commands. A path on the command line still runs that fixture. The contract's mutation tests
145
+ # are a custom harness run directly:
146
+ #
147
+ # python3 scripts/atlas_test.py -> "atlas tests: N/N pass" with N asserted, exit 0
148
+ #
149
+ # declared in that file's own docblock and wired into .github/workflows/atlas-ci.yml. Declaring a
150
+ # pytest section now would add a second, empty test surface whose green exit means nothing. When a
151
+ # real pytest suite exists, configure it here and give it a failing case first.
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env python3
2
+ """The installable entry point: resolve WHICH atlas, then run the contract's own CLI against it.
3
+
4
+ A SEPARATE MODULE (2.11.0) because `atlascore` fixes the root at IMPORT time: this resolves it first,
5
+ exports it, then imports the harness. IT PRINTS THE RULE THAT DECIDED THE ROOT: an explicit flag and
6
+ a lucky fall-through are the same answer with very different trust. A CONSUMER PINS A REF, NEVER
7
+ `main`, in `.atlas.yaml`, so the pin is reviewed in its own diff.
8
+ WITH NO ROOT AND NO CHECKOUT (3.53.0) it fetches its own version's release, sha256-checked; else refuses.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import hashlib
14
+ import io
15
+ import os
16
+ import re
17
+ import shutil
18
+ import sys
19
+ import tarfile
20
+ import tempfile
21
+ from pathlib import Path
22
+
23
+ import yaml
24
+
25
+ CONSUMER_CONFIG = ".atlas.yaml"
26
+ FLAG = "--atlas-root"
27
+ RELEASES = "https://github.com/HLIntel/thea-software/releases/download"
28
+ INSTALLED_FROM = "the checkout this entry point was installed from"
29
+ MARKER = ".thea-release.sha256" # written last: an unmarked cache is never used
30
+ # REFUSE RATHER THAN INVENT (3.47.0): a key not known by name is refused at its file:line.
31
+ SECTIONS, PIN = ("atlas", "stack_tiers", "markdown_policy"), ("ref", "root", "task", "change_class", "process")
32
+
33
+
34
+ class ConfigError(ValueError):
35
+ """A root flag or consumer config this entry point refuses to guess about."""
36
+
37
+
38
+ def _keys(path: Path, node, what: str, allowed=()) -> dict:
39
+ if not isinstance(node, yaml.MappingNode):
40
+ raise ConfigError(f"{path}:{node.start_mark.line + 1}: {what} must be a mapping")
41
+ out = {}
42
+ for key, value in node.value:
43
+ name, line = key.value, key.start_mark.line + 1
44
+ if not isinstance(name, str) or name in out or allowed and name not in allowed:
45
+ raise ConfigError(f"{path}:{line}: bad or repeated key {name!r} in {what}; allowed: {allowed}")
46
+ out[name] = value
47
+ return out
48
+
49
+
50
+ def _pin(path: Path) -> dict[str, str]:
51
+ """The `atlas:` mapping of one config file, every key checked by name."""
52
+ try:
53
+ doc = yaml.compose(path.read_text(encoding="utf-8"))
54
+ except yaml.YAMLError as exc:
55
+ mark = getattr(exc, "problem_mark", None)
56
+ raise ConfigError(f"{path}:{mark.line + 1 if mark else 1}: not parseable YAML") from None
57
+ sections = _keys(path, doc, CONSUMER_CONFIG, SECTIONS) if doc else {}
58
+ pins = {name: _keys(path, node, name) for name, node in sections.items()}.get("atlas", {})
59
+ for name, value in pins.items():
60
+ if name not in PIN or value.tag != "tag:yaml.org,2002:str" or not value.value.strip():
61
+ raise ConfigError(f"{path}:{value.start_mark.line + 1}: atlas.{name}: want a string in {PIN}")
62
+ return {name: value.value for name, value in pins.items()}
63
+
64
+
65
+ def _config(start: Path) -> tuple[dict, Path | None]:
66
+ """The pin of the nearest .atlas.yaml at or above `start`; ConfigError on any doubt."""
67
+ for path in (d / CONSUMER_CONFIG for d in [start, *start.parents]):
68
+ if path.exists():
69
+ return _pin(path), path
70
+ return {}, None
71
+
72
+
73
+ def root_flag(argv: list[str]) -> tuple[str | None, int, int]:
74
+ """(value, index, width) of the root flag, or (None, -1, 0); refused with no value (3.47.0)."""
75
+ hits = [i for i, arg in enumerate(argv) if arg == FLAG or arg.startswith(FLAG + "=")]
76
+ if not hits:
77
+ return None, -1, 0
78
+ i, eq = hits[0], argv[hits[0]] != FLAG
79
+ value = argv[i].partition("=")[2] if eq else (argv[i + 1 :] or [""])[0]
80
+ if len(hits) > 1 or not value.strip() or value.startswith("-") and not eq:
81
+ raise ConfigError(f"{FLAG} needs one directory, given once; got {value!r}")
82
+ return value, i, 1 if eq else 2
83
+
84
+
85
+ def resolve_root(argv: list[str], cwd: Path) -> tuple[Path, str]:
86
+ """The atlas this invocation runs against, and the rule that decided it. In declared order."""
87
+ value = root_flag(argv)[0]
88
+ if value is not None:
89
+ return Path(value).expanduser().resolve(), f"explicit {FLAG}"
90
+ for var in ("THEA_ROOT", "CODE_DEVELOPMENT_ROOT"): # the second is the pre-3.0 name, still honoured
91
+ if os.environ.get(var):
92
+ return Path(os.environ[var]).resolve(), f"{var} in the environment"
93
+ config, where = _config(cwd)
94
+ if config.get("root"):
95
+ base = (where.parent / config["root"]).resolve()
96
+ return base, f"root declared in {where.name} (ref {config.get('ref', 'unpinned')})"
97
+ return Path(__file__).resolve().parents[1], INSTALLED_FROM
98
+
99
+
100
+ class FetchError(RuntimeError):
101
+ """A release atlas refused: unreachable, unverified, or another version."""
102
+
103
+
104
+ def _get(url: str) -> bytes:
105
+ import urllib.request # noqa: PLC0415
106
+
107
+ try:
108
+ with urllib.request.urlopen(url, timeout=60) as r: # noqa: S310 — a fixed https base
109
+ return r.read()
110
+ except (OSError, ValueError) as exc:
111
+ raise FetchError(f"cannot download {url}: {exc}") from None
112
+
113
+
114
+ def fetch_atlas(version: str) -> Path:
115
+ """Release v<version>'s tree, cached or downloaded and sha256-checked; else FetchError."""
116
+ dest = Path(os.environ.get("XDG_CACHE_HOME") or Path.home() / ".cache", "thea", f"atlas-{version}")
117
+ if (dest / MARKER).is_file():
118
+ return dest
119
+ name = f"thea-v{version}.tar.gz"
120
+ url = f"{RELEASES}/v{version}/{name}"
121
+ want = re.findall(
122
+ rf"^([0-9a-f]{{64}}) [ *]{re.escape(name)}$", _get(url + ".sha256").decode(errors="replace"), re.M
123
+ )
124
+ blob = _get(url)
125
+ if len(want) != 1 or hashlib.sha256(blob).hexdigest() != want[0]:
126
+ raise FetchError(f"{name}: sha256 is not its release's one digest {want}")
127
+ dest.parent.mkdir(parents=True, exist_ok=True)
128
+ work = Path(tempfile.mkdtemp(dir=dest.parent))
129
+ try:
130
+ with tarfile.open(fileobj=io.BytesIO(blob)) as tar:
131
+ tops = {m.name.split("/")[0] for m in tar}
132
+ tar.extractall(work, filter="data") # refuses absolute, climbing and escaping links
133
+ tree = work / tops.pop()
134
+ if tops or (tree / "VERSION").read_text().strip() != version:
135
+ raise FetchError(f"{name} is not one tree of contract {version}")
136
+ (tree / MARKER).write_text(f"{want[0]} {name}\n")
137
+ shutil.rmtree(dest, ignore_errors=True) # an unmarked, interrupted unpack
138
+ os.replace(tree, dest)
139
+ except (tarfile.TarError, OSError, TypeError) as exc: # TypeError: no data filter before 3.11.4
140
+ raise FetchError(f"{name} could not be unpacked: {exc}") from None
141
+ finally:
142
+ shutil.rmtree(work, ignore_errors=True)
143
+ return dest
144
+
145
+
146
+ def _resolved(argv: list[str]) -> tuple:
147
+ try:
148
+ root, rule = resolve_root(argv, Path.cwd())
149
+ if rule != INSTALLED_FROM or (root / "atlas.yaml").exists():
150
+ return root, rule
151
+ if os.environ.get("THEA_NO_FETCH") == "1":
152
+ return root, rule + "; THEA_NO_FETCH=1"
153
+ from importlib.metadata import version # noqa: PLC0415
154
+
155
+ return fetch_atlas(version("thea-software")), "its own release, sha256-checked"
156
+ except (ConfigError, FetchError, ImportError) as exc:
157
+ print(f"refused: {exc}", file=sys.stderr)
158
+ return None, None
159
+
160
+
161
+ def main(argv: list[str] | None = None) -> int:
162
+ argv = list(sys.argv[1:] if argv is None else argv)
163
+ root, rule = _resolved(argv)
164
+ if root is None:
165
+ return 2
166
+ _, index, width = root_flag(argv)
167
+ del argv[index : index + width]
168
+ if not (root / "atlas.yaml").exists():
169
+ print(f"no atlas at {root} (resolved by: {rule})", file=sys.stderr)
170
+ print(f"point at a checkout with {FLAG}, THEA_ROOT, or `atlas: root:` in {CONSUMER_CONFIG}", file=sys.stderr)
171
+ return 2
172
+ os.environ["THEA_ROOT"] = os.environ["CODE_DEVELOPMENT_ROOT"] = str(root)
173
+ # THE HARNESS COMES FROM THE ATLAS, NEVER THE WHEEL (3.7.0): a bundled copy is a second implementation.
174
+ harness = root / "scripts"
175
+ if not (harness / "atlas.py").exists():
176
+ print(f"{root} has an atlas.yaml and no scripts/atlas.py — not a Thea checkout", file=sys.stderr)
177
+ return 2
178
+ sys.path.insert(0, str(harness))
179
+ if "--where" in argv:
180
+ print(f"atlas root: {root}")
181
+ print(f"resolved by: {rule}")
182
+ # An agent handed only an install must still find where to start: the resolved atlas's entry.
183
+ print(f"agent entry: {root / '.agent' / 'bootstrap.json'} (then: thea gate <file>)")
184
+ return 0
185
+ import atlas # noqa: PLC0415 — deliberate: the root must be exported before this import
186
+
187
+ return atlas.main(argv or ["check"])
188
+
189
+
190
+ def mcp_main() -> int:
191
+ """`thea-mcp`: the same root resolution, then serve the resolved atlas's MCP route on stdio."""
192
+ argv = sys.argv[1:]
193
+ if "--where" in argv:
194
+ return main(argv)
195
+ root, rule = _resolved(argv)
196
+ if root is None:
197
+ return 2
198
+ if not (root / "scripts" / "thea_mcp.py").exists():
199
+ print(f"no Thea MCP server at {root} (resolved by: {rule})", file=sys.stderr)
200
+ return 2
201
+ os.environ["THEA_ROOT"] = os.environ["CODE_DEVELOPMENT_ROOT"] = str(root)
202
+ sys.path.insert(0, str(root / "scripts"))
203
+ import thea_mcp # noqa: PLC0415 — deliberate: the root must be exported before this import
204
+
205
+ return thea_mcp.serve()
206
+
207
+
208
+ if __name__ == "__main__":
209
+ sys.exit(main())
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: thea-software
3
+ Version: 3.53.0
4
+ Summary: Contract harness for Thea, the engineering layer for AI. The atlas is polyglot; only this harness is Python.
5
+ Project-URL: Homepage, https://github.com/HLIntel/thea-software
6
+ Project-URL: Documentation, https://github.com/HLIntel/thea-software/blob/main/llms.txt
7
+ Project-URL: Issues, https://github.com/HLIntel/thea-software/issues
8
+ Project-URL: Source, https://github.com/HLIntel/thea-software
9
+ Project-URL: Agent entry, https://raw.githubusercontent.com/HLIntel/thea-software/main/.agent/bootstrap.json
10
+ Project-URL: LLM instructions, https://raw.githubusercontent.com/HLIntel/thea-software/main/llms.txt
11
+ Project-URL: Changelog, https://github.com/HLIntel/thea-software/blob/main/docs/VERSIONING.md
12
+ Keywords: engineering-atlas,polyglot,contract-verification,ai-agents,mcp,llm,agent-harness,code-verification,developer-tools,static-analysis,supply-chain-security,claude-code,agents-md
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Software Development :: Quality Assurance
18
+ Classifier: Topic :: Software Development :: Testing
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Requires-Python: >=3.11
21
+ License-File: LICENSE
22
+ Requires-Dist: pyyaml<7,>=6.0.3
23
+ Provides-Extra: quality
24
+ Requires-Dist: ruff>=0.6; extra == "quality"
25
+ Dynamic: license-file
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ VERSION
4
+ pyproject.toml
5
+ scripts/atlas_cli.py
6
+ scripts/thea_software.egg-info/PKG-INFO
7
+ scripts/thea_software.egg-info/SOURCES.txt
8
+ scripts/thea_software.egg-info/dependency_links.txt
9
+ scripts/thea_software.egg-info/entry_points.txt
10
+ scripts/thea_software.egg-info/requires.txt
11
+ scripts/thea_software.egg-info/top_level.txt
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ atlas = atlas_cli:main
3
+ thea = atlas_cli:main
4
+ thea-mcp = atlas_cli:mcp_main
@@ -0,0 +1,4 @@
1
+ pyyaml<7,>=6.0.3
2
+
3
+ [quality]
4
+ ruff>=0.6
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+