Expand description
渾儀 (Húnyí) — the semantic observation dimension of Tianheng.
Where the gnomon 圭表 observes imports, 渾儀 observes meaning via the AST (syn):
does a module’s public API expose a forbidden type? That is the complement of
import-governance — a type imported for internal use is fine, but a type named in a pub
signature or alias chain is observed.
Declare a SignatureBoundary in Rust, check it against a Cargo workspace, and get
an Outcome. The heavy syn parser is quarantined to this crate, keeping the functional
core dependency-light (crates/shengmo/src/law.rs).
Govern by reaction, not instruction.
Layout. Each semantic capability is a self-contained reaction module
(check_<cap> → check_<cap>_boundary → <cap>_findings); check_all composes them all
with a single cargo metadata read. The shared reaction spine lives in the driver module
and the canonical rule labels in rules, below every capability so none depends on another.
Structs§
- Async
Exposure Boundary - An async-exposure boundary: a module’s public API must not declare an
async fn. The implicit-existential complement ofImplTraitBoundary: anasync fnleaks a compiler-insertedimpl Future(and commits the seam’s contract to an async model), so where impl-trait forbids a written-> impl Future, this forbids theasync fnsugar (observed fromsyn::Signature.asyncness). Governs public free fns, public inherent methods, and public trait method declarations; trait-impl methods (asyncness dictated by the trait) and private items are excluded. Declarative intent by anchor scoping — “this declared seam is synchronous” (a sync-core/async-edges layering), not a blanket “no async”. - Baseline
- Recorded set of accepted violations.
- Bound
Decl - One declared observation bound: its identity, the shape it stops at, and where the measure stops.
- BoundId
- A declared bound’s identity:
<capability>/<scenario-slug>, derived from where the bound is declared. - DynTrait
Boundary - A dyn-trait boundary: a module’s public API must not expose trait-object (
dyn) syntax. The type-shape complement ofSignatureBoundary(signature-coupling): where that forbids an exposed named type, this forbids an exposed type shape — adynnode at any depth in the governed public surface. Internaldynis never a violation — this governs exposure across the declared seam, not internal dynamic dispatch, so it is intent (by anchor scoping), not a lint. Declared in Rust and composed with the other dimensions at the gate. - Finding
- Pair human-readable finding text with stable structured identity.
- Forbidden
Marker Boundary - A forbidden-marker boundary: types defined in a module subtree must not acquire a
forbidden trait — by
#[derive(T)]or a hand-writtenimpl T for <a subtree type>. Declared in Rust and composed at the gate. The complement to exposure, impl-locality, and visibility; it delivers the “this layer is notT-able” intent. - Impl
Trait Boundary - An impl-trait boundary: a module’s public API must not return a written
impl Trait(return-positionimpl Trait/ RPIT). The existential complement ofDynTraitBoundary: where that forbids the dynamic-dispatch shape (dyn), this forbids the existential shape — an unnameable type the caller cannot name, store without boxing, or rely on beyond its declared bounds. Governs return positions only: argument-positionimpl Trait(APIT) is universal (a caller-chosen generic), not an existential leak, and is never governed;async fn’s implicitimpl Futureis a distinct compiler-inserted existential, out of scope. Declared in Rust and composed with the other dimensions at the gate. - Report
- All violations from one evaluation.
- RuleKey
- A validated semantic key for one rule family and its identity-bearing parameters.
- Semantic
Boundaries - The 渾儀 (semantic) dimension’s boundaries, gathered so the shell takes the dimension as
one unit rather than one parameter per capability. Each field is one capability’s
boundaries;
check_allevaluates every non-empty bundle with a singlecargo metadataread. - Semantic
Observer - The semantic dimension as an
Observer. - Signature
Boundary - A semantic boundary: the public API of a module must not expose any forbidden type. Declared in Rust (the single source of truth), alongside — and composed with — the static constitution at the gate. Each dimension owns its own declaration DSL and expresses findings in the shared 璇璣 model; the shell merges them into one reaction.
- Structured
Fact Identity - A validated, dimension-agnostic identity for one observed fact.
- Subject
- What an observation was asked to enforce, and how much of the workspace it reached.
- Trait
Impl Boundary - A trait-impl-locality boundary: within a target crate, the named trait may be
implemented only inside the declared allowed module location(s). An
impl <Trait> for <Type>block outside them is a violation. Declared in Rust (the single source of truth) and composed with the other dimensions at the gate. This governs impl locality — the complement of exposure (SignatureBoundary) and of the static import boundary. It governs only the target crate’s own impl sites; it makes no claim about downstream crates (that would be external trait sealing, an essential gap). - Unsafe
Boundary - An unsafe-confinement boundary: within a target crate,
unsafe(blocks,unsafe fn/impl/trait,unsafe extern) may appear only under the declared subtree(s); a site outside all of them reacts. Declared in Rust (the single source of truth), composed at the gate. - Violation
- One violated boundary.
- Violation
Id - A violation’s stable semantic identity.
- Visibility
Boundary - A visibility boundary: a governed module must not declare any bare-
pubitems — a declared-visibility hygiene rule for an internal / impl-detail layer. The rule is syntactic (thepubkeyword on the module’s own direct items), not crate- reachability:pub(crate)/pub(super)/pub(in …)/private are allowed, and attribute- derived public surface (#[macro_export],#[no_mangle]) is out of scope (the deferred attribute capability’s domain). Declared in Rust and composed with the other dimensions at the gate.
Enums§
- Boundary
Kind - Which kind of boundary produced a violation.
- Defence
- The evidence state of a declared observation bound.
- Demonstrates
- What a bound’s pinning test must demonstrate, derived from its
Extent. - Extent
- Where a reaction’s measure stops for one declared shape.
- Fact
Granularity - Which part of an observed fact a granularity bound limits.
- Outcome
- The reaction’s outcome.
- Owner
- Who must act if a declared false negative is ever to close.
- Polarity
- The repair direction a boundary-drift violation points to.
- Reached
- What a reaction does with a shape it did see.
- Scan
Depth - The depth or granularity level of a boundary observation.
- Severity
- How strongly a boundary reacts.
- Visibility
Ceiling - The maximum declared visibility a governed module’s direct items may carry. An item whose
declared-visibility rank is strictly above the ceiling reacts; at or below it passes.
(
Publicis deliberately not a ceiling — it would never react.)
Constants§
- ASYNC_
EXPOSURE_ RULE - Async-exposure: a module’s public API must not declare an
async fn. - DYN_
TRAIT_ RULE - Dyn-trait: a module’s public API must not expose trait-object (
dyn) syntax. - FORBIDDEN_
MARKER_ RULE - Forbidden-marker: a subtree’s types must not acquire a forbidden trait.
- IMPL_
TRAIT_ RULE - Impl-trait: a module’s public API must not return a written
impl Trait(RPIT). - SIGNATURE_
RULE - Signature-coupling: a module’s public API must not expose a forbidden type.
- TRAIT_
IMPL_ RULE - Trait-impl-locality: a trait may be implemented only in its declared location(s).
- UNSAFE_
CONFINEMENT_ RULE - Unsafe-confinement:
unsafeis confined to the declared subtree(s). - VISIBILITY_
MODULE_ RULE - Visibility,
Moduleceiling: nothing more visible than module-private. - VISIBILITY_
RULE - Visibility,
Crateceiling (themust_not_declare_pubsugar): no bare-pubitems. Kept verbatim so the sugar’s findings and baselines never churn. - VISIBILITY_
SUPER_ RULE - Visibility,
Superceiling: nothing more visible thanpub(super).
Traits§
- Observer
- A participant in one governance run: it observes a workspace, and declares what it does not observe.
Functions§
- apply_
baseline - Mark each violation recorded in baseline as baselined.
- check
- Run the semantic boundaries against the Cargo workspace at
manifest_path. - check_
all - Evaluate every declared semantic boundary against the workspace with a single
cargo metadataread, merging all findings into one outcome. A constitution error on any boundary supersedes (exit 2). An empty bundle returnsOutcome::Cleanbefore metadata is read. The per-capabilitycheck/check_trait_impl_locality/check_visibilityentries remain for direct use; the shell andSemanticObservercompose via this. - check_
async_ exposure - Run the async-exposure boundaries against the Cargo workspace at
manifest_path. - check_
dyn_ trait - Run the dyn-trait boundaries against the Cargo workspace at
manifest_path. - check_
forbidden_ marker - Run the forbidden-marker boundaries against the Cargo workspace at
manifest_path. - check_
impl_ trait - Run the impl-trait boundaries against the Cargo workspace at
manifest_path. - check_
trait_ impl_ locality - Run the trait-impl-locality boundaries against the Cargo workspace at
manifest_path. - check_
unsafe_ confinement - Run the unsafe-confinement boundaries against the Cargo workspace at
manifest_path. - check_
visibility - Run the visibility boundaries against the Cargo workspace at
manifest_path. - observation_
bounds - Every observation bound 渾儀 declares, grouped by the capability that declares it.