Grant Stellmacher
RegistryAEF

AEF 1300

AEF 1300: Record Structure and Scope Declaration

What an attested execution record contains, and what a declaration must say before a run begins

v0.1

1. Status#

AEF 1300 v0.1 is an early draft and will change. It is the sixth document in the series and the first in the 1300 block.

This document is normative throughout. Its requirements bind an attested execution record and an implementation that produces one. Requirements on what a verifier does belong to AEF 1200, and where a field exists only to enable a check, the check is cited rather than restated.

This document did not ship alone. A conformant record, the tooling that produces it, a trust base statement with its parties named, three verification results, and a tampered copy that fails were built alongside it and are published at `/aef/examples/run-0001`. Section 13 reports what building them changed. Nine requirements in this document exist in their current form because a first draft could not be satisfied, and section 15 lists them.

AEF 1000 is the source of authority. AEF 1001 supplies the vocabulary, used exactly and not redefined. AEF 1100 supplies the threat analysis, cited by threat id. AEF 1101 and AEF 1200 are cited by section and requirement id.

Versions are dated, kept at their own paths, and recorded in CHANGELOG.md beside this document.

2. Why this document exists#

AEF 1200 section 7.2 concluded that an unqualified PASS is unreachable, because three of its eight checks depend on record fields no document specified. AEF 1200 section 15 listed thirteen such fields. This document supplies them.

The larger reason is that the series reached five documents and roughly twenty-five thousand words with no conformant record in existence. A specification that has never been satisfied is a hypothesis about a specification. AEF 1000 section 9 states that no requirement ships until something has been built that satisfies it and something has been built that fails it, and until now that rule had nothing to apply to.

3. Normative language#

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL are to be interpreted as described in RFC 2119 and RFC 8174, and only when they appear in all capitals.

Requirements are numbered R1 through R26 and are collected in section 12.

4. The record#

R1. An aer MUST be a JSON object carrying exactly these members: `aefVersion`, `runId`, `declaration`, `declarationSeal`, `actLog`, `inputState`, `outputArtifacts`, `permissionSurface`, `approvalRecord`, `roles`, `keyBinding`, `trustBase`, `hashAlg`, and `seal`.

R2. `aefVersion` MUST name this document and its version, as `1300/0.1`. AEF 1001 section 8 states that conformance is always to a document and a version, and a record that does not name both cannot be checked against anything.

The member set is fixed rather than open. An open set would let an implementation carry material the seal covers and no verifier examines, which is a place for content to hide inside an otherwise valid record.

5. Serialization and canonical form#

This is where interoperability dies if it is left to profiles, so the position is taken here.

R3. An aer MUST be serialized as UTF-8 JSON.

R4. The canonical form over which a seal is computed MUST be the JSON Canonicalization Scheme of RFC 8785.

R5. An aer MUST NOT contain a number that is not an integer within the IEEE 754 double-precision safe range, and MUST NOT contain a JSON value that RFC 8785 cannot serialize.

R5 exists because RFC 8785's number serialization is the part implementations most often get wrong, and no field in this document needs a fraction. A count is an integer, a digest is a string, a time is a string. Excluding the hard case is cheaper than requiring everyone to implement it correctly, and an implementation that rejects rather than silently mis-serializes is the one a reviewer can trust.

R6. The bytes a seal covers MUST be the canonical form of the sealed object with its own `seal` member removed, and nothing else.

R6 fixes the boundary question every signing format has to answer. Stating it as removal of one named member, rather than as a list of covered members, means adding a member to this specification later cannot silently leave it outside the seal.

6. The declaration#

The declared scope is the most consequential structure in the framework, because completeness is asserted against it (AEF 1001 section 8) and AEF 1000 principle 3 makes absence within it a finding.

R7. A declaration MUST contain `aefVersion`, `runId`, `declaredAt`, `purpose`, `include`, `exclude`, `elements`, `termination`, and `approvalRequired`. It MAY contain `linkage`.

6.1 Inclusion and exclusion, both#

R8. `include` and `exclude` MUST each be an array of selectors. An act is inside the declared boundary if it matches at least one `include` selector and no `exclude` selector.

Inclusion alone cannot express a boundary of the form "everything under this path except this subtree" without enumerating the complement, which is unbounded. Exclusion alone has no boundary at all, since everything not excluded is included and the record's scope becomes the world. Requiring both, with exclusion narrowing inclusion, is the only combination that expresses ordinary boundaries compactly and still terminates.

R9. A selector MUST be an object with `channel` and `target`, both strings. `` matches any value. A `target` ending in `/` matches any value with that prefix.

6.2 Machine-comparable, not merely readable#

R10. A declaration's boundary MUST be expressed so that a program can decide, for any act log entry, whether it falls inside.

AEF 1001 section 6.2 requires only that a reader can determine membership. That is too weak for AEF 1200 V15, which requires a verifier to test every entry. A boundary a human can adjudicate and a machine cannot is a boundary whose enforcement depends on somebody doing the work, which is the defect class AEF 1101 section 16 catalogues.

The cost is real and is not hidden. A selector grammar this small cannot express boundaries that depend on the content of an act rather than its channel and target. Section 16 records that as a limit.

6.3 Declared elements and unsupported elements#

R11. `elements` MUST contain one entry for each of `actLog`, `inputState`, `outputArtifacts`, `permissionSurface`, and `approvalRecord`. Each entry MUST carry `status` of either `present` or `unsupported`, and an entry with status `unsupported` MUST carry a `reason`.

This is the field AEF 1200 section 15 item 3 surfaced and no earlier list contained. It is what lets a record be honest about its own gaps rather than silently omitting them, and it is the difference between the two readings AEF 1000 principle 3 distinguishes: a step that produced no evidence is unsupported rather than presumed fine.

Without it, an absent element and a declared-absent element are indistinguishable, and AEF 1200 V16 has nothing to test against. With it, the operator's claim that an element does not apply is written down, dated, sealed, and attributable, which is the same move AEF 1001 section 6.1 makes for the boundary and buys the same thing: not prevention, but a stated claim a reviewer can reject.

6.4 Termination#

R12. `termination` MUST be one of `{"kind":"explicit-close"}`, `{"kind":"act-count","count":n}`, or `{"kind":"deadline","notAfter":t}`.

R13. Under `explicit-close`, the act log MUST contain exactly one entry with `closes` set to true, and it MUST be the final entry.

AEF 1100 threat 6.4 states that truncation is the cheapest pre-seal attack because it requires no editing, only a decision about when to stop, and that a truncated record is internally consistent and complete against a scope that ends where the record ends. A termination condition is what makes the stated end and the recorded end two different things that can disagree.

What this buys, stated precisely. Under `explicit-close`, a record truncated before its closing entry now fails a check. Under `act-count`, a record with fewer entries than declared fails. Neither prevents an operator from declaring a termination it always intends to reach, so this does not close threat 6.4; it converts the cheapest attack into one that requires the declaration to have been drawn to accommodate it in advance. The disposition in AEF 1100 is not changed by this document, and section 14 records the case for revisiting it.

6.5 Sealed before execution#

R14. A declaration MUST be sealed as its own object, with its own seal, before the first act of the run is captured.

R15. An aer MUST carry `declarationSeal`, a digest over the canonical form of the sealed declaration envelope, and the declaration inside the aer MUST be identical to the one that was sealed.

AEF 1100 threat 7.3 identifies scope amendment after execution as the threat that undermines AEF 1001's central defense: everything declaration buys rests on the declaration having been made in ignorance of the outcome, and nothing establishes that it was.

What separate sealing does and does not achieve. It produces an artifact that cannot be revised after the fact without detection, and it lets a reviewer who obtained the declaration before the run compare it against the one the record carries. It does not establish ordering against an external clock, because the seal time on the declaration comes from the same time source as everything else, and AEF 1100 threat 10.3 makes that the operator's assertion where the clock is the operator's. The worked example demonstrates exactly this: the declaration is sealed first, the record binds it, the verifier confirms the binding, and the result still carries a qualification saying the seal time is not anchored. Threat 7.3 remains CONDITIONAL on anchoring that AEF 1400 has not specified. What changed is that there is now an artifact for an anchor to attach to.

6.6 Run linkage#

R16. `linkage`, where present, MUST carry `groupId` and `position`.

AEF 1100 section 18 proposes a linkage identifier to make run splitting visible. It is specified as OPTIONAL, and the reason is worth stating rather than burying, because a required-but-worthless field is worse than an optional one.

Linkage is operator-declared and inherits every weakness of the declared boundary. An operator fragmenting work to avoid describing it will not join the fragments with a group identifier. Making linkage mandatory would produce records where the field is present and singleton, which looks like a complete group and is not distinguishable from one. So linkage makes fragmentation visible where the operator chooses to declare it, and does nothing where they do not. AEF 1100 threat 7.2 stays CONCEDED, and this document does not claim otherwise.

7. The act log#

R17. Each act log entry MUST carry `seq`, `channel`, `target`, `prev`, and `capturedAt`, and MAY carry `instruction`, `effect`, and `closes`.

7.1 Chaining#

R18. The first entry's `prev` MUST be null. Every subsequent entry's `prev` MUST be a digest over the canonical form of the entry immediately preceding it.

AEF 1100 threat 6.5 leaves chaining here and states the conclusion a verifier draws: after seal time, reordering is detected by the seal; before seal time, order is the operator's assertion unless entries are chained. AEF 1200 V21 and V22 state what a verifier does with the presence or absence of a chain.

Chaining binds order into the entries rather than alongside them, so an operator reordering entries before sealing must recompute every subsequent digest. That is not a defense against an operator who does recompute them, and the seal covers the whole log either way. What it buys is defense in depth that showed up unprompted in the worked example: the tampered copy fails two checks rather than one, because altering a single field broke both the seal and the chain link that depended on it.

8. Time#

R19. Every recorded time in an aer MUST be an object with `value`, an RFC 3339 timestamp, and `source`, an object carrying `id`, `kind` of either `operator` or `external`, and `party`.

AEF 1001 section 9 defines five distinct moments and states that conflating any two is a class of error rather than an instance. Attaching the source to each occurrence, rather than declaring one source for the record, is what lets a record have an externally anchored seal time and an operator-clocked capture time without either claim contaminating the other.

R20. A seal MUST carry `anchor`, an object with `anchored`, `party`, and `evidence`. Where `anchored` is false, `party` and `evidence` MUST be null.

The anchor field is specified here and its semantics belong to AEF 1400. This document requires the field so that a record produced today can be read by a verifier written after AEF 1400 exists, and so that the absence of an anchor is a recorded fact rather than a missing member. AEF 1200 V35 needs exactly this to report whether a seal time precedes a deprecation.

9. Roles#

R21. An aer MUST carry `roles` with `operator`, `approvingSigner`, `implementer`, and `verifierAuthor`. `approvingSigner` MUST be null where no party approved.

AEF 1001 section 7.1 makes disclosure of the operator and approving signer combination a MUST on the record, and AEF 1100 section 17 records that nothing checks whether the disclosure was made. R21 gives it a field, which is what converts an obligation into something AEF 1200 V30 and V31 can test.

`verifierAuthor` is included because AEF 1001 section 7.1 names a third combination that weakens principle 4: an implementer who also authors the verifier leaves the verifier with no adversary in its history. That combination was previously visible only to someone who already knew the project. In the worked example it is disclosed, and the verification result carries a qualification naming it.

10. Key binding, artifacts, approval, and trust base#

R22. `keyBinding` MUST carry `mechanism`, one of `none`, `x509`, `certificate-transparency`, `key-transparency`, or `pin`, together with `keyId`, `publicKey`, and `alg`.

The enumeration matches the mechanisms AEF 1101 section 9 analyses and AEF 1200 V13 assigns checks to. `none` is a permitted value, and naming it is the point: a record whose key binding supplies no external assertion says so, and AEF 1200 V11 forbids a verifier reporting identity for it.

R23. `inputState` entries MUST carry `ref`, `retained`, and `digest`. `outputArtifacts` entries MUST carry `ref` and `digest`. Every digest MUST carry `alg` and `value`.

`retained` answers AEF 1001 open question 2 in the narrow sense the checks need: a reviewer can tell whether the content behind a reference is available or whether only the reference survives. What a reference must contain to be resolvable by a stranger years later is not settled here, and section 16 records it.

R24. `approvalRecord` MUST be null or an object carrying `approvingSigner`, `approvedAt`, and `referent`, where `referent` is a digest. `declaration.approvalRequired` MUST state whether an approval was required.

`approvalRequired` is the field AEF 1200 V29 needed and could not have: a verifier cannot otherwise distinguish a run that needed no approval from one missing it. It is the operator's claim about the operator's own process, which is why the worked example's result carries a qualification for it rather than treating its absence as fine.

R25. `trustBase` MUST be a digest over the canonical form of a trust base statement in the form AEF 1101 section 6 requires.

R26. `hashAlg` MUST name the algorithm used for `prev`, `declarationSeal`, and artifact digests, and every digest MUST also carry its own `alg`.

R26 is redundant on its face and is required anyway. AEF 1200 V35 cannot report an algorithm as deprecated for a record that does not name its algorithms, and per-digest naming is what allows a record to migrate one algorithm without invalidating the others.

11. What this document does not specify#

Deferred deliberately, with the reason, because the worked example showed these were not ready rather than not needed.

Boundary adequacy. AEF 1001 open question 1 asks whether a declared boundary can be tested rather than only rejected. R10 makes membership decidable, which is a different and smaller thing. Nothing here says whether a boundary is adequate to a reviewer's question, and AEF 1100 threat 7.1 stays CONCEDED.

Reference resolution. R23 requires a reference and does not say what makes one resolvable by a party who does not have the operator's filesystem.

Cross-record indexing. AEF 1100 threat 6.7 needs an external index and this document defines a record, not a population of records.

Approval referent checking. AEF 1001 open question 3 belongs to AEF 1301. R24 requires the referent digest so that document has something to work with.

Anchor semantics. R20 requires the field; AEF 1400 states what makes an anchor real.

12. Requirement count and classification#

Twenty-six requirements, R1 through R26. Applying the test AEF 1101 section 16 established.

Checkable by inspecting a record: twenty-five. R1 through R13 and R15 through R26. Each names a member, a type, an enumeration, or a relationship between members, all of which a program reads off the artifact.

Checkable only by observing an implementation over time: one. R14, that the declaration was sealed before the first act was captured. A record carries a sealed declaration and a seal time, and where the clock is the operator's, nothing in the artifact establishes the ordering. This is the one requirement here whose observer does not exist yet, and AEF 1400 is what would supply it.

Twenty-five of twenty-six sit on the artifact side, which was the target.

Two of those twenty-five are checkable as to form and not as to substance, and counting them as fully checkable would overstate what the classification means. R11 requires a `reason` on an unsupported element and nothing tests whether the reason is candid. R21 requires role disclosure and nothing tests whether it is truthful. Both are requirements that a claim be made rather than that it be true, which is the most this framework asks of a self-reported field, and section 16 carries them.

13. The worked example#

Published at `/aef/examples/run-0001`, with every artifact at a permanent path.

The run. The tooling read the eight AEF documents published before this one, computed a SHA-256 digest for each, and wrote a manifest binding each document path to its digest. The manifest is a snapshot taken when the run executed, which was before this document existed, and it does not cover this document. The manifest is at `standards/aef/manifest.json` and a reader can recompute every digest in it from the repository.

What was produced. A declaration sealed before execution. A record with eighteen act log entries, eight input state items, one output artifact, a permission surface broader than what was touched, role disclosure, and a seal. A trust base statement with ten dependencies and their controlling parties named. Three verification results. A tampered copy of the record.

The result, in one line. `PASS_WITH_QUALIFICATIONS`, with twelve checks, zero failed, zero not run, and ten qualifications.

The ten qualifications, each with what it means the reader cannot conclude:

  1. `IDENTITY-NOT-ESTABLISHED`. The key sealed this record and nothing says whose key it is. You cannot conclude the operator sealed it.
  2. `NO-EQUIVOCATION-DETECTION`. No log would reveal the same identity bound to a different key elsewhere. You cannot conclude this key is the only one presented as this party's.
  3. `OTHER`, proposing `ELEMENT-UNSUPPORTED`. The approval record is declared unsupported. You cannot conclude anything an approval would have established.
  4. `ARTIFACTS-OPERATOR-SUPPLIED`. The artifacts compared came from the operator's repository. You cannot conclude this record describes work you asked about rather than work the operator chose to show, which is AEF 1100 threat 6.6.
  5. `TIME-OPERATOR-ASSERTED`. All twenty recorded times come from the host clock. You cannot conclude when anything happened, only the order the record asserts.
  6. `CAPTURE-TO-SEAL-INTERVAL-UNBOUNDED`. The interval was zero seconds and nothing constrains it. You cannot conclude that a future record from the same operator will have a small window.
  7. `OTHER`, proposing `SEAL-TIME-UNANCHORED`. Nothing outside the operator attests the seal time. You cannot conclude the record existed when it says it did.
  8. `APPROVAL-ABSENT`. No party approved, and the declaration says none was required. You cannot conclude anyone took responsibility for this run.
  9. `OTHER`, proposing `VERIFIER-SELF-AUTHORED`. The party that built the producing system also wrote the verifier. You cannot conclude the verifier had an adversary in its history, per AEF 1001 section 7.1.
  10. `OTHER`, proposing `TRUST-BASE-SELF-ASSERTED`. The trust base statement's completeness and externality answers are the operator's. You cannot conclude they are correct, per AEF 1101 section 16.

The tampered copy. One character in one `effect` field. The result is `FAIL`, first failing check `seal-integrity`, and a second check fails as well: the chain link over that entry breaks. AEF 1000 principle 4 holds that a verifier that has never rejected a tampered record verifies nothing, and this is the cheapest public demonstration that it rejects one.

The third result. Verification with the sealed declaration withheld returns `INCONCLUSIVE`, with `declaration-binding` recorded as not run. It is published because a vocabulary value nobody has seen produced is a claim about a vocabulary. All four outcome values in AEF 1200 section 7.1 are now demonstrated by artifacts rather than described.

The fixture set. Twenty-two golden fixtures, ten of them required to fail, covering a flipped byte in four different members, a broken chain, an act outside the boundary, truncation, a capture time after the seal, a mismatched declaration, and an artifact that does not match its digest. AEF 1001 section 6.12 requires a fixture set to include inputs required to fail, and the majority here are.

14. Findings from building it#

Separated as the shipping rule requires: fixed here before shipping, recorded as candidate revisions elsewhere, or unresolved.

14.1 Fixed in this document before shipping#

  1. The artifact check conflated three states, and the second half of the defect was found by reading the published files as a stranger would. The first verifier treated "nothing compared" as "the check could not run", which merged a record binding no artifacts with a record whose artifacts were withheld. R11 is why a record can now say which case applies, by declaring the element unsupported. The remaining half surfaced only when the published artifacts were downloaded over HTTP and verified with no repository present, which is the position an actual reviewer occupies: that returned INCONCLUSIVE, because unavailable artifacts still reached the not-run state. AEF 1200 section 8.4 says a mismatch is fatal and absence is not, so the verifier was wrong and now qualifies instead. A reviewer holding only the JSON gets PASS_WITH_QUALIFICATIONS with `ARTIFACTS-UNAVAILABLE` named. A regression fixture pins it.

The general lesson is worth more than the fix. Verifying your own artifact from inside your own working tree tests a configuration no reviewer is ever in, and AEF 1000 principle 2 says exactly this about operators. It applies to the framework's own tooling.

  1. The declaration had no separate seal in the first draft. It was a member of the record like any other, which made AEF 1100 threat 7.3 entirely unaddressed. R14 and R15 exist because writing the run script made the omission obvious: there was no artifact that could have existed before the run.
  2. Termination was absent from the first draft. R12 and R13 were added after the fixture for truncation had nothing to assert against.
  3. `approvalRequired` was absent. AEF 1200 V29 says a verifier cannot distinguish a run needing no approval from one missing it. Building the check proved the point: without R24's field the verifier had to guess, and it guessed by treating absence as acceptable, which is exactly what AEF 1200 V41 forbids.
  4. `verifierAuthor` was not in the role disclosure. AEF 1001 section 7.1 names three damaging combinations and the first draft's `roles` covered two.
  5. Canonicalization was unspecified. The first draft said "JSON" and left the seal boundary implicit. R4, R5, and R6 followed from having to actually compute a seal twice and get the same bytes.
  6. Digests carried no algorithm. They were bare hex strings until AEF 1200 V35's deprecation reporting was implemented and had nothing to name. R23 and R26 followed.
  7. The selector grammar was prose. R9 and R10 replaced a sentence saying a boundary should be checkable with a grammar a program can execute.
  8. Time sources were declared once per record. Attaching a source to every recorded time, per R19, was forced by wanting a record whose seal time could be anchored later without relabelling its capture times.

14.2 Candidate revisions to earlier documents, recorded and not applied#

Following the constraint that held in AEF 1200 section 16.

  1. AEF 1200 section 7.4's qualification registry is incomplete. The example emitted four conditions no registry class covers, correctly classed `OTHER` under V7: `ELEMENT-UNSUPPORTED`, `SEAL-TIME-UNANCHORED`, `VERIFIER-SELF-AUTHORED`, and `TRUST-BASE-SELF-ASSERTED`. This is the mechanism V7 was designed to produce and it fired on the first record ever built. All four belong in AEF 1200 v0.2.
  2. AEF 1200 section 8's check list is incomplete. Two fatal checks the example needs have no entry there: `declaration-binding` and `termination`. Both exist because this document requires fields AEF 1200 could not have anticipated. AEF 1200 v0.2.
  3. AEF 1200 has no per-check status. INCONCLUSIVE is defined only at the result level, so a check that could not run inside an otherwise sound verification has nowhere to say so. The reference verifier carries a check-level status of held, failed, not-run, or qualified, which AEF 1200 does not define. AEF 1200 v0.2, and it is the most substantive of these.
  4. AEF 1200 V42 is over-broad as written. A substring test flagged a qualification class named `TRUST-BASE-SELF-CERTIFIED`, which criticises the trust base rather than claiming anything about the record. The class was renamed and the fixture narrowed to conclusion-bearing fields, but V42 should say it constrains conclusions rather than vocabulary. AEF 1200 v0.2.
  5. AEF 1200 V25's qualification text is wrong at small intervals. The example's capture-to-seal interval is zero seconds and the qualification still says the interval is unbounded. That is true about the framework and misleading about the record. AEF 1200 v0.2.
  6. AEF 1101 section 6's dependency record cannot express an absent assertion. It requires a controlling party "named specifically enough that a reviewer could contact or audit them". Entry 2 of the worked trust base is the claim that the key belongs to the named party, and no party asserts it, because the mechanism is `none`. The honest cell is "no party", which the form does not contemplate and which reads as an evasion rather than a finding. AEF 1101 v0.2.
  7. AEF 1101 section 13 entries 2 and 3 are now answerable. Its open question 1 asks the editor to name the key binding authority and time source for the reference implementation. For the implementation published here the answers are that there is no key binding authority and the time source is the host system clock under the operator's control. AEF 1101 v0.2.
  8. AEF 1100 threat 6.4 may warrant revisiting. With R12 and R13, a record truncated before its declared closing entry fails a check. The disposition is CONCEDED and the condition for CONDITIONAL now plausibly exists. Not applied, because the mitigation depends on the operator having declared a termination it did not intend to reach, and whether that counts is 1100's call.

14.3 Unresolved#

  1. R14 has no observer. Nothing in a record establishes that the declaration was sealed before the first act, where the clock is the operator's. The requirement is stated because AEF 1400 can supply the observer later, and until then it is a requirement on a process with no artifact behind it.
  2. The example's verifier and its subject share an author. The verification result says so, which is the most the framework offers, and AEF 1201 is what would change it.
  3. A second independent implementation does not exist, so nothing here has been shown to be implementable by anyone but its author. AEF 1000 section 11 makes two independent implementations the trigger for moving the framework to a standards body, and this is one.

15. What could not be produced#

Reported because the brief that produced this document asked, and because a specification whose example is silent about its failures is an advertisement.

Nothing in this document could not be produced. Every requirement R1 through R26 is satisfied by the published record, which is the minimum bar for shipping them and is not a strong claim: they were written by the same person who built the thing that satisfies them, in the same session, which is the defect AEF 1001 section 7.1 names.

One requirement could not be demonstrated. R14, sealing before execution, is performed by the tooling and is not established by the artifact, for the reason section 14.3 gives.

One thing the brief asked for could not be produced honestly. The brief anticipated that some checks would report INCONCLUSIVE because the infrastructure does not exist. In the event every check ran, and the honest result carries qualifications rather than inconclusive checks. Manufacturing an inconclusive check to match the expectation would have been the exact defect this series is about. The fourth outcome value is instead demonstrated by a separate verification with the declaration withheld, which produces INCONCLUSIVE for a real reason.

16. Requirements with no observer#

The defect class audited in AEF 1000, AEF 1100 section 17, AEF 1101 section 16, and AEF 1200 section 17, applied here.

R11's `reason` has no threshold. "Not applicable" satisfies it. An implementation can mark every element unsupported with a one-word reason and produce a conformant record that establishes nothing, and the verifier will correctly report a long list of qualifications, which is the system working. The defect is that the record is conformant, not that the result is wrong.

R21's role disclosure is self-reported. An operator can name a separate approving signer that is a wholly controlled subsidiary. Nothing tests independence, and AEF 1001 section 7.1 does not define it.

R10's decidability is checkable and its adequacy is not. A boundary of `{"channel":"","target":""}` is perfectly decidable and admits everything, so it satisfies R10 while making scope-membership vacuous. This is AEF 1100 threat 7.1 wearing a grammar.

R14 has no observer at all, per section 14.3.

The `purpose` field is prose and nothing checks it against the acts. A record can declare one purpose and perform acts consistent with the selectors but unrelated to the stated intent.

17. Weaknesses in this document#

The selector grammar is too small. It matches on channel and target only, so a boundary that depends on the content of an act cannot be expressed. Real runs will want that, and the likely response is a richer grammar, which is the point at which decidability stops being obvious.

Fixing the member set may be premature. R1 forbids extension, which prevents content hiding inside a valid record and also prevents anyone extending the format without a version bump. For a v0.1 with one implementation this is probably right and it is the requirement most likely to be wrong.

The example is a weak test of the specification. One record, one run, one implementation, one author. It proves the specification is satisfiable, which is what section 2 said was missing. It does not show that the specification is satisfiable by someone else, that the fields are sufficient for a run with an approver, or that anything here survives a run with genuinely external key binding and time, since neither exists.

Nine requirements exist because a draft failed, which is an argument that more drafting would produce more. Section 14.1 lists changes forced by building one record. There is no reason to think a second record would force none.

Termination is weaker than it appears. R13 catches truncation only where the operator declared `explicit-close` and then truncated. An operator who intends to truncate declares `deadline` and stops early within it.

18. Open questions#

  1. Reference resolution for unretained input state. AEF 1001 open question 2, narrowed but not closed by R23's `retained` flag. AEF 1300 v0.2.
  2. Boundary adequacy. AEF 1001 open question 1 and AEF 1100 threat 7.1. Unassigned, and section 16 suggests it may not be answerable within a record.
  3. Whether the member set should stay closed. Section 17. AEF 1300 v0.2.
  4. Whether a selector grammar can grow without losing decidability. Section 17. AEF 1300 v0.2.
  5. An external index of records, which AEF 1100 threats 6.7 and 11.2 both need and no document owns.
  6. Whether a verification result should itself be a sealed record. Carried forward from AEF 1200 open question 6, and the worked example makes it concrete: three verification results are published as plain JSON with no seal, so every threat in AEF 1100 section 6 applies to them.

19. Terms used here that AEF 1001 does not define#

Recorded rather than coined silently, following AEF 1100 section 16, AEF 1101 section 15, and AEF 1200 section 21.

  • Selector. The unit of a declared boundary, per R9.
  • Canonical form. The byte sequence a seal covers, per R4 and R6.
  • Declaration envelope. The separately sealed object carrying a declaration and its own seal, per R14.
  • Termination condition. The declared statement of where a run ends, per R12.
  • Element status. Whether a declared element is present or unsupported, per R11.

Still undefined from earlier documents and used here: time source and key history, recorded by AEF 1100 section 16 and unresolved through three subsequent documents. R19 now requires every recorded time to name a source whose defining document does not exist, which is the wrong order for the third time in this series and is stated as such.

20. License and citation#

Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).

Cite as:

Stellmacher, G. (2026). AEF 1300: Record Structure and Scope Declaration, v0.1. 13 August 2026. https://grantstell.com/aef/1300

Cite the version and date, always.

Cite this document

Stellmacher, G. (2026). AEF 1300: Record Structure and Scope Declaration, v0.1. 13 August 2026. https://grantstell.com/aef/1300

Cite the version and date, always. Claims are expected to be contradicted by later versions.