artefact

package
v0.0.1-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package artefact holds each of the five artefacts' own schema, the checks that read one artefact against itself — kind: against its directory, an artefact's own name against its file's basename, the credential slot's shape, the Target declaration's own two cross-field rules, and the Manifest's request, input-schema and path grammars (§3, §4, §12) — and, starting with the Definition, the first checks that read more than one artefact at a time: whether a name an artefact writes for another resolves, and the two checks a (Definition, Target) binding decides that neither artefact alone can (§4, §5, issue #93). The Repository declaration, the Target declaration, the Manifest and the Definition's schemas exist so far — a Procedure arrives in its own ticket and grows this package the same way (issues #89, #90, #91, #93).

This file is the Definition's own schema, the checks that read it against itself — kind: against definitions/, definition: against the file's basename, and the two keys' own shape (§3, §4, issue #93) — and the first checks in this package that read more than one artefact at once: whether provider: and every targets: member name an artefact this repository holds, whether a destroy: member names an Operation the bound Provider declares, and the two checks that need a (Definition, Target) pair rather than either artefact alone — a Target outside the bound Provider's class, a Capability the Target's declaration does not grant, and the Target's credential slots not covering the bound Provider's Auth scheme, the twelfth shape of manifest-inconsistent left open by #92 (§4, §5).

This file is the Manifest's own schema, the checks that read it against itself — kind: against providers/, provider: against the file's basename, the request written under exactly one Capability, the input-schema subset, and the path and template-hole grammars (§3, §4, §12, issue #91) — and the Manifest's oracle: the checks that read a Manifest's own declarations against each other, with nothing but the file in hand (§4, issue #92). capability-mismatch and identity-undeclared read what an Operation's own request and record: imply against what the Manifest declares elsewhere; manifest-inconsistent is twelve decidable-from-one- file shapes of one fact sharing one code; header-reserved and capability-reserved refuse a name the tool holds rather than an internal contradiction, the second of them being the one check here whose subject is not the Manifest but where it was loaded from — §11's rule that an Extension may never hold the shell Capability, which is why it runs in CheckManifest and not in the body the built-in shares (issue #186). One further shape of manifest-inconsistent — Target slot coverage — needs a (Definition, Target) binding neither this file nor this milestone's artefacts supplied on their own, and is definition.go's, alongside target-class-mismatch, a code of its own that needs the same binding (issue #93).

opaque is not among the keys any schema here admits — it is never a writable key at all, being a property of the Capability an Operation's request uses rather than a fact the Operation states (§3) — so a Manifest author who writes it earns unknown-key like any other key the schema at that position does not define.

This file is the Procedure's own schema, the Step and the nested invocation that share `steps:`, the reference grammar a value position embeds a path in, and the three load-time rules issue #94 lands: the resolution positions `definition:`, `procedure:`, `operation:` and a reference's two halves add; the command, `hyper`'s own `shell` Provider knowing nothing of it so the argv arrives as the Step's own `args:`; and a repeated `over: values:` member, the Store's own `record-identity-collision` fired one Run earlier, against an artefact rather than a branch (§3, §4, §12).

The two keys, the Bound and the opaque `destroy` opt-ins — the authority a Step's binding needs against its Definition's claim and its Target's grant — are issue #95's, landed here: kind-not-granted, operation-not-claimed, target-not-claimed, bound-missing, bound-illegal and destroy-unscoped, the last widened past its opaque origin by issue #157 — which also lands the empty `over: values:` member beside it, the other authored shape reaching an identity with no name. A Capability its Target grants is checked already, in definition.go, needing no Step to exist.

Issue #97 lands here too: the closed eleven-member operator set's own operand-type rules (predicate-type-mismatch), checked wherever a predicate stands — a selector, a condition, or a polling Pattern's `until:` in manifest.go, which calls back into this file's checkPredicateCore rather than duplicate it; the three `over:` forms themselves, `assets:`, `observations:` and `values:`, closed to a fourth and each checked against the Kind that may declare it; the two Record roots' own `field:` rule — one declared field name, resolved against the union of every Operation the bound Provider declares, since an `assets:`/`observations:` selector ranges over a (Definition, Target) series a different Operation of the same Provider may have written (reference-unresolvable), and refused again where that field is one the Manifest declares `secret:`; `skip-if-recorded-unreachable`, a `skip-if-recorded` Step expanding over `assets:`; and `bound-exceeded`, the offline half decided from an `over: values:` list's authored length alone, the run-time half over `assets:`/`observations:` left to a Run that needs the Store to count them.

Issue #98 lands the host grant and the one Expansion-identity fault decidable with no Store: an Operation's host: template expanded at load into its finite candidate set — {from-target} to the bound Target's grant, an enumeration hole against the enumerations: entry it names, the cross-product where a template carries more than one hole — and compared against the grant, a member absent earning host-not-granted; the intersection deciding whether host-input: is required at all; an over: values: list wired {item: $} into the Operation's host-input: compared against the same grant under the same code, host-list-ness read off the wiring and never off a declaration; and record-identity-collision for an authored two-or-more-member values: list whose members can only ever project one identity, the Operation's identity: resolving before the call with no {item:} reference reaching the value that fills it — the same code the duplicate-member load site fires, found against the wiring rather than against the list.

This file is the transitive walk itself — the one traversal issue #96's three rules ride: an invoked Procedure's own declared envelope reaching outside its caller's (the composition half of envelope-exceeded, procedure.go carrying the file-local half), and the two Cadence rules, cadence-run-once and cadence-secret-output, which cost this walk a rule each rather than a traversal of their own. All three read every procedures/ file at once — a nested invocation's own file, to any depth — which is what sets this apart from procedure.go's per-file checks and is why it lives in its own file with its own entry points, BuildProcedureGraph and CheckProcedureGraph.

A fourth rule is here because it is about the graph rather than about anything read through it: procedure-cycle, an invocation graph that closes on itself (issue #146). The three above tolerate a cycle — a name already being walked contributes nothing further — which is right for them and silent, and §6 states the graph is acyclic rather than hoping it is.

Index

Constants

View Source
const (
	KeyDefinition = "definition"
	KeyOperation  = "operation"
	KeyProvider   = "provider"
	KeyProcedure  = "procedure"
)

The four keys an AbsentName is written under, which are the authoring format's own and not §12's kind: values — three of them spell a kind and the fourth names a key inside a Manifest. They are stated here because the reader that sets one and the surface that renders it are in two packages, and a fifth absence arriving should not be two literals nothing ties together.

View Source
const (
	OriginBuiltIn   = "built-in"
	OriginExtension = "extension"
)

The two members of §12's Provider origin set, and the criterion is where the Manifest's bytes load from: inside the binary, or a tracked file in providers/ (ADR-0073). It says nothing about whether those bytes were ever verified against a registry — a built-in and a locally authored Extension both make no such claim, and whether a Manifest claimed an upstream is the second, orthogonal fact its origin: block carries.

The spelling is built-in and not builtin. §12's baseline_absent already carries built-in on §8's wire for the same fact about the same Manifest, and one fact reaching two wires reaches them under one name.

View Source
const BuiltinShellProviderName = "shell"

BuiltinShellProviderName is the name the compiled-in Manifest below declares for itself, and the one member of §12's built-in Provider set.

It is spelled once because three things read it: the Provider namespace, which starts from it; the fold, which declines an Extension that takes it; and the check that names the taking (§11, §12, IsBuiltinProviderName).

View Source
const BuiltinShellProviderPath = "<built-in>/shell"

BuiltinShellProviderPath is the pseudo-path §9 renders for the built-in shell Provider's Manifest, <built-in>/shell — not a File a check row may ever cite, the built-in having no file to open, but a label these internals thread through the same functions a providers/ file's checks use (§3, §9, §11).

View Source
const BuiltinShellProviderYAML = `` /* 1741-byte string literal not displayed */

BuiltinShellProviderYAML is hyper's own shell Provider, compiled into the binary exactly as §12 states it: six Operations, Kind crossed with the Repeatability values each Kind may declare, sharing one request — an empty shell: block, the argv arriving as the Operation input named command in a Step's args: — and, on the four that carry one, one projection (§3, §12, issue #91).

View Source
const CodeArtefactAbsent = "artefact-absent"

CodeArtefactAbsent is the code a name an artefact writes for one of this repository's own artefacts earns where it resolves to nothing — a Definition's provider: or a targets: member here, and, as those artefacts arrive, a Step's definition: and a nested invocation's procedure: (§4, ADR-0064). The row carries the file and line the name was written on and the path hyper looked for, so the two edits it points at are fix the name and write that file.

View Source
const CodeBoundExceeded = "bound-exceeded"

CodeBoundExceeded is the code an over: values: list longer than the Step's own declared bound: earns, decided offline: the list is authored in the Procedure, so its length is read off the file, and it is an upper bound on what the Expansion can reach — the Store only ever removes members from it. The run-time half of the same check, over assets: and observations:, needs the Store to count and is left to a Run (§4, §5, §6, §12, issue #97).

View Source
const CodeBoundIllegal = "bound-illegal"

CodeBoundIllegal is the code an opaque destroy Step carrying a bound: earns — the one Step that carries no Bound, a count of the commands it ran saying nothing about what any of them did (§4, §5, issue #95).

View Source
const CodeBoundMissing = "bound-missing"

CodeBoundMissing is the code a destroy Step carrying no bound: earns — an absent Bound means unbounded, and unbounded is refused before anything runs (§4, §5, issue #95).

View Source
const CodeCadenceMalformed = "cadence-malformed"

CodeCadenceMalformed is the code a `cadence:` outside §10's five-field grammar earns — the closure that grammar has always stated and nothing enforced (§10, §12). A nickname, a month or a day *name*, a sixth seconds field, a timezone or an offset, `?`, `L`, `W`, `#`, a value outside its field's span and a range that runs backwards are each this one code: the grammar is closed by what it admits rather than by a list of what it rejects, and a name is refused on the ground the nickname is, being a second spelling of a Cadence the numeric form already states.

It is a Procedure's own check — one scalar in one file — so it lands here beside name-mismatch and the Step checks rather than in the transitive graph walk, where the two Cadence *composition* rules live because those read other files (procedure_graph.go). Both codes on one artefact is two problems on the page: cadence-run-once and cadence-secret-output turn on a Cadence being declared and never on its being legible, and `check` reports every problem rather than the first (§4).

View Source
const CodeCadenceRunOnce = "cadence-run-once"

CodeCadenceRunOnce is the code a Procedure declaring a Cadence earns for reaching a run-once Step at any depth: a Cadence over a run-once Step declares a recurrence with a lifespan of one occurrence, which is not a thing an author can have meant (§4, §5, ADR-0038, issue #96).

View Source
const CodeCadenceSecretOutput = "cadence-secret-output"

CodeCadenceSecretOutput is the code a Procedure declaring a Cadence earns for reaching a Step whose Operation declares secret: output at any depth: such a Step Refuses where the invocation supplied no Secret sink, and the workflow project generates supplies none, so where a Cadence carries it the Refusal lands at every occurrence and the Procedure works never (§4, §5, ADR-0077, issue #96). It is its own code rather than a second cause folded into cadence-run-once: a reader handed cadence-run-once on a secret: clash edits a repeatability: that is correct.

View Source
const CodeCapabilityMismatch = "capability-mismatch"

CodeCapabilityMismatch is the code a Manifest's declared capabilities: earns for disagreeing with what hyper derives from every Operation's own request block — over-declared or under, either direction (§3, §4).

View Source
const CodeCapabilityNotGranted = "capability-not-granted"

CodeCapabilityNotGranted is the code a Capability the bound Provider's Operations require and the bound Target's declaration does not grant earns, checked per (Definition, Target) pair — a Target declaration is written without knowing which Provider will bind it, so the question can only be asked once a binding exists (§3, §4).

View Source
const CodeCapabilityReserved = "capability-reserved"

CodeCapabilityReserved is the code a Manifest loaded from providers/ earns for reaching a Capability reserved to the Providers hyper ships — shell, the one behind an opaque Operation, so that *a third party can never ship a Provider that runs commands on your machine*, which is the honest form §13 states the guarantee in (§11, §12, ADR-0004).

It is drawn on a name the tool holds rather than on an internal contradiction, which is header-reserved's shape one artefact-class over (§4): what capability-mismatch reads is whether a Manifest agrees with itself, and a Manifest can reach this one while agreeing with itself exactly.

View Source
const CodeCommandMalformed = "command-malformed"

CodeCommandMalformed is the code a shell Step's command: earns for being empty, there being no executable to name, or for naming its executable — the first member, the reach axis — by reference rather than by literal (§3, §4, ADR-0051). It is its own code and never a widening of hole-illegal: command: is never a template hole and could not be one (§3), and a reader handed hole-illegal here would go looking for one.

View Source
const CodeCredentialSlotMalformed = "credential-slot-malformed"

CodeCredentialSlotMalformed is the code a credential slot's value earns wherever it is not exactly a mapping whose sole key is env:, and the code env: itself earns wherever it is written outside a credential slot, in any artefact (§4).

View Source
const CodeDefinitionKindsMixed = "definition-kinds-mixed"

CodeDefinitionKindsMixed is the code read in kinds: earns for standing beside mutate, or beside a destroy: claim naming any Operation: a Definition observes or it effects, never both (§3, §4, ADR-0032). It reads one file and needs no Target, which is why it is checked before any resolution below.

View Source
const CodeDestroyUnscoped = "destroy-unscoped"

CodeDestroyUnscoped is the code a destroy Step carrying no over: selector earns: without one it is invoked once, has no Expansion to write a Tombstone under and declares no identity, so it would reach the world and leave nothing in the record at all (§4, §5, ADR-0053, issue #95).

It is one code because it is one check. Opacity is not a clause of that argument — a `destroy` carries no `record:` whatever its Capability, so an `http` one with no selector holds the same nameless member and reaches the Store with the same empty identity. The check was stated where it was noticed rather than where it holds, and it fires on every destroy Step now (§4, §5, ADR-0085, issue #157).

View Source
const CodeEnvelopeExceeded = "envelope-exceeded"

CodeEnvelopeExceeded is the code a Step outside its own Procedure's declared Target and Kind envelope earns, and the code an invoked Procedure's transitive envelope reaching outside its caller's declared one earns too — one code for both shapes, checked before the first Step of either runs so composition cannot widen blast radius by accident (§4, §5, issue #96).

View Source
const CodeHeaderReserved = "header-reserved"

CodeHeaderReserved is the code drawn on the five headers hyper computes for itself — Host, Content-Length, Content-Type, Transfer-Encoding, Connection — earns wherever a second writer names one, compared case-insensitively: an Auth scheme's name: parameter and an ordinary headers: entry alike, one check with two writers (§3, §4, §12).

View Source
const CodeHoleIllegal = "hole-illegal"

CodeHoleIllegal is the code a template hole earns wherever it resolves outside its position's legal source, or stands in a position §12 does not list at all — inside an Auth scheme's parameters, the one position with no legal source at all, and a body: mapping key, which is no position at all (§3, §4, §12).

View Source
const CodeHostNotGranted = "host-not-granted"

CodeHostNotGranted is the one code over the two comparisons of a host set against the bound Target's grant (§3, §4, ADR-0024, ADR-0029, issue #98): a member of the candidate set an Operation's host: template expands to at load, and a member of an over: values: list the Step's wiring makes a host list, are the same comparison and carry the same name — a member absent from the grant, from either origin, is host-not-granted.

View Source
const CodeIdentityUndeclared = "identity-undeclared"

CodeIdentityUndeclared is the code an Operation projecting a Record and declaring no identity: for it earns — a Record's name is the value the identity field holds, and a Record with none produces one nothing can identify (§3, §4).

View Source
const CodeKindMismatch = "kind-mismatch"

CodeKindMismatch is the code a kind: disagreeing with its directory or filename is refused under (§4, §12).

View Source
const CodeKindNotGranted = "kind-not-granted"

CodeKindNotGranted is the code a Step whose bound Operation's own Kind is not in the intersection of its Definition's claimed Kind and its bound Target's accepted Kinds earns — both authored, neither derived, so a claim of "never destroys" is a fact the reviewer can trust rather than the Manifest's word for it (§4, §5, issue #95).

View Source
const CodeLocalReserved = "local-reserved"

CodeLocalReserved is the code a declaration named local earns for carrying an auth: block or a class: other than local — the two things the reserved name changes about an otherwise ordinary Target declaration (§4).

View Source
const CodeManifestInconsistent = "manifest-inconsistent"

CodeManifestInconsistent is the one code twelve decidable-from-one- Manifest shapes of a Manifest disagreeing with itself share, each pointing a reader at one file, one Operation, and two adjacent keys rather than earning a code of its own (§3, §4). The thirteenth shape — Target slot coverage — needs a (Definition, Target) binding to decide and is #93's, and the fourteenth — a candidate set and a bound Target's grant intersecting to several hosts under an Operation declaring no host-input: — needs a Step's binding and is #98's, emitted from procedure.go where that binding is read.

The twelfth of the twelve is a path: carrying a ? or a #. The ? is the two adjacent keys in the plainest form the code has — the value is in path: and it belongs in query: — and the # is the same fault with no key to move to, a fragment being a thing no request carries at all (ADR-0107, issue #229).

View Source
const CodeManifestSchemaUnsupported = "manifest-schema-unsupported"

CodeManifestSchemaUnsupported is the code a Manifest declaring a schema version above ManifestSchemaVersion earns (§4, §12).

It is spelled here, at the check that decides it, on CodeOriginDigestMismatch's own footing — and read from here by internal/cli, which names the remedy for it. One string rather than two that happen to agree.

**It is not CodeSchemaUnsupported.** That one is an *input* schema reaching outside §4's four-keyword subset, one Operation deep inside a Manifest this reader understands, and its remedy is an ordinary artefact edit. This one is the whole file in a shape this binary does not know, and its remedy is a different binary — nothing in the repository is the fault. The two read alike and share nothing else, which is why each is spelled out where it is decided rather than either reaching for the other.

View Source
const CodeNameMismatch = "name-mismatch"

CodeNameMismatch is the code an artefact's own name disagreeing with its file's basename is refused under — a Target declaration's target:, a Manifest's provider:, a Definition's definition:, and, as that artefact arrives, a Procedure's procedure: (§4, §12). It is never widened into kind-mismatch: the two disagreements send a reader to different edits.

View Source
const CodeOpaqueDestroyNotGranted = "opaque-destroy-not-granted"

CodeOpaqueDestroyNotGranted is the code a Definition claiming an opaque destroy Operation against a Target whose declaration has not opted into opaque-destroy: earns, checked per (Definition, Target) pair on CodeCapabilityNotGranted's own rule — the artefact half of the check; the credential half is resolved at Run start and belongs to §5 (§4, §5, issue #95).

View Source
const CodeOperationNotClaimed = "operation-not-claimed"

CodeOperationNotClaimed is the code a destroy Step whose Operation is not named among its Definition's destroy: claims earns — granularity follows severity, so read and mutate check at Kind level (kind-not-granted) and destroy checks by name (§4, §5, issue #95).

View Source
const CodeOriginDigestMismatch = "origin-digest-mismatch"

CodeOriginDigestMismatch is the code an installed Manifest earns when the bytes standing in providers/ are not the bytes `install` verified against the digest recorded beside them (§4, §12).

It is spelled here, at the check that recomputes it offline, and read from here by `install`, which answers the same code over the same fact at the other end of one mechanism: a fetch verifies published bytes once, and this is that verification made repeatable by anyone reading the repository, long after the machine that performed it is gone (§11). One string rather than two that happen to agree.

View Source
const CodePredicateTypeMismatch = "predicate-type-mismatch"

CodePredicateTypeMismatch is the code an operator handed a type it does not take earns — a timestamp under greater_than or less_than, an in: whose members are not all one type, exists: false, an in: of one member or none, an empty starts_with: or ends_with:, and a predicate against a field the Manifest declares secret, that field reaching the Store as a constant no comparison can read. It is the same code §6 carries for a stored value the same operator cannot compare, split on whether the fault is authored and knowable offline — this file's half — or found against a value only a Run has (§4, §6, §12, ADR-0035, issue #97).

View Source
const CodeProcedureCycle = "procedure-cycle"

CodeProcedureCycle is the code an invocation graph that closes on itself earns: a Procedure invoking one it is already inside of, directly or through a chain of any length. §6 states the graph is static and that a cycle is rejected before the first Step, and this is the walk that can state it — every procedures/ file at once, and the chain in hand as it recurses. It is cited at the invocation entry that closes the loop rather than at the Procedure the walk entered at, that entry being the line an author edits to break it (§4, §6, ADR-0002, issue #146).

View Source
const CodeRecordIdentityCollision = "record-identity-collision"

CodeRecordIdentityCollision is the code two members of one `over: values:` list that are one identity under a case-insensitive fold earn at load — the Store's own check and the Store's own code, fired here one Run earlier, against an artefact rather than a branch (§3, §4, §8).

View Source
const CodeReferenceUnresolvable = "reference-unresolvable"

CodeReferenceUnresolvable is the code the same fault earns where the namespace is what an artefact declares rather than what the repository holds — a Definition's destroy: member against the Operations its bound Provider declares, here, and, elsewhere, a Step's operation:, a field: at either Record root, and the step: half of a reference (§3, §4). A missing artefact is one the reader may have to write; a missing member is a key inside an artefact that already exists, and where that artefact is a built-in or somebody else's Extension it is not theirs to write at all.

View Source
const CodeSchemaUnsupported = "schema-unsupported"

CodeSchemaUnsupported is the code an input schema reaching outside the four-keyword subset earns — type, enum, properties, items, and nothing else (§4, §12).

View Source
const CodeSeriesReference = "series-reference"

CodeSeriesReference is the code a reference naming an earlier Step whose bound Operation's declared Record cardinality is series earns — pairing an expanding Step against a stored series is a join by identity between two Record series, and no such join is ever performed (§3, §4).

View Source
const CodeSkipIfRecordedUnreachable = "skip-if-recorded-unreachable"

CodeSkipIfRecordedUnreachable is the code a skip-if-recorded Step expanding over assets: earns: an effectful Expansion reaches only Assets whose head stands, and the value's own test skips exactly while a head stands, so every member skips on every Run and no call can ever go out — a Step refused for what it can never do rather than for what it might (§4, §5, §12, ADR-0056, issue #97).

View Source
const CodeTargetClassMismatch = "target-class-mismatch"

CodeTargetClassMismatch is the code a Definition naming a Target outside its Provider's declared class: earns (§3, §4) — a Target class only ever rejects a mismatch and never expands a Definition's reach.

View Source
const CodeTargetInconsistent = "target-inconsistent"

CodeTargetInconsistent is the code hosts: earns for disagreeing with whether capabilities: grants http — present without the grant, or the grant without it (§4).

View Source
const CodeTargetNotClaimed = "target-not-claimed"

CodeTargetNotClaimed is the code a Step binding a Target its Definition's targets: list does not name earns — its own member rather than a widening of operation-not-claimed, since a reader handed that code on a target: line would go looking at destroy:, which is the wrong edit (§3, §4, issue #95).

View Source
const KindDefinition = "definition"

KindDefinition is the one kind: value a file in definitions/ may carry (§12's kind table).

View Source
const KindProcedure = "procedure"

KindProcedure is the one kind: value a file in procedures/ may carry (§12's kind table).

View Source
const KindProvider = "provider"

KindProvider is the one kind: value a file in providers/ may carry, and the one the built-in shell Provider authors outright, having no file (§12's kind table).

View Source
const KindRepositoryDeclaration = "repository-declaration"

KindRepositoryDeclaration is the one kind: value hyper.yaml may carry — the one artefact whose file agrees with its filename rather than a directory (§12's kind table).

View Source
const KindTargetDeclaration = "target-declaration"

KindTargetDeclaration is the one kind: value a file in targets/ may carry (§12's kind table).

View Source
const ManifestSchemaVersion = 1

ManifestSchemaVersion is the highest Manifest schema version this binary reads, and the whole of the mechanism §11 states: `hyper` reads any Manifest at or below it and Refuses on one written above it (ADR-0028).

**One today, and reading *down* is built by not building anything.** There is one version, which is what the built-in declares and what every Manifest §3 illustrates carries, so there is no older shape to migrate from — and the migration path for a second is written when a second exists rather than guessed at now.

It is a compiled-in constant because that is what the fact is: *which shapes this binary knows* is answerable before any tree is walked, on IsBuiltinProviderName's own footing. And it is **one** constant read from one place because a ceiling spelled twice is two answers to *may I read this file*, one of which would be wrong the day the integer moves.

A Manifest is the one artefact carrying an explicit schema version at all, being the one authored outside this repository's own pin (§3, ADR-0023) — which is why this ceiling exists here and nowhere else in internal/artefact.

View Source
const ReservedCapability = "shell"

ReservedCapability is the one member of §12's Capability set that is reserved to the Providers hyper ships: shell, the Capability behind an opaque Operation.

It is spelled apart from BuiltinShellProviderName above, which is the same four letters standing for a different fact — one is a Provider's name and the other a Capability's, and a Manifest may take the second while renaming itself past the first, which is the whole of what a fork of the built-in is (§11).

View Source
const SecretMarker = "<secret>"

SecretMarker is the one constant a credential's position is marked with, wherever `hyper` writes a position a secret occupies (§7). §7 fixes two such positions: a Record field a Manifest declares secret, which arrives with the Store, and the Auth scheme a surface rendering a Provider composes, which is what reaches it here. One constant rather than one per position is what §7 requires — it is what keeps the Store's byte comparison honest, a rotated secret writing identical bytes — and it is why nothing here needs a credential in hand: the marker stands in the position, and the position is the scheme's (ADR-0007, ADR-0031).

View Source
const ShellCommandInput = "command"

ShellCommandInput is the one input a `shell` Operation's request is: the argv, arriving in a Step's `args:` under this name (§3, §12, ADR-0051).

The words are the Step's rather than the Manifest's — a `shell:` block carries no keys at all — so this name is the whole of the coupling between the Capability and the Procedure that supplies it, and every reading of it spells it once: the reachability check over a Manifest's inputs, the `args:` check over a Step's, the identity `$.command` fills before the call, and the Run that resolves the argv.

Variables

View Source
var DefinitionDeclaration = schema.Schema{
	Type: schema.Object,
	Properties: []schema.Property{
		{Name: "kind", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "definition", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "provider", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "kinds", Required: false, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String, Enum: []string{"read", "mutate"}},
		}},
		{Name: "destroy", Required: false, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String},
		}},
		{Name: "targets", Required: true, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String},
		}},
	},
}

DefinitionDeclaration is a Definition's own schema (§3): the definition: this file's name is checked against, the provider: it is a named, authority-scoped use of, the kinds: it claims for read and mutate — destroy is not a member, granularity following severity so a destroy claim names Operations instead — the destroy: Operations it claims by name, and the targets: it may bind, named literally rather than by class or tag. additionalProperties: false is forced rather than authored (§12), so a sixth key is unknown-key wherever it appears. A Definition carries no argument value of its own — those belong to the Step (§3).

View Source
var ManifestDeclaration = schema.Schema{
	Type: schema.Object,
	Properties: []schema.Property{
		{Name: "kind", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "provider", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "schema-version", Required: true, Schema: schema.Schema{Type: schema.Integer}},
		{Name: "class", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "capabilities", Required: true, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String, Enum: []string{"http", "shell"}},
		}},

		{Name: "auth", Required: false, Schema: schema.Schema{Type: schema.Object, Open: true}},
		{Name: "enumerations", Required: false, Schema: schema.Schema{Type: schema.Object, Open: true}},
		{Name: "operations", Required: true, Schema: schema.Schema{Type: schema.Object, Open: true}},
		{Name: "origin", Required: false, Schema: schema.Schema{
			Type: schema.Object,
			Properties: []schema.Property{
				{Name: "ref", Required: true, Schema: schema.Schema{Type: schema.String}},
				{Name: "digest", Required: true, Schema: schema.Schema{Type: schema.String}},
			},
		}},
	},
}

ManifestDeclaration is a Manifest's own top-level schema (§3): its name, an explicit schema-version — the one artefact that carries one, the repository-wide version pin not reaching its author — the class: of Target its Definitions may bind, the capabilities: it requires, the auth: scheme it authenticates with if it authenticates at all, any enumerations: its Capability-relevant holes draw on, operations: keyed by Operation name, and, on an installed Manifest, the origin: block hyper itself writes. additionalProperties: false is forced rather than authored (§12), so a sixth key is unknown-key wherever it appears.

View Source
var ProcedureDeclaration = schema.Schema{
	Type: schema.Object,
	Properties: []schema.Property{
		{Name: "kind", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "procedure", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "targets", Required: true, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String},
		}},
		{Name: "cadence", Required: false, Schema: schema.Schema{Type: schema.String}},
		{Name: "steps", Required: true, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.Object, Open: true},
		}},
	},
}

ProcedureDeclaration is a Procedure's own top-level schema (§3): the procedure: this file's name is checked against, the targets: envelope authored rather than derived, an optional cadence: whose five-field grammar checkCadence holds it to (§10), and the ordered steps: list. Each steps: entry is read at its own position, against whichever of stepDeclaration or invocationDeclaration it turns out to be — an Open object here is deliberately coarse, catching only "is this an object" so checkSteps's own dispatch is what reports a mismatched shape, never this schema reporting one first under the wrong key. additionalProperties: false is forced rather than authored (§12), so a sixth top-level key is unknown-key wherever it appears.

View Source
var RepositoryDeclaration = schema.Schema{
	Type: schema.Object,
	Properties: []schema.Property{
		{Name: "kind", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "version", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "digest", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "retention", Required: false, Schema: schema.Schema{Type: schema.Duration}},
	},
}

RepositoryDeclaration is hyper's own schema for hyper.yaml (§3): kind, version and its digest, written only by hyper project, and the retention policy that bounds Compaction, omitted meaning nothing is ever removed. Nothing else is admitted — additionalProperties: false is forced rather than authored (§12), so a fifth key is unknown-key wherever it appears. hyper.yaml carries no name key: one repository has one Repository declaration, and there is nothing to tell it apart from (§3).

View Source
var TargetDeclaration = schema.Schema{
	Type: schema.Object,
	Properties: []schema.Property{
		{Name: "kind", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "target", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "class", Required: true, Schema: schema.Schema{Type: schema.String}},
		{Name: "kinds", Required: true, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String, Enum: []string{"read", "mutate", "destroy"}},
		}},
		{Name: "capabilities", Required: true, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String, Enum: []string{"http", "shell"}},
		}},
		{Name: "hosts", Required: false, Schema: schema.Schema{
			Type:  schema.Array,
			Items: &schema.Schema{Type: schema.String},
		}},
		{Name: "opaque-destroy", Required: false, Schema: schema.Schema{Type: schema.Boolean}},
		{Name: "auth", Required: false, Schema: schema.Schema{Type: schema.Object, Open: true}},
	},
}

TargetDeclaration is the reviewed half of a Target (§3, §4): the kinds: it accepts and the capabilities: it grants, both closed sets (§12); the hosts: it grants — one list rather than a mapping keyed by Capability, since http is the only member that ever reaches one; its class:, open rather than enumerated here, a class only ever rejecting a mismatch against a Provider's own; whether it opts into opaque-destroy:; and an auth: mapping naming the environment variable each credential slot resolves from. auth: is Open: its members are credential slots the repository names itself, and checkCredentialSlots reads their insides — there is no fixed Properties list for a mapping keyed by name to enumerate.

Functions

func BuiltinShellProviderRoot

func BuiltinShellProviderRoot() *yaml.Node

BuiltinShellProviderRoot decodes BuiltinShellProviderYAML and returns its document root, so that the one decode of hyper's own bytes is written here rather than reimplemented at each caller: CheckBuiltinShellProvider, builtinShellProviderInfo (issue #93) and the repository load (issue #109), which carries the built-in as an artefact like any other and needs a root to carry (ADR-0039). It is exported for the third of those.

Each call decodes afresh, which is why the constant and not the node is what the callers share. That is sound only because the subject is a compiled-in constant no repository author can touch: two decodes of immutable bytes cannot disagree, where two reads of one file could. Nothing here may be reused for an artefact that came off disk.

func CheckBuiltinShellProvider

func CheckBuiltinShellProvider() []problem.Problem

CheckBuiltinShellProvider validates BuiltinShellProviderYAML against every check CheckManifest runs except the three that read a Manifest against where it was loaded from — kind-mismatch has no directory to compare against and name-mismatch no basename, the built-in authoring its name outright and having no file at all, and capability-reserved is §11's rule about a Manifest in providers/, which this is not (§3, §11). It is checked like any other Manifest, with no exemption: a Provider is data, and data check may not read is an advisory analyzer wearing the tool's own badge.

The three are absent because the function they live in is never called for these bytes, rather than because a branch inside it lets them through. An exemption would be the thing §11 does not have: the built-in is entitled to the Capability for being compiled in, and *compiled in* is the whole of the criterion (ADR-0039, ADR-0073).

func CheckDefinition

func CheckDefinition(file string, root *yaml.Node, providers ProviderIndex, targets TargetIndex) []problem.Problem

CheckDefinition validates a definitions/ file's already-parsed root against DefinitionDeclaration and every check that reads a Definition on its own (§3, §4, issue #93): kind: against definitions/, definition: against the file's basename, and the two-keys rule. providers and targets are the repository-wide namespaces provider:, targets: members and destroy: members resolve against, and the per-pair checks that need a binding. root is nil where the file parsed to no document at all; the schema check still runs and reports every required key the file never supplied.

func CheckManifest

func CheckManifest(file string, root *yaml.Node, manifest []byte) []problem.Problem

CheckManifest validates a providers/ file's already-parsed root against ManifestDeclaration and every check that reads a Manifest against itself (§3, §4, §12, issue #91): kind: against providers/, provider: against the file's basename, and checkManifestBody's grammar checks. root is nil where the file parsed to no document at all; the schema check still runs and reports every required key the file never supplied.

It is also where §11's two rules about a Manifest **loaded from providers/** run, and the placement is the criterion: what capability-reserved and origin-digest-mismatch are about is where the file came from, which is what calling this function already means — artefactChecks routes the built-in to CheckBuiltinShellProvider and every providers/ file here (issues #186, #189).

manifest is the exact bytes root parsed from, which the load keeps beside every artefact for manifest_digest's reason and for `operation`'s (§7, §9, internal/repository). It stands where every sibling check's extra arguments stand, after the artefact's own two: it is what this check needs **beyond** the parse tree rather than a second spelling of it — the digest an installed Manifest records covers a byte range of the file, which is not a thing a parse tree holds (§11, manifest_origin.go).

**One check stands ahead of all of them and replaces them.** A Manifest declaring a schema version above the one this binary reads is one code and nothing else, this reader having no claim on the shape of the keys beneath it (§11, ADR-0028, manifest_schema.go). It is written as a return rather than as a suppression each check consults, which is the same argument the drop in withReservedCapability makes one row at a time: a check that has to know it is reading a partially understood file is the shape §11 warns about.

func CheckProcedure

func CheckProcedure(file string, root *yaml.Node, providers ProviderIndex, definitions DefinitionIndex, targets TargetIndex, procedures ProcedureIndex) []problem.Problem

CheckProcedure validates a procedures/ file's already-parsed root against ProcedureDeclaration and every check that reads a Procedure against itself and the repository (§3, §4, issue #94): kind: against procedures/, procedure: against the file's basename, and each steps: entry against whichever shape it turns out to be. providers, definitions and procedures are the repository-wide namespaces a Step's operation: and definition:, and a nested invocation's procedure:, resolve against; targets is the namespace this Procedure's own declared targets: list resolves against, read here into the declared Target and Kind envelope every Step directly in this file is checked against (envelope-exceeded, §4, §5, issue #96). The transitive half of that same walk — an invoked Procedure's own envelope against its caller's, and the two Cadence rules that ride the same walk — needs every procedures/ file at once and is CheckProcedureGraph's (issue #96). root is nil where the file parsed to no document at all; the schema check still runs and reports every required key the file never supplied.

func CheckProcedureGraph

func CheckProcedureGraph(graph ProcedureGraph) []problem.Problem

CheckProcedureGraph walks graph and reports the rules that need every procedures/ file at once (§4, §5, issues #96, #146): the graph closing on itself — a Procedure invoking one it is already inside of, which is procedure-cycle and is collected first, being the one fault about the shape of the graph rather than about anything reachable through it (what order a surface renders it in is problem.Sort's, over the file and line every row carries); an invoked Procedure's own transitive envelope reaching outside its caller's declared targets: — the composition half of envelope-exceeded, cited at the invocation that makes the composition, procedure.go's own file-local checks having already covered a Step directly in a file reaching past its own Procedure's declared envelope — and, on a Procedure declaring a Cadence, a reachable run-once Step (cadence-run-once) or a reachable Step whose Operation declares secret: output (cadence-secret-output), each cited at the cadence: line of the Procedure declaring the recurrence rather than wherever in the graph the fact was read, since that line is the one an author can act on: narrow the Cadence away, or edit the Step.

func CheckRepositoryDeclaration

func CheckRepositoryDeclaration(file string, root *yaml.Node) []problem.Problem

CheckRepositoryDeclaration validates hyper.yaml's already-parsed root against RepositoryDeclaration and its kind:. root is nil where the file parsed to no document at all (yamlsubset.Parse's ok=true, root=nil case); the schema check still runs and reports every required key hyper.yaml never supplied.

func CheckTargetDeclaration

func CheckTargetDeclaration(file string, root *yaml.Node) []problem.Problem

CheckTargetDeclaration validates a targets/ file's already-parsed root against TargetDeclaration and the four checks that read this artefact against itself: kind: against targets/, target: against the file's basename, every credential slot's shape, local's two reserved rules, and hosts: against capabilities: (§3, §4, issue #90).

func DeclaredName

func DeclaredName(root *yaml.Node, key string) string

DeclaredName is the name an artefact declares for itself: the scalar under the top-level key its kind names itself with — definition:, procedure:, provider: or target: — and "" where that key is absent, carries something other than a plain scalar, or the file did not parse at all.

It is one reader for the four because the four kinds name themselves by one rule and differ only in the word (§3, §12). The rule it holds is the one every name in the repository resolves by: a name is matched against what the artefact declares rather than against its filename, so a case-insensitive filesystem cannot decide what resolves and what does not (§9, ADR-0060). A key the artefact never wrote answers nothing rather than guessing, which is ADR-0064's rule — what is wrong with an artefact is check's to report and never a reader's to substitute for. Only top-level keys are read: a Step's own definition: is a Step's, and no artefact is named by a key nested inside it.

The two named readers beside it — ManifestProviderName and TargetDeclarationName — are this reader under the key each of them fixes, and they keep their names because a caller folding the Provider namespace is asking for a Provider's name rather than for a key's scalar (issue #118).

func IsBuiltinProviderName

func IsBuiltinProviderName(name string) bool

IsBuiltinProviderName says whether name is a built-in Provider's, which is §12's built-in set read as the thing it doubles as: **the list of names no Extension may take** (provider-name-collision, §11).

One member today, and the set grows only where the reserved half of the Capability set grows — hyper ships a Provider only where the Capability it needs is one nobody else may declare (ADR-0039). It is enumerated against the binary's own constants rather than derived from the loaded repository because that is what the set is: a fact about what this binary compiles in, answerable before any tree is walked.

**It is one predicate because two readers of the set would be two answers.** The fold declines a colliding Manifest and the check names it, and a name the fold declined and the check said nothing about is a file that vanished from the namespace with no row to explain it.

func IsReservedCapability

func IsReservedCapability(name string) bool

IsReservedCapability says whether name is a Capability no Manifest loaded from providers/ may hold, declared or derived (capability-reserved, §11).

**One member, and http is not it.** §12 closes the Capability set at two and reserves exactly one: http describes what it does and shell cannot describe anything, so what an Operation cannot describe and who may write one are one fact (ADR-0004). A third party can never ship a Provider that runs commands on your machine, and that sentence is this predicate.

**It is closed by the same criterion that closes the built-in Provider set, and neither grows without the other.** hyper ships a Provider only where the Capability it needs is one nobody else may declare (ADR-0039), so a new reserved member is a new built-in and a new built-in is a new reserved member — which is why this predicate stands beside IsBuiltinProviderName rather than in the file that reads capabilities: off a Manifest.

func ManifestDigest

func ManifestDigest(bytes []byte) string

ManifestDigest is manifest_digest: SHA-256 over a Manifest's exact bytes, with sha256: inline because hyper chose the algorithm (§7). The bytes are the file in providers/ for an Extension and the compiled-in constant for the built-in, which has no blob in the repository at all.

Over the bytes rather than a canonical form of what they parse to, because a second digest of one Manifest is a second representation that can disagree with the one `install` verified, and because a reader checks bytes with sha256sum and a canonical form only where something has written that form out for them. Reformatting a Manifest moves it, and moves every later Record's Provenance with it — correct rather than noisy: the reviewed artefact moved.

It is never abbreviated by anything that renders it (§8, ADR-0047): a digest is verified with sha256sum rather than recognised by eye, so a shortened one is a value the reader has to go somewhere else to complete.

func ManifestProviderName

func ManifestProviderName(root *yaml.Node) string

ManifestProviderName is the name a Manifest declares for itself, or "" where its provider: is absent or is not a plain scalar. It is exported because the Provider namespace is not the only thing folded over that rule: `hyper providers` writes one row per member of that namespace and needs the bytes each name loaded from, which the index does not carry (§9, issue #111) — and two folds of one rule written twice is where the day comes that a name is in the namespace and not on the list.

func ManifestProviderNamePosition

func ManifestProviderNamePosition(root *yaml.Node) (line, column int)

ManifestProviderNamePosition is where that name is written — the line and column of the `provider:` scalar — for the one check that reports against a Manifest it did not itself read: `provider-name-collision`, whose subject is the Provider namespace and whose row still lands on the scalar its author has to edit (§4, §11, internal/verify).

It stands beside ManifestProviderName rather than at its caller for that reader's own stated reason: the key a Provider names itself under is spelled once, here, so a caller asking where the name is written is asking about a Provider's name rather than about a key's scalar (issue #118).

func ManifestSchemaUnsupported

func ManifestSchemaUnsupported(root *yaml.Node) bool

ManifestSchemaUnsupported says whether root declares a schema version above the one this binary reads — the predicate **both halves of the rule read**.

The check below names the file and the load declines it: a Manifest above the ceiling contributes nothing to the Provider namespace, which is the mechanism `provider-name-collision` introduced one rule over (internal/repository's manifestsByName, internal/verify's collisionProblems). One predicate rather than two readings, for that rule's own reason: a name the fold declined and the check said nothing about is a file that vanished from the namespace with no row to explain it.

A root carrying no legible schema-version at all is **not** unsupported here. What this answers is *is this version above mine*, and a file that declares no version has already earned schema-mismatch from a schema that requires one — so it is checked like any other Manifest and its faults are its own.

func OperationNode

func OperationNode(root *yaml.Node, name string) *yaml.Node

OperationNode is the node one Operation of a Manifest is declared by, and nil where the name is not a key of a legible operations: block — the same lookup OperationSource performs over the same mapping, matching byte-exact as every name in the tool does (§9, ADR-0060).

It is exported because where an Operation is declared is this package's fact and what its declaration *means* is not: internal/capability reads the http: block out of one and internal/projection reads the record: block, and neither has any business knowing that an Operation lives under a Manifest's operations: key. One lookup, three readers, and a Manifest's own shape spelled in one place (issue #135).

func OperationSource

func OperationSource(manifest []byte, root *yaml.Node, name string) (string, bool)

OperationSource is the Manifest lines declaring one Operation, verbatim: a range of the file's own bytes, taken from the Operation's key line through the last line of its mapping, with the comment above the key included and the blank lines after it trimmed.

It is the one reader here that answers with bytes rather than with facts, and that is the whole of why it exists. A Manifest is written in the format the caller is expected to author Definitions in (§3), so handing the lines back unchanged teaches that format at the moment the caller needs it — and §12 closes the identity: `operation` writes these lines back unchanged, and what a reviewer reads is what manifest_digest covers. A re-encoding that produced equivalent YAML would break that silently, the digest still being right over bytes the reviewer never saw. So nothing here parses a value, re-indents a line or re-wraps one: the parse tree is read for where the range is and the bytes are copied out of the file.

manifest is the exact bytes root parsed from, which is what the load keeps beside every Manifest for this reason and for manifest_digest's (§7). Passing the pair rather than re-reading the file is what makes the built-in shell Provider answerable at all: it has no file, and its bytes are the constant compiled into the binary (§12, ADR-0039).

It finds nothing where the name is not a key of a legible operations: block, which is the lookup a usage error is written off (§9, ADR-0060), and where the Manifest has no such block to look in at all — what is wrong with it is check's to name and never this reader's to guess at (ADR-0064).

func ProcedureCadence

func ProcedureCadence(root *yaml.Node) string

ProcedureCadence is the recurrence a Procedure declares, exactly as it was written, and "" where it declares none. It is DeclaredName's reader under the key this one fixes — a caller asking for a Cadence is asking for a Procedure's recurrence rather than for a key's scalar, and a Cadence is a Procedure's alone: a key of that name on any other artefact is not one.

It reads and does not judge. Whether the expression is one §10's grammar admits is the gloss's question to answer and `cadence-malformed`'s to refuse, and neither is this reader's (§10, §12).

func ProviderOrigin

func ProviderOrigin(path string) string

ProviderOrigin reads a loaded Manifest's origin off the path its bytes came from, which is the whole of §12's criterion. The pseudo-path the built-in carries is the one that answers built-in — hyper ships a Provider only where nobody else could write it, so that set is closed and enumerated with the paths (ADR-0039) — and every other Manifest hyper can load is a file in providers/, whether it arrived by `hyper install` or was typed there by hand: an Extension is a Provider authored by someone other than hyper rather than one fetched from a registry.

func SourceLines

func SourceLines(source []byte) []string

SourceLines is a file's own lines, in order, each without the newline that ended it: the numbering §8 states for a review, counted from one over every line including blank ones, and the bytes the working tree holds on each of them.

It is the whole-file reading of the index OperationSource takes a range out of, and it is that index promoted rather than a second one written beside it (issue #118). `operation` copies the lines declaring one Operation and a review copies all of them; both are the file's own bytes cut at its own newlines, and two readers of one file must not be able to disagree about where a line begins — a review's line numbers are what its citations resolve against, and `operation`'s range is what a reviewer's digest covers.

Nothing is re-encoded on the way through. A line's leading indentation, its trailing spaces and a carriage return an editor left before the newline are the artefact's own bytes and are handed back as they were read; what is taken off is the one byte that says where the line ended. A file whose last line carries no newline has the same lines as one whose editor wrote one, and an empty file has no line at all — zero documents is valid YAML, and a review of nothing is not a review of one blank line.

func TargetDeclarationName

func TargetDeclarationName(root *yaml.Node) string

TargetDeclarationName is the name a Target declaration declares for itself, or "" where its target: is absent or is not a plain scalar. It is exported for ManifestProviderName's own reason: the Target namespace is not the only thing folded over that rule — the load folds each name to the declaration it came from, so `hyper targets` and a Definition's targets: resolve one name to one declaration by construction rather than by two folds agreeing (§9, issue #112).

func TopLevelKeyLine

func TopLevelKeyLine(root *yaml.Node, name string) int

TopLevelKeyLine is the line root's own top-level key of that name is written on, and 0 where it writes none. It is topLevelFields' other half: that walk answers with a key's value and this one with the key itself, which is what a surface annotating a *line* needs — §8 marks the targets: line, and a block sequence's first member is a line below the key that names it.

It is exported for the one surface that reports a fault against an artefact it did not check: a Probe's host is refused against the hosts: the Target named local declares, and a Refusal names the line to edit (§9, ADR-0042). Every other caller of it here is a mark or a check that already holds the node.

Types

type AbsentName

type AbsentName struct {
	Key      string
	Name     string
	Provider string
}

AbsentName is the name that resolved to nothing on a Step the gutter marks unresolved: the key it was written under — definition, operation, provider or procedure — the name it named, and, where the key is operation, the Provider whose Manifest it was looked for in.

Name is "" where the key carried nothing legible to resolve at all, which is a different absence from a name that resolved to nothing and is why the name is carried rather than assumed present.

The key is the authoring format's own, and provider is one of the four although no Step writes it: a Step's definition: resolves and the Definition it found names a Provider that does not, which is a name on the Step's own line failing one hop out (§3, §4).

type Authority

type Authority struct {
	Definitions map[string]DefinitionFacts
	Targets     map[string]TargetFacts
}

Authority is the supply behind §8's `AUTHORITY` table: the two namespaces the relation is read across, each keyed by the name its artefact declares for itself.

It is one relation and not two tables. §5's authority rule is an intersection — a Definition claims Kinds and Targets, a Target declaration accepts Kinds — and an intersection privileges neither operand, so the artefact under review supplies one end of it and which end decides the filter and nothing else (ADR-0069). Three of the five artefacts supply an end and two are members of no pair at all.

Both maps are the load's own folds, so the Definition a name means here and the Definition a Step's definition: resolves to are the same file rather than two walks agreeing (issue #109). A name absent from either is a name that resolved to nothing — which covers a file that is not there and one that is there and will not parse alike, the two differing in nothing this table can act on (ADR-0064).

func (Authority) Table

func (a Authority) Table(kind string, root *yaml.Node) AuthorityTable

Table is the relation on the artefact under review: the pairs its end of it supplies, each read across both namespaces, sorted.

kind is §12's own kind: value, read off the load's path by the caller rather than off this file's key: a file whose directory and kind: disagree is a load error §12 already names, and the filter follows what the artefact is read as.

The artefact under review supplies its own end from root, which stands in the namespace for the length of this rendering. The two agree in every repository a check passes on, and where two files declare one name they do not: what a review states is the file it was pointed at.

type AuthorityRow

type AuthorityRow struct {
	Definition        string
	Target            string
	DefinitionKinds   []string
	TargetKinds       []string
	Effective         []string
	DestroyOperations []string
}

AuthorityRow is one pairing as the table states it: which Definition, which Target, what each claims and accepts, their intersection, and the `destroy` Operations the Definition names (§5, §8).

The three Kind lists carry full names and never the page's initials. The initials are a notation this screen renders an intersection in and the names are the values, exactly as `envelope ✓` and `"envelope ok"` are one fact in two notations (§8, ADR-0026).

DefinitionKinds carries `destroy` where the Definition's destroy: names any Operation, derived at that one position rather than read. §3 keeps `destroy` out of kinds: precisely so this column can derive it, granularity following severity (§8).

A list is nil where its end of the pairing has no supply and non-nil otherwise, empty included — and that one encoding is the whole of what says so, a second boolean beside it being a fact stated twice. A Definition that claims no Kind at all claims none, where one that did not load claims nothing this table can read: the page renders the first as an em dash and the second as §8's `unresolved`, and a supply that resolved to nothing and one that resolved to something unreadable are the same absence here.

Effective is the intersection, in the Definition's own claim order: §5's check reads a claim against a grant, so the claim is the operand the intersection is ordered by. It is nil where either end lacks a supply.

type AuthorityTable

type AuthorityTable struct {
	// Renders is false on the two artefacts that are members of no pair — a
	// Manifest, whose Operations declare the Kinds a Definition *may* claim
	// rather than claiming any, and a Repository declaration, which pairs
	// with nothing. On those the table is absent entire rather than empty.
	Renders bool
	// Discovered is true where the row set is discovered across
	// definitions/ rather than authored in the artefact under review, which
	// is the one filter a file that did not load can silently remove a row
	// from. It is why a discovery failure is counted beneath the table on
	// that artefact and nowhere else (ADR-0069).
	Discovered bool
	Rows       []AuthorityRow
}

AuthorityTable is the relation on one artefact: whether it renders at all, whether its row set was discovered rather than authored, and the rows.

The three travel together because a caller needs all three to render the block and no two of them are separable: a table that does not render has no rows and no discovery to have failed, and an empty table means one thing where an edit could produce a row and another where none could (§8).

type ChangeFact

type ChangeFact struct {
	// Key is the key the fact is written at — `kinds`, `targets`,
	// `destroy`, `capabilities`, `operations`, `cadence`, `target`, `over`,
	// `bound` — or, for the credential source, the slot it belongs to
	// spelled as §8's own `credential <slot>`.
	Key string
	// Step is the id of the Step this fact belongs to, and "" where the
	// subject is the artefact itself. It is the coordinate a flag citing the
	// fact carries, and the identity the two sides of a range are paired on:
	// a Step on one side only has no before-and-after of its own.
	Step string
	// SubjectLine is the line the fact's subject opens on — a Step's own
	// `- id:`, or the artefact's first line where the subject is the
	// artefact. It is the anchor of last resort for a citation, and it is a
	// line the gutter marks on every Step there is (§8).
	SubjectLine int
	// Lines are the lines the fact is written across: the key's own, and
	// each line a member of the value stands on. They are what a citation is
	// chosen from — a flag cites the line carrying its subject, and where a
	// fact spans a block the line that moved is the one carrying it.
	//
	// It is empty where the artefact writes no such key, which is a fact
	// stated by omission and rendered `–` (§8).
	Lines []int
	// Shape is what the value is, which decides both what a row renders and
	// what makes two readings of it differ. It follows the value at the row
	// and never the class above it, which is why it is a member here rather
	// than a fact about the key: the Target set class alone carries a set
	// for a Procedure's envelope and a scalar for the `target:` a Step binds
	// (§8).
	Shape FactShape
	// Members are a set's members or a selector's, in the order a row
	// renders them: sorted by Unicode code point wherever the fact compares
	// as a set, and as authored for a `values:` selector, whose order *is*
	// the fact (§6, §8).
	Members []string
	// Value is a scalar's text as the artefact wrote it, and a selector's
	// form name — `values`, `assets` or `observations`. A cell dropping the
	// form could not tell an `assets` selector from an `observations` one,
	// which is the difference between ranging over what `hyper` built and
	// over what it read (§5, §8).
	Value string
	// Wire is the value as §8's row stream carries it: **the artefact's own
	// parsed shape**, in the order the page renders it, and nil where the
	// artefact states the value by omission — the absence the page renders
	// `–` and the wire states by writing no member at all.
	//
	// It is here rather than composed by a renderer because the page's
	// notation is that chapter's geometry and never a fact either surface
	// states (ADR-0059): a ` · `-separated run and a `field operator
	// operand` line are renderings, and a reader composing the wire out of
	// them would have to parse its own rendering back — and could not, an
	// `in:` list and a bare operand rendering alike once a conjunct is one
	// line of text (fact_wire.go).
	Wire json.RawMessage
}

ChangeFact is one `(subject, fact)` pair as one artefact's own lines carry it: which key it is written at, which subject inside the artefact it belongs to, where it is written, and the value.

A class emits one row per pair rather than one row, so a Definition's claimed Kinds and the `destroy` Operations it names are two facts under one class (§12). The class names are the grouping and reach no screen: what a row names is the key, which is what a reader greps for and what the gutter marks.

func ReadChangeFacts

func ReadChangeFacts(kind string, root *yaml.Node) []ChangeFact

ReadChangeFacts is one artefact's facts, in the order its own lines carry them.

A **Repository declaration** answers none, and that is the enumeration holding rather than a roster left short: its `version:` is the pin, which is `the digests`' `hyper_version` and has no class here, and its `retention:` is one of the lines §12's catch-all counts. Both move on a review's screen — the change column marks them like any other line — and neither is a fact this vocabulary names (§7, §12).

func (ChangeFact) Same

func (f ChangeFact) Same(other ChangeFact) bool

Same reports whether two readings of one fact are the same fact, which is what decides whether a row is emitted at all. **A fact that did not move emits no row, however its bytes moved**: a reordered set moves the file and moves nothing this reports, which is the comparison being by the fact's own equality and never by the text (§8, §12).

func (ChangeFact) Written

func (f ChangeFact) Written() bool

Written reports whether the artefact writes this fact at all. A fact with no line is one stated by omission — an absent `bound:` being unbounded, an absent `over:` a Step invoked once, an absent `cadence:` no recurrence — and what renders in its place is `–` rather than a naming of what the absence means, which is a claim and not a value (§8).

type CredentialSlot

type CredentialSlot struct {
	Slot string
	Env  string
	// Line is the 1-indexed line the slot's own key is written on, which is
	// what §8 says `credential-absent` cites: the `env:` line of the Target
	// declaration whose slot the environment did not fill. A row reporting a
	// Target's credentials has never asked for it and does not read it; a
	// Refusal has to, an absence with no coordinate being a search rather
	// than an edit (§8).
	Line int
}

CredentialSlot is one member of a Target declaration's auth: mapping as a surface reports it: the slot the repository named, and the environment variable that slot resolves from. The variable's name and never its value — nothing hyper writes has ever held a secret, and the pair exists so that a declaration carrying slots for more than one scheme says which fills what (§3, §9, ADR-0007).

Env is empty where the slot names no variable, which is a slot whose value is not the mapping whose sole key is env: that §4 fixes. The slot is still a slot the declaration carries, so it is still reported; what is wrong with it is credential-slot-malformed, which is check's to name (ADR-0064).

type DefinitionFacts

type DefinitionFacts struct {
	Kinds   []string
	Destroy []string
	Targets []string
}

DefinitionFacts is what a Definition claims, in the shape a surface reports it: ordered lists rather than the membership sets DefinitionInfo carries.

It is ReadTargetFacts's other end. The two readings are one artefact read for two questions: a check asks *does this Definition claim that Kind*, which is a set, and a row states *what does this Definition claim*, which is an enumeration answered in the file's own order — a claim silently reduced or re-sorted is not the claim the reviewer has open beside it (§3, §5, §8).

Targets is every member of targets: as written, including one that resolves to no declaration. DefinitionInfo.Targets drops those, a check having nothing to check them against; a row may not, a Definition claiming three Targets and rendering two rows saying the third was never claimed (§8, ADR-0064).

Each list is nil where its key is absent, which is the ordinary absence rule a reader reads off it (§7): a Definition claiming no `destroy` Operation carries no destroy: at all.

func ReadDefinitionFacts

func ReadDefinitionFacts(root *yaml.Node) DefinitionFacts

ReadDefinitionFacts reads those three facts off a Definition's own root. It judges none of them, on ReadTargetFacts's own rule: a Definition naming a Kind outside the closed set, or a Target that is not there, states what it states here and earns its problem from check (ADR-0064). What it drops is what it cannot read — a list member that is not a plain scalar has no value to report.

type DefinitionIndex

type DefinitionIndex map[string]DefinitionInfo

DefinitionIndex maps a definitions/ file's own definition: to what a Step binding it is checked against — a Step's definition: resolves against this namespace (§3, §4, issue #94).

func BuildDefinitionIndex

func BuildDefinitionIndex(definitionRoots []*yaml.Node, targets TargetIndex) DefinitionIndex

BuildDefinitionIndex adds one entry per definitions/ root whose definition: is a legible scalar, on BuildProviderIndex's own rule. targets is the namespace a targets: member resolves against — the same TargetIndex CheckDefinition's own per-pair checks read — so a member that does not resolve there contributes nothing to DefinitionInfo.Targets, CheckDefinition having already named that fault on the Definition's own line (ADR-0064). An entry whose provider: is absent or illegible carries ProviderName "" — a Step naming this Definition resolves no Operation against an empty provider name, which is reference-unresolvable on the same rule as any other name that does not resolve.

type DefinitionInfo

type DefinitionInfo struct {
	ProviderName string
	Kinds        map[string]bool
	Destroy      map[string]bool
	Targets      map[string]TargetInfo
}

DefinitionInfo is what checking a Step against the Definition it binds needs, read once per repository pass rather than reparsed per Step that names it (§3, §4, §5, issue #95): the provider: it names, unresolved — a Step's operation: and args: are checked against a second lookup, into ProviderIndex, once ProviderName has resolved; the Kinds it claims via kinds: — read and/or mutate, the claim half of the two keys; the Operations it claims for destroy:, by name — the same set both operation-not-claimed and the destroy half of ClaimsKind read; and the targets: it claims, resolved against TargetIndex and keyed by name — the namespace a Step's target: resolves against and nothing wider (§4), and the source of the Kinds a Step's bound Target grants.

func (DefinitionInfo) ClaimsKind

func (d DefinitionInfo) ClaimsKind(kind string) bool

ClaimsKind reports whether this Definition's own claim covers kind — membership in kinds: for read and mutate, and a non-empty destroy: for destroy, granularity following severity the same way the Step-level check against it does (§4, §5, issue #95).

type DefinitionMarks

type DefinitionMarks struct {
	Kinds, Destroy, Targets KeyMark
}

DefinitionMarks is §8's roster on a Definition: the Kinds it claims, the `destroy` Operations it names, and the Targets it may bind, each beside the line that makes the claim.

All three are authored in the file being read, which is the whole of why a Definition's `provider:` carries no mark: this screen annotates what `hyper` derived from these lines, and nothing it derived reaches a Manifest (§8).

func ReadDefinitionMarks

func ReadDefinitionMarks(root *yaml.Node) DefinitionMarks

ReadDefinitionMarks reads those three off a Definition's own root. The values are ReadDefinitionFacts's, so the Kinds the gutter marks and the Kinds `AUTHORITY` states are one reading of one artefact rather than two that agree; what this adds is the line each of them is written on, which is the anchor a mark needs and a row does not (§8).

type FactShape

type FactShape int

FactShape is what a fact's value is, which decides both how a row renders it and what makes two of them differ (§8). It is the shape of the value at the row and never the class above it: the Target set class alone carries a set for a Procedure's envelope and a scalar for the `target:` a Step binds.

const (
	// FactSet is a set of names, comparing by set equality: declared Kinds,
	// a Target set, required Capabilities, the Operations a Manifest
	// exposes, a Definition's `destroy:` claim. It is the shape a direction
	// is decidable on by inclusion, which is why the rule is quantified over
	// the shape rather than listed over the classes (§12).
	FactSet FactShape = iota
	// FactBound is a Step's `bound:`: a magnitude, comparing numerically,
	// and the one scalar a direction is decidable on.
	FactBound
	// FactScalar is a scalar no direction is available for — a Step's
	// `target:` and a credential slot's variable. It takes `changed` and its
	// full before-and-after text.
	FactScalar
	// FactCadence is a Procedure's declared recurrence: a scalar under the
	// shape rule and a stacked cell under the mandatory gloss, which are two
	// rules meeting in one place and neither is the other (§8, §10,
	// ADR-0005, ADR-0063).
	FactCadence
	// FactSelector is a Step's `over:`, in any of its three forms. It takes
	// `changed` however it moved: predicate subsumption is undecidable in
	// general, so a surface calling `equals: preview` → `starts_with:
	// preview-` a widening would be inventing the one thing it may not
	// invent (§12).
	FactSelector
)

type HostReach

type HostReach struct {
	Reach   Reach
	Host    string
	Granted int
}

HostReach is where a call goes, and why it goes nowhere.

Host is the host the call reaches under ReachGranted, and under ReachNotGranted the host it *would* have reached — the value the input carried, or the first candidate the template expanded to — so a Refusal can name what was asked for. It is "" where nothing named one at all, which is `{from-target}` against a grant with nothing in it: the grant is the only thing that could have named a host, and it named none.

Granted is how many hosts the candidate set and the grant intersected to, and is read only under ReachUndecidable, that being the count above one.

func ResolveHost

func ResolveHost(provider ProviderInfo, operation OperationInfo, target TargetInfo, suppliedHost string) HostReach

ResolveHost walks ADR-0029's three steps at invocation rather than at load. suppliedHost is the value of the input the Operation's `host-input:` names, and is ignored where it names none — which is where a Probe's `--input` and a Step's `args:` arrive at one function: both supply the Operation's inputs, and neither can name a host the grant does not hold.

The two arms are §3's own, and they do not consult the same thing. Where the Operation declares `host-input:`, the input **always carries a whole host** and *the value that input carries is checked for grant membership like any other* — an enumeration hole being a compact way of writing a large candidate set rather than a second thing filled at Run time, and the candidate set having done its work at load, where the grant was checked against it. Where it declares none, the intersection decides and `hyper` fills the one host it resolved to.

type InputInfo

type InputInfo struct {
	Type string
	Enum []string
}

InputInfo is what checking a Step's args: value against one Operation input needs: the type: it declares, read the way an argument's own type is — object and array are the two a reference may never fill (§3, §4) — and the enum: its value is checked against, nil where the input declares none.

type KeyMark

type KeyMark struct {
	Line   int
	Values []string
}

KeyMark is one top-level key's own line and what `hyper` derived from what it carries: the line the key is written on, 0 where the artefact writes no such key, and the derived values in the artefact's own order.

The values are the fact and not the marker: which of them is upper-cased, what stands in front of them and how they are separated is §8's vocabulary and the rendering surface's to compose, exactly as a StepMark's Kind is (§8).

Values is empty on a key that is written and yields nothing — a `hosts:` that is not a list of scalars, an `auth:` naming neither of §12's two schemes. That is a line with no derived fact rather than a fact that is empty, and the two are one thing to every surface: nothing was derived, so nothing is marked.

type ManifestFacts

type ManifestFacts struct {
	AuthScheme    string
	Capabilities  []string
	SchemaVersion *int
	OriginRef     string
	OriginDigest  string
	Operations    []OperationFacts
}

ManifestFacts is what a Manifest declares about itself, in the shape a surface reports it — `hyper provider`'s header row, which exists to state what a Manifest declares (§9).

It is ReadTargetFacts's counterpart and stands beside ProviderInfo for ProviderInfo's own reason: one artefact read for two questions. A check asks *may this Definition bind that Provider*, which is a set of memberships; a row states *what does this Manifest declare*, which is an enumeration and the composition an Auth scheme writes. Neither reading judges the artefact — a Manifest that declares a Capability outside the closed set states what it states here and earns its problem from check (ADR-0064).

AuthScheme is the header the Manifest's scheme composes, with the credential's position marked; the word §12 fixes for a Manifest carrying no auth: block, and "" where it carries one `hyper` cannot read as a scheme — which is a schema fault check names, and not an absence of authentication a row may report as one.

SchemaVersion is a pointer because the Manifest's own schema-version: is an integer and a Manifest that wrote something else has stated no version at all: 0 would be an answer to a question nothing asked, and the ordinary absence rule is what a reader reads off its absence (§7).

OriginRef and OriginDigest are the origin: block's two members, both empty where the block is absent — a built-in Provider and a locally authored Extension alike, which together are the whole of what distinguishes an installed Extension from one an author wrote (ADR-0073).

Operations are in the Manifest's own order, which is the order they were authored in. The normative order a listing is ranged over in is the surface's rule and is applied there: `hyper operation` writes a Manifest's declaring lines back verbatim, so the authored order is preserved exactly where it is the answer (§9).

func ReadManifestFacts

func ReadManifestFacts(root *yaml.Node) ManifestFacts

ReadManifestFacts reads those facts off a Manifest's own root. Like ReadTargetFacts it judges nothing and drops what it cannot read: a member this returns empty is a member the Manifest did not legibly state, which is check's to report and never this reader's to guess at (ADR-0064).

The digest is not here: it is SHA-256 over a Manifest's exact bytes and not over what they parsed to (§7), so it is ManifestDigest's and is taken over the bytes the load kept.

type ManifestMarks

type ManifestMarks struct {
	Auth, Capabilities KeyMark
	Operations         []OperationMark
}

ManifestMarks is §8's roster on a Manifest: the Auth scheme it names, the Capabilities its Operations require, and one entry per Operation.

func ReadManifestMarks

func ReadManifestMarks(root *yaml.Node) ManifestMarks

ReadManifestMarks reads that roster off a Manifest's own root, the built-in's compiled-in bytes included: what the load handed this reader is a parsed root, and where those bytes came from is the header's fact and not a mark's (§8, §11, ADR-0039).

Every Operation is read through operationInfoFromNode, which is the reading every check makes of the same entry, so the Kind the gutter marks and the Kind a Step is refused against are one read of one artefact (§4, §9).

type OperationDetail

type OperationDetail struct {
	Capabilities      []string
	Bound             string
	PatternsResolved  []string
	RecordCardinality string
	RecordIdentity    string
	Repeatability     string
	Deadline          string
	DeadlineSeconds   *int
	ConcurrencyLimit  int
}

OperationDetail is the derived half of `hyper operation`'s answer: the facts the Manifest's own lines do not carry in that form, computed once here so that no caller re-derives what `hyper` already has (§9).

It stands beside the source rather than instead of it. The source teaches the format a caller is expected to author Definitions in, and this states what reading that format would otherwise cost — which Capability the request is written under, whether a Bound is mandatory, illegal or moot, and the three facts an Operation states by omission.

Capabilities carries the one Capability the Operation's request is written under — an Operation uses exactly one (§12) — and is empty where the request block names neither Capability or names both, which is schema-mismatch from `check` and never a Capability this reader may pick between (ADR-0064).

Bound is one of the three members above, and "" where kind: is not one of the three Kinds: the fact is read off a declared Kind, and there is none to read it off.

PatternsResolved is the members of §12's three-member set the Operation declares, and it is empty rather than nil where it declares none: a caller asking which Patterns run around this call is answered *none of them*, which is a fact, where an absent member would say the question was not asked.

RecordCardinality and RecordIdentity are the record: block's two facts and are both "" where there is no record: — a destroy, which projects no Record of its own. The identity is the identity: scalar verbatim, a template hole and a response path alike.

Repeatability is the effective value and not the declared one: an Operation whose Manifest omits repeatability: gets run-once where it effects and repeatable where it reads (§12, ADR-0037). run-once is rendered even though no artefact may write that word, which makes it exactly parallel to opaque — a fact no artefact declares and every surface renders.

Deadline is the authored spelling, 30s, and DeadlineSeconds is that duration in seconds: §9 fixed the wire name and its unit with it, and the spelling is what a page standing beside the source renders, that being what the source says. DeadlineSeconds is a pointer because 0s is a duration an author can write, so 0 is a value this member must be able to state rather than the absence of one (§7).

ConcurrencyLimit is the effective limit and is always present: the declared concurrency:, or 1 where absent, and 1 on every mutate and destroy, whose Expansion is serial and which may not declare the key at all. A caller asking *how many at once* gets a number for every Operation, and the rule about which Kinds may author the key stays in §3 where authoring rules live, rather than being inferred here from a field that came back empty (ADR-0045).

func ReadOperationDetail

func ReadOperationDetail(root *yaml.Node, name string) OperationDetail

ReadOperationDetail reads the derived block for one Operation of a Manifest's own root. Like ReadManifestFacts it judges nothing and drops what it cannot read: a member this returns empty is a member the Manifest did not legibly state, which is check's to report and never this reader's to guess at (ADR-0064).

It answers with the empty detail where name is not a key of a legible operations: block — the nothing-to-read case of that same rule. There is no second return value saying so, because resolution is the surface's and has already happened where the Operation's own source came from: OperationSource and this read one mapping for one key, so neither can find what the other did not (§9, ADR-0060).

type OperationFacts

type OperationFacts struct {
	Name    string
	Kind    string
	Opaque  bool
	Summary string
}

OperationFacts is one Operation as a listing reports it: the name the Manifest keys it by, the Kind it declares, whether it is Opaque, and a derived summary (§9).

Kind is read from the Manifest's own kind: and never inferred from the name — an Operation called delete_thing that declares mutate is a mutate (§12). Opaque is not read from the Manifest at all in the sense the other two are: opacity is a property of the Capability the Operation's request uses, so it is read from the request block, and no artefact anywhere declares it (§12).

type OperationInfo

type OperationInfo struct {
	IsShell       bool
	Kind          string
	HasSeries     bool
	RecordFields  map[string]bool
	Inputs        map[string]InputInfo
	Repeatability string
	HasSecret     bool
	SecretFields  map[string]bool
	// HostTemplate is the raw host: scalar an http: block carries — ""
	// on a shell Operation, which has no host: at all — the template
	// whose at-load expansion is the candidate set the bound Target's
	// grant is checked against (§3, ADR-0029, issue #98).
	HostTemplate string
	// HostInput is the raw host-input: scalar — "" where the Operation
	// declares none — naming the one input that carries a whole host
	// where the candidate set and the grant intersect to several, and
	// the position that makes an over: values: list a host list where a
	// Step wires {item: $} into it (§3, §4, issue #98).
	HostInput string
	// Identity is the raw identity: scalar record: carries — "" on a
	// destroy, which projects nothing — read to decide whether an
	// Expansion's members can be shown to project one identity before
	// any call goes out: a template hole or $.command on a shell
	// Operation resolve before the call, and any response path does not
	// (§3, §4, issue #98).
	Identity string
}

OperationInfo is what checking a Step against the Operation it binds needs, read once per repository pass alongside the rest of ProviderInfo rather than reparsed per Step that names it (§3, §4, issue #94): whether its request is the shell Capability, the one hyper's own Provider may declare and the one whose argv arrives as the input named command, and the same fact by which opacity is read rather than declared (§5, §13, issue #95); its own Kind — read, mutate or destroy — the two keys and the Bound both check against; its Record cardinality, series where its record: carries an over: and one otherwise — the fact a reference's step: half is refused against (series-reference); the field names its record: projects, nil on an Operation with no record: at all — the namespace a reference's path: half resolves against; every input its input: schema declares, by name; its own Repeatability, "" where undeclared — the fact IsRunOnce reads, and the two Cadence rules' own walk with it (issue #96); whether its own secret: is present and names at least one field — the other fact that same walk reads; and SecretFields, the field names secret: itself names — the set a predicate's own field: is checked against, nil where secret: is absent (§3, §4, §12, issue #97).

func (OperationInfo) IsOpaqueDestroy

func (o OperationInfo) IsOpaqueDestroy() bool

IsOpaqueDestroy reports whether this Operation is the one Step §5's Bound rule and its over: requirement both turn on — a destroy Operation whose request is opaque, the shell Capability (§4, §5, §13, issue #95).

func (OperationInfo) IsRunOnce

func (o OperationInfo) IsRunOnce() bool

IsRunOnce reports whether this Operation is the effectful default the Cadence walk refuses at any depth (§4, §5, issue #96): its repeatability: is omitted and its Kind is mutate or destroy — the one combination with no spelling of its own, run-once having none. A read's undeclared Repeatability is always repeatable rather than run-once (§12), so a read is never run-once whatever its Repeatability reads.

func (OperationInfo) SuppliedHost

func (o OperationInfo) SuppliedHost(inputs map[string]schema.Scalar) string

SuppliedHost is the value of the input the Operation's `host-input:` names, and "" where it names none — the whole of what the resolution below needs from an invocation's arguments (§3, ADR-0029).

It is here rather than at either caller because the reading is the same reading at both: a Probe's `--input` and a Step's `args:` are one map of resolved inputs, and which of them carries a host is the Operation's fact.

type OperationMark

type OperationMark struct {
	Line          int
	Name          string
	Kind          string
	Repeatability string
	Opaque        bool
}

OperationMark is one member of `operations:` as the gutter marks it, beside the line its key is written on — which is the line that binds the claim, an Operation's body being everything indented beneath its name.

Name is the key itself. It is no part of the mark — the marker stands beside the line the name is written on and would only repeat it — and it is what a flag indexing that line names, a Manifest carrying no coordinate on the wire for the row to be read by (§8, §12).

Kind is what the Manifest declares and is never inferred from the Operation's name (§12), and it is "" where the entry declares none legibly.

Repeatability is the effective value and not the declared one: an Operation whose Manifest omits `repeatability:` is run-once where it effects and repeatable where it reads (§12, ADR-0037). It is the same derivation `hyper operation` renders, so `run-once` — a word no artefact may write — reaches this column exactly as `opaque` does. It is "" where `kind:` is not one of the three, there being no default to read off a Kind the Manifest never stated.

Opaque is whether the Operation's request uses an Opaque Capability, read off the request block because no artefact anywhere declares it (§12).

type ProcedureGraph

type ProcedureGraph map[string]procedureGraphInfo

ProcedureGraph is every procedures/ file's own per-file facts, keyed by the name it declares: the namespace the transitive walk recurses through, and what a review's own gutter reads a nested invocation's transitive envelope off of (§4, §5, §8, issues #96, #120). Its members are unexported because what a caller does with the graph is walk it, never read one file's entry.

func BuildProcedureGraph

func BuildProcedureGraph(roots []ProcedureRoot, providers ProviderIndex, definitions DefinitionIndex) ProcedureGraph

BuildProcedureGraph reads roots into the namespace CheckProcedureGraph walks: one procedureGraphInfo per procedures/ file whose procedure: is a legible scalar, on BuildProcedureIndex's own rule — a root whose procedure: is absent or illegible contributes no entry, having already earned its own schema-mismatch or name-mismatch and being no name a nested invocation could ever resolve to (§4, §5, issue #96). providers and definitions are the repository-wide namespaces a Step's definition: and operation: resolve against, needed here only to read a Step's own Kind, Repeatability and secret-output fact — every other fact about a Step is procedure.go's own file-local checks' business, not this walk's.

func (ProcedureGraph) Reaches

func (g ProcedureGraph) Reaches(name string) ProcedureReach

Reaches answers name's own ProcedureReach, walking every procedures/ file the graph holds to whatever depth name's invocations run to.

A name the graph does not hold reaches nothing and reads everything it reaches, which is the same answer a Procedure with no Steps gives and the same answer this walk gives every name it cannot resolve: there is no Step under it that effects, the fault is already reported where it was authored, and `project` writes nothing where `check` reports anything (ADR-0064).

type ProcedureIndex

type ProcedureIndex map[string]bool

ProcedureIndex maps a procedures/ file's own procedure: to whether it exists — the namespace a nested invocation's procedure: resolves against (§3, §4, issue #94).

func BuildProcedureIndex

func BuildProcedureIndex(procedureRoots []*yaml.Node) ProcedureIndex

BuildProcedureIndex adds one entry per procedures/ root whose procedure: is a legible scalar, on BuildProviderIndex's own rule.

type ProcedureMarks

type ProcedureMarks struct {
	EnvelopeLine    int
	EnvelopeTargets []string
	EnvelopeHolds   bool
	Steps           []StepMark
}

ProcedureMarks is what a review derives about a Procedure's own lines — the supply behind §8's marker column, and the facts a reviewer with the file open in a diff cannot see because none of them are in the file: an Operation's Kind is declared in a Manifest two directories away, its opacity is declared nowhere at all, and the envelope check quantifies over every Step's target: at once (§8, issue #120).

It reads and does not judge, on ReadManifestFacts's own rule: a name that resolves to nothing is marked as the absence it is rather than refused, a review not running check and not declining (ADR-0064). Nothing an author wrote is in here either — a comment is source and is read for nothing (§8).

EnvelopeLine is the targets: line the envelope mark stands beside, and 0 where the Procedure declares no targets: at all — there being no line to mark and the missing key being check's to report.

EnvelopeTargets are the Targets that line declares, in the file's own order and as written, including one that resolves to no declaration. It is the envelope the mark is a verdict on, which is what an index of that verdict states rather than restating the verdict (§8, §12): the values are the fact and how they are punctuated is the rendering surface's.

EnvelopeHolds is whether every Step and every nested invocation this reader could derive an envelope contribution from stays inside the declared envelope. The comparisons are envelope-exceeded's — a bound Target outside the declared targets:, and a Kind outside the union those targets accept — together with the transitive half CheckProcedureGraph runs, over the graph that check walks rather than a second derivation of a Procedure's reach.

What it quantifies over is not what check quantifies over, and the difference is a rendering rule rather than a disagreement. checkStepEnvelope reports an out-of-envelope target: whatever else about the Step failed to resolve; this mark reads nothing off a Step it derived nothing else about, §8 fixing that an unresolved Step carries no Kind, no opacity and no envelope contribution. So a Step whose definition: names nothing and whose target: is outside the envelope renders `unresolved` beside `envelope ✓` here and earns envelope-exceeded from check — which is the two surfaces doing their own jobs: check reports what is wrong with the artefact, and a review annotates what hyper derived from these lines (ADR-0026, ADR-0064).

func ReadProcedureMarks

func ReadProcedureMarks(root *yaml.Node, providers ProviderIndex, definitions DefinitionIndex, targets TargetIndex, graph ProcedureGraph) ProcedureMarks

ReadProcedureMarks reads a Procedure's own root into the marks its gutter carries. providers, definitions and graph are the namespaces a Step's definition: and operation: and a nested invocation's procedure: resolve against — the same three CheckProcedure and CheckProcedureGraph resolve them against, so what the gutter marks and what check refuses are one reading of one repository. targets is the namespace this Procedure's own declared targets: resolve against, which is where the Kind half of the envelope comes from.

It is a Procedure's reader and answers nothing on any other artefact: only a Procedure has Steps, so only a Procedure carries a Kind, a Target or an envelope mark (§8).

type ProcedureReach

type ProcedureReach struct {
	// Pairs is each (Definition, Target) pair once, in the Steps' own
	// order and a nested invocation's after its caller's — deterministic,
	// so one repository answers one way. The env: block orders itself by
	// variable name and does not read this order (§10); what it needs is
	// that a walk of one repository twice is a walk of one repository.
	//
	// They are store.Pair because they are §6's own noun, and the same
	// pairs a Run's credential pass and the Store's schema test are
	// quantified over — one concept, and the walk that finds them early
	// answers in the type the walk that binds them uses.
	Pairs []store.Pair
	// EveryStepReads is whether every Step reachable from this Procedure
	// declares kind: read — the fact deciding whether its workflow takes
	// the Store's concurrency group. Reachability decides it and not the
	// Procedure's own declared Steps: a read-looking Procedure that
	// invokes an effectful one effects (§10).
	EveryStepReads bool
}

ProcedureReach is what one Procedure reaches, to any depth, that nothing about a single procedures/ file can answer: the pairs its Steps bind, and whether every Step it reaches is a read (§10, issue #176).

Both are the projection's, and both come off the walk the two Cadence rules already ride rather than a traversal of their own: a Procedure's reach is one question, and asking it twice is where the day comes that the env: block and the concurrency group disagree about what a Procedure runs.

type ProcedureRoot

type ProcedureRoot struct {
	File string
	Root *yaml.Node
}

ProcedureRoot pairs one procedures/ file's own relative path with its already-parsed root — what BuildProcedureGraph reads the transitive walk's own per-file facts off of, needing every procedures/ file's own name to know where a citation belongs (§4, §5, issue #96).

type ProviderIndex

type ProviderIndex map[string]ProviderInfo

ProviderIndex maps a Provider's own name — a built-in or a providers/ file's provider: — to what a Definition binding it is checked against. It is the namespace a Definition's provider: resolves against (§4).

func BuildProviderIndex

func BuildProviderIndex(manifestRoots []*yaml.Node) ProviderIndex

BuildProviderIndex starts from the built-in Providers — today, shell alone — and adds one entry per providers/ root whose provider: is a legible scalar. A root whose provider: is absent or malformed has already earned its own schema-mismatch and contributes nothing to the namespace other artefacts resolve against — the same rule ADR-0064 states for a file that will not parse at all, applied to a file that parses but names itself badly.

It is handed roots the load has already folded, and that is what keeps a built-in's name a built-in's: the fold is where an Extension taking one is declined, so no colliding root reaches this walk to overwrite the entry above it (§11, internal/repository's manifestsByName). Nothing here decides a collision, and a caller that passed the providers/ roots raw would be asking this to answer a question §11 answers elsewhere.

type ProviderInfo

type ProviderInfo struct {
	Class        string
	Capabilities map[string]bool
	Operations   map[string]OperationInfo
	AuthSlots    []string
	RecordFields map[string]bool
	SecretFields map[string]bool
	// Enumerations is the Manifest's own enumerations: block, name to
	// members — the one source a Capability-relevant hole in an
	// Operation's host: may resolve to, and half the candidate set
	// expansion the host grant is checked against (§3, §12, issue #98).
	Enumerations map[string][]string
}

ProviderInfo is what checking a Definition against its bound Provider needs, read once per repository pass rather than reparsed per Definition that binds it (§4, §5): the class its Definitions may bind, the Capabilities its Operations require, the Operations it declares — the namespace a destroy: member and a Step's operation: resolve against — the credential slot names its Auth scheme requires, nil where it authenticates nothing, and RecordFields and SecretFields, the union of every Operation's own two sets of the same name (§3, §4, §12, issue #97). The union rather than one Operation's own set is what a selector's and a condition's field: resolve against: assets:/observations: range over the (Definition, Target) Record series a different Operation of the same Provider may have written — a destroy Step's own Operation projects no record: at all, and its selector still names the fields the mutate that created what it destroys projected.

func (ProviderInfo) Summary

func (p ProviderInfo) Summary() string

Summary is the derived summary a `providers` row carries (§9). §3's Manifest schema has no summary: key and §12 forces additionalProperties: false at every level, so no Manifest can carry one and no Manifest author can write one; what stands in its place is built from the facts the Manifest does state — its class:, the Capabilities it requires, and its Operation count by Kind — on §9's own rule that making the caller re-derive what hyper already computed is waste.

A fact the Manifest never stated is dropped rather than rendered empty: a file that parses and names itself is in the Provider namespace whatever else it left out (ADR-0064), and a summary reading "class ; requires " would state two declarations that are not there. An Operation count is the one part always written, a Manifest declaring none saying so in words.

type Reach

type Reach int

Reach is what resolving an invocation's host answered.

const (
	// ReachGranted: the call reaches Host, which the grant admits.
	ReachGranted Reach = iota
	// ReachNotGranted: nothing the call could reach is granted.
	// `host-not-granted` (§4, ADR-0042).
	ReachNotGranted
	// ReachUndecidable: the candidate set and the grant intersect to
	// several hosts under an Operation naming no `host-input:`, so which
	// host the request would reach is not decided by anything. `check`
	// reports this as `manifest-inconsistent` wherever a Step binds the
	// Operation (§4), so a Run reaches it only where `check` has not run;
	// a Probe is a binding no artefact wrote, and reaches it always.
	ReachUndecidable
	// ReachIllegible: the `host:` template writes a hole naming neither
	// `from-target` nor a declared enumeration, which `check` has already
	// refused as `hole-illegal`. There is nothing to expand and so nothing
	// to decide (ADR-0064).
	ReachIllegible
)

type RepositoryDeclarationMarks

type RepositoryDeclarationMarks struct {
	Version, Retention KeyMark
}

RepositoryDeclarationMarks is §8's roster on a Repository declaration: the `hyper` version every Run in this repository is gated on, and the retention policy that bounds Compaction (§3, §11).

The digest beside the pin carries no mark, and the roster is what says so: the two members here are the facts that govern every Run in this repository — what `hyper` it is pinned to, and how long its Records are kept — where the digest is `hyper project`'s own writing about the pin rather than a third thing the repository declares (§11, §12).

func ReadRepositoryDeclarationMarks

func ReadRepositoryDeclarationMarks(root *yaml.Node) RepositoryDeclarationMarks

ReadRepositoryDeclarationMarks reads those two off `hyper.yaml`'s own root. A repository declaring no `retention:` has no line to mark and therefore no cell, which is different from a line rendering a blank one (§8).

type RepositoryFacts

type RepositoryFacts struct {
	// Retention is the policy as the artefact spells it, `90d`, and empty
	// where the declaration carries no `retention:` at all.
	//
	// The empty string is the whole of *this repository has agreed to lose
	// nothing*, and it is safe as a sentinel because no duration is empty:
	// §3 admits `<count><unit>` and nothing else, so a key written with no
	// value is a key that declared no policy. That is also the only reading
	// that is safe to get wrong in one direction — a policy read as absent
	// removes nothing (§3, §7).
	Retention string
	// Digest is the released artefact's checksum as the declaration spells
	// it, algorithm inline — `sha256:` and sixty-four hex digits — and
	// empty where the declaration carries none.
	//
	// It is written by `project` and read by `project`: the version pins
	// which release the generated workflow installs and this pins the bytes
	// that release is, literal in the file so that nothing is resolved when
	// the job runs (§11). The schema makes it required, so empty here is a
	// declaration `check` has already refused rather than a state a
	// projection has to have an answer for (§3, ADR-0064).
	Digest string
}

RepositoryFacts is what the Repository declaration says that a command acts on, in the shape a command reads it: the retention policy that bounds Compaction, and the digest the projection freezes.

The version pin is deliberately not here. It is the gate's, and the gate reads `hyper.yaml`'s bytes before the repository is loaded at all — a second reading of one fact through a second door is exactly what §12's opening rule closes (§9, §11, ADR-0020). The digest beside it is not the gate's and never was: `hyper` never hashes itself, and what the digest covers is the released artefact a runner fetches — a fact about the world outside this checkout, read here like any other thing the declaration says (§11, ADR-0020).

It is the third of these readers and stands beside ReadTargetFacts and ReadManifestFacts for their reason: a check asks *is this value well formed*, which is a schema question, and a command asks *what did the repository declare*, which is this. Neither judges — a `retention:` that is not a duration states what it states here and earns its `schema-mismatch` from `check` (ADR-0064).

func ReadRepositoryFacts

func ReadRepositoryFacts(root *yaml.Node) RepositoryFacts

ReadRepositoryFacts reads them off `hyper.yaml`'s own root.

type Step

type Step struct {
	// ID is the Step's authored `id:` — what the Journal matches a Step by
	// across Runs, and what the Step table's second column renders (§7, §8).
	ID string
	// Definition, Operation and Target are the binding: the three names a
	// Step resolves against the repository's namespaces. All three are ""
	// on a nested invocation, which binds nothing.
	Definition, Operation, Target string
	// Invocation is the `procedure:` a nested invocation names, and "" on a
	// Step proper. An invocation is not a Step: it writes no Journal file
	// and reaches no Disposition, and its own Steps are Steps of the one
	// Run (§6, §7).
	Invocation string
	// Require is the `require:` a Requirement carries, and nil on both other
	// shapes. It is a Requirement's whole content beside its `id:`: the
	// predicate the Run must satisfy to go on, in the condition's own root —
	// a named earlier Step's Record, `step:` beside `field:` (§3, §12).
	//
	// A Requirement is not a Step either, and on the invocation's own three
	// grounds: it writes no Journal file, none of §12's Dispositions
	// describes one, and it takes no position in the sequence. What it does
	// instead is halt, which is how a Procedure that claims no effectful
	// authority stops a Run (§6, ADR-0116).
	Require *yaml.Node
	// Args are the Step's `args:`, by input name, as authored: a scalar
	// literal, or the mapping a reference is written as. What each may be
	// is §3's, and reading one against the Operation's declared input type
	// is the engine's at the moment the value is needed.
	Args map[string]*yaml.Node
	// Over, When and Bound are the three keys a Step may carry beside its
	// binding: the selector whose Expansion §6 resolves, the condition
	// §6 evaluates before it, and the Bound §5 makes mandatory on a
	// `destroy`. They are held as nodes because nothing here reads them —
	// their presence is what a milestone that has not built one declines
	// on, and their content belongs to the milestone that has.
	Over, When, Bound *yaml.Node
	// Line is where the Step's own entry begins, which is what a Refusal
	// citing this Step points a caret at (§8).
	Line int
}

Step is one member of a Procedure's `steps:` — a Step proper, the nested invocation that shares the sequence with it, or the Requirement that shares it with both, told apart by which of `procedure:`, `require:` and the three binding keys it carries (§3).

Every member is held as it was authored and never as it resolves. `Kind` is not here: a Step's Kind is its Operation's, read off the Manifest, and a Procedure that named one would be declaring an authority its Provider owns (ADR-0025).

func ReadProcedureSteps

func ReadProcedureSteps(root *yaml.Node) []Step

ReadProcedureSteps reads a Procedure's `steps:` in written order, which is the order they run in and the order their `<nnnn>` is counted in (§6, §12).

A root that is not a Procedure, or one carrying no legible `steps:`, reads as no Steps at all rather than as a fault — the reader's rule this package follows everywhere (ADR-0064).

func (Step) IsInvocation

func (s Step) IsInvocation() bool

IsInvocation reports whether this member is a nested Procedure invocation rather than a Step: it names a `procedure:` and binds nothing.

func (Step) IsRequirement

func (s Step) IsRequirement() bool

IsRequirement reports whether this member is a Requirement rather than a Step: it carries a `require:`, binds nothing and invokes nothing (§3, issue #236).

type StepMark

type StepMark struct {
	Line        int
	ID          string
	Requirement bool
	Unresolved  bool
	Absent      AbsentName
	Kind        string
	Operation   string
	Bounded     bool
	Bound       string
	Opaque      bool
	Targets     []string
}

StepMark is one entry of a Procedure's steps: as the gutter marks it, in the order the file declares them.

Line is the line the entry opens on, which is the line that binds the claim: a Step's own `- id:`, and a nested invocation's.

ID is the id: the entry declares, "" where it declares none legibly. It is the coordinate a flag citing this line carries — a Step is named by its id: on every surface in the tool — and no part of the mark: the gutter stands beside the line and needs no name for it (§8, §12).

Unresolved is §8's one mark for four absences: a definition:, an operation:, a bound Provider or a nested procedure: that names nothing. It is one name and not four because the gutter marks and does not classify — which name failed is FLAGS' text — and a mark that fired carries nothing else: no Kind to read, no opacity, and no contribution to the envelope check.

Absent is which of those four it was, set exactly where Unresolved is: the key that carried the name, the name itself, and the Provider an Operation was looked for on. It is the classification the gutter does not make and the flag does, and it is carried as the facts rather than as a sentence — what a rendering says about them is the rendering surface's (§8, §12).

Kind is the Operation's declared Kind, read from the Manifest and never inferred from the Operation's name (§12). It is "" on a nested invocation, which invokes no Operation and has no blast radius of its own to declare.

Operation is the operation: the Step names, which resolved: a flag indexing this line names what is being invoked, where the marker beside it carries the Kind that invocation reaches. It is "" on a nested invocation for Kind's own reason.

Bounded is whether the Step declares a bound: at all, whatever its Kind. It is the fact rather than the mark: a mutate Step with none is marked mutate! and a destroy Step with none is bound-missing, a static check's to report, so the rendering of this fact differs by Kind and the reading does not (§4).

Bound is that Bound's value as the Step wrote it, "" where the Step declares none or declares one this cannot read. The two are one key read for two questions — whether a Bound stands behind the Step, and what it says — and a value that would not read is a bound: check's to report and a fact this states nothing about (ADR-0064).

Opaque is whether the Operation's request uses an Opaque Capability, which is read off the request and declared beside no Operation anywhere (§12).

Targets is what the mark binds: the one Target a Step's target: names, as written; or, on a nested invocation, the transitive envelope it reaches, in name order — the envelope §3 states, walked to any depth. It is empty on a Requirement, which reaches nothing.

Requirement is whether the entry is one: a `require:` and an `id:`, binding nothing and invoking nothing. Every other member of the mark is empty on one, and that is the gutter's supply rule holding rather than a roster left short — a Requirement's whole content is authored on the line the reviewer is reading, so there is nothing `hyper` derived for a marker to carry (§8, ADR-0026, ADR-0116).

type TargetDeclarationMarks

type TargetDeclarationMarks struct {
	Kinds, Capabilities, Hosts KeyMark
	Credentials                []KeyMark
	OpaqueDestroy              int
}

TargetDeclarationMarks is §8's roster on a Target declaration: the Kinds it accepts, the Capabilities it grants, the hosts it grants, the environment variable each credential slot resolves from, and the opt-in that admits an `opaque` `destroy` (§4, §8).

Credentials is one entry per member of `auth:`, in the mapping's own order, each carrying the slot's own line and the variable it names. A slot whose value is not the mapping §4 fixes carries no value: the slot is still a line of the file and still renders, and what is wrong with it is `credential-slot-malformed` from `check` (ADR-0064).

OpaqueDestroy is the opt-in's own line where the declaration grants it, and 0 where it writes none or writes the default. The grant is the whole of what is derived there and there is no value beside it, so the line alone is the mark's supply — a declaration writing `opaque-destroy: false` admits exactly what one writing nothing admits, and a mark there would name a grant that was not made.

func ReadTargetDeclarationMarks

func ReadTargetDeclarationMarks(root *yaml.Node) TargetDeclarationMarks

ReadTargetDeclarationMarks reads that roster off a Target declaration's own root. The three list-shaped facts are ReadTargetFacts's, on ReadDefinitionMarks's own rule; the credential slots are walked here because what a mark needs off a slot is the line its key is written on, which is the one thing a row reporting a Target's credentials has never asked for (§9).

type TargetFacts

type TargetFacts struct {
	Hosts        []string
	Kinds        []string
	Capabilities []string
	Credentials  []CredentialSlot
}

TargetFacts is what a Target declaration grants, in the shape a surface reports it: ordered lists rather than the membership sets TargetInfo carries.

The two readings are one artefact read for two questions. A check asks *does this Target grant that host*, which is a set; a row states *what does this Target grant*, which is an enumeration and is answered in the declaration's own order — a grant silently reduced or re-sorted is not the grant the reviewer has open beside it (§3, ADR-0024, ADR-0029).

Hosts is nil where the declaration enumerates no host, which is a Target granting no http: hosts: is the one key here a declaration may leave out, and the ordinary absence rule is what a reader reads off it (§4, §7).

func ReadTargetFacts

func ReadTargetFacts(root *yaml.Node) TargetFacts

ReadTargetFacts reads those four facts off a Target declaration's own root. It judges none of them: a declaration that names a Kind outside the closed set, or a host that is not a hostname, states what it states here and earns its problem from check (ADR-0064). What it does drop is what it cannot read — a list member that is not a plain scalar has no value to report.

type TargetIndex

type TargetIndex map[string]TargetInfo

TargetIndex maps a Target declaration's own target: to what a Definition binding it is checked against. It is the namespace a Definition's targets: member resolves against (§4).

func BuildTargetIndex

func BuildTargetIndex(declarationRoots []*yaml.Node) TargetIndex

BuildTargetIndex adds one entry per targets/ root whose target: is a legible scalar, on BuildProviderIndex's own rule. The name is read through TargetDeclarationName, which is the same rule the load folds each name to its declaration by: the namespace a targets: resolves against and the list `hyper targets` writes cannot disagree about which declaration a name means (issue #112).

type TargetInfo

type TargetInfo struct {
	Class         string
	Capabilities  map[string]bool
	AuthSlots     map[string]bool
	Kinds         map[string]bool
	OpaqueDestroy bool
	Hosts         map[string]bool
}

TargetInfo is what checking a Definition against a Target it binds needs: the class it declares, the Capabilities it grants, the credential slot names its auth: mapping supplies, the Kinds it accepts — the grant half of the two keys, a Step's bound Definition supplying the claim — whether it has opted into opaque-destroy: (§3, §4, §5, issue #95), and the granted host set its hosts: enumerates — the comparand both host-not-granted comparisons run against (§3, §4, ADR-0024, ADR-0029, issue #98).

type Touched

type Touched struct {
	// Lines are the working tree's lines the change column marks: a line
	// whose content differs from the baseline, a line that is new, and the
	// line a deletion anchors to. **One mark and not three** — the gutter
	// marks and does not classify, and a direction is `FLAGS`' text (§8).
	Lines map[int]bool
	// Anchors is each removed line's own number in the baseline against the
	// working-tree line its deletion is cited at. It is what lets a flag
	// about a fact the working tree no longer carries cite a line the gutter
	// marked, which is the whole of what a citation is for (§8, §12).
	Anchors map[int]int
}

Touched is one reading of the range over one artefact.

func ReadTouched

func ReadTouched(baseline, working []string, root *yaml.Node) Touched

ReadTouched reads the range over one artefact: the baseline's lines, the working tree's, and the working tree as `hyper` parsed it.

The parse is the working tree's alone. The baseline is read as text here because that is the whole of what the column needs, and a baseline that will not parse still marks the lines that moved — which is the same discipline the header holds one member over: an absence is named where it is, and nothing downstream of it is silently dropped (§8, ADR-0064).

func (Touched) Marked

func (t Touched) Marked(line int) bool

Marked reports whether the change column marks that line.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL