graflo.architecture.profile¶
Named conformance profiles over a manifest.
A profile is a versioned list of mechanically checkable assertions. It reads only fields the contract already has, introduces no semantics and touches no backend -- so it can run against manifests this package did not author, which is the point.
Eager re-export: the subpackage imports nothing heavier than the contract models, so there is no lazy-facade cost to avoid here.
Modules:
| Name | Description |
|---|---|
context |
What a profile check reads, and the vocabularies it recognises. |
inverses |
Audit of declared inverses across the whole manifest, and its |
model |
The conformance report, and the waiver document that can excuse part of it. |
runner |
Profile definition, registry, and the entry points every surface calls. |
world_model |
The World Model Profile: six mechanically checkable assertions. |
Attributes¶
INVERSES_PROFILE = Profile(name='inverses', version=PROFILE_VERSION, assertions=(Assertion(_CONSISTENT, 'Declared inverses are realized without contradiction', True, check_inverses_consistent), Assertion(_COMPLETE, 'Every realization of an inverse is complete', True, check_inverses_complete)))
module-attribute
¶
Severity = Literal['error', 'warning', 'info']
module-attribute
¶
Status = Literal['pass', 'fail', 'warn', 'waived', 'not_applicable']
module-attribute
¶
VocabularyStatus = Literal['live', 'unknown', 'malformed']
module-attribute
¶
WORLD_MODEL_PROFILE = Profile(name='world-model', version=PROFILE_VERSION, assertions=(Assertion(_A1, 'Types are grounded in an external vocabulary', True, check_grounded_types), Assertion(_A2, 'Every vertex declares an identity mode', True, check_declared_identity), Assertion(_A3, 'Every edge declares its directionality', True, check_declared_directionality), Assertion(_A4, 'Every measured property carries a unit', True, check_declared_units), Assertion(_A5, 'Temporal validity is declared or waived', True, check_temporal), Assertion(_A6, 'Provenance is expressible and attached', True, check_provenance)))
module-attribute
¶
__all__ = ['INVERSES_PROFILE', 'WORLD_MODEL_PROFILE', 'Assertion', 'AssertionResult', 'CheckContext', 'Finding', 'InverseReport', 'PairStatus', 'PrefixAllowListResolver', 'Profile', 'ProfileReport', 'ProfileWaivers', 'Severity', 'Status', 'VocabularyResolver', 'VocabularyStatus', 'Waiver', 'audit_inverses', 'check_manifest', 'check_manifest_config', 'get_profile', 'list_profiles', 'run_profile']
module-attribute
¶
Classes¶
Assertion
dataclass
¶
One mechanically checkable claim about a manifest.
Source code in graflo/architecture/profile/runner.py
AssertionResult
¶
Bases: ConfigBaseModel
One assertion's outcome over the whole manifest.
Source code in graflo/architecture/profile/model.py
Attributes¶
checked = PydanticField(default=0, description='Elements examined. Zero means the assertion had nothing to say about this manifest, which is reported as ``not_applicable`` rather than as a pass.')
class-attribute
instance-attribute
¶
findings = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
id = PydanticField(...)
class-attribute
instance-attribute
¶
required = PydanticField(default=True)
class-attribute
instance-attribute
¶
status = PydanticField(...)
class-attribute
instance-attribute
¶
title = PydanticField(...)
class-attribute
instance-attribute
¶
waiver = PydanticField(default=None)
class-attribute
instance-attribute
¶
CheckContext
dataclass
¶
Everything an assertion may read.
Attributes:
| Name | Type | Description |
|---|---|---|
manifest |
GraphManifest
|
The parsed, |
authored |
Mapping[str, Any] | None
|
The document the author wrote, when the caller has it.
|
waivers |
ProfileWaivers | None
|
Operator waivers to apply, if any. |
resolver |
VocabularyResolver
|
Vocabulary liveness backend. |
Source code in graflo/architecture/profile/context.py
Attributes¶
authored = None
class-attribute
instance-attribute
¶
has_authored
property
¶
Whether declaration-sensitive assertions can be decided at all.
manifest
instance-attribute
¶
resolver = field(default_factory=PrefixAllowListResolver)
class-attribute
instance-attribute
¶
waivers = None
class-attribute
instance-attribute
¶
Methods:¶
__init__(manifest, authored=None, waivers=None, resolver=PrefixAllowListResolver())
¶
authored_edges()
¶
Authored edge blocks; empty when the document is absent.
authored_vertices()
¶
Authored vertex blocks by name; empty when the document is absent.
Source code in graflo/architecture/profile/context.py
Finding
¶
Bases: ConfigBaseModel
One assertion's verdict about one element.
Source code in graflo/architecture/profile/model.py
Attributes¶
assertion = PydanticField(...)
class-attribute
instance-attribute
¶
detail = PydanticField(default_factory=dict, description='Machine payload -- the IRI, the unit token, the identity mode.')
class-attribute
instance-attribute
¶
message = PydanticField(..., description='One line, already readable without the detail payload.')
class-attribute
instance-attribute
¶
severity = PydanticField(...)
class-attribute
instance-attribute
¶
status = PydanticField(...)
class-attribute
instance-attribute
¶
target = PydanticField(default=None, description='The element this is about, in a stable address form: ``vertex:Observation``, ``vertex:Observation.result_value``, ``edge:Observation-hasFeatureOfInterest->Asset``, or ``manifest``.')
class-attribute
instance-attribute
¶
InverseReport
¶
Bases: ConfigBaseModel
Everything known about how a manifest realizes its declared inverses.
Source code in graflo/architecture/profile/inverses.py
Attributes¶
findings = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
pairs = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
symmetric = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
Methods:¶
conflicts()
¶
introduced_since(before)
¶
Findings of this report that before did not have.
audit_inverses(after).introduced_since(audit_inverses(before)) is what
a change did to the inverses, whatever produced the change.
Source code in graflo/architecture/profile/inverses.py
notes()
¶
pair(relation)
¶
The status of the pair that relation belongs to, either side.
repairable()
¶
to_lines()
¶
The report as text. The one renderer.
Source code in graflo/architecture/profile/inverses.py
PairStatus
¶
Bases: PairRealization
A declared pair across schema and ingestion.
Source code in graflo/architecture/profile/inverses.py
Attributes¶
feeding = PydanticField(default_factory=dict, description='Per resource that writes either relation of the pair: how it feeds the materialized inverse. Empty when nothing is materialized.')
class-attribute
instance-attribute
¶
native_candidate = PydanticField(default=None, description='The relation that would be listed in `native_inverses`: the one that has edges while its inverse has none.')
class-attribute
instance-attribute
¶
native_eligibility = PydanticField(default=None, description='Rules that would be broken if the database maintained this pair; empty means eligible. None when the pair is already native.')
class-attribute
instance-attribute
¶
PrefixAllowListResolver
dataclass
¶
Recognises :data:KNOWN_NAMESPACES; everything else is unknown.
The honest v0.1 answer to "does this resolve to a live vocabulary": it
checks the shape and the namespace and says so, rather than dereferencing
anything. unknown is reported as a warning, never as a failure.
Source code in graflo/architecture/profile/context.py
Attributes¶
namespaces = KNOWN_NAMESPACES
class-attribute
instance-attribute
¶
Methods:¶
__init__(namespaces=KNOWN_NAMESPACES)
¶
resolve(iri)
¶
Source code in graflo/architecture/profile/context.py
Profile
dataclass
¶
A named conformance level.
Source code in graflo/architecture/profile/runner.py
ProfileReport
¶
Bases: ConfigBaseModel
The result of checking one manifest against one named profile.
Source code in graflo/architecture/profile/model.py
Attributes¶
assertions = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
graflo_version = PydanticField(default=None)
class-attribute
instance-attribute
¶
manifest_hash = PydanticField(default=None, description='Content address of the manifest checked, so a stored report can be matched back to the artifact that produced it.')
class-attribute
instance-attribute
¶
ok
property
¶
No error-severity finding survived waivers.
profile = PydanticField(...)
class-attribute
instance-attribute
¶
profile_version = PydanticField(...)
class-attribute
instance-attribute
¶
status = PydanticField(...)
class-attribute
instance-attribute
¶
subject = PydanticField(default=None, description='What was checked -- a path, or ``uuid@version``. Set by the caller.')
class-attribute
instance-attribute
¶
Methods:¶
errors()
¶
Every finding that makes the manifest non-conformant.
Source code in graflo/architecture/profile/model.py
to_lines()
¶
The report as text. The one renderer -- every surface calls this.
Source code in graflo/architecture/profile/model.py
warnings()
¶
Every advisory finding, waived assertions included.
ProfileWaivers
¶
Bases: ConfigBaseModel
A sidecar document of waivers granted against one profile.
Source code in graflo/architecture/profile/model.py
Attributes¶
profile = PydanticField(default='world-model')
class-attribute
instance-attribute
¶
subject = PydanticField(default=None, description='What these waivers were granted against -- a manifest name or content hash. Advisory: nothing enforces the match.')
class-attribute
instance-attribute
¶
waivers = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
Methods:¶
for_assertion(assertion_id)
¶
The waiver covering assertion_id, or None.
VocabularyResolver
¶
Bases: Protocol
Decides whether an IRI resolves to a vocabulary worth grounding in.
A protocol rather than a class so the bundled prefix check can be replaced by a real registry lookup without touching the report model or any of the surfaces that render it.
Source code in graflo/architecture/profile/context.py
Waiver
¶
Bases: ConfigBaseModel
An operator's decision to excuse one assertion, with its reason.
Source code in graflo/architecture/profile/model.py
Attributes¶
assertion = PydanticField(..., description='Identifier of the assertion this waiver excuses, e.g. ``temporal``.')
class-attribute
instance-attribute
¶
expires = PydanticField(default=None)
class-attribute
instance-attribute
¶
granted_at = PydanticField(default=None)
class-attribute
instance-attribute
¶
granted_by = PydanticField(default=None)
class-attribute
instance-attribute
¶
reason = PydanticField(..., description='Why the assertion does not apply to this deployment. Required: a waiver without a reason is a silent pass with extra steps.')
class-attribute
instance-attribute
¶
Functions:¶
audit_inverses(manifest)
¶
Report how manifest realizes every declared inverse, and what is wrong with it.
Reads the schema, the physical profile and the ingestion model; changes nothing, raises nothing, and does not need the manifest to have loaded.
Source code in graflo/architecture/profile/inverses.py
check_manifest(manifest, *, profile='world-model', authored=None, waivers=None, subject=None, resolver=None)
¶
Check an already-parsed manifest.
Prefer :func:check_manifest_config when the authored document is
available: without it the declaration assertions can only warn.
Source code in graflo/architecture/profile/runner.py
check_manifest_config(config, *, profile='world-model', waivers=None, subject=None, resolver=None)
¶
Check the manifest config as authored.
The primary entry point. Parses config into a manifest and keeps the original mapping alongside it, so an assertion can tell "the author did not declare this" from "the author declared the value that is also the default".
Source code in graflo/architecture/profile/runner.py
get_profile(name)
¶
The profile called name.
Raises:
| Type | Description |
|---|---|
KeyError
|
no such profile, naming the ones that exist. |
Source code in graflo/architecture/profile/runner.py
list_profiles()
¶
run_profile(profile, context)
¶
Run every assertion of profile against context.