Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions docs/artifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ invalidation handles failed in-place restores.
`CachedDataset[T]` is a concrete resumable Artifact and ordinary re-iterable
`Dataset[T]`. Its constructor retains one `Ref[AutoRef]` source without loading,
traversing, or implicitly saving it. Before successful computation, `ready` is
false and spec, length, and iteration raise `ArtifactNotReadyError`. Completed
false and spec, length, and iteration raise `ArtifactNotReadyError`. Supply a
soft source `Definition` as `Ref(definition)`; a bare Definition is rejected
rather than assigned implicit reference intent. Completed
state publishes the codec's actual NumPy-backed output spec with exact container
kinds, mapping keys/order, tensor values, shapes, yield boundaries, and supported
dtypes. Ragged, sparse, Python-object, and nullable-object leaves are rejected.
Expand Down Expand Up @@ -168,12 +170,12 @@ likewise accept non-materializing Dataset/model references and require explicit
prediction and target label Methods. They never decode logits, probabilities,
or one-hot values implicitly. A caller can use `ArgMax` or another declared
Method in the supplied conversion graph when that conversion is intended.
All five supplied metric helpers return an inert `Template` when any supported
argument contains `Template` or `Par`; concrete-only calls continue to return an
uncomputed Fold. Invalid known literal controls fail while authoring the symbolic
call, while checks that depend on unresolved values run when the bound factory is
built. Symbolic lifting itself constructs no helper Method and performs no input
work.
All five supplied metric helpers return an inert class-rooted `Definition` when
any supported argument contains a symbolic Definition value or `Par`; concrete-only
calls continue to return an uncomputed Fold. Invalid known literal controls fail
while authoring the symbolic call, while checks that depend on unresolved values
run when the bound Definition is concretized. Symbolic lifting itself constructs
no helper Method and performs no input work.
Incoming `StateRef` inputs remain exact nested references in that declared graph:
a later model save does not replace the selected snapshot. Factory construction
never saves an unpersisted source or model. A completed metric Fold can restore
Expand Down
6 changes: 5 additions & 1 deletion docs/dispatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ Reports contain only bounded diagnostic categories, redacted backend identifiers
coverage and requirement results. They never retain call data, handles,
credentials, source, selectors, Stores, or reservations. Incomplete static
coverage remains in `explain` diagnostics even when a normal unresolved call
does not warn. `explain` never emits `DispatchCoverageWarning`.
does not warn. When `run` or `submit` emits `DispatchCoverageWarning`, its
message includes bounded diagnostic categories and directs callers to
`dispatch.explain(...)` for the full report; `explain` itself does not warn.
Incomplete coverage means undiscovered calls may hide worker requirements,
not that the workload failed or that no declarations were found.

## Probing And Static Coverage

Expand Down
17 changes: 12 additions & 5 deletions docs/execute.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ The core adapter supports ordinary functions, lambdas, nested functions and
closures, bound methods, callable instances, `@function` callables, `Method`, and
managed-operation callables. It sends one whole callable/argument/capture graph,
including globals, defaults, annotations, instance fields, and `__slots__`.
Symbolic `Definition` values have an explicit graph node and retain their class,
positional-versus-skipped argument shape, keyword data, aliases, and frozen
container spelling. They do not fall through the Definition's public `Mapping`
view. A Mat boundary can therefore materialize a transported Definition in the
worker, while an explicit `Ref[Definition]` remains symbolic data.
Without an explicit signature role, built-in containers are traversed and known
DRYML semantic leaves use their authority-aware representation. Other trusted
Python leaves use bounded dill serialization with ordinary pickle state behavior;
Expand Down Expand Up @@ -329,11 +334,13 @@ earlier restores nor replays the workload.
`decode_core_outcome()` exposes `CoreAdaptationOutcome` and
`CoreOutcomeEvidence` value types. Evidence has exact StateRefs and
Store-table-relative publication status only; it never carries a live Repo,
Store, `StoreReport`, argument, or result. A delivered worker failure preserves
known publication evidence but does not imply rollback, retry, or successful
caller refresh. Coordinator recovery reports this bounded category as
`core execution worker failed: <reason>` without including submitted values or
remote exception payloads.
Store, `StoreReport`, argument, or result. A delivered core-worker failure raises
`CoreExecutionError` with `core execution worker failed: <reason>`, preserves
only its bounded failure category and known publication evidence, and does not
imply rollback, retry, or successful caller refresh. Because the core adapter
returns an opaque outcome through generic Execute before coordinator recovery,
this is not a generic `RemoteExecutionError`; submitted values, traceback text,
and exception values are not transported.

`PreparedCoreCall` contains only invocation bytes, frozen storage setup, and
opaque update descriptors. It never retains caller Objects or refresh progress.
Expand Down
64 changes: 35 additions & 29 deletions docs/formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,24 +86,31 @@ Fixture authority is checked out byte-for-byte via `.gitattributes`, without
line-ending conversion. Git for Windows needs long-path support to check out the
snapshot directory fixtures; CI enables `core.longpaths` for its Git processes.

## Template V1

`Template.to_data()` uses the closed `{"schema": "dryml-template", "version":
1, ...}` graph format. It retains typed scalar values, symbolic targets, graph
aliases, expression/repetition nodes, factories, exact references, and `Ref`
recipe boundaries without importing a target, constructing an Object, or calling
a factory. The format rejects cycles, unknown tags/versions, dangling or
duplicate labels, non-finite values, live handles, custom providers, and payloads
over 16 MiB. `TemplateSelector` uses the same format for its captured template
and built-in integer-range or finite-choice domains; runtime providers and
`TemplateGenerator` have no persistence format.

Only a constructor slot explicitly annotated `Ref[Template]` may carry an
unresolved Template into a CDef. The carried recipe is terminal CDef data and is
opaque to materialization, Store authority traversal, and ordinary template
rewrites unless a template operation explicitly opts into Ref traversal. Existing
Store-v3 authority is unchanged; query sidecar version changes invalidate derived
indexes only and never rewrite definitions or Store records.
## Symbolic Definition And Generator Selector V1

Quoted symbolic Definition data uses the closed
`{"schema": "dryml-definition-expression", "version": 1, ...}` graph format.
It preserves typed scalar values, symbolic targets, graph aliases, parameter,
arithmetic, and repetition nodes, factories, exact references, and `QuotedDef`
quotation without importing a target, constructing an Object, or calling a
factory. The format rejects cycles, unknown tags/versions, dangling or duplicate
labels, non-finite values, live handles, custom providers, and payloads over 16
MiB.

`GeneratorSelector` retains the established closed
`{"schema": "dryml-template", "version": 1, "kind": "template-selector", ...}`
payload tag and canonical bytes for compatible built-in integer-range and
finite-choice distributions. It decodes directly into Definition-based state.
Runtime providers and `Generator` instances are nonportable. The retained
`dryml-template` name is a format-compatibility tag only; it does not restore a
runtime Template value.

Fresh `Ref[Definition]` and Template-role constructor values persist as a Ref
link to `QuotedDef`. The quoted payload is terminal local data, opaque to
materialization and ordinary symbolic traversal unless an operation explicitly
opts into Ref traversal. Existing Store-v3 authority is unchanged; query sidecar
version changes invalidate derived indexes only and never rewrite definitions or
Store records.

## Workflow Records

Expand All @@ -114,19 +121,18 @@ status cells without opening an Experiment, checkpoint, Dataset, or Artifact
payload. Pandas is only a lazy inspection dependency; it is not part of this
format or a reader requirement.

`TemplateBundle` is a `dryml-template` v1 graph with kind `template-bundle`.
It preserves inert quoted recipes and must not resolve or construct their target
objects while decoding. Completed `Value` Artifacts retain their result through
the `dryml.artifacts.value` v1 envelope. A `TrainState` is ordinary Object state,
not a separate file format: its named state and supported historical three-slot
state are validated by its state hooks before restored progress is installed.
Completed `Value` Artifacts retain their result through the
`dryml.artifacts.value` v1 envelope. A `TrainState` is ordinary Object state, not
a separate file format: its named state and supported historical three-slot state
are validated by its state hooks before restored progress is installed. Experiment
artifact mappings persist individual Template-role Definitions as quotation data
in canonical key order; there is no aggregate recipe-container format.

The small `tests/fixtures/qualification_reader_v1/` fixtures are reproducible reader inputs
generated by `generate.py`. Use `PYTHONPATH=src python
tests/fixtures/qualification_reader_v1/generate.py --output <empty-directory>` to make a
clean candidate; omitting `--output` deliberately regenerates the source
directory. The ExperimentData and Value fixtures exercise their actual readers;
TemplateBundle is generated through and exercises its actual template codec.
directory. The ExperimentData and Value fixtures exercise their actual readers.
`TrainState` is a code-free named `__setstate__` compatibility vector, not a
portable pickle codec claim. The manifest schema pins every payload filename and
SHA-256 before reader tests decode it. The fixtures contain no backend objects,
Expand All @@ -144,9 +150,9 @@ contains its temporary extraction directory.

The selector grammar is closed and preserves Definition/CDef sharing, omitted
positional arguments, links, selector-as-data wrappers, supported `Match` tags,
symbol representation, and exact ObjectRef/StateRef leaves. Template expression
and generator-domain payloads use the separate Template V1 codec above; retired
SearchSpace generator tags are not accepted.
symbol representation, and exact ObjectRef/StateRef leaves. Symbolic Definition
quotation and generator-selector domain payloads use the separate bounded codecs
above; retired SearchSpace generator tags are not accepted.
It does not permit arbitrary Python objects or live Store handles. The codec
rejects duplicate mapping keys, unknown fields/tags, invalid selector/reference
depth 32, 65,536 nodes, 4,096 entries per container, 1 MiB strings, 4,096-bit
Expand Down
33 changes: 18 additions & 15 deletions docs/graph_querying.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,18 @@ scan unless `analyze=True`. The legacy eligible materialize-only CDef paths keep
their indexed behavior. Store indexes remain candidate-only derived state, never
authority for root membership or a no-match conclusion.

## Template Selectors

`Template.as_selector()` creates a loose ordinary Selector that preserves known
concrete structure but intentionally drops unknown parameter, arithmetic, and
topology relationships. Use `TemplateGenerator.support_selector()` when a query
must verify captured domain support, linked names, derived values, ordering, and
shared-node topology exactly. Template support verification is residual to index
prefiltering and never constructs candidate Objects or factory targets. A provider
without exact verification raises an explicit unsupported-verification error; a
numeric bound alone is never accepted as a match.
## Symbolic Definition Selectors

`Definition.as_selector()` retains its ordinary selector behavior. Use
`Definition.loose_selector()` to project known symbolic structure into a loose
ordinary Selector; it intentionally drops unknown parameter, arithmetic, and
topology relationships. Use `Generator.support_selector()` when a query must
verify captured distribution support, linked names, derived values, ordering, and
shared-node topology exactly. Exact Generator support verification is residual to
index prefiltering and never constructs candidate Objects or factory targets. A
provider without an exact proof raises
`UnsupportedGeneratorVerificationError`; a numeric bound alone is never accepted
as a match.

Exact support remains residual because graph-distinct authoritative witnesses
cannot be collapsed into structural index rows. Stored queries use the loose
Expand All @@ -103,12 +105,13 @@ roots before residual verification. The default terminal limit is 65,536
authoritative visits; prefilter rejections and duplicate source visits consume
the budget before suppression. Lower it with `max_witnesses(n)` or explicitly
disable it with `max_witnesses(None)`. Finite-support assignment work is also
bounded cumulatively for the terminal and can raise `TemplateLimitError` before
any partial result is returned.
bounded cumulatively for the terminal and can raise `ParameterizationLimitError`.

`require_indexed()` and `scan_policy("forbid")` reject exact support because the
residual always needs complete witness verification. Exact selectors use exact
symbolic class matching and cannot be converted with `references()` or `where()`,
`require_indexed()` and `scan_policy("forbid")` reject exact support when a
residual is needed. Materialize-only traversal with `contains_ref=True` is
deterministically empty and requires no scan, even for a GeneratorSelector.
Exact selectors use exact symbolic class matching and cannot be converted with
`references()` or `where()`,
or rewritten with `categorical()`, `restore()`, or `exact()`. Refining a fixed
result with another exact selector is supported only when the result retained
complete immutable witness evidence; otherwise it raises `QueryDomainError`.
Expand Down
13 changes: 7 additions & 6 deletions docs/immutable_definition_graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ the retained reference under its managed Repo.
The signature boundary determines newly authored Ref/Mat edges; see
[Signatures](signatures.md) for supported annotations and delivery behavior.

Template repetition distinguishes construction topology from configuration.
Repeated groups receive fresh CDef nodes by default while same-named template
parameters retain one value; `Shared(...)` preserves node identity at matching
positions. This does not make FactorySpec consumers share TensorFlow/Torch backend
instances or weights. A declared `Ref[Template]` is terminal recipe data in this
graph and can remain unresolved without becoming a materializing edge.
Symbolic Definition repetition distinguishes construction topology from
configuration. Repeated groups receive fresh CDef nodes by default while
same-named active parameters retain one value; `Shared(...)` preserves node
identity at matching positions. This does not make FactorySpec consumers share
TensorFlow/Torch backend instances or weights. A Definition admitted through a
Template role is terminal `QuotedDef` recipe data in this graph and can remain
symbolic without becoming a materializing edge.
12 changes: 7 additions & 5 deletions docs/managed_operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,19 @@ callback boundary.
callback boundary: it explicitly stages and checkpoints its terminal training
state inside its own managed body. Its private observer runs first after that
checkpoint is published and associated, writes the pending ExperimentData row,
then evaluates checkpoint-bound Artifacts in declaration order and records their
then evaluates checkpoint-bound Artifacts in canonical artifact-key order and records their
terminal row status. Only then do caller callbacks run in their original order,
followed by the normal interruption decision. This is Experiment policy, not a
generic managed final-hook protocol. A callback failure retains the associated
checkpoint and any independently published Artifact/history state; it never
reports overall managed completion.

Experiment validates its configured Artifact quotations before it changes training
phase or invokes the trainer. This is Experiment-owned inert definition checking,
not a managed lifecycle hook: it may inspect recipe roots and managed declarations
but does not construct Artifacts, materialize training inputs, or publish state.
Experiment accepts only its direct `Mapping[str, Template] | None` artifact
mapping. It validates the configured Template-role Definition quotations before it
changes training phase or invokes the trainer. This is Experiment-owned inert
definition checking, not a managed lifecycle hook: it may inspect recipe roots and
managed declarations but does not construct Artifacts, materialize training
inputs, or publish state.

Status, interruption, resume, and recovery locate retained StateRefs across the
caller-supplied state Repo rather than re-evaluating current routing. One complete,
Expand Down
6 changes: 3 additions & 3 deletions docs/ml_workflow_qualification_verification.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ validates exact Method and Models public manifests, confirms the retired
./tests.sh tests/package/test_public_imports.py \
tests/package/test_release_artifacts.py \
tests/models/test_qualification_persistence_fixtures.py \
tests/models/test_qualification_contract.py \
tests/artifacts/test_value.py tests/core/test_template_bundle.py \
tests/models/test_qualification_contract.py \
tests/artifacts/test_value.py tests/core/test_generator_persistence.py \
tests/test_timing_plugin.py tests/docs/test_cdef_v2_documentation.py --no-cov -x
```

Expand All @@ -266,7 +266,7 @@ qualification or evidence that 4.9.9 executed.
The focused persistence tests validate the closed manifest schema and SHA-256 of
every fixture payload before reading it, then read a nonempty ExperimentData v1
row through its actual reader and canonical re-encoder, a real `Value`
`value.pkl` receipt, the actual TemplateBundle codec, and a code-free named
`value.pkl` receipt, portable GeneratorSelector data, and a code-free named
`TrainState.__setstate__` compatibility vector. The committed Value pickle has a
static no-executable-opcode check before unpickling. A clean explicit generator
destination reproduces every committed fixture byte with no missing or extra
Expand Down
25 changes: 17 additions & 8 deletions docs/objects_and_defs.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,23 @@ an unchanged factory declaration. `FactorySpec.build(namespace=...)` resolves an
invokes the target at that explicit consumer boundary; resolution can import
trusted target code.

## Templates

`Definition.as_template()` explicitly converts a soft definition into an inert
`Template`; direct authoring uses `Template(Target, ...)`. Templates substitute
only static values and defer generation to `TemplateGenerator`, whose completed
sample/grid results are ordinary Definitions. This does not construct the target
or factory. See [Definition Templates](templates.md) for namespaces, repetition,
exact support selectors, and the intentional SearchSpace migration.
## Symbolic Definitions

`Definition` is also the sole runtime value for symbolic construction. It may
contain `Par` roots and supported arithmetic or repetition expressions while
remaining immutable. `names` reports active roots in authored first-occurrence
order and `is_resolved` means only that no active expression remains. Neither
operation resolves a target, interprets a receiving constructor role, applies
defaults, or proves a constructor call is complete or valid.

Use `Definition.sub(...)` for static binding and `Definition.remap(...)` for
simultaneous root renaming; both return new Definitions and do not construct,
save, import, or sample. `Distribution` is not construction data and is rejected
anywhere in Definition-owned structure. To vary every remaining active root, pass
the partially bound Definition and one exact root-to-Distribution mapping to a
`Generator`. Its samples and grid members are resolved Definitions. See
[Symbolic Definitions And Generation](templates.md) for expression traversal,
role admission, and exact support selection.

## Categorical Selectors

Expand Down
Loading
Loading