Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions notations/examples/packages/documents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ Used by the removal-integrity test (`packages/documents-cli/tests/test_documents

1. Removal (delete both folders, drop from `packages:` list) leaves no trace in the repository.
2. Absence of the package is truly silent: a repository that never declared it is byte-identical to one where it was used then removed.

[RP-17: one document, two editions, independent reviews](../rp17.md) shows a
synthetic recovery-arrangements document, its release binding, and use of the
read-only provenance checker. It separates current package metadata from
proposed identity/edition semantics and annual recurrence support.
264 changes: 264 additions & 0 deletions notations/examples/packages/rp17.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# RP-17: one document, two editions, independent reviews

This synthetic example is for authors using the optional
[documents package](../../packages/documents.md). People, evidence and
content are fictional. Let **Y = 2026**, so Y+1 is 2027. Dates in the narrative
are business dates; execution and issuance records below use UTC instants.
The example distinguishes current package fields, accepted specifications and
proposed semantics. It adds no core TYPE or validator rule.

## Three different things

| Thing | Identity and meaning |
|---|---|
| Information subject | `BUSINESS_OBJECT-RECOVERY-1`: recovery arrangements — recovery priorities, responsibilities and procedures at business-information grain. |
| Document identity | **RP-17**, “Recovery arrangements”, using **FORM-RP-17** throughout. A stable business identifier, independent of an edition label, reporting period or source commit. FORM-RP-17 identifies the template, not the issued document. |
| Retained issued edition | A (`doc-rp17-a-1`, package version `1.0`) or B (`doc-rp17-b-1`, version `2.0`). Each identifies its own retained content, authors, issuance event and coverage. A/B are display labels, not SemVer values. |

The exact existing recommendation is
[`notations/ELEMENT_PRIMITIVES.md` §7.15 at revision 7fd36d24e34f4cd115953d6e64777d9df51a42a3](https://github.com/transitrix/methodology/blob/7fd36d24e34f4cd115953d6e64777d9df51a42a3/notations/ELEMENT_PRIMITIVES.md#715-business_object--02_businessbusiness-objects).
It allows `type: document` among the BUSINESS_OBJECT information sub-kinds,
at business value-chain grain. Its scope note excludes application data
structures and a document's perceptible representation. Thus a document-shaped
business concept can already be a BUSINESS_OBJECT; a retained PDF or its
edition is not thereby another BUSINESS_OBJECT.

The narrow clarification proposed here is to make that boundary explicit when
using the optional package: information subject, stable document identity and
retained edition are separate concerns. Existing valid `type: document` models
remain valid. No bulk conversion, new DOCUMENT/VERSION/CADENCE TYPE, schema
migration or migration promise follows.

## Timeline and retained history

RP-17 describes recovery arrangements for a fictional customer portal. In A,
recovery uses a manual service switch and a service-desk contact sequence. Q2
changes the switch procedure and the contact sequence; those content changes
produce B. The reporting periods record coverage, not review recurrence.

| Event | Explicit record | Consequence |
|---|---|---|
| Q1 Y coverage | `coverage-q1`: January 1 through March 31 Y, inclusive; scope “Q1 recovery arrangements”. | A covers this period. Neither period boundary is an execution or issue date. |
| April 10 Y, 10:00 UTC | Issuance `issue-a`: RP-17, A, FORM-RP-17; authors Mira Vale and Owen Reed; retained artifact `retained-a`; history entry “Initial Q1 issue”. | Issue A once. No review execution is asserted. |
| April 20 Y | Actual review `review-a` explicitly examines retained A unchanged. | Keep its execution evidence; no new edition and no issuance-history entry. |
| Q2 Y coverage | `coverage-q2`: April 1 through June 30 Y, inclusive; scope “Q2 recovery arrangements”. | Changed content needs a separate retained edition. |
| July 10 Y, 10:00 UTC | Issuance `issue-b`: RP-17, B, FORM-RP-17; authors Mira Vale and Ivo Chen; predecessor A under RP-17; retained artifact `retained-b`; history entry “Revised switch procedure and contact sequence for Q2”. | B succeeds A. Retain A and its history. This issuance is not a review. |
| July 15 Y | Association `binding-portal-32`: Portal 3.2 (`RELEASE-PORTAL-32`, belonging to `PRODUCT-PORTAL-1`) explicitly selects retained B. | B is the release's edition even though its latest completed review still concerns A. Do not select A by review date. |
| April 20 Y+1 | Actual review `review-b` explicitly examines retained B unchanged. | Keep its execution evidence. No C, no third issuance-history entry. |

The issuance history contains exactly `issue-a` and `issue-b`. Review evidence
has its own records and can be displayed alongside history without being
represented as issuance. Source-control commits capture edits to records or
inputs; they do not establish any of the business events in this table.

The annual business rule is “review recovery arrangements every April 20 at
09:00 UTC”. Scheduled dates alone do not prove completion. One running recovery
process instance owns the review Activity; finishing either review does not end
that instance. The termination condition is withdrawal of the recovery mandate.

These are **illustrative execution facts**, using the separation of instance,
Activity and execution from the
[accepted recurring-Activity specification](../../recurring-activities.md):

| Record | Scheduled for | Actual start / finish | Outcome and retained evidence |
|---|---|---|---|
| `review-a`, instance `recovery-1`, step `STEP-RECOVERY-REVIEW-1` | `2026-04-20T09:00:00Z` | `2026-04-20T09:02:00Z` / `2026-04-20T09:30:00Z` | Succeeded; A unchanged. `review-evidence-a` explicitly names `doc-rp17-a-1` and its retained artifact digest; no edition emitted. |
| `review-b`, same instance and step | `2027-04-20T09:00:00Z` | `2027-04-20T09:01:00Z` / `2027-04-20T09:35:00Z` | Succeeded; B unchanged. `review-evidence-b` explicitly names `doc-rp17-b-1` and its retained artifact digest; no edition emitted. |

The instance would retain its actual start, pinned definition revision and
explicit operational policy separately. A complete integration must retain
those records and the evidence bodies; these example keys are not proof of real
execution. The accepted profile's explicit closed admission window with
300-second grace permits these starts, if bound to the instance. Its
missed/overlap/stop rules still apply independently of edition production.

**Annual recurrence is a proposed extension.** The accepted calendar profile
allows only `FREQ=WEEKLY;INTERVAL=<positive integer>`; its elapsed-seconds form
cannot substitute for an annual calendar rule. `FREQ=YEARLY` is not accepted.
The existing specification is not a scheduler, execution store, schema or
runtime implementation. No annual schedule is activated by this example.

A later unchanged Q3 coverage record may be recorded without issuing C.
Applicability of B to Q3 needs a separate explicit applicability assertion
naming B, Q3, its scope, assessor and retained supporting evidence. Until that
exists, reuse is unknown. Even with it, B's retained bytes and original Q2
coverage stay unchanged; the assertion does not retroactively broaden B.

## Current package representation and support boundaries

The [package schema §§2.4–2.6](../../packages/documents.md) can hold a
`document-type` with adopter-defined fields and two issued `document` records.
For example, define `doct-recovery-1` with these required fields:

| Field key | Datatype | A value | B value |
|---|---|---|---|
| `DocumentIdentity` | STRING | RP-17 | RP-17 |
| `Form` | STRING | FORM-RP-17 | FORM-RP-17 |
| `EditionLabel` | STRING | A | B |
| `Authors` | TEXT | Mira Vale; Owen Reed | Mira Vale; Ivo Chen |
| `Coverage` | TEXT | Q1 2026, January 1–March 31 | Q2 2026, April 1–June 30 |
| `IssueHistory` | TEXT | issue-a: Initial Q1 issue | issue-b: Revised switch procedure and contact sequence for Q2 |
| `Predecessor` | STRING | none | doc-rp17-a-1 |

One instance fragment, using only existing package fields:

```yaml
package: documents
kind: document
id: doc-rp17-b-1
type: doct-recovery-1
version: "2.0"
status: issued
issued_at: "2026-07-10T10:00:00Z"
values:
DocumentIdentity: "RP-17"
Form: "FORM-RP-17"
EditionLabel: "B"
Authors: "Mira Vale; Ivo Chen"
Coverage: "Q2 2026, April 1–June 30"
IssueHistory: "issue-b: Revised switch procedure and contact sequence for Q2"
Predecessor: "doc-rp17-a-1"
canon_refs:
- BUSINESS_OBJECT-RECOVERY-1
- RELEASE-PORTAL-32
```

A uses its own id, `version: "1.0"`, issue timestamp and values from the table.
This is a representation recipe, not a new built-in template or a complete
adopter model. The `canon_refs` citations are package→core only; neither the
BUSINESS_OBJECT nor the RELEASE points back into the package. In particular,
listing a RELEASE in `canon_refs` does **not** prove its association to B.

| Fact or constraint | Existing expression / proposed meaning | Specification, implementation and release status |
|---|---|---|
| Business information and document subtype | BUSINESS_OBJECT §7.15 | Existing core specification included in methodology v7.0.0; unchanged here. |
| Template, edition record, SemVer, issue time, status | `document-type`, `document`, `version`, `issued_at`, `status` | Experimental package specification included in v7.0.0. DOCS-001–007 are specified rules; the source tree's `packages/documents-cli` contains integrity tests, not an executable validator. Do not claim CLI enforcement. |
| RP-17, FORM-RP-17, A/B, authors, history, coverage and predecessor | Adopter-defined `fields` / `values` above | Existing metadata container. Structured identity resolution, label uniqueness within identity, predecessor ownership, history invariants and coverage/applicability semantics are proposed, not validated by these strings. |
| Retained bytes and source revision | Renderer output, run record and adapter evidence | Existing renderer implementation; retention is the adopter's responsibility. A recorded commit or matching hash does not prove generation. |
| Annual definition, scheduled dates, executions and evidence | Existing PROCESS/STEP concepts plus accepted recurring-Activity separation | Accepted recurring specification is included as documentation in v7.0.0; execution/runtime support is explicitly excluded. Annual timing and edition-specific review bindings remain proposed. |
| Portal release identity and product membership | Existing RELEASE/PRODUCT plus explicit adapter association | Checker compares independently supplied associations; it does not resolve core citations, choose an edition or validate release admission. |
| Q3 applicability and unchanged reviews with no edition | Separate evidence assertions / execution records | Proposed edition-specific meaning; no new package or core fields adopted. |
| Provenance unknowns and contradictions | `document-provenance/1` | Implemented read-only source API included in v7.0.0. This is not evidence of npm publication or an installed consumer integration. |

Removal still means deleting the adopter's `documents/` folder and removing its
`packages:` entry. Keep this example's edition metadata and supplemental
associations on the package/integration side. No core backlink, schema edit or
validator hook is required. An undeclared package remains silent.

## Calling the existing provenance checker

Run the following with Node 20+ from a checkout. It illustrates one retained B
artifact and the existing renderer serialization seam. The byte strings and
independent observer literals are synthetic; the snippet does not render a
real document or establish generation. In production, use exact previously
retained bytes, immutable observations from an authorized observer, and a real
policy decision covering the entire selected bundle. Never construct
`observed` by copying the record's claims.

```js
import { createHash } from 'node:crypto';
import { checkDocumentProvenance }
from './packages/document-renderer/src/provenance.mjs';
import { buildRunRecord, serializeRunRecord }
from './packages/document-renderer/src/run-record.mjs';

const sha = bytes => createHash('sha256').update(bytes).digest('hex');
const output = Buffer.from('RP-17 B: revised switch procedure and contact sequence.\n');
const run = Buffer.from(serializeRunRecord(buildRunRecord({
header: { recipe_id: 'recovery.sdd', recipe_version: '1.0' },
repositoryCommit: null, // no independently retained source snapshot here
modelId: null,
runTimestamp: '2026-07-10T09:50:00Z', // render time, not issue time
renderDate: '2026-06-30', // selection validity date, not execution date
profile: 'strict',
})));
const claims = {
product_id: 'PRODUCT-PORTAL-1', release_id: 'RELEASE-PORTAL-32',
document_issue_id: 'doc-rp17-b-1', document_revision: 'B',
output_sha256: sha(output), output_run_sha256: sha(run),
};
// Fictional independent observation of binding-portal-32 and release membership.
const observed = {
product_id: 'PRODUCT-PORTAL-1', release_id: 'RELEASE-PORTAL-32',
release_product_id: 'PRODUCT-PORTAL-1',
document_issue_id: 'doc-rp17-b-1', document_revision: 'B',
};
const inspect = bundle => checkDocumentProvenance({
authorize: async () => true, // this demonstration contains only synthetic data
load: async () => bundle,
});
const retained = await inspect({ run, output, claims, observed });
const legacy = await inspect({ run, output });
const conflict = await inspect({ run, output, claims, observed: {
...observed, document_issue_id: 'doc-rp17-a-1', document_revision: 'A',
}});
for (const [name, result] of Object.entries({ retained, legacy, conflict })) {
const checks = Object.fromEntries(result.checks.map(c => [c.id, c.status]));
console.log(name, JSON.stringify({
contract: result.contract_version, status: result.status,
incomplete: result.incomplete,
edition: checks['association.document_issue_id'],
label: checks['association.document_revision'],
bytes: checks['output.bytes'], binding: checks['output.run-binding'],
generation: checks['run.generation'],
}));
}
```

Retained B has consistent edition, label, bytes and declared output/run binding;
overall it remains **incomplete**, with generation **unverifiable**. Legacy
edition/label/bytes/binding remain **unverifiable** even though the output bytes
are present. Conflicting A observations versus B claims yield **inconsistent**
edition and label and overall **inconsistent**, while `incomplete` remains true.
The checker never substitutes the latest review, latest edition or closest date.
It compares a declaration of output/run binding; it does not prove the output
was generated by that run. `recipe_version` is also independent of A/B.

## Interpreting incomplete or conflicting records

These assessments separate proposed semantic integrity from existing checker
results. The checker does not validate edition ownership or review execution.

| Observation | Required interpretation |
|---|---|
| A and B resolve to RP-17, with B explicitly succeeding A | Positive proposed edition chain. Preserve both artifacts and two issuance entries. |
| Completed `review-a` or `review-b`, evidence explicitly naming the examined edition, unchanged outcome and no emitted edition | Positive review without edition. Completion does not require a new issue/history entry. |
| Edition has no resolvable document identity | Orphan; proposed semantic integrity failure. Do not infer RP-17 from its filename. |
| B's predecessor belongs to a different document | Cross-document conflict; proposed semantic integrity failure, even if labels/dates look plausible. |
| Two editions under RP-17 share label B | Duplicate-label conflict within that identity. The same label under another identity is not this conflict. |
| April 20 is scheduled, but no actual execution/evidence exists | Performance unknown; do not mark reviewed. If an authoritative missed disposition exists, record missed, not succeeded. |
| No release/edition association, or no independent observation | `association.document_issue_id` / `association.document_revision` unverifiable; no date-based fallback. |
| Release record claims B; independent evidence says A | Conflicting associations stay explicit; checker inconsistent, potentially also incomplete. |
| Present run/output with missing generation evidence | `run.generation` unverifiable; matching hashes cannot upgrade it. |
| Q3 has unchanged content but no applicability evidence | A coverage record may exist; B's applicability to Q3 stays unknown. No automatic C and no mutation of retained B. |

## Small proposed extension, not adopted support

The missing meaning is resolvable document identity across issued instances,
explicit same-identity succession, edition-bound review evidence, and separate
coverage/applicability and release bindings. A minimal **logical** shape is:

- Identity: stable key, title, form reference and optional subject citation.
- Edition: identity key, label, package document id, predecessor key or explicit
none, authors, issued-at, coverage references and retained artifact reference
with digest. An issuance-history entry refers to that edition and event.
- Review evidence: execution key, examined edition/artifact digest, outcome and
evidence reference. No required produced-edition field.
- Applicability: edition key, independent period/scope, assessor and evidence.
- Release binding: product/release key, edition key and retained artifact
reference, backed by independent association evidence.

These are proposed relationships, not new accepted YAML keys or package object
kinds. A decision must fix their package-local serialization, identity/label
uniqueness, predecessor resolution and retained-evidence obligations before a
validator can enforce them. Annual timing separately needs an explicit calendar
profile (April 20 at 09:00 UTC, with the accepted admission and disposition
policy retained); it must not be approximated as 365 days or 52 weeks.

Compatibility requires opt-in additions on the package/integration side,
unchanged existing documents and core models, package→core citations only,
unchanged removal, and silence when undeclared. Acceptance for that extension
requires all the positive and negative interpretations above, preservation of
unknown/conflicting evidence, and no extra issuance from an unchanged review.
This example proposes that bounded meaning; it neither adopts it nor promises
runtime, migration, publication or installed support.
Loading