millforge 0.1.0__py3-none-any.whl

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.
Files changed (116) hide show
  1. millforge/__init__.py +1174 -0
  2. millforge/_forge/LICENSE +21 -0
  3. millforge/_forge/PROVENANCE.json +295 -0
  4. millforge/_forge/UPDATE_POLICY.md +24 -0
  5. millforge/_forge/__init__.py +14 -0
  6. millforge/_forge/adapter.py +2232 -0
  7. millforge/_forge/base_runner.py +121 -0
  8. millforge/_forge/clients/__init__.py +10 -0
  9. millforge/_forge/clients/base.py +200 -0
  10. millforge/_forge/context/__init__.py +23 -0
  11. millforge/_forge/context/manager.py +178 -0
  12. millforge/_forge/context/strategies.py +335 -0
  13. millforge/_forge/core/__init__.py +16 -0
  14. millforge/_forge/core/inference.py +433 -0
  15. millforge/_forge/core/messages.py +119 -0
  16. millforge/_forge/core/runner.py +479 -0
  17. millforge/_forge/core/steps.py +108 -0
  18. millforge/_forge/core/workflow.py +400 -0
  19. millforge/_forge/errors.py +222 -0
  20. millforge/_forge/guardrails/__init__.py +21 -0
  21. millforge/_forge/guardrails/error_tracker.py +71 -0
  22. millforge/_forge/guardrails/guardrails.py +194 -0
  23. millforge/_forge/guardrails/nudge.py +47 -0
  24. millforge/_forge/guardrails/response_validator.py +119 -0
  25. millforge/_forge/guardrails/step_enforcer.py +183 -0
  26. millforge/_forge/prompts/__init__.py +16 -0
  27. millforge/_forge/prompts/nudges.py +95 -0
  28. millforge/_forge/prompts/templates.py +285 -0
  29. millforge/_version.py +3 -0
  30. millforge/artifacts.py +570 -0
  31. millforge/base/__init__.py +97 -0
  32. millforge/base/composition.py +402 -0
  33. millforge/base/context.py +285 -0
  34. millforge/base/harness.py +138 -0
  35. millforge/base/identity.py +465 -0
  36. millforge/base/options.py +34 -0
  37. millforge/base/platform.py +17 -0
  38. millforge/base/prompt.py +317 -0
  39. millforge/base/runner.py +546 -0
  40. millforge/compiled_plan.py +970 -0
  41. millforge/compiler/__init__.py +231 -0
  42. millforge/compiler/artifact_validation.py +257 -0
  43. millforge/compiler/canonicalization.py +169 -0
  44. millforge/compiler/capabilities.py +66 -0
  45. millforge/compiler/catalogs.py +500 -0
  46. millforge/compiler/diagnostics.py +491 -0
  47. millforge/compiler/graph.py +678 -0
  48. millforge/compiler/lowering.py +198 -0
  49. millforge/compiler/output.py +692 -0
  50. millforge/compiler/parsing.py +1424 -0
  51. millforge/compiler/requests.py +1180 -0
  52. millforge/compiler/schema_validation.py +272 -0
  53. millforge/compiler/semantic.py +490 -0
  54. millforge/compiler/service.py +448 -0
  55. millforge/compiler/source.py +375 -0
  56. millforge/compiler/validators.py +184 -0
  57. millforge/connectors/__init__.py +95 -0
  58. millforge/connectors/admission.py +801 -0
  59. millforge/connectors/broker.py +202 -0
  60. millforge/connectors/contracts.py +1159 -0
  61. millforge/connectors/diagnostics.py +189 -0
  62. millforge/connectors/fake.py +66 -0
  63. millforge/connectors/runtime.py +236 -0
  64. millforge/contracts.py +2860 -0
  65. millforge/custom_tools/__init__.py +67 -0
  66. millforge/custom_tools/compiler.py +724 -0
  67. millforge/custom_tools/contracts.py +1093 -0
  68. millforge/custom_tools/diagnostics.py +205 -0
  69. millforge/eval_artifacts.py +952 -0
  70. millforge/eval_boundary.py +2435 -0
  71. millforge/eval_fixtures/__init__.py +1 -0
  72. millforge/eval_fixtures/default_pack/__init__.py +1 -0
  73. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.bug_diagnosis.traceback.v1.json +52 -0
  74. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.direct_edit.import_sort.v1.json +52 -0
  75. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.evidence_discipline.no_source_change.v1.json +51 -0
  76. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.false_closure.visible_green.v1.json +52 -0
  77. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.multi_file.api_contract.v1.json +54 -0
  78. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.recovery.malformed_artifact.v1.json +54 -0
  79. millforge/eval_fixtures/default_pack/manifest.json +12 -0
  80. millforge/eval_modes.py +1282 -0
  81. millforge/eval_presets.py +1398 -0
  82. millforge/eval_reports.py +2517 -0
  83. millforge/eval_suite.py +2429 -0
  84. millforge/eval_trials.py +2632 -0
  85. millforge/eval_workflow.py +794 -0
  86. millforge/exceptions.py +122 -0
  87. millforge/model_backend.py +2098 -0
  88. millforge/protocols.py +340 -0
  89. millforge/py.typed +0 -0
  90. millforge/runtime.py +1791 -0
  91. millforge/testing/__init__.py +1089 -0
  92. millforge/tools/__init__.py +83 -0
  93. millforge/tools/builtin_runtime.py +1339 -0
  94. millforge/tools/builtins.py +773 -0
  95. millforge/tools/execution.py +1545 -0
  96. millforge/tools/path_policy.py +155 -0
  97. millforge/tools/pi_compat/PI_LICENSE +21 -0
  98. millforge/tools/pi_compat/PROVENANCE.json +55 -0
  99. millforge/tools/pi_compat/UPDATE_POLICY.md +36 -0
  100. millforge/tools/pi_compat/__init__.py +34 -0
  101. millforge/tools/pi_compat/contracts.py +49 -0
  102. millforge/tools/pi_compat/editing.py +390 -0
  103. millforge/tools/pi_compat/mutations.py +57 -0
  104. millforge/tools/pi_compat/operations.py +401 -0
  105. millforge/tools/pi_compat/paths.py +155 -0
  106. millforge/tools/pi_compat/process.py +1375 -0
  107. millforge/tools/pi_compat/search.py +738 -0
  108. millforge/tools/pi_compat/truncation.py +267 -0
  109. millforge/tools/pi_compat_catalog.py +396 -0
  110. millforge/tools/pi_compat_runtime.py +460 -0
  111. millforge/tools/registry.py +553 -0
  112. millforge/tools/results.py +533 -0
  113. millforge-0.1.0.dist-info/METADATA +844 -0
  114. millforge-0.1.0.dist-info/RECORD +116 -0
  115. millforge-0.1.0.dist-info/WHEEL +4 -0
  116. millforge-0.1.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,844 @@
1
+ Metadata-Version: 2.4
2
+ Name: millforge
3
+ Version: 0.1.0
4
+ Summary: A typed Python runner and harness compiler for guarded LLM tool execution.
5
+ Project-URL: Homepage, https://github.com/tim-osterhus/millforge
6
+ Project-URL: Repository, https://github.com/tim-osterhus/millforge
7
+ Author-email: Tim Osterhus <tim@millrace.ai>
8
+ Maintainer-email: Tim Osterhus <tim@millrace.ai>
9
+ License-Expression: Apache-2.0
10
+ License-File: LICENSE
11
+ Keywords: agents,guardrails,llm,millforge,tool-calling
12
+ Classifier: Development Status :: 2 - Pre-Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: httpx>=0.27
26
+ Requires-Dist: pathspec<1,>=0.12
27
+ Requires-Dist: pydantic>=2.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: build; extra == 'dev'
30
+ Requires-Dist: mypy; extra == 'dev'
31
+ Requires-Dist: pytest; extra == 'dev'
32
+ Requires-Dist: pytest-asyncio; extra == 'dev'
33
+ Requires-Dist: ruff; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # Millforge
37
+
38
+ A typed Python runner and harness compiler for guarded LLM tool execution.
39
+
40
+ It is inspired by the principles of
41
+ [Forge guardrails](https://github.com/antoinezambelli/forge).
42
+
43
+ Millforge is currently pre-alpha. Its author and maintainer is
44
+ Tim Osterhus <tim@millrace.ai>, and its canonical homepage and source repository
45
+ are [github.com/tim-osterhus/millforge](https://github.com/tim-osterhus/millforge).
46
+
47
+ Millforge is licensed under Apache-2.0; packaged upstream MIT notices and
48
+ provenance records remain at `millforge/_forge/{LICENSE,PROVENANCE.json}` and
49
+ `millforge/tools/pi_compat/{PI_LICENSE,PROVENANCE.json}`.
50
+
51
+ ## Forge Provenance
52
+
53
+ | Field | Value |
54
+ |----------|-----------------------------------------------------------------------------|
55
+ | Name | forge-guardrails |
56
+ | Version | 0.7.4 |
57
+ | License | MIT |
58
+ | Upstream | [https://github.com/antoinezambelli/forge](https://github.com/antoinezambelli/forge) |
59
+ | Commit | `bd99f4df0a7aab2fd4db2e6dae7f810a32617d76` |
60
+
61
+ Millforge is an independent project. Its public API is Millforge-owned, while
62
+ `src/millforge/_forge/` contains a private vendored subset of the reviewed
63
+ Forge v0.7.4 guarded-loop implementation. That subset is limited to
64
+ transport-free protocol helpers, workflow/message/step/inference/runner
65
+ modules, guardrails, prompt helpers, fixed context management, the private
66
+ Millforge plan-translation adapter layer, and private model/tool/terminal
67
+ bridge adapters, plus `ForgeGuardrailBackend` runtime integration.
68
+
69
+ The vendored subset intentionally excludes provider clients, proxy/server/CLI
70
+ modules, eval assets, dashboards, hardware discovery, `httpx`, provider SDKs,
71
+ and transport implementation code. Runtime package code does not import or
72
+ depend on `ref-forge/`.
73
+
74
+ Machine-readable provenance lives in
75
+ `src/millforge/_forge/PROVENANCE.json`. The upstream MIT license is retained in
76
+ `src/millforge/_forge/LICENSE`, and update rules are documented in
77
+ `src/millforge/_forge/UPDATE_POLICY.md`.
78
+
79
+ Private behavioral patches are recorded in the manifest's
80
+ `private_behavior_patches` section. They currently cover configurable guarded
81
+ loop violation budgets, non-retryable tool outcomes, strict supported-subset
82
+ JSON Schema conversion, mapped prerequisite argument enforcement, and private
83
+ subset import safety. Runtime adapter behavior also classifies exhausted
84
+ prerequisite correction budgets as `budget_exhausted` with diagnostic code
85
+ `prerequisite_budget_exhausted`.
86
+
87
+ ## Snapshot Comparison
88
+
89
+ Millforge's reference snapshot in `ref-forge/` is based on upstream
90
+ [forge-guardrails](https://github.com/antoinezambelli/forge) tag
91
+ [`v0.7.4`](https://github.com/antoinezambelli/forge/releases/tag/v0.7.4).
92
+ The snapshot was taken at commit
93
+ `bd99f4df0a7aab2fd4db2e6dae7f810a32617d76`.
94
+
95
+ **Note:** The `ref-forge/` directory is a plain-file snapshot and does **not**
96
+ contain `.git` metadata. It is provided for reference and comparison purposes
97
+ only.
98
+
99
+ ## Development
100
+
101
+ - Python 3.11 or newer
102
+ - Install for development: `pip install -e ".[dev]"`
103
+ - Run tests: `pytest`
104
+ - Lint: `ruff check .`
105
+ - Format: `ruff format --check .`
106
+
107
+ | Runtime | Support |
108
+ |---------|---------|
109
+ | Linux on Python 3.11-3.13 | Supported |
110
+ | macOS on Python 3.11-3.12 | Supported |
111
+ | WSL | Supported through Linux |
112
+ | Native Windows | Deferred |
113
+
114
+ CPython is the gated interpreter. PyPy and other alternative interpreters are
115
+ not currently claimed as supported.
116
+
117
+ To verify the committed checkout without inherited local state, run this from
118
+ the source repository in a POSIX shell using the provisioned development
119
+ environment:
120
+
121
+ ```bash
122
+ source_repo=$(git rev-parse --show-toplevel)
123
+ source_commit=$(git rev-parse HEAD)
124
+ tmp_dir=$(mktemp -d)
125
+ trap 'rm -rf "$tmp_dir"' EXIT
126
+
127
+ git clone --no-hardlinks "$source_repo" "$tmp_dir/millforge"
128
+ cd "$tmp_dir/millforge"
129
+ test "$(git rev-parse HEAD)" = "$source_commit"
130
+ test ! -e millrace-agents
131
+ test ! -e ideas
132
+ test ! -e ref-forge
133
+ test ! -e reference
134
+ test -z "$(git status --short --untracked-files=all)"
135
+
136
+ python -m pytest \
137
+ tests/test_connector_custom_tool_closure.py \
138
+ tests/test_pi_compat_operations.py \
139
+ tests/test_tool_registry_closure.py \
140
+ tests/test_forge_provenance.py
141
+ python -m pytest -m "not live_model_backend"
142
+ test -z "$(git status --short)"
143
+ ```
144
+
145
+ ## Millforge Base
146
+
147
+ `millforge-base` is an unrestricted compatibility preset based on
148
+ `@earendil-works/pi-coding-agent` 0.79.6.
149
+
150
+ Runner execution is supported on Linux and macOS. WSL is supported through its
151
+ Linux execution semantics (`sys.platform == "linux"`). Native Windows is
152
+ unsupported and deferred: package import and argument-free
153
+ `describe_millforge_base()` inspection remain available there, but composition,
154
+ runner creation, and execution raise `UnsupportedPlatformError` before context
155
+ discovery, artifact creation, model resolution, provider calls, process work,
156
+ or tool side effects. Millforge does not claim native Windows path, shell,
157
+ process-tree, or fixture parity.
158
+
159
+ > A Python behavioral port of Pi 0.79.6's complete built-in coding tool pack, adapted to Millforge's compiler and runtime contracts.
160
+
161
+ It exposes Pi-derived `read`, `bash`, `edit`, `write`, `grep`, `find`, and
162
+ `ls` tools, plus `submit`, `block`, and `reject` terminal controls.
163
+
164
+ **Security warning:** `millforge-base` is unrestricted and unsandboxed.
165
+
166
+ > millforge-base runs with the permissions of the Millforge process. It can read, write, delete, execute commands, access the network, and access credentials available to that process. Use only in trusted environments.
167
+
168
+ Deliberate adaptations replace Pi's Node filesystem and process APIs with
169
+ Python APIs, use the documented Python search behavior instead of `fd`/`rg`,
170
+ return text-only supported-image reads, translate cancellation to Millforge's
171
+ poll/wait protocol, and resolve the host shell through the Pi-compatible
172
+ platform policy. The machine-readable source records and adaptations are in
173
+ `src/millforge/tools/pi_compat/PROVENANCE.json`.
174
+
175
+ The Python composition API creates the validated source, compiled plan,
176
+ Pi-compatible executor, and sanitized metadata without a provider call:
177
+
178
+ ```python
179
+ from pathlib import Path
180
+
181
+ from millforge import create_millforge_base_components
182
+
183
+ components = create_millforge_base_components(
184
+ model_profile=profile,
185
+ cwd=Path("/absolute/workspace"),
186
+ cancellation_resolver=cancellation_resolver,
187
+ )
188
+ ```
189
+
190
+ The supported live OpenAI-compatible surface is
191
+ `create_millforge_base_live_runner()`. Construction is async only so any
192
+ factory-owned HTTP client can be cleaned up if a later local construction step
193
+ fails; it performs no network request or provider probe. Every Millforge type
194
+ and factory in this direct construction, execution, and asynchronous cleanup
195
+ example is imported from the `millforge` package root:
196
+
197
+ ```python
198
+ from pathlib import Path
199
+
200
+ from millforge import (
201
+ AuthenticationPolicy,
202
+ AuthenticationScheme,
203
+ CapabilityDeclarations,
204
+ CapabilitySupport,
205
+ EndpointConfig,
206
+ OpenAICompatibleTimeouts,
207
+ RequestOptionAllowlist,
208
+ ResolvedModelProfile,
209
+ SecretRef,
210
+ create_millforge_base_live_runner,
211
+ )
212
+
213
+ secret_ref = SecretRef(secret_id="model-key", env_var="MODEL_API_KEY")
214
+ profile = ResolvedModelProfile(
215
+ profile_id="local-tools",
216
+ provider_id="openai-compatible",
217
+ model_id="tool-model",
218
+ endpoint=EndpointConfig(base_url="https://models.example/v1"),
219
+ authentication=AuthenticationPolicy(
220
+ scheme=AuthenticationScheme.BEARER,
221
+ secret_ref=secret_ref,
222
+ ),
223
+ capabilities=CapabilityDeclarations(
224
+ support={
225
+ "tool_calls": CapabilitySupport.SUPPORTED,
226
+ "system_messages": CapabilitySupport.SUPPORTED,
227
+ "tool_result_messages": CapabilitySupport.SUPPORTED,
228
+ }
229
+ ),
230
+ request_options=RequestOptionAllowlist(
231
+ allowed_options=("parallel_tool_calls",),
232
+ ),
233
+ timeout_seconds=90,
234
+ source_digest="caller-profile-v1",
235
+ )
236
+
237
+ live_runner = await create_millforge_base_live_runner(
238
+ profile_id="local-tools",
239
+ model_profile=profile,
240
+ secret_ref=secret_ref,
241
+ secret_resolver=secret_resolver,
242
+ cwd=Path("/absolute/workspace"),
243
+ clock=clock,
244
+ cancellation_resolver=cancellation_resolver,
245
+ artifact_writer_factory=artifact_writer_factory,
246
+ timeouts=OpenAICompatibleTimeouts(
247
+ connect_seconds=10,
248
+ read_seconds=90,
249
+ write_seconds=30,
250
+ pool_seconds=10,
251
+ local_total_seconds=75,
252
+ ),
253
+ # http_transport=httpx.MockTransport(handler), # deterministic offline seam
254
+ )
255
+ async with live_runner:
256
+ result = await live_runner.execute(request)
257
+ ```
258
+
259
+ Here `request` is a public `HarnessExecutionRequest` whose compiled-harness and
260
+ capability values agree with `live_runner.components`; the isolated package
261
+ smoke in `scripts/installed_package_smoke.py` shows the complete request and a
262
+ two-call fake OpenAI-compatible traversal. Consumer code does not import
263
+ `millforge.model_backend`, `millforge._forge`, or checkout-only test helpers.
264
+
265
+ The effective model-call timeout is the minimum of the request deadline, the
266
+ resolved profile's `timeout_seconds`, and `local_total_seconds`; each HTTP phase
267
+ is narrowed further by its named bound. The live runner owns and closes only the
268
+ model client and HTTP client it creates. The secret resolver, clock,
269
+ cancellation resolver, artifact-writer factory, and optional injected
270
+ `AsyncHttpTransport` (including `httpx.MockTransport`) remain caller-owned.
271
+ `aclose()` is idempotent,
272
+ factory-owned resources close once, and execution after close raises
273
+ `MillforgeBaseClosedError`.
274
+
275
+ `HarnessExecutionRequest.stage` is provider-local: it identifies the compiled
276
+ Millforge harness stage, not a caller workflow plane, node, route, dispatch
277
+ identity, or authority. `MillforgeBaseRunner` admits exactly
278
+ `StageIdentity(plane="execution", node_id="millforge-base",
279
+ stage_kind_id="millforge_base")` and rejects every field mismatch before the
280
+ private invocation executor, model, or tools are called. Caller-supplied
281
+ `request_id` and `run_id` values are opaque correlation values; Millforge
282
+ validates and echoes them unchanged but does not interpret them as routing,
283
+ outcome, or terminal authority. An external adapter retains and applies any
284
+ caller workflow identity and authority separately. Per-request
285
+ `runner.invocation_evidence_for(request)` returns immutable, self-hashed
286
+ invocation evidence that carries those same correlation values without adding
287
+ workflow authority. Its request-local serialized schema is `1.2`; consumers
288
+ must treat its digest as changed from the earlier composition-only evidence.
289
+
290
+ Selected output is an opt-in, invocation-local request authority. The public
291
+ `SelectedOutputRequirement` contract freezes one required/optional closed JSON
292
+ schema and pins its canonical SHA-256 digest; `SelectedOutputAbsent` and
293
+ `SelectedOutputPresent(value=None)` keep omission distinct from JSON `null`.
294
+ Selected schemas and admitted values are bounded by named public ceilings and
295
+ reject unsupported keywords/types, duplicate keys, non-finite numbers, invalid
296
+ bounds, and oversized or excessively nested data. The selected schema digest
297
+ and required/optional state appear in request-local invocation evidence only
298
+ when authority is present; no-selection request serialization and behavior are
299
+ preserved.
300
+
301
+ For a custom subset, define an ordinary harness DSL graph with the desired
302
+ Pi-compatible descriptor references and compile it through the normal
303
+ Millforge compiler; `MillforgeBaseOptions` deliberately has no tool-selection
304
+ setting. Millrace may select `millforge-base` as a compile-time default only
305
+ when the pinned runner descriptor declares the current platform. On native
306
+ Windows, default resolution must fail closed or select another explicitly
307
+ configured supported runner; runtime fallback must never remap an already
308
+ compiled Millforge binding.
309
+ Millrace default selection, external workflow mapping, and live efficacy
310
+ evaluation remain explicitly deferred to Millrace integration work.
311
+
312
+ ## Millforge 03A Closure Evidence
313
+
314
+ Closure evidence for 03A was refreshed on `2026-06-14T09:11:34Z` for
315
+ `task-03a-r2-04-closure-evidence-and-gates`.
316
+
317
+ Contract coverage:
318
+
319
+ - Source contract field table: `HarnessSource`, `StageScopeSource`,
320
+ `PromptSource`, `BudgetSource`, `ContextPolicySource`, `HarnessGraphSource`,
321
+ `HarnessNodeSource`, `PrerequisiteSource`, `ArgumentMatchSource`,
322
+ `ArtifactPolicySource`, and terminal artifact policies are implemented in
323
+ `src/millforge/compiler/source.py` with strict Pydantic v2 models,
324
+ `extra="forbid"`, frozen contracts, explicit defaults, identifier bounds,
325
+ collection bounds, tuple-backed snapshots, and mapping-to-record conversion.
326
+ - Canonical YAML and equivalent JSON examples are covered by
327
+ `tests/compiler/test_parsing.py`; both front ends validate into the same
328
+ `HarnessSource` model.
329
+ - Parser threat and limit matrix coverage includes duplicate keys, decoded key
330
+ equivalence, unsafe YAML aliases/anchors/merge keys/tags, non-string keys,
331
+ multiple documents, non-finite numbers, controls, invalid UTF-8, source size,
332
+ nesting depth, entry count, scalar size, numeric lexeme limits, JSON leading
333
+ whitespace, trailing JSON content, and top-level object requirements.
334
+ - Diagnostic trigger evidence covers request, parse, schema, cross-field,
335
+ source-secret, ordering, truncation, and redaction cases in
336
+ `tests/compiler/test_diagnostics.py`, `tests/compiler/test_parsing.py`, and
337
+ `tests/compiler/test_requests.py`, including public unsupported-format parser
338
+ coverage for `MF-S005`, exact schema trigger coverage for `MF-S021`
339
+ unknown fields, `MF-S022` identifiers, `MF-S023` unversioned tool
340
+ references, `MF-S024` budgets, and `MF-S025` context policy values, plus
341
+ request-admission precedence for `MF-S018`.
342
+ - Source-location examples cover parser and schema diagnostics with RFC 6901
343
+ field paths and one-based line/column locations.
344
+ - Request and result serialized examples, result invariant matrix, raw request
345
+ admission examples, path-containment evidence, output-directory evidence,
346
+ source hash examples, replacement-race evidence, deep-snapshot proof, and
347
+ no-I/O/deferred-boundary proof are covered by `tests/compiler/test_requests.py`,
348
+ `tests/compiler/test_source.py`, and
349
+ `tests/compiler/test_frontend_boundaries.py`.
350
+ - Schema-phase failure results preserve `source_document_sha256` and parsed
351
+ `harness_id` after a successful source parse, while request-phase and
352
+ parse-phase failures continue to omit parsed identity; `tests/compiler/test_requests.py`
353
+ covers the expected-harness mismatch and adjacent cross-field failure
354
+ boundaries.
355
+ - Secret-helper evidence is covered without recording suspected source scalar
356
+ values; diagnostics and serialized outputs use redacted fields only.
357
+ - Dependency and deferred-boundary audit evidence confirms compiler modules do
358
+ not import `_forge`, runtime execution, catalog resolution, HTTP/network,
359
+ subprocess, or model/tool invocation boundaries.
360
+
361
+ Verification commands and results:
362
+
363
+ ```text
364
+ python -m pytest
365
+ 732 passed, 1 skipped in 8.89s
366
+
367
+ python -m ruff check .
368
+ All checks passed!
369
+
370
+ python -m ruff format --check .
371
+ 58 files already formatted
372
+
373
+ python -m mypy .
374
+ Success: no issues found in 35 source files
375
+
376
+ python -m build
377
+ Successfully built millforge-0.1.0.tar.gz and millforge-0.1.0-py3-none-any.whl
378
+ ```
379
+
380
+ Source-control evidence:
381
+
382
+ ```text
383
+ git diff --stat acd4491b905e635d6d3f9e9878206042a74692eb
384
+ README.md | 90 ++
385
+ src/millforge/compiler/__init__.py | 103 ++
386
+ src/millforge/compiler/diagnostics.py | 400 ++++++++
387
+ src/millforge/compiler/parsing.py | 1424 ++++++++++++++++++++++++++++
388
+ src/millforge/compiler/requests.py | 1152 ++++++++++++++++++++++
389
+ src/millforge/compiler/source.py | 375 ++++++++
390
+ src/millforge/compiler/validators.py | 171 ++++
391
+ tests/compiler/test_diagnostics.py | 159 ++++
392
+ tests/compiler/test_frontend_boundaries.py | 71 ++
393
+ tests/compiler/test_parsing.py | 579 +++++++++++
394
+ tests/compiler/test_requests.py | 955 +++++++++++++++++++
395
+ tests/compiler/test_source.py | 203 ++++
396
+ 12 files changed, 5682 insertions(+)
397
+
398
+ git status --short --branch
399
+ ## main...origin/main [ahead 1]
400
+ ```
401
+
402
+ ## Millforge 03B Semantic Compiler Boundary
403
+
404
+ 03B adds a private semantic compiler layer under `src/millforge/compiler/`.
405
+ It consumes an accepted 03A `CompileInvocation` and `HarnessSource` plus one
406
+ tool catalog snapshot and one model-profile snapshot. It resolves exact tool
407
+ bindings and the compiled model profile, validates graph legality, top-level
408
+ argument matches, required capability grants, and terminal-required artifacts,
409
+ then produces a private immutable `ResolvedHarness` for later lowering.
410
+
411
+ The resolved IR is not a public API and is not a compiled plan. 03B performs no
412
+ source or output path I/O, source-file rereads, catalog refresh, plugin
413
+ discovery, network calls, subprocess calls, runtime execution, output writes,
414
+ compiled-plan hashing, or lowering. Those responsibilities are orchestrated by
415
+ the 03C default compiler service in `src/millforge/compiler/service.py`, which
416
+ delegates lowering to `src/millforge/compiler/lowering.py` and compiler output
417
+ publication in `src/millforge/compiler/output.py`; runtime execution and
418
+ registry/runtime work remain deferred.
419
+
420
+ Remediated 03B closure evidence was refreshed on `2026-06-14T18:35:03Z` for
421
+ `task-03b-r1-05-exact-closure-evidence-and-offline-gates`. The closure target is
422
+ exact semantic parity with the canonical 03B root-source contract, not a new
423
+ public compiled-plan or runtime result family. The evidence expects exact
424
+ code-to-trigger coverage for catalog resolution, schema normalization, graph and
425
+ argument validation, capability aggregation, artifact satisfiability, deferred
426
+ scope, source-control state, and full offline gates.
427
+
428
+ Representative 03B fixtures live under `tests/compiler/`:
429
+
430
+ - `test_catalogs.py` covers catalog metadata capture, closed lookup outcomes,
431
+ `resolve_exact` protocol shape, immutable descriptor admission, model-profile
432
+ admission, lookup exception redaction, and reusable static snapshot fixtures.
433
+ - `test_schema_validation.py` covers the compiler-owned JSON Schema subset,
434
+ scalar `const` replacement for `type`, `null` const values, declared enum
435
+ order, numeric scalar duplicate identity, deterministic normalization,
436
+ compatibility bytes, and checked-in golden parity vectors without importing
437
+ private Forge modules.
438
+ - `test_graph.py`, `test_capabilities.py`, and
439
+ `test_artifact_validation.py` cover graph reachability and legality,
440
+ terminal-prerequisite separation from argument-match failures, exact
441
+ capability aggregation, artifact satisfiability, duplicate artifact IDs,
442
+ terminal-gated producer evidence, determinism, and no-cascade behavior.
443
+ - `test_semantic.py` covers successful semantic compilation into the private
444
+ immutable IR, 03A failure pass-through without catalog access, catalog
445
+ resolution failures including `MF-R009` internal failures, duplicate bindings,
446
+ duplicate model tool names, capability and artifact failures, and
447
+ unresolved-node suppression.
448
+ - `test_frontend_boundaries.py` audits compiler modules for deferred imports
449
+ and forbidden I/O/runtime invocation calls.
450
+
451
+ ## Millforge 03C Compiler Service, Lowering, and Output Boundary
452
+
453
+ 03C's default validated compiler service in `src/millforge/compiler/service.py`
454
+ orchestrates admitted compile requests through semantic validation, lowering,
455
+ compiled-hash verification, and atomic output publication. The service exposes
456
+ the public typed `HarnessCompiler` boundary, reuses the parsed source carried
457
+ by request admission, preserves front-end-before-catalog ordering, and returns
458
+ immutable compile results with deterministic diagnostics.
459
+
460
+ `tests/compiler/test_service.py` covers successful commits,
461
+ front-end-before-catalog precedence, semantic failure normalization, and
462
+ output-directory admission failure handling. `tests/compiler/test_lowering.py`
463
+ covers accepted field shape, nested required fields, deterministic ordering,
464
+ compiled-hash verification, and forbidden-data exclusion.
465
+ `tests/compiler/test_output.py` covers request identity hashing, path
466
+ confinement, admitted-directory revalidation, no-clobber reuse/conflict,
467
+ durability failure handling, and diagnostics persistence.
468
+ The compiler test area also includes checked-in YAML/JSON golden harness
469
+ fixtures under `tests/compiler/fixtures/`, exact semantic and compiled-plan
470
+ byte/hash assertions, output failure injection, and same-destination
471
+ concurrent publication coverage. The representative golden fixtures cover
472
+ three fixture pairs, including a rich case with two legal terminal results
473
+ (`BLOCKED` and `BUILDER_COMPLETE`), a terminal-required artifact, all accepted
474
+ budget fields, context phase thresholds, and multi-capability aggregation.
475
+ Across all three cases, the representative fixture set pins exact diagnostics
476
+ report shape and semantic-change hash movement without importing production
477
+ Spec 07 preset ownership.
478
+ Output diagnostics use the 03C root-source meanings: `MF-O001` for invalid
479
+ output paths, `MF-O002` for diagnostics write failures, `MF-O003` for plan
480
+ write failures, `MF-O004` for existing content-addressed output integrity
481
+ failures, and `MF-O005` for temporary output cleanup failures.
482
+ Lowering and internal diagnostics use the R2 root-source meanings:
483
+ `MF-L001` for lowering invariant failures, `MF-L002` for accepted compiled-plan
484
+ validation failures, `MF-L003` for source semantic hash failures, `MF-L004` for
485
+ compiled hash verification failures, and `MF-I001` for bounded compiler
486
+ internal errors.
487
+
488
+ 03C compiler output is the accepted `CompiledHarnessPlan` contract, not a
489
+ compiler-specific plan shape. `source_document_sha256` remains compile-result
490
+ evidence over the admitted normalized source document bytes, while
491
+ `source_sha256` is stored in the emitted plan as the SHA-256 of the canonical
492
+ validated semantic payload. The compiled hash is calculated by removing only
493
+ the top-level `compiled_sha256` field from a complete JSON-mode plan payload,
494
+ serializing with the shared canonical JSON encoder, hashing the UTF-8 bytes,
495
+ reconstructing the final plan, and passing the shared
496
+ `verify_compiled_plan_sha256()` verifier before output commit.
497
+ The compiler service uses the shared
498
+ `src/millforge/compiled_plan.py::calculate_compiled_plan_sha256()` helper for
499
+ that pre-verifier check, preserving Arbiter criterion 7's single owned
500
+ compiled-hash algorithm boundary.
501
+
502
+ Emitted plan bytes are canonical compact UTF-8 JSON with one trailing newline
503
+ and are published under the admitted output directory as relative
504
+ `<url-escaped-harness-id>@<harness-version>.<compiled-sha256>.compiled.json`
505
+ paths, for example
506
+ `compiled/millforge.test.golden.compiler.v1@1.1d65583fe8bd8379d95f889fe0e889d9ee28ada85d912db9188191eb73bddc52.compiled.json`.
507
+ Diagnostics remain request-addressed and use request-only,
508
+ source-document-hash plus request-hash, or compiled-digest plus request-hash
509
+ path forms such as
510
+ `compiled/<harness-id>@<harness-version>.<compiled-sha256>.request-<request-identity-sha256>.diagnostics.json`.
511
+ Diagnostics reports move from prepared to committed evidence only after plan
512
+ publication is confirmed, and serialized diagnostics redact secret-looking
513
+ messages and scalar fields before persistence. The
514
+ `FileCompiledHarnessLoader` loads those emitted bytes through the same
515
+ parse/hash/identity verifier used by runtime preflight. The focused
516
+ compatibility test in `tests/compiler/test_service.py` removes the original
517
+ harness source tree, loads only the emitted compiled bytes, and proves
518
+ `DefaultHarnessRuntime` reaches the deterministic fake backend after preflight.
519
+
520
+ Representative 03C coverage remains offline and deterministic. It covers the
521
+ compiler-output boundary, hash stability, output-state guarantees, runtime
522
+ loader/preflight compatibility, Forge adapter field compatibility, and package
523
+ content inspection without live provider calls. The public offline Spec 07
524
+ preset registry and readiness report now live in `millforge.eval_presets`,
525
+ the public offline 08B eval-trial contract boundary, including
526
+ caller-selected append-only campaign-store APIs, now lives in
527
+ `millforge.eval_trials`, and the public offline 08C eval-reporting layer,
528
+ including budget policy, live-admission diagnostics, metric aggregation, and
529
+ deterministic JSON/Markdown report generation, now lives in
530
+ `millforge.eval_reports`, while live Spec 07 execution and admission remain
531
+ deferred to the owning workstream. The 08C `report.json`, `report.md`, and
532
+ report-hash artifacts are deterministic offline evidence only: they document
533
+ campaign contracts, budget/admission state, metrics, confounds, decision rules,
534
+ and reproducibility hashes, and they explicitly do not support Pi-vs-Millforge
535
+ model-performance conclusions from offline fake execution. The public offline
536
+ `millforge.eval_suite` layer also offers `configure_offline_fake_eval_campaign()`
537
+ for preflight and `run_offline_fake_eval_campaign()` for the full
538
+ deterministic dry-campaign flow, which composes packaged fixtures, paired
539
+ trial planning, offline fake execution, append-only campaign-store writes,
540
+ resume indexing, and deterministic report generation under a caller-selected
541
+ root. The same dry-campaign result now carries compact public closure evidence
542
+ with deterministic hashes, counts, unresolved live dependencies, live-denial
543
+ coverage references, Spec 07E treatment harness hash evidence, public hygiene
544
+ flags, and an explicit offline-only claim boundary. No CLI is added for this
545
+ slice: the public Python entry points keep the dry-run contract importable and
546
+ testable while command UX, live runner orchestration, and operator-facing
547
+ campaign controls remain deferred to the live-campaign workstream. Future live
548
+ campaigns should reuse the same fixture-pack, trial-plan, append-only record,
549
+ budget/admission, report, and closure-evidence contracts, replacing only the
550
+ offline fake runner with admitted live Pi and Millforge runner execution.
551
+
552
+ 03C R2 closure evidence maps the latest Arbiter gaps to completed work:
553
+ canonical lowering/internal diagnostic meanings, three representative YAML/JSON
554
+ fixture pairs with exact semantic and compiled hashes plus diagnostics report
555
+ shape assertions, and a complete deterministic failure-injection matrix across
556
+ source semantic hashing, accepted-plan validation, compiled-hash verification,
557
+ diagnostics persistence, plan output, publication, directory fsync, and
558
+ temporary cleanup boundaries. The evidence continues to preserve the typed
559
+ `HarnessCompiler` protocol, accepted `CompiledHarnessPlan` lowering, output
560
+ addressing, same-plan concurrency, different-request diagnostics non-collision,
561
+ and runtime compatibility through emitted compiled bytes loaded without the
562
+ original source tree.
563
+
564
+ ## Millforge 03D Compiler Hardening and Spec 03 Closure
565
+
566
+ 03D closes the implemented Spec 03 compiler packet while preserving the
567
+ accepted 03C baseline at commit
568
+ `ebfa3ed205758780fef431674cf525e50f1559a5`. The final closure evidence is
569
+ retained in the run-local conformance matrix and refreshed closure report for
570
+ `task-03d-r4-03-closure-evidence-gate-refresh`, which preserved the exact
571
+ offline gate set after the matrix parity pass and redacted the broad
572
+ secret-pattern scan outputs.
573
+
574
+ 03D hardening adds or retains exact evidence for bounded parser adversarial
575
+ coverage, source-contract property checks, graph oracle tests, catalog drift,
576
+ descriptor-change hash behavior, capability/artifact validation, service
577
+ failure precedence, deterministic compile variants, diagnostics sentinel
578
+ redaction, filesystem/output failure injection, runtime loading from emitted
579
+ compiled bytes, package/dependency boundaries, archive contents, Forge
580
+ provenance, and unchanged `ref-forge/` state.
581
+
582
+ Default verification remains offline and deterministic: the compiler suite,
583
+ full pytest suite, Ruff lint, Ruff format check, MyPy, package build, wheel
584
+ listing (`python -m zipfile -l dist/*.whl`), sdist listing
585
+ (`tar -tzf dist/*.tar.gz`), baseline diff stat (`git diff --stat
586
+ ebfa3ed205758780fef431674cf525e50f1559a5`), and source-control status
587
+ (`git status --short --branch --untracked-files=all`) are the closure gates.
588
+ The live OpenAI-compatible backend smoke remains opt-in and is not part of
589
+ default closure.
590
+
591
+ 03D does not implement or claim Millrace runner binding, production built-in
592
+ tool registry behavior, admitted connector compilation, small-model Millrace
593
+ workflow behavior, production Spec 07 preset compilation, comparative
594
+ evaluation workflow behavior, or live provider/model/tool execution. Those
595
+ remain deferred to Spec 01, Spec 04, Spec 05, Spec 06, Spec 07, and Spec 08
596
+ respectively.
597
+
598
+ ## Millforge 04A Tool Registry Core
599
+
600
+ 04A adds the public `millforge.tools` registry core. It provides immutable
601
+ `ToolDescriptor`, `ToolTimeoutPolicy`, and `ToolOutputPolicy` contracts,
602
+ registry-computed deterministic descriptor hashes, explicit in-process
603
+ `ToolRegistry` registration, immutable exact-version
604
+ `FrozenToolRegistrySnapshot` lookup, and projection into the existing compiler
605
+ catalog and `ToolBindingRef` path.
606
+
607
+ The package exposes registry constants, descriptor hash records, typed registry
608
+ errors, and descriptor hash payload inspection helpers for deterministic
609
+ evidence. Descriptor and snapshot hashing remains generic and registry-owned;
610
+ 04A does not ship production `builtin.*` descriptors, a default production
611
+ registry, production presets, tool execution or dispatch, connector admission,
612
+ live provider dependencies, or Millrace runner integration.
613
+
614
+ ## Millforge 04B Built-In Tool Descriptor Data
615
+
616
+ 04B adds the descriptor-only production `builtin.*` catalog data under
617
+ `src/millforge/tools/`. It now spans 26 version-1 built-in descriptors for
618
+ request inspection, workspace listing/reading/searching/writing/patching,
619
+ named test execution, static checks, artifact read/write, terminal
620
+ submit/reject/escalate actions, and the fixed artifact bridge readers and
621
+ split verdict writers, all using the accepted 04A registry contracts.
622
+
623
+ The built-in catalog stays import-safe and side-effect-free. It exposes the
624
+ immutable descriptor set, deterministic registry construction helper, and
625
+ frozen exact-version snapshot helper, but it still does not add tool execution,
626
+ dispatch maps, connector admission, custom tools, production presets, queue
627
+ policy, implementation registration objects, or Millrace runner integration.
628
+
629
+ ### Spec 07 Capability Projection Boundary
630
+
631
+ Spec 07 compile cases validate concrete tool-level compiler/catalog grants,
632
+ including `request.read`, `artifact.read`, `artifact.write`, `workspace.read`,
633
+ `workspace.write`, `workspace.diff.read`, `process.test`,
634
+ `process.static_check`, and `terminal.intent`. These grants are the catalog
635
+ capability vocabulary used by built-in descriptors and semantic compilation.
636
+
637
+ That vocabulary remains separate from the broader 06B eval-stage capability
638
+ envelope concepts. 06B envelopes include `evidence.emit`, `runner.invoke`,
639
+ `shell.run`, and broad workspace, package, network, git, and runtime-control
640
+ envelopes. Spec 07 projects eval-stage needs into concrete compiler/catalog
641
+ tool grants; it does not rename or replace the 06B capability names.
642
+
643
+ The boundary is pinned by
644
+ `tests/test_eval_presets.py::test_checker_compile_case_needs_tool_level_grants_not_only_06b_eval_envelope`
645
+ and
646
+ `tests/test_builtin_tool_catalog.py::test_builtin_descriptors_feed_capability_validation`.
647
+
648
+ ## Millforge 04C Tool Execution Boundary
649
+
650
+ 04C adds the compiled-plan-scoped runtime execution boundary under
651
+ `src/millforge/tools/`. It exposes `create_builtin_tool_executor(...)` from
652
+ `millforge.tools` and admits calls only through exact `ToolBindingRef`
653
+ matches from the frozen compiled plan plus the accepted 04B built-in snapshot.
654
+
655
+ Runtime implementations stay explicit and source-owned. Accepted built-in
656
+ `implementation_id` values are registered to callables in source rather than
657
+ descriptor import strings, dotted paths, plugin loading, connector lookup, or
658
+ other dynamic dispatch.
659
+
660
+ Binding denial is fail-closed and typed, with deterministic `not_found`,
661
+ `conflict`, and `binding_mismatch` categories for uncompiled names, ambiguous
662
+ model-visible names, runtime-implementation gaps, and projection mismatches.
663
+
664
+ `DefaultHarnessRuntime` threads a runtime-owned `ToolExecutionContext` through
665
+ the guarded session and into the tool-executor bridge, so tool dispatch uses
666
+ trusted request, stage, run, workspace, artifact, capability, deadline, and
667
+ cancellation data supplied by the runtime rather than model-authored
668
+ substitutes.
669
+
670
+ ### Execution Validation, Results, And Traces
671
+
672
+ Model tool calls are converted into closed `ValidatedToolCall` objects before
673
+ implementation entry, so extra fields are rejected by schema rather than
674
+ flowing into the runtime.
675
+
676
+ The runtime rechecks prerequisites, required capabilities, deadlines, and
677
+ cancellation before dispatch. Built-in calls also pass through an
678
+ executor-owned, non-effectful pre-entry policy gate before implementation
679
+ entry, covering workspace logical-path containment, artifact declarations and
680
+ availability, shell profile/selector/timeout admission, and terminal artifact
681
+ requirements. The runtime validates implementation output against descriptor
682
+ output schemas after completion and fails closed on invalid output before
683
+ model-visible return, then redacts and bounds accepted results before return.
684
+
685
+ Every attempted or denied call emits a `ToolTraceRecord`. Pre-entry denials
686
+ persist `side_effect_certainty=not_attempted`, and resolved, ambiguous, and
687
+ uncompiled binding states are preserved through `binding_resolution_status`.
688
+ Connector traces also carry structured approval, drift, request/response,
689
+ retry, and redacted-evidence fields so failures stay auditable without prose
690
+ summaries.
691
+
692
+ ## Millforge 04D Tool Registry Closure Evidence
693
+
694
+ 04D closes the accepted Spec 04 tool-registry packet with retained offline
695
+ evidence rather than new production authority. The closure surface is the
696
+ machine-checkable conformance matrix at
697
+ `tests/fixtures/spec04_conformance_matrix.json`, validated by
698
+ `tests/test_tool_registry_closure.py`, plus focused readiness tests for the
699
+ 04A registry contracts, 04B built-in descriptor catalog, and 04C built-in
700
+ execution boundary.
701
+
702
+ The package and documentation audits keep the public claim narrow:
703
+ implemented Spec 04 behavior covers registry descriptors, built-in catalog
704
+ data, exact compiled-plan tool binding, built-in execution policy gates,
705
+ trace/result evidence. Offline 05A through 05D closure work adds connector
706
+ admission, runtime-boundary admission snapshots, compile-only custom-tool
707
+ descriptors, and mixed registry/catalog/compiler evidence through the generic
708
+ tool path. Deferred live connector transport, marketplace installation,
709
+ production stage presets, Millrace runner integration, eval-suite execution,
710
+ live connector execution, and live provider/model/tool execution remain
711
+ deferred.
712
+
713
+ Default Spec 04 closure verification is offline and deterministic. The retained
714
+ gate set includes the focused registry closure suite, the full pytest suite,
715
+ Ruff lint and format checks, MyPy, `pip check`, package build, wheel and sdist
716
+ archive listings, the accepted 04C baseline diff, source-control status, and
717
+ private-state checks for `millrace-agents/`, `ideas/`, and `ref-forge/`.
718
+
719
+ ## Millforge 05A Connector Descriptor Admission
720
+
721
+ 05A adds the public `millforge.connectors` package for deterministic offline
722
+ connector descriptor admission. It exposes frozen connector identity, discovery
723
+ snapshot, admission manifest, admission policy, admission result, admission
724
+ record, and diagnostic contracts, plus `admit_connector_tools(...)` for
725
+ lowering explicitly admitted discovered tools into existing immutable
726
+ `ToolDescriptor` objects.
727
+
728
+ Discovery snapshots are evidence only: they are not tool catalogs, do not
729
+ implement `ToolCatalogSnapshot`, and are rejected before semantic compilation
730
+ can resolve model-visible tools. Admitted connector descriptors continue through
731
+ the generic `ToolRegistry`, `FrozenToolRegistrySnapshot`, and compiler catalog
732
+ path rather than a connector-specific runtime catalog.
733
+
734
+ Connector input and output schemas are normalized through the accepted
735
+ compiler-owned JSON Schema subset. Unsupported bound keywords such as
736
+ `maxLength`, `maxItems`, `minimum`, and `maximum` are rejected at admission
737
+ with explicit schema-error diagnostics because runtime does not enforce those
738
+ bounds.
739
+
740
+ 05A remains offline and descriptor-only. It does not implement real MCP stdio
741
+ or HTTP transport, connector process launching, sockets, live connector
742
+ discovery, live connector invocation, credential use, a runtime connector
743
+ broker, production connector presets, Millrace runner integration, or
744
+ Millrace approval token handling.
745
+
746
+ ## Millforge 05B Connector Runtime Admission Snapshot
747
+
748
+ 05B adds the runtime-owned `ConnectorAdmissionSnapshot` and
749
+ `ConnectorAdmissionBinding` contracts, plus the connector-scoped
750
+ `ConnectorBroker`, `ConnectorInvocationRequest`, and `ConnectorBrokerOutcome`
751
+ runtime boundary. The snapshot deep-freezes accepted 05A
752
+ `ConnectorAdmissionRecord` evidence into exact bindings keyed by `tool_id`,
753
+ `tool_version`, and `descriptor_sha256`, exposes a deterministic
754
+ `snapshot_sha256`, and preserves `connector_id`, `provider_tool_name`,
755
+ `connector_identity_sha256`, `discovery_snapshot_sha256`, `raw_tool_sha256`,
756
+ `input_schema_sha256`, `output_schema_sha256`, `provider_description_sha256`,
757
+ `required_capabilities`, `side_effect_class`, `idempotency`,
758
+ `timeout_policy`, `output_policy`, optional `idempotency_key_policy`,
759
+ `approval_policy`, and `admission_record_sha256`. `CompiledToolBindingExecutor`
760
+ and `create_tool_executor(...)` require that the snapshot and broker be
761
+ provided for compiled connector descriptors while built-in-only plans continue
762
+ to construct and execute unchanged.
763
+
764
+ Before broker entry, the executor revalidates broker-exposed provider evidence
765
+ against the admitted connector identity, discovery snapshot, raw tool, and
766
+ schema or description hashes when those fields are available. It also
767
+ compares preserved admission `required_capabilities` against the compiled
768
+ connector descriptor before broker entry; capability drift fails closed with a
769
+ `binding_mismatch` denial that stays distinct from ordinary runtime
770
+ capability-grant failures.
771
+
772
+ Broker requests are keyed by `connector_id` and `provider_tool_name`, carry
773
+ validated JSON object arguments plus `tool_id`, `tool_version`,
774
+ `descriptor_sha256`, and runtime provenance, and stay narrow enough for the
775
+ offline `DeterministicFakeConnectorBroker` to keep connector boundary tests
776
+ deterministic.
777
+
778
+ Snapshot construction fails closed for missing, duplicate, stale,
779
+ descriptor-inconsistent, or non-connector admission records, and later source
780
+ mutation cannot change the frozen runtime bindings.
781
+
782
+ ## Millforge 05C Custom-Tool Mini-Compiler
783
+
784
+ 05C adds the public `millforge.custom_tools` package for deterministic offline
785
+ custom-tool contracts and diagnostics. It exposes frozen source manifest,
786
+ declaration, compiler policy, compilation record, compilation result, and
787
+ diagnostic contracts, plus `compile_custom_tools(...)`, deterministic hash
788
+ helpers, and validation helpers for raw contract inputs.
789
+
790
+ Accepted `runtime_kind=contract_only` declarations lower into immutable hashed
791
+ `ToolDescriptor` data and one immutable `CustomToolCompilationRecord` per
792
+ descriptor while remaining compatible with the existing `ToolRegistry`,
793
+ `FrozenToolRegistrySnapshot`, and compiler catalog path. Accepted results
794
+ normalize descriptor and record ordering by package, tool, version,
795
+ model-facing identity, implementation, descriptor hash, and record hash, while
796
+ rejected diagnostics are sorted canonically with evidence-aware tie-breakers.
797
+ The contracts keep explicit UTC provenance, closed approval/runtime enums, and
798
+ redacted bounded diagnostics for malformed source.
799
+
800
+ 05C stays compile-only. It does not register executable custom-tool runtime
801
+ implementations, expose a custom tool registry or catalog, launch tools, broker
802
+ connectors, run sandboxed code, integrate with a runner, or claim executable
803
+ runtime support.
804
+
805
+ ## Millforge 05D Mixed Connector And Custom-Tool Closure
806
+
807
+ 05D adds deterministic offline closure evidence that combines built-in,
808
+ admitted connector, and compiled contract-only custom-tool descriptors through
809
+ the existing `ToolRegistry`, `FrozenToolRegistrySnapshot`, compiler catalog,
810
+ semantic validation, lowering, and compiler service path. The machine-readable
811
+ conformance matrix at `tests/fixtures/spec05_conformance_matrix.json` and the
812
+ focused smoke in `tests/test_connector_custom_tool_closure.py` back the mixed
813
+ registry, mixed catalog, harness selection, and illegal tool-denial rows.
814
+
815
+ The closure fixtures cover connector discovery, admission manifest, admission
816
+ policy, custom-tool source manifest, expected hashes, and a mixed harness
817
+ fixture under `tests/fixtures/spec05_mixed_harness/`. 05D remains offline and
818
+ does not add live connector transport, marketplace installation, automatic
819
+ discovery or admission, custom runtime execution, runner integration, eval
820
+ workflows, or live model/backend validation.
821
+
822
+ ### Opt-In Live Model Backend Smoke
823
+
824
+ Normal test runs are offline, deterministic, and do not require provider
825
+ credentials. The live OpenAI-compatible backend smoke is marked
826
+ `live_model_backend` and is skipped unless explicitly enabled:
827
+
828
+ ```bash
829
+ MILLFORGE_LIVE_MODEL_BACKEND_SMOKE=1 \
830
+ MILLFORGE_LIVE_MODEL_PROFILE_ID=<profile-id> \
831
+ MILLFORGE_LIVE_MODEL_PROVIDER_ID=<provider-id> \
832
+ MILLFORGE_LIVE_MODEL_ID=<model-id> \
833
+ MILLFORGE_LIVE_MODEL_BASE_URL=<openai-compatible-base-url> \
834
+ MILLFORGE_LIVE_MODEL_SECRET_ID=<secret-ref-id> \
835
+ MILLFORGE_LIVE_MODEL_SECRET_ENV_VAR=<credential-env-var-name> \
836
+ <credential-env-var-name>=<credential> \
837
+ python -m pytest -m live_model_backend tests/test_model_backend.py
838
+ ```
839
+
840
+ Optional variables: `MILLFORGE_LIVE_MODEL_AUTH_SCHEME` (`bearer` or `header`),
841
+ `MILLFORGE_LIVE_MODEL_AUTH_HEADER` for custom header authentication,
842
+ `MILLFORGE_LIVE_MODEL_TIMEOUT_SECONDS`, and
843
+ `MILLFORGE_LIVE_MODEL_MAX_OUTPUT_TOKENS`. The smoke records only sanitized
844
+ provider, model, latency, finish reason, and usage metadata.