degrade: The Degradation Engine (capability-driven lowering, annotate + report)#
lower_with_enclaves immutably rewrites every non-native node through the declarative
REGISTRY until the target writer sees only native semantic nodes. Exact target rules override
target-neutral fallbacks; instance preflights refine nominally-native capability entries; every
approximation, replacement, drop, and verified enclosure produces a path/span-addressed
ConversionReport entry. A ConversionArtifact binds each enclosed report row to one exact
source-occurrence carrier and a writer-recovered final typed marker link; legacy lower raises
rather than discard a real carrier. Provenance comments are target-native and remain beside the
affected flow construct when structurally legal.
Extensions receive the same process-wide REGISTRY: use REGISTRY.register,
REGISTRY.register_preflight, and REGISTRY.register_comment to extend policy without changing
the traversal mechanism.
The Degradation Engine (capability-driven lowering, annotate + report).
lower_with_enclaves immutably rewrites every non-native node through the declarative
REGISTRY until the target writer sees only native semantic nodes. Exact target rules override
target-neutral fallbacks; instance preflights refine nominally-native capability entries; every
approximation, replacement, drop, and verified enclosure produces a path/span-addressed
ConversionReport entry. A ConversionArtifact binds each enclosed report row to one exact
source-occurrence carrier and a writer-recovered final typed marker link; legacy lower raises
rather than discard a real carrier. Provenance comments are target-native and remain beside the
affected flow construct when structurally legal.
Extensions receive the same process-wide REGISTRY: use REGISTRY.register,
REGISTRY.register_preflight, and REGISTRY.register_comment to extend policy without changing
the traversal mechanism.
- class myform.degrade.Action(*values)#
The externally meaningful result of a non-native capability decision.
- classmethod from_capability(capability: Capability) Action#
Map a non-native writer capability to its report action.
- exception myform.degrade.ArtifactRequiredError(enclaves: tuple[EnclaveRecord, ...], *, operation: str)#
A legacy return shape would discard one or more enclave carriers.
- class myform.degrade.ConversionArtifact(*, text: str, report: ConversionReport, enclaves: tuple[EnclaveRecord, ...] = (), marker_links: tuple[Link, ...] = (), marker_text_hash: str | None = None, marker_format: str | None = None, marker_options: dict[str, JsonValue] | None = None)#
Target text, its complete report, and every addressed enclave carrier.
- classmethod from_parts(*, text: str, report: ConversionReport, enclaves: tuple[EnclaveRecord, ...] = (), marker_links: tuple[Link, ...] = (), marker_options: Mapping[str, JsonValue] | None = None) Self#
Recover target-native marker evidence from the exact rendered target text.
Caller-supplied links are accepted only when they exactly match the target writer’s recovery result; they cannot stand in for parsing the final target syntax.
- class myform.degrade.ConversionReport(*, target: str, entries: tuple[ReportEntry, ...] = ())#
The complete ordered record of a single lowering pass.
- property lossy: bool#
Whether at least one node was replaced or dropped rather than approximated.
ENCLOSEDis deliberately not lossy, and the exclusion is the point of the capability rather than an oversight: an enclave relocates its node’s content into a carrier that ships with the output instead of degrading it, so nothing was lost. A conversion whose only non-native acts were enclosures is complete, not lossy – which is precisely what makesENCLAVEworth reaching for overCARRYorDROP.
- summary() str#
Render one deterministic CLI-ready summary line.
- class myform.degrade.EnclaveRecord(*, id: str, content_hash: str, source_format: str, source_path: tuple[int, ...] = (), node_kind: str, carrier_path: str, payload: AnyNode, source_text: str | None = None)#
One deterministic, reversible carrier for a source node.
idaddresses the canonical carrier envelope, whilecontent_hashretains the node’s position-independent semantic identity. The JSON carrier path is always relative and derived from the full SHA-256 id.- classmethod from_node(node: Node, *, source_format: str, source_path: tuple[int, ...] = ()) Self#
Build a carrier from one typed source node.
- Parameters:
node – Original typed node before lowering.
source_format – Registered format that produced
node.source_path – Structural occurrence path in the source document.
- Returns:
A validated carrier with a canonical full-SHA address.
- Raises:
ValueError – If
source_formatis empty ornodeis not a concrete typed node.
- exception myform.degrade.DegradationError#
Base class for structured degradation failures.
- class myform.degrade.LoweringContext(target: str, source: str, path: Path, capability: Capability, config: DegradeConfig, options: Mapping[str, object], document: Doc, _enclave_subject: Node | None = None, _enclave_source: Node | None = None)#
Read-only context handed to a lowering transform.
- enclave(node: Node) EnclaveRecord#
Build the canonical carrier from the engine-owned pre-transform source snapshot.
- exception myform.degrade.LoweringCycleError(target: str, node_kind: str, path: tuple[int, ...])#
A lowering rule recreated a node already active in its replacement lineage.
- exception myform.degrade.LoweringDepthError(target: str, node_kind: str, path: tuple[int, ...], depth: int)#
A lowering lineage exceeded the configured replacement-depth guard.
- class myform.degrade.LoweringRegistry#
Mutable extension registry consulted read-only during each lowering pass.
- property rules: Mapping[tuple[str, str], LoweringRule]#
A read-only live view of the registered lowering table.
- property comments: Mapping[str, CommentFactory]#
A read-only live view of target-specific provenance comment factories.
- property preflights: Mapping[tuple[str, str], PreflightRule]#
A read-only live view of content-sensitive native checks.
- register(target: str, node_kind: str, *, name: str | None = None, note: str = '', purpose: PurposeTag | None = None, fallback: str = '', improve: Improve | None = None, replace: bool = False) Callable[[Transform], Transform]#
Decorate and register a transform under
(target, node_kind).- Parameters:
target – Target format name, or
'*'for a target-neutral fallback.node_kind – The model node
typediscriminator.name – Stable report rule name. Defaults to the function name.
note – Static report note, joined with any dynamic
RuleResult.note.purpose – Assist purpose tag;
Nonemeans the assist is never called.fallback – Human-readable deterministic-fallback description for assist requests.
improve – Optional interpreter for an
AssistResult; the generic text interpreter is used when absent.replace – Permit deliberate replacement of an existing key.
- Returns:
A decorator that returns the transform unchanged.
- register_preflight(target: str, node_kind: str, *, name: str | None = None, replace: bool = False) Callable[[Preflight], Preflight]#
Decorate a content-sensitive refinement for a nominally native node kind.
A check returns
None/NATIVEwhen the instance is writable and a non-native capability when it needs ordinary registered lowering. Checks refine onlyNATIVEtable entries; an explicit table policy is never upgraded or bypassed.
- register_comment(target: str, *, replace: bool = False) Callable[[CommentFactory], CommentFactory]#
Decorate a target-specific provenance-comment node factory.
- resolve(target: str, node_kind: str) LoweringRule | None#
Resolve an exact target rule, falling back to the target-neutral table.
- preflight_for(target: str, node_kind: str) PreflightRule | None#
Resolve an exact content-sensitive check, then a target-neutral one.
- comment_for(target: str, entry: ReportEntry, context: LoweringContext) Node | None#
Build a target-native provenance comment, when that target registered one.
- class myform.degrade.LoweringRule(target: str, node_kind: str, transform: Transform, name: str, note: str = '', purpose: PurposeTag | None = None, fallback: str = '', improve: Improve | None = None)#
One registered lowering transform and its assist/report metadata.
- exception myform.degrade.MissingLoweringRuleError(target: str, node_kind: str, capability: Capability)#
A capability table requested lowering but no target/neutral rule exists.
- class myform.degrade.PreflightRule(target: str, node_kind: str, check: Preflight, name: str)#
One content-sensitive refinement of a nominally native kind.
- class myform.degrade.ReportEntry(*, span: Span | None = None, path: tuple[int, ...] = (), node_kind: str, action: Action, rule: str, note: str = '', carrier_id: str | None = None, carrier_path: str | None = None)#
One reported non-native act at a source-tree address.
- class myform.degrade.RuleResult(nodes: Replacement, note: str = '', terminal: bool = False, enclave: EnclaveRecord | None = None)#
A normalized-friendly rule result with optional out-of-band carrier.
- exception myform.degrade.StrictDegradationError(entry: ReportEntry)#
Strict mode encountered a replacement or drop.
- myform.degrade.lower(doc: ~myform.model.nodes.Doc, capabilities: ~collections.abc.Mapping[str, ~myform.writers.base.Capability], config: ~myform.config.options.DegradeConfig | ~collections.abc.Mapping[str, ~typing.Any] | None = None, assist: ~myform.assist.base.Assist | None = None, *, target: str, default_capability: ~myform.writers.base.Capability = Capability.NATIVE, options: ~collections.abc.Mapping[str, ~typing.Any] | None = None, registry: ~myform.degrade.registry.LoweringRegistry = <myform.degrade.registry.LoweringRegistry object>, max_depth: int = 64) tuple[Doc, ConversionReport]#
Lower a document only when the legacy return shape would discard no carriers.
Use
lower_with_enclaveswhen a capability table may requestCapability.ENCLAVE. Marker-only rules remain compatible here because they produce no carrier and are reported as ordinary, lossy replacements.- Raises:
ArtifactRequiredError – A lowering returned a real carrier; call
lower_with_enclaves.
- myform.degrade.lower_with_enclaves(doc: ~myform.model.nodes.Doc, capabilities: ~collections.abc.Mapping[str, ~myform.writers.base.Capability], config: ~myform.config.options.DegradeConfig | ~collections.abc.Mapping[str, ~typing.Any] | None = None, assist: ~myform.assist.base.Assist | None = None, *, target: str, default_capability: ~myform.writers.base.Capability = Capability.NATIVE, options: ~collections.abc.Mapping[str, ~typing.Any] | None = None, registry: ~myform.degrade.registry.LoweringRegistry = <myform.degrade.registry.LoweringRegistry object>, max_depth: int = 64) tuple[Doc, ConversionReport, tuple[EnclaveRecord, ...]]#
Lower
docuntil every remaining semantic node is native totarget.The original document is never mutated. A wholly native document is returned by identity; a changed document is revalidated from owned data before return. The supplied assist object is captured once for the whole call and invoked only by rules explicitly carrying a purpose tag, after their deterministic fallback has already succeeded.
- Parameters:
doc – The source typed document.
capabilities – Writer node-kind capability table.
config –
DegradeConfig, a raw degrade-section mapping, or defaults.assist – One optional assist instance for the whole pass.
target – Target writer format name (the first registry-key component).
default_capability – Capability for kinds absent from
capabilities.options – Full conversion/target options exposed immutably to lowering rules. This is separate from the compatible
config=DegradeConfigpolicy path.registry – Lowering registry, overridable for isolated extensions/tests.
max_depth – Maximum non-native replacement-chain depth.
- Returns:
The writer-native document, its complete non-native-action report, and every addressed enclave carrier in stable encounter order.
- Raises:
MissingLoweringRuleError – A non-native kind has no exact or neutral rule.
StrictDegradationError – Strict mode encounters
CARRY,DROP, orENCLAVE.LoweringCycleError – A rule recreates an active node unchanged.
LoweringDepthError – A replacement chain exceeds
max_depth.ValueError – A rule returns something other than zero/one/many nodes.