Recogniser capability contract¶
Draftwright consumes the public capability manifest installed with quiddity; it never
reads a sibling checkout or a package-private file. The matching Draftwright-owned declaration is
implemented in draftwright.recogniser_contract and validated in CI.
The package manifest describes geometry evidence. Draftwright separately declares, for every
package family, its IR adapter, fluent Sheet surface, generated-Sheet behavior, drawing consumer,
completeness treatment, and documentation. A stage is either supported, deferred,
not-applicable, or unsupported, with the evidence required by that state. This separation lets
other CAD consumers apply different policy without making Draftwright policy part of the geometry
library.
Declared-feature geometry reads use a different public boundary. The installed package's
inspection manifest format 1 is joined to the separate Draftwright-owned declaration in
draftwright.inspection_contract. That contract admits inspection API major 1 and exactly the
consumed quiddity.inspection symbol schemas: the five geometry readers, their public
result/error types, the cylindrical surface parameter layout, bevel rejection reasons, and the
semantic names and units of the Double-D tuple. It also checks the exact installed package
version. Recognition-family policy does not leak into this smaller measurement contract, and an
additive inspection symbol does not pretend to be a new recogniser family.
What failures mean¶
Validation fails closed and names the family and boundary whenever possible:
- family inventory mismatch (
stale=) — Draftwright declares a family the installed package no longer ships, so a declared adapter would call a recogniser that is gone. Remove or repoint the declaration.
The opposite direction does not fail this validation. A family the package ships and
Draftwright has not declared cannot reach any Draftwright code path, and blocking on it made the
package unreleasable until its consumer caught up. It is reported by
pending_family_declarations and fails tests/test_recogniser_adoption.py in Draftwright's own
CI instead — adoption is still required, and is enforced where the decision is made. Provide the
downstream behavior or an explicit non-supported state as before.
- record schema mismatch — a consumed record schema changed. Review the record fields and
compatibility notes, update the relevant adapter and tests, then explicitly list the accepted
schema version. A bounded dual-readable list may name the current and next additive schemas
during a provider-first release; it is never an open-ended range.
- stale implementation — a declared adapter, Sheet method, emitter, renderer, or completeness
function no longer resolves. Repair the implementation reference and its independent behavior
evidence; do not merely rename the string.
- evidence is missing — a supported claim points at a deleted test or document. Restore or
replace the behavior evidence before changing the path.
- unknown state or unsupported format — the installed contract uses semantics this Draftwright
version does not understand. Upgrade the validator before accepting the package version.
- geometry-only family invents semantics — geometry used for critique was incorrectly given an
inferred IR/DSL/code-generation/drawing path. Keep it geometry-only unless a separately reviewed
Draftwright feature introduces authored semantics and compatibility evidence.
- reserved family claims supported downstream semantics — a family-level deferred or
unsupported disposition still advertises an implemented downstream stage. Either make the
family disposition supported with behavior evidence, or defer/disable every semantic stage and
retain its tracking issue.
- state transition lacks evidence — a capability was strengthened or weakened without a named
Draftwright version, release notes, and compatibility tests. Supply all three as one reviewed
transition.
Adding or changing a recogniser¶
For an additive field that increments an existing record schema, update the relevant Draftwright
adapter and declaration when advancing the exact quiddity dependency pin. Tests must
prove the installed schema is accepted while later schemas still fail. The package version belongs
only in pyproject.toml and uv.lock; the capability declaration derives runtime identities from
installed package metadata.
For each applicable stage, add the adapter, declaration, emitted-Sheet round trip, drawing behavior,
and completeness evidence; for an inapplicable or deferred stage, state why and link its tracking
issue. The contract test derives package record outputs, converter registries, live Sheet methods,
and emitter branches independently, so copying a new name into the declaration alone cannot make CI
pass.
Quiddity 0.3.0 runtime contract¶
The runtime pins the published quiddity==0.3.0 package, following the 0.2.4 adoption in
#1486 and the migration in
#1471. 0.2.7 is a patch adoption: it requires
circumferential cylinder support to establish a turned-profile axis line, so rounded plate corners
and parallel offset cylinders no longer form a false stepped shaft
(quiddity#586, #1555).
No family, record schema or adapter changed.
Quiddity 0.2.9 exposes native cylindrical seats as open-arc SectionRecess channels and
keeps coaxial bores separated across exterior air gaps. The pinned frame now retains six
Ø1.1 × 3.0 mm hinge bores and three Ø14.3 seats. The seat grammar remains explicitly
unsupported in Draftwright pending #1613.
Adapter refusals of derived hole patterns are recorded with same-run identity so their
physical members remain in the ordinary-hole requirement ledger (#1607/#1619). These changes
use the existing public schemas. Identical patterns on different opening planes retain the
provider's documented grouping limitation (quiddity#595);
separate physical bores must not be merged to recover a pattern.
0.2.7 also partitions bands by physical axis line rather than by axis direction, requiring two
distinct diameters per line. One body can therefore publish several coaxial
TurnedProfiles where 0.2.6 published at most one. Analysis.profiles already holds every
body-local profile and is unaffected; Analysis.prof remains the compatible zero/one view and
is None for a plural result, which sends holes.py's a.prof is not None branches down their
non-rotational path. No fixture in this repository reaches plural cardinality on either
version, so the green tiers are not evidence that path behaves well — it is newly reachable
and untested. Its public quiddity, quiddity.evidence and
quiddity.inspection surfaces supply recognition, exact occurrence evidence and declared geometry
reads. There is one recognition aggregate per build; consumers project that result rather than
calling the document builder to obtain another run.
The manifest has 29 families. The gusset-ribs family proves rib thickness, support legs and
body occurrence, while gusset-rib-patterns relates accepted ribs as arrays or mirror pairs.
Draftwright preserves those exact member relations in dedicated GussetRibFeature IR, exposes
the same facts through Sheet.gusset_rib(...) and generated scripts, and places one correlated
solver-owned callout carrying thickness, both legs and the proven pitch or mirror spacing. The
completeness ledger follows each physical member and the group relation independently (#1705).
One section-recesses family replaces the former pockets, pocket
patterns, channels, rectangular and round-bottom blind slots, passages and prismatic pockets.
RecognitionResult.section_recesses contains the immutable occurrences;
section_recess_patterns relates them by run-local occurrence indices; section_recess_refusals
retains the provider's explicit reasons for refusing candidate geometry. The public document
builder is a serialization front door, not another feature family or a production rescan.
The shared adapter reads the published frame, profile, run interval and ends and lowers supported principal-axis geometry to the existing pocket, channel and blind-slot IR. It preserves the opening direction and edge anchoring and rejects malformed records. Supported rounded rectangular pockets retain their corner radius, and supported cylindrical-mouth pockets carry maximum-depth intent rather than an invented uniform depth. Valid profiles and end shapes outside the drafting grammar remain explicit unsupported outcomes, including the two-plane passage cases. Pattern members resolve to the original records in the same aggregate before they share a drawing owner. Missing members, duplicate indices, cross-body grouping and inconsistent lattice geometry fail closed.
Independent pocket and pattern corpora, channel ownership tests and both blind-slot corpora check
measurements, public declarations, executed generated code and the placed requirement ledger.
Recognition refusals retain source provenance and contribute an unsupported outcome without a
fabricated position. Report and inspection schema v2 name producer.quiddity; their v1 schemas
remain available for existing documents.
The common-part restoration checks the five rounded tuner-jig pockets and their grouped callout, corner radii, pitch and absolute locations; pockets cut into cylindrical stock; and the pierced U-channel's supported channel measurements. Automatic recognition, declared input and executed Sheet scripts retain the supported recess facts. These checks do not turn a successfully rendered part into a completeness guarantee.
The preceding Draftwright 0.4.20 / Quiddity 0.2.2 release documented annotation losses for mixed and nested pockets (Quiddity #536), bore-intersected or edge-open recesses (#538), and pockets in cylindrical stock (#541). Those historical limitations must not be used to excuse the common cases restored in #1486. Conversely, recognising more source profiles does not imply that every profile now has a supported drafting grammar. General complex pockets and nonuniform passages can still produce explicit unsupported requirements.
Check the source occurrence outcomes, placed requirements and lint for affected geometry. Regression expectations are reassessed per fixture: a restored supported case must pass, while an unsupported case must retain its truthful diagnostic rather than an approximate old annotation. Recognition, declaration, placement, reporting and coverage checks remain release gates.
bosses remains a fully consumed reference family. repeating-radial-profiles remains geometry-only
critique evidence for a separately authored gear declaration, with no inferred gear feature.
Hole completeness evidence¶
The holes completeness boundary is supported from the versioned format-1 corpus in
tests/fixtures/evaluation/corpus-v1.json. Its expected holes, identity fields, nominal values,
tolerances and fixture hashes are independently authored. Neither RecognitionResult,
feature_census, the compiled plan nor the hole-requirement ledger supplies the denominator.
The corpus includes positive, negative, ambiguous, compound and topology-order-variant cases and
reports detection recall/false positives, parameter fidelity and downstream usefulness as separate
layers; there is deliberately no composite score.
For each observed provider hole, the evaluation follows four real artifacts: the automatic
build's PartModel, an explicit public Sheet.hole declaration, an executed
emit_sheet_script result and the placed drawing's measurement provenance. The existing
fail-closed hole-requirement correspondence supplies the join from a provider record to each IR
artifact; it never creates expected facts. A missing or ambiguous correspondence scores
unknown, a placement/ink loss scores unsupported, and only supported earns downstream
credit. Mutations that delete provider holes, corrupt a declaration, remove generated feature
lines or erase drawing measurement provenance reduce the corresponding layer.
Hole-pattern completeness evidence¶
The hole-patterns completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-hole-patterns-v1.json. The corpus covers rectangular grids,
bolt circles, linear arrays, a near-pattern negative, compound arrangements and a
reverse-serialized topology pair. It scores one arrangement occurrence per provider group rather
than treating its member holes as new physical occurrences. Member sizes, depths, bottoms and
individual locations remain exclusively in the hole corpus.
Each provider pattern must contain the exact accepted RecognitionResult.holes objects and no
member may belong to two aggregate patterns. The observer follows the existing fail-closed hole
ledger to one exact PatternFeature through the automatic IR, public Sheet.pattern declaration,
executed generated Sheet code and placed grouping/pitch/BCD evidence. Mutations that delete the
derived provider inventory, corrupt the declaration, remove generated pattern lines or remove a
placed pitch dimension reduce the corresponding independent layer.
Countersink completeness evidence¶
The countersinks completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-countersinks-v1.json. Its seven construction-authored cases own
seven physical conical seats, 28 provider-parameter checks, and 28 downstream checks. The
negative controls distinguish solid external cone transitions and shallow deburr chamfers from an
internal functional seat; the positive cases include a mixed-size ownership pair, equal seats
sharing one grouped callout, and a bijectively renumbered, reverse-serialized topology pair.
Identity is the signed mouth axis plus physical opening centre. Opening diameter, drill diameter,
included angle, and geometric depth are detection parameters, not four new drawing requirements.
The provider aggregate must reuse each accepted CounterSink object exactly once on its owning
HoleRecord.csink; Draftwright validates that chosen owner with the provider's public semantic
predicate and fails closed on mismatches, multiplicity, or canonical-site collisions. It then
follows that identity through the existing hole IR, public
Sheet.hole(..., csink=...), generated code, and the two exact compiler measurements
countersink.diameter / countersink.angle. Confirmed solver-placed, role-specific ⌵ ⌀… × …°
ink is required for drawing credit, so diameter and angle cannot confirm each other merely because
both numbers occur in the label. Bore diameter, through/depth, grouping, and location remain owned
once by the hole ledger.
The current singular hole waist cannot attribute both seats of a two-sided countersunk bore. That
limitation remains fail-visible: the attached seat is followed normally, while the other physical
seat contributes explicit unverifiable diameter and angle outcomes with no invented canonical
member key. Completeness support means every aggregate seat receives an honest outcome; it does
not claim every drawing scores 100%. Removing provider seats, deleting the IR or generated csink,
corrupting the Sheet declaration, or removing/corrupting finished ink reduces the corresponding
independent evidence.
Double-D completeness evidence¶
The double-d-bores completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-double-d-bores-v1.json. Eleven construction-authored cases
contribute ten physical through-profile occurrences, 50 provider-parameter checks and 40
downstream checks. Principal X/Y/Z axes, a 30° flat rotation, disconnected coaxial bodies,
heterogeneous compounds and a reverse-serialized topology pair are positive controls; round,
blind, opposed-blind and solid-stock cases keep the family boundary fail-closed.
Axis plus full location identifies each physical frame, so disconnected coaxial bodies cannot
collapse by dropping the through-axis coordinate. Major diameter, A/F, depth, through state and
the unoriented flat line are scored parameters. The complete provider inventory must correspond
one-to-one, with exact multiplicity, to the automatic IR, public Sheet.double_d_bore
declaration and executed generated Sheet code. Drawing credit requires compiler-confirmed
bore.diameter and profile_across_flats.length identities together on exact role-specific
⌀major THRU DOUBLE-D across A/F ink. The provider's fixed ownership excludes the same void
from ordinary holes, so this profile fact does not recount a circular bore.
Flat completeness evidence¶
The flats completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-flats-v1.json. Its seven construction-authored cases contribute
nine physical across-flats requirements, 27 parameter checks and 36 downstream checks. The scope
covers a non-round negative, a lone D-flat, axis-aligned and slanted Double-D stock, independent
parallel lobes, independent coaxial stock and a reverse-serialized topology pair.
The denominator represents physical stock requirements, not provider face records: the two
opposed faces of one Double-D stock line form one across-flats fact, while parallel lobes and
disjoint coaxial spans remain distinct facts. Identity uses the canonical axis, axis line and stock
span; across-flats size, face count and anchors are scored parameters. Each fact must survive the
automatic IR, public Sheet.flat declaration, executed generated Sheet code and placed
measurement-provenance boundary. Removing provider flats, weakening a nominal, corrupting a
declaration or generated script, or losing the placed callout/provenance reduces the corresponding
independent score.
Pocket completeness evidence¶
The lone-pocket grammar within section-recesses is independently supported from
tests/fixtures/evaluation/corpus-pockets-v1.json. Ten construction-authored cases contribute 13
physical pockets, 52 parameter checks and 52 downstream checks. The corpus covers a through-slot
negative, one off-centre pocket, an edge-anchored corner interruption, equal independent pockets,
opposite openings, a principal side opening, an unsupported polygonal-pocket ownership negative, separate
compound bodies and a reverse-serialized topology pair.
Identity uses width/long/depth axes, opening sign and physical location; width, length, depth and
edge anchoring are scored parameters. Interior pockets require three size outcomes plus two
directional datum locations. Edge-anchored pockets intentionally require only their three sizes
because the adjacent stock edges establish position. Pattern members are excluded rather than
double-counted. Each fact must survive automatic IR, public Sheet.pocket, executed generated
Sheet code and placed size/location provenance. The IR now retains provider open_sign, and the
shared location renderer records which physical X/Y ordinate landed while preserving ADR 4 (was 0016)'s
single public location authoring unit.
Pocket-pattern completeness evidence¶
The pocket-pattern grammar within section-recesses is independently supported from
tests/fixtures/evaluation/corpus-pocket-patterns-v1.json. Seven construction-authored cases
cover 30° linear and rectangular-grid positives, the two-member threshold, unequal-spacing
ambiguity, a plain negative, an axis-aligned underside compound case and a reverse-serialized
topology pair. The four expected arrangements contribute 41 parameter checks and 16 downstream
checks; hard-coding the linear direction or grid angle lowers parameter fidelity.
Each pattern is one physical grouping requirement: its member pockets are excluded from the lone
pocket denominator. Identity retains arrangement kind, axes, opening side and exact member sites;
count, member width/length/depth, edge anchoring, centre and pitch/lattice values are scored
parameters. The observer follows one exact PocketPatternFeature through automatic IR, public
Sheet.pocket_pattern, executed generated code and placed count/size/pitch/location evidence.
Compiler identities and structured X/Y location facts establish ownership, while the final
observer also checks exact compiler-approved ink, including an approved pitch tolerance only when
every physical gap supports the collapsed claim. Diagonal pocket-pattern pitch dimensions use
exact segment-versus-label clearance rather than a false-blocking whole-ink hull. Removing
provider patterns, weakening a nominal or orientation, corrupting a declaration or generated
script, or deleting/corrupting placed evidence reduces the corresponding independent layer.
Groove completeness evidence¶
The grooves completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-grooves-v1.json. Eight construction-authored cases contribute
ten physical annular recesses, twenty parameter checks and forty downstream checks. The corpus
covers a monotonic turned-step negative, all three principal axes, a narrow circlip ownership
case, equal grooves on separate bodies and a geometrically identical pair created with reversed
Boolean order.
Axis and the physical axis-line/station anchor identify each occurrence; axial width and floor
diameter are scored parameters. Each source must join exactly one GrooveFeature through
automatic IR, public Sheet.groove, executed generated Sheet code and one placed semantic
{width} WIDE × ø{diameter} callout carrying both compiler identities. Raw boss and turned-step
inventories may see a reduced band, but Draftwright suppresses that floor from their IR paths so
its diameter is drafted once. Removing provider grooves, changing width/diameter/axis/location,
corrupting declaration or generated code, or severing either measurement claim reduces the
corresponding independent layer.
Quiddity's optional Groove.profile key now identifies the exact body-local turned profile.
The compiler and independent axial/step ledgers use that key and still cross-check the published
axis line and axial band. Missing profile identity retains the geometric ambiguity refusal;
a missing profile in an authored subset cannot redirect the groove to another coaxial body.
Generated declarations replace the provider key with the same profile_group token used for the
owning steps. The keyed nested-body and omission checks live in
tests/test_groove_profile.py; they supplement the unchanged authored groove corpus.
Rectangular-pad completeness evidence¶
The rectangular-pads completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-rectangular-pads-v1.json. Twelve construction-authored cases
contribute twelve physical pads, 36 parameter checks and 48 downstream checks. The corpus covers
all six signed principal orientations, equal pads on separate bodies, reversed Boolean order,
and full-span ledge, nested-staircase and detached-body negatives.
Axis, signed material direction and attachment-plane centre identify each occurrence; footprint
width/length and terminal-to-attachment height are scored parameters. Each source must join one
exact PadFeature through automatic IR, public Sheet.pad, executed generated Sheet code, and
five compiler-owned drawing requirements: both footprint sizes, height and two directional
locations. The final observer follows compiler identities and structured directional facts to
the exact placed ink without using annotation names, views or page coordinates. Removing provider
pads, changing an identity or measurement, corrupting declaration or generated code, or severing
a measurement claim or directional fact reduces the corresponding independent layer.
Polygonal-boss completeness evidence¶
The polygonal-bosses completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json. Eleven construction-authored
cases contribute ten physical attached hexagonal prisms, 40 parameter checks and 40 downstream checks.
The corpus covers all three principal axes, in-plane rotation, equal occurrences on separate
bodies, reversed Boolean order, and recess, detached-prism, whole-stock, circular-boss and
rectangular-pad negatives.
Principal axis and physical prism centre identify each occurrence. The released provider family
guarantees a six-side schema invariant; that invariant, A/F, height and
the canonical set of ordered flat-direction/physical-centre pairs are scored parameters. Each
source must join one exact PolygonalBossFeature through automatic IR, public
Sheet.polygonal_boss, executed generated Sheet code, and two compiler-owned drawing
requirements: the solver-placed A/F leader retains its semantic identity and lands on one
physical flat support, while attached height survives as its own dimension identity. Removing
provider records, changing identity or prism evidence, corrupting declaration or generated code,
moving the leader, changing either statement, or severing either measurement claim reduces the
corresponding independent layer. The older generic boss-height fallback no longer owns polygonal
prisms; the family ledger distinguishes placed, structured-note, suppressed, dropped, missing
and unverifiable outcomes without duplicate diagnostics.
Polygonal-stock completeness evidence¶
The polygonal-stock completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-polygonal-stock-v1.json. Thirteen construction-authored cases
contribute six physical whole-stock hexagonal prisms, 24 parameter checks and 24 downstream
checks. The corpus covers all three principal axes, in-plane rotation, non-origin bounds and
two equivalent topology orders. Circular and rectangular stock, an irregular six-sided prism,
a regular octagon, an attached hexagonal boss, recessed extra topology and a compound remain
outside this exact single-solid family.
Principal axis and physical prism centre identify the occurrence. The released provider family
owns exactly six-sided stock; side count, A/F, axial length and the canonical ring of coupled
flat-direction/physical-centre pairs are scored parameters. Each source must join one exact
PolygonalStockFeature through automatic IR, public Sheet.polygonal_stock, executed generated
Sheet code, and two compiler-owned drawing requirements. The A/F statement must be a confirmed
solver-placed leader with its tip on a retained physical flat, while stock length must retain its
own confirmed Dimension identity. Arbitrary rigid motion is exercised through the public framed
recognition route without changing the default raw rollout policy. The public declaration remains
capable of expressing other even-sided regular stock; only the provider-owned automatic family is
narrowed to its released hexagonal schema.
Plate completeness evidence¶
The plates completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-plates-v1.json. Eleven construction-authored cases contribute
twenty body-local slab occurrences, twenty thickness checks and eighty downstream checks. The
corpus covers all three principal orientations, additive and cut U-channels, equal occurrences on
separate bodies, reverse-ordered topology, cross-family ambiguity, and single-slab, detached,
thick-block and rotational negatives.
A Plate occurrence is a thin material slab in a multi-plate prismatic body; a lone flat plate is
owned by the whole-part envelope and is intentionally outside this denominator. Exact axis,
axial interval and both in-plane witness coordinates join each provider record to one
PlateFeature; the independently authored identity pins axis, physical axial station and both
transverse witness coordinates for every occurrence. Thickness is the
single scored parameter. Each occurrence must survive automatic IR, public Sheet.plate, executed
generated Sheet code and the compiler's thickness.length drawing identity. A planner-derived
opposite U-channel wall is explicitly inapplicable only because the envelope, first wall and
channel-width chain states it; other requirements need real solver-placed Dimension ink.
Material spans already owned by an exact envelope, step-level/shoulder chain, slot pattern or
attached polygonal boss likewise remain inapplicable rather than becoming duplicate Plate
requirements. Raw polygonal-boss ownership requires a valid support record, a single-solid part,
and a boss-plus-slab span equal to the complete envelope axis. Plural-solid inventories remain
unverifiable because Plate carries no body provenance; malformed or partial-span ownership fails
closed.
Derived drawing credit additionally requires every dependency's compiler-approved finished claim
or structured satisfaction; provenance attached to incorrect ink is not enough.
Annotation names, views and page coordinates never establish correspondence. Removing or
malforming provider records, changing the interval or witness, corrupting declaration/generated
code, changing the printed value, or severing measurement provenance reduces the corresponding
independent layer.
Chamfer completeness evidence¶
The chamfers completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-chamfers-v1.json. Ten construction-authored cases contribute
twelve physical bevels, 36 parameter checks and 48 downstream checks. The corpus covers a plain
negative, equal planar bevels on all three principal axes, an asymmetric bevel, a turned conical
treatment, equal occurrences on separate bodies, reversed Boolean-operation order and the
AngledStep/Chamfer ownership contest.
Axis, physical bevel anchor and planar/turned form identify each occurrence; both legs and the
derived angle are scored parameters. Each source must join exactly one ChamferFeature through
automatic IR, public Sheet.chamfer, executed generated Sheet code and a placed semantic callout
carrying its compiler identity. The drawing observation checks C versus leg × angle syntax and
the live leader's physical bevel or turned-profile station independently of annotation names.
Equal specifications may share one n× callout only when every member measurement remains on that
ink. Removing provider records, weakening a leg/angle, corrupting a declaration or generated line,
moving the leader, changing its text or severing provenance reduces the corresponding layer.
Fillet completeness evidence¶
The fillets completeness boundary is independently supported from
tests/fixtures/evaluation/corpus-fillets-v1.json. Ten construction-authored cases contribute
fourteen physical rounds, fourteen parameter checks and 56 downstream checks. The corpus covers a
plain negative, equal planar rounds on all three principal axes, four repeated edges on one body, a
turned toroidal treatment, equal occurrences on separate bodies, reversed Boolean-operation order
and the CircularBlindStep/Fillet ownership contest.
Axis, physical surface anchor and planar/turned form identify each occurrence; radius is the scored
parameter. Each source must join exactly one FilletFeature through automatic IR, public
Sheet.fillet, executed generated Sheet code and a placed semantic callout carrying its compiler
identity. The drawing observation checks R/n× R syntax and the live leader's physical round or
turned-profile station independently of annotation names. Equal radii may share one callout only
when every member measurement remains on that ink. Removing provider records, changing radius,
corrupting a declaration or generated line, moving the leader, changing its text or severing
provenance reduces the corresponding layer.
Circular-blind-step completeness evidence¶
The circular-blind-steps family is supported from the public CircularBlindStep record.
Exact principal run axis, quarter-cylinder radius, terminal-to-open centreline and canonical
transverse arc endpoint/centre/endpoint section identify one occurrence. Draftwright retains the
complete oriented geometry in one CircularBlindStepFeature, exposes the explicit-only
Sheet.circular_blind_step(...) declaration, and preserves the same correspondence through
generated Sheet code without rescanning topology.
Radius and stopped depth become independently addressable circular_step_radius.radius and
circular_step_depth.length requirements. One solver-placed leader points to the physical curved
wall in the axis end view and communicates R… × … DEEP; an authored set may retain either term
without resurrecting the other, and each numeric value keeps its own tolerance. The fail-closed
ledger follows each requirement to placed, structured-note, suppressed, dropped, missing or
unverifiable outcomes. Duplicate or malformed source/IR correspondence is never paired by order.
The aggregate ownership contest is preserved: the curved wall belongs to CircularBlindStep rather
than also yielding a Fillet requirement. Partial model construction preserves that atomic decision:
a caller may supply either or both inventories when they agree with the aggregate, but every
divergent override fails closed instead of producing duplicate or missing radius semantics. The two
public record families are independently quantised and carry no shared provider owner identity, so
Draftwright does not guess a cross-family correspondence from nearby scalar anchors. On a part whose
aggregate owns neither family, explicit one-family injection remains available, but simultaneous
non-empty Fillet and CircularBlindStep inventories are refused for the same reason.
Paired-ramp-step completeness evidence¶
The paired-ramp-steps family is supported as a complete consumer path from the public
PairedRampStep record. Exact principal axis, shared-ridge midpoint, equal acute angle and
open-to-terminal run identify one occurrence. Draftwright lowers it to one
PairedRampStepFeature with independently addressable ramp_angle.angle and
ramp_run.length requirements, exposes the explicit-only Sheet.paired_ramp_step(...)
declaration, and preserves the same feature through generated Sheet code.
One solver-placed compound leader in the axis end view communicates 2× angle × run RUN and
carries both compiler measurement identities. An authored set may retain either requirement
without resurrecting the omitted one, and tolerances remain attached to their own numeric value.
The completeness ledger follows each requirement independently to placed, structured-note,
suppressed, dropped, missing or unverifiable outcomes; duplicate source/IR correspondence fails
closed rather than choosing by order.
Through-step completeness evidence¶
The through-steps family is supported from the public ThroughStep record. Exact principal
axis, removed-prism midpoint, through length and the complete three-point open section identify
one occurrence. Automatic lowering supports every principal run axis. An X/Y-run occurrence is
left with the established face-level plus shoulder/plate grammar only when that grammar proves
both exact physical leg intervals (including an envelope-defined complementary interval); a
partially covered occurrence instead lowers as one aggregate and replaces its exact matching
legacy fragments. Explicit Sheet.through_step(...) declarations choose the same local two-leg
grammar on any principal axis. Both paths preserve their correspondence facts in generated Sheet
code without a second geometry scan.
The two orthogonal section legs become independently addressable
through_step_leg.length.<axis> requirements. The through length remains structural because the
part envelope already states that extent; printing it again would double-dimension the part.
Both legs are solver-placed in the axis end view, outside the missing corner, and carry their own
compiler identities and tolerances. The fail-closed ledger follows each selected leg through
placed, structured-note, suppressed, dropped, missing or unverifiable outcomes; duplicate or
mutated source/IR correspondence is never paired by order. A coordinate-proven complete legacy
projection is inapplicable only while its exact alternate measurement identities are actually
placed or structurally satisfied. Authored omission and placement failure remain suppressed or
dropped; missing alternate ink remains missing. Axis or family presence alone can never claim
an outcome.
Turned-step completeness evidence¶
The turned-steps completeness boundary is independently supported by
tests/fixtures/evaluation/corpus-turned-steps-v1.json. Eleven hash-pinned STEP cases contribute
26 physical outside-diameter bands, 52 parameter checks and 104 downstream checks. The corpus
covers all three principal axes, a translated blind-bored shaft, repeated equal lengths, separate
body-local axis lines, a coaxial through bore, groove overlap, a plain negative and a distinct-hash
topology-order pair. Axis line plus axial station identifies a band; its axial length and diameter
are scored parameters rather than identity, so weakening either lowers fidelity instead of hiding
as a missed occurrence.
Every retained band must cross the automatic IR, the existing public Sheet.step(...) word,
executed generated Sheet code and compiler-confirmed drawing evidence. Drawing credit requires an
exact physical shoulder-to-shoulder length witness and exact OD surface evidence, together with the
complete compiler-approved printed value. Equal adjacent lengths may share n× value ink only when
that annotation carries every member identity, prints the exact multiplier and value, and spans the
complete claimed run. Generated declarations retain coupled length/midpoint precision for
odd-thousandth spans rather than rounding the two facts independently. Automatic IR must also
retain the source band's complete validated TurnedProfileKey ownership at the key's full
published precision. One unique largest band
in one body-local profile may use the rotational profile's equivalent od.diameter
representation, but only when axis line and exact diameter identify that single physical band; one
part-global OD never multiplies across equal or disjoint bands. Each uniquely
correlated groove consumes its own narrow floor band once; ambiguous profile ownership fails
closed instead of guessing, and malformed groove evidence makes the affected groove and raw
turned-band rosters unverifiable. Groove coverage and floor-band ownership share one strict schema:
principal axis, immutable three-finite-real location, and positive finite-real width and diameter;
coercible strings, booleans, mutable points, infinities and NaNs cannot suppress a band. The
axis-line join admits only the half-quantum boundary between a 0.001 mm Groove.at and an
eight-decimal TurnedProfileKey.axis_origin. The root turned_steps and grooves inventories must
remain immutable tuples; a mutable or one-shot substitute is snapshotted once to preserve its
observable cardinality but receives only unverifiable outcomes. If even cardinality is unavailable,
one aggregate unverifiable contract outcome remains visible rather than being mistaken for a valid
empty family. The shared ownership predicate is used by IR lowering, physical lint and the
completeness ledger so their denominators cannot drift.
Framed step-family evidence¶
The released 0.4.10 framed route is exercised for circular-blind-steps, paired-ramp-steps and
through-steps as one consumer boundary. Each construction-authored part is built through the raw
route, the provider-owned local frame, and the same local frame after a combined non-principal
rotation and translation of the source solid. The two framed builds must return identical family
records and IR, an empty semantic build diff, identical compiler-backed ink, and clean physical
lint. Raw and framed principal-axis names may differ because the latter are local coordinates;
the radius/depth, angle/run, and unequal two-leg manufacturing requirements must not.
All three local records still pass through the already-public declaration vocabulary —
Sheet.circular_blind_step(...), Sheet.paired_ramp_step(...) and Sheet.through_step(...) — and
executed generated Sheet code must reconstruct the exact framed feature. No framed-only feature or
placement API is introduced. CircularBlindStep endpoints, radius and depth are independently
quantised by the provider to six significant figures, so derived spans can differ by a few final
places—especially when absolute coordinates are subtracted. IR and completeness validation sum
the relevant published values' decimal half-cells, admitting exactly that bounded uncertainty
while rejecting outside-cell spans and sections. This is consumer normalization of an existing
released schema, not a changed recogniser contract.
Remaining supported-family completeness work is tracked by family group rather than the closed shared design issue: #1371 covers channels, slots and slot patterns, while #1373 retains face levels and risers. #1374's chamfer, fillet and turned-step slices are supported by independent physical corpora.
Historical: recognisers 0.4.8 raw boundary and RaisedPad v2¶
Draftwright pinned the published b123d-recognisers==0.4.8 wheel in the preceding release.
At that time the default route deliberately called build_raw_recognition_result; records
remained in the caller/world coordinate system. #1357 now provides a reviewed explicit
framed-result activation added with 0.4.9. The 0.4.8 tests used the public framed API as release
evidence for upstream #331, #332, and #334, comparing each aggregate inventory with the
corresponding public family call on the exact returned local solid. Production added no fallback,
second aggregate, or family rescan. Face levels,
risers, and turned profiles remained outside framed production pending their subsequently released
upstream fixes.
RaisedPad schema v2 makes a pad normal and its material-outward sign explicit. Draftwright maps
the six signed principal orientations into one PadFeature: world bounds and direction survive
automatic recognition, Sheet.pad(axis=..., direction=...), and executed generated code. The
compiler assigns one end-on semantic view and stable identities for footprint width, footprint
length, terminal-to-attachment height, and both in-plane locations. Footprint/location dimensions
and the … HIGH leader are placed by the ordinary shared solve; no annotation accepts a raw page
position. Removing any one of those five physical facts produces
pad_footprint_not_defined. This is complete consumer semantics, but #1372 still owns the
independently authored rectangular-pad detection/parameter/downstream benchmark corpus required
before claiming family-level completeness.
Blind-slot drawing grammar¶
Quiddity publishes both blind-slot shapes as SectionRecess occurrences in the unified inventory.
Their consumer contracts remain distinct. Both now have dedicated Draftwright feature types and public Sheet words. The rectangular family
uses RectangularBlindSlotFeature and
Sheet.rectangular_blind_slot(...) declaration, generated-code round trip and solver-owned
OPEN SLOT width × capped-run × depth DEEP callout. Its axes and opening signs remain structural
correspondence facts while all printed sizes cross the approved compiler boundary. Native raw and
rigidly moved framed builds preserve the same three measurements and drawing semantics.
This is intentionally not an ordinary through SlotFeature, which cannot state a blind terminal
wall or section depth, and not a rectangular pocket, which cannot state the open end. Independent
physical completeness is now supported by a seven-case authored corpus covering all six run/open
orientations and a separately sized specimen. Each recognised occurrence contributes three
requirements—width, capped run and flat-bottom depth—and exact released structural facts join it to
one IR feature before measurement identities establish placed, structured-note, authored-
suppressed, dropped, missing or unverifiable outcomes. Labels, annotation names, views, projections,
leader tips and page coordinates cannot certify correspondence. The rectangular family therefore
participates in audited_score.
The round-bottom family lowers one-to-one to RoundBottomBlindSlotFeature and declares through
Sheet.round_bottom_blind_slot(...). Its three addressable requirements are capped run length,
straight bottom-flat width and the equal round-side radius. Total opening width
(flat_width + 2 × radius) and profile depth (radius) are derived geometry, not extra independent
requirements. Generated code preserves every structural fact and role-specific decoration; one
solver-owned ROUND-BOTTOM OPEN SLOT … leader carries only compiler-approved values. Its separate
seven-case corpus covers all signed principal orientations and an independently sized specimen,
with exact full-record correspondence and parameter/outcome provenance under the same fail-closed
rules as the rectangular family. It now participates independently in audited_score; ordinary
slots, pockets, channels and rectangular blind slots do not share ownership.
Path-complete Blend drawing grammar¶
Quiddity 0.2.2 retains Blend schema v3 with nested StraightBlendPath and
CircularBlendPath schema-v1 records. The installed manifest and the independently declared
consumer schemas must agree before these records can reach drawing generation.
The supported Blend adapter preserves the complete discriminated path. Straight occurrences keep
their canonical line direction and anchor; circular occurrences keep their centre, canonical
normal, and major path radius; both keep rolling-ball radius and proved convex/concave material
side. BlendFeature, Sheet.blend(...), generated replay, report projection, renderer, and
completeness all carry those facts. The provider aggregate remains the only Fillet/Blend precedence
authority, and Draftwright does not rescan or reinterpret detached faces. Circular leaders combine
the two radii with analysis-owned coaxial cylinder candidates, then use exact same-run
occurrence/IR ownership and the provider-issued defining face to select the physical surface
tangency instead of the rolling path or its centre. A declaration without that face authority
refuses competing support radii rather than choosing another body's cylinder; the shared placement
solve still owns the page position.
Historical 0.4.12 adoption and additive-family boundary¶
Draftwright initially pinned b123d-recognisers==0.4.12, including the immutable 0.4.11 Blend
addition and the 0.4.12 OrientedSlot, OrientedSlotArray, and OrientedSlotGrid records. The
provider capability manifest therefore contains 33 families. Every family and public record has an
explicit consumer declaration and registry home; the inspection API remains format 1 / major 1.
The adoption initially deferred all three additive families. #1433 has now reviewed and promoted
schema-v1 blends: provider reconciliation is the sole Fillet/Blend precedence authority, and each
remaining accepted convex chain owns one radius requirement. Dedicated BlendFeature IR retains
the complete canonical axis_direction; Sheet.blend(...), generated replay and the shared
solver-owned n× R leader preserve it without pretending it is a legacy Fillet. Exact occurrence
and measurement provenance place Blend in audited_score.
Standalone oriented_slots are supported through dedicated vector-valued IR, the public
Sheet.oriented_slot(...) declaration, executable generated code, two compiler-approved width/length
requirements, and solver-owned leaders. Exact run-local identity binds each accepted record to its
IR owner. Array/grid members are excluded by exact provider-record membership and retain the
still-deferred oriented-slot-patterns policy; they are not emitted as competing singletons.
The shared requirement ledger feeds both lint and reports. Malformed or copied pattern authority
is refused rather than reconstructed from equal geometry.
The existing schema-v1 PairedRampStep record is unchanged, while 0.4.12 expands provider
recognition to shallow nonzero ramp pairs. A released shallow specimen now crosses the already
supported consumer path without changing meaning: exact record-to-IR lowering, the existing
Sheet.paired_ramp_step(...) declaration, executed generated code, two compiler-approved angle/run
requirements, one solver-owned compound leader, and the established completeness ledger. Existing
raw and provider-framed contract suites continue to guard the ADR 3 (was 0020) boundary. Draftwright uses no
provider-private geometry or sibling checkout for any of these claims.
1438 first consumed the release's public raw b123d_recognisers.evidence acquisition. One¶
RecognitionEvidence owns the accepted physical occurrence/face references and projects the same
RecognitionResult the existing compiler and lint consumers already read. Draftwright retains
both in its per-drawing RecognitionCache, including across scale/view retries; declared builds
remain recognition-free until physical critique, and a bare result is never rescanned merely to
backfill evidence. Recognisers 0.4.14 publishes the framed-evidence contract requested by
b123d-recognisers#463, but Draftwright's
framed route remains evidence-less until the independent #1438 consumer slice adopts it; it does
not infer cross-frame occurrence identity in the interim.
Round-boss ownership is now explicit at that same run-local boundary. Each accepted BossRecord
retains the exact consumer-selected final owner: its singleton BossFeature, the one existing
same-diameter representative, its body-local turned step, or the groove that absorbs that step or
the profile-gate fallback. The occurrence's own geometry remains available even when the drawing
uses a consolidated owner. Ambiguous selection fails closed as unexpectedly_missing; it cannot be
certified by equal values, ordering, rendered labels, or topology identity.
FaceLevel and RiserEvidence occurrences now receive explicit evidence_only outcomes. This
follows the released provider manifest: both are role=evidence, deliberately absent from the
feature census, and consumed as shared substrate for Draftwright's correlated StepLevelFeature
height/shoulder projection. The aggregate face-level and riser families remain supported; the
outcome says only that each raw evidence record is not itself an independent inferred feature or
completeness requirement. It adds no Sheet word, IR adapter, drawing ink, or provider API.
Historical: recognisers 0.4.9 prepared frame boundary¶
Draftwright's 0.4.9 boundary accepted RiserEvidence v2,
TurnedStep/TurnedProfile v2, and the nested TurnedProfileKey v1. These records preserve
same-solid levels and physical turned-profile membership in compounds. The fail-closed capability
join rejects an older, future, missing, or malformed schema instead of treating it as equivalent.
ADR 3 (was 0020) adds prepare_framed_detection, the one Draftwright-owned intake for the public
prepare_framed_part seam. A successful unit retains the caller-space source as provenance while
pairing the exact local working solid, provider frame, prepared cylinders, Draftwright's local
rotational classification, and aggregate. Classification reuses the prepared cylinder objects;
it does not scan the local topology again. Provider refusal returns its exact typed reason and no
recognition result. There is no hidden raw fallback.
FULL frames establish a directed ordered basis. ORTHOGONAL representatives do not establish sign,
axis interchange, or material identity. AXIAL representatives additionally do not establish roll,
so only roll-invariant facts may be consumed until a particular asymmetric requirement is audited.
Analysis.profiles carries every body-local turned profile through the shared compiler waist on
both the raw and explicit framed routes. Its compatible Analysis.prof projection is populated
only for zero/one-profile consumers; single_turned_profile() likewise refuses plural cardinality
without implying that plural compilation is unsupported. Neither route selects, merges, or discards
a physical profile merely to satisfy that singular accessor.
analysis._analyse activates this boundary only for explicit framed_recognition=True. The exact
working solid then feeds detected compilation, projection and physical lint while caller geometry
remains provenance; AP242 correlation records cross one point/vector/box transform. Typed provider
refusal selects one visible raw fallback at the top-level product-policy boundary. Raw remains the
default while #1357 accumulates supported-platform CI and representative real-part canaries.
Angled-step boundary¶
The installed aggregate reconciles a slanted face claimed by both Chamfer and AngledStep in
favour of RecognitionResult.angled_steps. Draftwright consumes that aggregate result and does not
repeat the provider's topological ownership decision. The corpus fixture
tests/fixtures/issue_1247_angled_blind_step.step pins a genuine partial-width ramp with a
triangular blind end beside an ordinary full-length chamfer: direct recognition sees two chamfers
and one angled step, while the aggregate keeps one of each.
An AngledStep record supplies its angle, two legs, run length, axis and slanted-face centre. Those
measurements are geometric evidence, not a reviewed manufacturing-annotation choice: selecting an
angle plus run, the two legs, a slanted-face dimension, or a section/detail view would invent a
Draftwright requirement grammar that the IR, Sheet surface and compiler do not currently carry.
Draftwright therefore keeps the family disposition unsupported, creates no inferred IR feature,
Sheet declaration, generated code or annotation, and emits
angled_step_requirement_unsupported at warning severity for every aggregate occurrence. Each
occurrence contributes one unsupported completeness requirement. Issue #1247 records this
consumer decision.
Unsupported polygonal-pocket and passage grammar¶
Quiddity's unified SectionRecess inventory carries both supported and unsupported profile
geometry. Draftwright selects its existing drawing grammar from the exact public section and ends;
it does not rerun provider recognition or retain a second legacy pocket/passage inventory.
A general polygonal recess has no truthful rectangular W × L × D DEEP callout. A general line/arc
through-opening likewise cannot be represented by a regular-polygon HEX … A/F THRU callout.
These occurrences retain the decisions recorded by #1246 and #1245: no inferred IR feature, public
declaration, generated feature or annotation is invented. Each occurrence instead contributes one
unsupported completeness outcome and its corresponding prismatic_pocket_requirement_unsupported
or passage_requirement_unsupported warning. Exact mouth-to-section correlation can replace a
generic unsupported-profile warning for that occurrence; unrelated unrecognised geometry remains
visible. The old accepted-only Passage projection no longer exists and cannot add another count.
Provider refusals are distinct from accepted geometry outside the drawing grammar. Each exact
SectionRecessRefusal is retained with its reason and original evidence, emits
section_recess_recognition_refused, and carries no fabricated feature position. A valid unmatched
supported recess still contributes its full independent requirement count. A malformed recess
cannot establish a trustworthy family or denominator and is rejected at intake.
Step families introduced in recognisers 0.4.6¶
The 0.4.6 provider manifest adds circular-blind-steps, paired-ramp-steps, and
through-steps. Their typed records expose physical axes, locations, run lengths, and the relevant
section or angle. Those facts do not by themselves choose Draftwright's manufacturing requirement,
semantic view, or dimension grammar, so each family receives a separate reviewed disposition.
All three step families now have complete supported paths. Through-step automatic ownership supports every principal run axis while retaining an X/Y occurrence's existing Z-up grammar only when both physical legs and their actual outcomes are proved; the explicit Sheet surface likewise supports all principal axes. Circular blind steps retain their oriented centreline/quarter-arc correspondence and communicate independently addressable radius and stopped-depth requirements in one end-view leader. Issue #1382 records the reviewed downstream dispositions.