diff --git a/CITATION.cff b/CITATION.cff index 99b6658..7a00d38 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,7 +2,7 @@ cff-version: 1.2.0 message: "Cite it by the paper it rests on, Two-Sided Constraints on a Valued Lattice." type: software title: "@lapxo/bound" -version: "0.1.4" +version: "0.1.5" authors: - name: "Lapxo" license: "MIT" diff --git a/LICENSE b/LICENSE index 8788fc3..065c07b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,3 @@ -the license this place is bound by MIT License Copyright (c) 2026 Lapxo diff --git a/README.md b/README.md index 77edb0d..751ab9f 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,31 @@ Declare what must hold. Read what does. Keep the evidence ```bash -npx @lapxo/bound@0.1.4 fold --as help -npx @lapxo/bound@0.1.4 fold +npx @lapxo/bound@0.1.5 fold --as help +npx @lapxo/bound@0.1.5 fold ``` ## How Bound reads a project Bound reads a project's admitted statements and observations through its selected Topos, then renders the declared views and records their inputs in receipts. The example below explains the object; a file-fold alone does not calculate its intervals. +## Use Bound in a project + +From a project with an admitted lock and selected views, inspect its standing, ask for its evidence, then verify the committed outputs: + +```sh +npx @lapxo/bound@0.1.5 fold --as lines +npx @lapxo/bound@0.1.5 fold --as receipts@1 +npx @lapxo/bound@0.1.5 fold --check +``` + +Use this flow to review a project change or check a dependency's declared contract. `--check` verifies existing evidence; it does not execute a missing reading. A file fold names readings and explicitly says that it computed no encounters. + +Independent observations are judged through the declared typed cells view. The selected topos supplies the form, origin evidence and bounds. Bound keeps attribution and exact-ID withdrawals through the fold. + +A selected form can instead describe a set of artifacts, a delivery interval or another domain's values. The project declares the form, origin evidence and views; Bound does not infer them from filenames or units. + + ## A meeting everyone can understand Ana is available from 10 to 14, Luis from 12 to 16, and the room from 10 to 13. Their common availability is 12 to 13. A boss available from 18 to 20 makes the encounter incompatible. Withdrawing that exact reading restores the overlap; Ana, Luis and the room remain. @@ -49,11 +66,11 @@ lot_dir="$(mktemp -d)" Have the selected view produce a proposal at `$lot_dir/proposal.bound`, or prepare the project's permitted lines there for review. Unsigned proposals use `by=target`, without a preassigned epoch or `sig`. Lots stay outside the repository; the committed bound files are only `TARGET.bound` and `receipts.bound`. ```sh -npx @lapxo/bound@0.1.4 sign "$lot_dir/proposal.bound" \ +npx @lapxo/bound@0.1.5 sign "$lot_dir/proposal.bound" \ --key "$BOUND_KEY_ID" --key-file "$BOUND_KEY_FILE" \ > "$lot_dir/signed.bound" && -npx @lapxo/bound@0.1.4 land "$lot_dir/signed.bound" && -npx @lapxo/bound@0.1.4 fold +npx @lapxo/bound@0.1.5 land "$lot_dir/signed.bound" && +npx @lapxo/bound@0.1.5 fold ``` `sign` assigns the admitted epoch and writes the signed lot to stdout. `land` validates the whole lot before admission. A refusal is evidence to inspect; it is not success. Do not proceed after a failed signature or admission. The key file is a PKCS8 private key matching the admitted public key; do not put it in the lot, source tree, package or CI artifacts. @@ -97,3 +114,7 @@ A pin names standing, not a download URL or runtime entry. Its declared artifact Use Bound where independently attributed observations must be judged against an accepted contract: compatibility between components, operational limits, or a team's project requirements. The selected topos must supply the actual measurements; a digest identifies the evidence without declaring it true. [Contribute a counterexample or a proposed lot](CONTRIBUTING.md). + +## Foundations and related libraries + +The two-sided constraint object is described in Nahum Ochoa's [Two-Sided Constraints on a Valued Lattice](https://doi.org/10.5281/zenodo.21858428), DOI `10.5281/zenodo.21858428`. Bound uses the object through [Obligations](https://github.com/Lapxo/obligations); [Topos](https://github.com/Lapxo/topos) supplies the wire and contracts for forms, views and selected worlds. Bound admits, folds and retains evidence across those declared boundaries. A digest identifies bytes; it does not certify that an observation is true. diff --git a/TARGET.bound b/TARGET.bound index 3776cf7..b548671 100644 --- a/TARGET.bound +++ b/TARGET.bound @@ -1,6 +1,14 @@ -bound-lock/1 about="# @lapxo/bound\n\nDeclare what must hold. Read what does. Keep the evidence.\n\nBound reads a project's admitted statements, checks observations against its requirements, and produces the views its selected topos declares. It keeps conflicting evidence and its origins instead of choosing a convenient answer.\n\n`fold` reads. `sign` signs a proposed lot. `land` admits that lot under the place's authority. These acts work across domains: a selected topos supplies forms, units, readers and views.\n\n## Start in an admitted project\n\n```sh\nnpx @lapxo/bound@0.1.4 fold --as help\nnpx @lapxo/bound@0.1.4 fold\n```\n\nThe help view prints:\n\n```text\nverbs fold land sign\nflags --as --check --key --key-file --signer --place\n```\n\nThe default fold runs the project's declared views. Its authority and selected topos determine what can be admitted, read and shown.\n\nStart with the team's accepted TARGET, admitted authority and selected readers. [Full usage guide](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md).\n\n## A meeting everyone can understand\n\nAna is available from 10 to 14, Luis from 12 to 16, and the room from 10 to 13. Their common availability is 12 to 13. A boss available from 18 to 20 makes the encounter incompatible. Withdrawing that exact reading restores the overlap; Ana, Luis and the room remain.\n\nWith an interval form, those are object operations: observe independent claims, meet them, withdraw by id, and read the state. A narrower compatible meet is not a fork. Folding a file of declarations alone does not calculate meeting availability.\n\nThe same pattern applies to a delivery window, a sensor's allowed range, or an agreed performance budget. The chosen topos determines the units and how evidence is obtained. Bound does not supply a meeting-specific rule.\n\n## See how information holds together\n\n![Cells, travelling bounds and a local join](https://raw.githubusercontent.com/Lapxo/bound/2053bb6d6188f04538114eae6a0add5166944ed3/docs/readme-assets/atlas.svg)\n\nA travelling ceiling on B reaches C and G through their declared rest. A local join widens B alone. D is independent. The figure shows those relations; point size and camera distance do not measure information.\n\n| State | Meaning |\n| --- | --- |\n| REQUIRED | Compatible bounds, fewer than two independent origins. |\n| FREE | Independent origins meet and their encounter fits the bounds. |\n| CONFLICT | Bounds conflict, or eligible claims have no common encounter. |\n| FORBIDDEN | An inhabited encounter does not fit the bounds. |\n\nBounds are checked before origins and claims. A receipt is evidence of a reading, not another origin. Duplicating one does not add freedom.\n\n## Change a project without erasing evidence\n\nWork in the project's directory. Use an existing admitted key identifier and its matching private key stored outside every repository. The admitted key also names its signer with `keys/ measure=signer value=file`; `signer/timeout` and `signer/response-bytes` declare its limits. Your public key and coverage belong to the authority contract; possession of a private key alone does not authorize a scope.\n\n```sh\nexport BOUND_KEY_ID='your-admitted-key-id'\nexport BOUND_KEY_FILE=\"$HOME/Private/keys/your-device.pem\"\nlot_dir=\"$(mktemp -d)\"\n```\n\nHave the selected view produce a proposal at `$lot_dir/proposal.bound`, or prepare the project's permitted lines there for review. Unsigned proposals use `by=target`, without a preassigned epoch or `sig`. Lots stay outside the repository; the committed bound files are only `TARGET.bound` and `receipts.bound`.\n\n```sh\nnpx @lapxo/bound@0.1.4 sign \"$lot_dir/proposal.bound\" \\\n --key \"$BOUND_KEY_ID\" --key-file \"$BOUND_KEY_FILE\" \\\n > \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.4 land \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.4 fold\n```\n\n`sign` assigns the admitted epoch and writes the signed lot to stdout. `land` validates the whole lot before admission. A refusal is evidence to inspect; it is not success. Do not proceed after a failed signature or admission. The key file is a PKCS8 private key matching the admitted public key; do not put it in the lot, source tree, package or CI artifacts.\n\nFor typed object withdrawals, `takes` names the exact claim or mark id. Removing a local join leaves the travelling sign live. For untyped configuration, use the wire's exact withdrawal selectors; do not combine withdrawal and replacement with identical selectors in one lot. Wire alphabet updates supersede by epoch.\n\n[Authority, withdrawals, receipts and PR review](docs/usage.md).\n\n## Read a declared view and reuse its evidence\n\nWhen the project has admitted a cells view:\n\n```sh\nnpx @lapxo/bound@0.1.4 fold --as cells\n```\n\nThe installed interval scene printed this on an unchanged second reading:\n\n```text\nRECEIPTS 4 read · 0 opened · idle · provider 0\n```\n\nNative receipts identify the live semantic inputs, declared rest, selected topos, codecs and selected rendering implementation. They exclude delivery count, display paths and Bound's error wrapper. A local join changes its own cell's receipt. A travelling sign changes dependent cells. Missing or corrupt carried bytes cannot prove reuse.\n\nFor judgement:\n\n```sh\nnpx @lapxo/bound@0.1.4 fold --check\n```\n\nKeep stdout, stderr and the exit status. `--check` is not an install-and-build replacement. A source test passing does not pay an unread ceiling, prove a cold clone, or accept a release.\n\n## Select a topos by what it declares\n\n`sources/` says where a world can be obtained. An admitted `uses/` names the digest of that topos's folded standing: canonical live claims in wire byte order, excluding signature envelopes and host shape. Re-signing the same standing preserves the pin. A changed live form, class, view or offer changes it.\n\n`restsOn` closes artifact bytes separately. A capsule is one offer. Forms, classes and views need no capsule merely to be selected. Runtime and packing do not define standing identity. npm dependency ranges remain package metadata; they are not standing pins.\n\n| Responsibility | Owner |\n| --- | --- |\n| Meet, state, live acts and rest | Obligations |\n| Wire, forms, classes, views and offer contracts | Topos |\n| Admission, folding and evidence | Bound |\n| Domain measurement and representation | Selected topos |\n| Storage, transport and execution | Host |\n\nCell `restsOn` is the object's relation. Directory prefixes and file summaries are host coordinates, not object rest. Wire tokens are protocol constants, not organization, host, path or key literals.\n\n## Repository rules\n\nCommit `TARGET.bound`, `receipts.bound` and the outputs the forge reads. Ignore `.bound/` from the first line of `.gitignore`. Keep proposals, signed lots, keys, ledgers, caches and dependency blobs outside the published tree.\n\nThe lock is the project's own contract and pins. Read a dependency's declarations from its selected standing; do not copy its lines into your lock. README, package metadata and workflows must be renders of admitted declarations. A scan is an observation, not permission to lower a ceiling.\n\nA PR proposes lines and the leaf changes they render. The judge uses the team's accepted contract independently of the proposed revision. Preserve refusals, conflicting origins and unpaid demands. [Repository and contribution rules](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md#repository-and-pr-review).\n\n## An atlas you can question\n\nInformation can share a history without sharing a single presentation. The same admitted cells can support a compact status view, a spatial view of their relations, or a focused reading of one disagreement. Each view asks for a region and resolution; its selected topos determines the representation.\n\nThis makes changes inspectable. A local act can remain local, travelling bounds can reach dependent cells, and a receipt can name the inputs of the reading you saw. You can ask what changed and what depends on it without turning a drawing into the algebra.\n\nA pin names standing, not a download URL or runtime entry. Its declared artifact dependencies close the bytes needed for an offered operation. The boundary lets a form or view remain meaningful even when it has no executable capsule.\n\nUse Bound where independently attributed observations must be judged against an accepted contract: compatibility between components, operational limits, or a team's project requirements. The selected topos must supply the actual measurements; a digest identifies the evidence without declaring it true.\n\n[Contribute a counterexample or a proposed lot](CONTRIBUTING.md).\n" at=witness:bound/014-candidate by=target form=alphabet measure=text role=writes scope=prose/en/files/public-0 shape=README.md value=lock +bound-lock/1 about="# @lapxo/bound\n\n## Use Bound in a project\n\nFrom a project with an admitted lock and selected views, inspect its standing, ask for its evidence, then verify the committed outputs:\n\n```sh\nnpx @lapxo/bound@0.1.5 fold --as lines\nnpx @lapxo/bound@0.1.5 fold --as receipts@1\nnpx @lapxo/bound@0.1.5 fold --check\n```\n\nUse this flow to review a project change or check a dependency's declared contract. `--check` verifies existing evidence; it does not execute a missing reading. A file fold names readings and explicitly says that it computed no encounters.\n\nIndependent observations are judged through the declared typed cells view. The selected topos supplies the form, origin evidence and bounds. Bound keeps attribution and exact-ID withdrawals through the fold.\n\nA selected form can instead describe a set of artifacts, a delivery interval or another domain's values. The project declares the form, origin evidence and views; Bound does not infer them from filenames or units.\n\n\nDeclare what must hold. Read what does. Keep the evidence.\n\nBound reads a project's admitted statements, checks observations against its requirements, and produces the views its selected topos declares. It keeps conflicting evidence and its origins instead of choosing a convenient answer.\n\n`fold` reads. `sign` signs a proposed lot. `land` admits that lot under the place's authority. These acts work across domains: a selected topos supplies forms, units, readers and views.\n\n## Start in an admitted project\n\n```sh\nnpx @lapxo/bound@0.1.5 fold --as help\nnpx @lapxo/bound@0.1.5 fold\n```\n\nThe help view prints:\n\n```text\nverbs fold land sign\nflags --as --check --key --key-file --signer --place\n```\n\nThe default fold runs the project's declared views. Its authority and selected topos determine what can be admitted, read and shown.\n\nStart with the team's accepted TARGET, admitted authority and selected readers. [Full usage guide](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md).\n\n## A meeting everyone can understand\n\nAna is available from 10 to 14, Luis from 12 to 16, and the room from 10 to 13. Their common availability is 12 to 13. A boss available from 18 to 20 makes the encounter incompatible. Withdrawing that exact reading restores the overlap; Ana, Luis and the room remain.\n\nWith an interval form, those are object operations: observe independent claims, meet them, withdraw by id, and read the state. A narrower compatible meet is not a fork. Folding a file of declarations alone does not calculate meeting availability.\n\nThe same pattern applies to a delivery window, a sensor's allowed range, or an agreed performance budget. The chosen topos determines the units and how evidence is obtained. Bound does not supply a meeting-specific rule.\n\n## See how information holds together\n\n![Cells, travelling bounds and a local join](https://raw.githubusercontent.com/Lapxo/bound/2053bb6d6188f04538114eae6a0add5166944ed3/docs/readme-assets/atlas.svg)\n\nA travelling ceiling on B reaches C and G through their declared rest. A local join widens B alone. D is independent. The figure shows those relations; point size and camera distance do not measure information.\n\n| State | Meaning |\n| --- | --- |\n| REQUIRED | Compatible bounds, fewer than two independent origins. |\n| FREE | Independent origins meet and their encounter fits the bounds. |\n| CONFLICT | Bounds conflict, or eligible claims have no common encounter. |\n| FORBIDDEN | An inhabited encounter does not fit the bounds. |\n\nBounds are checked before origins and claims. A receipt is evidence of a reading, not another origin. Duplicating one does not add freedom.\n\n## Change a project without erasing evidence\n\nWork in the project's directory. Use an existing admitted key identifier and its matching private key stored outside every repository. The admitted key also names its signer with `keys/ measure=signer value=file`; `signer/timeout` and `signer/response-bytes` declare its limits. Your public key and coverage belong to the authority contract; possession of a private key alone does not authorize a scope.\n\n```sh\nexport BOUND_KEY_ID='your-admitted-key-id'\nexport BOUND_KEY_FILE=\"$HOME/Private/keys/your-device.pem\"\nlot_dir=\"$(mktemp -d)\"\n```\n\nHave the selected view produce a proposal at `$lot_dir/proposal.bound`, or prepare the project's permitted lines there for review. Unsigned proposals use `by=target`, without a preassigned epoch or `sig`. Lots stay outside the repository; the committed bound files are only `TARGET.bound` and `receipts.bound`.\n\n```sh\nnpx @lapxo/bound@0.1.5 sign \"$lot_dir/proposal.bound\" \\\n --key \"$BOUND_KEY_ID\" --key-file \"$BOUND_KEY_FILE\" \\\n > \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.5 land \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.5 fold\n```\n\n`sign` assigns the admitted epoch and writes the signed lot to stdout. `land` validates the whole lot before admission. A refusal is evidence to inspect; it is not success. Do not proceed after a failed signature or admission. The key file is a PKCS8 private key matching the admitted public key; do not put it in the lot, source tree, package or CI artifacts.\n\nFor typed object withdrawals, `takes` names the exact claim or mark id. Removing a local join leaves the travelling sign live. For untyped configuration, use the wire's exact withdrawal selectors; do not combine withdrawal and replacement with identical selectors in one lot. Wire alphabet updates supersede by epoch.\n\n[Authority, withdrawals, receipts and PR review](docs/usage.md).\n\n## Read a declared view and reuse its evidence\n\nWhen the project has admitted a cells view:\n\n```sh\nnpx @lapxo/bound@0.1.5 fold --as cells\n```\n\nThe installed interval scene printed this on an unchanged second reading:\n\n```text\nRECEIPTS 4 read · 0 opened · idle · provider 0\n```\n\nNative receipts identify the live semantic inputs, declared rest, selected topos, codecs and selected rendering implementation. They exclude delivery count, display paths and Bound's error wrapper. A local join changes its own cell's receipt. A travelling sign changes dependent cells. Missing or corrupt carried bytes cannot prove reuse.\n\nFor judgement:\n\n```sh\nnpx @lapxo/bound@0.1.5 fold --check\n```\n\nKeep stdout, stderr and the exit status. `--check` is not an install-and-build replacement. A source test passing does not pay an unread ceiling, prove a cold clone, or accept a release.\n\n## Select a topos by what it declares\n\n`sources/` says where a world can be obtained. An admitted `uses/` names the digest of that topos's folded standing: canonical live claims in wire byte order, excluding signature envelopes and host shape. Re-signing the same standing preserves the pin. A changed live form, class, view or offer changes it.\n\n`restsOn` closes artifact bytes separately. A capsule is one offer. Forms, classes and views need no capsule merely to be selected. Runtime and packing do not define standing identity. npm dependency ranges remain package metadata; they are not standing pins.\n\n| Responsibility | Owner |\n| --- | --- |\n| Meet, state, live acts and rest | Obligations |\n| Wire, forms, classes, views and offer contracts | Topos |\n| Admission, folding and evidence | Bound |\n| Domain measurement and representation | Selected topos |\n| Storage, transport and execution | Host |\n\nCell `restsOn` is the object's relation. Directory prefixes and file summaries are host coordinates, not object rest. Wire tokens are protocol constants, not organization, host, path or key literals.\n\n## Repository rules\n\nCommit `TARGET.bound`, `receipts.bound` and the outputs the forge reads. Ignore `.bound/` from the first line of `.gitignore`. Keep proposals, signed lots, keys, ledgers, caches and dependency blobs outside the published tree.\n\nThe lock is the project's own contract and pins. Read a dependency's declarations from its selected standing; do not copy its lines into your lock. README, package metadata and workflows must be renders of admitted declarations. A scan is an observation, not permission to lower a ceiling.\n\nA PR proposes lines and the leaf changes they render. The judge uses the team's accepted contract independently of the proposed revision. Preserve refusals, conflicting origins and unpaid demands. [Repository and contribution rules](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md#repository-and-pr-review).\n\n## An atlas you can question\n\nInformation can share a history without sharing a single presentation. The same admitted cells can support a compact status view, a spatial view of their relations, or a focused reading of one disagreement. Each view asks for a region and resolution; its selected topos determines the representation.\n\nThis makes changes inspectable. A local act can remain local, travelling bounds can reach dependent cells, and a receipt can name the inputs of the reading you saw. You can ask what changed and what depends on it without turning a drawing into the algebra.\n\nA pin names standing, not a download URL or runtime entry. Its declared artifact dependencies close the bytes needed for an offered operation. The boundary lets a form or view remain meaningful even when it has no executable capsule.\n\nUse Bound where independently attributed observations must be judged against an accepted contract: compatibility between components, operational limits, or a team's project requirements. The selected topos must supply the actual measurements; a digest identifies the evidence without declaring it true.\n\n[Contribute a counterexample or a proposed lot](CONTRIBUTING.md).\n\n\n## Foundations and related libraries\n\nThe two-sided constraint object is described in Nahum Ochoa's [Two-Sided Constraints on a Valued Lattice](https://doi.org/10.5281/zenodo.21858428), DOI `10.5281/zenodo.21858428`. Bound uses the object through [Obligations](https://github.com/Lapxo/obligations); [Topos](https://github.com/Lapxo/topos) supplies the wire and contracts for forms, views and selected worlds. Bound admits, folds and retains evidence across those declared boundaries. A digest identifies bytes; it does not certify that an observation is true.\n" at=witness:minimal-public-surface-015 by=target form=alphabet measure=text role=writes scope=prose/en/files/public-0 shape=README.md value=lock +bound-lock/1 about="# Authenticated evidence view\n\nThe declared evidence@8 view projects authenticated delivery history of this place. It preserves signatures and key attribution, including admitted receipts from an attest-class key. Evidence is not normative configuration, proof of truth, or an independent observation origin. Authority and coverage are checked by the existing Topos contract; no consumer or device type changes that boundary.\n\n\nThe no sample specifies an uncovered write and tampered signed bytes. Both must refuse by name. Exact withdrawals remove only covered normative lines; authenticated evidence remains inspectable. The vectors assert status, signature verification and observable CLI output. No private key bytes are printed or shipped.\n" at=witness:minimal-public-surface-015 by=target form=alphabet measure=text role=writes scope=prose/en/files/contract-evidence-view shape=docs/contracts/evidence-view.md value=lock bound-lock/1 about="# Contributing to Bound\n\nBring a counterexample, an observation or a proposed lot. Include the inputs and the output that led you to it. A signature establishes who was authorized to speak; it does not make their result true.\n\n## Set up a working copy\n\nClone the repository and use the Node version supported by package.json. If package-lock.json is present, run npm ci; otherwise use npm install --ignore-scripts --no-package-lock. Then run:\n\n```sh\nnpm run build\nnpm test\n```\n\nThese are development checks, not project acceptance. For a place with admitted trust context and native receipts, run the product judgement as well:\n\n```sh\nnpx @lapxo/bound@0.1.0 fold --check\n```\n\nPreserve a refusal and its exit status in your report. Do not borrow a neighbouring checkout's ledger or substitute local bytes for a named pin.\n\n## Make the smallest useful change\n\nBound owns admission, folding and evidence. Topos owns grammar, forms, classes, views and their contracts. A selected topos owns domain measurement. Obligations owns the algebra. Keep each change in its layer; do not put a domain decoder, path-based inference or a fallback for a missing pin into Bound.\n\nAn algebra change needs an independent oracle and a counterexample. A host change needs evidence for authentic bytes, failure propagation or reuse. A view change needs its declared region and implementation identity. A test should fail for a plausible incorrect implementation, not assert a source string or repeat the same expression on both sides.\n\nKeep regressions for changed signatures, unauthorized coverage, exact-id withdrawal, conflicting evidence, local versus travelling acts, corrupt content and duplicate delivery. Consolidate repeated setup and duplicate scenarios without removing distinct falsifiers.\n\n## Propose and admit\n\nKeep proposal and signed-lot files outside the repository. Use the current admitted wire, by=target, and no preassigned epoch or signature. The team's admitted key signs the lot; Bound admits it under scope coverage. The [usage guide](docs/usage.md) explains the transaction and external key-file requirements.\n\nSend the proposed lines with the leaf changes they render. A hand-edited render is evidence of the intended change, not an admitted contribution. Do not edit the accepted TARGET to make a test or ceiling pass. If a render disagrees with the lock, fix the proposed lines and re-render it.\n\nCommit only the project's TARGET.bound and native receipts.bound as bound files. The first .gitignore line excludes .bound/. Do not commit keys, stores, ledgers, caches, capsules, archives or vendored dependencies.\n\n## Submit a pull request\n\nExplain the concrete behavior before and after the change, the affected layer, and the checks you ran. Include stdout, stderr and exit status for a CLI case. State which reader and input bytes produced the evidence; a source harness is not an installed-package proof.\n\nPolicy changes receive explicit team review separately from measurements of the proposed source. Keep incompatible readings and their origins visible. Never remove a failing test or weaken a ceiling to obtain acceptance. Withdraw statements through their admitted history; do not rewrite prior signatures, tags or releases.\n\nDocumentation and workflows follow the same review: propose their lines and include the rendered changes.\n" at=policy:public-prose by=target form=alphabet measure=text role=writes scope=prose/en/files/public-1 shape=CONTRIBUTING.md value=lock -bound-lock/1 about="# Using Bound\n\nThis guide covers the current CLI in a place whose wire and authority are already admitted. A fresh unsigned TARGET is a proposal, not a trusted project. The prepared repository is not yet a certified empty-clone bootstrap.\n\n## Before the first fold\n\nYou need the team's accepted TARGET and trust context, authentic bytes for each selected digest, and the readers/views that TARGET names. Do not borrow a neighbouring repository's ledger or copy node_modules to make a missing pin look available.\n\nThe published repository carries exactly TARGET.bound and receipts.bound as bound files. Local admission history lives in the ignored .bound/ store. Published standing excludes the signature envelope; owner public keys retain their signatures.\n\nStart by asking for help and folding the project. If a selected view is unavailable, use the named refusal and its fix; do not invent an output with a similar name.\n\n## Keys and coverage\n\nUse a named key already admitted by the project. The authority contract declares its public key, class and scope coverage. Signing uses a declared port. The lock names `keys/ measure=signer value=`; `signer/timeout` and `signer/response-bytes` bound each invocation. The built-in `file` port reads a matching PKCS8 PEM outside the repository through `--key-file`. For a command port, the host supplies a `BOUND_SIGNERS` registry mapping that admitted name to `{ \"kind\": \"command\", \"executable\": \"...\", \"args\": [] }`. A repository declaration cannot authorize a program. `--signer ` must match the admitted selection.\n\nA new device must have its public key and coverage admitted by an authority that already covers the intended scope. The CLI does not currently certify silent key creation or tap-to-sign. This guide does not substitute a self-authorized fixture key for the team's authority.\n\nFor automation through the file port, supply the private key through the runner's secret storage to a temporary external file with restricted permissions. A command signer receives the lot once as canonical signed bytes, one line per record in order. It returns one canonical wire response per record, containing `by` and `sig`, in that same order. Bound verifies the entire reply against the admitted public key before any admission. Timeout, nonzero exit, missing or invalid replies refuse the whole lot; raw signer output is not logged. Hosts can keep private keys outside Bound through this port. Key generation, storage and rotation belong to the host. Do not print, commit or upload it. A source-control token and a Bound authority key have different purposes. Key rotation and revocation are changes to the admitted authority contract, not edits that erase prior signatures.\n\n## Proposal → signature → admission → reading\n\nPrepare the proposed lines outside the repository. Each line must use the current wire's fields, forms and required set. Configuration retains its legacy required fields, including `at`. Typed cells, claims and marks use their exact row grammar; `role=reads` or `at` cannot repair an incomplete typed record.\n\nA proposal names `by=target` and omits epoch/signature. The CLI assigns epoch from admitted history when signing. Never copy an epoch from an example or change a signed line's body.\n\nUse the signing and admission transaction in the README. Shell `&&` prevents a failed sign from being followed by land. Successful signing alone does not mean admission. Successful admission alone does not mean every requirement is paid. Fold after land and inspect its states, receipts and exit status.\n\nCLI sign authenticates wire inscriptions. It is different from the object's travelling ceiling sign. The selected Topos decodes spans and supplies origin/witness context; Bound must not guess those from by, widens or a path.\n\n## Reading and withdrawing\n\nAsk only for a view admitted by the project, such as cells. A local join widens that cell with a witness; it leaves the travelling ceiling live. A travelling require supplies a floor. Claims carry distinct origins; their signatures do not by themselves establish independent origins.\n\nFor typed histories, a negative record names the exact id in takes. Withdrawing a claim removes that live observation; withdrawing a join removes that local widening, not the sign. A fresh claim with the same content is a new identity, not resurrection of a withdrawn id. Re-delivery of the same signed bytes is idempotent.\n\nFor configuration, the negative line preserves the exact non-envelope selectors and changes value to withdraw. Do not withdraw and replace identical selectors in the same batch. Use a new epoch when superseding an alphabet declaration. Never withdraw evidence merely to obtain a green verdict.\n\n## Receipts and refusals\n\nreceipts.bound is native fold output. Do not write it by hand, use JSON from a test as a receipt, or copy receipts from another tree. Unchanged inputs can reuse verified region receipts; missing bytes require recomputation or a refusal. A duplicate receipt does not create another origin.\n\nREFUSE·wire means the current grammar does not admit the record. REFUSE·pin/release means named authentic content or its closure is unavailable or does not match. REFUSE·view means the requested view cannot be rendered under its contract. Authority refusal means the signer is not covered. Keep the line and the failed exit status; follow an explicit fix without changing the named digest or dropping a conflicting statement.\n\nrelease/blocks is policy read by the fold. Its admitted category links select existing obligations. The fold prints each missing reading or crossed ceiling as BLOCK; a blocked or incomplete policy is not READY. Read the captured verdict for the exact candidate instead of inferring acceptance from a successful render.\n\n## Repository and PR review\n\nThe accepted TARGET is independent of a contributor's scan. Commit native receipts and admitted renders, not local .bound/ state. A page disagreeing with TARGET must be re-rendered; a ceiling is not lowered to fit the page.\n\nA contribution is a proposed lot with the leaf changes rendered from it. Send that lot for admission by the team's coverage. Do not submit hand-edited lock output as already accepted. Check secrets, extra bound files, foreign vendoring and uncaptured page claims before review.\n\nA review includes the product fold, meaningful suites and verification of the rendered bytes. Preserve their actual output and exit status.\n" at=policy:bound/011-signing-docs by=target form=alphabet measure=text role=writes scope=prose/en/files/public-2 shape=docs/usage.md value=lock +bound-lock/1 about="# Exact release artifact\n\nPacking is a host operation. An archive digest names those archive bytes; it is not the identity of a Topos standing. The release pipeline makes one archive and transfers that same file to its destinations. Repeating a pack operation is not a proof of identical bytes.\n\nThe archive conformance vector declares the host package command, digest algorithm, execution deadline, response bound and its sample packages. It packs each sample once, hashes the resulting bytes, verifies both destination copies, installs offline without package scripts and compares every listed installed member with the input bytes. It executes the installed entry and checks its declared output. Changed archive bytes refuse by digest before they can be treated as the named artifact. The negative control fails when that verification is removed.\n\nThe samples use independent packages with different contents. Their outputs and member digests are captured by the executable vector; their file presence alone is not evidence. The selected publication reader measures this quartet through the existing process contract, and native receipts supply its member status to the plan.\n\nThis is conformance of the packaging recipe. Acceptance of a particular Bound candidate additionally requires the exact archive audit, clean installation and product CLI captures for that archive. A previous archive's captures cannot certify changed implementation bytes. The final candidate must be rebuilt after admitted metadata changes, with every changed member accounted for. The product witness uses the installed reader directly, without a checkout ledger or source conditions.\n\nRendering and installation are different boundaries. README, the manifest and the standard MIT text remain native renders. Publication to a registry or forge is a later owner action; this vector does not publish, authenticate to an account, create a tag or infer an external release from a local file.\n" at=witness:public-contracts-by-operation by=target form=alphabet measure=text role=writes scope=prose/en/files/contract-archive shape=docs/contracts/archive.md value=lock +bound-lock/1 about="# Explanation — historical profile\n\nThe declared view selects idea, what-holds and refuses from the byte-pinned historical document provider. The place owns its language and prose. Idea renders its own heading and body. The other two regions require their declared law readings or captured refusals; absent evidence supplies no invented result. The executable sample uses two unrelated places, checks the complete explanation file, repeats the product fold without a file difference and asks the named view directly. It also refuses a well-formed view asking an unoffered region. This quartet proves own-prose projection and absence under this profile; it does not certify law readings, a rejection corpus, typed-object states or the pending general document contract. Bound does not parse this prose.\n\n# README — historical profile\n\nThe declared view selects hero@3, commands@3 and idea@3 from the byte-pinned historical document provider. The place supplies its name, tagline, language, sentence rule and idea. Commands and measured badges are absent in the sample: no command, number or success is invented to fill them. Two unrelated places check the generated README, a second unchanged product fold and the named view; a declared unoffered region refuses by name. The implementation member is verified against the admitted historical artifact. This quartet proves the selected prose profile, not command execution, badges with measured values or a general document grammar. The eight text@3 demands remain unpaid.\n\n# Citation file — historical profile\n\nThe declared view asks the pinned document provider for cff at resolution 3. It projects the place name, version and optional citation metadata into CFF text. The sample uses the exact implementation member from the admitted historical artifact, names its hash and license, and exercises two unrelated places through the compiled CLI. It checks complete citation bytes and two equal readings; title and version follow each place. An unoffered region refuses by view name. Missing optional metadata is omitted; missing name can produce an empty answer under this historical profile. Rendering is not verification of a scientific claim or an external DOI. This pinned profile does not implement the pending general document contract.\n\n# Guide — historical profile\n\nThe declared view asks seq from the pinned historical document provider. The place owns page/seq lines and their heading. Canonical input order supplies the steps; the provider numbers that order and writes the requested shape. The executable sample uses two unrelated procedures, checks their complete Markdown and reads each view twice without differences. A declared view with an unoffered region refuses by name. An empty step set may have an empty answer; it is not invented evidence. A rendered instruction does not prove that instruction was executed. The implementation bytes remain the existing pinned profile, not a document grammar inside Bound.\n\n# Reference — historical profile\n\nThe declared view combines term, set and ref from the pinned historical document provider. The profile projects the place term and meaning, its selected world names and links to its declared Markdown shapes. The executable sample runs two unrelated places, checks their own term and meaning, the actual selected world and relative guide link, and captures two identical CLI readings. A view asking an unoffered region refuses by name. Missing terms or links can yield empty component answers; these are not measurements or a claim that obligations were paid. These historical regions and selectors belong to the selected Topos; Bound supplies verified inputs and dispatch only. The general document contract remains unpaid.\n\n# Manifest render profile\n\nThis declared view uses the selected verbatim-prose provider at text@3. The place assigns its complete manifest text to its output shape; Bound verifies and dispatches the selected offer and writes that shape. The provider does not infer a package schema, dependency graph or fields from the filename. The sample renders two places with distinct JSON bodies twice and checks exact file bytes. Two distinct prose bodies assigned to the same shape refuse; earlier outputs remain unchanged. This proves rendering, not that arbitrary JSON is an installable package.\n\n# Workflow render profile\n\nThis declared view uses the selected verbatim-prose provider at text@3. The place owns the workflow text and its shape; Bound does not infer a forge or manufacture pipeline steps. The sample writes distinct YAML bodies in two places, reads the rendered files twice and compares exact bytes. Conflicting bodies for one shape refuse without replacing prior outputs. This is a render contract, not evidence that a forge executed, staged or published a release. The release pipeline has its separate artifact gate.\n\n# Usage render profile\n\nThis declared view uses the selected verbatim-prose provider at text@3. A prose line with measure=text and the requested shape supplies its own body. The sample renders distinct Markdown bodies in two places twice and compares exact bytes. Multiple identical bodies are one text; differing bodies for one shape refuse. It invents no sections or documentation schema. This existing profile does not pay the eight general-document demands or validate commands that prose happens to mention; executable commands require their own captured vectors.\n\n# Build configuration — historical profile\n\nThe declared tsconfig view asks the admitted package provider for its build region. It projects the place's build/* lines whose shape matches the requested file: true and false become JSON booleans, other option values remain strings, and include separates its declared alternatives. The byte-fixed fixture names the implementation member and its artifact independently; Bound does not interpret compiler options. Two unrelated places exercise the compiled CLI, check the complete generated configuration and two byte-identical readings. A declared view asking an unoffered region refuses by name. This profile renders configuration; it does not validate compiler options or claim a successful build. An empty option set renders an empty compilerOptions object. It is a pinned historical profile, not the pending general document contract.\n" at=witness:public-contracts-by-operation by=target form=alphabet measure=text role=writes scope=prose/en/files/contract-documents shape=docs/contracts/documents.md value=lock +bound-lock/1 about="# Help view\n\nA declared help view projects the instrument verb and flag table. It is generated from that table, not copied prose or a claim that another world is supported. Asking it does not authorize a line or call a selected external reader. The sample declares view/help value=help, checks the printed three verbs and refuses a declared view whose region has no provider.\n\n# Lines view\n\nA declared lines view projects canonical normative standing as wire lines. It is a configuration reading; it does not compute encounters or turn evidence into authority. Live exact withdrawals disappear from normative standing while authenticated evidence remains inspectable through its own view. The sample verifies signatures and attribution, redelivery ONCE, exact withdrawals, tampering and uncovered writes. A declared missing provider refuses rather than returning an invented reading.\n\n# Receipts view\n\nThe native receipt view projects the fold through the admitted Topos receipt contract. The sample uses the published place profile receipts@8|receipts@0|receipts@1: observations, summary and current region bytes. These are that profile’s declared projections, not a universal enumeration of resolutions. A receipt identifies the actual observed set; it is not an origin or a valuation. The sample obtains a native receipt, verifies its signed delivery from an attest-class key through evidence, and checks idempotent delivery. The refused sample names an uncovered write, tampered signature and declared view without a provider. No harness-written JSON is used as a receipt.\n\n## Public verification\n\nFull-resolution native reading receipts carry the verified canonical UTF-8 input closure in the bytes row and the verified output in the count row, through the wire’s existing about field. Count, digest and measured duration keep their existing meanings. The host verifies the supplied bytes against those digests before reuse; an altered supplied carrier is not replaced by a cached copy. Historical local-only receipts still require their authentic CAS bytes. No private ledger or store is needed to verify a complete public receipt.\n\nFile-region seals hash configuration through Topos’s existing publication projection. Admission envelopes and retired history stay in the authority ledger; live declarations and ordinary file bytes remain inputs. Object history uses its own contract. A public checkout must carry receipts made for its actual files and compiled reader, not seals copied from a different tree. Verification does not run readers, fetch dependencies, refresh receipts or grant authority.\n\n# Why a coordinate\n\n`bound fold --as why` explains the live declarations whose exact `needs` member or `shape` names that coordinate. It prints the selector, witness and value. It does not compute an object encounter or infer authority from a path. The published sample bootstraps two independent places, explains each declared source coordinate and prints `OPEN` for a coordinate no declaration names. That absence is not zero, green or a state. A declared view with no provider refuses by name with a nonzero status. Calling why without a coordinate is not this sample’s acceptance vector; its empty historical capture pays nothing.\n\n# Declared programs\n\nThe programs view asks the selected Topos demand-status projection at resolution 8. Selection, minimum, evidence, elapsed reading and time ceiling coordinates belong to that Topos contract; Bound only hands admitted declarations and region receipts. Program status is derived from that evidence and the declared dependency graph. A demand with no evidence remains unread, its dependant remains blocked, and a missing elapsed reading keeps deadline unread. No cell encounter, origin count or information quantity is computed by this view. The sample uses the published SDK implementation on two unrelated demand chains, captures equal readings twice, names the next unblocked coordinate, and refuses dependency cycles. It does not provide stage conformance evidence or claim either program closed.\n\n# Demand card\n\nThe declared card view asks the selected Topos demand-card projection at resolution 8. It reads the selected demand coordinates, their explicit dependencies and the handed evidence region under selectors declared by that Topos. It does not infer progress from files or convert a declaration into proof. A requirement without evidence is unread; an unpaid predecessor blocks its dependant. The next coordinate is an unblocked unpaid demand. Deadline is unread when no elapsed receipt is handed; absence is not zero. These labels describe program evidence, not Obligations cell states. The sample pins the implementation member from the published Topos SDK, folds two unrelated places twice with equal stdout and refuses a declared dependency cycle. This sample intentionally has no evidence to close either program; it certifies the projection of absence and order, not stage acceptance.\n" at=witness:public-contracts-by-operation by=target form=alphabet measure=text role=writes scope=prose/en/files/contract-views shape=docs/contracts/views.md value=lock +bound-lock/1 about="# Published contracts\n\nEvery public surface names its contract, accepted sample, captured executable vector and rejected sample. Missing members, differing artifact digests and failed vectors remain unpaid. Publication conformance is distinct from installed-artifact acceptance.\n\nThe selected Topos projects each quartet as a reading through the existing wire. Execution proofs are dependency readings; identical vector bytes share one proof. Each reading names its exact handed inputs and dependent receipt digests. Bound verifies those closures and keeps native count/bytes receipts by digest. A closed reading costs no new execution. The publication aggregate reads the quartet receipts; it never starts an inventory batch.\n\nExecution slots, per-execution timeout and response bytes are declared resource lines in the selected Topos. Bounds remain unchanged. A failed reading is not cached as a successful proof. Earlier completed readings stay verified, so a later refusal does not force them to execute again. Changed, missing or corrupt bytes cannot reuse their receipts. Output and execution history retain their exact coordinates.\n\n## Act cost\n\nEach declared reading and each host invocation is measured separately. The total duration of a pass is a diagnostic; it is not the cost of one indivisible act. The cost/act ceiling reads the largest measured act or the remaining unpartitioned host work. Nested invocations are not charged twice. A slow or refused act retains its cost. Native reading receipts retain measured seconds separately from semantic identity; reusing a receipt performs no new reader execution. Missing historical durations are not invented as zero.\n\n## Public verification\n\nFull-resolution native reading receipts carry the verified canonical UTF-8 input closure in the bytes row and the verified output in the count row, through the wire’s existing about field. Count, digest and measured duration keep their existing meanings. The host verifies the supplied bytes against those digests before reuse; an altered supplied carrier is not replaced by a cached copy. Historical local-only receipts still require their authentic CAS bytes. No private ledger or store is needed to verify a complete public receipt.\n\nFile-region seals hash configuration through Topos’s existing publication projection. Admission envelopes and retired history stay in the authority ledger; live declarations and ordinary file bytes remain inputs. Object history uses its own contract. A public checkout must carry receipts made for its actual files and compiled reader, not seals copied from a different tree. Verification does not run readers, fetch dependencies, refresh receipts or grant authority.\n" at=witness:public-receipts-verify-without-private-store by=target form=alphabet measure=text role=writes scope=prose/en/files/publication-contract shape=docs/contracts/publication.md value=lock +bound-lock/1 about="# Using Bound\n\nThis guide covers the current CLI in a place whose wire and authority are already admitted. A fresh unsigned TARGET is a proposal, not a trusted project. The prepared repository is not yet a certified empty-clone bootstrap.\n\n## Before the first fold\n\nYou need the team's accepted TARGET and trust context, authentic bytes for each selected digest, and the readers/views that TARGET names. Do not borrow a neighbouring repository's ledger or copy node_modules to make a missing pin look available.\n\nThe published repository carries exactly TARGET.bound and receipts.bound as bound files. Local admission history lives in the ignored .bound/ store. Published standing excludes the signature envelope; owner public keys retain their signatures.\n\nStart by asking for help and folding the project. If a selected view is unavailable, use the named refusal and its fix; do not invent an output with a similar name.\n\n## Keys and coverage\n\nUse a named key already admitted by the project. The authority contract declares its public key, class and scope coverage. Signing uses a declared port. The lock names `keys/ measure=signer value=`; `signer/timeout` and `signer/response-bytes` bound each invocation. The built-in `file` port reads a matching PKCS8 PEM outside the repository through `--key-file`. For a command port, the host supplies a `BOUND_SIGNERS` registry mapping that admitted name to `{ \"kind\": \"command\", \"executable\": \"...\", \"args\": [] }`. A repository declaration cannot authorize a program. `--signer ` must match the admitted selection.\n\nA new device must have its public key and coverage admitted by an authority that already covers the intended scope. The CLI does not currently certify silent key creation or tap-to-sign. This guide does not substitute a self-authorized fixture key for the team's authority.\n\nFor automation through the file port, supply the private key through the runner's secret storage to a temporary external file with restricted permissions. A command signer receives the lot once as canonical signed bytes, one line per record in order. It returns one canonical wire response per record, containing `by` and `sig`, in that same order. Bound verifies the entire reply against the admitted public key before any admission. Timeout, nonzero exit, missing or invalid replies refuse the whole lot; raw signer output is not logged. Hosts can keep private keys outside Bound through this port. Key generation, storage and rotation belong to the host. Do not print, commit or upload it. A source-control token and a Bound authority key have different purposes. Key rotation and revocation are changes to the admitted authority contract, not edits that erase prior signatures.\n\n## Proposal → signature → admission → reading\n\nPrepare the proposed lines outside the repository. Each line must use the current wire's fields, forms and required set. Configuration retains its legacy required fields, including `at`. Typed cells, claims and marks use their exact row grammar; `role=reads` or `at` cannot repair an incomplete typed record.\n\nA proposal names `by=target` and omits epoch/signature. The CLI assigns epoch from admitted history when signing. Never copy an epoch from an example or change a signed line's body.\n\nUse the signing and admission transaction in the README. Shell `&&` prevents a failed sign from being followed by land. Successful signing alone does not mean admission. Successful admission alone does not mean every requirement is paid. Fold after land and inspect its states, receipts and exit status.\n\nCLI sign authenticates wire inscriptions. It is different from the object's travelling ceiling sign. The selected Topos decodes spans and supplies origin/witness context; Bound must not guess those from by, widens or a path.\n\n## Reading and withdrawing\n\nAsk only for a view admitted by the project, such as cells. A local join widens that cell with a witness; it leaves the travelling ceiling live. A travelling require supplies a floor. Claims carry distinct origins; their signatures do not by themselves establish independent origins.\n\nFor typed histories, a negative record names the exact id in takes. Withdrawing a claim removes that live observation; withdrawing a join removes that local widening, not the sign. A fresh claim with the same content is a new identity, not resurrection of a withdrawn id. Re-delivery of the same signed bytes is idempotent.\n\nFor configuration, the negative line preserves the exact non-envelope selectors and changes value to withdraw. Do not withdraw and replace identical selectors in the same batch. Use a new epoch when superseding an alphabet declaration. Never withdraw evidence merely to obtain a green verdict.\n\n## Receipts and refusals\n\nreceipts.bound is native fold output. Do not write it by hand, use JSON from a test as a receipt, or copy receipts from another tree. Unchanged inputs can reuse verified region receipts; missing bytes require recomputation or a refusal. A duplicate receipt does not create another origin.\n\nREFUSE·wire means the current grammar does not admit the record. REFUSE·pin/release means named authentic content or its closure is unavailable or does not match. REFUSE·view means the requested view cannot be rendered under its contract. Authority refusal means the signer is not covered. Keep the line and the failed exit status; follow an explicit fix without changing the named digest or dropping a conflicting statement.\n\nrelease/blocks is policy read by the fold. Its admitted category links select existing obligations. The fold prints each missing reading or crossed ceiling as BLOCK; a blocked or incomplete policy is not READY. Read the captured verdict for the exact candidate instead of inferring acceptance from a successful render.\n\n## Repository and PR review\n\nThe accepted TARGET is independent of a contributor's scan. Commit native receipts and admitted renders, not local .bound/ state. A page disagreeing with TARGET must be re-rendered; a ceiling is not lowered to fit the page.\n\nA contribution is a proposed lot with the leaf changes rendered from it. Send that lot for admission by the team's coverage. Do not submit hand-edited lock output as already accepted. Check secrets, extra bound files, foreign vendoring and uncaptured page claims before review.\n\nA review includes the product fold, meaningful suites and verification of the rendered bytes. Preserve their actual output and exit status.\n\n## Declaring a demand\n\nA new demand records what remains to be proved. Admission does not create conformance evidence or pay it. An OWED line after land says the declaration was admitted and remains unpaid. Signing authority and conformance evidence are separate inputs.\n\nThe selected program projection reads declared requirements and handed evidence. Missing evidence stays unread; a missing elapsed-time reading is not zero. A dependency cannot close before its requirements and predecessors. Declaring a plan never certifies a release.\n" at=witness:declared-demand-close by=target form=alphabet measure=text role=writes scope=prose/en/files/public-2 shape=docs/usage.md value=lock +bound-lock/1 about="# Walk\n\n`bound fold --as walk@` compares the admitted place with an authenticated peer inventory. Resolution is interpreted by the declared Topos selection and projection contract; it is not restricted to three fixed numbers. The wire declares region membership, context, origin and cuts. The output names touched regions, open regions and payload bytes; protocol and imported bytes carry their own units.\n\nForeign history retains its signed origin epoch. Sender keys authenticate that history and never grant coverage or independent origins in the receiver. Whole-region prefixes are verified before ingress. Import and the receiver-signed local receipt commit atomically; only that receipt advances the receiver's local epoch. Foreign withdrawals are confined to the same authenticated origin and exact identifier. A repeated valid delivery adds no lines and retains its existing import receipt. A rejected or interrupted ingress adds neither evidence nor a receipt.\n\nThe published sample uses the same compiled public reader on measurement and artifact places. It compares equal summaries, opens a differing region, exchanges at intermediate declared resolutions, converges by union, retains disagreement and verifies replay after a later local act. It rejects tampered payloads, missing records, unauthorized signatures, non-prefix epochs and undeclared context changes. It interrupts a real receiver signer and verifies unchanged ingress and local history. Dead-owner recovery is a separate host action; this view does not silently recover it. The typed object's origin-local claims and withdrawals are a separate conformance vector, not inferred from configuration counts.\n" at=witness:publish-native-walk-contract by=target form=alphabet measure=text role=writes scope=prose/en/files/view-walk shape=docs/contracts/view-walk.md value=lock +bound-lock/1 about="# fold\n\n`bound fold` reads the admitted place. Configuration output names readings and says no encounters computed; its counts are not independent-origin states. A declared cells view projects admitted typed history into Obligations. A selected world defines other views; its contract decides when empty output is valid. A refusal or nonzero status wins over any parseable diagnostic stdout. `--check` verifies receipts without inventing a missing reading. The published evidence vector folds fresh places, preserves admitted key attribution, reads a native receipt and checks exact withdrawals. The typed-object quartet covers object states separately.\n\n# land\n\n`bound land ` admits authenticated lines through the same boundary used by signing and previews. Authority, coverage, historical wire and typed context remain distinct checks. Unknown wire and tampered signatures refuse. Exact redelivery returns ONCE; it does not append another origin or grant new authority. Withdrawals remain exact under their declared contract. A refusal does not append a partial act. The published evidence vector lands fresh places, refuses unauthorized writes and tampering, redelivers signed bytes and exercises exact withdrawals. The signing-port vector additionally checks interrupted or invalid command responses do not land a partial lot.\n\n# sign\n\n`bound sign ` returns canonical signed lines after validating the whole lot. The admitted key selects a declared signer; `--signer` selects the same port explicitly. File and command mechanisms use one port. Topos signing-lot/1 frames canonical bytes in lot order, one invocation per lot, and returns signatures and public-key IDs. Verification checks the admitted public key, independently of the mechanism. A command is invoked without a shell and under declared bounds. No secret output is disclosed in refusals. Missing, invalid, partial, timed-out or failed responses refuse; `land` cannot commit their partial output. The sample compares file and command signatures and landed lines, checks invocation count and ledger hashes, and refuses an unknown wire version. The sample uses ephemeral keys outside the place; no owner key is included.\n" at=witness:public-contracts-by-operation by=target form=alphabet measure=text role=writes scope=prose/en/files/contract-cli shape=docs/contracts/cli.md value=lock +bound-lock/1 about="## Typed cell, claim and mark records\n\nThe object profile is selected by admitted `wire/object/*` claims in a historical wire snapshot. The epoch of `wire/object/types` is its activation E; a typed record must have epoch >= E. An older record keeps the older grammar. Merely adding object words to `wire/fields` does not admit a typed profile.\n\n`fromLine` selects grammar before validating required fields: a record without `type` remains configuration, retaining its required `at`, `role`, `form`, `measure` and `value`; a typed record selects its exact required/allowed row. Configuration cannot carry object-only fields. An incomplete typed record receives no configuration defaults. The parse result distinguishes configuration from cell/claim/mark. `sign=+1|-1` is an object act, `sig` its signature envelope, and a host sign operation produces that envelope.\n\nThe common object envelope is `type`, `scope`, `id`, `epoch`, `by`, `sig`. Object records reject `at`: epoch orders acts, and `widens` names a local join witness. The following is the declared reference profile. The admitted row alphabets, not this table or a host decoder, are the source of required/allowed field permission.\n\n| Row | Fields in addition to the common envelope | Meaning |\n| --- | --- | --- |\n| cell | form, measure, params, restsOn, topos | Define a cell and its selected form/context. |\n| claim/positive | sign, origin, value | Observe an encoded span, sign=+1. |\n| claim/negative | sign, takes | Withdraw an exact claim ID, sign=-1. |\n| mark/travelling | sign, pole, reach, value | Ceiling sign: sign=+1, pole=ceiling, reach=travels. |\n| mark/local | sign, pole, reach, value, widens | Local join: sign=+1, pole=ceiling, reach=local; another mark, retaining the travelling sign. |\n| mark/floor-travelling | sign, pole, reach, value | Travelling require: sign=+1, pole=floor, reach=travels; no widens. |\n| mark/negative | sign, takes | Withdraw an exact mark ID, sign=-1; no pole/reach/widens. |\n\nEach row has both `wire/object/required/` and `wire/object/allowed/`. Unknown keys, missing required keys, floor/local, floor+widens, and travelling widening refuse without coercion. A configuration demand is unrelated to a floor mark. `by` authenticates a signing key; it is not an independent observation origin.\n\nFor a cell, `restsOn=none` represents no parents; otherwise it is a canonical byte-ordered alphabet of coordinates. Several parents are permitted. Only declared cell-coordinate edges form object rest; a directory prefix, a configuration artifact digest, and a host source location do not. Context validation rejects reachable cycles before algebraic parts are requested.\n\nThe cell's `topos` names folded standing, and its `params` identifies declared parameter bytes. A selected provider decodes values and supplies origin/witness authorization from admitted evidence. A host does not infer interval endpoints, map a key to an origin, or accept widens as its own witness. Missing pin, artifact, decoder, origin or witness refuses by cause. Cell definitions and pins are immutable in this profile; migration is not inferred.\n\n`objectHistory` preserves typed history separately from configuration; `validateObjectContext` checks IDs, cell ownership, exact takes, witness order and declared rest under the selected context. Exact redelivery is idempotent; one ID with different canonical content refuses. Signature-envelope differences never bypass verification.\n\nAfter admission, the instrument projects the acts into Obligations. Sign and require travel along declared rest; a witnessed join is local. Descendants inherit travelling marks without local widening. Live exact-ID withdrawals remain confined to their authenticated history. Keys, snapshots, signing devices and repeated receipts do not create independent origins. Compatible meets are not forks. Object states and their precedence come from Obligations; configuration folds do not compute object encounters.\n" at=witness:minimal-contract-015 by=target form=alphabet measure=text role=writes scope=prose/en/files/contract-typed-object shape=docs/contracts/typed-object.md value=lock bound-lock/1 about=", & " at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/cite/and value=lock bound-lock/1 about="\nOne history, several viewsIllustrative spatial view of B, C, G and independent D. C rests on B and G rests on C. B's travelling ceiling is 0 to 50 and travelling floor 40 to 100. Its local join widens only B to 0 to 100. Region receipts retain selected topos and implementation identity. Background points are decorative, not additional measured cells.\n\n\n\n\n\n\n\n\n\nTHE ALGEBRA IN 60 SECONDS\nOne history. Several views.\nA cell keeps its readings. A connection carries only what travels.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nTravelling bounds\nceiling 0..50floor 40..100\nB → C → G\n\nLocal join\nB widens to 0..100\nThe travelling sign stays live.\n\n\nB\nC\nG\nD\nceiling 0..50\nceiling 0..50\nIndependent cell\nD declares no rest on B.\nRegion: the cells selected by a view\n\nSelected topos\nForms and views · pinned folded standing\nReceipts at resolution 1\nSemantic inputs + selected implementation\nIllustrative layout · connections denote declared rest · position and size do not measure importance\n" at=policy:public-prose by=target form=alphabet measure=text role=writes scope=prose/en/files/public-3 shape=docs/readme-assets/atlas.svg value=lock bound-lock/1 about="A REFUSE prints its line and stops. Nothing after it is a fact." at=witness:project-coordinates-are-relative by=target form=alphabet kind=axiom measure=status needs=samples/yes/a-refuse-plants.json|samples/no/a-refuse-plants.json role=demands scope=law/a-refuse-plants value=present @@ -10,24 +18,48 @@ bound-lock/1 about="A fold" at=policy:bound/readme by=target form=alphabet measu bound-lock/1 about="A fold, live" at=policy:bound/door by=target form=alphabet measure=text role=writes scope=prose/en/seq/heading value=lock bound-lock/1 about="A line" at=policy:bound/readme by=target form=alphabet measure=text role=writes scope=prose/en/figure/line/heading value=present bound-lock/1 about="A lock is the set of lines a place is bound by. A receipt is what a reader saw. The fold is their meet. Each line carries scope, role, form, measure, value, needs, at, by, epoch, sig." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/the-object value=present +bound-lock/1 about="A new snapshot has a new evidence identity, not automatically a new independent origin. Preserve the admitted attribution and the chosen Topos's independence contract. Repeated readings, time periods, signing devices and receipt copies must not manufacture freedom." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/01 value=lock +bound-lock/1 about="A port's digest identifies executable bytes, not permission to execute them. Coverage, request authority, bounds, framing and resource dependencies are checked separately. `port/**` coverage is a proposed namespace policy to admit, not an existing universal authority rule." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/05 value=lock bound-lock/1 about="A second independent reader must agree. The fold rebuilds from the files alone, offline." at=witness:project-coordinates-are-relative by=target form=alphabet kind=axiom measure=status needs=samples/yes/verify-agrees.json|samples/no/verify-agrees.json role=demands scope=law/verify-agrees value=present +bound-lock/1 about="A sequence of declared readings is not an indivisible act. Preserve total pass time as a diagnostic; measure each reading and host invocation, account for unpartitioned work, keep refusals and the 60-second ceiling unchanged." at=witness:declared-act-cost by=target form=alphabet measure=text role=writes scope=rationale/015/cost-boundary value=present +bound-lock/1 about="Algebraic vacuity, absence of observations and lack of recent activity are separate facts. A view may expose inactivity over an admitted window, but cannot rename it algebraic vacuity or read missing history as zero." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/02 value=lock bound-lock/1 about="Bind a package release with the pipeline views. Bind a page to its receipts with view/readme. Refuse a dependency drift with dep pins. Ask a second head that must agree." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/learn value=present bound-lock/1 about="Bound is the application of that algebra: signed bounds, folded by one meet, refused when they fork." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/paper value=present -bound-lock/1 about="Bound reads a project's admitted statements and observations through its selected Topos, then renders the declared views and records their inputs in receipts. The example below explains the object; a file-fold alone does not calculate its intervals.\n\n## A meeting everyone can understand\n\nAna is available from 10 to 14, Luis from 12 to 16, and the room from 10 to 13. Their common availability is 12 to 13. A boss available from 18 to 20 makes the encounter incompatible. Withdrawing that exact reading restores the overlap; Ana, Luis and the room remain.\n\nWith an interval form, those are object operations: observe independent claims, meet them, withdraw by id, and read the state. A narrower compatible meet is not a fork. Folding a file of declarations alone does not calculate meeting availability.\n\nThe same pattern applies to a delivery window, a sensor's allowed range, or an agreed performance budget. The chosen topos determines the units and how evidence is obtained. Bound does not supply a meeting-specific rule.\n\n## See how information holds together\n\n![Cells, travelling bounds and a local join](https://raw.githubusercontent.com/Lapxo/bound/2053bb6d6188f04538114eae6a0add5166944ed3/docs/readme-assets/atlas.svg)\n\nA travelling ceiling on B reaches C and G through their declared rest. A local join widens B alone. D is independent. The figure shows those relations; point size and camera distance do not measure information.\n\n| State | Meaning |\n| --- | --- |\n| REQUIRED | Compatible bounds, fewer than two independent origins. |\n| FREE | Independent origins meet and their encounter fits the bounds. |\n| CONFLICT | Bounds conflict, or eligible claims have no common encounter. |\n| FORBIDDEN | An inhabited encounter does not fit the bounds. |\n\nBounds are checked before origins and claims. A receipt is evidence of a reading, not another origin. Duplicating one does not add freedom.\n\n## Change a project without erasing evidence\n\nWork in the project's directory. Use an existing admitted key identifier and its matching private key stored outside every repository. The admitted key also names its signer with `keys/ measure=signer value=file`; `signer/timeout` and `signer/response-bytes` declare its limits. Your public key and coverage belong to the authority contract; possession of a private key alone does not authorize a scope.\n\n```sh\nexport BOUND_KEY_ID='your-admitted-key-id'\nexport BOUND_KEY_FILE=\"$HOME/Private/keys/your-device.pem\"\nlot_dir=\"$(mktemp -d)\"\n```\n\nHave the selected view produce a proposal at `$lot_dir/proposal.bound`, or prepare the project's permitted lines there for review. Unsigned proposals use `by=target`, without a preassigned epoch or `sig`. Lots stay outside the repository; the committed bound files are only `TARGET.bound` and `receipts.bound`.\n\n```sh\nnpx @lapxo/bound@0.1.4 sign \"$lot_dir/proposal.bound\" \\\n --key \"$BOUND_KEY_ID\" --key-file \"$BOUND_KEY_FILE\" \\\n > \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.4 land \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.4 fold\n```\n\n`sign` assigns the admitted epoch and writes the signed lot to stdout. `land` validates the whole lot before admission. A refusal is evidence to inspect; it is not success. Do not proceed after a failed signature or admission. The key file is a PKCS8 private key matching the admitted public key; do not put it in the lot, source tree, package or CI artifacts.\n\nFor typed object withdrawals, `takes` names the exact claim or mark id. Removing a local join leaves the travelling sign live. For untyped configuration, use the wire's exact withdrawal selectors; do not combine withdrawal and replacement with identical selectors in one lot. Wire alphabet updates supersede by epoch.\n\n[Authority, withdrawals, receipts and PR review](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md).\n\n## Select a topos by what it declares\n\n`sources/` says where a world can be obtained. An admitted `uses/` names the digest of that topos's folded standing: canonical live claims in wire byte order, excluding signature envelopes and host shape. Re-signing the same standing preserves the pin. A changed live form, class, view or offer changes it.\n\n`restsOn` closes artifact bytes separately. A capsule is one offer. Forms, classes and views need no capsule merely to be selected. Runtime and packing do not define standing identity. npm dependency ranges remain package metadata; they are not standing pins.\n\n| Responsibility | Owner |\n| --- | --- |\n| Meet, state, live acts and rest | Obligations |\n| Wire, forms, classes, views and offer contracts | Topos |\n| Admission, folding and evidence | Bound |\n| Domain measurement and representation | Selected topos |\n| Storage, transport and execution | Host |\n\nCell `restsOn` is the object's relation. Directory prefixes and file summaries are host coordinates, not object rest. Wire tokens are protocol constants, not organization, host, path or key literals.\n\n## Repository rules\n\nCommit `TARGET.bound`, `receipts.bound` and the outputs the forge reads. Ignore `.bound/` from the first line of `.gitignore`. Keep proposals, signed lots, keys, ledgers, caches and dependency blobs outside the published tree.\n\nThe lock is the project's own contract and pins. Read a dependency's declarations from its selected standing; do not copy its lines into your lock. README, package metadata and workflows must be renders of admitted declarations. A scan is an observation, not permission to lower a ceiling.\n\nA PR proposes lines and the leaf changes they render. The judge uses the team's accepted contract independently of the proposed revision. Preserve refusals, conflicting origins and unpaid demands. [Repository and contribution rules](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md#repository-and-pr-review).\n\n## An atlas you can question\n\nInformation can share a history without sharing a single presentation. The same admitted cells can support a compact status view, a spatial view of their relations, or a focused reading of one disagreement. Each view asks for a region and resolution; its selected topos determines the representation.\n\nThis makes changes inspectable. A local act can remain local, travelling bounds can reach dependent cells, and a receipt can name the inputs of the reading you saw. You can ask what changed and what depends on it without turning a drawing into the algebra.\n\nA pin names standing, not a download URL or runtime entry. Its declared artifact dependencies close the bytes needed for an offered operation. The boundary lets a form or view remain meaningful even when it has no executable capsule.\n\nUse Bound where independently attributed observations must be judged against an accepted contract: compatibility between components, operational limits, or a team's project requirements. The selected topos must supply the actual measurements; a digest identifies the evidence without declaring it true.\n\n[Contribute a counterexample or a proposed lot](CONTRIBUTING.md)." at=witness:bound/014-candidate by=target form=alphabet measure=text role=writes scope=prose/en/idea value=present +bound-lock/1 about="Bound reads a project's admitted statements and observations through its selected Topos, then renders the declared views and records their inputs in receipts. The example below explains the object; a file-fold alone does not calculate its intervals.\n\n## Use Bound in a project\n\nFrom a project with an admitted lock and selected views, inspect its standing, ask for its evidence, then verify the committed outputs:\n\n```sh\nnpx @lapxo/bound@0.1.5 fold --as lines\nnpx @lapxo/bound@0.1.5 fold --as receipts@1\nnpx @lapxo/bound@0.1.5 fold --check\n```\n\nUse this flow to review a project change or check a dependency's declared contract. `--check` verifies existing evidence; it does not execute a missing reading. A file fold names readings and explicitly says that it computed no encounters.\n\nIndependent observations are judged through the declared typed cells view. The selected topos supplies the form, origin evidence and bounds. Bound keeps attribution and exact-ID withdrawals through the fold.\n\nA selected form can instead describe a set of artifacts, a delivery interval or another domain's values. The project declares the form, origin evidence and views; Bound does not infer them from filenames or units.\n\n\n## A meeting everyone can understand\n\nAna is available from 10 to 14, Luis from 12 to 16, and the room from 10 to 13. Their common availability is 12 to 13. A boss available from 18 to 20 makes the encounter incompatible. Withdrawing that exact reading restores the overlap; Ana, Luis and the room remain.\n\nWith an interval form, those are object operations: observe independent claims, meet them, withdraw by id, and read the state. A narrower compatible meet is not a fork. Folding a file of declarations alone does not calculate meeting availability.\n\nThe same pattern applies to a delivery window, a sensor's allowed range, or an agreed performance budget. The chosen topos determines the units and how evidence is obtained. Bound does not supply a meeting-specific rule.\n\n## See how information holds together\n\n![Cells, travelling bounds and a local join](https://raw.githubusercontent.com/Lapxo/bound/2053bb6d6188f04538114eae6a0add5166944ed3/docs/readme-assets/atlas.svg)\n\nA travelling ceiling on B reaches C and G through their declared rest. A local join widens B alone. D is independent. The figure shows those relations; point size and camera distance do not measure information.\n\n| State | Meaning |\n| --- | --- |\n| REQUIRED | Compatible bounds, fewer than two independent origins. |\n| FREE | Independent origins meet and their encounter fits the bounds. |\n| CONFLICT | Bounds conflict, or eligible claims have no common encounter. |\n| FORBIDDEN | An inhabited encounter does not fit the bounds. |\n\nBounds are checked before origins and claims. A receipt is evidence of a reading, not another origin. Duplicating one does not add freedom.\n\n## Change a project without erasing evidence\n\nWork in the project's directory. Use an existing admitted key identifier and its matching private key stored outside every repository. The admitted key also names its signer with `keys/ measure=signer value=file`; `signer/timeout` and `signer/response-bytes` declare its limits. Your public key and coverage belong to the authority contract; possession of a private key alone does not authorize a scope.\n\n```sh\nexport BOUND_KEY_ID='your-admitted-key-id'\nexport BOUND_KEY_FILE=\"$HOME/Private/keys/your-device.pem\"\nlot_dir=\"$(mktemp -d)\"\n```\n\nHave the selected view produce a proposal at `$lot_dir/proposal.bound`, or prepare the project's permitted lines there for review. Unsigned proposals use `by=target`, without a preassigned epoch or `sig`. Lots stay outside the repository; the committed bound files are only `TARGET.bound` and `receipts.bound`.\n\n```sh\nnpx @lapxo/bound@0.1.5 sign \"$lot_dir/proposal.bound\" \\\n --key \"$BOUND_KEY_ID\" --key-file \"$BOUND_KEY_FILE\" \\\n > \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.5 land \"$lot_dir/signed.bound\" &&\nnpx @lapxo/bound@0.1.5 fold\n```\n\n`sign` assigns the admitted epoch and writes the signed lot to stdout. `land` validates the whole lot before admission. A refusal is evidence to inspect; it is not success. Do not proceed after a failed signature or admission. The key file is a PKCS8 private key matching the admitted public key; do not put it in the lot, source tree, package or CI artifacts.\n\nFor typed object withdrawals, `takes` names the exact claim or mark id. Removing a local join leaves the travelling sign live. For untyped configuration, use the wire's exact withdrawal selectors; do not combine withdrawal and replacement with identical selectors in one lot. Wire alphabet updates supersede by epoch.\n\n[Authority, withdrawals, receipts and PR review](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md).\n\n## Select a topos by what it declares\n\n`sources/` says where a world can be obtained. An admitted `uses/` names the digest of that topos's folded standing: canonical live claims in wire byte order, excluding signature envelopes and host shape. Re-signing the same standing preserves the pin. A changed live form, class, view or offer changes it.\n\n`restsOn` closes artifact bytes separately. A capsule is one offer. Forms, classes and views need no capsule merely to be selected. Runtime and packing do not define standing identity. npm dependency ranges remain package metadata; they are not standing pins.\n\n| Responsibility | Owner |\n| --- | --- |\n| Meet, state, live acts and rest | Obligations |\n| Wire, forms, classes, views and offer contracts | Topos |\n| Admission, folding and evidence | Bound |\n| Domain measurement and representation | Selected topos |\n| Storage, transport and execution | Host |\n\nCell `restsOn` is the object's relation. Directory prefixes and file summaries are host coordinates, not object rest. Wire tokens are protocol constants, not organization, host, path or key literals.\n\n## Repository rules\n\nCommit `TARGET.bound`, `receipts.bound` and the outputs the forge reads. Ignore `.bound/` from the first line of `.gitignore`. Keep proposals, signed lots, keys, ledgers, caches and dependency blobs outside the published tree.\n\nThe lock is the project's own contract and pins. Read a dependency's declarations from its selected standing; do not copy its lines into your lock. README, package metadata and workflows must be renders of admitted declarations. A scan is an observation, not permission to lower a ceiling.\n\nA PR proposes lines and the leaf changes they render. The judge uses the team's accepted contract independently of the proposed revision. Preserve refusals, conflicting origins and unpaid demands. [Repository and contribution rules](https://github.com/Lapxo/bound/blob/2053bb6d6188f04538114eae6a0add5166944ed3/docs/usage.md#repository-and-pr-review).\n\n## An atlas you can question\n\nInformation can share a history without sharing a single presentation. The same admitted cells can support a compact status view, a spatial view of their relations, or a focused reading of one disagreement. Each view asks for a region and resolution; its selected topos determines the representation.\n\nThis makes changes inspectable. A local act can remain local, travelling bounds can reach dependent cells, and a receipt can name the inputs of the reading you saw. You can ask what changed and what depends on it without turning a drawing into the algebra.\n\nA pin names standing, not a download URL or runtime entry. Its declared artifact dependencies close the bytes needed for an offered operation. The boundary lets a form or view remain meaningful even when it has no executable capsule.\n\nUse Bound where independently attributed observations must be judged against an accepted contract: compatibility between components, operational limits, or a team's project requirements. The selected topos must supply the actual measurements; a digest identifies the evidence without declaring it true.\n\n[Contribute a counterexample or a proposed lot](CONTRIBUTING.md).\n\n## Foundations and related libraries\n\nThe two-sided constraint object is described in Nahum Ochoa's [Two-Sided Constraints on a Valued Lattice](https://doi.org/10.5281/zenodo.21858428), DOI `10.5281/zenodo.21858428`. Bound uses the object through [Obligations](https://github.com/Lapxo/obligations); [Topos](https://github.com/Lapxo/topos) supplies the wire and contracts for forms, views and selected worlds. Bound admits, folds and retains evidence across those declared boundaries. A digest identifies bytes; it does not certify that an observation is true.\n" at=witness:minimal-readme-015 by=target form=alphabet measure=text role=writes scope=prose/en/idea value=present bound-lock/1 about="Cite it as {name}." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/cff/name value=lock bound-lock/1 about="Cite it by the paper it rests on, Two-Sided Constraints on a Valued Lattice." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/cff/paper value=lock +bound-lock/1 about="Conflicting live wire declarations refuse by scope; no vacuous alphabet." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/wire/unique-live-alphabet.md|samples/yes/wire/unique-live-alphabet.json|vectors/wire/unique-live-alphabet.json|samples/no/wire/unique-live-alphabet.json role=demands scope=wire/unique-live-alphabet value=present bound-lock/1 about="Declare what must hold. Read what does. Keep the evidence." at=policy:bound/historical-prose by=target form=alphabet measure=text role=writes scope=docs/tagline value=present bound-lock/1 about="Declared runtime processes participate in the instrument implementation identity." at=policy:bound/receipts by=target form=alphabet kind=process measure=id needs=dist/cli/host.js|dist/cli/observe.js|dist/host/located.js|dist/host/provide.js role=writes scope=process/runtime value=present +bound-lock/1 about="Deterministic repair means a reproducible proposed lot, not automatic human approval. A red can lack measurements, authority, a witness or a unique repair. Such a case returns an explicit unmet requirement; it never invents a paying line." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/06 value=lock +bound-lock/1 about="Elapsed days from 2026-10-07; deadline 2026-10-21. An unread clock is not payment." at=policy:bound/015-plan by=target form=interval measure=days role=demands scope=plan/0.1.5/time value=0..14 +bound-lock/1 about="Every selected public coordinate has its exact contract/yes/vector/no quartet and executable conformance; availability is not proof." at=witness:publication-is-measured by=target form=interval measure=count needs=docs/contracts/publication.md|docs/contracts/publication.inventory.json role=reads scope=contract/published value=0..0 +bound-lock/1 about="Exact npm archive integrity for acorn 8.19.0. Library metadata, not Topos standing or a release mount; npm verifies the matching package-lock integrity." at=policy:host-module-identity by=target form=alphabet measure=id role=writes scope=dep/acorn value=sha512:a09940dd78919bb0b293aa850f6267f1a93d07b8d2cb4ab2d340033b7fbc7694f42d28c58a1418bf80b4d8b142498255dd0dfbc58c30472e66f88a48894cea5b +bound-lock/1 about="Exchange cost requires units: transferred regions, payload bytes, protocol overhead and verification work. Reused regions transfer zero semantic payload. Variable-size regions cannot obey a byte ceiling stated merely as a count of open regions." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/03 value=lock bound-lock/1 about="First session" at=policy:bound/readme by=target form=alphabet measure=id role=writes scope=page/seq/heading value=present bound-lock/1 about="First use" at=policy:bound/readme by=target form=alphabet measure=text role=writes scope=prose/en/commands/heading value=lock +bound-lock/1 about="Historical file-fold illustration using cellOfLines; not the typed object. No admitted native observation vector certifies it in this release. Re-entry requires its contract, two unrelated native CLI places, a rejection sample and the exact installed vector. No current view is advertised; withdrawal is not payment." at=witness:withdraw-unpublished-legacy-views by=target form=alphabet measure=status needs=docs/contracts/view-figure-fold.md|samples/yes/view-figure-fold.json|vectors/view-figure-fold.json|samples/no/view-figure-fold.json role=demands scope=plan/0.1.6/view-figure-fold value=present +bound-lock/1 about="Historical illustration depends on genuine captured refusals; no complete shipped conformance vector currently certifies it. Re-entry requires its contract, two unrelated native CLI places, a rejection sample and the exact installed vector. No current view is advertised; withdrawal is not payment." at=witness:withdraw-unpublished-legacy-views by=target form=alphabet measure=status needs=docs/contracts/view-figure-refuses.md|samples/yes/view-figure-refuses.json|vectors/view-figure-refuses.json|samples/no/view-figure-refuses.json role=demands scope=plan/0.1.6/view-figure-refuses value=present +bound-lock/1 about="Historical line illustration depends on native said/lines receipts; no complete shipped conformance vector currently certifies it. Re-entry requires its contract, two unrelated native CLI places, a rejection sample and the exact installed vector. No current view is advertised; withdrawal is not payment." at=witness:withdraw-unpublished-legacy-views by=target form=alphabet measure=status needs=docs/contracts/view-figure-line.md|samples/yes/view-figure-line.json|vectors/view-figure-line.json|samples/no/view-figure-line.json role=demands scope=plan/0.1.6/view-figure-line value=present +bound-lock/1 about="Historical line region reads sources/; the native CLI returned empty and does not compute the promised standing pin. URLs are not pins. Re-entry requires its contract, two unrelated native CLI places, a rejection sample and the exact installed vector. No current view is advertised; withdrawal is not payment." at=witness:withdraw-unpublished-legacy-views by=target form=alphabet measure=status needs=docs/contracts/view-release.md|samples/yes/view-release.json|vectors/view-release.json|samples/no/view-release.json role=demands scope=plan/0.1.6/view-release value=present bound-lock/1 about="How Bound reads a project" at=policy:bound/historical-prose by=target form=alphabet measure=text role=writes scope=prose/en/idea/heading value=lock bound-lock/1 about="How to add or change a lock" at=policy:bound/readme by=target form=alphabet measure=id role=writes scope=page/exchange/heading value=present bound-lock/1 about="In an empty folder, write a three-line TARGET.bound, run bound ., and see the stranger four lines printed. Then land, then bound . --as card --key . A fact is a printed line." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/first-use/lead value=lock +bound-lock/1 about="Inventory actual installed public surface; missing artifacts remain unpaid." at=witness:public-contracts-by-operation by=target form=alphabet measure=status needs=docs/contracts/archive.md|docs/contracts/cli.md|docs/contracts/documents.md|docs/contracts/evidence-view.md|docs/contracts/typed-object.md|docs/contracts/view-walk.md|docs/contracts/views.md|samples/no/archive-conformance.json|samples/no/historical-document-views.json|samples/no/native-views.json|samples/no/program-views.json|samples/no/query-views.json|samples/no/signing-port.json|samples/no/typed-object.json|samples/no/walk.json|samples/yes/archive-conformance.json|samples/yes/historical-document-views.json|samples/yes/native-views.json|samples/yes/program-views.json|samples/yes/query-views.json|samples/yes/signing-port.json|samples/yes/typed-object.json|samples/yes/walk.json|vectors/archive-conformance.json|vectors/historical-document-views.json|vectors/native-views.json|vectors/program-views.json|vectors/query-views.json|vectors/signing-port.json|vectors/typed-object.json|vectors/walk-publication.json role=demands scope=plan/0.1.5/0 value=present bound-lock/1 about="Joining two files is putting their lines together: order does not matter, and a line twice is still one. A disagreement does not break the merge; it shows as CONFLICT. A file travels alone. Bound never guesses: one origin is REQUIRED, not FREE. Each of these is a test in bound/test/laws.test.ts." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/what-holds/lead value=lock bound-lock/1 about="Land the batch with the key that covers it." at=policy:bound/readme by=target form=alphabet measure=id role=writes scope=page/seq/key value=present +bound-lock/1 about="MIT License\n\nCopyright (c) 2026 Lapxo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." at=witness:bound/015-standard-mit by=target form=alphabet measure=text role=writes scope=prose/en/files/license shape=LICENSE value=lock bound-lock/1 about="No fourth verb. A batch lands whole or not at all. A bound nobody has a reading for is refused. A changed byte of a signed line does not verify. Bound does not know whether a claim is true in the world: it knows who signed what, and whether the ranges meet." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/refuses/lead value=lock +bound-lock/1 about="Not every existing export needs removal because its docs are incomplete. Inventory supported package exports, CLI verbs/views, record families and provider-facing protocols. Distinguish documented public surface from internal implementation files; review accidental published subpaths. Withdraw public support through an explicit compatibility decision, not by erasing history or inventing new verbs." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/07 value=lock bound-lock/1 about="One lot lands one place. A lot for many places lands the same lines at each." at=witness:project-coordinates-are-relative by=target form=alphabet kind=axiom measure=status needs=samples/yes/one-lot-one-place.json|samples/no/one-lot-one-place.json role=demands scope=law/one-lot-one-place value=present bound-lock/1 about="Only the declared license is requested by this historical page." at=policy:bound/historical-prose by=target form=alphabet measure=id role=writes scope=docs/badges value=license +bound-lock/1 about="Optional Stage 3: carry only if unpaid at the red time ceiling; no payment inferred." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/015-stage-3.md|samples/yes/015-stage-3.json|vectors/015-stage-3.json|samples/no/015-stage-3.json role=demands scope=plan/0.1.6/3 value=present +bound-lock/1 about="Optional Stage 4: carry only if unpaid at the red time ceiling; no payment inferred." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/015-stage-4.md|samples/yes/015-stage-4.json|vectors/015-stage-4.json|samples/no/015-stage-4.json role=demands scope=plan/0.1.6/4 value=present +bound-lock/1 about="Optional Stage 6: carry only if unpaid at the red time ceiling; no payment inferred." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/015-stage-6.md|samples/yes/015-stage-6.json|vectors/015-stage-6.json|samples/no/015-stage-6.json role=demands scope=plan/0.1.6/6 value=present +bound-lock/1 about="Optional Stage 7: carry only if unpaid at the red time ceiling; no payment inferred." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/015-stage-7.md|samples/yes/015-stage-7.json|vectors/015-stage-7.json|samples/no/015-stage-7.json role=demands scope=plan/0.1.6/7 value=present +bound-lock/1 about="Optional Stage 8: carry only if unpaid at the red time ceiling; no payment inferred." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/015-stage-8.md|samples/yes/015-stage-8.json|vectors/015-stage-8.json|samples/no/015-stage-8.json role=demands scope=plan/0.1.6/8 value=present +bound-lock/1 about="Optional Stage 9: carry only if unpaid at the red time ceiling; no payment inferred." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/015-stage-9.md|samples/yes/015-stage-9.json|vectors/015-stage-9.json|samples/no/015-stage-9.json role=demands scope=plan/0.1.6/9 value=present +bound-lock/1 about="Output names the computation and distinguishes valid empty output from refusal." at=witness:public-contracts-by-operation by=target form=alphabet measure=status needs=docs/contracts/cli.md|docs/contracts/typed-object.md|samples/no/native-views.json|samples/no/typed-object.json|samples/yes/native-views.json|samples/yes/typed-object.json|vectors/native-views.json|vectors/typed-object.json restsOn=plan/0.1.5/1 role=demands scope=plan/0.1.5/2 value=present bound-lock/1 about="Pending general document projection at .github/workflows/release.yml; no automatic output is claimed by this capability demand." at=policy:own-prose by=target form=alphabet measure=id role=demands scope=view/files/workflow/release value=text@3 bound-lock/1 about="Pending general document projection at .github/workflows/tag.yml; no automatic output is claimed by this capability demand." at=policy:own-prose by=target form=alphabet measure=id role=demands scope=view/files/workflow/tag value=text@3 bound-lock/1 about="Pending general document projection at .github/workflows/test.yml; no automatic output is claimed by this capability demand." at=policy:own-prose by=target form=alphabet measure=id role=demands scope=view/files/workflow/test value=text@3 @@ -37,6 +69,8 @@ bound-lock/1 about="Pending general document projection at docs/readme-assets/at bound-lock/1 about="Pending general document projection at docs/usage.md; no automatic output is claimed by this capability demand." at=policy:own-prose by=target form=alphabet measure=id role=demands scope=view/files/public-2 value=text@3 bound-lock/1 about="Pending general document projection at package.json; no automatic output is claimed by this capability demand." at=policy:own-prose by=target form=alphabet measure=id role=demands scope=view/files/manifest value=text@3 bound-lock/1 about="Preview with fold --as before it lands." at=policy:bound/readme by=target form=alphabet measure=id role=writes scope=page/seq/look value=present +bound-lock/1 about="Publish contracts and typed-object samples; attest evidence is visible through a declared view." at=witness:published-plan-evidence by=target form=alphabet measure=status needs=docs/contracts/evidence-view.md|docs/contracts/typed-object.md|samples/no/native-views.json|samples/no/typed-object.json|samples/yes/native-views.json|samples/yes/typed-object.json|vectors/native-views.json|vectors/typed-object.json restsOn=plan/0.1.5/0 role=demands scope=plan/0.1.5/1 value=present +bound-lock/1 about="Reading regions compose all adopted world answers with origins and disagreements retained; shaped files keep one writer." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/readings/compose-origins.md|samples/yes/readings/compose-origins.json|vectors/readings/compose-origins.json|samples/no/readings/compose-origins.json role=demands scope=readings/compose-origins value=present bound-lock/1 about="Rejected: a source URL does not define authenticated release lineage or order. A bump proposal requires an explicit release contract; downloaded bytes cannot replace an immutable standing pin." at=policy:bound/014-review by=target form=alphabet measure=text role=writes scope=policy/rejected/newest-by-url value=lock bound-lock/1 about="Rejected: empty output is not universally a failure. Missing required inputs remain unpaid; a completed empty result is valid only where its declared Topos contract permits it." at=policy:bound/014-review by=target form=alphabet measure=text role=writes scope=policy/rejected/empty-is-failure value=lock bound-lock/1 about="Rejected: key-name depth does not determine authority. Key identifier grammar and ambiguity belong to Topos; coverage and admitted public keys govern authorization." at=policy:bound/014-review by=target form=alphabet measure=text role=writes scope=policy/rejected/nested-key-authority value=lock @@ -45,13 +79,22 @@ bound-lock/1 about="Release selection of existing obligations; their fold eviden bound-lock/1 about="Release selection of existing obligations; their fold evidence determines the verdict." at=policy:bound/release by=target form=alphabet measure=id role=writes scope=release/category/cli value=cli/**|fold/idle|cost/act bound-lock/1 about="Release selection of existing obligations; their fold evidence determines the verdict." at=policy:bound/release by=target form=alphabet measure=id role=writes scope=release/category/integrity value=literal/host|literal/key|literal/org|literal/path|duplicate/src|door/unreceipted bound-lock/1 about="Release selection of existing obligations; their fold evidence determines the verdict." at=policy:bound/release by=target form=alphabet measure=id role=writes scope=release/category/pins value=resolve-by-url|offline|the-stranger +bound-lock/1 about="Render documentation and standard MIT license; verify one exact staged artifact." at=witness:public-contracts-by-operation by=target form=alphabet measure=status needs=docs/contracts/archive.md|samples/no/archive-conformance.json|samples/yes/archive-conformance.json|vectors/archive-conformance.json restsOn=plan/0.1.5/5 role=demands scope=plan/0.1.5/10 value=present +bound-lock/1 about="Render only this place admitted MIT text through the selected generic prose provider." at=witness:bound/015-standard-mit by=target form=alphabet measure=id needs=LICENSE role=demands scope=view/license-native shape=LICENSE value=text@3 bound-lock/1 about="Render this place admitted manifest prose through the existing explicitly selected text provider; general document capability demands remain unchanged." at=policy:bound/presentation by=target form=alphabet measure=id needs=package.json role=demands scope=view/manifest-render shape=package.json value=text@3 +bound-lock/1 about="Replace the built-in module parser with a declared bounded command under a published host closure contract, then remove Acorn from Bound. Prove identical implementation identities and refusal of an unclosed runtime graph on unrelated programs; no regex fallback and no universal source grammar in the kernel." at=witness:host-command-requires-its-publication-quartet by=target form=alphabet measure=status needs=docs/contracts/host-module-command.md|samples/no/host-module-command.json|samples/yes/host-module-command.json|vectors/host-module-command.json role=demands scope=plan/0.1.6/host-module-command value=present +bound-lock/1 about="Reported unpaid by the Head clean-install matrix: authority-class evidence is exposed but attest receipts appear in no view. Confirm against exact archive; preserve admitted attribution." at=witness:head/014-clean-install by=target form=alphabet measure=status needs=docs/contracts/evidence-view.md|samples/yes/attest-evidence.json|vectors/attest-evidence.json|samples/no/attest-evidence.json role=demands scope=contract/published/attest-evidence-view value=present +bound-lock/1 about="Reported unpaid by the Head clean-install matrix: the typed-object sample is absent from the package. Confirm against exact archive; no receipt is fabricated." at=witness:head/014-clean-install by=target form=alphabet measure=status needs=docs/contracts/typed-object.md|samples/yes/typed-object.json|vectors/typed-object.json|samples/no/typed-object.json role=demands scope=contract/published/typed-object-sample value=present bound-lock/1 about="Rewriting hero, idea and the other section regions as compositions of atoms is 0.1.1, not done quietly here." at=policy:bound/010 by=target form=alphabet kind=conjecture measure=status role=demands scope=open/section-regions-as-atoms value=present +bound-lock/1 about="Source origin is distinct from local coordinates; requested verified bytes are handed to every declared eligible reader." at=policy:bound/015-plan by=target form=alphabet measure=status needs=docs/contracts/region/origin-input.md|samples/yes/region/origin-input.json|vectors/region/origin-input.json|samples/no/region/origin-input.json role=demands scope=region/origin-input value=present bound-lock/1 about="The coordinate of the observed host implementation digest in the native receipt set." at=policy:bound/receipts by=target form=alphabet measure=id role=writes scope=audit/wire/receipt-instrument value=instrument/implementation bound-lock/1 about="The explicitly selected historical document profile over this place own prose; general text@3 demands remain unpaid." at=policy:readme-without-debt-section by=target form=alphabet measure=id needs=README.md role=demands scope=view/readme-historical shape=README.md value=hero@3|commands@3|idea@3 +bound-lock/1 about="The host adapter parses literal JavaScript imports when identifying the implementation behind receipts. It executes no module and does not inventory domain exports, duplicates or literals. It does not enforce arbitrary dynamic-import closure or claim a capsule sandbox." at=policy:host-module-identity by=target form=alphabet measure=text role=writes scope=rationale/host/module-parser value=present bound-lock/1 about="The native public receipt carries its actual observed set at resolution 8 before the authenticated summary at resolution 0 and current region bytes at resolution 1." at=witness:a-public-receipt-carries-its-observations by=target form=alphabet measure=id role=demands scope=view/receipts shape=receipts.bound value=receipts@8|receipts@0|receipts@1 bound-lock/1 about="The object" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/the-object/heading value=lock bound-lock/1 about="The paper" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/the-paper/heading value=lock +bound-lock/1 about="The previously declared cell card remains available under its explicit object coordinate; it is not silently treated as a demand scheduler." at=witness:preserved-cell-card by=target form=alphabet measure=id role=demands scope=view/object-card value=cells +bound-lock/1 about="The proposed laws are not already paid merely because this text names them. Inventory actual standing lines and current evidence first. New laws, category links and grammar require named admission acts. Obligations remains unchanged." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/08 value=lock bound-lock/1 about="The same signed lot and admitted snapshot share admission validation; a prospective reading neither admits nor writes. The vector reports failures; unread is not agreement." at=witness:prospective-admission-agrees by=target form=interval measure=count needs=samples/admission/yes/one-boundary.json|samples/admission/no/one-boundary.json|test/admission-boundary.test.ts|vectors/process/admission-boundary.vector.json role=reads scope=admission/one-boundary value=0..0 bound-lock/1 about="This place own build option, observed from its source tsconfig for the selected historical build profile." at=policy:bound/build-profile by=target form=alphabet measure=id role=writes scope=build/allowImportingTsExtensions shape=tsconfig.json value=true bound-lock/1 about="This place own build option, observed from its source tsconfig for the selected historical build profile." at=policy:bound/build-profile by=target form=alphabet measure=id role=writes scope=build/composite shape=tsconfig.json value=true @@ -76,6 +119,8 @@ bound-lock/1 about="This place requests complete blocks at resolution three from bound-lock/1 about="Try it" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/first-use/heading value=lock bound-lock/1 about="Two-Sided Constraints on a Valued Lattice" at=policy:bound/010 by=target form=alphabet measure=author role=writes scope=cites/two-sided-constraints value="Ochoa, N." bound-lock/1 about="Two-Sided Constraints on a Valued Lattice" at=policy:bound/010 by=target form=alphabet measure=doi role=writes scope=cites/two-sided-constraints value=10.5281/zenodo.21858428 +bound-lock/1 about="Unpaid optional stages carry to 0.1.6 only when the admitted time ceiling reads red; mandatory stages remain gates." at=policy:bound/015-plan by=target form=alphabet measure=id role=writes scope=scope/carry-over value=plan/0.1.6 +bound-lock/1 about="Walk exchanges admitted regional evidence by declared wire; disagreements remain." at=witness:published-plan-evidence by=target form=alphabet measure=status needs=docs/contracts/view-walk.md|samples/no/walk.json|samples/yes/walk.json|vectors/walk-publication.json restsOn=plan/0.1.5/2 role=demands scope=plan/0.1.5/5 value=present bound-lock/1 about="What holds" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/what-holds/heading value=lock bound-lock/1 about="What is open" at=policy:bound/paid by=target form=alphabet measure=text role=writes scope=prose/en/open/heading value=lock bound-lock/1 about="What it refuses" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/refuses/heading value=lock @@ -83,13 +128,13 @@ bound-lock/1 about="What it refuses" at=policy:bound/010-figure by=target form=a bound-lock/1 about="What it rests on" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/rests/heading value=lock bound-lock/1 about="What rests on it" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/rested/heading value=lock bound-lock/1 about="Write the line as by=target." at=policy:bound/readme by=target form=alphabet measure=id role=writes scope=page/seq/line value=present +bound-lock/1 about="Zero port invocations applies to selection/help, receipt-only check, prospective evaluation and signing's observation/execution ports. Signing necessarily invokes its declared signer. A shaped render, observation or admitted verification request may execute its explicitly requested provider under the relevant contract. Never hide execution behind a purported inspection command." at=policy:bound/015-plan by=target form=alphabet measure=text role=writes scope=rationale/015/04 value=lock bound-lock/1 about="`{scope}` is demanded and not paid" at=policy:bound/paid by=target form=alphabet measure=text role=writes scope=prose/en/open/unpaid value=lock bound-lock/1 about="`{scope}` reads `{reading}`, outside its ceiling" at=policy:bound/paid by=target form=alphabet measure=text role=writes scope=prose/en/open/outside value=lock bound-lock/1 about="a byte lives only while a standing line names it: the store is the receipts of blobs, laid snapshots and answer caches, and 2G is the ceiling" at=policy:bound/store by=target form=interval measure=bytes role=reads scope=store/bytes value=0..2000000000 bound-lock/1 about="a capsule as it declares itself: the lines of its own lock, handed whole as the host reads them, never its files" at=policy:bound/regions by=target form=alphabet measure=lines role=reads scope=region/capsule value=capsule.bound bound-lock/1 about="a capture of the CLI on the meeting sample agrees with this fold" at=witness:project-coordinates-are-relative by=target form=interval measure=capture-differs needs=samples/yes/meeting.bound role=reads scope=capture/differs value=0..0 bound-lock/1 about="a fold runs where freedom remains: a region whose bytes meet its receipt at resolution 1 is closed, and the receipt is the result" at=witness:a-fold-over-a-closed-region by=target form=interval measure=idle role=reads scope=fold/idle value=0..0 -bound-lock/1 about="a line of the lock, drawn from the citation sample" at=witness:project-coordinates-are-relative by=target form=alphabet measure=id needs=docs/img/line.svg|samples/yes/line.bound role=demands scope=view/figure-line shape=docs/img/line.svg value=figure-line@1 bound-lock/1 about="a lock is stale only when its pid is gone, and an accept that dies prints REFUSE·crash" at=witness:a-dead-pid-is-stale by=target form=alphabet measure=id role=reads scope=act/stale value=esrch bound-lock/1 about="a one-line index in the tree is loaded by role, each region by name" at=witness:a-located-index-loaded-by-role by=target form=alphabet measure=id role=reads scope=host/located value=role bound-lock/1 about="after the host surface cut, the host is the lines the fold prints for src/host|src/observe|src/cli" at=witness:host-io-split-recounted-the-kernel by=target form=interval measure=host-lines role=reads scope=host/lines value=0..3269 @@ -119,7 +164,7 @@ bound-lock/1 about="lines, not a page: blobs, laid snapshots and answer caches n bound-lock/1 about="name: release\non:\n workflow_run:\n workflows: [tag]\n types: [completed]\n push:\n tags: ['v*']\njobs:\n release:\n if: github.event_name == 'push' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main')\n runs-on: ubuntu-latest\n permissions:\n contents: write\n outputs:\n tag: ${{ steps.version.outputs.tag }}\n asset: ${{ steps.archive.outputs.asset }}\n sha256: ${{ steps.archive.outputs.sha256 }}\n steps:\n - uses: actions/checkout@v4\n with:\n ref: ${{ github.event.workflow_run.head_sha || github.sha }}\n fetch-depth: 0\n - id: version\n env:\n EVENT_NAME: ${{ github.event_name }}\n REF_NAME: ${{ github.ref_name }}\n run: |\n version=\"v$(node -p \"require('./package.json').version\")\"\n if [ \"$EVENT_NAME\" = push ]; then\n test \"$REF_NAME\" = \"$version\"\n fi\n git rev-parse --verify \"refs/tags/$version\"\n echo \"tag=$version\" >> \"$GITHUB_OUTPUT\"\n git checkout --detach \"$version\"\n - uses: actions/setup-node@v4\n with:\n node-version: 24\n - run: npm ci\n - run: npm run build\n - run: npm test\n - run: node dist/cli/verb.js fold --check\n - id: archive\n env:\n GH_TOKEN: ${{ github.token }}\n run: |\n version=\"${{ steps.version.outputs.tag }}\"\n asset=\"$(npm pack --ignore-scripts --silent)\"\n echo \"asset=$asset\" >> \"$GITHUB_OUTPUT\"\n expected=\"$(sha256sum \"$asset\" | cut -d ' ' -f 1)\"\n echo \"sha256=$expected\" >> \"$GITHUB_OUTPUT\"\n if ! gh release view \"$version\" >/dev/null 2>&1; then\n gh release create \"$version\" \"$asset\" --title \"$version\" --notes \"$(git log -1 --format=%B)\"\n fi\n download_dir=\"$(mktemp -d)\"\n gh release download \"$version\" --pattern \"$asset\" --dir \"$download_dir\"\n actual=\"$(sha256sum \"$download_dir/$asset\" | cut -d ' ' -f 1)\"\n test \"$expected\" = \"$actual\"\n publish:\n needs: release\n environment: release\n runs-on: ubuntu-latest\n permissions:\n contents: read\n id-token: write\n steps:\n - uses: actions/checkout@v4\n with:\n ref: ${{ needs.release.outputs.tag }}\n - uses: actions/setup-node@v4\n with:\n node-version: 24\n - run: npm install --global npm@'12.1.0'\n - env:\n GH_TOKEN: ${{ github.token }}\n TAG: ${{ needs.release.outputs.tag }}\n ASSET: ${{ needs.release.outputs.asset }}\n EXPECTED: ${{ needs.release.outputs.sha256 }}\n run: |\n mkdir candidate\n gh release download \"$TAG\" --pattern \"$ASSET\" --dir candidate\n actual=\"$(sha256sum \"candidate/$ASSET\" | cut -d ' ' -f 1)\"\n test \"$EXPECTED\" = \"$actual\"\n npm stage publish \"./candidate/$ASSET\" --access public --ignore-scripts\n" at=policy:bound/011-port-release by=target form=alphabet measure=text role=writes scope=prose/en/files/workflow/release shape=.github/workflows/release.yml value=lock bound-lock/1 about="name: tag\non:\n workflow_run:\n workflows: [test]\n types: [completed]\njobs:\n tag:\n if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main'\n runs-on: ubuntu-latest\n permissions:\n contents: write\n steps:\n - uses: actions/checkout@v4\n with:\n ref: ${{ github.event.workflow_run.head_sha }}\n fetch-depth: 0\n - run: |\n version=\"v$(node -p \"require('./package.json').version\")\"\n git tag --list \"$version\" | grep -q . && exit 0\n git tag \"$version\" && git push origin \"$version\"\n" at=policy:bound/pipeline by=target form=alphabet measure=text role=writes scope=prose/en/files/workflow/tag shape=.github/workflows/tag.yml value=lock bound-lock/1 about="name: test\non:\n push:\n branches: [main]\n pull_request:\njobs:\n test:\n strategy:\n fail-fast: false\n matrix:\n node: [22, 24]\n runs-on: ubuntu-latest\n permissions:\n contents: read\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: ${{ matrix.node }}\n - run: npm ci\n - run: npm run build\n - run: npm test\n - name: Verify native closure and receipt reuse\n run: |\n node dist/cli/verb.js fold --check > \"$RUNNER_TEMP/bound-check.log\" 2>&1 || { cat \"$RUNNER_TEMP/bound-check.log\"; exit 1; }\n cat \"$RUNNER_TEMP/bound-check.log\"\n grep -Eq '^PASS +closed' \"$RUNNER_TEMP/bound-check.log\"\n grep -Eq '^RECEIPTS [1-9][0-9]* read · 0 opened' \"$RUNNER_TEMP/bound-check.log\"\n - run: npm pack --silent\n" at=policy:bound/pipeline by=target form=alphabet measure=text role=writes scope=prose/en/files/workflow/test shape=.github/workflows/test.yml value=lock -bound-lock/1 about="npx @lapxo/bound@0.1.4 fold --as help\nnpx @lapxo/bound@0.1.4 fold" at=witness:bound/014-candidate by=target form=alphabet measure=text role=writes scope=prose/en/commands value=lock +bound-lock/1 about="npx @lapxo/bound@0.1.5 fold --as help\nnpx @lapxo/bound@0.1.5 fold" at=witness:bound/015-prose-version by=target form=alphabet measure=text role=writes scope=prose/en/commands value=lock bound-lock/1 about="obligations is the meet. topos is the line. Worlds outside bound read a calendar, a package, a page. Bound reads lines, folds them, lands what was signed, and signs." at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/rests/on value=present bound-lock/1 about="one origin is REQUIRED, two that meet inside every bound are FREE, two that meet outside a bound are FORBIDDEN, and two that do not meet are CONFLICT" at=policy:bound/010-states by=target form=alphabet measure=id role=writes scope=notation/states value="one origin=REQUIRED|claims that meet and fit the bounds=FREE|claims that meet outside the bounds=FORBIDDEN|bounds that cross=CONFLICT" bound-lock/1 about="take the package in" at=policy:bound/door by=target form=alphabet measure=id role=writes scope=install value=npx @@ -184,7 +229,6 @@ bound-lock/1 about="the fields the line figure fills" at=policy:bound/readme by= bound-lock/1 about="the fields the refuses figure fills" at=policy:bound/010-figure by=target form=alphabet measure=id role=writes scope=form/template/figure/refuses value=input|why bound-lock/1 about="the fields the what-holds axiom line fills" at=policy:bound/readme by=target form=alphabet measure=id role=writes scope=form/template/what-holds/axiom value=sentence|name|rests bound-lock/1 about="the fold as wire lines, so a script reads lines rather than parsing the human form" at=policy:bound/010 by=target form=alphabet measure=id role=demands scope=view/lines value=lines -bound-lock/1 about="the fold drawn from the meeting-time sample: two claims that meet and one that falls apart" at=witness:project-coordinates-are-relative by=target form=alphabet measure=id needs=docs/img/fold.svg|samples/yes/meeting.bound role=demands scope=view/figure-fold shape=docs/img/fold.svg value=figure-fold@1 bound-lock/1 about="the folder the no samples of this place live in" at=witness:project-coordinates-are-relative by=target form=alphabet measure=id role=writes scope=samples/no value=samples/no bound-lock/1 about="the folder the yes samples of this place live in" at=witness:project-coordinates-are-relative by=target form=alphabet measure=id role=writes scope=samples/yes value=samples/yes bound-lock/1 about="the forge capsule that answers github-actions and renders the publish auth a place names — a token as the secret it names, trusted as the workflow's own identity — packed against the notation release and the algebra release, each laid from its digest; the release before it stays named until no view reads the regions only it answers" at=witness:a-token-auth-no-law-read by=target form=alphabet measure=id role=writes scope=dep/topos-github/actions shape=dist/index.js value=sha256:8ad84ca313988769a933bedf0a7f4fb87d087b9a5911b1df6b984557ddafb294 @@ -234,10 +278,9 @@ bound-lock/1 about="the release of the forge capsule, named by the digest of wha bound-lock/1 about="the release of the language capsule, named by the digest of what its published place holds" at=policy:bound/one-cell by=target form=alphabet measure=id role=reads scope=dep/topos-typescript-tree value=sha256:fcd87e3dcb13cb4f4bcb8f96b5cab419b8ee6930612979bb6f143c8a1a3dcc98 bound-lock/1 about="the release of the lock reader, named by the digest of what its published place holds" at=policy:bound/one-cell by=target form=alphabet measure=id role=reads scope=dep/topos-bound value=sha256:23ea35997c2ada24d7f0da362b9bd112ed52c1ab9bbcdcea1e9eeb91699bd854 bound-lock/1 about="the release of the node package capsule, named by the digest of what its published place holds" at=policy:bound/one-cell by=target form=alphabet measure=id role=reads scope=dep/topos-node value=sha256:c4ae9ecd8ecc422f6eedc17ae02202611517ae1a0c42ed1dbfcfcc97b534119e -bound-lock/1 about="the release of the notation, named by the digest of what its published place holds" at=witness:bound/014-sdk-published by=target form=alphabet measure=id needs=node_modules/@lapxo/topos role=reads scope=dep/topos shape=package value=sha256:ff642185cfb19d7555fb941575bd714e54f854c2f4fadf34b156bc684db4b885 +bound-lock/1 about="the release of the notation, named by the digest of what its published place holds" at=witness:published-topos-011 by=target form=alphabet measure=id needs=node_modules/@lapxo/topos role=reads scope=dep/topos shape=package value=sha256:9562133f6ac7a94630333715d62acda5c29e2f0e88d5c68d1b2966b03879c330 bound-lock/1 about="the release of the pages capsule, named by the digest of what its published place holds" at=policy:bound/one-cell by=target form=alphabet measure=id role=reads scope=dep/topos-doc value=sha256:adc787638f8cb2c9f050b295e30a7959830682e793e6e5f3e265c85bd6ce6ebb bound-lock/1 about="the release of the vectors reader, named by the digest of what its published place holds" at=witness:vectors-read-without-a-row-per-region by=target form=alphabet measure=id role=reads scope=dep/topos-json value=sha256:ddee424ba7c852f966569250f6b5520ecf4079a86cec673ac1a4fc88a934a56d -bound-lock/1 about="the release pin of a world, never drawn on the door" at=policy:bound/readme by=target form=alphabet measure=id role=demands scope=view/release value=line bound-lock/1 about="the scopes a born lock keeps an about on, even when the measure is not text" at=policy:bound/wire-words by=target form=alphabet measure=id role=writes scope=audit/wire/kept-about value=license bound-lock/1 about="the second head, asked live when its latest word rests on another lock: the program that folds the ledger without bound, run with no key; what it says is read, never kept" at=policy:bound/heads by=target form=alphabet measure=id role=reads scope=head/second value=verify/src/cli.ts bound-lock/1 about="the shape a published place pins as: the one word the instrument asks of the lock, never guessed by length or letter" at=policy:bound/wire-words by=target form=alphabet measure=id role=writes scope=audit/wire/pin-shape value=package @@ -254,23 +297,23 @@ bound-lock/1 about="the typescript tree world after its released capsule: said, bound-lock/1 about="the vectors a place holds, a row per region, as the fold counts them from its receipts" at=policy:bound/regions by=target form=alphabet measure=receipts role=reads scope=region/vectors value=vector/** bound-lock/1 about="the vectors world saying its own description in its own lock: the regions of 2fb13c6f unchanged, its prose under its key; packed from releases only, topos 0.1.2 and the algebra release, each laid from its digest" at=policy:bound/capsules by=target form=alphabet measure=id role=writes scope=dep/topos-json/own-what shape=dist/index.js value=sha256:5ec73255e3f089e3b9c7bc1d6351a07b8aa302a346fe16ed44cbcb67293c7891 bound-lock/1 about="the version the forge tags, read from the manifest" at=policy:bound/pipeline by=target form=alphabet measure=id role=writes scope=pipeline/version value="node -p \"require('./package.json').version\"" -bound-lock/1 about="the version this place is bound at" at=witness:bound/014-candidate by=target form=alphabet measure=id role=writes scope=version value=0.1.4 +bound-lock/1 about="the version this place is bound at" at=witness:bound/015-candidate by=target form=alphabet measure=id role=writes scope=version value=0.1.5 bound-lock/1 about="the writer that vouches each source at the digest a take judged it: a family the wire lists, which bound reads here and never spells" at=policy:bound/store by=target form=alphabet measure=id role=reads scope=store/vouches value=tree bound-lock/1 about="this place is a package: class defaults of package resolve here" at=policy:bound/place by=target form=alphabet measure=id role=writes scope=place/kind value=package bound-lock/1 about="topos-node with a thin manifest: no typesVersions, main or types, dev dependencies only where a line says so, and a bin field from the place bin/ lines" at=policy:bound/capsules by=target form=alphabet measure=id role=writes scope=dep/topos-node/thin-manifest shape=dist/index.js value=sha256:da1fd0bb74f72ae95bce5929055c50ccd150d8903ba5560d99df48bf236d8dc0 bound-lock/1 about="two renders of an SVG sample are the same bytes" at=witness:project-coordinates-are-relative by=target form=interval measure=redrawn needs=docs/img role=reads scope=figures/redrawn value=0..0 bound-lock/1 about="usage, rendered from VERB_NAMES and FLAGS, never written by hand" at=policy:bound/010 by=target form=alphabet measure=id role=demands scope=view/help value=help bound-lock/1 about="views/world resolves into worlds, and a place's bytes are its files, its lock, and the root lines that resolve into it" at=witness:a-world-line-opens-worlds by=target form=alphabet measure=id role=reads scope=bytes/world value=worlds -bound-lock/1 about="what a fold refuses, drawn from the first refused case" at=witness:project-coordinates-are-relative by=target form=alphabet measure=id needs=docs/img/refuses.svg role=demands scope=view/figure-refuses shape=docs/img/refuses.svg value=figure-refuses@1 bound-lock/1 about="what a place own lock says for the tree under its own name: its prose, and the silent substitutions it bounds in its own code, the place written after the steps the glob names" at=policy:bound/places by=target form=alphabet measure=id role=reads scope=place/speaks-under value=prose/*|hazard/silent-substitution -bound-lock/1 about="what is open, as cards, one lane at a time: / --as card --key lane-X" at=policy:bound/views by=target form=alphabet measure=id role=demands scope=view/card value=cells +bound-lock/1 about="what is open, as cards, one lane at a time: / --as card --key lane-X" at=witness:declared-plan-card by=target form=alphabet measure=id role=demands scope=view/card value=demand-card@8 bound-lock/1 about="what the CLI printed on a sample and the REFUSE a drafted land printed, kept as receipts" at=policy:bound/doi by=target form=alphabet measure=receipts role=reads scope=region/captures value=capture/**|*refused* bound-lock/1 about="what the forge runs to check this place: the suites, then a quiet fold" at=policy:bound/pipeline-published-dependencies by=target form=alphabet measure=id role=writes scope=pipeline/check value="npm test && node dist/cli/verb.js fold --check" bound-lock/1 about="what the second head found, which leaves the place has written, and the place's own readings as the fold holds them: the verdict line's counts, each of the place's own ceilings as the fold reads it, unpaid and outside reds, RANK readings, the walk, captures, figures, literals and the door" at=witness:project-coordinates-are-relative by=target form=alphabet measure=receipts role=reads scope=region/state value=second/verdict|write/**|leaf/**|verdict/*|audit/*|coordinate/**|asked/**|unpaid/**|outside/**|fold/idle|cost/act|cli/verbs|store/bytes|src/lines|literal/**|duplicate/**|door/unreceipted|figures/**|capture/**|walk/** bound-lock/1 about="when the apart claim is withdrawn" at=policy:bound/door by=target form=alphabet measure=id role=writes scope=form/style/fold/back value=2.2 bound-lock/1 about="where a located world keeps each region file, by directory and extension, so the host loads the tree beside the pin" at=policy:bound/010 by=target form=alphabet measure=id role=writes scope=release/layout value=src/regions:.ts bound-lock/1 about="who signs this place" at=policy:bound/010 by=target form=alphabet measure=id role=writes scope=author value=Lapxo -bound-lock/1 about="{\n \"name\": \"@lapxo/bound\",\n \"version\": \"0.1.4\",\n \"type\": \"module\",\n \"description\": \"Read the bounds you already wrote, fold them, and name the contradictions.\",\n \"main\": \"dist/cli/verb.js\",\n \"types\": \"dist/cli/verb.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/cli/verb.d.ts\",\n \"default\": \"./dist/cli/verb.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"test\": \"node --import ./test/setup.ts --test test/*.test.ts\",\n \"clean\": \"rm -rf dist .tsbuildinfo* tsconfig.tsbuildinfo\",\n \"build\": \"node tools/build.mjs\",\n \"prepack\": \"npm run build\"\n },\n \"files\": [\n \"LICENSE\",\n \"README.md\",\n \"CONTRIBUTING.md\",\n \"dist/**/*\",\n \"TARGET.bound\",\n \"receipts.bound\",\n \"docs/usage.md\",\n \"docs/readme-assets/atlas.svg\"\n ],\n \"author\": \"Lapxo\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@lapxo/obligations\": \"0.3.5\",\n \"@lapxo/topos\": \"0.1.9\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.0.0\"\n },\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=22.15\"\n },\n \"bin\": {\n \"bound\": \"./dist/cli/verb.js\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Lapxo/bound.git\"\n },\n \"homepage\": \"https://github.com/Lapxo/bound#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/Lapxo/bound/issues\"\n },\n \"keywords\": [\n \"cli\",\n \"content-addressed\",\n \"provenance\",\n \"receipts\",\n \"constraints\",\n \"reproducible\"\n ]\n}" at=witness:bound/014-candidate by=target form=alphabet measure=text role=writes scope=prose/en/files/manifest shape=package.json value=lock +bound-lock/1 about="{\n \"name\": \"@lapxo/bound\",\n \"version\": \"0.1.5\",\n \"type\": \"module\",\n \"description\": \"Read the bounds you already wrote, fold them, and name the contradictions.\",\n \"main\": \"dist/cli/verb.js\",\n \"types\": \"dist/cli/verb.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/cli/verb.d.ts\",\n \"default\": \"./dist/cli/verb.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"test\": \"node --import ./test/setup.ts --test --test-concurrency=2 test/*.test.ts\",\n \"clean\": \"rm -rf dist .tsbuildinfo* tsconfig.tsbuildinfo\",\n \"build\": \"node tools/build.mjs\",\n \"prepack\": \"npm run build\"\n },\n \"files\": [\n \"LICENSE\",\n \"README.md\",\n \"CONTRIBUTING.md\",\n \"dist/**/*\",\n \"TARGET.bound\",\n \"receipts.bound\",\n \"docs/usage.md\",\n \"docs/readme-assets/atlas.svg\",\n \"docs/contracts/*.md\"\n ],\n \"author\": \"Lapxo\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@lapxo/obligations\": \"0.3.5\",\n \"@lapxo/topos\": \"^0.1.11\",\n \"acorn\": \"8.19.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.0.0\"\n },\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=22.15\"\n },\n \"bin\": {\n \"bound\": \"./dist/cli/verb.js\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Lapxo/bound.git\"\n },\n \"homepage\": \"https://github.com/Lapxo/bound#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/Lapxo/bound/issues\"\n },\n \"keywords\": [\n \"cli\",\n \"content-addressed\",\n \"provenance\",\n \"receipts\",\n \"constraints\",\n \"reproducible\"\n ]\n}\n" at=witness:minimal-public-surface-015 by=target form=alphabet measure=text role=writes scope=prose/en/files/manifest shape=package.json value=lock +bound-lock/1 about="{\n \"profile\": \"quartet-process@1\",\n \"scope\": \"contract/published\",\n \"surface\": [\n \"contract/published/attest-evidence-view\",\n \"contract/published/cli/fold\",\n \"contract/published/cli/land\",\n \"contract/published/cli/sign\",\n \"contract/published/pipeline/archive\",\n \"contract/published/typed-object-sample\",\n \"contract/published/view/card\",\n \"contract/published/view/citation-file\",\n \"contract/published/view/explanation\",\n \"contract/published/view/guide\",\n \"contract/published/view/help\",\n \"contract/published/view/lines\",\n \"contract/published/view/manifest-render\",\n \"contract/published/view/programs\",\n \"contract/published/view/readme-historical\",\n \"contract/published/view/receipts\",\n \"contract/published/view/reference\",\n \"contract/published/view/release-workflow-render\",\n \"contract/published/view/tsconfig\",\n \"contract/published/view/usage-profile\",\n \"contract/published/view/walk\",\n \"contract/published/view/why\"\n ],\n \"note\": \"Explicit public-surface inventory. A selected coordinate without a descriptor is unpaid. Outstanding capability demands are not advertised implementations.\"\n}" at=witness:exact-archive-conformance by=target form=alphabet measure=text role=writes scope=prose/en/files/publication-inventory shape=docs/contracts/publication.inventory.json value=lock bound-lock/1 about="{count} hold" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/badge/held value=lock bound-lock/1 about="{lo}..{hi} · {state}" at=policy:bound/readme by=target form=alphabet measure=text role=writes scope=prose/en/figure/fold/together value=present bound-lock/1 about="{title} (Version {version})" at=policy:bound/010 by=target form=alphabet measure=text role=writes scope=prose/en/cite/versioned value=lock @@ -329,6 +372,12 @@ bound-lock/1 at=policy:bound/014-host-profile by=target form=interval measure=by bound-lock/1 at=policy:bound/014-host-profile by=target form=interval measure=bytes role=writes scope=transport/response-bytes value=0..67108864 bound-lock/1 at=policy:bound/014-host-profile by=target form=interval measure=milliseconds role=writes scope=reader/timeout value=0..30000 bound-lock/1 at=policy:bound/014-host-profile by=target form=interval measure=milliseconds role=writes scope=transport/timeout value=0..30000 +bound-lock/1 at=policy:bound/015-plan by=target form=alphabet measure=digest role=writes scope=dep/programs shape=ab851507d007068757f4f0a286a5231237ec63499204ab767c343d7ef90ddb49 value=sha256:6dd67481ae70011143764232465eb4d0140d0143a9928080b471bf2df5b5e45a +bound-lock/1 at=policy:bound/015-plan by=target form=alphabet measure=digest role=writes scope=uses/programs value=sha256:bd89b6a84e48b8e0ff392c68806ce5104956f1e9cb018b760fd97ba9a4e822c0 +bound-lock/1 at=policy:bound/015-plan by=target form=alphabet measure=id role=demands scope=view/programs value=demand-status@8 +bound-lock/1 at=policy:bound/015-plan by=target form=alphabet measure=id role=writes scope=plan/selection value=plan/0.1.5/0|plan/0.1.5/1|plan/0.1.5/2|plan/0.1.5/5|plan/0.1.5/10|plan/0.1.6/3|plan/0.1.6/4|plan/0.1.6/6|plan/0.1.6/7|plan/0.1.6/8|plan/0.1.6/9 +bound-lock/1 at=policy:bound/015-plan by=target form=alphabet measure=id role=writes scope=scope/minimum value=plan/0.1.5/0|plan/0.1.5/1|plan/0.1.5/2|plan/0.1.5/5|plan/0.1.5/10 +bound-lock/1 at=policy:bound/015-plan by=target form=alphabet measure=receipts role=writes scope=region/program-evidence value=contract/**|plan/** bound-lock/1 at=policy:bound/authority by=owner epoch=1 form=alphabet measure=public-key role=writes scope=keys/owner sig="ed25519:era1:IA0IME384zILkebRhsBRopKbz8uPLRX95xUu45dqM0vrc5RzPaeiyJR9s/bb/QFtY6fLiilDy17p89cN3Tm6AQ==" value="MCowBQYDK2VwAyEAIYI0be8OWhf3HcVceKpibjgZ+hbYJKYO5ayX8Kk16LE=" bound-lock/1 at=policy:bound/authority by=target form=alphabet measure=class role=writes scope=keys/owner value=authorize bound-lock/1 at=policy:bound/authority by=target form=alphabet measure=coverage role=writes scope=keys/owner value=* @@ -340,7 +389,6 @@ bound-lock/1 at=policy:bound/presentation by=target form=alphabet measure=id rol bound-lock/1 at=policy:bound/presentation by=target form=alphabet measure=id role=writes scope=notation/renders value="free=FREE|required=REQUIRED" bound-lock/1 at=policy:bound/publish by=target form=alphabet measure=id role=reads scope=publish/keys value=authorize|attest|read bound-lock/1 at=policy:bound/release by=target form=alphabet measure=id role=reads scope=release/layout value=dist/regions:.js|src/regions:.ts -bound-lock/1 at=policy:bound/release by=target form=alphabet measure=id role=writes scope=release/blocks value=integrity|pins|admission|cli bound-lock/1 at=policy:bound/split by=target form=alphabet measure=id role=writes scope=split/host value=src/host|src/observe|src/cli bound-lock/1 at=policy:bound/split by=target form=alphabet measure=id role=writes scope=split/kernel value=src/fold|src/judge|src/land|src/render|src/kernel bound-lock/1 at=policy:bound/split by=target form=interval measure=cli-flags role=reads scope=cli/flags value=0..6 @@ -363,14 +411,18 @@ bound-lock/1 at=policy:prose/render-contract by=target form=alphabet measure=dig bound-lock/1 at=policy:prose/render-contract by=target form=alphabet measure=id role=writes scope=dep/prose-render shape=dist/regions/text.js value=sha256:a1c31a72a31eaf8ea7df0fb98235c4b465aee1d9575aebcc480f09b4bf64daf1 bound-lock/1 at=policy:public-artifact-source by=target form=alphabet measure=id role=writes scope=sources/obligations value=https://registry.npmjs.org/@lapxo/obligations/-/obligations-0.3.5.tgz bound-lock/1 at=policy:public-artifact-source by=target form=alphabet measure=id role=writes scope=sources/typescript value=https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz -bound-lock/1 at=policy:rendering by=target form=alphabet measure=digest role=writes scope=uses/rendering value=sha256:0f7653b659f372fd7bc1b140d0103606ebd8814dee8ef3be30949c6647b482a3 bound-lock/1 at=policy:selected-wire by=target form=alphabet measure=digest role=writes scope=uses/wire value=sha256:a717c60945add1facfd822b3ee2da73a8fa2f781dd0aa2de9be778e66b8f3591 bound-lock/1 at=witness:admission-samples-are-inputs by=target form=alphabet measure=coordinates role=reads scope=region/captures value=src/**|test/**|vectors/process/**|dist/**|package.json|TARGET.bound|samples/admission/** bound-lock/1 at=witness:admission-samples-are-inputs by=target form=alphabet measure=coordinates role=reads scope=region/vectors value=src/**|test/**|vectors/process/**|dist/**|package.json|TARGET.bound|samples/admission/** bound-lock/1 at=witness:bound/014-sdk-source by=target form=alphabet measure=id role=writes scope=sources/topos value=https://registry.npmjs.org/@lapxo/topos/-/topos-0.1.9.tgz -bound-lock/1 at=witness:explicit-executable-candidate by=target form=alphabet measure=id role=writes scope=dep/topos-doc/born shape=dist/index.js value=sha256:2c507e7fe764e55d08fc27b01567d462060fe50d1896d19866f831a823852ae5 -bound-lock/1 at=witness:process-captures-reader by=target form=alphabet measure=digest role=writes scope=dep/process-readings shape=dist/regions/vectors.js value=sha256:b22d161e8ae7c96789c7fb038b1d755fa149203c7e035c6d2fa5f2a164fecb54 -bound-lock/1 at=witness:process-captures-selection by=target form=alphabet measure=digest role=writes scope=uses/process-readings value=sha256:a55f6849b39e77b6fcd89b2a2ba8fa286a7c8626193bbfe14aef30bef6b29458 +bound-lock/1 at=witness:bound/015-declared-reader-closure by=target form=alphabet measure=digest role=writes scope=dep/source-readings shape=dist/regions/source.js value=sha256:4254d2792e9e9826955869350da433a7c18a2211f158a3bc5f590e40db0153de +bound-lock/1 at=witness:bound/015-declared-reader-closure by=target form=alphabet measure=digest role=writes scope=uses/source-readings value=sha256:5393797da6adb25038d3ff94935be96376331735b259e125093a9e10e891f4de +bound-lock/1 at=witness:bound/015-hermetic-render-closure by=target form=alphabet measure=digest role=writes scope=uses/rendering value=sha256:c0094dc8c916b3c8ea9df19666816a28230c01808e5d792833c156e8d454a2f0 +bound-lock/1 at=witness:bound/015-hermetic-render-closure by=target form=alphabet measure=id role=writes scope=dep/topos-doc/born shape=dist/index.js value=sha256:04feef01a8c59cae7ea842198d1faf0091b424129872a847b41c7da0bca6fabf +bound-lock/1 at=witness:bounded-process-vectors by=target form=alphabet measure=digest role=writes scope=dep/process-readings shape=55b78b6c0a8ae86d84853ae34773b3a6947b31738b1242b20efa0da492ca0547 value=sha256:3f17467234fe9fce12d2859da21f7deba428b8279b387d33cb769e932ada3ecc +bound-lock/1 at=witness:bounded-process-vectors by=target form=alphabet measure=digest role=writes scope=uses/process-readings value=sha256:1dc6bb7b0a8587eadc52dacc3a74934d8707042a1078182a687d10d3df2deb0e +bound-lock/1 at=witness:per-reading-publication by=target form=alphabet measure=digest role=writes scope=dep/publication-readings shape=c298746ef68fdf192a0feede8f514e42f28700a2c2bc542edabee7c7c090f64d value=sha256:63404128efbf4173dfcb8ba757cf9c8cc41f692dd13d5d00a0835d8c70dec7e0 +bound-lock/1 at=witness:per-reading-publication by=target form=alphabet measure=digest role=writes scope=uses/publication-readings value=sha256:ded485f3bf8ac0f11c73f61223f4180038b8c44904ea4f573a240b59a651a489 bound-lock/1 at=witness:project-coordinates-are-relative by=target form=interval measure=count needs=samples/core/yes/exchange-cost.json|samples/core/no/exchange-cost.json role=reads scope=exchange/cost value=0..0 bound-lock/1 at=witness:project-coordinates-are-relative by=target form=interval measure=count needs=samples/core/yes/idempotent.json|samples/core/no/idempotent.json role=reads scope=idempotent value=0..0 bound-lock/1 at=witness:project-coordinates-are-relative by=target form=interval measure=count needs=samples/core/yes/no-error.json|samples/core/no/no-error.json role=reads scope=no-error value=0..0 @@ -385,6 +437,18 @@ bound-lock/1 at=witness:project-coordinates-are-relative by=target form=interval bound-lock/1 at=witness:project-coordinates-are-relative by=target form=interval measure=count needs=samples/literal/yes/org.json|samples/literal/no/org.json role=reads scope=literal/org value=0..0 bound-lock/1 at=witness:project-coordinates-are-relative by=target form=interval measure=count needs=samples/literal/yes/path.json|samples/literal/no/path.json role=reads scope=literal/path value=0..0 bound-lock/1 at=witness:public-artifact-closure by=target form=alphabet measure=digest needs=node_modules/typescript role=reads scope=dep/typescript shape=package value=sha256:10e108c9cf7d5f2879053dff18515fb405abf2ccef63eaaf017d9c571687a1d3 -bound-lock/1 at=witness:source-reader by=target form=alphabet measure=digest role=writes scope=dep/source-readings shape=dist/regions/source.js value=sha256:5ccae33a9e99f6acba690d9664e22cfe818205841e4e9d3083d4b24fb68d7075 +bound-lock/1 at=witness:public-contracts-by-operation by=target form=alphabet measure=id needs=docs/contracts/archive.md role=demands scope=view/contract-archive-reference shape=docs/contracts/archive.md value=text@3 +bound-lock/1 at=witness:public-contracts-by-operation by=target form=alphabet measure=id needs=docs/contracts/cli.md role=demands scope=view/contract-cli-reference shape=docs/contracts/cli.md value=text@3 +bound-lock/1 at=witness:public-contracts-by-operation by=target form=alphabet measure=id needs=docs/contracts/documents.md role=demands scope=view/contract-documents-reference shape=docs/contracts/documents.md value=text@3 +bound-lock/1 at=witness:public-contracts-by-operation by=target form=alphabet measure=id needs=docs/contracts/views.md role=demands scope=view/contract-views-reference shape=docs/contracts/views.md value=text@3 +bound-lock/1 at=witness:public-instrument-input-is-declared by=target form=alphabet measure=coordinates role=writes scope=region/publication value=docs/contracts/**|samples/**|vectors/**|tools/publication/**|tools/samples/**|dist/**|package.json|TARGET.bound +bound-lock/1 at=witness:publication-is-measured by=target form=alphabet measure=id needs=docs/contracts/publication.inventory.json role=demands scope=view/publication-inventory shape=docs/contracts/publication.inventory.json value=text@3 +bound-lock/1 at=witness:publication-is-measured by=target form=alphabet measure=id needs=docs/contracts/publication.md role=demands scope=view/publication-contract shape=docs/contracts/publication.md value=text@3 +bound-lock/1 at=witness:publication-is-measured by=target form=alphabet measure=id role=writes scope=release/blocks value=integrity|pins|admission|cli|contract +bound-lock/1 at=witness:publication-is-measured by=target form=alphabet measure=id role=writes scope=release/category/contract value=contract/published +bound-lock/1 at=witness:publication-is-measured by=target form=alphabet measure=receipts role=writes scope=region/program-evidence value=contract/**|plan/**|docs/contracts/**|samples/**|vectors/** +bound-lock/1 at=witness:publication-is-measured by=target form=alphabet measure=receipts role=writes scope=region/publication value=contract/published/**|docs/contracts/**|samples/**|vectors/** +bound-lock/1 at=witness:publication-samples by=target form=alphabet measure=id needs=docs/contracts/evidence-view.md role=demands scope=view/contract-evidence-view shape=docs/contracts/evidence-view.md value=text@3 +bound-lock/1 at=witness:publication-samples by=target form=alphabet measure=id needs=docs/contracts/typed-object.md role=demands scope=view/contract-typed-object shape=docs/contracts/typed-object.md value=text@3 +bound-lock/1 at=witness:publish-native-walk-contract by=target form=alphabet measure=id needs=docs/contracts/view-walk.md role=demands scope=view/contract-walk shape=docs/contracts/view-walk.md value=text@3 bound-lock/1 at=witness:source-region-inputs by=target form=alphabet measure=coordinates role=reads scope=region/source value=src/**/*.ts -bound-lock/1 at=witness:source-selection by=target form=alphabet measure=digest role=writes scope=uses/source-readings value=sha256:4129c469d3296a1fcda640f59e0d7c37f255b1e88c2f8e2447cd1359a514f356 diff --git a/docs/contracts/archive-conformance.publication.json b/docs/contracts/archive-conformance.publication.json new file mode 100644 index 0000000..f02f5ca --- /dev/null +++ b/docs/contracts/archive-conformance.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/pipeline/archive", + "members": [ + { + "role": "contract", + "path": "docs/contracts/archive.md", + "digest": "sha256:eedbd0ca544377080763c035053e532bfc46ddd496c3794e0cac2e0d6286e3a9" + }, + { + "role": "yes", + "path": "samples/yes/archive-conformance.json", + "digest": "sha256:1e2a1ce055edb12da86e1ddbbf78e1f9cb910ad6fe14f57fc3e360751e604a4c" + }, + { + "role": "vector", + "path": "vectors/archive-conformance.json", + "digest": "sha256:c9e9566f19db9feb6a8a7619315bdb19d66f2cd7bba90f911fc047b89f4ebd8f" + }, + { + "role": "no", + "path": "samples/no/archive-conformance.json", + "digest": "sha256:e14e5007e6b097be39964a749a09fb7143f652129869a8902743eee3ec9b89ea" + } + ] +} diff --git a/docs/contracts/archive.md b/docs/contracts/archive.md new file mode 100644 index 0000000..11c0891 --- /dev/null +++ b/docs/contracts/archive.md @@ -0,0 +1,11 @@ +# Exact release artifact + +Packing is a host operation. An archive digest names those archive bytes; it is not the identity of a Topos standing. The release pipeline makes one archive and transfers that same file to its destinations. Repeating a pack operation is not a proof of identical bytes. + +The archive conformance vector declares the host package command, digest algorithm, execution deadline, response bound and its sample packages. It packs each sample once, hashes the resulting bytes, verifies both destination copies, installs offline without package scripts and compares every listed installed member with the input bytes. It executes the installed entry and checks its declared output. Changed archive bytes refuse by digest before they can be treated as the named artifact. The negative control fails when that verification is removed. + +The samples use independent packages with different contents. Their outputs and member digests are captured by the executable vector; their file presence alone is not evidence. The selected publication reader measures this quartet through the existing process contract, and native receipts supply its member status to the plan. + +This is conformance of the packaging recipe. Acceptance of a particular Bound candidate additionally requires the exact archive audit, clean installation and product CLI captures for that archive. A previous archive's captures cannot certify changed implementation bytes. The final candidate must be rebuilt after admitted metadata changes, with every changed member accounted for. The product witness uses the installed reader directly, without a checkout ledger or source conditions. + +Rendering and installation are different boundaries. README, the manifest and the standard MIT text remain native renders. Publication to a registry or forge is a later owner action; this vector does not publish, authenticate to an account, create a tag or infer an external release from a local file. diff --git a/docs/contracts/attest-evidence.publication.json b/docs/contracts/attest-evidence.publication.json new file mode 100644 index 0000000..88d848f --- /dev/null +++ b/docs/contracts/attest-evidence.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/attest-evidence-view", + "members": [ + { + "role": "contract", + "path": "docs/contracts/evidence-view.md", + "digest": "sha256:522740051150e3b35dcca31bcc398b18b8cc8b5f9b18417ec4c676f5ea59e61d" + }, + { + "role": "yes", + "path": "samples/yes/native-views.json", + "digest": "sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3" + }, + { + "role": "no", + "path": "samples/no/native-views.json", + "digest": "sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5" + }, + { + "role": "vector", + "path": "vectors/native-views.json", + "digest": "sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc" + } + ] +} diff --git a/docs/contracts/cli-fold.publication.json b/docs/contracts/cli-fold.publication.json new file mode 100644 index 0000000..2fd09e7 --- /dev/null +++ b/docs/contracts/cli-fold.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/cli/fold", + "members": [ + { + "role": "contract", + "path": "docs/contracts/cli.md", + "digest": "sha256:97cddb7dac0c426b40c51d852d6176ae8f389351cc3366206f8acb0e58c7117a" + }, + { + "role": "yes", + "path": "samples/yes/native-views.json", + "digest": "sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3" + }, + { + "role": "no", + "path": "samples/no/native-views.json", + "digest": "sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5" + }, + { + "role": "vector", + "path": "vectors/native-views.json", + "digest": "sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc" + } + ] +} diff --git a/docs/contracts/cli-land.publication.json b/docs/contracts/cli-land.publication.json new file mode 100644 index 0000000..8552229 --- /dev/null +++ b/docs/contracts/cli-land.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/cli/land", + "members": [ + { + "role": "contract", + "path": "docs/contracts/cli.md", + "digest": "sha256:97cddb7dac0c426b40c51d852d6176ae8f389351cc3366206f8acb0e58c7117a" + }, + { + "role": "yes", + "path": "samples/yes/native-views.json", + "digest": "sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3" + }, + { + "role": "no", + "path": "samples/no/native-views.json", + "digest": "sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5" + }, + { + "role": "vector", + "path": "vectors/native-views.json", + "digest": "sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc" + } + ] +} diff --git a/docs/contracts/cli-sign.publication.json b/docs/contracts/cli-sign.publication.json new file mode 100644 index 0000000..0018210 --- /dev/null +++ b/docs/contracts/cli-sign.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/cli/sign", + "members": [ + { + "role": "contract", + "path": "docs/contracts/cli.md", + "digest": "sha256:97cddb7dac0c426b40c51d852d6176ae8f389351cc3366206f8acb0e58c7117a" + }, + { + "role": "yes", + "path": "samples/yes/signing-port.json", + "digest": "sha256:2bbf951b29ba00e715443c1ea24884a46296ee2a5bf7fd03f6fd681ea0eacb69" + }, + { + "role": "no", + "path": "samples/no/signing-port.json", + "digest": "sha256:bb45e5385c5efad77607edfcd79af5faa5cb064d30b2d27a0b9c79de807bca15" + }, + { + "role": "vector", + "path": "vectors/signing-port.json", + "digest": "sha256:53cc8abaccbcb37385fdc1acd1d251c4d3d77ca44df4f8436ee498acf40d4fde" + } + ] +} diff --git a/docs/contracts/cli.md b/docs/contracts/cli.md new file mode 100644 index 0000000..c5f4dbb --- /dev/null +++ b/docs/contracts/cli.md @@ -0,0 +1,11 @@ +# fold + +`bound fold` reads the admitted place. Configuration output names readings and says no encounters computed; its counts are not independent-origin states. A declared cells view projects admitted typed history into Obligations. A selected world defines other views; its contract decides when empty output is valid. A refusal or nonzero status wins over any parseable diagnostic stdout. `--check` verifies receipts without inventing a missing reading. The published evidence vector folds fresh places, preserves admitted key attribution, reads a native receipt and checks exact withdrawals. The typed-object quartet covers object states separately. + +# land + +`bound land ` admits authenticated lines through the same boundary used by signing and previews. Authority, coverage, historical wire and typed context remain distinct checks. Unknown wire and tampered signatures refuse. Exact redelivery returns ONCE; it does not append another origin or grant new authority. Withdrawals remain exact under their declared contract. A refusal does not append a partial act. The published evidence vector lands fresh places, refuses unauthorized writes and tampering, redelivers signed bytes and exercises exact withdrawals. The signing-port vector additionally checks interrupted or invalid command responses do not land a partial lot. + +# sign + +`bound sign ` returns canonical signed lines after validating the whole lot. The admitted key selects a declared signer; `--signer` selects the same port explicitly. File and command mechanisms use one port. Topos signing-lot/1 frames canonical bytes in lot order, one invocation per lot, and returns signatures and public-key IDs. Verification checks the admitted public key, independently of the mechanism. A command is invoked without a shell and under declared bounds. No secret output is disclosed in refusals. Missing, invalid, partial, timed-out or failed responses refuse; `land` cannot commit their partial output. The sample compares file and command signatures and landed lines, checks invocation count and ledger hashes, and refuses an unknown wire version. The sample uses ephemeral keys outside the place; no owner key is included. diff --git a/docs/contracts/documents.md b/docs/contracts/documents.md new file mode 100644 index 0000000..1d78434 --- /dev/null +++ b/docs/contracts/documents.md @@ -0,0 +1,35 @@ +# Explanation — historical profile + +The declared view selects idea, what-holds and refuses from the byte-pinned historical document provider. The place owns its language and prose. Idea renders its own heading and body. The other two regions require their declared law readings or captured refusals; absent evidence supplies no invented result. The executable sample uses two unrelated places, checks the complete explanation file, repeats the product fold without a file difference and asks the named view directly. It also refuses a well-formed view asking an unoffered region. This quartet proves own-prose projection and absence under this profile; it does not certify law readings, a rejection corpus, typed-object states or the pending general document contract. Bound does not parse this prose. + +# README — historical profile + +The declared view selects hero@3, commands@3 and idea@3 from the byte-pinned historical document provider. The place supplies its name, tagline, language, sentence rule and idea. Commands and measured badges are absent in the sample: no command, number or success is invented to fill them. Two unrelated places check the generated README, a second unchanged product fold and the named view; a declared unoffered region refuses by name. The implementation member is verified against the admitted historical artifact. This quartet proves the selected prose profile, not command execution, badges with measured values or a general document grammar. The eight text@3 demands remain unpaid. + +# Citation file — historical profile + +The declared view asks the pinned document provider for cff at resolution 3. It projects the place name, version and optional citation metadata into CFF text. The sample uses the exact implementation member from the admitted historical artifact, names its hash and license, and exercises two unrelated places through the compiled CLI. It checks complete citation bytes and two equal readings; title and version follow each place. An unoffered region refuses by view name. Missing optional metadata is omitted; missing name can produce an empty answer under this historical profile. Rendering is not verification of a scientific claim or an external DOI. This pinned profile does not implement the pending general document contract. + +# Guide — historical profile + +The declared view asks seq from the pinned historical document provider. The place owns page/seq lines and their heading. Canonical input order supplies the steps; the provider numbers that order and writes the requested shape. The executable sample uses two unrelated procedures, checks their complete Markdown and reads each view twice without differences. A declared view with an unoffered region refuses by name. An empty step set may have an empty answer; it is not invented evidence. A rendered instruction does not prove that instruction was executed. The implementation bytes remain the existing pinned profile, not a document grammar inside Bound. + +# Reference — historical profile + +The declared view combines term, set and ref from the pinned historical document provider. The profile projects the place term and meaning, its selected world names and links to its declared Markdown shapes. The executable sample runs two unrelated places, checks their own term and meaning, the actual selected world and relative guide link, and captures two identical CLI readings. A view asking an unoffered region refuses by name. Missing terms or links can yield empty component answers; these are not measurements or a claim that obligations were paid. These historical regions and selectors belong to the selected Topos; Bound supplies verified inputs and dispatch only. The general document contract remains unpaid. + +# Manifest render profile + +This declared view uses the selected verbatim-prose provider at text@3. The place assigns its complete manifest text to its output shape; Bound verifies and dispatches the selected offer and writes that shape. The provider does not infer a package schema, dependency graph or fields from the filename. The sample renders two places with distinct JSON bodies twice and checks exact file bytes. Two distinct prose bodies assigned to the same shape refuse; earlier outputs remain unchanged. This proves rendering, not that arbitrary JSON is an installable package. + +# Workflow render profile + +This declared view uses the selected verbatim-prose provider at text@3. The place owns the workflow text and its shape; Bound does not infer a forge or manufacture pipeline steps. The sample writes distinct YAML bodies in two places, reads the rendered files twice and compares exact bytes. Conflicting bodies for one shape refuse without replacing prior outputs. This is a render contract, not evidence that a forge executed, staged or published a release. The release pipeline has its separate artifact gate. + +# Usage render profile + +This declared view uses the selected verbatim-prose provider at text@3. A prose line with measure=text and the requested shape supplies its own body. The sample renders distinct Markdown bodies in two places twice and compares exact bytes. Multiple identical bodies are one text; differing bodies for one shape refuse. It invents no sections or documentation schema. This existing profile does not pay the eight general-document demands or validate commands that prose happens to mention; executable commands require their own captured vectors. + +# Build configuration — historical profile + +The declared tsconfig view asks the admitted package provider for its build region. It projects the place's build/* lines whose shape matches the requested file: true and false become JSON booleans, other option values remain strings, and include separates its declared alternatives. The byte-fixed fixture names the implementation member and its artifact independently; Bound does not interpret compiler options. Two unrelated places exercise the compiled CLI, check the complete generated configuration and two byte-identical readings. A declared view asking an unoffered region refuses by name. This profile renders configuration; it does not validate compiler options or claim a successful build. An empty option set renders an empty compilerOptions object. It is a pinned historical profile, not the pending general document contract. diff --git a/docs/contracts/evidence-view.md b/docs/contracts/evidence-view.md new file mode 100644 index 0000000..fc44387 --- /dev/null +++ b/docs/contracts/evidence-view.md @@ -0,0 +1,6 @@ +# Authenticated evidence view + +The declared evidence@8 view projects authenticated delivery history of this place. It preserves signatures and key attribution, including admitted receipts from an attest-class key. Evidence is not normative configuration, proof of truth, or an independent observation origin. Authority and coverage are checked by the existing Topos contract; no consumer or device type changes that boundary. + + +The no sample specifies an uncovered write and tampered signed bytes. Both must refuse by name. Exact withdrawals remove only covered normative lines; authenticated evidence remains inspectable. The vectors assert status, signature verification and observable CLI output. No private key bytes are printed or shipped. diff --git a/docs/contracts/publication.inventory.json b/docs/contracts/publication.inventory.json new file mode 100644 index 0000000..5419358 --- /dev/null +++ b/docs/contracts/publication.inventory.json @@ -0,0 +1,29 @@ +{ + "profile": "quartet-process@1", + "scope": "contract/published", + "surface": [ + "contract/published/attest-evidence-view", + "contract/published/cli/fold", + "contract/published/cli/land", + "contract/published/cli/sign", + "contract/published/pipeline/archive", + "contract/published/typed-object-sample", + "contract/published/view/card", + "contract/published/view/citation-file", + "contract/published/view/explanation", + "contract/published/view/guide", + "contract/published/view/help", + "contract/published/view/lines", + "contract/published/view/manifest-render", + "contract/published/view/programs", + "contract/published/view/readme-historical", + "contract/published/view/receipts", + "contract/published/view/reference", + "contract/published/view/release-workflow-render", + "contract/published/view/tsconfig", + "contract/published/view/usage-profile", + "contract/published/view/walk", + "contract/published/view/why" + ], + "note": "Explicit public-surface inventory. A selected coordinate without a descriptor is unpaid. Outstanding capability demands are not advertised implementations." +} diff --git a/docs/contracts/publication.md b/docs/contracts/publication.md new file mode 100644 index 0000000..e89a2e1 --- /dev/null +++ b/docs/contracts/publication.md @@ -0,0 +1,17 @@ +# Published contracts + +Every public surface names its contract, accepted sample, captured executable vector and rejected sample. Missing members, differing artifact digests and failed vectors remain unpaid. Publication conformance is distinct from installed-artifact acceptance. + +The selected Topos projects each quartet as a reading through the existing wire. Execution proofs are dependency readings; identical vector bytes share one proof. Each reading names its exact handed inputs and dependent receipt digests. Bound verifies those closures and keeps native count/bytes receipts by digest. A closed reading costs no new execution. The publication aggregate reads the quartet receipts; it never starts an inventory batch. + +Execution slots, per-execution timeout and response bytes are declared resource lines in the selected Topos. Bounds remain unchanged. A failed reading is not cached as a successful proof. Earlier completed readings stay verified, so a later refusal does not force them to execute again. Changed, missing or corrupt bytes cannot reuse their receipts. Output and execution history retain their exact coordinates. + +## Act cost + +Each declared reading and each host invocation is measured separately. The total duration of a pass is a diagnostic; it is not the cost of one indivisible act. The cost/act ceiling reads the largest measured act or the remaining unpartitioned host work. Nested invocations are not charged twice. A slow or refused act retains its cost. Native reading receipts retain measured seconds separately from semantic identity; reusing a receipt performs no new reader execution. Missing historical durations are not invented as zero. + +## Public verification + +Full-resolution native reading receipts carry the verified canonical UTF-8 input closure in the bytes row and the verified output in the count row, through the wire’s existing about field. Count, digest and measured duration keep their existing meanings. The host verifies the supplied bytes against those digests before reuse; an altered supplied carrier is not replaced by a cached copy. Historical local-only receipts still require their authentic CAS bytes. No private ledger or store is needed to verify a complete public receipt. + +File-region seals hash configuration through Topos’s existing publication projection. Admission envelopes and retired history stay in the authority ledger; live declarations and ordinary file bytes remain inputs. Object history uses its own contract. A public checkout must carry receipts made for its actual files and compiled reader, not seals copied from a different tree. Verification does not run readers, fetch dependencies, refresh receipts or grant authority. diff --git a/docs/contracts/typed-object.md b/docs/contracts/typed-object.md new file mode 100644 index 0000000..0808744 --- /dev/null +++ b/docs/contracts/typed-object.md @@ -0,0 +1,27 @@ +## Typed cell, claim and mark records + +The object profile is selected by admitted `wire/object/*` claims in a historical wire snapshot. The epoch of `wire/object/types` is its activation E; a typed record must have epoch >= E. An older record keeps the older grammar. Merely adding object words to `wire/fields` does not admit a typed profile. + +`fromLine` selects grammar before validating required fields: a record without `type` remains configuration, retaining its required `at`, `role`, `form`, `measure` and `value`; a typed record selects its exact required/allowed row. Configuration cannot carry object-only fields. An incomplete typed record receives no configuration defaults. The parse result distinguishes configuration from cell/claim/mark. `sign=+1|-1` is an object act, `sig` its signature envelope, and a host sign operation produces that envelope. + +The common object envelope is `type`, `scope`, `id`, `epoch`, `by`, `sig`. Object records reject `at`: epoch orders acts, and `widens` names a local join witness. The following is the declared reference profile. The admitted row alphabets, not this table or a host decoder, are the source of required/allowed field permission. + +| Row | Fields in addition to the common envelope | Meaning | +| --- | --- | --- | +| cell | form, measure, params, restsOn, topos | Define a cell and its selected form/context. | +| claim/positive | sign, origin, value | Observe an encoded span, sign=+1. | +| claim/negative | sign, takes | Withdraw an exact claim ID, sign=-1. | +| mark/travelling | sign, pole, reach, value | Ceiling sign: sign=+1, pole=ceiling, reach=travels. | +| mark/local | sign, pole, reach, value, widens | Local join: sign=+1, pole=ceiling, reach=local; another mark, retaining the travelling sign. | +| mark/floor-travelling | sign, pole, reach, value | Travelling require: sign=+1, pole=floor, reach=travels; no widens. | +| mark/negative | sign, takes | Withdraw an exact mark ID, sign=-1; no pole/reach/widens. | + +Each row has both `wire/object/required/` and `wire/object/allowed/`. Unknown keys, missing required keys, floor/local, floor+widens, and travelling widening refuse without coercion. A configuration demand is unrelated to a floor mark. `by` authenticates a signing key; it is not an independent observation origin. + +For a cell, `restsOn=none` represents no parents; otherwise it is a canonical byte-ordered alphabet of coordinates. Several parents are permitted. Only declared cell-coordinate edges form object rest; a directory prefix, a configuration artifact digest, and a host source location do not. Context validation rejects reachable cycles before algebraic parts are requested. + +The cell's `topos` names folded standing, and its `params` identifies declared parameter bytes. A selected provider decodes values and supplies origin/witness authorization from admitted evidence. A host does not infer interval endpoints, map a key to an origin, or accept widens as its own witness. Missing pin, artifact, decoder, origin or witness refuses by cause. Cell definitions and pins are immutable in this profile; migration is not inferred. + +`objectHistory` preserves typed history separately from configuration; `validateObjectContext` checks IDs, cell ownership, exact takes, witness order and declared rest under the selected context. Exact redelivery is idempotent; one ID with different canonical content refuses. Signature-envelope differences never bypass verification. + +After admission, the instrument projects the acts into Obligations. Sign and require travel along declared rest; a witnessed join is local. Descendants inherit travelling marks without local widening. Live exact-ID withdrawals remain confined to their authenticated history. Keys, snapshots, signing devices and repeated receipts do not create independent origins. Compatible meets are not forks. Object states and their precedence come from Obligations; configuration folds do not compute object encounters. diff --git a/docs/contracts/typed-object.publication.json b/docs/contracts/typed-object.publication.json new file mode 100644 index 0000000..1c84237 --- /dev/null +++ b/docs/contracts/typed-object.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/typed-object-sample", + "members": [ + { + "role": "contract", + "path": "docs/contracts/typed-object.md", + "digest": "sha256:73925fbdaa4a9418b63fe28a9f6d36430eaaa59eb357657cdbe45129fb9454fe" + }, + { + "role": "yes", + "path": "samples/yes/typed-object.json", + "digest": "sha256:b54bac71e89800f09cb55331a4cebde2e280d5240b062a317ffabbc02edcfa7d" + }, + { + "role": "vector", + "path": "vectors/typed-object.json", + "digest": "sha256:32f8b095f4a240c6a3c640797a9f0fbc05506fa623e7cb61f0d9fd8c8bd9124a" + }, + { + "role": "no", + "path": "samples/no/typed-object.json", + "digest": "sha256:03ac2a40efbea4232025e99d37f06bca03292fcfe3c41c8c27dd5647080951a0" + } + ] +} diff --git a/docs/contracts/view-card.publication.json b/docs/contracts/view-card.publication.json new file mode 100644 index 0000000..482b3ff --- /dev/null +++ b/docs/contracts/view-card.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/card", + "members": [ + { + "role": "contract", + "path": "docs/contracts/views.md", + "digest": "sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8" + }, + { + "role": "yes", + "path": "samples/yes/program-views.json", + "digest": "sha256:b1e8feb6839050a09410dade936cbb827ac438ff8c7b962e5fefd50f601d1b15" + }, + { + "role": "no", + "path": "samples/no/program-views.json", + "digest": "sha256:bf6b2fbd11290920e31f46c18012be2230ffdab47dc7013d3a0aafae1fd6cbe7" + }, + { + "role": "vector", + "path": "vectors/program-views.json", + "digest": "sha256:a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71" + } + ] +} diff --git a/docs/contracts/view-citation-file.publication.json b/docs/contracts/view-citation-file.publication.json new file mode 100644 index 0000000..3500631 --- /dev/null +++ b/docs/contracts/view-citation-file.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/citation-file", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-explanation.publication.json b/docs/contracts/view-explanation.publication.json new file mode 100644 index 0000000..44827aa --- /dev/null +++ b/docs/contracts/view-explanation.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/explanation", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-guide.publication.json b/docs/contracts/view-guide.publication.json new file mode 100644 index 0000000..3a58f14 --- /dev/null +++ b/docs/contracts/view-guide.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/guide", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-help.publication.json b/docs/contracts/view-help.publication.json new file mode 100644 index 0000000..72429dc --- /dev/null +++ b/docs/contracts/view-help.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/help", + "members": [ + { + "role": "contract", + "path": "docs/contracts/views.md", + "digest": "sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8" + }, + { + "role": "yes", + "path": "samples/yes/native-views.json", + "digest": "sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3" + }, + { + "role": "no", + "path": "samples/no/native-views.json", + "digest": "sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5" + }, + { + "role": "vector", + "path": "vectors/native-views.json", + "digest": "sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc" + } + ] +} diff --git a/docs/contracts/view-lines.publication.json b/docs/contracts/view-lines.publication.json new file mode 100644 index 0000000..94f3647 --- /dev/null +++ b/docs/contracts/view-lines.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/lines", + "members": [ + { + "role": "contract", + "path": "docs/contracts/views.md", + "digest": "sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8" + }, + { + "role": "yes", + "path": "samples/yes/native-views.json", + "digest": "sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3" + }, + { + "role": "no", + "path": "samples/no/native-views.json", + "digest": "sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5" + }, + { + "role": "vector", + "path": "vectors/native-views.json", + "digest": "sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc" + } + ] +} diff --git a/docs/contracts/view-manifest-render.publication.json b/docs/contracts/view-manifest-render.publication.json new file mode 100644 index 0000000..a3a1553 --- /dev/null +++ b/docs/contracts/view-manifest-render.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/manifest-render", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-programs.publication.json b/docs/contracts/view-programs.publication.json new file mode 100644 index 0000000..ac66c99 --- /dev/null +++ b/docs/contracts/view-programs.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/programs", + "members": [ + { + "role": "contract", + "path": "docs/contracts/views.md", + "digest": "sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8" + }, + { + "role": "yes", + "path": "samples/yes/program-views.json", + "digest": "sha256:b1e8feb6839050a09410dade936cbb827ac438ff8c7b962e5fefd50f601d1b15" + }, + { + "role": "no", + "path": "samples/no/program-views.json", + "digest": "sha256:bf6b2fbd11290920e31f46c18012be2230ffdab47dc7013d3a0aafae1fd6cbe7" + }, + { + "role": "vector", + "path": "vectors/program-views.json", + "digest": "sha256:a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71" + } + ] +} diff --git a/docs/contracts/view-readme-historical.publication.json b/docs/contracts/view-readme-historical.publication.json new file mode 100644 index 0000000..d1feb30 --- /dev/null +++ b/docs/contracts/view-readme-historical.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/readme-historical", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-receipts.publication.json b/docs/contracts/view-receipts.publication.json new file mode 100644 index 0000000..7b9a63e --- /dev/null +++ b/docs/contracts/view-receipts.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/receipts", + "members": [ + { + "role": "contract", + "path": "docs/contracts/views.md", + "digest": "sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8" + }, + { + "role": "yes", + "path": "samples/yes/native-views.json", + "digest": "sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3" + }, + { + "role": "no", + "path": "samples/no/native-views.json", + "digest": "sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5" + }, + { + "role": "vector", + "path": "vectors/native-views.json", + "digest": "sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc" + } + ] +} diff --git a/docs/contracts/view-reference.publication.json b/docs/contracts/view-reference.publication.json new file mode 100644 index 0000000..348a0e7 --- /dev/null +++ b/docs/contracts/view-reference.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/reference", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-release-workflow-render.publication.json b/docs/contracts/view-release-workflow-render.publication.json new file mode 100644 index 0000000..a5fc70b --- /dev/null +++ b/docs/contracts/view-release-workflow-render.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/release-workflow-render", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-tsconfig.publication.json b/docs/contracts/view-tsconfig.publication.json new file mode 100644 index 0000000..f75b8a7 --- /dev/null +++ b/docs/contracts/view-tsconfig.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/tsconfig", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-usage-profile.publication.json b/docs/contracts/view-usage-profile.publication.json new file mode 100644 index 0000000..4054329 --- /dev/null +++ b/docs/contracts/view-usage-profile.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/usage-profile", + "members": [ + { + "role": "contract", + "path": "docs/contracts/documents.md", + "digest": "sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375" + }, + { + "role": "yes", + "path": "samples/yes/historical-document-views.json", + "digest": "sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc" + }, + { + "role": "no", + "path": "samples/no/historical-document-views.json", + "digest": "sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9" + }, + { + "role": "vector", + "path": "vectors/historical-document-views.json", + "digest": "sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94" + } + ] +} diff --git a/docs/contracts/view-walk.md b/docs/contracts/view-walk.md new file mode 100644 index 0000000..079cc5c --- /dev/null +++ b/docs/contracts/view-walk.md @@ -0,0 +1,7 @@ +# Walk + +`bound fold --as walk@` compares the admitted place with an authenticated peer inventory. Resolution is interpreted by the declared Topos selection and projection contract; it is not restricted to three fixed numbers. The wire declares region membership, context, origin and cuts. The output names touched regions, open regions and payload bytes; protocol and imported bytes carry their own units. + +Foreign history retains its signed origin epoch. Sender keys authenticate that history and never grant coverage or independent origins in the receiver. Whole-region prefixes are verified before ingress. Import and the receiver-signed local receipt commit atomically; only that receipt advances the receiver's local epoch. Foreign withdrawals are confined to the same authenticated origin and exact identifier. A repeated valid delivery adds no lines and retains its existing import receipt. A rejected or interrupted ingress adds neither evidence nor a receipt. + +The published sample uses the same compiled public reader on measurement and artifact places. It compares equal summaries, opens a differing region, exchanges at intermediate declared resolutions, converges by union, retains disagreement and verifies replay after a later local act. It rejects tampered payloads, missing records, unauthorized signatures, non-prefix epochs and undeclared context changes. It interrupts a real receiver signer and verifies unchanged ingress and local history. Dead-owner recovery is a separate host action; this view does not silently recover it. The typed object's origin-local claims and withdrawals are a separate conformance vector, not inferred from configuration counts. diff --git a/docs/contracts/view-walk.publication.json b/docs/contracts/view-walk.publication.json new file mode 100644 index 0000000..cdc1b9c --- /dev/null +++ b/docs/contracts/view-walk.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/walk", + "members": [ + { + "role": "contract", + "path": "docs/contracts/view-walk.md", + "digest": "sha256:fc4cf29128d028c49380db8c28f8b68b692b8f25e577ed3eec238cb805cb18b6" + }, + { + "role": "yes", + "path": "samples/yes/walk.json", + "digest": "sha256:d316e1ca1d07ee2a70038d1ee0df1d6e0d318f71d6364fd13377d2b9ee26a0ac" + }, + { + "role": "vector", + "path": "vectors/walk-publication.json", + "digest": "sha256:d31a059a2eb8b137ec026d0c5b7b2aea5de809f349526c6bc4a916abe14a0113" + }, + { + "role": "no", + "path": "samples/no/walk.json", + "digest": "sha256:9e1b17f0e99285b1d89cf1967158422836ebdcd6542b2eea3cee074c5c26c233" + } + ] +} diff --git a/docs/contracts/view-why.publication.json b/docs/contracts/view-why.publication.json new file mode 100644 index 0000000..c048606 --- /dev/null +++ b/docs/contracts/view-why.publication.json @@ -0,0 +1,25 @@ +{ + "scope": "contract/published/view/why", + "members": [ + { + "role": "contract", + "path": "docs/contracts/views.md", + "digest": "sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8" + }, + { + "role": "yes", + "path": "samples/yes/query-views.json", + "digest": "sha256:105bdcf69a8179659033c898c8e27ee3d37aabdd0fb6f221a6affe10c579e317" + }, + { + "role": "no", + "path": "samples/no/query-views.json", + "digest": "sha256:a161c1c33dcfd357b610ae6835ecc4b16d7918a9216bab07ecb4de132e2b2ba4" + }, + { + "role": "vector", + "path": "vectors/query-views.json", + "digest": "sha256:2bf6a95f93dabc27c79db679eaf9ad4f5a6e7835e74d762df62fe256c5ea21c1" + } + ] +} diff --git a/docs/contracts/views.md b/docs/contracts/views.md new file mode 100644 index 0000000..e7d4f3f --- /dev/null +++ b/docs/contracts/views.md @@ -0,0 +1,29 @@ +# Help view + +A declared help view projects the instrument verb and flag table. It is generated from that table, not copied prose or a claim that another world is supported. Asking it does not authorize a line or call a selected external reader. The sample declares view/help value=help, checks the printed three verbs and refuses a declared view whose region has no provider. + +# Lines view + +A declared lines view projects canonical normative standing as wire lines. It is a configuration reading; it does not compute encounters or turn evidence into authority. Live exact withdrawals disappear from normative standing while authenticated evidence remains inspectable through its own view. The sample verifies signatures and attribution, redelivery ONCE, exact withdrawals, tampering and uncovered writes. A declared missing provider refuses rather than returning an invented reading. + +# Receipts view + +The native receipt view projects the fold through the admitted Topos receipt contract. The sample uses the published place profile receipts@8|receipts@0|receipts@1: observations, summary and current region bytes. These are that profile’s declared projections, not a universal enumeration of resolutions. A receipt identifies the actual observed set; it is not an origin or a valuation. The sample obtains a native receipt, verifies its signed delivery from an attest-class key through evidence, and checks idempotent delivery. The refused sample names an uncovered write, tampered signature and declared view without a provider. No harness-written JSON is used as a receipt. + +## Public verification + +Full-resolution native reading receipts carry the verified canonical UTF-8 input closure in the bytes row and the verified output in the count row, through the wire’s existing about field. Count, digest and measured duration keep their existing meanings. The host verifies the supplied bytes against those digests before reuse; an altered supplied carrier is not replaced by a cached copy. Historical local-only receipts still require their authentic CAS bytes. No private ledger or store is needed to verify a complete public receipt. + +File-region seals hash configuration through Topos’s existing publication projection. Admission envelopes and retired history stay in the authority ledger; live declarations and ordinary file bytes remain inputs. Object history uses its own contract. A public checkout must carry receipts made for its actual files and compiled reader, not seals copied from a different tree. Verification does not run readers, fetch dependencies, refresh receipts or grant authority. + +# Why a coordinate + +`bound fold --as why` explains the live declarations whose exact `needs` member or `shape` names that coordinate. It prints the selector, witness and value. It does not compute an object encounter or infer authority from a path. The published sample bootstraps two independent places, explains each declared source coordinate and prints `OPEN` for a coordinate no declaration names. That absence is not zero, green or a state. A declared view with no provider refuses by name with a nonzero status. Calling why without a coordinate is not this sample’s acceptance vector; its empty historical capture pays nothing. + +# Declared programs + +The programs view asks the selected Topos demand-status projection at resolution 8. Selection, minimum, evidence, elapsed reading and time ceiling coordinates belong to that Topos contract; Bound only hands admitted declarations and region receipts. Program status is derived from that evidence and the declared dependency graph. A demand with no evidence remains unread, its dependant remains blocked, and a missing elapsed reading keeps deadline unread. No cell encounter, origin count or information quantity is computed by this view. The sample uses the published SDK implementation on two unrelated demand chains, captures equal readings twice, names the next unblocked coordinate, and refuses dependency cycles. It does not provide stage conformance evidence or claim either program closed. + +# Demand card + +The declared card view asks the selected Topos demand-card projection at resolution 8. It reads the selected demand coordinates, their explicit dependencies and the handed evidence region under selectors declared by that Topos. It does not infer progress from files or convert a declaration into proof. A requirement without evidence is unread; an unpaid predecessor blocks its dependant. The next coordinate is an unblocked unpaid demand. Deadline is unread when no elapsed receipt is handed; absence is not zero. These labels describe program evidence, not Obligations cell states. The sample pins the implementation member from the published Topos SDK, folds two unrelated places twice with equal stdout and refuses a declared dependency cycle. This sample intentionally has no evidence to close either program; it certifies the projection of absence and order, not stage acceptance. diff --git a/docs/reference.md b/docs/reference.md index 0f5f410..3847151 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -3,13 +3,23 @@ | | | |---|---| | pin | process-readings | +| pin | programs | | pin | prose-render | +| pin | publication-readings | | pin | rendering | | pin | source-readings | | pin | wire | +- [archive](contracts/archive.md) +- [cli](contracts/cli.md) +- [documents](contracts/documents.md) +- [evidence-view](contracts/evidence-view.md) +- [typed-object](contracts/typed-object.md) +- [views](contracts/views.md) +- [view-walk](contracts/view-walk.md) - [why](why.md) - [guide](guide.md) +- [publication](contracts/publication.md) - [README](../README.md) - [reference](reference.md) - [usage](usage.md) diff --git a/docs/usage.md b/docs/usage.md index bb78419..71ebe4d 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -51,3 +51,9 @@ The accepted TARGET is independent of a contributor's scan. Commit native receip A contribution is a proposed lot with the leaf changes rendered from it. Send that lot for admission by the team's coverage. Do not submit hand-edited lock output as already accepted. Check secrets, extra bound files, foreign vendoring and uncaptured page claims before review. A review includes the product fold, meaningful suites and verification of the rendered bytes. Preserve their actual output and exit status. + +## Declaring a demand + +A new demand records what remains to be proved. Admission does not create conformance evidence or pay it. An OWED line after land says the declaration was admitted and remains unpaid. Signing authority and conformance evidence are separate inputs. + +The selected program projection reads declared requirements and handed evidence. Missing evidence stays unread; a missing elapsed-time reading is not zero. A dependency cannot close before its requirements and predecessors. Declaring a plan never certifies a release. diff --git a/docs/why.md b/docs/why.md index de2ee72..61c6866 100644 --- a/docs/why.md +++ b/docs/why.md @@ -2,6 +2,23 @@ Bound reads a project's admitted statements and observations through its selected Topos, then renders the declared views and records their inputs in receipts. The example below explains the object; a file-fold alone does not calculate its intervals. +## Use Bound in a project + +From a project with an admitted lock and selected views, inspect its standing, ask for its evidence, then verify the committed outputs: + +```sh +npx @lapxo/bound@0.1.5 fold --as lines +npx @lapxo/bound@0.1.5 fold --as receipts@1 +npx @lapxo/bound@0.1.5 fold --check +``` + +Use this flow to review a project change or check a dependency's declared contract. `--check` verifies existing evidence; it does not execute a missing reading. A file fold names readings and explicitly says that it computed no encounters. + +Independent observations are judged through the declared typed cells view. The selected topos supplies the form, origin evidence and bounds. Bound keeps attribution and exact-ID withdrawals through the fold. + +A selected form can instead describe a set of artifacts, a delivery interval or another domain's values. The project declares the form, origin evidence and views; Bound does not infer them from filenames or units. + + ## A meeting everyone can understand Ana is available from 10 to 14, Luis from 12 to 16, and the room from 10 to 13. Their common availability is 12 to 13. A boss available from 18 to 20 makes the encounter incompatible. Withdrawing that exact reading restores the overlap; Ana, Luis and the room remain. @@ -38,11 +55,11 @@ lot_dir="$(mktemp -d)" Have the selected view produce a proposal at `$lot_dir/proposal.bound`, or prepare the project's permitted lines there for review. Unsigned proposals use `by=target`, without a preassigned epoch or `sig`. Lots stay outside the repository; the committed bound files are only `TARGET.bound` and `receipts.bound`. ```sh -npx @lapxo/bound@0.1.4 sign "$lot_dir/proposal.bound" \ +npx @lapxo/bound@0.1.5 sign "$lot_dir/proposal.bound" \ --key "$BOUND_KEY_ID" --key-file "$BOUND_KEY_FILE" \ > "$lot_dir/signed.bound" && -npx @lapxo/bound@0.1.4 land "$lot_dir/signed.bound" && -npx @lapxo/bound@0.1.4 fold +npx @lapxo/bound@0.1.5 land "$lot_dir/signed.bound" && +npx @lapxo/bound@0.1.5 fold ``` `sign` assigns the admitted epoch and writes the signed lot to stdout. `land` validates the whole lot before admission. A refusal is evidence to inspect; it is not success. Do not proceed after a failed signature or admission. The key file is a PKCS8 private key matching the admitted public key; do not put it in the lot, source tree, package or CI artifacts. @@ -86,3 +103,7 @@ A pin names standing, not a download URL or runtime entry. Its declared artifact Use Bound where independently attributed observations must be judged against an accepted contract: compatibility between components, operational limits, or a team's project requirements. The selected topos must supply the actual measurements; a digest identifies the evidence without declaring it true. [Contribute a counterexample or a proposed lot](CONTRIBUTING.md). + +## Foundations and related libraries + +The two-sided constraint object is described in Nahum Ochoa's [Two-Sided Constraints on a Valued Lattice](https://doi.org/10.5281/zenodo.21858428), DOI `10.5281/zenodo.21858428`. Bound uses the object through [Obligations](https://github.com/Lapxo/obligations); [Topos](https://github.com/Lapxo/topos) supplies the wire and contracts for forms, views and selected worlds. Bound admits, folds and retains evidence across those declared boundaries. A digest identifies bytes; it does not certify that an observation is true. diff --git a/package-lock.json b/package-lock.json index 399fd42..478df75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "@lapxo/bound", - "version": "0.1.4", + "version": "0.1.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@lapxo/bound", - "version": "0.1.4", + "version": "0.1.5", "license": "MIT", "dependencies": { "@lapxo/obligations": "0.3.5", - "@lapxo/topos": "0.1.9" + "@lapxo/topos": "^0.1.11", + "acorn": "8.19.0" }, "bin": { "bound": "dist/cli/verb.js" @@ -33,9 +34,9 @@ } }, "node_modules/@lapxo/topos": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@lapxo/topos/-/topos-0.1.9.tgz", - "integrity": "sha512-uZE925/7Usut0sQs3onZ1nDe4Zv7HkJUnk2fEXVaffJcORiE7oRGzjCYYVlDqctoN9384YG9J+gW2gW2TxBGUA==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@lapxo/topos/-/topos-0.1.11.tgz", + "integrity": "sha512-fBl68I8P02H4T2tmXhUrVdvQrJsF0dJtiNqBQx9oe8NNRncAa2LN2b6V4CXyh/+zzirWU5u1yJ9BcpxaxaWrZg==", "license": "MIT", "dependencies": { "@lapxo/obligations": "^0.3.5" @@ -54,6 +55,18 @@ "undici-types": "~6.21.0" } }, + "node_modules/acorn": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", diff --git a/package.json b/package.json index fd819e3..9d69546 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lapxo/bound", - "version": "0.1.4", + "version": "0.1.5", "type": "module", "description": "Read the bounds you already wrote, fold them, and name the contradictions.", "main": "dist/cli/verb.js", @@ -13,7 +13,7 @@ "./package.json": "./package.json" }, "scripts": { - "test": "node --import ./test/setup.ts --test test/*.test.ts", + "test": "node --import ./test/setup.ts --test --test-concurrency=2 test/*.test.ts", "clean": "rm -rf dist .tsbuildinfo* tsconfig.tsbuildinfo", "build": "node tools/build.mjs", "prepack": "npm run build" @@ -26,13 +26,15 @@ "TARGET.bound", "receipts.bound", "docs/usage.md", - "docs/readme-assets/atlas.svg" + "docs/readme-assets/atlas.svg", + "docs/contracts/*.md" ], "author": "Lapxo", "license": "MIT", "dependencies": { "@lapxo/obligations": "0.3.5", - "@lapxo/topos": "0.1.9" + "@lapxo/topos": "^0.1.11", + "acorn": "8.19.0" }, "devDependencies": { "@types/node": "^20.0.0", diff --git a/receipts.bound b/receipts.bound index a65320f..10d7963 100644 --- a/receipts.bound +++ b/receipts.bound @@ -1,92 +1,314 @@ -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:bbff6b8fc616 form=alphabet measure=observed role=writes scope= value=ab7da20ef55567fd -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=alphabet measure=observed role=writes scope= value=ab7da20ef55567fd -bound-lock/1 at=place:sha256:c79e6047c8b811fc107bf779ceae2c944f25a4b48d2391e74c78b532e479b4e8 by=reader:2c507e7fe764 form=alphabet measure=observed role=writes scope=./ value=c79e6047c8b811fc -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=alphabet measure=observed role=writes scope= value=c8df87bf85f05d4f -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:bbff6b8fc616 form=alphabet measure=text role=reads scope=capture/help value="closing: verbs fold land sign · flags --as --check --key --key-file --signer --place\n" -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:bbff6b8fc616 form=alphabet measure=text role=reads scope=capture/meeting value="INPUT [[\"Ana\",10,14],[\"Luis\",12,16],[\"room\",10,13],[\"boss\",18,20]]\nMEET {\"lo\":12,\"hi\":13}\nCONFLICT boss\nWITHDRAW boss {\"lo\":12,\"hi\":13}\n" -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=cli-exit-closed role=reads scope=cli/exit/closed value=0..0 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=cli-exit-refuse role=reads scope=cli/exit/refuse value=1..1 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=cli-exit-usage role=reads scope=cli/exit/usage value=2..2 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=cli-flags role=reads scope=cli/flags value=6..6 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=count role=reads scope=admission/one-boundary value=0..0 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=count role=reads scope=idempotent value=0..0 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=count role=reads scope=nothing-deleted value=0..0 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=count role=reads scope=offline value=0..0 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=count role=reads scope=one-writer value=0..0 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=count role=reads scope=resolve-by-url value=0..0 -bound-lock/1 at=place:sha256:ab7da20ef55567fd8a85a49fff3ef412a55367b7046fcd4b5b0fbb1b332bb239 by=reader:c448c64e0bac form=interval measure=count role=reads scope=the-stranger value=0..0 -bound-lock/1 at=place:sha256:c79e6047c8b811fc107bf779ceae2c944f25a4b48d2391e74c78b532e479b4e8 by=reader:2c507e7fe764 form=interval measure=unreceipted role=reads scope=door/unreceipted value=0..0 -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=alphabet measure=id role=reads scope=source/locations/duplicate/src value=none -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=alphabet measure=id role=reads scope=source/locations/literal/host value=none -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=alphabet measure=id role=reads scope=source/locations/literal/key value=none -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=alphabet measure=id role=reads scope=source/locations/literal/org value=none -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=alphabet measure=id role=reads scope=source/locations/literal/path value=none -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=interval measure=count role=reads scope=literal/host value=0..0 -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=interval measure=count role=reads scope=literal/key value=0..0 -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=interval measure=count role=reads scope=literal/org value=0..0 -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=interval measure=count role=reads scope=literal/path value=0..0 -bound-lock/1 at=place:sha256:c8df87bf85f05d4f10c5e3e4011067fd84144738a09e83a9ed1bdf4d7c3078d0 by=reader:0f5306d0e183 form=interval measure=duplicate-bodies role=reads scope=duplicate/src value=0..0 -bound-lock/1 at=cone:0abeb4d9e38dbbf12bf63c9e20e50b4066f7cae49b2a42a0b93e3ee6ea34aedb by=judge form=alphabet measure=status role=writes scope=law/a-fact-is-a-printed-line value=present -bound-lock/1 at=cone:0abeb4d9e38dbbf12bf63c9e20e50b4066f7cae49b2a42a0b93e3ee6ea34aedb by=judge form=alphabet measure=cone role=writes scope=law/a-fact-is-a-printed-line value=samples/yes/a-fact-is-a-printed-line.json|samples/no/a-fact-is-a-printed-line.json -bound-lock/1 at=cone:957f15a6bf76172db7ad6fc3ad985d3a2d29d53b0d7f26496278534a6b27eaa5 by=judge form=alphabet measure=status role=writes scope=law/a-refuse-plants value=present -bound-lock/1 at=cone:957f15a6bf76172db7ad6fc3ad985d3a2d29d53b0d7f26496278534a6b27eaa5 by=judge form=alphabet measure=cone role=writes scope=law/a-refuse-plants value=samples/yes/a-refuse-plants.json|samples/no/a-refuse-plants.json -bound-lock/1 at=cone:c4e8823785cb957bd016ff4f294f1fa5c89213b8cac249ffdc93b972288b8d48 by=judge form=alphabet measure=status role=writes scope=law/one-lot-one-place value=present -bound-lock/1 at=cone:c4e8823785cb957bd016ff4f294f1fa5c89213b8cac249ffdc93b972288b8d48 by=judge form=alphabet measure=cone role=writes scope=law/one-lot-one-place value=samples/yes/one-lot-one-place.json|samples/no/one-lot-one-place.json -bound-lock/1 at=cone:9b1915d477c82eba64f0b9a7928018db772788398ca8a13afd438831417ee43a by=judge form=alphabet measure=status role=writes scope=law/three-verbs value=present -bound-lock/1 at=cone:9b1915d477c82eba64f0b9a7928018db772788398ca8a13afd438831417ee43a by=judge form=alphabet measure=cone role=writes scope=law/three-verbs value=samples/yes/three-verbs.json|samples/no/three-verbs.json -bound-lock/1 at=cone:f4bf42894d608f16e39cb757609c9d0a82f50b31749b13599a4fc5ee303fcdf8 by=judge form=alphabet measure=status role=writes scope=law/verify-agrees value=present -bound-lock/1 at=cone:f4bf42894d608f16e39cb757609c9d0a82f50b31749b13599a4fc5ee303fcdf8 by=judge form=alphabet measure=cone role=writes scope=law/verify-agrees value=samples/yes/verify-agrees.json|samples/no/verify-agrees.json -bound-lock/1 at=cone:38393cb6f8e1d9c0c7afd2c6faf7a953232e0edbb57f1029e50c0f828ddf4197 by=judge form=alphabet measure=id role=writes scope=view/citation-file value=cff -bound-lock/1 at=cone:38393cb6f8e1d9c0c7afd2c6faf7a953232e0edbb57f1029e50c0f828ddf4197 by=judge form=alphabet measure=cone role=writes scope=view/citation-file value=CITATION.cff -bound-lock/1 at=cone:2207bfb7237fd7dbf4e4fb11f070cf4ec126ae7db52044504795b64eccfc9e0c by=judge form=alphabet measure=id role=writes scope=view/explanation value=idea|what-holds|refuses -bound-lock/1 at=cone:2207bfb7237fd7dbf4e4fb11f070cf4ec126ae7db52044504795b64eccfc9e0c by=judge form=alphabet measure=cone role=writes scope=view/explanation value=docs/why.md -bound-lock/1 at=cone:5af7aa019f81d75b150501e03cf4c96cce75f87d47ed0922c1f3179c14e5e67d by=judge form=alphabet measure=id role=writes scope=view/guide value=seq -bound-lock/1 at=cone:5af7aa019f81d75b150501e03cf4c96cce75f87d47ed0922c1f3179c14e5e67d by=judge form=alphabet measure=cone role=writes scope=view/guide value=docs/guide.md -bound-lock/1 at=cone:0216dcddc9cc5cf08e750f1e10cbe17ad3408e9ee4b6aa3185ded9b880d1f9b0 by=judge form=alphabet measure=id role=writes scope=view/manifest-render value=text@3 -bound-lock/1 at=cone:0216dcddc9cc5cf08e750f1e10cbe17ad3408e9ee4b6aa3185ded9b880d1f9b0 by=judge form=alphabet measure=cone role=writes scope=view/manifest-render value=package.json -bound-lock/1 at=cone:fa1469604beca94fbe698011c94bf0fedcdea56ce9b851809d8d99d13bc648a2 by=judge form=alphabet measure=id role=writes scope=view/readme-historical value=hero@3|commands@3|idea@3 -bound-lock/1 at=cone:fa1469604beca94fbe698011c94bf0fedcdea56ce9b851809d8d99d13bc648a2 by=judge form=alphabet measure=cone role=writes scope=view/readme-historical value=README.md -bound-lock/1 at=cone:73e5f49f2c68ae68297168be62142f4c0310322535b892de92e7b5b71cbbd798 by=judge form=alphabet measure=id role=writes scope=view/reference value=term|set|ref -bound-lock/1 at=cone:73e5f49f2c68ae68297168be62142f4c0310322535b892de92e7b5b71cbbd798 by=judge form=alphabet measure=cone role=writes scope=view/reference value=docs/reference.md -bound-lock/1 at=cone:83acd4200e0d85822ec7758f1425c8ece7e8ca0523660aa6bf2f17484642a79e by=judge form=alphabet measure=id role=writes scope=view/release-workflow-render value=text@3 -bound-lock/1 at=cone:83acd4200e0d85822ec7758f1425c8ece7e8ca0523660aa6bf2f17484642a79e by=judge form=alphabet measure=cone role=writes scope=view/release-workflow-render value=.github/workflows/release.yml -bound-lock/1 at=cone:fd85558d34bab73004bfbaef02834284a34899a49d582069417ffb79be54e0a6 by=judge form=alphabet measure=id role=writes scope=view/usage-profile value=text@3 -bound-lock/1 at=cone:fd85558d34bab73004bfbaef02834284a34899a49d582069417ffb79be54e0a6 by=judge form=alphabet measure=cone role=writes scope=view/usage-profile value=docs/usage.md -bound-lock/1 at=place:sha256:2b9e2b300e99a774144996b034812d2f6630c230c70ad0cf39c2385b435cde31 by=bound form=alphabet measure=digest role=writes scope=instrument/implementation value=sha256:2b9e2b300e99a774144996b034812d2f6630c230c70ad0cf39c2385b435cde31 -bound-lock/1 at=place:sha256:5a227f054030a40455a7b540aa60c3839f1cee0532a285dd60e788c78acd90f5 by=bound form=alphabet measure=digest role=writes scope=receipts value=sha256:86d74168cbb84387ed9c513e2b371dd3d51f8ac071b23dcf9f9fe7f14bb527be -bound-lock/1 at=place:sha256:1708944f6cdec2b588a774a8428c4593584a89e1950c6d229a64e078a82a93fc by=bound form=interval measure=count role=writes scope=receipts/ value=2..2 -bound-lock/1 at=place:sha256:b640331baae474caedf5407440fde660bd5c636f60dc5240e0881835f0fcef7d by=bound form=interval measure=count role=writes scope=receipts/. value=1..1 -bound-lock/1 at=place:sha256:f6727d0688d4d99d601e8fb543996618bb51310d2bb172895261501714c95584 by=bound form=interval measure=count role=writes scope=receipts/admission value=1..1 -bound-lock/1 at=place:sha256:1a7d0d8e652f008f5d8e25b53f78755caf703bffdd80ab36a19838596d888590 by=bound form=interval measure=count role=writes scope=receipts/capture value=2..2 -bound-lock/1 at=place:sha256:5b2bbc14f2d71c5b156a2900469191077ba537f6e8dc412293c7c8008752d7fb by=bound form=interval measure=count role=writes scope=receipts/cli value=4..4 -bound-lock/1 at=place:sha256:1ba3aadc3fc9eb4c7bc601c7f5467c41929d79466313e908999d56a1cf50b08d by=bound form=interval measure=count role=writes scope=receipts/door value=1..1 -bound-lock/1 at=place:sha256:ff7c3f1ad83d53e399d24f2638c01c15c895b76b1bf26d06c132f728b5ae56f5 by=bound form=interval measure=count role=writes scope=receipts/duplicate value=1..1 -bound-lock/1 at=place:sha256:f2068c6936f87554740100696c1c533f1e109b1ec94e2c17287e08183e3f4ed4 by=bound form=interval measure=count role=writes scope=receipts/idempotent value=1..1 -bound-lock/1 at=place:sha256:3b9e8da7aa8f1a10a4f01de3236c6ee36d02fde650e954440ac4a59f187e9884 by=bound form=interval measure=count role=writes scope=receipts/instrument value=1..1 -bound-lock/1 at=place:sha256:24023fde10bc3f5ad0c60d2b04cca3907b111a5431c6d6f0fc1171a9c3a67c8c by=bound form=interval measure=count role=writes scope=receipts/law value=10..10 -bound-lock/1 at=place:sha256:95911622e93010cc4662b2daf80d1b412f49968d9409fd3357b9c5f9502d552b by=bound form=interval measure=count role=writes scope=receipts/literal value=4..4 -bound-lock/1 at=place:sha256:dafbe0ac24795e387c523cdd1b5edfaaaa33bd55e34ee99ed51f12edc1b5c6ad by=bound form=interval measure=count role=writes scope=receipts/nothing-deleted value=1..1 -bound-lock/1 at=place:sha256:ed596ff6a2b891871961af526dda7bbfd05e2a6aefc181d10a4ba3a2923007e2 by=bound form=interval measure=count role=writes scope=receipts/offline value=1..1 -bound-lock/1 at=place:sha256:281c92fcd639c99b5cf2fbfde6def0825f5ea5b5e64a4810910ef25dd2fb74e7 by=bound form=interval measure=count role=writes scope=receipts/one-writer value=1..1 -bound-lock/1 at=place:sha256:33de48fd74213538fb6c43cadb9a264ce08f58159d51e62b1b333c5b592e994e by=bound form=interval measure=count role=writes scope=receipts/resolve-by-url value=1..1 -bound-lock/1 at=place:sha256:ded656218830b8bc739d6138f03c6cb586f3d24bfd44e4f9bf830a0abd95ccf9 by=bound form=interval measure=count role=writes scope=receipts/source value=5..5 -bound-lock/1 at=place:sha256:5e4c70661ea67c16c9437b6b189e14d351c12e2c95432b0422b7f62abd014161 by=bound form=interval measure=count role=writes scope=receipts/the-stranger value=1..1 -bound-lock/1 at=place:sha256:fa57d0e94c4564179cd375ca21dc974936fd08ec7b0e21d827bf8bce767b2729 by=bound form=interval measure=count role=writes scope=receipts/view value=16..16 -bound-lock/1 at=place:sha256:0a01469a1b91d0c00123aeaaf6bfd35ffae8cba64dc06d7cc79029332a105ed8 by=bound form=alphabet measure=bytes role=writes scope=receipts/ value=sha256:0a01469a1b91d0c00123aeaaf6bfd35ffae8cba64dc06d7cc79029332a105ed8 -bound-lock/1 at=place:sha256:0a01469a1b91d0c00123aeaaf6bfd35ffae8cba64dc06d7cc79029332a105ed8 by=bound form=alphabet measure=bytes role=writes scope=receipts/. value=sha256:0a01469a1b91d0c00123aeaaf6bfd35ffae8cba64dc06d7cc79029332a105ed8 -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/admission value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/capture value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/cli value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/door value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/duplicate value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/idempotent value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/instrument value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/law value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/literal value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/nothing-deleted value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/offline value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/one-writer value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/resolve-by-url value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/source value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/the-stranger value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d -bound-lock/1 at=place:sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d by=bound form=alphabet measure=bytes role=writes scope=receipts/view value=sha256:b9206465188ba307a75919bbdbf6f69f2f69e0b8508ff424600810d1a16da85d +bound-lock/1 at=place:sha256:016b057e0b7881814a5f5c4037bdf86ad21832e612ecf6f15572d6a5239d3562 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=016b057e0b788181 +bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/cli/sign value=02d170611b5e36f6 +bound-lock/1 at=place:sha256:0ae0dabaefde481e9aafd26cb34fa8e4fd1752951c542d58135e5a40e8743a0e by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published value=0ae0dabaefde481e +bound-lock/1 at=place:sha256:0b84bfd900a3a45bb896cfc6194a3104df04d9e29b0fdb84ffa98081e23d40b9 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/2f14480f0cb138e9d65402e161118bd33173091f4f0476a0956f268ef48204fe/9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c value=0b84bfd900a3a45b +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=alphabet measure=observed role=writes scope= value=12d296c24aac7286 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:b4a4ef5b4fab form=alphabet measure=observed role=writes scope= value=12d296c24aac7286 +bound-lock/1 at=place:sha256:18962bf356bc0bdec1933236c430d3b4d93cb11643a3c10cb4f1f825a887b0de by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/53cc8abaccbcb37385fdc1acd1d251c4d3d77ca44df4f8436ee498acf40d4fde value=18962bf356bc0bde +bound-lock/1 at=place:sha256:22fd7319ca3fe91ffc8cefdaa1cb93834d1e94f23866f3048afb3c5173871283 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/24f823b8091ad0e6bc2523012e42e09f3d2b8340484fa2a8bf5f5c8ff28cfc2f/ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 value=22fd7319ca3fe91f +bound-lock/1 at=place:sha256:27ea9fd3811d6af6e3499f5465e62ef4bc17cda1e28e0297d7c7ab59a94aa6a7 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/1142aa9847fe2d5dcba0d1c313b1770cd7f0d23f26d2289faf3204e43568d5c9/ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b value=27ea9fd3811d6af6 +bound-lock/1 at=place:sha256:286301dd7741d2517b2f4b8577d6306c48a75264ccdbea3559fdaa40bfd2f6b7 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71 value=286301dd7741d251 +bound-lock/1 at=place:sha256:2d105b936f1ad95ddf113dc73dd42fb32a80b648cfee5a4d53b19d6ffce8a723 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/508a694913f8447f0c9569dbf49d5619e7028e07b69af9c6f630fe29bbfe354e/f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 value=2d105b936f1ad95d +bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/receipts value=2e65d8efc4e522b8 +bound-lock/1 at=place:sha256:33fe10dee97b5b58f219449e404a691c851edf8d4452319c9f19ddb5c6d6ae49 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/1c1a518629e0254cf043dea049ca020ac9d66b6aa64c724d32f79c141f5ebbe4/8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c value=33fe10dee97b5b58 +bound-lock/1 at=place:sha256:356f6f63fe3f6ca2efc3784daa65ac99be016e37299d81d48dab65c01162827b by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/30bb47bf7c73d4e74f396581010e2032eeeed2179496e73fa04d0fbcf2c6b540/02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f value=356f6f63fe3f6ca2 +bound-lock/1 at=place:sha256:3c261753fb0ac4756471fab14c8fa75aa2a684f25defe6704436d3e6537f4813 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/a1b8ddf809f5e4a7f91702aafea1df612d9abc9fc80c6b6ef26f5329b5dd69eb/4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f value=3c261753fb0ac475 +bound-lock/1 at=place:sha256:401c79478174d4ea0cd6e60861c8e7f22cc05b201e7090d06592eacd446dc7fd by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/934a5bb815ce02a97af891d9a8cb4e49fb2e9ab75fa7bc17ddb00f02537766d5/eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 value=401c79478174d4ea +bound-lock/1 at=place:sha256:46f0a2d1a6e62392d67f072527b5bdc3e3c0a9790bc86584e3f9167ee2d0fe69 by=reader:04feef01a8c5 form=alphabet measure=observed role=writes scope=./ value=46f0a2d1a6e62392 +bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/card value=4882565964567a3c +bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/citation-file value=4af44663b57f04c8 +bound-lock/1 at=place:sha256:51c989c8398539fd856c0a503bf1d19bb63da348deaf12bf359f5bb9ae66edbc by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=51c989c8398539fd +bound-lock/1 at=place:sha256:5497250f21cae4ea13927a4eb200e61fc6109497ac9145857b2d39e3503cf036 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/07a6fa8f4c5abcf023a4643b0830e86f82ec280c37c760f9f87729c1fde8cbb6/59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 value=5497250f21cae4ea +bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/release-workflow-render value=59981e0dc076e5bb +bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/help value=606d733c96ceeef8 +bound-lock/1 at=place:sha256:627263bd9c1efc14089183909f596b8c077cee919632ac66265f6df8097741e9 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/b22901c107d927b59527e324dbf3ed5fe2e442829f86e2ffb47e98c48a57f299/6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf value=627263bd9c1efc14 +bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/cli/land value=6895a06c8c527303 +bound-lock/1 at=place:sha256:72f4971c211abd0ef8f0dd22dcbd7898e9c2180615025e742fa7134279b8aca4 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/8dfb03e666dcb1836aebd396a87c004cb243bfb5b6d231f54d5cea627fbcf1a5/4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 value=72f4971c211abd0e +bound-lock/1 at=place:sha256:73cd91242a512c2c91db16356571aaacb91f70d9abf7a62c11ff3e3dc54c6887 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/033a648a40b8bf19e7fc9798f7c55ca57db97721207920355360e84e46c9a001/ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e value=73cd91242a512c2c +bound-lock/1 at=place:sha256:78287c5074c7e7544a568d14d9d8e3244f2bccd8e4bd848fa43a1b48b5547c32 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/83d362bbceb8696d461393a6123faa0a4e18b772fb84b880b166b68dee976d45/dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f value=78287c5074c7e754 +bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/cli/fold value=7e711ad2867b736a +bound-lock/1 at=place:sha256:81efb0bc6be0a816672ce24f813d6a6b68b4777dacac2abe9685969d3bbcd2b4 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/32f8b095f4a240c6a3c640797a9f0fbc05506fa623e7cb61f0d9fd8c8bd9124a value=81efb0bc6be0a816 +bound-lock/1 at=place:sha256:846dfb54ddf7f6f91af763e17a93971744331c0a4623b0ca743ba583a9a0b431 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/c6e8ddf2f5173b21fa27eeab80a29deafc9897d88db7d07ba99dea3685a53d92/df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 value=846dfb54ddf7f6f9 +bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/explanation value=84993cd7d02c0e8a +bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/attest-evidence-view value=8d7416ad2205c9ab +bound-lock/1 at=place:sha256:8dbed6f68003f8331a7751863c9855c4fe12cbac1899eebfb7edb01deaf9a289 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/e5ea9ccc092991c41e0ea296aed52cae2e1e52c8c25d829ad30fdcbe85be26a7/c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea value=8dbed6f68003f833 +bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/walk value=8e675c4bbe8f90b8 +bound-lock/1 at=place:sha256:90cb0cf49fd948cad0d063582714eeb67b0d45716d0d10bb4ea422709b4c1126 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/14297ddb7404c5404df6cf5b4fc55d6f1727d7c8ffecfab3b5c6d71b5187a63a/e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 value=90cb0cf49fd948ca +bound-lock/1 at=place:sha256:92a5542e4e172b0f23bae2db5803bda063810aeffa81a4d462ea31a37852a87e by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/02a8c2ff35335f7a1c2500c41f57a85782bba3ca0d62cd4ce81cc06d26b16b0d/84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 value=92a5542e4e172b0f +bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/typed-object-sample value=9b99180418307609 +bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/why value=ac8dede30afbab95 +bound-lock/1 at=place:sha256:ae86ff6459dbeb06cf25e48b61be04acb004962ee3b658ec6302cfccb2893dbd by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/95609518b145f36d265c51bfb52c12bd05e306aa9a9d9bbcb788406d80660524/d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 value=ae86ff6459dbeb06 +bound-lock/1 at=place:sha256:b44e6e447635c1680a4331b3c4c7f7dcb673969759b2643b5529b84d009be01b by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/264d1f241f59b1cc55184a8caa9424f64b37060c618401f0410631c0deac9a80/606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 value=b44e6e447635c168 +bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/tsconfig value=c19e0e84fce58e57 +bound-lock/1 at=place:sha256:c2043ab008c7b2ca76f6bff173d203e0fbf8e42eacc0f5d8ad373b1014a66c31 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/b90f9482ce70efa52b839dcaceefb9f1fefbcf4a6da624ca7d989fdb78e86ae0/7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 value=c2043ab008c7b2ca +bound-lock/1 at=place:sha256:d2eb1fec213fc1917772e261a19b9d108f26945fa18be2169ad95a6465426a16 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/c9e9566f19db9feb6a8a7619315bdb19d66f2cd7bba90f911fc047b89f4ebd8f value=d2eb1fec213fc191 +bound-lock/1 at=place:sha256:d5fda6295ad59e9ceed5143aa4b35e64c5438d758728cf033a23d089392c2da1 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/d31a059a2eb8b137ec026d0c5b7b2aea5de809f349526c6bc4a916abe14a0113 value=d5fda6295ad59e9c +bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/programs value=d8a9b617aac1d532 +bound-lock/1 at=place:sha256:dc7179fbff0f1dffe0ab3d0f25f2262e84e107bdcea6a5d92f12938a57e79810 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=execute/2bf6a95f93dabc27c79db679eaf9ad4f5a6e7835e74d762df62fe256c5ea21c1 value=dc7179fbff0f1dff +bound-lock/1 at=place:sha256:ddf17a356900e26badeabff89d82f39cff86b9bcb56ba83e8bcaa4b7b4c18027 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/bce6461bf205cc9bb4967563ebe076b0df551ef542015bad57311d2d55ec223a/8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 value=ddf17a356900e26b +bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/usage-profile value=df137c5abda876f2 +bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/lines value=dfed5a46fee7046f +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=alphabet measure=observed role=writes scope= value=e2602308ed24728e +bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/guide value=e510a3633fcb70ab +bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/readme-historical value=eca5a803bc3b7de6 +bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/reference value=ee67453c707dc9b4 +bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/pipeline/archive value=f2ba95dbc77e18d3 +bound-lock/1 at=place:sha256:f93aad2af89a8fd1ac93a700c11f80c60635d66c66856651ac7949ee0669fa2b by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=receipts/readings/210190f8555962eb95389dbb6f2fbb248d62a0ea592b34e8d97c6be18abb00d7/2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 value=f93aad2af89a8fd1 +bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=observed role=writes scope=contract/published/view/manifest-render value=ffc6c35806e9a10e +bound-lock/1 about="bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/cli.md value=met\nbound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/signing-port.json value=met\nbound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/signing-port.json value=met\nbound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/signing-port.json value=met\nbound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/cli/sign value=0..0\n" at=place:sha256:356f6f63fe3f6ca2efc3784daa65ac99be016e37299d81d48dab65c01162827b by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/30bb47bf7c73d4e74f396581010e2032eeeed2179496e73fa04d0fbcf2c6b540/02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met\nbound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met\nbound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met\nbound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met\nbound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/receipts value=0..0\n" at=place:sha256:f93aad2af89a8fd1ac93a700c11f80c60635d66c66856651ac7949ee0669fa2b by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/210190f8555962eb95389dbb6f2fbb248d62a0ea592b34e8d97c6be18abb00d7/2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met\nbound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/program-views.json value=met\nbound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/program-views.json value=met\nbound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/program-views.json value=met\nbound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/card value=0..0\n" at=place:sha256:72f4971c211abd0ef8f0dd22dcbd7898e9c2180615025e742fa7134279b8aca4 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/8dfb03e666dcb1836aebd396a87c004cb243bfb5b6d231f54d5cea627fbcf1a5/4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/citation-file value=0..0\n" at=place:sha256:3c261753fb0ac4756471fab14c8fa75aa2a684f25defe6704436d3e6537f4813 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/a1b8ddf809f5e4a7f91702aafea1df612d9abc9fc80c6b6ef26f5329b5dd69eb/4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/release-workflow-render value=0..0\n" at=place:sha256:5497250f21cae4ea13927a4eb200e61fc6109497ac9145857b2d39e3503cf036 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/07a6fa8f4c5abcf023a4643b0830e86f82ec280c37c760f9f87729c1fde8cbb6/59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met\nbound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met\nbound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met\nbound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met\nbound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/help value=0..0\n" at=place:sha256:b44e6e447635c1680a4331b3c4c7f7dcb673969759b2643b5529b84d009be01b by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/264d1f241f59b1cc55184a8caa9424f64b37060c618401f0410631c0deac9a80/606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/cli.md value=met\nbound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met\nbound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met\nbound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met\nbound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/cli/land value=0..0\n" at=place:sha256:627263bd9c1efc14089183909f596b8c077cee919632ac66265f6df8097741e9 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/b22901c107d927b59527e324dbf3ed5fe2e442829f86e2ffb47e98c48a57f299/6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/cli.md value=met\nbound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met\nbound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met\nbound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met\nbound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/cli/fold value=0..0\n" at=place:sha256:c2043ab008c7b2ca76f6bff173d203e0fbf8e42eacc0f5d8ad373b1014a66c31 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/b90f9482ce70efa52b839dcaceefb9f1fefbcf4a6da624ca7d989fdb78e86ae0/7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/explanation value=0..0\n" at=place:sha256:92a5542e4e172b0f23bae2db5803bda063810aeffa81a4d462ea31a37852a87e by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/02a8c2ff35335f7a1c2500c41f57a85782bba3ca0d62cd4ce81cc06d26b16b0d/84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/evidence-view.md value=met\nbound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met\nbound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met\nbound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met\nbound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/attest-evidence-view value=0..0\n" at=place:sha256:33fe10dee97b5b58f219449e404a691c851edf8d4452319c9f19ddb5c6d6ae49 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/1c1a518629e0254cf043dea049ca020ac9d66b6aa64c724d32f79c141f5ebbe4/8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/view-walk.md value=met\nbound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/walk.json value=met\nbound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/walk.json value=met\nbound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/walk-publication.json value=met\nbound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/walk value=0..0\n" at=place:sha256:ddf17a356900e26badeabff89d82f39cff86b9bcb56ba83e8bcaa4b7b4c18027 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/bce6461bf205cc9bb4967563ebe076b0df551ef542015bad57311d2d55ec223a/8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/typed-object.md value=met\nbound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/typed-object.json value=met\nbound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/typed-object.json value=met\nbound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/typed-object.json value=met\nbound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/typed-object-sample value=0..0\n" at=place:sha256:0b84bfd900a3a45bb896cfc6194a3104df04d9e29b0fdb84ffa98081e23d40b9 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/2f14480f0cb138e9d65402e161118bd33173091f4f0476a0956f268ef48204fe/9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met\nbound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/query-views.json value=met\nbound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/query-views.json value=met\nbound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/query-views.json value=met\nbound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/why value=0..0\n" at=place:sha256:73cd91242a512c2c91db16356571aaacb91f70d9abf7a62c11ff3e3dc54c6887 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/033a648a40b8bf19e7fc9798f7c55ca57db97721207920355360e84e46c9a001/ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/tsconfig value=0..0\n" at=place:sha256:8dbed6f68003f8331a7751863c9855c4fe12cbac1899eebfb7edb01deaf9a289 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/e5ea9ccc092991c41e0ea296aed52cae2e1e52c8c25d829ad30fdcbe85be26a7/c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met\nbound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/program-views.json value=met\nbound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/program-views.json value=met\nbound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/program-views.json value=met\nbound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/programs value=0..0\n" at=place:sha256:ae86ff6459dbeb06cf25e48b61be04acb004962ee3b658ec6302cfccb2893dbd by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/95609518b145f36d265c51bfb52c12bd05e306aa9a9d9bbcb788406d80660524/d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/usage-profile value=0..0\n" at=place:sha256:846dfb54ddf7f6f91af763e17a93971744331c0a4623b0ca743ba583a9a0b431 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/c6e8ddf2f5173b21fa27eeab80a29deafc9897d88db7d07ba99dea3685a53d92/df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met\nbound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met\nbound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met\nbound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met\nbound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/lines value=0..0\n" at=place:sha256:78287c5074c7e7544a568d14d9d8e3244f2bccd8e4bd848fa43a1b48b5547c32 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/83d362bbceb8696d461393a6123faa0a4e18b772fb84b880b166b68dee976d45/dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/guide value=0..0\n" at=place:sha256:90cb0cf49fd948cad0d063582714eeb67b0d45716d0d10bb4ea422709b4c1126 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/14297ddb7404c5404df6cf5b4fc55d6f1727d7c8ffecfab3b5c6d71b5187a63a/e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/readme-historical value=0..0\n" at=place:sha256:401c79478174d4ea0cd6e60861c8e7f22cc05b201e7090d06592eacd446dc7fd by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/934a5bb815ce02a97af891d9a8cb4e49fb2e9ab75fa7bc17ddb00f02537766d5/eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/reference value=0..0\n" at=place:sha256:27ea9fd3811d6af6e3499f5465e62ef4bc17cda1e28e0297d7c7ab59a94aa6a7 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/1142aa9847fe2d5dcba0d1c313b1770cd7f0d23f26d2289faf3204e43568d5c9/ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/archive.md value=met\nbound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/archive-conformance.json value=met\nbound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/archive-conformance.json value=met\nbound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/archive-conformance.json value=met\nbound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/pipeline/archive value=0..0\n" at=place:sha256:2d105b936f1ad95ddf113dc73dd42fb32a80b648cfee5a4d53b19d6ffce8a723 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/508a694913f8447f0c9569dbf49d5619e7028e07b69af9c6f630fe29bbfe354e/f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 value=5..5 +bound-lock/1 about="bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met\nbound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met\nbound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/manifest-render value=0..0\n" at=place:sha256:22fd7319ca3fe91ffc8cefdaa1cb93834d1e94f23866f3048afb3c5173871283 by=reader:bf562bd10737 form=interval measure=count role=writes scope=receipts/readings/24f823b8091ad0e6bc2523012e42e09f3d2b8340484fa2a8bf5f5c8ff28cfc2f/ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 value=5..5 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/archive-conformance.publication.json value=sha256:6085a889a9b94fd27e55e004fd46919fe5889fc1851cc22bfd86d2c97badb4c8\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/archive.md value=sha256:eedbd0ca544377080763c035053e532bfc46ddd496c3794e0cac2e0d6286e3a9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/c9e9566f19db9feb6a8a7619315bdb19d66f2cd7bba90f911fc047b89f4ebd8f value=sha256:b45fd971e6975b1965057d4028d083d3cc801e2f713bf226840cfe54adfeb7b6\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/archive-conformance.json value=sha256:e14e5007e6b097be39964a749a09fb7143f652129869a8902743eee3ec9b89ea\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/archive-conformance.json value=sha256:1e2a1ce055edb12da86e1ddbbf78e1f9cb910ad6fe14f57fc3e360751e604a4c\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/archive-conformance.json value=sha256:c9e9566f19db9feb6a8a7619315bdb19d66f2cd7bba90f911fc047b89f4ebd8f\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/c9e9566f19db9feb6a8a7619315bdb19d66f2cd7bba90f911fc047b89f4ebd8f role=reads scope=contract/published/pipeline/archive value=docs/contracts/archive-conformance.publication.json|docs/contracts/archive.md|samples/no/archive-conformance.json|samples/yes/archive-conformance.json|vectors/archive-conformance.json\n" at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/508a694913f8447f0c9569dbf49d5619e7028e07b69af9c6f630fe29bbfe354e/f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 value=sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/attest-evidence.publication.json value=sha256:51225a212193c1a629ef3cf8d3ca8e139f69b58f80b60133792ac6b72aaae316\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/evidence-view.md value=sha256:522740051150e3b35dcca31bcc398b18b8cc8b5f9b18417ec4c676f5ea59e61d\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=sha256:3a398c822afb8e23807daa39cd919a6daddb73211e6d5b8e895c9c09202eff67\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/native-views.json value=sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/native-views.json value=sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/native-views.json value=sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc role=reads scope=contract/published/attest-evidence-view value=docs/contracts/attest-evidence.publication.json|docs/contracts/evidence-view.md|samples/no/native-views.json|samples/yes/native-views.json|vectors/native-views.json\n" at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/1c1a518629e0254cf043dea049ca020ac9d66b6aa64c724d32f79c141f5ebbe4/8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c value=sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/cli-fold.publication.json value=sha256:c95c704f175e189b1d0f7f0a91374e251689e0a2f7265cc759c55cf5b9e8be1a\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/cli.md value=sha256:97cddb7dac0c426b40c51d852d6176ae8f389351cc3366206f8acb0e58c7117a\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=sha256:3a398c822afb8e23807daa39cd919a6daddb73211e6d5b8e895c9c09202eff67\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/native-views.json value=sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/native-views.json value=sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/native-views.json value=sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc role=reads scope=contract/published/cli/fold value=docs/contracts/cli-fold.publication.json|docs/contracts/cli.md|samples/no/native-views.json|samples/yes/native-views.json|vectors/native-views.json\n" at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/b90f9482ce70efa52b839dcaceefb9f1fefbcf4a6da624ca7d989fdb78e86ae0/7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 value=sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/cli-land.publication.json value=sha256:8187552aaee39c9e2b748158623ba341f8c2e132a3aa472dcb89b1986311796d\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/cli.md value=sha256:97cddb7dac0c426b40c51d852d6176ae8f389351cc3366206f8acb0e58c7117a\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=sha256:3a398c822afb8e23807daa39cd919a6daddb73211e6d5b8e895c9c09202eff67\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/native-views.json value=sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/native-views.json value=sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/native-views.json value=sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc role=reads scope=contract/published/cli/land value=docs/contracts/cli-land.publication.json|docs/contracts/cli.md|samples/no/native-views.json|samples/yes/native-views.json|vectors/native-views.json\n" at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/b22901c107d927b59527e324dbf3ed5fe2e442829f86e2ffb47e98c48a57f299/6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf value=sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/cli-sign.publication.json value=sha256:c6b3a00809e69db29861160b6dfaded9d491cb398f48d4ba18f583e8f2d74a1c\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/cli.md value=sha256:97cddb7dac0c426b40c51d852d6176ae8f389351cc3366206f8acb0e58c7117a\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/53cc8abaccbcb37385fdc1acd1d251c4d3d77ca44df4f8436ee498acf40d4fde value=sha256:11c627b728151466c36e9a2b3433d0345f86e2142cd5135311dd3fc65dafa20d\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/signing-port.json value=sha256:bb45e5385c5efad77607edfcd79af5faa5cb064d30b2d27a0b9c79de807bca15\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/signing-port.json value=sha256:2bbf951b29ba00e715443c1ea24884a46296ee2a5bf7fd03f6fd681ea0eacb69\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/signing-port.json value=sha256:53cc8abaccbcb37385fdc1acd1d251c4d3d77ca44df4f8436ee498acf40d4fde\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/53cc8abaccbcb37385fdc1acd1d251c4d3d77ca44df4f8436ee498acf40d4fde role=reads scope=contract/published/cli/sign value=docs/contracts/cli-sign.publication.json|docs/contracts/cli.md|samples/no/signing-port.json|samples/yes/signing-port.json|vectors/signing-port.json\n" at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/30bb47bf7c73d4e74f396581010e2032eeeed2179496e73fa04d0fbcf2c6b540/02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f value=sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-citation-file.publication.json value=sha256:8fd8362d2b64292c0eb5b587984e67f65417df611ff0f35876af58e42ab3f2b6\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/citation-file value=docs/contracts/documents.md|docs/contracts/view-citation-file.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/a1b8ddf809f5e4a7f91702aafea1df612d9abc9fc80c6b6ef26f5329b5dd69eb/4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f value=sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-explanation.publication.json value=sha256:c60066fb7a05399af4f62aff0e30a18c5ceb79c229bef6fa2369acd880eec428\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/explanation value=docs/contracts/documents.md|docs/contracts/view-explanation.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/02a8c2ff35335f7a1c2500c41f57a85782bba3ca0d62cd4ce81cc06d26b16b0d/84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 value=sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-guide.publication.json value=sha256:40c884f7e1f7004330767073288fca859239cb621a565e5a4348b3b5243854fd\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/guide value=docs/contracts/documents.md|docs/contracts/view-guide.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/14297ddb7404c5404df6cf5b4fc55d6f1727d7c8ffecfab3b5c6d71b5187a63a/e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 value=sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-manifest-render.publication.json value=sha256:51b9a7d904d0d6986c8e392c3bd9a64edc75ecbadbdc5056d6dd69cf380e6d02\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/manifest-render value=docs/contracts/documents.md|docs/contracts/view-manifest-render.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/24f823b8091ad0e6bc2523012e42e09f3d2b8340484fa2a8bf5f5c8ff28cfc2f/ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 value=sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-readme-historical.publication.json value=sha256:74d5de324c84700455fd5d1f27ade0db283bc819bd7077fa0ba5b9bb91185ebf\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/readme-historical value=docs/contracts/documents.md|docs/contracts/view-readme-historical.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/934a5bb815ce02a97af891d9a8cb4e49fb2e9ab75fa7bc17ddb00f02537766d5/eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 value=sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-reference.publication.json value=sha256:2d79bedaeb09f7a983d7825f2155f5830c2a12a913a77f5f8246391015c63bda\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/reference value=docs/contracts/documents.md|docs/contracts/view-reference.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/1142aa9847fe2d5dcba0d1c313b1770cd7f0d23f26d2289faf3204e43568d5c9/ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b value=sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-release-workflow-render.publication.json value=sha256:bddd22afcb7479de5e1fa835bbd7edaca668859a33eb58a64aa9e94c86aed0a1\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/release-workflow-render value=docs/contracts/documents.md|docs/contracts/view-release-workflow-render.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/07a6fa8f4c5abcf023a4643b0830e86f82ec280c37c760f9f87729c1fde8cbb6/59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 value=sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-tsconfig.publication.json value=sha256:017235397bbd6cae017dc257fb2db87380325046ae87b63f2db53b0d6205e904\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/tsconfig value=docs/contracts/documents.md|docs/contracts/view-tsconfig.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/e5ea9ccc092991c41e0ea296aed52cae2e1e52c8c25d829ad30fdcbe85be26a7/c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea value=sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/documents.md value=sha256:a22d9b27c7be1c168ea985d703a9c86c19157c8e24193e7dcc34d3f33ea44375\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-usage-profile.publication.json value=sha256:e0fe246c4768c2022524fe54d7eb0849a2a8cbc3b3ba9e94ea34f5fa9a2b84ef\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=sha256:300164d752ca409fc77a01d32da0445ad8731c2dd93a036969b5e7beca46b6f4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/historical-document-views.json value=sha256:85d091dd6fbf4c3438e7f04700d70bbded4260eb38804e049a1bc9c301bbedb9\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/historical-document-views.json value=sha256:1e375ddc0be9538404e7258e862a60fc5454cd2b7dde1afe27b28de0228467bc\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/historical-document-views.json value=sha256:6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 role=reads scope=contract/published/view/usage-profile value=docs/contracts/documents.md|docs/contracts/view-usage-profile.publication.json|samples/no/historical-document-views.json|samples/yes/historical-document-views.json|vectors/historical-document-views.json\n" at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/c6e8ddf2f5173b21fa27eeab80a29deafc9897d88db7d07ba99dea3685a53d92/df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 value=sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/typed-object.md value=sha256:73925fbdaa4a9418b63fe28a9f6d36430eaaa59eb357657cdbe45129fb9454fe\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/typed-object.publication.json value=sha256:377034f586a73b4c3ae899d295005b9b970443694ae78622cb5249e287082e20\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/32f8b095f4a240c6a3c640797a9f0fbc05506fa623e7cb61f0d9fd8c8bd9124a value=sha256:c663fc43f0617059742224b099ca1c7e737dc2de5a5a60a22dba08fe35572def\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/typed-object.json value=sha256:03ac2a40efbea4232025e99d37f06bca03292fcfe3c41c8c27dd5647080951a0\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/typed-object.json value=sha256:b54bac71e89800f09cb55331a4cebde2e280d5240b062a317ffabbc02edcfa7d\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/typed-object.json value=sha256:32f8b095f4a240c6a3c640797a9f0fbc05506fa623e7cb61f0d9fd8c8bd9124a\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/32f8b095f4a240c6a3c640797a9f0fbc05506fa623e7cb61f0d9fd8c8bd9124a role=reads scope=contract/published/typed-object-sample value=docs/contracts/typed-object.md|docs/contracts/typed-object.publication.json|samples/no/typed-object.json|samples/yes/typed-object.json|vectors/typed-object.json\n" at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/2f14480f0cb138e9d65402e161118bd33173091f4f0476a0956f268ef48204fe/9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c value=sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-card.publication.json value=sha256:1d50d3bce5ec3155cf5ac1f32160a27cbb5c67b4bf23d8397dc5b3fb192cd709\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/views.md value=sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71 value=sha256:4e0baef9f577396d72d0e83003cbf2aa8450a5b59a9d46b92254fc9eb7ea6557\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/program-views.json value=sha256:bf6b2fbd11290920e31f46c18012be2230ffdab47dc7013d3a0aafae1fd6cbe7\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/program-views.json value=sha256:b1e8feb6839050a09410dade936cbb827ac438ff8c7b962e5fefd50f601d1b15\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/program-views.json value=sha256:a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71 role=reads scope=contract/published/view/card value=docs/contracts/view-card.publication.json|docs/contracts/views.md|samples/no/program-views.json|samples/yes/program-views.json|vectors/program-views.json\n" at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/8dfb03e666dcb1836aebd396a87c004cb243bfb5b6d231f54d5cea627fbcf1a5/4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 value=sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-help.publication.json value=sha256:90c3752d23c7429f512ed780ad293652db5b3098d91bdb63d1f4b86753b1aee0\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/views.md value=sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=sha256:3a398c822afb8e23807daa39cd919a6daddb73211e6d5b8e895c9c09202eff67\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/native-views.json value=sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/native-views.json value=sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/native-views.json value=sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc role=reads scope=contract/published/view/help value=docs/contracts/view-help.publication.json|docs/contracts/views.md|samples/no/native-views.json|samples/yes/native-views.json|vectors/native-views.json\n" at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/264d1f241f59b1cc55184a8caa9424f64b37060c618401f0410631c0deac9a80/606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 value=sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-lines.publication.json value=sha256:a6107a627b7a2cf18d96bbb1a21f61b1a3562c7eb6a67252cf94ac4964e7c23e\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/views.md value=sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=sha256:3a398c822afb8e23807daa39cd919a6daddb73211e6d5b8e895c9c09202eff67\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/native-views.json value=sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/native-views.json value=sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/native-views.json value=sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc role=reads scope=contract/published/view/lines value=docs/contracts/view-lines.publication.json|docs/contracts/views.md|samples/no/native-views.json|samples/yes/native-views.json|vectors/native-views.json\n" at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/83d362bbceb8696d461393a6123faa0a4e18b772fb84b880b166b68dee976d45/dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f value=sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-programs.publication.json value=sha256:d22ea5b51f369bdb89d8ff762cb61f5c05994c9eaac3e59131ed40139b2294f7\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/views.md value=sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71 value=sha256:4e0baef9f577396d72d0e83003cbf2aa8450a5b59a9d46b92254fc9eb7ea6557\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/program-views.json value=sha256:bf6b2fbd11290920e31f46c18012be2230ffdab47dc7013d3a0aafae1fd6cbe7\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/program-views.json value=sha256:b1e8feb6839050a09410dade936cbb827ac438ff8c7b962e5fefd50f601d1b15\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/program-views.json value=sha256:a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71 role=reads scope=contract/published/view/programs value=docs/contracts/view-programs.publication.json|docs/contracts/views.md|samples/no/program-views.json|samples/yes/program-views.json|vectors/program-views.json\n" at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/95609518b145f36d265c51bfb52c12bd05e306aa9a9d9bbcb788406d80660524/d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 value=sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-receipts.publication.json value=sha256:1275c2f0fc854ca3c115aec57b6a2800425026a12c1c35c874857c6fa2f692e3\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/views.md value=sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=sha256:3a398c822afb8e23807daa39cd919a6daddb73211e6d5b8e895c9c09202eff67\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/native-views.json value=sha256:7750551a70599cbecb37ee5659797ba8ff1dd84a11e17cbbe0c77ff62aecb3a5\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/native-views.json value=sha256:888de96de74e6944d18d425245093845c54dd8374adc6c56f589c3e40da9f2e3\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/native-views.json value=sha256:1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc role=reads scope=contract/published/view/receipts value=docs/contracts/view-receipts.publication.json|docs/contracts/views.md|samples/no/native-views.json|samples/yes/native-views.json|vectors/native-views.json\n" at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/210190f8555962eb95389dbb6f2fbb248d62a0ea592b34e8d97c6be18abb00d7/2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 value=sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-walk.md value=sha256:fc4cf29128d028c49380db8c28f8b68b692b8f25e577ed3eec238cb805cb18b6\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-walk.publication.json value=sha256:d9f7d39ef313e213748a77e190fb6347aad98e378cfbfb66e97eb7e86d39e2cd\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/d31a059a2eb8b137ec026d0c5b7b2aea5de809f349526c6bc4a916abe14a0113 value=sha256:2b8d5197021a90cd9330185e419314f15e4e03bcf26a96357564614a5dcfd746\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/walk.json value=sha256:9e1b17f0e99285b1d89cf1967158422836ebdcd6542b2eea3cee074c5c26c233\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/walk.json value=sha256:d316e1ca1d07ee2a70038d1ee0df1d6e0d318f71d6364fd13377d2b9ee26a0ac\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/walk-publication.json value=sha256:d31a059a2eb8b137ec026d0c5b7b2aea5de809f349526c6bc4a916abe14a0113\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/d31a059a2eb8b137ec026d0c5b7b2aea5de809f349526c6bc4a916abe14a0113 role=reads scope=contract/published/view/walk value=docs/contracts/view-walk.md|docs/contracts/view-walk.publication.json|samples/no/walk.json|samples/yes/walk.json|vectors/walk-publication.json\n" at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/bce6461bf205cc9bb4967563ebe076b0df551ef542015bad57311d2d55ec223a/8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 value=sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 +bound-lock/1 about="bound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/view-why.publication.json value=sha256:b554a63a3c9f2cba85cbc4cc4809324f0cd8c4903326029912270bceda206acb\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=docs/contracts/views.md value=sha256:66851597b8afad44ebbd89af57c07316c03876d5e6a51853e6a74665fc32f8c8\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=execute/2bf6a95f93dabc27c79db679eaf9ad4f5a6e7835e74d762df62fe256c5ea21c1 value=sha256:09b54e87d99534ad2a15c521fb4d7b30e133529de8b6b6f834bde6920886013f\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=implementation value=sha256:bf562bd10737d3817699639784b932f04b52c078396d395c7a2c5b31e4315351\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/no/query-views.json value=sha256:a161c1c33dcfd357b610ae6835ecc4b16d7918a9216bab07ecb4de132e2b2ba4\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=samples/yes/query-views.json value=sha256:105bdcf69a8179659033c898c8e27ee3d37aabdd0fb6f221a6affe10c579e317\nbound-lock/1 at=policy:input-identity by=host form=alphabet measure=digest role=writes scope=vectors/query-views.json value=sha256:2bf6a95f93dabc27c79db679eaf9ad4f5a6e7835e74d762df62fe256c5ea21c1\nbound-lock/1 at=receipt:1 form=alphabet measure=reads needs=execute/2bf6a95f93dabc27c79db679eaf9ad4f5a6e7835e74d762df62fe256c5ea21c1 role=reads scope=contract/published/view/why value=docs/contracts/view-why.publication.json|docs/contracts/views.md|samples/no/query-views.json|samples/yes/query-views.json|vectors/query-views.json\n" at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=bytes role=writes scope=receipts/readings/033a648a40b8bf19e7fc9798f7c55ca57db97721207920355360e84e46c9a001/ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e value=sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e +bound-lock/1 at=place:sha256:016b057e0b7881814a5f5c4037bdf86ad21832e612ecf6f15572d6a5239d3562 by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/1f17bde653377103acf8888717b0ad5c2b83b79860a4833be93270532b76c0dc value=0..0 +bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/cli.md value=met +bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/signing-port.json value=met +bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/signing-port.json value=met +bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/signing-port.json value=met +bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/cli/sign value=0..0 +bound-lock/1 at=place:sha256:02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/30bb47bf7c73d4e74f396581010e2032eeeed2179496e73fa04d0fbcf2c6b540/02d170611b5e36f69b3e3efe805ee82e340de03f4a5d66db5c9df77b863d1d9f value=0.394798..0.394798 +bound-lock/1 at=place:sha256:0ae0dabaefde481e9aafd26cb34fa8e4fd1752951c542d58135e5a40e8743a0e by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=cli-exit-closed role=reads scope=cli/exit/closed value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=cli-exit-refuse role=reads scope=cli/exit/refuse value=1..1 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=cli-exit-usage role=reads scope=cli/exit/usage value=2..2 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=cli-flags role=reads scope=cli/flags value=6..6 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=count role=reads scope=admission/one-boundary value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=count role=reads scope=idempotent value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=count role=reads scope=nothing-deleted value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=count role=reads scope=offline value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=count role=reads scope=one-writer value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=count role=reads scope=resolve-by-url value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:6039da051052 form=interval measure=count role=reads scope=the-stranger value=0..0 +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:b4a4ef5b4fab form=alphabet measure=text role=reads scope=capture/help value="ci-clean-closure: verbs fold land sign · flags --as --check --key --key-file --signer --place\n" +bound-lock/1 at=place:sha256:12d296c24aac7286a475b6a22bbefcf51a92ac4e7b58d9cb9abbfeec37b0b0f2 by=reader:b4a4ef5b4fab form=alphabet measure=text role=reads scope=capture/meeting value="INPUT [[\"Ana\",10,14],[\"Luis\",12,16],[\"room\",10,13],[\"boss\",18,20]]\nMEET {\"lo\":12,\"hi\":13}\nCONFLICT boss\nWITHDRAW boss {\"lo\":12,\"hi\":13}\n" +bound-lock/1 at=place:sha256:18962bf356bc0bdec1933236c430d3b4d93cb11643a3c10cb4f1f825a887b0de by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/53cc8abaccbcb37385fdc1acd1d251c4d3d77ca44df4f8436ee498acf40d4fde value=0..0 +bound-lock/1 at=place:sha256:286301dd7741d2517b2f4b8577d6306c48a75264ccdbea3559fdaa40bfd2f6b7 by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/a10f688f48b2a9686cfe9ebc3908fa06d04cb0d3e86602a51d47511076f81f71 value=0..0 +bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met +bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met +bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met +bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met +bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/receipts value=0..0 +bound-lock/1 at=place:sha256:2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/210190f8555962eb95389dbb6f2fbb248d62a0ea592b34e8d97c6be18abb00d7/2e65d8efc4e522b829c38688a79aa0a40825a0d93e91a663e6599331aa468711 value=0.385962..0.385962 +bound-lock/1 at=place:sha256:46f0a2d1a6e62392d67f072527b5bdc3e3c0a9790bc86584e3f9167ee2d0fe69 by=reader:04feef01a8c5 form=interval measure=unreceipted role=reads scope=door/unreceipted value=0..0 +bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met +bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/program-views.json value=met +bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/program-views.json value=met +bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/program-views.json value=met +bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/card value=0..0 +bound-lock/1 at=place:sha256:4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/8dfb03e666dcb1836aebd396a87c004cb243bfb5b6d231f54d5cea627fbcf1a5/4882565964567a3c73eb778fe06e7fd76db536cc04cb417494382838f5776d54 value=0.396696..0.396696 +bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/citation-file value=0..0 +bound-lock/1 at=place:sha256:4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/a1b8ddf809f5e4a7f91702aafea1df612d9abc9fc80c6b6ef26f5329b5dd69eb/4af44663b57f04c881dfee9245d67926f06dfe02d36d467ecfb290959e35fa2f value=0.409404..0.409404 +bound-lock/1 at=place:sha256:51c989c8398539fd856c0a503bf1d19bb63da348deaf12bf359f5bb9ae66edbc by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/6a40dad06f119dee45834bf4252c138c7368c07c5a814068a573da7f4bc72a94 value=0..0 +bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/release-workflow-render value=0..0 +bound-lock/1 at=place:sha256:59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/07a6fa8f4c5abcf023a4643b0830e86f82ec280c37c760f9f87729c1fde8cbb6/59981e0dc076e5bb29052cb6c0bdbb52e8c9f4fce74e6dab0c42596811cacee6 value=0.408602..0.408602 +bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met +bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met +bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met +bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met +bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/help value=0..0 +bound-lock/1 at=place:sha256:606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/264d1f241f59b1cc55184a8caa9424f64b37060c618401f0410631c0deac9a80/606d733c96ceeef8f18257a54ab794965ea67adede298522e36f03c3876d1ec8 value=0.385764..0.385764 +bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/cli.md value=met +bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met +bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met +bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met +bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/cli/land value=0..0 +bound-lock/1 at=place:sha256:6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/b22901c107d927b59527e324dbf3ed5fe2e442829f86e2ffb47e98c48a57f299/6895a06c8c5273035f15b0f163babb4072da014fa268e49327cd0c66828ecfaf value=0.379314..0.379314 +bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/cli.md value=met +bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met +bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met +bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met +bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/cli/fold value=0..0 +bound-lock/1 at=place:sha256:7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/b90f9482ce70efa52b839dcaceefb9f1fefbcf4a6da624ca7d989fdb78e86ae0/7e711ad2867b736a3b38706b250cd6e6deebabe2ee2814a5c8dfa29fc4942d15 value=0.386650..0.386650 +bound-lock/1 at=place:sha256:81efb0bc6be0a816672ce24f813d6a6b68b4777dacac2abe9685969d3bbcd2b4 by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/32f8b095f4a240c6a3c640797a9f0fbc05506fa623e7cb61f0d9fd8c8bd9124a value=0..0 +bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/explanation value=0..0 +bound-lock/1 at=place:sha256:84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/02a8c2ff35335f7a1c2500c41f57a85782bba3ca0d62cd4ce81cc06d26b16b0d/84993cd7d02c0e8a0517ecf90322326179f6978e680a37dcc1a103d5bd97ba16 value=0.387840..0.387840 +bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/evidence-view.md value=met +bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met +bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met +bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met +bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/attest-evidence-view value=0..0 +bound-lock/1 at=place:sha256:8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/1c1a518629e0254cf043dea049ca020ac9d66b6aa64c724d32f79c141f5ebbe4/8d7416ad2205c9ab8983de790facc7bdd82638d534c283f0a99209c32d9b7c3c value=0.396812..0.396812 +bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/view-walk.md value=met +bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/walk.json value=met +bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/walk.json value=met +bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/walk-publication.json value=met +bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/walk value=0..0 +bound-lock/1 at=place:sha256:8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/bce6461bf205cc9bb4967563ebe076b0df551ef542015bad57311d2d55ec223a/8e675c4bbe8f90b857a44d0416809918b9c2d7dc6a0b0f27b4abe47b1293b8d5 value=0.401232..0.401232 +bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/typed-object.md value=met +bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/typed-object.json value=met +bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/typed-object.json value=met +bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/typed-object.json value=met +bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/typed-object-sample value=0..0 +bound-lock/1 at=place:sha256:9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/2f14480f0cb138e9d65402e161118bd33173091f4f0476a0956f268ef48204fe/9b99180418307609a49bcae286f05666623b6781d0734b65aee2be6f92b0a90c value=0.407236..0.407236 +bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met +bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/query-views.json value=met +bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/query-views.json value=met +bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/query-views.json value=met +bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/why value=0..0 +bound-lock/1 at=place:sha256:ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/033a648a40b8bf19e7fc9798f7c55ca57db97721207920355360e84e46c9a001/ac8dede30afbab954fe16958b63dbe44bcd584da14dd995c30ea7333c9e5e25e value=0.390222..0.390222 +bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/tsconfig value=0..0 +bound-lock/1 at=place:sha256:c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/e5ea9ccc092991c41e0ea296aed52cae2e1e52c8c25d829ad30fdcbe85be26a7/c19e0e84fce58e57b3260584e81869918d23bc6a6a8c0412b0a1482cb98d3eea value=0.403700..0.403700 +bound-lock/1 at=place:sha256:d2eb1fec213fc1917772e261a19b9d108f26945fa18be2169ad95a6465426a16 by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/c9e9566f19db9feb6a8a7619315bdb19d66f2cd7bba90f911fc047b89f4ebd8f value=0..0 +bound-lock/1 at=place:sha256:d5fda6295ad59e9ceed5143aa4b35e64c5438d758728cf033a23d089392c2da1 by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/d31a059a2eb8b137ec026d0c5b7b2aea5de809f349526c6bc4a916abe14a0113 value=0..0 +bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met +bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/program-views.json value=met +bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/program-views.json value=met +bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/program-views.json value=met +bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/programs value=0..0 +bound-lock/1 at=place:sha256:d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/95609518b145f36d265c51bfb52c12bd05e306aa9a9d9bbcb788406d80660524/d8a9b617aac1d53277510e5ce45ad1f0b4a5aed6d8208c2e2b33e7835f3239e4 value=0.381692..0.381692 +bound-lock/1 at=place:sha256:dc7179fbff0f1dffe0ab3d0f25f2262e84e107bdcea6a5d92f12938a57e79810 by=reader:bf562bd10737 form=interval measure=count role=reads scope=proof/execute/2bf6a95f93dabc27c79db679eaf9ad4f5a6e7835e74d762df62fe256c5ea21c1 value=0..0 +bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/usage-profile value=0..0 +bound-lock/1 at=place:sha256:df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/c6e8ddf2f5173b21fa27eeab80a29deafc9897d88db7d07ba99dea3685a53d92/df137c5abda876f2b25d24a0a5d221cb4aef7879066959ebc9b61e00159d40c2 value=0.394309..0.394309 +bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/views.md value=met +bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/native-views.json value=met +bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/native-views.json value=met +bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/native-views.json value=met +bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/lines value=0..0 +bound-lock/1 at=place:sha256:dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/83d362bbceb8696d461393a6123faa0a4e18b772fb84b880b166b68dee976d45/dfed5a46fee7046ffdef6a36b765e92c5c0d5fe396eb7e50aa3add00a7cba86f value=0.413223..0.413223 +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=alphabet measure=id role=reads scope=source/locations/duplicate/src value=none +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=alphabet measure=id role=reads scope=source/locations/literal/host value=none +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=alphabet measure=id role=reads scope=source/locations/literal/key value=none +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=alphabet measure=id role=reads scope=source/locations/literal/org value=none +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=alphabet measure=id role=reads scope=source/locations/literal/path value=none +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=interval measure=count role=reads scope=literal/host value=0..0 +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=interval measure=count role=reads scope=literal/key value=0..0 +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=interval measure=count role=reads scope=literal/org value=0..0 +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=interval measure=count role=reads scope=literal/path value=0..0 +bound-lock/1 at=place:sha256:e2602308ed24728ed06deec55d2c2a3f2662185bc2cbf7afbe6aaac5a767212b by=reader:cff08bccafa4 form=interval measure=duplicate-bodies role=reads scope=duplicate/src value=0..0 +bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/guide value=0..0 +bound-lock/1 at=place:sha256:e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/14297ddb7404c5404df6cf5b4fc55d6f1727d7c8ffecfab3b5c6d71b5187a63a/e510a3633fcb70abaaa8e869a819c7498525b182a6ac08c8a5709ee4d778bd58 value=0.390025..0.390025 +bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/readme-historical value=0..0 +bound-lock/1 at=place:sha256:eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/934a5bb815ce02a97af891d9a8cb4e49fb2e9ab75fa7bc17ddb00f02537766d5/eca5a803bc3b7de67705bbac4ba786d1698559edc8f2e18d7a9650261966ffb0 value=0.452130..0.452130 +bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/reference value=0..0 +bound-lock/1 at=place:sha256:ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/1142aa9847fe2d5dcba0d1c313b1770cd7f0d23f26d2289faf3204e43568d5c9/ee67453c707dc9b4cfa12bb46d285a10ce8fa39724f05a4de2955ad251471e9b value=0.392356..0.392356 +bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/archive.md value=met +bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/archive-conformance.json value=met +bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/archive-conformance.json value=met +bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/archive-conformance.json value=met +bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/pipeline/archive value=0..0 +bound-lock/1 at=place:sha256:f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/508a694913f8447f0c9569dbf49d5619e7028e07b69af9c6f630fe29bbfe354e/f2ba95dbc77e18d393085659845e86880e5e92ebc4634d1f8803fa744fd6b993 value=0.396171..0.396171 +bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=docs/contracts/documents.md value=met +bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/no/historical-document-views.json value=met +bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=samples/yes/historical-document-views.json value=met +bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=alphabet measure=status role=reads scope=vectors/historical-document-views.json value=met +bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=interval measure=count role=reads scope=contract/published/view/manifest-render value=0..0 +bound-lock/1 at=place:sha256:ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 by=reader:bf562bd10737 form=interval measure=s role=writes scope=receipts/readings/24f823b8091ad0e6bc2523012e42e09f3d2b8340484fa2a8bf5f5c8ff28cfc2f/ffc6c35806e9a10ecc6920eb6a021a84e746b0229752527529c4ba8a53af9468 value=0.396612..0.396612 +bound-lock/1 at=place:sha256:4238b3a3ffecf5f6b8a729f54cdaa4aaf9fca2c8415b04d6f5586a9dfbba74fa by=bound form=alphabet measure=digest role=writes scope=instrument/implementation value=sha256:4238b3a3ffecf5f6b8a729f54cdaa4aaf9fca2c8415b04d6f5586a9dfbba74fa +bound-lock/1 at=place:sha256:5201c9a556b699d54b340680a53229ab8722383742777c7051f71ac3d925dafb by=bound form=alphabet measure=digest role=writes scope=receipts value=sha256:2ec47d2b4d869d86f918ff3907147097577420fc8b22ab60bf866f0bb3e4a3cb +bound-lock/1 at=place:sha256:6b0d67c3e4a37fe599faf0732e0b288efc9061f1a55a265999fdc76a61b196ea by=bound form=interval measure=count role=writes scope=receipts/ value=2..2 +bound-lock/1 at=place:sha256:e0577141a5e9f2e2cf0f91978a4479f29e6d9224bea39380960525cac735d86b by=bound form=interval measure=count role=writes scope=receipts/. value=1..1 +bound-lock/1 at=place:sha256:e0e9a6049885d093319b67e83fec21ae7f63237c59f9aec678a3d4804b75c597 by=bound form=interval measure=count role=writes scope=receipts/admission value=1..1 +bound-lock/1 at=place:sha256:671c21cdb4424e84aa09cd4058eaa48f5acfc64953f3a0e46b25fd135a3973a3 by=bound form=interval measure=count role=writes scope=receipts/capture value=2..2 +bound-lock/1 at=place:sha256:4f7c4f5d5d7f05f776b0c2d6749755e8ee04e5cf1bb0e3e1d65d8f87c0d8d720 by=bound form=interval measure=count role=writes scope=receipts/cli value=4..4 +bound-lock/1 at=place:sha256:1e4beedad4c6cb046c4a56c4140c03b5f87dce81470ca30bcfd09a554460661a by=bound form=interval measure=count role=writes scope=receipts/contract value=46..46 +bound-lock/1 at=place:sha256:634b9a650f0f4cac81844e91aeeebeb82d890cc77c2290387ae8ca7607e1b9a4 by=bound form=interval measure=count role=writes scope=receipts/docs value=22..22 +bound-lock/1 at=place:sha256:6ecb155df4396e6ff0d9cfe86cbae2422d359e25525022cf264791a0da3d5b32 by=bound form=interval measure=count role=writes scope=receipts/door value=1..1 +bound-lock/1 at=place:sha256:14efce37002fcf7059ba79f536b5977dec16b6a3f420c9ece61c188f742405ef by=bound form=interval measure=count role=writes scope=receipts/duplicate value=1..1 +bound-lock/1 at=place:sha256:7fea53e015f42ad8a2bcb09062d4501e07a956b694ac9f479efcd7e3ed71d196 by=bound form=interval measure=count role=writes scope=receipts/execute value=8..8 +bound-lock/1 at=place:sha256:1ba83648360ee62057f115ccc51c76ad863d2cacfe72be5906fe3047a64b780a by=bound form=interval measure=count role=writes scope=receipts/idempotent value=1..1 +bound-lock/1 at=place:sha256:54a1aa95180da1823567572736a95624f73abf2d449e10e552c65ce6d506e086 by=bound form=interval measure=count role=writes scope=receipts/instrument value=1..1 +bound-lock/1 at=place:sha256:1e455d16eae3f8af6ec0572b277acd383acbc15797955332f993ce9a75ed8303 by=bound form=interval measure=count role=writes scope=receipts/literal value=4..4 +bound-lock/1 at=place:sha256:d7f5e860bfaaf291a02a2e62054be0ac9bf542cbff4eb905a416818722a1b557 by=bound form=interval measure=count role=writes scope=receipts/nothing-deleted value=1..1 +bound-lock/1 at=place:sha256:d7d51468324c7307c87f6a11e744c5e15e85d469355f31136026f1ba3ad6ff20 by=bound form=interval measure=count role=writes scope=receipts/offline value=1..1 +bound-lock/1 at=place:sha256:4c78d38f6152b24eee45901fc9fff04037b2eecbde016c7f8300482484db5baf by=bound form=interval measure=count role=writes scope=receipts/one-writer value=1..1 +bound-lock/1 at=place:sha256:f746f301e18200f812d69e6da1319bd3a127f21b4d5a7288203f51edc0535791 by=bound form=interval measure=count role=writes scope=receipts/proof value=8..8 +bound-lock/1 at=place:sha256:be85aecacf43eb3265555116b54032fa3024f3b29009d0b0d96e175c0ce31bdd by=bound form=interval measure=count role=writes scope=receipts/receipts value=88..88 +bound-lock/1 at=place:sha256:5856f172141c4fb90aafcf3bdad633bfc3352b9fa7eed3574997fd914d883780 by=bound form=interval measure=count role=writes scope=receipts/resolve-by-url value=1..1 +bound-lock/1 at=place:sha256:4b269b9de1c22ace4784068b3ea5d9f942530b54ce2a5ab06e4ea0d976e08708 by=bound form=interval measure=count role=writes scope=receipts/samples value=44..44 +bound-lock/1 at=place:sha256:4b33d417a5bf1d38c2e54272a5d73b86971166d546620d9ea7b9fb72c579368b by=bound form=interval measure=count role=writes scope=receipts/source value=5..5 +bound-lock/1 at=place:sha256:a78ac2fe3576a2f34f2730373c45cba6c2f32ae438f614bb87a2b03ac1df922b by=bound form=interval measure=count role=writes scope=receipts/the-stranger value=1..1 +bound-lock/1 at=place:sha256:a65c7bb49b41e44dbd1e0d5647bb8ed45cd7bb88e06ced4445a7f27d106a8678 by=bound form=interval measure=count role=writes scope=receipts/vectors value=22..22 +bound-lock/1 at=place:sha256:d45c094f99cf3682350761af394ee0408eefc70bf2e15f4e03bba7fe639b0964 by=bound form=alphabet measure=bytes role=writes scope=receipts/ value=sha256:d45c094f99cf3682350761af394ee0408eefc70bf2e15f4e03bba7fe639b0964 +bound-lock/1 at=place:sha256:d45c094f99cf3682350761af394ee0408eefc70bf2e15f4e03bba7fe639b0964 by=bound form=alphabet measure=bytes role=writes scope=receipts/. value=sha256:d45c094f99cf3682350761af394ee0408eefc70bf2e15f4e03bba7fe639b0964 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/admission value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/capture value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/cli value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/contract value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:97aefbb559f7476e91c95e653eb91fa83ffe264f132facc4cc948c50be298725 by=bound form=alphabet measure=bytes role=writes scope=receipts/docs value=sha256:97aefbb559f7476e91c95e653eb91fa83ffe264f132facc4cc948c50be298725 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/door value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/duplicate value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/execute value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/idempotent value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/instrument value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/literal value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/nothing-deleted value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/offline value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/one-writer value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/proof value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/receipts value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/resolve-by-url value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:9b85837d71b031e91e3e0849c437251d94fa4647a53f1d5342a92260f8cd0442 by=bound form=alphabet measure=bytes role=writes scope=receipts/samples value=sha256:9b85837d71b031e91e3e0849c437251d94fa4647a53f1d5342a92260f8cd0442 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/source value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 by=bound form=alphabet measure=bytes role=writes scope=receipts/the-stranger value=sha256:d5ef7c696b66f8b882f09bfec8292f9225b63177963a45702d889e4862f16337 +bound-lock/1 at=place:sha256:dbb4dae555687d63a1ab1aedc2199b4647e09b58f98edbc941f21e8e0fb777ce by=bound form=alphabet measure=bytes role=writes scope=receipts/vectors value=sha256:dbb4dae555687d63a1ab1aedc2199b4647e09b58f98edbc941f21e8e0fb777ce diff --git a/samples/no/archive-conformance.json b/samples/no/archive-conformance.json new file mode 100644 index 0000000..9f0f166 --- /dev/null +++ b/samples/no/archive-conformance.json @@ -0,0 +1,4 @@ +{ + "cause": "digest-mismatch", + "byteOffset": 8 +} diff --git a/samples/no/attest-evidence.json b/samples/no/attest-evidence.json new file mode 100644 index 0000000..d43cab4 --- /dev/null +++ b/samples/no/attest-evidence.json @@ -0,0 +1,7 @@ +{ + "uncovered": { + "scope": "sample/north", + "value": "uncovered" + }, + "tamperedValue": "altered" +} diff --git a/samples/no/historical-build.json b/samples/no/historical-build.json new file mode 100644 index 0000000..996ed63 --- /dev/null +++ b/samples/no/historical-build.json @@ -0,0 +1,4 @@ +{ + "view": "unoffered", + "region": "not-offered" +} diff --git a/samples/no/historical-document-views.json b/samples/no/historical-document-views.json new file mode 100644 index 0000000..5e6a3fb --- /dev/null +++ b/samples/no/historical-document-views.json @@ -0,0 +1,11 @@ +{ + "view": "unoffered", + "region": "not-offered", + "conflict": { + "path": "disagreement.txt", + "bodies": [ + "One reading.\n", + "Another reading.\n" + ] + } +} diff --git a/samples/no/historical-presentation.json b/samples/no/historical-presentation.json new file mode 100644 index 0000000..996ed63 --- /dev/null +++ b/samples/no/historical-presentation.json @@ -0,0 +1,4 @@ +{ + "view": "unoffered", + "region": "not-offered" +} diff --git a/samples/no/native-views.json b/samples/no/native-views.json new file mode 100644 index 0000000..2c4946a --- /dev/null +++ b/samples/no/native-views.json @@ -0,0 +1,8 @@ +{ + "uncovered": { + "scope": "sample/north", + "value": "uncovered" + }, + "tamperedValue": "altered", + "missingView": "not-provided-by-this-place" +} diff --git a/samples/no/program-views.json b/samples/no/program-views.json new file mode 100644 index 0000000..6a91e19 --- /dev/null +++ b/samples/no/program-views.json @@ -0,0 +1,3 @@ +{ + "cycle": true +} diff --git a/samples/no/prose-views.json b/samples/no/prose-views.json new file mode 100644 index 0000000..c546456 --- /dev/null +++ b/samples/no/prose-views.json @@ -0,0 +1,7 @@ +{ + "path": "disagreement.txt", + "bodies": [ + "One reading.\n", + "Another reading.\n" + ] +} diff --git a/samples/no/query-views.json b/samples/no/query-views.json new file mode 100644 index 0000000..428c86d --- /dev/null +++ b/samples/no/query-views.json @@ -0,0 +1,4 @@ +{ + "absentCoordinate": "not-declared.txt", + "missingView": "missing" +} diff --git a/samples/no/signing-port.json b/samples/no/signing-port.json new file mode 100644 index 0000000..190d113 --- /dev/null +++ b/samples/no/signing-port.json @@ -0,0 +1 @@ +{"unknownVersion":"bound-lock/0"} diff --git a/samples/no/typed-object.json b/samples/no/typed-object.json new file mode 100644 index 0000000..5b3d074 --- /dev/null +++ b/samples/no/typed-object.json @@ -0,0 +1,142 @@ +[ + { + "name": "floor-local", + "record": { + "type": "mark", + "scope": "B", + "id": "invalid-floor", + "sign": "+1", + "pole": "floor", + "reach": "local", + "value": "40..*" + }, + "refusal": "positive mark" + }, + { + "name": "floor-widens", + "record": { + "type": "mark", + "scope": "B", + "id": "floor-widens", + "sign": "+1", + "pole": "floor", + "reach": "travels", + "widens": "local-opening", + "value": "40..*" + }, + "refusal": "positive mark" + }, + { + "name": "travelling-widens", + "record": { + "type": "mark", + "scope": "B", + "id": "travelling-widens", + "sign": "+1", + "pole": "ceiling", + "reach": "travels", + "widens": "local-opening", + "value": "0..100" + }, + "refusal": "positive mark" + }, + { + "name": "object-at", + "record": { + "type": "claim", + "scope": "C", + "id": "object-at", + "sign": "+1", + "origin": "ana", + "value": "44..47", + "at": "origin:ana" + }, + "refusal": "object records carry no at" + }, + { + "name": "typed-missing-origin", + "record": { + "type": "claim", + "scope": "C", + "id": "incomplete", + "sign": "+1", + "value": "44..47" + }, + "refusal": "required.*origin" + }, + { + "name": "legacy-role-cannot-rescue", + "record": { + "type": "claim", + "scope": "C", + "id": "legacy-role", + "role": "reads", + "sign": "+1", + "value": "44..47" + }, + "refusal": "role=.*not allowed" + }, + { + "name": "untyped-id", + "record": { + "scope": "evidence/config", + "role": "writes", + "form": "alphabet", + "measure": "id", + "value": "present", + "at": "policy:sample", + "id": "untyped" + }, + "refusal": "id=.*object-only" + }, + { + "name": "missing-origin-grant", + "record": { + "type": "claim", + "scope": "C", + "id": "missing-origin", + "sign": "+1", + "origin": "unadmitted", + "value": "44..47" + }, + "refusal": "origin is not attested" + }, + { + "name": "missing-witness-grant", + "record": { + "type": "mark", + "scope": "B", + "id": "missing-witness", + "sign": "+1", + "pole": "ceiling", + "reach": "local", + "widens": "unadmitted", + "value": "0..100" + }, + "refusal": "join witness is not admitted" + }, + { + "name": "id-collision", + "record": { + "type": "mark", + "scope": "B", + "id": "s-B", + "sign": "+1", + "pole": "ceiling", + "reach": "travels", + "value": "0..49" + }, + "refusal": "record ID collision" + }, + { + "name": "cross-cell-takes", + "record": { + "type": "mark", + "scope": "G", + "id": "cross-cell", + "sign": "-1", + "takes": "s-B" + }, + "refusal": "incompatible withdrawal target" + } +] diff --git a/samples/no/walk.json b/samples/no/walk.json new file mode 100644 index 0000000..0d5fbe3 --- /dev/null +++ b/samples/no/walk.json @@ -0,0 +1,16 @@ +{ + "contract": "whole-region@1", + "cases": [ + "conflicting wire/fields", + "altered payload", + "missing payload", + "epoch outside signed cut", + "unauthorized signer", + "stale receiver base", + "unsupported resolution", + "omitted earlier records", + "insertion at an already verified epoch", + "interrupted receiver signer" + ], + "invariant": "No rejected or interrupted lot adds admitted evidence or a local import receipt. Dead-owner lock requires separate host recovery." +} diff --git a/samples/typed/artifacts.json b/samples/typed/artifacts.json new file mode 100644 index 0000000..1d21ee2 --- /dev/null +++ b/samples/typed/artifacts.json @@ -0,0 +1,81 @@ +{ + "cells": [ + { + "scope": "B", + "restsOn": "none" + }, + { + "scope": "C", + "restsOn": "B" + }, + { + "scope": "G", + "restsOn": "C" + }, + { + "scope": "D", + "restsOn": "none" + } + ], + "acts": [ + { + "type": "mark", + "scope": "B", + "id": "s-B", + "sign": "+1", + "pole": "ceiling", + "reach": "travels", + "value": "lock|readme" + }, + { + "type": "mark", + "scope": "B", + "id": "j-B", + "sign": "+1", + "pole": "ceiling", + "reach": "local", + "widens": "local-opening", + "value": "lock|readme|source" + }, + { + "type": "mark", + "scope": "B", + "id": "r-B", + "sign": "+1", + "pole": "floor", + "reach": "travels", + "value": "lock" + }, + { + "type": "claim", + "scope": "C", + "id": "c-C", + "sign": "+1", + "origin": "ana", + "value": "lock|readme" + }, + { + "type": "claim", + "scope": "C", + "id": "c-L", + "sign": "+1", + "origin": "luis", + "value": "lock" + } + ], + "form": "alphabet", + "measure": "artifact", + "params": { + "tokens": [ + "lock", + "readme", + "source" + ] + }, + "scenarios": { + "conflicting": "readme", + "outside": "source", + "floorConflict": "source" + }, + "place": "repository-artifacts" +} diff --git a/samples/typed/artifacts.vector.json b/samples/typed/artifacts.vector.json new file mode 100644 index 0000000..65478fd --- /dev/null +++ b/samples/typed/artifacts.vector.json @@ -0,0 +1,173 @@ +{ + "status": "captured installed prototype output, not native receipts or release acceptance", + "sample": "artifacts", + "capture": "evidence/shipped-sample.artifacts.json", + "readerArchive": "sha256:f35f1f6d2d3123c726d26f65abafe648e6b529ed3661e2d9dc308dcb1bdf228d", + "pin": "sha256:c65f4340d3f2a95103d85f68059a882ebbeb5616de31d20ed06f430889252767", + "observations": [ + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":3},\"width\":3},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"words\":{\"0\":7},\"width\":3},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":1},\"width\":3},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FREE\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":1},\"width\":3},\"origins\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":3},\"width\":3}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":1},\"width\":3}}],\"rest\":[\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"c-C\",\"origin\":\"ana\"},{\"id\":\"c-L\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":3},\"width\":3}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":1},\"width\":3}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":7},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":7},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":3},\"width\":3},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"words\":{\"0\":7},\"width\":3},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":1},\"width\":3},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FREE\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":1},\"width\":3},\"origins\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":3},\"width\":3}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":1},\"width\":3}}],\"rest\":[\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"c-C\",\"origin\":\"ana\"},{\"id\":\"c-L\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":3},\"width\":3}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":1},\"width\":3}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":7},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":7},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":3},\"width\":3},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"words\":{\"0\":7},\"width\":3},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":1},\"width\":3},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"CONFLICT\",\"parts\":{\"floor\":{\"words\":{\"0\":0},\"width\":3},\"ceiling\":{\"words\":{\"0\":0},\"width\":3},\"origins\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":3},\"width\":3}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":1},\"width\":3}},{\"id\":\"disagreement\",\"at\":8,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":2},\"width\":3}}],\"rest\":[\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"c-C\",\"origin\":\"ana\"},{\"id\":\"c-L\",\"origin\":\"luis\"},{\"id\":\"disagreement\",\"origin\":\"ana\"}],\"marks\":[],\"claims\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":3},\"width\":3}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":1},\"width\":3}},{\"id\":\"disagreement\",\"at\":8,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":2},\"width\":3}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":7},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":7},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":3},\"width\":3},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"words\":{\"0\":7},\"width\":3},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":1},\"width\":3},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":7},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":7},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":3},\"width\":3},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"words\":{\"0\":7},\"width\":3},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":1},\"width\":3},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FORBIDDEN\",\"parts\":{\"floor\":{\"words\":{\"0\":0},\"width\":3},\"ceiling\":{\"words\":{\"0\":0},\"width\":3},\"origins\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":4},\"width\":3}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":4},\"width\":3}}],\"rest\":[\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"outside-a\",\"origin\":\"ana\"},{\"id\":\"outside-b\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":4},\"width\":3}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":4},\"width\":3}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":7},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":7},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":3},\"width\":3},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"words\":{\"0\":7},\"width\":3},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":1},\"width\":3},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FORBIDDEN\",\"parts\":{\"floor\":{\"words\":{\"0\":0},\"width\":3},\"ceiling\":{\"words\":{\"0\":0},\"width\":3},\"origins\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":4},\"width\":3}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":4},\"width\":3}}],\"rest\":[\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"outside-a\",\"origin\":\"ana\"},{\"id\":\"outside-b\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":4},\"width\":3}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":4},\"width\":3}}]}", + "CELL {\"cell\":\"G\",\"state\":\"CONFLICT\",\"parts\":{\"floor\":{\"words\":{\"0\":0},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"words\":{\"0\":0},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[\"incompatible-floor\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":4},\"width\":3},\"id\":\"incompatible-floor\",\"at\":14}],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":7},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":7},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":1},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[],\"ownMarks\":[\"s-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":3},\"width\":3},\"id\":\"s-B\",\"at\":3},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":1},\"width\":3},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FORBIDDEN\",\"parts\":{\"floor\":{\"words\":{\"0\":0},\"width\":3},\"ceiling\":{\"words\":{\"0\":0},\"width\":3},\"origins\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":4},\"width\":3}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":4},\"width\":3}}],\"rest\":[\"B\"],\"required\":{\"words\":{\"0\":1},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"outside-a\",\"origin\":\"ana\"},{\"id\":\"outside-b\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"words\":{\"0\":4},\"width\":3}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"words\":{\"0\":4},\"width\":3}}]}", + "CELL {\"cell\":\"G\",\"state\":\"CONFLICT\",\"parts\":{\"floor\":{\"words\":{\"0\":0},\"width\":3},\"ceiling\":{\"words\":{\"0\":3},\"width\":3},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"words\":{\"0\":0},\"width\":3},\"signed\":{\"words\":{\"0\":3},\"width\":3}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[\"incompatible-floor\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"words\":{\"0\":4},\"width\":3},\"id\":\"incompatible-floor\",\"at\":14}],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"words\":{\"0\":7},\"width\":3},\"ceiling\":{\"words\":{\"0\":7},\"width\":3},\"origins\":[],\"rest\":[],\"required\":{\"words\":{\"0\":7},\"width\":3},\"signed\":{\"words\":{\"0\":7},\"width\":3}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "case": "floor-local", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire B \u00b7 a positive mark is ceiling/travels, ceiling/local with widens, or floor/travels without widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "floor-widens", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire B \u00b7 a positive mark is ceiling/travels, ceiling/local with widens, or floor/travels without widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "travelling-widens", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire B \u00b7 a positive mark is ceiling/travels, ceiling/local with widens, or floor/travels without widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "object-at", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire C \u00b7 object records carry no at: order is epoch and a local join witness is widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "typed-missing-origin", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire C \u00b7 a claim/positive record has no declared required `origin` \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "legacy-role-cannot-rescue", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire C \u00b7 `role=` is not allowed on claim/positive \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "untyped-id", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire evidence/config \u00b7 `id=` is an object-only field: untyped configuration cannot carry it \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "missing-origin-grant", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: origin is not attested for missing-origin \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "missing-witness-grant", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: join witness is not admitted for missing-witness \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "id-collision", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: record ID collision s-B \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "cross-cell-takes", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: unauthorized or incompatible withdrawal target s-B \u00b7 nothing landed\n", + "ledgerUnchanged": true + } + ] +} diff --git a/samples/typed/contract.json b/samples/typed/contract.json new file mode 100644 index 0000000..b81020d --- /dev/null +++ b/samples/typed/contract.json @@ -0,0 +1,37 @@ +{ + "status": "publication candidate; member declarations admitted and installed prototype inclusion verified; release acceptance unpaid", + "owner": "selected Topos provides interval decoding and explicit origin/witness grants; Bound admits; Obligations computes", + "run": "node tools/samples/run-typed.mjs", + "assets": [ + "wire.json", + "yes.json", + "no.json", + "artifacts.json", + "range.vector.json", + "artifacts.vector.json" + ], + "provider": "tools/samples/typed-provider.mjs", + "installation": "uses only published SDK modules and the selected installed Bound CLI; no source conditions, checkout ledger, owner key or pre-existing CAS", + "checks": [ + "native PIN before cells", + "exact artifact hashes", + "sign travels; join stays local", + "floor travels", + "two independent origins", + "REQUIRED", + "FREE", + "CONFLICT claims", + "CONFLICT bounds", + "FORBIDDEN", + "exact-id withdrawal", + "unchanged receipt reuse", + "floor+local refuses", + "second unrelated place selects alphabet form for repository artifacts" + ], + "oracle": "direct cell/sign/join/require/observe/parts/state/live calls from Obligations 0.3.5", + "limitations": [ + "full typed rejection corpus still unpaid", + "publication quartet is not yet measured by the admitted contract/published law", + "mandatory walk and exact 0.1.5 acceptance remain unpaid" + ] +} diff --git a/samples/typed/no.json b/samples/typed/no.json new file mode 100644 index 0000000..5b3d074 --- /dev/null +++ b/samples/typed/no.json @@ -0,0 +1,142 @@ +[ + { + "name": "floor-local", + "record": { + "type": "mark", + "scope": "B", + "id": "invalid-floor", + "sign": "+1", + "pole": "floor", + "reach": "local", + "value": "40..*" + }, + "refusal": "positive mark" + }, + { + "name": "floor-widens", + "record": { + "type": "mark", + "scope": "B", + "id": "floor-widens", + "sign": "+1", + "pole": "floor", + "reach": "travels", + "widens": "local-opening", + "value": "40..*" + }, + "refusal": "positive mark" + }, + { + "name": "travelling-widens", + "record": { + "type": "mark", + "scope": "B", + "id": "travelling-widens", + "sign": "+1", + "pole": "ceiling", + "reach": "travels", + "widens": "local-opening", + "value": "0..100" + }, + "refusal": "positive mark" + }, + { + "name": "object-at", + "record": { + "type": "claim", + "scope": "C", + "id": "object-at", + "sign": "+1", + "origin": "ana", + "value": "44..47", + "at": "origin:ana" + }, + "refusal": "object records carry no at" + }, + { + "name": "typed-missing-origin", + "record": { + "type": "claim", + "scope": "C", + "id": "incomplete", + "sign": "+1", + "value": "44..47" + }, + "refusal": "required.*origin" + }, + { + "name": "legacy-role-cannot-rescue", + "record": { + "type": "claim", + "scope": "C", + "id": "legacy-role", + "role": "reads", + "sign": "+1", + "value": "44..47" + }, + "refusal": "role=.*not allowed" + }, + { + "name": "untyped-id", + "record": { + "scope": "evidence/config", + "role": "writes", + "form": "alphabet", + "measure": "id", + "value": "present", + "at": "policy:sample", + "id": "untyped" + }, + "refusal": "id=.*object-only" + }, + { + "name": "missing-origin-grant", + "record": { + "type": "claim", + "scope": "C", + "id": "missing-origin", + "sign": "+1", + "origin": "unadmitted", + "value": "44..47" + }, + "refusal": "origin is not attested" + }, + { + "name": "missing-witness-grant", + "record": { + "type": "mark", + "scope": "B", + "id": "missing-witness", + "sign": "+1", + "pole": "ceiling", + "reach": "local", + "widens": "unadmitted", + "value": "0..100" + }, + "refusal": "join witness is not admitted" + }, + { + "name": "id-collision", + "record": { + "type": "mark", + "scope": "B", + "id": "s-B", + "sign": "+1", + "pole": "ceiling", + "reach": "travels", + "value": "0..49" + }, + "refusal": "record ID collision" + }, + { + "name": "cross-cell-takes", + "record": { + "type": "mark", + "scope": "G", + "id": "cross-cell", + "sign": "-1", + "takes": "s-B" + }, + "refusal": "incompatible withdrawal target" + } +] diff --git a/samples/typed/range.vector.json b/samples/typed/range.vector.json new file mode 100644 index 0000000..937b464 --- /dev/null +++ b/samples/typed/range.vector.json @@ -0,0 +1,173 @@ +{ + "status": "captured installed prototype output, not native receipts or release acceptance", + "sample": "range", + "capture": "evidence/shipped-sample.range.json", + "readerArchive": "sha256:f35f1f6d2d3123c726d26f65abafe648e6b529ed3661e2d9dc308dcb1bdf228d", + "pin": "sha256:c98647a42b55fc829e39dea4ee295bec4b36530f17540e4125f2e686f5fd61a7", + "observations": [ + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"lo\":0,\"hi\":50},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"lo\":0,\"hi\":100},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":40,\"hi\":100},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FREE\",\"parts\":{\"floor\":{\"lo\":44,\"hi\":47},\"ceiling\":{\"lo\":44,\"hi\":47},\"origins\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"lo\":42,\"hi\":48}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"lo\":44,\"hi\":47}}],\"rest\":[\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"c-C\",\"origin\":\"ana\"},{\"id\":\"c-L\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"lo\":42,\"hi\":48}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"lo\":44,\"hi\":47}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":0,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":0,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"lo\":0,\"hi\":50},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"lo\":0,\"hi\":100},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":40,\"hi\":100},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FREE\",\"parts\":{\"floor\":{\"lo\":44,\"hi\":47},\"ceiling\":{\"lo\":44,\"hi\":47},\"origins\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"lo\":42,\"hi\":48}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"lo\":44,\"hi\":47}}],\"rest\":[\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"c-C\",\"origin\":\"ana\"},{\"id\":\"c-L\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"lo\":42,\"hi\":48}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"lo\":44,\"hi\":47}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":0,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":0,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"lo\":0,\"hi\":50},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"lo\":0,\"hi\":100},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":40,\"hi\":100},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"CONFLICT\",\"parts\":{\"floor\":{\"lo\":44,\"hi\":43},\"ceiling\":{\"lo\":44,\"hi\":43},\"origins\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"lo\":42,\"hi\":48}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"lo\":44,\"hi\":47}},{\"id\":\"disagreement\",\"at\":8,\"origin\":\"ana\",\"span\":{\"lo\":40,\"hi\":43}}],\"rest\":[\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"c-C\",\"origin\":\"ana\"},{\"id\":\"c-L\",\"origin\":\"luis\"},{\"id\":\"disagreement\",\"origin\":\"ana\"}],\"marks\":[],\"claims\":[{\"id\":\"c-C\",\"at\":6,\"origin\":\"ana\",\"span\":{\"lo\":42,\"hi\":48}},{\"id\":\"c-L\",\"at\":7,\"origin\":\"luis\",\"span\":{\"lo\":44,\"hi\":47}},{\"id\":\"disagreement\",\"at\":8,\"origin\":\"ana\",\"span\":{\"lo\":40,\"hi\":43}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":0,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":0,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"lo\":0,\"hi\":50},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"lo\":0,\"hi\":100},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":40,\"hi\":100},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":0,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":0,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"lo\":0,\"hi\":50},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"lo\":0,\"hi\":100},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":40,\"hi\":100},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FORBIDDEN\",\"parts\":{\"floor\":{\"lo\":65,\"hi\":75},\"ceiling\":{\"lo\":65,\"hi\":50},\"origins\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"lo\":65,\"hi\":75}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"lo\":65,\"hi\":75}}],\"rest\":[\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"outside-a\",\"origin\":\"ana\"},{\"id\":\"outside-b\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"lo\":65,\"hi\":75}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"lo\":65,\"hi\":75}}]}", + "CELL {\"cell\":\"G\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":0,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":0,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[\"s-B\",\"j-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"lo\":0,\"hi\":50},\"id\":\"s-B\",\"at\":3},{\"pole\":\"ceiling\",\"reach\":\"local\",\"span\":{\"lo\":0,\"hi\":100},\"widens\":\"local-opening\",\"at\":4,\"id\":\"j-B\"},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":40,\"hi\":100},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FORBIDDEN\",\"parts\":{\"floor\":{\"lo\":65,\"hi\":75},\"ceiling\":{\"lo\":65,\"hi\":50},\"origins\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"lo\":65,\"hi\":75}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"lo\":65,\"hi\":75}}],\"rest\":[\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"outside-a\",\"origin\":\"ana\"},{\"id\":\"outside-b\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"lo\":65,\"hi\":75}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"lo\":65,\"hi\":75}}]}", + "CELL {\"cell\":\"G\",\"state\":\"CONFLICT\",\"parts\":{\"floor\":{\"lo\":60,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"lo\":60,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[\"incompatible-floor\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":60,\"hi\":100},\"id\":\"incompatible-floor\",\"at\":14}],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":0,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":0,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "args": [ + "fold", + "--as", + "cells" + ], + "status": 0, + "stdoutCELL": [ + "CELL {\"cell\":\"B\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":40,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[],\"ownMarks\":[\"s-B\",\"r-B\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"ceiling\",\"reach\":\"travels\",\"span\":{\"lo\":0,\"hi\":50},\"id\":\"s-B\",\"at\":3},{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":40,\"hi\":100},\"id\":\"r-B\",\"at\":5}],\"claims\":[]}", + "CELL {\"cell\":\"C\",\"state\":\"FORBIDDEN\",\"parts\":{\"floor\":{\"lo\":65,\"hi\":75},\"ceiling\":{\"lo\":65,\"hi\":50},\"origins\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"lo\":65,\"hi\":75}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"lo\":65,\"hi\":75}}],\"rest\":[\"B\"],\"required\":{\"lo\":40,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"B\"],\"ownMarks\":[],\"ownClaims\":[{\"id\":\"outside-a\",\"origin\":\"ana\"},{\"id\":\"outside-b\",\"origin\":\"luis\"}],\"marks\":[],\"claims\":[{\"id\":\"outside-a\",\"at\":12,\"origin\":\"ana\",\"span\":{\"lo\":65,\"hi\":75}},{\"id\":\"outside-b\",\"at\":13,\"origin\":\"luis\",\"span\":{\"lo\":65,\"hi\":75}}]}", + "CELL {\"cell\":\"G\",\"state\":\"CONFLICT\",\"parts\":{\"floor\":{\"lo\":60,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":50},\"origins\":[],\"rest\":[\"C\",\"B\"],\"required\":{\"lo\":60,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":50}},\"rest\":[\"C\",\"B\"],\"ownMarks\":[\"incompatible-floor\"],\"ownClaims\":[],\"marks\":[{\"pole\":\"floor\",\"reach\":\"travels\",\"span\":{\"lo\":60,\"hi\":100},\"id\":\"incompatible-floor\",\"at\":14}],\"claims\":[]}", + "CELL {\"cell\":\"D\",\"state\":\"REQUIRED\",\"parts\":{\"floor\":{\"lo\":0,\"hi\":100},\"ceiling\":{\"lo\":0,\"hi\":100},\"origins\":[],\"rest\":[],\"required\":{\"lo\":0,\"hi\":100},\"signed\":{\"lo\":0,\"hi\":100}},\"rest\":[],\"ownMarks\":[],\"ownClaims\":[],\"marks\":[],\"claims\":[]}" + ] + }, + { + "case": "floor-local", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire B \u00b7 a positive mark is ceiling/travels, ceiling/local with widens, or floor/travels without widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "floor-widens", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire B \u00b7 a positive mark is ceiling/travels, ceiling/local with widens, or floor/travels without widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "travelling-widens", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire B \u00b7 a positive mark is ceiling/travels, ceiling/local with widens, or floor/travels without widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "object-at", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire C \u00b7 object records carry no at: order is epoch and a local join witness is widens \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "typed-missing-origin", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire C \u00b7 a claim/positive record has no declared required `origin` \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "legacy-role-cannot-rescue", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire C \u00b7 `role=` is not allowed on claim/positive \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "untyped-id", + "status": 1, + "stderr": "bound: REFUSE\u00b7wire evidence/config \u00b7 `id=` is an object-only field: untyped configuration cannot carry it \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "missing-origin-grant", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: origin is not attested for missing-origin \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "missing-witness-grant", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: join witness is not admitted for missing-witness \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "id-collision", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: record ID collision s-B \u00b7 nothing landed\n", + "ledgerUnchanged": true + }, + { + "case": "cross-cell-takes", + "status": 1, + "stderr": "bound: REFUSE\u00b7context object context: unauthorized or incompatible withdrawal target s-B \u00b7 nothing landed\n", + "ledgerUnchanged": true + } + ] +} diff --git a/samples/typed/wire.json b/samples/typed/wire.json new file mode 100644 index 0000000..988a0de --- /dev/null +++ b/samples/typed/wire.json @@ -0,0 +1,22 @@ +[ + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/fields value=about|at|by|condition|epoch|form|id|kind|measure|needs|origin|params|pole|reach|restsOn|role|scope|shape|sig|sign|takes|topos|type|value|view|widens", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/required value=at|by|form|measure|role|scope|value", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/types value=cell|claim|mark", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/common value=by|epoch|id|scope|sig|type", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/reserved value=id|origin|params|pole|reach|sign|takes|topos|type|widens", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/config value=about|at|by|condition|epoch|form|kind|measure|needs|restsOn|role|scope|shape|sig|value|view", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/required/cell value=by|epoch|form|id|measure|params|restsOn|scope|sig|topos|type", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/cell value=by|epoch|form|id|measure|params|restsOn|scope|sig|topos|type", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/required/claim/positive value=by|epoch|id|origin|scope|sig|sign|type|value", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/claim/positive value=by|epoch|id|origin|scope|sig|sign|type|value", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/required/claim/negative value=by|epoch|id|scope|sig|sign|takes|type", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/claim/negative value=by|epoch|id|scope|sig|sign|takes|type", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/required/mark/travelling value=by|epoch|id|pole|reach|scope|sig|sign|type|value", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/mark/travelling value=by|epoch|id|pole|reach|scope|sig|sign|type|value", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/required/mark/local value=by|epoch|id|pole|reach|scope|sig|sign|type|value|widens", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/mark/local value=by|epoch|id|pole|reach|scope|sig|sign|type|value|widens", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/required/mark/floor-travelling value=by|epoch|id|pole|reach|scope|sig|sign|type|value", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/mark/floor-travelling value=by|epoch|id|pole|reach|scope|sig|sign|type|value", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/required/mark/negative value=by|epoch|id|scope|sig|sign|takes|type", + "bound-lock/1 at=policy:topos/fold by=target form=alphabet measure=id role=reads scope=wire/object/allowed/mark/negative value=by|epoch|id|scope|sig|sign|takes|type" +] diff --git a/samples/typed/yes.json b/samples/typed/yes.json new file mode 100644 index 0000000..f375bf9 --- /dev/null +++ b/samples/typed/yes.json @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "scope": "B", + "restsOn": "none" + }, + { + "scope": "C", + "restsOn": "B" + }, + { + "scope": "G", + "restsOn": "C" + }, + { + "scope": "D", + "restsOn": "none" + } + ], + "acts": [ + { + "type": "mark", + "scope": "B", + "id": "s-B", + "sign": "+1", + "pole": "ceiling", + "reach": "travels", + "value": "0..50" + }, + { + "type": "mark", + "scope": "B", + "id": "j-B", + "sign": "+1", + "pole": "ceiling", + "reach": "local", + "widens": "local-opening", + "value": "0..100" + }, + { + "type": "mark", + "scope": "B", + "id": "r-B", + "sign": "+1", + "pole": "floor", + "reach": "travels", + "value": "40..*" + }, + { + "type": "claim", + "scope": "C", + "id": "c-C", + "sign": "+1", + "origin": "ana", + "value": "42..48" + }, + { + "type": "claim", + "scope": "C", + "id": "c-L", + "sign": "+1", + "origin": "luis", + "value": "44..47" + } + ], + "form": "interval", + "measure": "count", + "params": { + "lo": 0, + "hi": 100 + }, + "scenarios": { + "conflicting": "40..43", + "outside": "65..75", + "floorConflict": "60..*" + }, + "place": "range" +} diff --git a/samples/walk/no.json b/samples/walk/no.json new file mode 100644 index 0000000..0d5fbe3 --- /dev/null +++ b/samples/walk/no.json @@ -0,0 +1,16 @@ +{ + "contract": "whole-region@1", + "cases": [ + "conflicting wire/fields", + "altered payload", + "missing payload", + "epoch outside signed cut", + "unauthorized signer", + "stale receiver base", + "unsupported resolution", + "omitted earlier records", + "insertion at an already verified epoch", + "interrupted receiver signer" + ], + "invariant": "No rejected or interrupted lot adds admitted evidence or a local import receipt. Dead-owner lock requires separate host recovery." +} diff --git a/samples/walk/refinement.json b/samples/walk/refinement.json new file mode 100644 index 0000000..8ae1bf2 --- /dev/null +++ b/samples/walk/refinement.json @@ -0,0 +1,9 @@ +[ + "bound-lock/1 at=policy:whole-region-walk-contract by=target form=alphabet measure=id role=writes scope=wire/walk/contract value=whole-region@1", + "bound-lock/1 at=policy:whole-region-walk-contract by=target form=alphabet measure=id role=writes scope=wire/walk/fields value=about|at|by|condition|epoch|form|id|kind|measure|needs|origin|params|pole|reach|restsOn|role|scope|shape|sign|takes|topos|type|value|view|widens", + "bound-lock/1 at=policy:whole-region-walk-contract by=target form=alphabet measure=id role=writes scope=wire/walk/metadata-fields value=at|by|condition|epoch|form|measure|role|scope|sig|value", + "bound-lock/1 at=policy:whole-region-walk-contract by=target form=alphabet measure=id role=writes scope=wire/walk/resolutions value=0|1|4|5|6|8", + "bound-lock/1 at=policy:whole-region-walk-contract by=target form=alphabet measure=id role=writes scope=wire/walk/projections value=0:inventory|1:summary|4:summary|5:summary|6:history|8:history", + "bound-lock/1 at=policy:coordinate-refinement by=target form=alphabet measure=id role=writes scope=wire/walk/partition value=scope-coordinates@1", + "bound-lock/1 at=policy:coordinate-refinement by=target form=alphabet measure=id role=writes scope=wire/walk/refinements value=0:1|1:1|4:3|5:all|6:all|8:all" +] diff --git a/samples/walk/typed-vector.json b/samples/walk/typed-vector.json new file mode 100644 index 0000000..accdc72 --- /dev/null +++ b/samples/walk/typed-vector.json @@ -0,0 +1,14 @@ +{ + "contract": "whole-region@1 typed foreign evidence", + "places": ["interval measurements", "repository artifact membership"], + "runner": "tools/samples/run-typed-walk.mjs", + "required": [ + "Origin context declares its complete semantic history fields, public authority resolution and the selected object provider", + "The native CLI admits authenticated cell/claim/mark histories as foreign evidence", + "A foreign claim withdrawal and a local claim sharing its target ID coexist", + "Foreign withdrawal stays in the evidence view; local claim stays live", + "Local cells and native cell receipts remain unchanged and idle", + "Replay prints ONCE, retaining one import receipt and no new local lines" + ], + "excludes": "This vector does not certify reconstruction of one object from several origin histories. Foreign evidence is never concatenated into local authority or a global epoch order." +} diff --git a/samples/walk/yes.json b/samples/walk/yes.json new file mode 100644 index 0000000..9ca66be --- /dev/null +++ b/samples/walk/yes.json @@ -0,0 +1,100 @@ +{ + "contract": "whole-region@1", + "places": [ + "measurement", + "artifact" + ], + "declarations": [ + [ + "wire/digest-algorithms", + "id", + "sha256" + ], + [ + "wire/signature-algorithms", + "id", + "ed25519:sample" + ], + [ + "wire/era", + "id", + "sample" + ], + [ + "wire/families", + "id", + "keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|view|region|uses|walk|sample" + ], + [ + "wire/fields", + "id", + "scope|role|form|measure|value|by|at|epoch|sig|condition|needs" + ], + [ + "wire/required", + "id", + "scope|role|form|measure|value|by|at" + ], + [ + "wire/forms", + "id", + "alphabet|interval" + ], + [ + "wire/roles", + "id", + "reads|writes|demands" + ], + [ + "wire/at-classes", + "id", + "origin|place|receipt|witness|policy" + ], + [ + "wire/walk/contract", + "id", + "whole-region@1" + ], + [ + "wire/walk/fields", + "id", + "scope|role|form|measure|value|by|at|epoch|condition|needs" + ], + [ + "wire/walk/metadata-fields", + "id", + "at|by|condition|epoch|form|measure|role|scope|sig|value" + ], + [ + "wire/walk/resolutions", + "id", + "0|1|4|6|8" + ], + [ + "signer/timeout", + "milliseconds", + "5000..5000", + "interval" + ], + [ + "signer/response-bytes", + "bytes", + "65536..65536", + "interval" + ], + [ + "wire/walk/projections", + "id", + "0:inventory|1:summary|4:summary|6:history|8:history" + ] + ], + "requirements": [ + "@0/@1/@8 escalation", + "authenticated whole-region prefixes", + "two clocks", + "union retains both origins", + "unchanged exchange zero payload", + "atomic native receipt", + "replay zero writes" + ] +} diff --git a/samples/yes/archive-conformance.json b/samples/yes/archive-conformance.json new file mode 100644 index 0000000..b1d0c16 --- /dev/null +++ b/samples/yes/archive-conformance.json @@ -0,0 +1,28 @@ +{ + "algorithm": "sha256", + "packageProgram": "npm", + "timeoutMs": 5000, + "maxBytes": 1048576, + "places": [ + { + "name": "specimen-index", + "version": "1.0.0", + "files": { + "README.md": "A specimen index.\n", + "LICENSE": "MIT License\n", + "entry.mjs": "console.log('specimens: stored');\n" + }, + "stdout": "specimens: stored\n" + }, + { + "name": "route-notes", + "version": "1.0.0", + "files": { + "README.md": "Route observations.\n", + "LICENSE": "MIT License\n", + "entry.mjs": "console.log('routes: recorded');\n" + }, + "stdout": "routes: recorded\n" + } + ] +} diff --git a/samples/yes/attest-evidence.json b/samples/yes/attest-evidence.json new file mode 100644 index 0000000..3e79388 --- /dev/null +++ b/samples/yes/attest-evidence.json @@ -0,0 +1,8 @@ +{ + "keyClasses": [ + "authorize", + "read", + "access", + "attest" + ] +} diff --git a/samples/yes/historical-build.json b/samples/yes/historical-build.json new file mode 100644 index 0000000..e3e9ed1 --- /dev/null +++ b/samples/yes/historical-build.json @@ -0,0 +1,78 @@ +{ + "profile": "historical-build@1", + "providerSource": "var __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/index.ts\nvar index_exports = {};\n__export(index_exports, {\n render: () => render\n});\nmodule.exports = __toCommonJS(index_exports);\n\n// node_modules/@lapxo/topos/dist/capsule/asked.js\nvar of = (line, field) => line?.[field] ?? \"\";\nvar found = (asked, scope) => asked.lines.find((line) => of(line, \"scope\") === scope);\nvar value = (asked, scope) => found(asked, scope) === void 0 ? void 0 : of(found(asked, scope), \"value\");\nvar listed = (asked, scope) => (value(asked, scope) ?? \"\").split(\"|\").filter(Boolean);\nvar lang = (asked) => value(asked, \"lang\") ?? \"\";\nvar at = (asked, scope) => ((line) => line === void 0 ? void 0 : of(line, \"value\"))(asked.lines.find((line) => of(line, \"scope\") === scope && of(line, \"shape\") === asked.shape));\nvar under = (asked, head) => asked.lines.filter((line) => of(line, \"shape\") === asked.shape && (of(line, \"scope\") === head || of(line, \"scope\").startsWith(`${head}/`))).map((line) => [of(line, \"scope\").slice(head.length + (of(line, \"scope\") === head ? 0 : 1)), of(line, \"value\")]).sort((a, b) => a[0] === \"\" ? -1 : b[0] === \"\" ? 1 : a[0].localeCompare(b[0]));\nvar json = (held) => `${JSON.stringify(held, null, 2)}\n`.split(\"\\n\").slice(0, -1);\nvar truth = (text) => text === \"true\" ? true : text === \"false\" ? false : text;\nvar sentence = (asked, text) => {\n const rule = listed(asked, `form/prose/${lang(asked)}/sentence`);\n let end = text.length;\n while (end > 0 && \".;:, \\n\".includes(text.charAt(end - 1)))\n end -= 1;\n const start = rule.includes(\"capital\") ? `${text.charAt(0).toUpperCase()}${text.slice(1, end)}` : text.slice(0, end);\n return rule.includes(\"period\") ? `${start}.` : start;\n};\n\n// node_modules/@lapxo/topos/dist/capsule/shell.js\nfunction shell(regions) {\n return (asked) => {\n const one = regions[asked.region];\n if (one === void 0)\n throw new Error(`REFUSE\\xB7region ${asked.region}: no line of this capsule renders it`);\n const short = one.reads.filter((read) => !asked.reads.includes(read));\n if (short.length)\n throw new Error(`REFUSE\\xB7region ${asked.region}: handed less than it declares, without ${short.join(\" \\xB7 \")}`);\n return one.region(asked);\n };\n}\n\n// src/regions/build.ts\nvar build = (asked) => {\n const options = under(asked, \"build\").filter(([name]) => name !== \"\");\n const include = options.find(([name]) => name === \"include\")?.[1];\n return json({ compilerOptions: Object.fromEntries(options.filter(([name]) => name !== \"include\").map(([name, held]) => [name, truth(held)])), ...include === void 0 ? {} : { include: include.split(\"|\") } });\n};\n\n// src/regions/manifest.ts\nvar versioned = (text) => Object.fromEntries((text ?? \"\").split(\"|\").filter(Boolean).map((one) => [one.slice(0, one.lastIndexOf(\"@\")), one.slice(one.lastIndexOf(\"@\") + 1)]));\nvar manifest = (asked) => {\n const [subpaths, bins, source, what] = [under(asked, \"exports\"), under(asked, \"bin\").filter(([name]) => name !== \"\"), at(asked, \"source\"), found(asked, `prose/${lang(asked)}/what`)];\n const resolved = (built) => ({ ...source ? { source: `./${source}${built.slice(built.indexOf(\"/\"))}.ts` } : {}, types: `./${built}.d.ts`, default: `./${built}.js` });\n const [repository, kind, side] = [at(asked, \"repository\"), at(asked, \"type\"), at(asked, \"sideEffects\")];\n return json({\n name: at(asked, \"name\"),\n version: at(asked, \"version\"),\n description: what === void 0 ? void 0 : sentence(asked, of(what, \"about\")),\n ...kind ? { type: kind } : {},\n license: at(asked, \"license\"),\n author: at(asked, \"author\"),\n ...repository ? { repository: { type: \"git\", url: `git+${repository}.git` } } : {},\n keywords: (at(asked, \"keywords\") ?? \"\").split(\"|\").filter(Boolean),\n ...side === void 0 ? {} : { sideEffects: truth(side) },\n engines: { node: at(asked, \"engines\") },\n exports: { ...Object.fromEntries(subpaths.map(([sub, built]) => [sub === \"\" ? \".\" : `./${sub}`, resolved(built)])), [`./${asked.shape}`]: `./${asked.shape}` },\n ...bins.length ? { bin: Object.fromEntries(bins.map(([name, built]) => [name, `./${built}.js`])) } : {},\n files: listed(asked, \"audit/wire/ships\"),\n scripts: Object.fromEntries(under(asked, \"scripts\").filter(([name]) => name !== \"\")),\n ...at(asked, \"dependencies\") === void 0 ? {} : { dependencies: versioned(at(asked, \"dependencies\")) },\n ...at(asked, \"devDependencies\") === void 0 ? {} : { devDependencies: versioned(at(asked, \"devDependencies\")) }\n });\n};\n\n// src/regions/published-manifest.ts\nvar publishedManifest = (asked) => {\n const held = JSON.parse(manifest(asked).join(\"\\n\"));\n for (const one of Object.values(held[\"exports\"])) if (typeof one === \"object\" && one !== null) delete one[\"source\"];\n return json(held);\n};\n\n// src/index.ts\nvar render = shell({\n build: { reads: [\"build/**\"], region: build },\n manifest: { reads: [\"name\", \"version\", \"type\", \"license\", \"author\", \"repository\", \"keywords\", \"sideEffects\", \"engines\", \"exports/**\", \"bin/**\", \"scripts/**\", \"dependencies\", \"devDependencies\", \"source\", \"lang\", \"prose/*/what\", \"form/prose/*/sentence\", \"audit/wire/ships\"], region: manifest },\n \"published-manifest\": { reads: [\"name\", \"version\", \"type\", \"license\", \"author\", \"repository\", \"keywords\", \"sideEffects\", \"engines\", \"exports/**\", \"bin/**\", \"scripts/**\", \"dependencies\", \"devDependencies\", \"source\", \"lang\", \"prose/*/what\", \"form/prose/*/sentence\", \"audit/wire/ships\"], region: publishedManifest }\n});\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n render\n});\n", + "providerDigest": "sha256:53c974b95957f654f13398bd6b2f781cb4b86f9f93a54d7a59fb2e4d38a7e017", + "provenance": { + "artifact": "sha256:384a74b07eb8c7235e584b2801dbda1d78acd7ef6dac933ab05400a40658c55b", + "member": "dist/index.js", + "fixtureOnly": true + }, + "regions": [ + { + "name": "build", + "reads": "build/**" + } + ], + "wire": [ + [ + "fields", + "scope|role|form|measure|value|by|at|epoch|sig|needs|shape|about|kind|restsOn" + ], + [ + "required", + "scope|role|form|measure|value|by|at" + ], + [ + "forms", + "alphabet|interval" + ], + [ + "families", + "keys|signer|wire|sample|tree|write|leaf|view|reader|read|fold|receipts|rendered|resolved|beat|region|prose|uses|dep|name|version|author|repository|license|lang|form|page|term|sources|build" + ], + [ + "roles", + "reads|writes|demands" + ], + [ + "at-classes", + "policy|place|origin|witness|receipt" + ], + [ + "era", + "sample" + ], + [ + "signature-algorithms", + "ed25519:sample" + ], + [ + "digest-algorithms", + "sha256" + ], + [ + "region-measures", + "coordinates|leaves|reads|receipts" + ] + ], + "places": [ + { + "name": "sensor-types", + "options": { + "target": "ES2022", + "strict": "true", + "declaration": "true", + "include": "src/**/*.ts|types/**/*.ts" + } + }, + { + "name": "route-types", + "options": { + "target": "ES2020", + "strict": "false", + "module": "NodeNext", + "include": "lib/**/*.ts" + } + } + ] +} diff --git a/samples/yes/historical-document-views.json b/samples/yes/historical-document-views.json new file mode 100644 index 0000000..6cab0ff --- /dev/null +++ b/samples/yes/historical-document-views.json @@ -0,0 +1,191 @@ +{ + "profile": "topos-doc-historical@0.1.2", + "providerSource": "// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/values.js\nfunction unpipe(value2) {\n const out = [];\n let at = \"\";\n for (let i = 0; i < value2.length; i++) {\n const c = value2[i];\n if (c === \"\\\\\") {\n const next = value2[i + 1];\n if (next !== \"|\" && next !== \"\\\\\")\n return null;\n at += next;\n i += 1;\n } else if (c === \"|\") {\n out.push(at);\n at = \"\";\n } else {\n at += c;\n }\n }\n out.push(at);\n return out;\n}\nvar OPEN = \"*\";\nvar num = (s) => {\n if (!/^-?\\d+(\\.\\d+)?$/.test(s))\n return null;\n const n = Number(s);\n return isFinite(n) ? n : null;\n};\nvar GRAMMARS = {\n interval: (value2) => {\n const at = value2.indexOf(\"..\");\n if (at < 0)\n return null;\n const lo = value2.slice(0, at);\n const hi = value2.slice(at + 2);\n const l = lo === OPEN ? null : num(lo);\n const h = hi === OPEN ? null : num(hi);\n if (lo !== OPEN && l === null || hi !== OPEN && h === null)\n return null;\n return { kind: \"interval\", lo: l, hi: h };\n },\n alphabet: (value2) => {\n const values = unpipe(value2);\n return values === null ? null : { kind: \"enumerated\", values };\n },\n ladder: (value2) => {\n const parts2 = unpipe(value2);\n if (parts2 === null || parts2.length !== 2)\n return null;\n return { kind: \"band\", floor: parts2[0] ?? \"\", ceiling: parts2[1] ?? \"\" };\n }\n};\nfunction boundOf(form2, value2, grammars) {\n const extra = Array.isArray(grammars) ? grammars.find((g) => g.form === form2) : void 0;\n if (extra)\n return extra.parse(value2);\n return GRAMMARS[form2]?.(value2) ?? null;\n}\nvar BOUND_FORMS = Object.keys(GRAMMARS);\nvar REF_RELATIONS = [\"within\", \"copies\", \"derives\"];\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/grammar.js\nvar [FORBID, EMPTY, MEMBER, PAIR, STEP, AT, EVERY, ESCAPE] = [\"not:\", \"none\", \"|\", \"=\", \"/\", \"@\", \"*\", \"\\\\\"];\nvar refuse = (grammar, why) => {\n throw new Error(`REFUSE\\xB7wire ${grammar}: ${why}`);\n};\nvar digits = (text) => text !== \"\" && [...text].every((one) => one >= \"0\" && one <= \"9\");\nfunction alphabet(given) {\n if (typeof given !== \"string\") {\n const written = given.members.map((one) => one.split(ESCAPE).join(ESCAPE + ESCAPE).split(MEMBER).join(ESCAPE + MEMBER)).join(MEMBER);\n if (given.polarity === \"forbid\")\n return FORBID + written;\n return written.startsWith(FORBID) || written === EMPTY ? refuse(\"alphabet\", \"a permitted alphabet neither begins with not: nor is the one word none\") : written || EMPTY;\n }\n const forbid = given.startsWith(FORBID);\n const body = forbid ? given.slice(FORBID.length) : given;\n const members = !forbid && body === EMPTY ? [] : unpipe(body) ?? refuse(\"alphabet\", \"a backslash escapes only a pipe or itself\");\n return { polarity: forbid ? \"forbid\" : \"permit\", members: members.filter((one) => one !== \"\") };\n}\nfunction fields(given) {\n if (typeof given !== \"string\")\n return alphabet({ polarity: \"permit\", members: given.map(([key, value2]) => key + PAIR + value2) });\n const read = alphabet(given);\n if (read.polarity === \"forbid\")\n refuse(\"fields\", \"fields carry no polarity\");\n return read.members.map((one) => one.indexOf(PAIR) > 0 ? [one.slice(0, one.indexOf(PAIR)), one.slice(one.indexOf(PAIR) + 1)] : refuse(\"fields\", `\\`${one}\\` is not key=value`));\n}\nfunction steps(given) {\n if (typeof given === \"string\")\n return given.split(STEP);\n return given.some((one) => one.includes(STEP)) ? refuse(\"steps\", \"a step holds no slash\") : given.join(STEP);\n}\nfunction atResolution(given) {\n if (typeof given !== \"string\")\n return given.at === void 0 ? given.name : given.name + AT + String(given.at);\n const at = given.lastIndexOf(AT);\n if (at < 0)\n return { name: given };\n const [name, said] = [given.slice(0, at), given.slice(at + 1)];\n if (name === \"\" || said !== EVERY && !digits(said))\n refuse(\"atResolution\", `\\`${given}\\` is not name@digits or name@*`);\n return { name, at: said === EVERY ? EVERY : Number(said) };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/capsule/asked.js\nvar of = (line, field) => line?.[field] ?? \"\";\nvar found = (asked, scope) => asked.lines.find((line) => of(line, \"scope\") === scope);\nvar value = (asked, scope) => found(asked, scope) === void 0 ? void 0 : of(found(asked, scope), \"value\");\nvar listed = (asked, scope) => alphabet(value(asked, scope) ?? \"\").members;\nvar lang = (asked) => value(asked, \"lang\") ?? \"\";\nvar receipts = (asked, region) => asked.regions[region]?.receipts ?? [];\nvar placeOf = (line) => of(line, \"at\").replace(/^[^:]*:/, \"\");\nvar regionLines = (asked, region) => asked.regions[region]?.lines ?? [];\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/classes.js\nfunction matchStar(pat, seg) {\n if (!pat.includes(\"*\"))\n return pat === seg;\n const bits = pat.split(\"*\");\n if (!seg.startsWith(bits[0]))\n return false;\n let i = bits[0].length;\n for (let b = 1; b < bits.length; b++) {\n const bit = bits[b];\n if (bit === \"\")\n return b === bits.length - 1 || matchStar(bits.slice(b).join(\"*\"), seg.slice(i));\n const hit = seg.indexOf(bit, i);\n if (hit < 0)\n return false;\n i = hit + bit.length;\n }\n return i === seg.length || pat.endsWith(\"*\");\n}\nfunction matchParts(g, gi, p, pi) {\n if (gi === g.length)\n return pi === p.length;\n if (g[gi] === \"**\") {\n if (gi + 1 === g.length)\n return true;\n for (let k = pi; k <= p.length; k++) {\n if (matchParts(g, gi + 1, p, k))\n return true;\n }\n return false;\n }\n if (pi === p.length)\n return false;\n if (!matchStar(g[gi], p[pi]))\n return false;\n return matchParts(g, gi + 1, p, pi + 1);\n}\nfunction matches(glob, place) {\n return matchParts(glob.split(\"/\"), 0, place.split(\"/\"), 0);\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/outcome.js\nvar fact = (value2) => ({ kind: \"fact\", value: value2 });\nvar abstain = (why) => ({ kind: \"abstain\", why });\nvar refuse2 = (why, named) => ({ kind: \"refuse\", why, ...named === void 0 ? {} : { named } });\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/line.js\nvar PROTOCOL = \"bound-lock/1\";\nvar NEEDS_QUOTE = /[ =\"\\n\\\\]/;\nfunction escape(value2) {\n if (!NEEDS_QUOTE.test(value2))\n return value2;\n return `\"${value2.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\"`;\n}\nfunction unescape(token) {\n if (!token.startsWith('\"'))\n return NEEDS_QUOTE.test(token) ? null : token;\n if (token.length < 2 || !token.endsWith('\"'))\n return null;\n const body = token.slice(1, -1);\n let out = \"\";\n for (let i = 0; i < body.length; i++) {\n const c = body[i];\n if (c !== \"\\\\\") {\n if (c === '\"')\n return null;\n out += c;\n continue;\n }\n const next = body[i + 1];\n if (next === '\"')\n out += '\"';\n else if (next === \"\\\\\")\n out += \"\\\\\";\n else if (next === \"n\")\n out += \"\\n\";\n else\n return null;\n i += 1;\n }\n return out;\n}\nvar UTF8 = new TextEncoder();\nfunction byBytes(a, b) {\n const x = UTF8.encode(a);\n const y = UTF8.encode(b);\n for (let i = 0; i < x.length && i < y.length; i++) {\n if (x[i] !== y[i])\n return x[i] - y[i];\n }\n return x.length - y.length;\n}\nvar unwritten = (fields2) => fields2[\"form\"] === \"interval\" && fields2[\"value\"] !== void 0 && fields2[\"value\"] !== \"withdraw\" && boundOf(\"interval\", fields2[\"value\"]) === null;\nfunction canonical(fields2, version = \"1\") {\n if (unwritten(fields2))\n throw new Error(`REFUSE\\xB7wire canonical: \\`${fields2[\"value\"]}\\` is no interval the wire writes: two ends, each decimal or *`);\n const keys2 = Object.keys(fields2).sort(byBytes);\n const tokens = keys2.map((k) => `${k}=${escape(fields2[k])}`);\n return [`${PROTOCOL.split(\"/\")[0]}/${version}`, ...tokens].join(\" \");\n}\nvar ABSENT = \"-\";\nfunction parse(text) {\n if (text.includes(\"\\n\")) {\n return refuse2(\"a line is one line \\u2014 a newline in a value must be escaped as `\\\\n`\");\n }\n const space = text.indexOf(\" \");\n const envelope = space === -1 ? text : text.slice(0, space);\n const [name, version] = envelope.split(\"/\");\n if (name !== PROTOCOL.split(\"/\")[0] || !version) {\n return refuse2(`no \\`bound-lock/\\` envelope \\u2014 found \\`${envelope.slice(0, 24)}\\``);\n }\n if (version !== PROTOCOL.split(\"/\")[1]) {\n return abstain(`\\`bound-lock/${version}\\` is a version this reader does not know`);\n }\n const fields2 = {};\n for (const token of tokensOf(space === -1 ? \"\" : text.slice(space + 1))) {\n if (token === null)\n return refuse2(\"a quoted value is not closed\");\n const at = token.indexOf(\"=\");\n if (at <= 0)\n return refuse2(`\\`${token.slice(0, 24)}\\` is not \\`key=value\\``);\n const key = token.slice(0, at);\n if (key in fields2)\n return refuse2(`\\`${key}\\` appears twice \\u2014 one line, one value per key`);\n const value2 = unescape(token.slice(at + 1));\n if (value2 === null)\n return refuse2(`\\`${key}\\` has an escaping this format does not define`);\n if (value2 !== ABSENT)\n fields2[key] = value2;\n }\n if (unwritten(fields2))\n return refuse2(`\\`${fields2[\"value\"]}\\` is no interval the wire reads: two ends, each decimal or *`);\n return fact({ version, fields: fields2 });\n}\nfunction* tokensOf(rest) {\n let at = 0;\n while (at < rest.length) {\n while (rest[at] === \" \")\n at += 1;\n if (at >= rest.length)\n return;\n let end = at;\n let quoted = false;\n while (end < rest.length && (quoted || rest[end] !== \" \")) {\n if (rest[end] === \"\\\\\" && quoted)\n end += 1;\n else if (rest[end] === '\"')\n quoted = !quoted;\n end += 1;\n }\n if (quoted) {\n yield null;\n return;\n }\n yield rest.slice(at, end);\n at = end;\n }\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/capsule/declaration.js\nvar standing = (lines) => lines.flatMap((line) => {\n const got = parse(line);\n return got.kind === \"fact\" && got.value.fields[\"value\"] !== \"withdraw\" ? [got.value.fields] : [];\n});\nfunction handed(reads, lines) {\n return standing(lines).filter((fields2) => reads.some((region) => matches(region, fields2[\"scope\"] ?? \"\")));\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/capsule/shell.js\nfunction shell(regions) {\n return typeof regions === \"string\" ? located(regions) : dispatch(regions, \"renders\");\n}\nvar dispatch = (regions, verb) => (asked) => {\n const one = regions[asked.region];\n if (one === void 0)\n throw new Error(`REFUSE\\xB7region ${asked.region}: no line of this capsule ${verb} it`);\n const short = one.reads.filter((read) => !asked.reads.includes(read));\n if (short.length)\n throw new Error(`REFUSE\\xB7region ${asked.region}: handed less than it declares, without ${short.join(\" \\xB7 \")}`);\n return one.region(asked);\n};\nvar located = (url) => Object.assign(() => {\n throw new Error(`REFUSE\\xB7world ${url}: its host answers it by the regions its own lock names`);\n}, { world: url });\nvar counted = (asked, what, n, measure) => [{ scope: `${asked.region}/${what}`, measure, role: \"reads\", bound: { kind: \"interval\", lo: n, hi: n } }];\nfunction receiptShell(regions) {\n return typeof regions === \"string\" ? located(regions) : dispatch(regions, \"answers\");\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/errors.js\nvar UnitError = class _UnitError extends Error {\n code;\n detail;\n constructor(code, message, detail = {}) {\n super(message);\n this.name = \"UnitError\";\n this.code = code;\n this.detail = Object.freeze({ ...detail });\n Object.setPrototypeOf(this, _UnitError.prototype);\n }\n};\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/order.js\nfunction build(levels, join, meet2) {\n const n = levels.length;\n for (let i = 0; i < n; i++) {\n if (levels.indexOf(levels[i]) !== i) {\n throw new UnitError(\"DUPLICATE_LEVEL\", `the level \\`${levels[i]}\\` is declared twice`, {\n level: levels[i]\n });\n }\n }\n const index = new Map(levels.map((l, i) => [l, i]));\n const leq = (a, b) => join[a][b] === b;\n const total = levels.every((_, i) => levels.every((__, j) => join[i][j] === i || join[i][j] === j));\n let simple = true;\n for (let x = 0; x < n && simple; x++) {\n for (let y = 0; y < n && simple; y++) {\n for (let z = 0; z < n; z++) {\n if (meet2[x][join[y][z]] !== join[meet2[x][y]][meet2[x][z]]) {\n simple = false;\n break;\n }\n }\n }\n }\n const all = [...levels.keys()];\n const bottomIx = all.find((i) => all.every((j) => leq(i, j))) ?? 0;\n const topIx = all.find((i) => all.every((j) => leq(j, i))) ?? n - 1;\n const joinIrr = all.filter((j) => j !== bottomIx && all.filter((x) => x !== j && leq(x, j)).reduce((acc, x) => join[acc][x], bottomIx) !== j);\n const meetIrr = all.filter((m) => m !== topIx && all.filter((x) => x !== m && leq(m, x)).reduce((acc, x) => meet2[acc][x], topIx) !== m);\n const seen = /* @__PURE__ */ new Set();\n const allDebits = [];\n for (const x of [...joinIrr, ...meetIrr]) {\n if (!seen.has(x)) {\n seen.add(x);\n allDebits.push(x);\n }\n }\n return {\n levels,\n isLadder: total,\n isSimple: simple,\n bottomIx,\n topIx,\n bottom: levels[bottomIx],\n top: levels[topIx],\n leq,\n higher: (a, b) => join[a][b],\n lower: (a, b) => meet2[a][b],\n rank(level) {\n const r = index.get(level);\n if (r === void 0) {\n throw new UnitError(\"UNKNOWN_LEVEL\", `no level \\`${level}\\` in this scale`, {\n level,\n levels\n });\n }\n return r;\n },\n stateOf(floor, ceiling) {\n if (!leq(floor, ceiling))\n return \"CONFLICT\";\n if (floor !== bottomIx)\n return \"REQUIRED\";\n if (ceiling !== topIx)\n return \"FORBIDDEN\";\n return \"FREE\";\n },\n joins: () => joinIrr.slice(),\n limits: () => meetIrr.slice(),\n debits: () => allDebits.slice(),\n intervalHeight(lo, hi) {\n if (!leq(lo, hi))\n return null;\n const inside = all.filter((x) => leq(lo, x) && leq(x, hi));\n const covers = (x) => inside.filter((y) => y !== x && leq(x, y) && !inside.some((z) => z !== x && z !== y && leq(x, z) && leq(z, y)));\n const long = /* @__PURE__ */ new Map([[lo, 0]]);\n const short = /* @__PURE__ */ new Map([[lo, 0]]);\n const walk = [...inside].sort((a, b) => inside.filter((z) => leq(z, a)).length - inside.filter((z) => leq(z, b)).length);\n for (const x of walk) {\n const lx = long.get(x);\n const sx = short.get(x);\n if (lx === void 0 || sx === void 0)\n continue;\n for (const y of covers(x)) {\n long.set(y, Math.max(long.get(y) ?? lx + 1, lx + 1));\n short.set(y, Math.min(short.get(y) ?? sx + 1, sx + 1));\n }\n }\n const l = long.get(hi);\n return l !== void 0 && l === short.get(hi) ? l : null;\n }\n };\n}\nfunction chain(levels) {\n if (!Array.isArray(levels) || levels.length === 0) {\n throw new UnitError(\"EMPTY_CHAIN\", \"a chain needs at least one level\");\n }\n const n = levels.length;\n const grid = (f) => [...Array(n)].map((_, i) => [...Array(n)].map((__, j) => f(i, j)));\n return build(levels, grid(Math.max), grid(Math.min));\n}\nfunction order(levels, leq) {\n if (!Array.isArray(levels) || levels.length === 0) {\n throw new UnitError(\"EMPTY_CHAIN\", \"an order needs at least one level\");\n }\n const n = levels.length;\n const bound = (a, b, up) => {\n const bs = [...Array(n).keys()].filter((x) => up ? leq[a][x] && leq[b][x] : leq[x][a] && leq[x][b]);\n const least = bs.filter((x) => bs.every((y) => up ? leq[x][y] : leq[y][x]));\n if (least.length !== 1) {\n throw new UnitError(\"MALFORMED\", `\\`${levels[a]}\\` and \\`${levels[b]}\\` have ${least.length} ${up ? \"lowest common\" : \"highest common\"} bounds, so this is not a usable scale`, { levels: [levels[a], levels[b]] });\n }\n return least[0];\n };\n const grid = (up) => [...Array(n)].map((_, i) => [...Array(n)].map((__, j) => bound(i, j, up)));\n return build(levels, grid(true), grid(false));\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/debit/unit.js\nfunction unit(subject, bounds) {\n return { subject, floor: bounds.floor, ceiling: bounds.ceiling };\n}\nvar permitAll = (c, subject) => unit(subject, { floor: c.bottom, ceiling: c.top });\nfunction state(c, u) {\n return c.stateOf(c.rank(u.floor), c.rank(u.ceiling));\n}\nfunction band(c, units, from, onFloor, onCeiling) {\n let floor = from.floor;\n let ceiling = from.ceiling;\n for (const u of units) {\n floor = onFloor(floor, c.rank(u.floor));\n ceiling = onCeiling(ceiling, c.rank(u.ceiling));\n }\n return { subject: units[0].subject, floor: c.levels[floor], ceiling: c.levels[ceiling] };\n}\nfunction fuse(c, units) {\n if (units.length === 0)\n return permitAll(c, \"\");\n return band(c, units, { floor: c.bottomIx, ceiling: c.topIx }, (a, b) => c.higher(a, b), (a, b) => c.lower(a, b));\n}\nfunction entails(c, a, b) {\n const [af, ac] = [c.rank(a.floor), c.rank(a.ceiling)];\n const [bf, bc] = [c.rank(b.floor), c.rank(b.ceiling)];\n return c.leq(bf, af) && c.leq(ac, bc);\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/debit/packed.js\nvar WIDTH = 32;\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/debit/masks.js\nfunction chunkCount(n) {\n if (n <= 0)\n return 0;\n return Math.ceil(n / WIDTH);\n}\nvar WideMask = class _WideMask {\n words;\n width;\n constructor(width, words2) {\n this.width = width;\n this.words = words2 ?? new Uint32Array(chunkCount(width));\n }\n static fromTokens(tokens, allowed) {\n const m = new _WideMask(tokens.length);\n tokens.forEach((t, i) => {\n if (allowed.has(t))\n m.set(i);\n });\n return m;\n }\n set(bit) {\n if (bit < 0 || bit >= this.width) {\n throw new UnitError(\"MALFORMED\", `bit ${bit} is outside a mask of width ${this.width}`, {\n bit,\n width: this.width\n });\n }\n this.words[bit >> 5] |= 1 << (bit & 31);\n }\n has(bit) {\n if (bit < 0 || bit >= this.width)\n return false;\n return (this.words[bit >> 5] & 1 << (bit & 31)) !== 0;\n }\n and(other) {\n const w = Math.max(this.width, other.width);\n const out = new _WideMask(w);\n const n = Math.min(this.words.length, other.words.length);\n for (let i = 0; i < n; i++)\n out.words[i] = this.words[i] & other.words[i];\n return out;\n }\n or(other) {\n const w = Math.max(this.width, other.width);\n const out = new _WideMask(w);\n for (let i = 0; i < out.words.length; i++) {\n out.words[i] = (this.words[i] ?? 0) | (other.words[i] ?? 0);\n }\n return out;\n }\n difference(other) {\n const w = Math.max(this.width, other.width);\n const out = new _WideMask(w);\n for (let i = 0; i < out.words.length; i++) {\n out.words[i] = (this.words[i] ?? 0) & ~(other.words[i] ?? 0);\n }\n const spare = w % 32;\n if (spare !== 0 && out.words.length > 0) {\n out.words[out.words.length - 1] &= (1 << spare) - 1;\n }\n return out;\n }\n subsetOf(other) {\n const n = Math.max(this.words.length, other.words.length);\n for (let i = 0; i < n; i++) {\n const a = this.words[i] ?? 0;\n const b = other.words[i] ?? 0;\n if ((a & ~b) !== 0)\n return false;\n }\n return true;\n }\n size() {\n let n = 0;\n for (let i = 0; i < this.width; i++)\n if (this.has(i))\n n++;\n return n;\n }\n members(tokens) {\n return tokens.filter((_, i) => this.has(i));\n }\n static filled(width) {\n const m = new _WideMask(width);\n if (width <= 0)\n return m;\n m.words.fill(4294967295);\n const spare = width % 32;\n if (spare !== 0)\n m.words[m.words.length - 1] = (1 << spare) - 1;\n return m;\n }\n};\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/scale-lattice.js\nfunction fromScale(c) {\n const inhabited = (x) => state(c, x) !== \"CONFLICT\";\n return {\n top: permitAll(c, \"\"),\n bottom: { subject: \"\", floor: c.levels[c.topIx] ?? \"\", ceiling: c.levels[c.bottomIx] ?? \"\" },\n leq: (a, b) => entails(c, a, b),\n meet: (a, b) => fuse(c, [a, b]),\n join: (a, b) => {\n if (!inhabited(a))\n return b;\n if (!inhabited(b))\n return a;\n return {\n subject: a.subject || b.subject,\n floor: c.levels[c.lower(c.rank(a.floor), c.rank(b.floor))] ?? a.floor,\n ceiling: c.levels[c.higher(c.rank(a.ceiling), c.rank(b.ceiling))] ?? a.ceiling\n };\n },\n show: (x) => `[${x.floor}, ${x.ceiling}]`,\n inhabited\n };\n}\nfunction subsets(tokens) {\n return {\n bottom: new WideMask(tokens.length),\n top: WideMask.filled(tokens.length),\n leq: (a, b) => a.subsetOf(b),\n meet: (a, b) => a.and(b),\n join: (a, b) => a.or(b),\n show: (x) => x.members(tokens).join(\",\"),\n inhabited: (x) => x.size() > 0\n };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/forms.js\nfunction intervals(lo, hi) {\n const low = Math.min(lo, hi);\n const high = Math.max(lo, hi);\n return {\n bottom: { lo: high, hi: low },\n top: { lo: low, hi: high },\n leq(a, b) {\n if (a.lo > a.hi)\n return true;\n if (b.lo > b.hi)\n return false;\n return b.lo <= a.lo && a.hi <= b.hi;\n },\n meet(a, b) {\n return { lo: Math.max(a.lo, b.lo), hi: Math.min(a.hi, b.hi) };\n },\n join(a, b) {\n if (a.lo > a.hi)\n return b;\n if (b.lo > b.hi)\n return a;\n return { lo: Math.min(a.lo, b.lo), hi: Math.max(a.hi, b.hi) };\n },\n show(x) {\n return x.lo > x.hi ? \"empty\" : `${x.lo}..${x.hi}`;\n },\n inhabited(x) {\n return x.lo <= x.hi;\n }\n };\n}\nfunction form(f) {\n const held = { lattice: f.lattice, parse: f.parse, emit: f.emit, count: f.count, show: f.show, points: f.points };\n const lacking = Object.entries(held).find(([, fn]) => typeof fn !== \"function\");\n if (lacking)\n throw new Error(`form \\`${f.id}\\` declared no ${lacking[0]}`);\n return f;\n}\nvar rec = (x) => x !== null && typeof x === \"object\" ? x : {};\nfunction strings(x) {\n return Array.isArray(x) ? x.map(String) : [];\n}\nvar drawn = (seed) => {\n let s = seed >>> 0;\n return () => {\n s = s + 1831565813 >>> 0;\n let t = Math.imul(s ^ s >>> 15, s | 1);\n t ^= t + Math.imul(t ^ t >>> 7, t | 61);\n return ((t ^ t >>> 14) >>> 0) / 4294967296;\n };\n};\nvar picked = (draw, xs) => xs[Math.floor(draw() * xs.length)];\nfunction bandCount(levels, folded) {\n if (levels.length === 0)\n return { kind: \"refused\", why: \"a ladder with no levels cannot be counted\" };\n const c = chain(levels);\n const f = c.rank(folded.floor);\n const cl = c.rank(folded.ceiling);\n if (!c.leq(f, cl))\n return { kind: \"finite\", n: 0 };\n const n = levels.filter((_, i) => c.leq(f, i) && c.leq(i, cl)).length;\n return { kind: \"finite\", n };\n}\nvar BAND = {\n parse(params, demand) {\n const L = this.lattice(params);\n const d = rec(demand);\n return {\n subject: String(d.subject ?? \"\"),\n floor: String(d.floor ?? L.top.floor),\n ceiling: String(d.ceiling ?? L.top.ceiling)\n };\n },\n emit(_params, value2) {\n return { subject: value2.subject, floor: value2.floor, ceiling: value2.ceiling };\n },\n count(folded, params) {\n return bandCount(strings(rec(params).levels), folded);\n },\n points(params, seed, n) {\n const L = this.lattice(params);\n const levels = strings(rec(params).levels);\n const draw = drawn(seed);\n const band2 = (floor, ceiling) => ({ subject: \"\", floor, ceiling });\n return Array.from({ length: n }, () => {\n const [a, b] = [picked(draw, levels), picked(draw, levels)];\n return [band2(a, b), band2(b, a)].find((x) => L.inhabited(x)) ?? band2(a, a);\n });\n }\n};\nvar ladderForm = form({\n id: \"ladder\",\n lattice(params) {\n const levels = strings(rec(params).levels);\n if (levels.length === 0)\n throw new Error(\"ladder needs levels\");\n return fromScale(chain(levels));\n },\n ...BAND,\n show(value2) {\n return value2.floor === value2.ceiling ? value2.floor : `${value2.floor}..${value2.ceiling}`;\n }\n});\nvar alphabetForm = form({\n id: \"alphabet\",\n lattice(params) {\n return subsets(strings(rec(params).tokens));\n },\n parse(params, demand) {\n const tokens = strings(rec(params).tokens);\n const d = rec(demand);\n const want = d.want !== void 0 ? strings(d.want) : tokens;\n return WideMask.fromTokens(tokens, new Set(want));\n },\n emit(params, value2) {\n return { want: value2.members(strings(rec(params).tokens)) };\n },\n count(folded) {\n return { kind: \"finite\", n: folded.size() };\n },\n show(value2) {\n return `${value2.size()}`;\n },\n points(params, seed, n) {\n const tokens = strings(rec(params).tokens);\n const draw = drawn(seed);\n return Array.from({ length: n }, () => WideMask.fromTokens(tokens, new Set(tokens.filter(() => draw() < 0.5))));\n }\n});\nvar continuousForm = form({\n id: \"continuous\",\n lattice(params) {\n const p = rec(params);\n return intervals(Number(p.lo ?? 0), Number(p.hi ?? 1));\n },\n parse(params, demand) {\n const L = this.lattice(params);\n const d = rec(demand);\n return {\n lo: d.lo === void 0 ? L.top.lo : Number(d.lo),\n hi: d.hi === void 0 ? L.top.hi : Number(d.hi)\n };\n },\n emit(_params, value2) {\n return { lo: value2.lo, hi: value2.hi };\n },\n count() {\n return { kind: \"refused\", why: \"a continuous band has no count; prefer not to exist over inventing one\" };\n },\n show(value2) {\n return value2.lo > value2.hi ? \"empty\" : `${value2.lo}..${value2.hi}`;\n },\n points(params, seed, n) {\n const p = rec(params);\n const lo = Number(p.lo ?? 0);\n const hi = Number(p.hi ?? 1);\n const draw = drawn(seed);\n const at = () => lo + Math.round(draw() * (hi - lo));\n return Array.from({ length: n }, () => ({ lo: at(), hi: at() }));\n }\n});\nvar latticeForm = form({\n id: \"lattice\",\n lattice(params) {\n const p = rec(params);\n const levels = strings(p.levels);\n const leq = p.leq;\n if (levels.length && leq)\n return fromScale(order(levels, leq));\n throw new Error(\"lattice needs levels+leq\");\n },\n ...BAND,\n show(value2) {\n return `${value2.floor}..${value2.ceiling}`;\n }\n});\nvar FORM_IMPLEMENTATIONS = [ladderForm, alphabetForm, continuousForm, latticeForm];\nvar FORMS = [...FORM_IMPLEMENTATIONS];\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/field.js\nfunction coordinate(name, steps2 = \"/\") {\n const at = name.split(new RegExp(`[${steps2.replace(/[.*+?^${}()|[\\]\\\\-]/g, \"\\\\$&\")}]`)).filter((s) => s !== \"\");\n while (at[at.length - 1] === \"*\" || at[at.length - 1] === \"**\")\n at.pop();\n return at;\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/obligatory.js\nfunction cell(at, epoch = 0, seen = [], restsOn2 = []) {\n return { at: coordinate(at), epoch, seen, restsOn: restsOn2 };\n}\nfunction live(lines) {\n const taken = new Set(lines.flatMap((line) => line.takes === void 0 ? [] : [line.takes]));\n return lines.filter((line) => line.takes === void 0 && (line.id === void 0 || !taken.has(line.id)));\n}\nfunction restOf(c, world = /* @__PURE__ */ new Map()) {\n const own = c.at.join(\"/\");\n const out = [];\n const held = /* @__PURE__ */ new Set();\n const edge = [...c.restsOn];\n for (let i = 0; i < edge.length; i += 1) {\n const name = edge[i];\n if (name === own)\n throw new UnitError(\"rest-cycle\", `obligations: REFUSE\\xB7rest ${own} rests on itself: an order of rest with a cycle has no fold to reach`, { at: own });\n if (held.has(name))\n continue;\n held.add(name);\n out.push(name);\n edge.push(...world.get(name)?.restsOn ?? []);\n }\n return out;\n}\nfunction parts(L, c, world = /* @__PURE__ */ new Map()) {\n const rest = restOf(c, world);\n const above = rest.flatMap((name) => live(world.get(name)?.marks ?? []).filter((one) => one.reach === \"travels\" && one.widens === void 0));\n const marks = [...live(c.marks ?? []), ...above].sort((a, b) => (a.at ?? 0) - (b.at ?? 0));\n let required = L.top;\n let signed = L.top;\n for (const one of marks) {\n if (one.pole === \"floor\")\n required = L.meet(required, one.span);\n else\n signed = one.widens === void 0 ? L.meet(signed, one.span) : L.join(signed, one.span);\n }\n const origins2 = live(c.seen);\n const held = origins2.reduce((acc, claim) => L.meet(acc, claim.span), L.top);\n return { floor: L.meet(required, held), ceiling: L.meet(signed, held), origins: origins2, rest, required, signed };\n}\nfunction state2(L, c, world = /* @__PURE__ */ new Map()) {\n const { floor, ceiling, origins: origins2, required, signed } = parts(L, c, world);\n if (!L.inhabited(L.meet(required, signed)))\n return \"CONFLICT\";\n if (new Set(origins2.map((claim) => claim.origin)).size < 2)\n return \"REQUIRED\";\n if (!L.inhabited(origins2.reduce((acc, claim) => L.meet(acc, claim.span), L.top)))\n return \"CONFLICT\";\n return L.inhabited(L.meet(floor, ceiling)) ? \"FREE\" : \"FORBIDDEN\";\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/meet.js\nfunction meet(L, c, world = /* @__PURE__ */ new Map()) {\n const { floor, ceiling } = parts(L, c, world);\n return L.meet(floor, ceiling);\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/encounter.js\nfunction encounter(L, c, world = /* @__PURE__ */ new Map()) {\n return { origins: new Set(live(c.seen).map((claim) => claim.origin)).size, held: meet(L, c, world) };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/sig.js\nfunction parseSignature(value2) {\n const colon = value2.lastIndexOf(\":\");\n if (colon <= 0 || colon === value2.length - 1)\n return null;\n return { algorithm: value2.slice(0, colon), raw: value2.slice(colon + 1) };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/claimline.js\nvar WITHDRAW = \"withdraw\";\nfunction admittedDigest(value2, wire) {\n const colon = value2.indexOf(\":\");\n return colon > 0 && wire.digests.has(value2.slice(0, colon)) && /^[0-9a-f]+$/i.test(value2.slice(colon + 1));\n}\nfunction isRegion(need) {\n if (need.startsWith(\"/\") || /[\\s\\\\]/.test(need))\n return false;\n const steps2 = need.split(\"/\").filter((step) => step !== \"\");\n return steps2.length > 0 && steps2.every((step, i) => step !== \".\" && step !== \"..\" && (!step.includes(\"*\") || i === steps2.length - 1));\n}\nvar FIELD_FORMS = {\n region: (value2) => value2.split(\"|\").filter(Boolean).every(isRegion),\n class: (value2, wire) => {\n const colon = value2.indexOf(\":\");\n if (colon <= 0 || !wire.classes.has(value2.slice(0, colon)))\n return false;\n const rest = value2.slice(colon + 1);\n return !/^[a-z0-9-]+:[0-9a-f]{16,}$/i.test(rest) || admittedDigest(rest, wire);\n },\n signature: (value2, wire) => {\n const got = parseSignature(value2);\n if (got === null || !wire.signatures.has(got.algorithm))\n return false;\n const era = got.algorithm.slice(got.algorithm.lastIndexOf(\":\") + 1);\n return admittedDigest(got.algorithm, wire) || got.algorithm.includes(\":\") && (wire.lists.get(\"era\")?.has(era) ?? false);\n },\n count: (value2) => /^\\d+$/.test(value2)\n};\nfunction debit(field, why) {\n return refuse2(why, field);\n}\nfunction fromLine(text, wire, grammars) {\n const line = parse(text);\n if (line.kind !== \"fact\") {\n return line.kind === \"abstain\" ? abstain(line.why) : refuse2(line.why, line.named);\n }\n const f = line.value.fields;\n if (wire) {\n for (const k of Object.keys(f))\n if (!wire.fields.has(k))\n return debit(k, `\\`${k}=\\` is not a field of the wire at epoch ${wire.epoch}`);\n for (const k of wire.required)\n if (f[k] === void 0)\n return debit(k, `a claim with no \\`${k}\\``);\n for (const [k, form2] of wire.formOf) {\n const v = f[k];\n if (v === void 0)\n continue;\n const ids = wire.lists.get(form2);\n const reads = FIELD_FORMS[form2] ?? (ids ? (value2) => ids.has(value2) : void 0);\n if (!reads)\n return abstain(`\\`${k}\\` takes the form ${form2}, which this reader does not know`);\n if (!reads(v, wire))\n return debit(k, `\\`${k}=${v}\\` is not a ${form2} of the wire at epoch ${wire.epoch}`);\n }\n if (f.role !== void 0 && !wire.roles.has(f.role))\n return abstain(`\\`role=${f.role}\\` is a role this wire does not name`);\n if (!wire.forms.has(f.form ?? \"\"))\n return abstain(`\\`form=${f.form}\\` is a form this wire does not name`);\n }\n const listed2 = Array.isArray(grammars) ? grammars : void 0;\n const bound = f.value === WITHDRAW ? { kind: \"enumerated\", values: [WITHDRAW] } : boundOf(f.form ?? \"\", f.value ?? \"\", listed2);\n if (bound === null) {\n const mine = BOUND_FORMS.includes(f.form ?? \"\") || (listed2?.some((g) => g.form === f.form) ?? false);\n return mine ? debit(\"value\", `\\`${f.value}\\` is not a ${f.form}`) : abstain(`\\`form=${f.form}\\` is a form this reader does not know`);\n }\n const role = f.role === \"writes\" ? \"writes\" : f.role === \"demands\" ? \"demands\" : \"reads\";\n const extra = {};\n for (const [k, v] of Object.entries(f)) {\n if ([\"scope\", \"measure\", \"form\", \"value\", \"by\", \"at\", \"role\", \"unit\", \"multiplicity\", \"epoch\", \"ref\", \"to\", \"ref_by\"].includes(k))\n continue;\n extra[k] = v;\n }\n const rel = f.ref;\n const to = f.to === void 0 ? null : unpipe(f.to);\n const reference = rel && to && REF_RELATIONS.includes(rel) ? { rel, to, by: f.ref_by === \"declared\" ? \"declared\" : \"inferred\" } : null;\n return fact({\n scope: f.scope ?? \"\",\n measure: f.measure ?? \"\",\n bound,\n role,\n by: f.by ?? \"\",\n at: f.at ?? \"\",\n ...f.unit !== void 0 ? { unit: f.unit } : {},\n ...f.multiplicity === \"one\" || f.multiplicity === \"many\" || f.multiplicity === \"unknown\" ? { multiplicity: f.multiplicity } : {},\n ...f.epoch !== void 0 ? { epoch: f.epoch } : {},\n ...reference ? { reference } : {},\n extra\n });\n}\nvar EPOCHS = intervals(-Infinity, Infinity);\nvar QUORUMS = intervals(1, Infinity);\n\n// ../provider-closure/world/dist/helpers/asked.js\nvar pairs = (asked, scope) => fields(value(asked, scope) ?? \"\");\nvar receiptLine = (asked, region, scope, place, measure) => receipts(asked, region).find((line) => of(line, \"scope\") === scope && (place === void 0 || placeOf(line) === place) && (measure === void 0 || of(line, \"measure\") === measure));\nvar receiptValue = (asked, region, scope, place, measure) => ((line) => line === void 0 ? void 0 : of(line, \"value\"))(receiptLine(asked, region, scope, place, measure));\nvar numeral = (said) => {\n const read = (value2) => {\n try {\n const got = fromLine(canonical({ at: \"place:numeral\", by: \"reader\", form: \"interval\", measure: \"count\", role: \"reads\", scope: \"numeral\", value: value2 }), null);\n return got.kind === \"fact\" && got.value.bound.kind === \"interval\" ? got.value.bound.lo ?? void 0 : void 0;\n } catch {\n return void 0;\n }\n };\n return said === void 0 ? NaN : read(said) ?? read(`${said}..${said}`) ?? NaN;\n};\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/observe.js\nfunction observe(c, claim, s = claim.takes === void 0 ? 1 : -1) {\n const takes = s === 1 ? void 0 : claim.takes ?? claim.id;\n if (s === 1 && claim.takes !== void 0)\n throw new UnitError(\"sign-mismatch\", \"obligations: REFUSE\\xB7observe a claim that takes another back is observed at \\u22121, never at +1\");\n if (s === -1 && takes === void 0)\n throw new UnitError(\"withdrawal-unnamed\", \"obligations: REFUSE\\xB7observe a withdrawal names the claim it takes back, never a value that looks like it\");\n const line = takes === void 0 ? claim : { origin: claim.origin, span: claim.span, sign: -1, takes, ...claim.at === void 0 ? {} : { at: claim.at } };\n return { ...c, epoch: Math.max(c.epoch, claim.at ?? c.epoch), seen: [...c.seen, line] };\n}\n\n// ../provider-closure/world/dist/helpers/language.js\nvar rule = (asked, name) => listed(asked, `form/prose/${lang(asked)}/${name}`);\nvar upper = (text) => `${text.charAt(0).toUpperCase()}${text.slice(1)}`;\nvar words = (asked, slug) => rule(asked, \"words\").includes(\"spaces\") ? slug.split(\"-\").join(\" \") : slug;\nvar heading = (asked, slug) => rule(asked, \"heading\").includes(\"capital\") ? upper(words(asked, slug)) : words(asked, slug);\nvar count = (asked, n, first = false) => {\n const word = rule(asked, \"numbers\")[n] ?? String(n);\n return first && rule(asked, \"sentence\").includes(\"capital\") ? upper(word) : word;\n};\nvar listOf = (asked, items) => {\n const [comma = \", \", and = \" and \"] = rule(asked, \"list\");\n return items.length > 1 ? `${items.slice(0, -1).join(comma)}${and}${items[items.length - 1]}` : items.join(\"\");\n};\nvar stated = (asked, state3) => rule(asked, `state/${state3}`)[0] ?? \"\";\nvar prose = (asked, key) => ((line) => line === void 0 ? void 0 : of(line, \"about\"))(found(asked, `prose/${lang(asked)}/${key}`) ?? found(asked, `form/prose/${lang(asked)}/page/${key}`));\nvar fill = (asked, key, text, fields2 = {}) => listed(asked, `form/template/${key}`).reduce((said, field) => said.split(`{${field}}`).join(String(fields2[field] ?? \"\")), text);\nvar say = (asked, key, fields2 = {}) => fill(asked, key, prose(asked, key) ?? \"\", fields2);\nvar sentence = (asked, text) => {\n const said = rule(asked, \"sentence\");\n let end = text.length;\n while (end > 0 && \".;:, \\n\".includes(text.charAt(end - 1)))\n end -= 1;\n const start = said.includes(\"capital\") ? `${text.charAt(0).toUpperCase()}${text.slice(1, end)}` : text.slice(0, end);\n return said.includes(\"period\") ? `${start}.` : start;\n};\nvar parted = (asked, key) => ((said) => said === void 0 ? [] : [said.trim()])(prose(asked, key));\nvar section = (asked, key) => ((said) => said ? [`## ${said}`, \"\"] : [])(prose(asked, `${key}/heading`));\nvar titled = (asked, key, parts2) => parts2.length ? [...section(asked, key), ...parts2.flatMap((part) => [part, \"\"])].slice(0, -1) : [];\n\n// ../provider-closure/world/dist/helpers/laws.js\nvar laws = (asked) => regionLines(asked, \"laws\");\nvar offers = (asked) => regionLines(asked, \"offers\");\nvar lawId = (law) => placeOf(law);\nvar lawKey = (law) => of(law, \"scope\").slice(lawId(law).lastIndexOf(\"/\") + 1);\nvar lawName = (asked, law) => words(asked, of(law, \"scope\").slice(lawId(law).length + 1));\nvar lawAt = (asked, scope) => laws(asked).find((one) => of(one, \"scope\") === scope);\nvar keys = (asked, rested) => alphabet(rested).members.map((scope) => ((law) => law === void 0 ? scope : lawKey(law))(lawAt(asked, scope))).join(\", \");\nvar object = (asked) => lawAt(asked, value(asked, \"notation/object\") ?? \"\");\nvar resting = (asked, scope) => offers(asked).filter((line) => alphabet(of(line, \"restsOn\")).members.includes(scope));\nvar moduleOf = (asked, offer) => alphabet(of(offer, \"needs\")).members.find((need) => receiptValue(asked, \"source\", \"source/carries\", need) !== void 0 || receipts(asked, \"source\").some((one) => placeOf(one) === need));\nvar sample = (asked, law, side) => {\n const family = value(asked, `samples/${side}`);\n const at = family === void 0 ? void 0 : alphabet(of(law, \"needs\")).members.find((need) => need.startsWith(`${family.replace(/\\/$/, \"\")}/`));\n const said = (field) => at === void 0 ? void 0 : receiptValue(asked, \"laws\", `said/${field}`, at);\n return { recorded: at !== void 0 && receipts(asked, \"laws\").some((line) => placeOf(line) === at && of(line, \"scope\").startsWith(\"said/\")), at, about: said(\"about\")?.split(\"\\n\"), title: said(\"title\"), brief: said(\"brief\") };\n};\nvar conjectured = (asked, law) => ((yes, no) => say(asked, \"open/conjecture\", {\n title: yes.title ?? sentence(asked, lawName(asked, law)).slice(0, -1),\n brief: yes.brief ?? of(law, \"about\"),\n breaks: no.brief ?? (no.about ?? [])[0] ?? \"\"\n}))(sample(asked, law, \"yes\"), sample(asked, law, \"no\"));\n\n// ../provider-closure/world/dist/helpers/look.js\nvar stands = (said) => Object.entries(said).filter((pair) => Boolean(pair[1]));\nvar look = (asked, key) => value(asked, `form/style/${key}`);\nvar spacing = (asked, figure) => Object.fromEntries(asked.lines.filter((line) => of(line, \"scope\").startsWith(`form/style/${figure}/`)).map((line) => [of(line, \"scope\").slice(`form/style/${figure}/`.length), numeral(of(line, \"value\"))]));\nvar attrs = (said) => stands(said).map(([k, v]) => ` ${k}=\"${escaped(v)}\"`).join(\"\");\nvar css = (rules2) => rules2.map(([at, said]) => [at, stands(said).map(([k, v]) => `${k}:${v}`).join(\";\")]).filter(([, body]) => body).map(([at, body]) => `${at}{${body}}`).join(\"\");\nvar between = (v, [a, b], [c, d]) => c + (v - a) / (b - a) * (d - c);\nvar px = (n) => Number.isFinite(n) ? String(numeral(n.toFixed(1))) : void 0;\nvar secs = (n) => Number.isFinite(n) ? `${n.toFixed(1)}s` : void 0;\nvar font = (asked, family, size) => ((face, at) => face && at ? { font: `${at} ${face}` } : { \"font-family\": face, \"font-size\": at })(look(asked, `font/${family}`), look(asked, `size/${size}`));\nvar style = (light, night) => ((lit) => lit.length || night ? [\"\"] : [])(light.filter(Boolean));\nvar classDef = (name, fill2, text) => ((said) => said ? [` classDef ${name} ${said}`] : [])([fill2 && `fill:${fill2}`, text && `color:${text}`, fill2 && `stroke:${fill2}`].filter(Boolean).join(\",\"));\n\n// ../provider-closure/world/dist/helpers/prose.js\nvar zoom = (summary, lines) => lines.length ? [`
${summary}`, \"\", ...lines, \"\", \"
\"] : [];\nvar inCell = /* @__PURE__ */ new Map([[\"|\", \"\\\\|\"]]);\nvar cellText = (text) => [...text].map((one) => inCell.get(one) ?? one).join(\"\").split(\"\\n\").join(\" \").split(\" \").filter(Boolean).join(\" \");\nvar escaped = (text) => text.split(\"&\").join(\"&\").split(\"<\").join(\"<\").split(\">\").join(\">\").split('\"').join(\""\");\nvar folder = (at) => steps(steps(at).slice(0, -1));\nvar reaches = (asked, key) => asked.at >= numeral(value(asked, `form/page/${key}`));\nvar stem = (at) => {\n const name = at.slice(at.lastIndexOf(\"/\") + 1);\n return name.includes(\".\") ? name.slice(0, name.lastIndexOf(\".\")) : name;\n};\nvar relative = (from, to) => {\n const [a, b] = [steps(from).filter(Boolean), steps(to).filter(Boolean)];\n const differ = a.findIndex((step, i) => step !== b[i]);\n const shared = differ < 0 ? a.length : differ;\n return steps([...a.slice(shared).map(() => \"..\"), ...b.slice(shared)]);\n};\nvar painted = (asked, name) => ({ name, colour: look(asked, `colour/${name}`), glyph: look(asked, `glyph/${name}`) });\nvar glyph = (asked, name) => pairs(asked, \"notation/glue\").find(([one]) => one === name)?.[1] ?? \"\";\nvar states = (asked) => pairs(asked, \"notation/renders\").map(([state3, name]) => ({ ...painted(asked, state3), name }));\nvar rendered = (asked, state3) => ({ ...painted(asked, state3), name: pairs(asked, \"notation/renders\").find(([one]) => one === state3)?.[1] ?? state3 });\nvar resolved = (asked, body) => {\n if (reaches(asked, \"statement\") || !body.length)\n return body;\n const head = body.findIndex((line) => line.startsWith(\"```\"));\n if (head < 0)\n return asked.at > 1 ? body : ((lead) => lead < 0 ? body : body.slice(0, lead))(body.findIndex((line, i) => i > 1 && line === \"\" && body[i - 1] !== \"\"));\n const lines = body.slice(head + 1, body.lastIndexOf(\"```\"));\n if (asked.at <= 1)\n return [...body.slice(0, head + 1), ...lines.slice(0, 1), \"```\"];\n const [cut] = rule(asked, \"separator\");\n if (cut === void 0)\n throw new Error(`REFUSE\\xB7resolution ${asked.region}@${asked.at}: form/prose/${lang(asked)}/separator names no separator to cut its steps at`);\n return [...body.slice(0, head + 1), ...lines.map((line) => line.split(cut).slice(0, asked.at).join(cut)), \"```\"];\n};\n\n// ../provider-closure/world/dist/helpers/cells.js\nvar SPANS = intervals(-Infinity, Infinity);\nvar hull = (ns) => ns.reduce((all, n) => SPANS.join(all, { lo: n, hi: n }), SPANS.bottom);\nvar apartOf = (met, at) => ((left) => left.length === 1 ? left[0] : void 0)(met.seen.flatMap((one) => ((rest) => rest.origins > 1 && SPANS.inhabited(rest.held) ? [{ who: one.origin, held: rest.held, count: rest.origins }] : [])(encounter(SPANS, met.seen.filter((other) => other !== one).reduce((held, claim) => observe(held, claim), cell(at))))));\nfunction cellOf(asked, at) {\n const shape = new Map(pairs(asked, \"notation/claim\"));\n const role = (name) => shape.get(name) ?? \"\";\n const fielded = receipts(asked, \"source\").filter((one) => placeOf(one) === at && of(one, \"scope\").startsWith(\"source/literal/\")).map((one) => new Map(fields(of(one, \"value\"))));\n const met = fielded.filter((one) => [\"who\", \"lo\", \"hi\"].every((name) => one.has(role(name))) && !one.has(role(\"without\"))).reduce((held, one) => observe(held, { origin: one.get(role(\"who\")) ?? \"\", span: { lo: numeral(one.get(role(\"lo\"))), hi: numeral(one.get(role(\"hi\"))) } }), cell(at));\n return built(met, at);\n}\nvar cellOfLines = (lines) => ((at) => built(lines.reduce((held, line) => ((got) => got.kind === \"fact\" && got.value.bound.kind === \"interval\" && got.value.bound.lo !== null && got.value.bound.hi !== null ? observe(held, { origin: of(line, \"by\"), span: { lo: got.value.bound.lo, hi: got.value.bound.hi } }) : held)(fromLine(canonical(line), null)), cell(at)), at))(of(lines[0], \"scope\"));\nvar built = (met, at) => {\n const { origins: origins2, held } = encounter(SPANS, met);\n const rest = SPANS.inhabited(held) ? void 0 : apartOf(met, at);\n return origins2 > 1 ? { claims: met.seen, held, hull: met.seen.reduce((all, one) => SPANS.join(all, one.span), SPANS.bottom), state: state2(SPANS, met), ...rest === void 0 ? {} : { rest } } : void 0;\n};\nvar captioned = (asked, met) => (met.rest !== void 0 ? say(asked, \"cell/outlier\", { count: count(asked, met.rest.count), ...met.rest.held, who: met.rest.who, state: met.state.toLowerCase() }) : SPANS.inhabited(met.held) ? say(asked, \"cell/together\", { count: count(asked, met.claims.length), ...met.held, state: met.state.toLowerCase() }) : \"\") || stated(asked, met.state);\nvar described = (asked, met) => say(asked, \"cell/origins\", {\n count: count(asked, met.claims.length, true),\n claims: listOf(asked, met.claims.map((one) => say(asked, \"cell/claim\", { who: one.origin, ...one.span }))),\n held: SPANS.inhabited(met.held) ? say(asked, \"cell/held\", { ...met.held }) : prose(asked, \"apart\") ?? \"\"\n});\nvar image = (asked, at, met) => `\"${escaped(described(asked,

`;\nvar labelOf = (asked, scope) => ((law) => law === void 0 ? scope : lawName(asked, law))(lawAt(asked, scope));\n\n// ../provider-closure/world/dist/helpers/examples.js\nvar examples = (asked, at = \"\") => {\n const got = receipts(asked, \"examples\").filter((line) => placeOf(line) === at && matches(\"examples/*\", of(line, \"scope\")));\n return [...new Set(got.map((line) => of(line, \"scope\")))].map((scope) => {\n const read = (measure) => got.find((one) => of(one, \"scope\") === scope && of(one, \"measure\") === measure);\n const origins2 = [found(asked, scope), read(\"id\")].filter((line) => of(line, \"value\") !== \"\");\n const tokens = [...new Set(origins2.map((line) => of(line, \"value\")))];\n const met = origins2.reduce((at2, line) => observe(at2, { origin: of(line, \"by\"), span: WideMask.fromTokens(tokens, /* @__PURE__ */ new Set([of(line, \"value\")])) }), cell(scope));\n return { name: steps(scope)[1] ?? \"\", source: of(read(\"source\"), \"value\"), printed: of(read(\"printed\"), \"value\"), at: of(read(\"at\") ?? read(\"leaf\"), \"value\"), state: state2(alphabetForm.lattice({ tokens }), met) };\n });\n};\nvar shortest = (asked, at = \"\") => [...examples(asked, at)].sort((a, b) => a.source.split(\"\\n\").length - b.source.split(\"\\n\").length || byBytes(a.name, b.name))[0];\nvar fence = (asked, one) => receiptValue(asked, \"source\", \"source/lang\", one.at) ?? \"\";\nvar run = (asked, one) => [`\\`\\`\\`${fence(asked, one)}`, ...one.source.trim().split(\"\\n\"), \"```\", \"\", \"```\", ...one.printed.split(\"\\n\"), \"```\"];\nvar glance = (asked, one, here) => {\n const printed = one.printed.split(\"\\n\");\n const depth = (line) => line.length - line.trimStart().length;\n const next = (i) => printed.slice(i + 1).find((line) => line.trim()) ?? \"\";\n const runner = asked.lines.find((line) => matches(\"form/runtime/*/run\", of(line, \"scope\")));\n const command = runner === void 0 ? \"\" : fill(asked, steps(of(runner, \"scope\")).slice(1).join(\"/\"), of(runner, \"value\"), { at: one.at });\n const [at, most] = [((learn) => learn === void 0 ? asked.at : numeral(learn))(value(asked, \"form/page/learn\")), numeral(value(asked, \"form/page/example\"))];\n const outline = printed.filter((line, i) => line.trim() && !depth(line) && !depth(next(i)));\n const [ran, fenced] = [command ? [\"```bash\", command, \"```\"] : [], (body) => [\"```\", ...body, \"```\"]];\n const shown = at > 1 ? printed : Number.isFinite(most) ? outline.slice(0, hull([0, most - ran.length - fenced([]).length]).hi) : outline;\n const part = (key, body) => body.length ? [.../* @__PURE__ */ ((said) => said ? [said, \"\"] : [])(prose(asked, `figure/learn/${key}`)), ...body] : [];\n const blocks = [part(\"run\", ran), part(\"printed\", fenced(shown)), /* @__PURE__ */ ((link) => link ? [link] : [])(say(asked, \"figure/learn/source\", { at: relative(here, one.at) }))];\n return blocks.filter((block) => block.length).flatMap((block, i) => i ? [\"\", ...block] : block);\n};\n\n// ../provider-closure/world/dist/helpers/figures.js\nvar figured = (asked, region, at) => asked.lines.filter((line) => of(line, \"scope\").startsWith(\"view/\") && ((members) => members.length === 1 && members.some((token) => ((read) => read.name === region && read.at === at)(atResolution(token))))(alphabet(of(line, \"value\")).members));\nvar figureAt = (line) => of(line, \"shape\") || void 0;\nvar drawn2 = (asked, drawing, alt, key = \"\", beneath = []) => ((at) => !drawing.length || at === void 0 ? [] : asked.shape === at ? drawing : [\n ...key ? section(asked, key) : [],\n `\"${escaped(alt)}\"${attrs({

`,\n ...beneath.length ? [\"\", ...beneath] : []\n])(figured(asked, asked.region, 1).map(figureAt).find(Boolean));\n\n// ../provider-closure/world/dist/helpers/refused.js\nvar tail = (scope) => (([n = \"\", word = \"\", ...file]) => ({ n, word, file: steps(file.reverse()) }))([...steps(scope)].reverse());\nvar refusedCases = (asked) => {\n const step = \"refused\";\n const said = [...receipts(asked, \"vectors\"), ...receipts(asked, \"captures\")].filter((line) => tail(of(line, \"scope\")).word === step);\n const where = (scope) => placeOf(said.find((line) => of(line, \"scope\") === scope) ?? {});\n const scopes = [...new Set(said.filter((line) => of(line, \"measure\") === \"why\").map((line) => of(line, \"scope\")))].sort((a, b) => byBytes(tail(a).file, tail(b).file) || numeral(tail(a).n) - numeral(tail(b).n));\n const read = (first, measure) => of(said.find((line) => of(line, \"scope\") === first && of(line, \"measure\") === measure), \"value\");\n return scopes.map((first) => ({ input: read(first, \"input\"), why: read(first, \"why\"), at: where(first), name: read(first, \"name\") || tail(first).file }));\n};\nvar refusedCase = (asked) => refusedCases(asked)[0];\n\n// ../provider-closure/world/dist/helpers/samples.js\nvar sampled = (asked, prefer = \"\") => {\n const family = value(asked, \"samples/yes\");\n const said = receipts(asked, \"laws\").filter((line) => of(line, \"scope\") === \"said/lines\");\n const eligible = prefer ? said.filter((line) => placeOf(line) === prefer) : family === void 0 ? [] : said.filter((line) => placeOf(line).startsWith(`${family.replace(/\\/$/, \"\")}/`));\n const [one] = [...eligible].sort((a, b) => byBytes(placeOf(a), placeOf(b)));\n return one === void 0 ? void 0 : { at: placeOf(one), lines: handed([\"**\"], of(one, \"value\").split(\"\\n\")) };\n};\nvar declaredSample = (asked, view) => {\n const needs = alphabet(of(view, \"needs\")).members;\n if (needs.length)\n return needs.flatMap((need) => sampled(asked, need)?.lines ?? []);\n return sampled(asked)?.lines ?? [];\n};\n\n// ../provider-closure/world/dist/helpers/notation.js\nvar symbolOf = (asked, type, name) => type.endsWith(\"[]\") ? `[${symbolOf(asked, type.slice(0, -\"[]\".length), name)}]` : listed(asked, \"notation/named\").includes(type) ? name : new Map(pairs(asked, \"notation/types\")).get(type) ?? type;\nfunction formulas(asked) {\n const pending = laws(asked).filter((line) => of(line, \"form\") === \"formula\");\n const parent = (formula) => of(formula, \"scope\").slice(0, of(formula, \"scope\").lastIndexOf(\"/\"));\n const out = [];\n while (pending.length) {\n const waits = (formula) => alphabet(of(lawAt(asked, parent(formula)), \"restsOn\")).members.some((on) => pending.some((other) => other !== formula && parent(other) === on));\n const next = pending.findIndex((formula) => !waits(formula));\n out.push(...pending.splice(next < 0 ? 0 : next, 1));\n }\n return out;\n}\nvar moduleOfObject = (asked, held) => resting(asked, of(held, \"scope\")).map((offer) => moduleOf(asked, offer)).find(Boolean);\nvar tuple = (asked) => {\n const held = object(asked);\n if (held === void 0 || !pairs(asked, \"notation/cell\").length)\n return void 0;\n const module = moduleOfObject(asked, held);\n const carries = new Set(alphabet(module === void 0 ? \"\" : receiptValue(asked, \"source\", \"source/carries\", module) ?? \"\").members);\n const [symbols, gloss] = [new Map(pairs(asked, \"notation/symbols\")), listed(asked, \"notation/gloss\")];\n const members = pairs(asked, \"notation/cell\");\n const shown = (carries.size ? members.filter(([member]) => carries.has(member)) : members).map(([, sym]) => sym);\n if (!shown.length)\n return void 0;\n return `${symbols.get(\"object\")} = ${glyph(asked, \"open\")}${shown.join(\", \")}${glyph(asked, \"close\")}${gloss.length ? ` ${gloss.join(\" \")}` : \"\"}`;\n};\nvar aligned = (asked) => {\n const held = object(asked);\n const chosen = listed(asked, \"notation/formulas\");\n const own = (chosen.length ? chosen : [...alphabet(of(held, \"restsOn\")).members, of(held, \"scope\")]).flatMap((scope) => formulas(asked).filter((line) => of(line, \"scope\").startsWith(`${scope}/`))).map((line) => of(line, \"value\"));\n const cut = (text) => hull([\"=\", glyph(asked, \"iff\"), glyph(asked, \"member\")].map((mark2) => text.indexOf(` ${mark2} `)).concat(text.indexOf(\": \")).filter((i) => i > 0)).lo;\n const side = hull(own.map((text) => text.slice(0, cut(text)).length)).hi;\n return own.map((text) => `${text.slice(0, cut(text)).padEnd(side)} ${text.slice(cut(text)).trimStart()}`);\n};\nvar moves = (asked) => {\n const [renders, at] = [pairs(asked, \"notation/renders\"), value(asked, \"notation/moves\") ?? \"\"];\n const split = (edge) => [edge.slice(0, edge.indexOf(\"\\u2192\")), edge.slice(edge.indexOf(\"\\u2192\") + 1)];\n const edges = alphabet(receiptValue(asked, \"laws\", \"said/moves\", at) ?? \"\").members.map(split);\n const known = (state3) => renders.some(([one]) => one === state3);\n const said = receipts(asked, \"laws\").filter((one) => placeOf(one) === at);\n const dangerous = alphabet(of(said.find((one) => of(one, \"scope\").endsWith(\"/dangerous\")), \"value\")).members.map(split);\n const moved = (one) => split(of(one, \"scope\").slice(of(one, \"scope\").lastIndexOf(\"/why/\") + \"/why/\".length));\n const whyOf = ([from, to]) => of(said.find((one) => of(one, \"scope\").includes(\"/why/\") && moved(one)[0] === from && (moved(one)[1] === to || !known(moved(one)[1]))), \"value\");\n if (!renders.length || !edges.length)\n return void 0;\n return edges.filter(([from, to]) => from !== to && known(from) && known(to)).sort(([a, b], [c, d]) => a === c ? b < d ? -1 : b > d ? 1 : 0 : a < c ? -1 : 1).map((edge) => ({ from: edge[0], to: edge[1], dangerous: dangerous.some(([from, to]) => from === edge[0] && to === edge[1]), why: whyOf(edge) }));\n};\n\n// ../provider-closure/world/dist/helpers/records.js\nvar entries = (asked, family) => {\n const held = asked.lines.filter((line) => of(line, \"scope\").startsWith(`${family}/`));\n return [...new Set(held.map((line) => of(line, \"scope\")))].map((scope) => {\n const own = held.filter((line) => of(line, \"scope\") === scope);\n return {\n scope,\n title: own.map((line) => of(line, \"about\")).find(Boolean) ?? words(asked, scope.slice(scope.indexOf(\"/\") + 1)),\n field: (measure) => ((line) => line === void 0 ? void 0 : of(line, \"value\"))(own.find((line) => of(line, \"measure\") === measure))\n };\n });\n};\nvar typedAs = (asked, head, type, beside) => [...new Map(receipts(asked, \"source\").filter((line) => of(line, \"scope\").startsWith(head) && receiptValue(asked, \"source\", of(line, \"scope\"), placeOf(line), \"type\") === type).map((line) => [`${placeOf(line)} ${of(line, \"scope\")}`, [of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1), receiptValue(asked, \"source\", of(line, \"scope\"), placeOf(line), beside) ?? \"\"]])).values()];\n\n// ../provider-closure/world/dist/helpers/shown.js\nvar NUMBER = /(? [...receipts(asked, \"state\"), ...receipts(asked, \"cases\"), ...receipts(asked, \"captures\"), ...receipts(asked, \"laws\")].flatMap((line) => [of(line, \"value\"), of(line, \"scope\")]).filter(Boolean);\nvar captured = (asked, name) => {\n const got = receiptValue(asked, \"captures\", `capture/${name}`);\n return got && got !== \"none\" ? got : void 0;\n};\nfunction unreceipted(asked) {\n const held = new Set(receipted(asked));\n const commands = prose(asked, \"commands\") ?? \"\";\n const idea = prose(asked, \"idea\") ?? \"\";\n const typed = commands.split(\"\\n\").filter((line) => TYPED.test(line)).length;\n const loose = [...`${idea}\n${commands}`.matchAll(NUMBER)].map((one) => one[0]).filter((n) => ![...held].some((said) => said.includes(n))).length;\n return typed + loose;\n}\n\n// ../provider-closure/world/dist/regions/alphabet.js\nvar render = (asked) => [\n `## ${prose(asked, \"reference/alphabet\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/alphabet-table\") ?? \"\",\n \"|---|---|\",\n ...[\"notation/cell\", \"notation/types\"].flatMap((scope) => pairs(asked, scope).map(([members, symbol]) => `| ${cellText(symbol)} | ${cellText(members)} |`))\n];\n\n// ../provider-closure/world/dist/regions/bond.js\nvar render2 = (asked) => {\n const first = shortest(asked);\n const cell2 = first === void 0 ? void 0 : cellOf(asked, first.at);\n if (cell2 === void 0)\n return [];\n const [held, alone, broken] = states(asked);\n const last = states(asked)[states(asked).length - 1]?.name;\n const [meets, { r, top, bottom, apart, axis }, mark2] = [SPANS.inhabited(cell2.held), spacing(asked, \"bond\"), look(asked, \"width/mark\")];\n const [mid, stroke] = [px(numeral(mark2) * axis), { stroke: alone?.colour, \"stroke-width\": look(asked, \"stroke/mark\"), \"stroke-linecap\": look(asked, \"stroke/cap\") }];\n const title = meets ? say(asked, \"cell/bond\", { count: cell2.claims.length }) : `${cell2.claims.length} ${say(asked, \"cell/apart\", { apart: prose(asked, \"apart\") ?? \"\" })}`;\n return [\n ``,\n `${title}`,\n ...meets ? [``] : [],\n ``,\n ``,\n \"\"\n ];\n};\n\n// ../provider-closure/world/dist/regions/cff.js\nvar render3 = (asked) => {\n const doiOf = (field) => value(asked, \"sources/doi\") === void 0 ? void 0 : field(\"doi\");\n const [paper, name] = [entries(asked, \"cites\").find((one) => doiOf(one.field) !== void 0), value(asked, \"name\")];\n if (name === void 0)\n return [];\n const quoted = (text) => JSON.stringify(text);\n const person = (who, indent) => (([family = \"\", ...given]) => given.length ? [`${indent}- family-names: ${quoted(family)}`, `${indent} given-names: ${quoted(given.join(\", \"))}`] : [`${indent}- name: ${quoted(who)}`])(who.split(\", \"));\n const optional = (key, scope) => ((said) => said === void 0 ? [] : [`${key}: ${quoted(said)}`])(value(asked, scope));\n const [authors, year, version, publisher] = [alphabet(paper?.field(\"author\") ?? \"\").members, paper?.field(\"year\"), paper?.field(\"version\"), paper?.field(\"publisher\")];\n const preferred = paper === void 0 ? [] : [\n \"preferred-citation:\",\n \" type: article\",\n ` title: ${quoted(paper.title)}`,\n ...authors.length ? [\" authors:\", ...authors.flatMap((one) => person(one, \" \"))] : [],\n ...year !== void 0 && Number.isInteger(numeral(year)) ? [` year: ${year}`] : [],\n ...version === void 0 ? [] : [` version: ${quoted(version)}`],\n ...publisher === void 0 ? [] : [\" publisher:\", ` name: ${quoted(publisher)}`],\n ` doi: ${quoted(doiOf(paper.field) ?? \"\")}`\n ];\n return resolved(asked, [\n \"cff-version: 1.2.0\",\n `message: ${quoted(paper ? say(asked, \"cff/paper\", { title: paper.title }) : say(asked, \"cff/name\", { name }))}`,\n \"type: software\",\n `title: ${quoted(name)}`,\n ...optional(\"version\", \"version\"),\n ...((author) => author === void 0 ? [] : [\"authors:\", ...person(author, \" \")])(value(asked, \"author\")),\n ...optional(\"repository-code\", \"repository\"),\n ...optional(\"license\", \"license\"),\n ...preferred\n ]);\n};\n\n// ../provider-closure/world/dist/regions/check.js\nvar render4 = (asked) => {\n const [glyph2, folds] = [states(asked)[0]?.glyph ?? \"\", asked.lines.find((one) => of(one, \"scope\") === \"fold\" && of(one, \"role\") === \"writes\")];\n const [repository, resolvedAt, command] = [value(asked, \"repository\"), value(asked, \"repository/resolved\"), value(asked, \"check\")];\n const how = [\n ...repository === void 0 || resolvedAt === void 0 ? [] : [say(asked, \"check/repository\", { glyph: glyph2, repository })],\n ...command === void 0 ? [] : [say(asked, \"check/command\", { glyph: glyph2, check: command })],\n ...folds === void 0 ? [] : [say(asked, \"check/fold\", { fold: of(folds, \"value\"), about: of(folds, \"about\") })]\n ];\n return resolved(asked, [...section(asked, \"check\"), say(asked, \"check/held\", { glyph: glyph2, count: receiptValue(asked, \"cases\", \"cases/held\") ?? 0 }), ...how.length ? [\"\", how.join(\" \\xB7 \")] : []]);\n};\n\n// ../provider-closure/world/dist/regions/claims.js\nvar reading = (asked, glob) => {\n const held = Object.values(asked.regions).flatMap((region) => region.receipts).filter((line2) => matches(glob, of(line2, \"scope\")));\n if (held.length > 1)\n throw new Error(`REFUSE\\xB7claim ${asked.region}@${asked.at}: ${glob} names ${held.length} receipts without a resolved value`);\n if (held.length === 1)\n return of(held[0], \"value\");\n const line = found(asked, glob);\n if (line === void 0 || of(line, \"value\") === \"withdraw\")\n return void 0;\n return of(line, \"form\") === \"interval\" ? of(line, \"value\") : of(line, \"form\") === \"alphabet\" ? String(listed(asked, glob).length) : void 0;\n};\nvar render5 = (asked) => {\n const here = folder(asked.shape);\n const held = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"claims/\") && of(line, \"value\") !== \"withdraw\").sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\")));\n const bullet = (scope, value2, needs) => {\n const [page] = alphabet(needs).members;\n const read = fields(value2).map(([name, glob]) => [name, reading(asked, glob)]);\n if (read.some(([, got]) => got === void 0))\n return [];\n const said = sentence(asked, say(asked, scope, Object.fromEntries(read.map(([name, got]) => [name, got ?? \"\"]))));\n if (!said)\n return [];\n return [`- **${said}**${page === void 0 ? \"\" : ` \\xB7 [${prose(asked, \"claims/receipt\") ?? \"\"}](${relative(here, page)})`}`];\n };\n const rows = held.flatMap((line) => bullet(of(line, \"scope\"), of(line, \"value\"), of(line, \"needs\")));\n return resolved(asked, rows.length ? [...section(asked, \"claims\"), ...rows] : []);\n};\n\n// ../provider-closure/world/dist/regions/commands.js\nvar render6 = (asked) => {\n const said = prose(asked, \"commands\");\n const out = captured(asked, \"quickstart\");\n const usage = captured(asked, \"usage\");\n const blocks = [\n ...said ? [\"```bash\", said, \"```\"] : [],\n ...out ? [\"```\", out, \"```\"] : [],\n ...usage ? [\"```\", usage, \"```\"] : []\n ];\n return resolved(asked, blocks);\n};\n\n// ../provider-closure/world/dist/regions/door.js\nvar render7 = (asked) => {\n const drawn3 = figured(asked, \"ranges\", 1)[0];\n const figure = drawn3 === void 0 ? void 0 : figureAt(drawn3);\n const one = figure === void 0 ? void 0 : shortest(asked);\n const cell2 = one === void 0 ? void 0 : cellOf(asked, one.at);\n const [what] = alphabet(of(found(asked, \"docs/what\"), \"needs\")).members;\n const parts2 = [\n ...figure !== void 0 && cell2 !== void 0 ? [image(asked, figure, cell2)] : [],\n ...what === void 0 ? [] : [((link, words2) => words2 ? `${say(asked, `${asked.region}/what`)} [${words2}](${link})` : `[${say(asked, `${asked.region}/what`)}](${link})`)(relative(folder(asked.shape), what), prose(asked, `${asked.region}/words`))]\n ];\n return resolved(asked, parts2.flatMap((part, i) => i ? [\"\", part] : [part]));\n};\n\n// ../provider-closure/world/dist/regions/unreceipted.js\nvar receipt = (asked) => counted({ ...asked, region: \"door\" }, \"unreceipted\", unreceipted(asked), \"unreceipted\");\n\n// ../provider-closure/world/dist/regions/figure.js\nvar render8 = (asked) => {\n const first = shortest(asked);\n const cell2 = first === void 0 ? void 0 : cellOf(asked, first.at);\n const at = figured(asked, \"ranges\", 1).map(figureAt).find(Boolean);\n const marks = prose(asked, \"marks\");\n return resolved(asked, at === void 0 || cell2 === void 0 ? [] : [image(asked, at, cell2), ...marks === void 0 ? [] : [\"\", marks]]);\n};\n\n// ../provider-closure/world/dist/regions/figure-fold.js\nvar render9 = (asked) => {\n const lines = declaredSample(asked, figured(asked, asked.region, 1)[0]);\n const cell2 = cellOfLines(lines.filter((line) => of(line, \"scope\") === of(lines[0], \"scope\")));\n const named = listed(asked, \"form/figure/fold\");\n const [claimed, met, apart] = named.map((state3) => rendered(asked, state3));\n const [g, wide] = [spacing(asked, \"fold\"), numeral(look(asked, \"width/figure\"))];\n const away = cell2?.rest?.who;\n const held = cell2 === void 0 ? void 0 : SPANS.inhabited(cell2.held) ? cell2.held : cell2.rest?.held;\n const said = cell2 === void 0 ? [] : [\n held === void 0 ? \"\" : say(asked, \"figure/fold/together\", { ...held, state: (named[1] ?? \"\").toLowerCase() }),\n away === void 0 || held === void 0 ? \"\" : say(asked, \"figure/fold/apart\", { who: away, state: cell2.state.toLowerCase() }),\n away === void 0 || held === void 0 || !Number.isFinite(g.back) ? \"\" : say(asked, \"figure/fold/back\", { ...held })\n ].filter(Boolean);\n const x = (v) => cell2 === void 0 ? NaN : between(v, [cell2.hull.lo - g.pad, cell2.hull.hi + g.pad], [g.margin, wide - g.margin]);\n const rows = cell2 === void 0 ? [] : cell2.claims.filter((claim) => claim.origin !== away);\n const out = cell2?.claims.find((claim) => claim.origin === away);\n const height = (rows.length + (out ? 1 : 0) + 1) * g.row + said.length * g.say + g.say;\n const bar = (lo, hi, y, body) => `${body}`;\n const fade = (begin) => ``;\n const turn = (from, to, begin) => ``;\n return drawn2(asked, cell2 === void 0 || held === void 0 || !said.length ? [] : [\n ``,\n ...style([css([[\"text\", { ...font(asked, \"text\", \"text\"), fill: painted(asked, \"text\").colour }]])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ``,\n ...rows.map((claim, i) => bar(claim.span.lo, claim.span.hi, g.top + i * g.row, `${out ? turn(claimed?.colour, apart?.colour, g.set) : \"\"}${out && Number.isFinite(g.back) ? turn(apart?.colour, claimed?.colour, g.back) : \"\"}`)),\n bar(held.lo, held.hi, g.top + rows.length * g.row, `${turn(claimed?.colour, met?.colour, g.meet)}${out ? turn(met?.colour, apart?.colour, g.set) : \"\"}${out && Number.isFinite(g.back) ? turn(apart?.colour, met?.colour, g.back) : \"\"}`),\n ...out ? [bar(out.span.lo, out.span.hi, g.top + (rows.length + 1) * g.row + g.gap, `${turn(claimed?.colour, apart?.colour, g.set)}${Number.isFinite(g.back) ? `` : \"\"}`)] : [],\n ...said.map((one, i) => `${escaped(one)}${fade(g.speak + i * g.meet)}`),\n \"\"\n ], listOf(asked, said), \"figure/fold\", ((caption) => caption ? [sentence(asked, caption)] : [])(cell2 === void 0 ? \"\" : captioned(asked, cell2)));\n};\n\n// ../provider-closure/world/dist/regions/figure-line.js\nvar render10 = (asked) => {\n const line = declaredSample(asked, figured(asked, asked.region, 1)[0])[0];\n const rows = listed(asked, \"form/figure/line\").map((field) => [field, of(line, field)]).filter(([, said]) => said !== \"\");\n const [held] = states(asked);\n const [g, wide] = [spacing(asked, \"line\"), look(asked, \"width/figure\")];\n const alt = line === void 0 ? \"\" : say(asked, \"figure/line\", { scope: of(line, \"scope\"), count: rows.length });\n const height = px(g.top + rows.length * g.row);\n return drawn2(asked, rows.length ? [\n ``,\n ...style([css([[\"text\", { ...font(asked, \"code\", \"code\"), fill: painted(asked, \"text\").colour }], [\".field\", { fill: held?.colour, \"font-weight\": look(asked, \"weight/strong\") }]])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ...rows.flatMap(([field, said], i) => [`${escaped(field)}`, `${escaped(said)}`]),\n \"\"\n ] : [], alt, \"figure/line\", alt ? [sentence(asked, alt)] : []);\n};\n\n// ../provider-closure/world/dist/regions/figure-refuses.js\nvar render11 = (asked) => {\n const told = refusedCase(asked);\n const [, , forbidden] = states(asked);\n const [g, wide] = [spacing(asked, \"refuses\"), look(asked, \"width/figure\")];\n const alt = told === void 0 || !told.input || !told.why ? \"\" : say(asked, \"figure/refuses\", { input: told.input, why: told.why });\n return drawn2(asked, told !== void 0 && alt ? [\n ``,\n ...style([\n css([[\"text\", { ...font(asked, \"text\", \"text\"), fill: painted(asked, \"text\").colour }], [\".cross\", { fill: forbidden?.colour, \"font-weight\": look(asked, \"weight/strong\") }]]),\n css([[\".asked\", { ...font(asked, \"code\", \"code\"), fill: forbidden?.colour, \"text-decoration\": \"line-through\" }]])\n ], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n `${escaped(forbidden?.glyph ?? \"\")}`,\n `${escaped(told.input)}`,\n `${escaped(told.why)}`,\n \"\"\n ] : [], alt, \"figure/refuses\");\n};\n\n// ../provider-closure/world/dist/regions/figure-world.js\nvar render12 = (asked) => {\n const shown = examples(asked).find((one) => one.name === value(asked, \"docs/world\"));\n const own = shown === void 0 ? regionLines(asked, \"capsule\") : handed([\"**\"], shown.printed.split(\"\\n\"));\n const said = (scope) => of(own.find((line) => of(line, \"scope\") === scope), \"value\");\n const nameOf = (line) => of(line, \"scope\").slice(of(line, \"scope\").indexOf(\"/\") + 1);\n const declared = own.filter((line) => of(line, \"scope\").startsWith(\"region/\") && of(line, \"measure\") === \"reads\");\n const regions = [...new Set(declared.map(nameOf))].sort();\n const ordered = [...declared].sort((a, b) => nameOf(a) < nameOf(b) ? -1 : nameOf(a) > nameOf(b) ? 1 : 0);\n const dir = value(asked, `form/runtime/${said(\"capsule/runtime\")}/regions`);\n const files = dir === void 0 || shown !== void 0 ? [] : receipts(asked, \"source\").map(placeOf).filter((at) => at.startsWith(dir) && regions.includes(stem(at)));\n const longest = hull([0, ...[...new Set(files)].map((at) => numeral(receiptValue(asked, \"source\", \"source/lines\", at)) || 0)]).hi;\n const uses = own.find((line) => of(line, \"scope\").startsWith(\"uses/\"));\n const release = new Set([said(\"capsule/topos\"), shown === void 0 ? value(asked, `uses/${asked.name}`) ?? \"\" : \"\"].filter((one) => one.startsWith(\"sha256:\")));\n const blob = shown === void 0 ? \"\" : of(uses, \"value\");\n const pin = blob.startsWith(\"sha256:\") && !release.has(blob) ? blob : \"\";\n const stages = [\n say(asked, \"figure/world/declares\", { domain: said(\"capsule/domain\"), runtime: said(\"capsule/runtime\"), effects: said(\"capsule/effects\") }),\n ...shown === void 0 ? [say(asked, \"figure/world/regions\", { count: regions.length, longest }), say(asked, \"figure/world/vectors\", { count: receipts(asked, \"vectors\").length })] : ordered.map((line) => say(asked, \"figure/world/region\", { name: nameOf(line), reads: of(line, \"value\") })),\n ...pin ? [say(asked, \"figure/world/pinned\", { place: asked.name })] : [],\n ...shown !== void 0 && pin ? [say(asked, \"figure/world/adopted\", { scope: of(uses, \"scope\") })] : [],\n say(asked, \"figure/world/host\", { runtime: said(\"capsule/runtime\") })\n ].filter((stage) => Boolean(stage));\n const [held, alone] = states(asked);\n const g = spacing(asked, \"world\");\n const [height, wide] = [stages.length * g.pitch, hull([numeral(look(asked, \"width/figure\")), Math.ceil(g.margin + hull([0, ...stages.map((stage) => stage.length)]).hi * g.char)]).hi];\n return drawn2(asked, own.length && stages.length ? [\n ``,\n ...style([css([[\"text\", { ...font(asked, \"code\", \"small\"), fill: painted(asked, \"text\").colour }], [\"rect\", { fill: \"none\", stroke: alone?.colour }], [\"line\", { stroke: held?.colour }]])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ...stages.flatMap((stage, i) => [\n ``,\n `${escaped(stage)}`,\n ...i ? [``] : []\n ]),\n \"\"\n ] : [], listOf(asked, stages), \"figure/world\");\n};\n\n// ../provider-closure/world/dist/regions/first-use.js\nvar render13 = (asked) => ((first) => first === void 0 ? [] : [...section(asked, \"first-use\"), say(asked, \"first-use/lead\", { name: first.name }), \"\", ...glance(asked, first, folder(asked.shape))])(shortest(asked));\n\n// ../provider-closure/world/dist/regions/forms.js\nvar render14 = (asked) => [\n `## ${prose(asked, \"reference/forms\") ?? \"\"}`,\n \"\",\n ...[...new Set(typedAs(asked, \"source/declared/\", value(asked, \"docs/forms\") ?? \"\", \"args\").map(([name, args]) => `- ${say(asked, \"reference/form\", { name, args: cellText(args) })}`))].sort()\n];\n\n// ../provider-closure/world/dist/regions/guide-at-zero.js\nvar render15 = (asked) => resolved(asked, [\n `# ${prose(asked, \"guide/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"contributing\", { check: value(asked, \"check\") ?? say(asked, \"guide/owed\"), open: count(asked, laws(asked).filter((line) => of(line, \"kind\") === \"conjecture\").length, true) })\n]);\n\n// ../provider-closure/world/dist/regions/hero.js\nvar badges = (asked) => {\n const [held, alone] = states(asked);\n const part = (text) => encodeURIComponent(text.split(\"-\").join(\"--\").split(\"_\").join(\"__\").split(\" \").join(\"_\"));\n const shield = (label, message, colour) => `![${label} ${message}](${value(asked, \"sources/badges\") ?? \"\"}/${part(label)}-${part(message)}-${(colour?.colour ?? \"\").slice(1)})`;\n const measured = (region, scope) => {\n const said = receiptValue(asked, region, scope);\n if (said === void 0)\n return void 0;\n for (const text of [said, `${said}..${said}`]) {\n try {\n const got = fromLine(canonical({ at: \"place:badge\", by: \"reader\", form: \"interval\", measure: \"count\", role: \"reads\", scope, value: text }), null);\n if (got.kind !== \"fact\" || got.value.bound.kind !== \"interval\")\n continue;\n const { lo, hi } = got.value.bound;\n if (lo !== null && lo === hi && Number.isFinite(lo))\n return lo;\n } catch {\n }\n }\n return void 0;\n };\n const cases = measured(\"cases\", \"cases/held\");\n const depends = found(asked, \"dependencies\") === void 0 ? void 0 : listed(asked, \"dependencies\").length;\n const verdict = receiptValue(asked, \"state\", \"second/verdict\");\n const doi = entries(asked, \"cites\").map((one) => value(asked, \"sources/doi\") === void 0 ? void 0 : one.field(\"doi\")).find(Boolean);\n const valued = (key) => {\n const said = value(asked, key);\n if (said === void 0)\n return [];\n const label = say(asked, `badge/${key}`) || key;\n const message = said === label || said.startsWith(`${label} `) ? said.slice(label.length).trim() : said;\n return message === \"\" ? [] : [shield(label, message, alone)];\n };\n const n = (scope) => measured(\"state\", scope);\n const digest = receiptValue(asked, \"state\", \"release/digest\") ?? \"\";\n const lawCounts = [\"verdict/met\", \"verdict/short\", \"verdict/over\", \"verdict/refused\", \"verdict/forks\"].map(n);\n const complete = verdict !== void 0 && lawCounts.every((one) => one !== void 0);\n const broken = !complete || lawCounts.slice(1).some((one) => one !== 0) || verdict !== \"agrees\";\n const drawn3 = {\n dependencies: () => depends === void 0 ? [] : [shield(say(asked, \"badge/dependencies\"), String(depends), depends ? alone : held)],\n cases: () => cases !== void 0 ? [shield(say(asked, \"badge/cases\"), say(asked, \"badge/held\", { count: cases }), held)] : [],\n verify: () => verdict === void 0 ? [] : [shield(say(asked, \"badge/verify\") || \"verify\", verdict, verdict === \"agrees\" ? held : alone)],\n doi: () => doi === void 0 ? [] : [`[${shield(say(asked, \"badge/doi\"), doi, alone)}](${value(asked, \"sources/doi\") ?? \"\"}${doi})`],\n release: () => digest ? [shield(say(asked, \"badge/release\") || \"release\", digest.replace(/^[^:]*:/, \"\").slice(0, 12), held)] : [],\n claims: () => ((c) => c !== void 0 ? [shield(say(asked, \"badge/claims\") || \"claims\", String(c), held)] : [])(n(\"verdict/claims\")),\n second: () => ((c) => c === void 0 ? [] : [shield(say(asked, \"badge/second\") || \"second\", String(c), verdict === \"agrees\" ? held : alone)])(n(\"verdict/met\")),\n laws: () => complete ? [shield(say(asked, \"badge/laws\") || \"laws\", `${lawCounts[0]}/${lawCounts.slice(0, 4).reduce((sum, one) => sum + (one ?? 0), 0)}`, broken ? alone : held)] : []\n };\n const named = found(asked, \"docs/badges\") !== void 0 ? listed(asked, \"docs/badges\") : listed(asked, \"wire/badges/world\").length ? listed(asked, \"wire/badges/world\") : listed(asked, \"audit/wire/badges/world\");\n return [named.flatMap((name) => (drawn3[name] ?? (() => valued(name)))()).join(\" \")];\n};\nvar render16 = (asked) => [\n ...((logo) => logo === void 0 ? [] : [`\"\"${attrs({

`, \"\"])(value(asked, \"docs/logo\")),\n `# ${value(asked, \"name\") ?? asked.name}`,\n \"\",\n ...badges(asked),\n ...((what) => what === void 0 ? [] : [\"\", sentence(asked, what)])(of(found(asked, \"docs/tagline\"), \"about\") || prose(asked, \"what\"))\n];\n\n// ../provider-closure/world/dist/regions/how-they-rest.js\nvar render17 = (asked) => {\n const where = (glob) => asked.lines.filter((line) => matches(glob, of(line, \"scope\")));\n const packages = new Map(where(\"*/name\").map((line) => [of(line, \"value\"), steps(of(line, \"scope\"))[0] ?? \"\"]));\n const among = where(\"*/dependencies\").flatMap((line) => alphabet(of(line, \"value\")).members.map((spec) => [...packages].find(([name]) => spec.startsWith(`${name}@`))?.[1]).filter((to) => to !== void 0).map((to) => ` ${steps(of(line, \"scope\"))[0] ?? \"\"} --> ${to}`)).sort(byBytes);\n const summary = asked.lines.find((line) => of(line, \"scope\").startsWith(`prose/${lang(asked)}/`) && of(line, \"scope\").endsWith(\"/rests\"));\n if (among.length)\n return zoom(of(summary, \"about\"), [\"```mermaid\", \"flowchart RL\", ...among, \"```\"]);\n const prefix = ((name) => name.slice(0, name.lastIndexOf(\"/\") + 1))(value(asked, \"name\") ?? \"\");\n const depends = alphabet(value(asked, \"dependencies\") ?? \"\").members;\n const needed = [...new Set(where(\"needs/*\").map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))].filter((one) => one && one !== asked.name);\n const pinned = [...new Set(where(\"uses/*\").map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))].filter((one) => depends.some((spec) => spec.startsWith(`${prefix}${one}@`)));\n const read = [...new Set(where(\"dep/*\").filter((line) => of(line, \"role\") === \"reads\").map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))];\n const rests2 = (needed.length ? needed : pinned.length ? pinned : read).filter((one) => one && one !== asked.name).sort(byBytes);\n return rests2.length ? [...((heading2) => heading2 ? [`## ${heading2}`, \"\"] : [])(prose(asked, \"rests/heading\")), say(asked, \"rests/on\", { names: listOf(asked, rests2) })] : [];\n};\n\n// ../provider-closure/world/dist/regions/idea.js\nvar render18 = (asked) => resolved(asked, titled(asked, \"idea\", parted(asked, \"idea\")));\n\n// ../provider-closure/world/dist/regions/line.js\nvar render19 = (asked) => {\n const pin = value(asked, `sources/${asked.name}`);\n if (pin === void 0)\n return [];\n const uses = value(asked, `uses/${asked.name}`) ?? \"\";\n const shown = [pin, ...uses && !uses.startsWith(\"sha256:\") ? [uses] : []];\n return resolved(asked, shown);\n};\n\n// ../provider-closure/world/dist/regions/install.js\nvar render20 = (asked) => {\n if (found(asked, `uses/${asked.name}`) !== void 0 || found(asked, `sources/${asked.name}`) !== void 0)\n return render19(asked);\n const [how, name] = [value(asked, \"install\"), value(asked, \"name\")];\n return resolved(asked, how === void 0 || name === void 0 ? [] : [\"```bash\", `${how} ${name}`, \"```\"]);\n};\n\n// ../provider-closure/world/dist/regions/learn.js\nvar restsOn = (asked, called, shown) => {\n const ids = /* @__PURE__ */ new Map();\n const offered = (call) => offers(asked).find((line) => of(line, \"scope\").endsWith(`/${call}`));\n const calls = called.filter((call) => offers(asked).some((line) => of(line, \"scope\").endsWith(`/${call}`) && of(line, \"restsOn\") !== \"\"));\n const edges = calls.flatMap((call, i) => alphabet(of(offered(call), \"restsOn\")).members.map((on) => ` c${i} --> ${ids.get(on) ?? ids.set(on, `l${ids.size}`).get(on)}`));\n const colour = states(asked)[0]?.colour;\n return edges.length ? [\n \"```mermaid\",\n \"flowchart LR\",\n ...calls.map((call, i) => ` c${i}[\"${call}\"]`),\n ...[...ids].map(([scope, id]) => ` ${id}([\"${labelOf(asked, scope)}\"])`),\n ...edges,\n ...classDef(\"shown\", colour, painted(asked, \"text-on\").colour),\n ` class ${ids.get(shown) ?? \"\"} shown`,\n \"```\"\n ] : [];\n};\nvar render21 = (asked) => {\n const one = examples(asked).find((example) => example.name === stem(asked.shape));\n if (one === void 0)\n return ((first) => first === void 0 ? [] : [\n ...section(asked, \"learn\"),\n ...glance(asked, first, folder(asked.shape)),\n ...((caption) => caption ? [\"\", sentence(asked, caption)] : [])(((cell3) => cell3 === void 0 ? \"\" : captioned(asked, cell3))(cellOf(asked, first.at)))\n ])(examples(asked).find((example) => example.name === value(asked, \"docs/learn\")) ?? shortest(asked));\n const called = receipts(asked, \"source\").filter((line) => placeOf(line) === one.at && of(line, \"scope\") === \"source/calls\").flatMap((line) => alphabet(of(line, \"value\")).members);\n const rests2 = /* @__PURE__ */ new Map();\n for (const call of called)\n for (const on of alphabet(of(offers(asked).find((line) => of(line, \"scope\").endsWith(`/${call}`)), \"restsOn\")).members)\n rests2.set(on, (rests2.get(on) ?? 0) + 1);\n const shown = [...rests2].sort((a, b) => b[1] - a[1] || byBytes(a[0], b[0]))[0]?.[0];\n const stated2 = shown === void 0 ? void 0 : lawAt(asked, shown);\n const graph = stated2 === void 0 || shown === void 0 ? [] : restsOn(asked, called, shown);\n const [cell2, here] = [cellOf(asked, one.at), asked.shape.slice(0, asked.shape.lastIndexOf(\"/\"))];\n const drawn3 = figured(asked, \"ranges\", numeral(value(asked, \"form/page/statement\"))).map(figureAt).find((at) => at !== void 0 && stem(at) === one.name);\n const shownFigure = drawn3 !== void 0 && cell2 !== void 0 ? [image(asked, relative(here, drawn3), cell2), \"\", sentence(asked, captioned(asked, cell2))] : shown !== void 0 && shown === value(asked, \"notation/object\") ? graph : [];\n return resolved(asked, [\n `# ${heading(asked, one.name)}`,\n \"\",\n ...shownFigure.length ? [...shownFigure, \"\"] : [],\n ...stated2 ? [sentence(asked, of(stated2, \"about\")), \"\"] : [],\n `## ${prose(asked, \"learn/run\") ?? \"\"}`,\n \"\",\n ...run(asked, one),\n \"\",\n ...graph.length && shownFigure !== graph ? [`## ${prose(asked, \"learn/rests\") ?? \"\"}`, \"\", ...graph, \"\"] : [],\n ...titled(asked, \"learn/source\", [say(asked, \"learn/source\", { at: relative(here, one.at), place: asked.name })])\n ]);\n};\n\n// ../provider-closure/world/dist/regions/license.js\nvar render22 = (asked) => resolved(asked, asked.lines.filter((line) => of(line, \"scope\") === \"license\" && of(line, \"about\") !== \"\").flatMap((line) => of(line, \"about\").split(\"\\n\")));\n\n// ../provider-closure/world/dist/regions/media.js\nvar render23 = (asked) => {\n const [kept, sha] = [value(asked, \"form/page/media\"), \"sha256:\"];\n const [still, players] = [[\"svg\", \"png\", \"gif\"], [\"video\", \"audio\"]];\n const source = (said) => said.startsWith(sha) ? kept && fill(asked, \"page/media\", kept, { digest: said.slice(sha.length) }) : said;\n const embed = (form2, src, about) => still.includes(form2) ? `

` : players.includes(form2) ? `<${form2}${attrs({ src, width: form2 === players[0] ? look(asked, \"width/figure\") : void 0 })} controls>` : void 0;\n const lines = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"media/\")).sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\")));\n return lines.flatMap((line) => /* @__PURE__ */ ((one) => one ? [\"\", one] : [])(embed(of(line, \"measure\"), source(of(line, \"value\")), of(line, \"about\")))).slice(1);\n};\n\n// ../provider-closure/world/dist/regions/notation.js\nvar formulaLaw = (asked, formula) => lawAt(asked, of(formula, \"scope\").slice(0, of(formula, \"scope\").lastIndexOf(\"/\")));\nvar arrows = (asked) => {\n const held = object(asked);\n const module = held === void 0 ? void 0 : moduleOfObject(asked, held);\n const symbols = new Map(pairs(asked, \"notation/symbols\"));\n const made = module === void 0 || held === void 0 ? [] : resting(asked, of(held, \"scope\")).map((line) => of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1)).flatMap((name) => {\n const params = receiptLine(asked, \"source\", `source/arrow/${name}`, module, \"params\");\n const result = receiptValue(asked, \"source\", `source/arrow/${name}`, module, \"result\");\n if (params === void 0 || result === void 0)\n return [];\n const typed = fields(of(params, \"value\")).map(([name2, type]) => symbolOf(asked, type, name2));\n const makes = symbolOf(asked, result, \"value\") === symbols.get(\"object\") && !typed.some((one) => one === symbols.get(\"object\") || one === `[${symbols.get(\"object\")}]`);\n return makes ? [] : [[name, `${typed.join(` ${glyph(asked, \"product\")} `)} ${glyph(asked, \"maps\")} ${symbolOf(asked, result, \"value\")}`]];\n });\n const kind = pairs(asked, \"notation/types\").find(([, sym]) => sym === symbols.get(\"state\"))?.[0] ?? \"\";\n const union = alphabet(of([...receipts(asked, \"source\")].filter((one) => of(one, \"scope\") === `source/union/${kind}`).sort((a, b) => byBytes(placeOf(a), placeOf(b)))[0], \"value\")).members;\n const width = hull(made.map(([name]) => name.length)).hi;\n return [...made.map(([name, arrow]) => `${name.padEnd(width)} : ${arrow}`), ...union.length ? [`${symbols.get(\"state\")}(${symbols.get(\"object\")}) ${glyph(asked, \"member\")} {${union.join(\", \")}}`] : []];\n};\nvar render24 = (asked) => {\n const head = tuple(asked);\n if (head === void 0)\n return [];\n if (asked.at <= 0)\n return [\"```text\", head, \"```\"];\n if (asked.at <= 1)\n return [\"```text\", head, ...aligned(asked), \"```\"];\n const all = formulas(asked);\n if (!reaches(asked, \"whole\"))\n return [\"```text\", head, \"```\", \"\", ...all.map((line) => `- \\`${of(line, \"value\")}\\` \\u2014 ${of(formulaLaw(asked, line), \"about\")}.`)];\n return [\n `## ${prose(asked, \"reference/notation\") ?? \"\"}`,\n \"\",\n \"```text\",\n head,\n \"```\",\n \"\",\n prose(asked, \"notation/table\") ?? \"\",\n \"|---|---|---|\",\n ...all.map((line) => ((law) => `| \\`${cellText(of(line, \"value\"))}\\` | ${law === void 0 ? \"\" : lawName(asked, law)} | ${cellText(of(law, \"about\"))} |`)(formulaLaw(asked, line))),\n \"\",\n \"```text\",\n ...arrows(asked),\n \"```\"\n ];\n};\n\n// ../provider-closure/world/dist/regions/open.js\nvar render25 = (asked) => {\n const needed = asked.lines.filter((line) => matches(\"needs/*\", of(line, \"scope\")) && of(line, \"value\") !== \"withdraw\");\n if (needed.length)\n return resolved(asked, [...section(asked, \"open\"), \"\", ...needed.map((line) => `- ${of(line, \"about\") || of(line, \"scope\")}`)]);\n const facts = (family) => receipts(asked, \"state\").filter((line) => of(line, \"scope\").startsWith(`${family}/`)).sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))).map((line) => [of(line, \"scope\").slice(family.length + 1), of(line, \"value\")]);\n const said = (family) => facts(family).map(([scope, reading2]) => say(asked, `open/${family}`, { scope, reading: reading2 })).filter(Boolean).map((one) => `- ${one}`);\n const judged = facts(\"conjecture\").map(([scope, reading2]) => ((law) => law === void 0 ? say(asked, \"open/open\", { scope, reading: reading2 }) : conjectured(asked, law))(lawAt(asked, scope))).filter(Boolean);\n const held = judged.length ? judged : laws(asked).filter((line) => of(line, \"kind\") === \"conjecture\").map((law) => conjectured(asked, law));\n const [unpaid, outside] = [said(\"unpaid\"), said(\"outside\")];\n if (!held.length && !unpaid.length && !outside.length)\n return [];\n return resolved(asked, [...section(asked, \"open\"), ...[\n ...held.length ? [\"\", say(asked, judged.length ? \"open/judged\" : \"open/lead\", { count: count(asked, held.length, true) }), \"\", ...held.map((one) => `- ${one}`)] : [],\n ...unpaid.length ? [\"\", ...unpaid] : [],\n ...outside.length ? [\"\", ...outside] : []\n ].slice(1)]);\n};\n\n// ../provider-closure/world/dist/regions/open-conjectures.js\nvar render26 = (asked) => {\n const held = laws(asked).filter((line) => of(line, \"kind\") === \"conjecture\");\n if (!held.length)\n return [];\n const bullet = (line) => `- ${conjectured(asked, line)}`;\n const who = pairs(asked, \"open/who\");\n const groups = [...new Set(who.map(([group]) => group))].map((group) => [group, held.filter((line) => who.some(([g, one]) => g === group && lawKey(line) === one))]);\n const loose = held.filter((line) => !who.some(([, one]) => lawKey(line) === one));\n const full = held.map((line) => `${sentence(asked, of(line, \"about\"))} ${(sample(asked, line, \"no\").about ?? [])[0] ?? \"\"}`.trim());\n return resolved(asked, [\n `## ${prose(asked, \"open/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"open/lead\", { count: count(asked, held.length, true) }),\n ...groups.flatMap(([group, lines]) => lines.length ? [\"\", say(asked, \"open/group\", { count: count(asked, lines.length, true), group }), \"\", ...lines.map(bullet)] : []),\n ...loose.length ? [\"\", ...loose.map(bullet)] : [],\n \"\",\n ...zoom(say(asked, \"open/full\"), full.flatMap((part) => [part, \"\"]).slice(0, -1))\n ]);\n};\n\n// ../provider-closure/world/dist/regions/operations.js\nvar render27 = (asked) => {\n const read = new Map(receipts(asked, \"offers\").map((line) => [of(line, \"scope\"), of(line, \"value\")]));\n const signature = (line) => {\n const [op, module] = [of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1), moduleOf(asked, line)];\n const head = module === void 0 ? void 0 : receiptValue(asked, \"source\", `source/signature/${op}`, module);\n return head === void 0 ? say(asked, \"reference/owed\") : cellText(head);\n };\n return [\n `## ${prose(asked, \"reference/operations\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/operations-table\") ?? \"\",\n \"|---|---|---|---|---|\",\n ...[...offers(asked)].sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))).map((line) => {\n const [view = \"\", op = \"\"] = steps(of(line, \"scope\")).slice(1);\n return `| ${op} | ${view} | \\`${signature(line)}\\` | ${((n) => Number.isNaN(n) ? 0 : n)(numeral(read.get(`${of(line, \"scope\")}/no-samples`)))} | ${cellText(keys(asked, of(line, \"restsOn\"))) || say(asked, \"reference/unrested\")} |`;\n })\n ];\n};\n\n// ../provider-closure/world/dist/regions/pointers.js\nvar render28 = (asked) => {\n const written = new Set(receipts(asked, \"state\").filter((one) => of(one, \"measure\") === \"fact\" && of(one, \"value\") === \"present\").map((one) => of(one, \"scope\").slice(of(one, \"scope\").indexOf(\"/\") + 1)));\n const views = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"view/\") && of(line, \"role\") === \"demands\");\n const pages = [...new Map(views.filter((view) => of(view, \"shape\").endsWith(\".md\") && of(view, \"shape\").includes(\"/\") && written.has(of(view, \"shape\"))).map((view) => [of(view, \"shape\"), view])).values()];\n const learn = pages.filter((view) => alphabet(of(view, \"value\")).members.some((token) => atResolution(token).name === \"learn\")).sort((a, b) => byBytes(of(a, \"shape\"), of(b, \"shape\")));\n const rest = pages.filter((view) => !learn.includes(view)).map((view) => [heading(asked, stem(of(view, \"shape\")).toLowerCase()), of(view, \"shape\")]).sort((a, b) => byBytes(a[0], b[0]));\n const bullets = [\n ...rest.map(([title, shape]) => `- [${title}](${shape})`),\n ...learn.length ? [`- ${say(asked, \"pointers/learn\", { pages: learn.map((view) => `[${words(asked, stem(of(view, \"shape\")))}](${of(view, \"shape\")})`).join(\", \") })}`] : []\n ];\n return resolved(asked, bullets.length ? [...section(asked, \"pointers\"), ...bullets] : []);\n};\n\n// ../provider-closure/world/dist/regions/ranges.js\nvar render29 = (asked) => {\n const one = reaches(asked, \"statement\") ? examples(asked).find((example) => example.name === stem(asked.shape)) : shortest(asked);\n const lines = reaches(asked, \"statement\") ? [] : sampled(asked, ((law) => law === void 0 ? \"\" : sample(asked, law, \"yes\").at ?? \"\")(object(asked)))?.lines ?? [];\n const cell2 = cellOfLines(lines.filter((line) => of(line, \"scope\") === of(lines[0], \"scope\"))) ?? (one === void 0 ? void 0 : cellOf(asked, one.at));\n if (cell2 === void 0)\n return [];\n const [held, alone, , forked] = states(asked);\n const apart = (i) => SPANS.inhabited(cell2.claims.filter((_, j) => j !== i).reduce((all, other) => SPANS.meet(all, other.span), SPANS.top));\n const g = spacing(asked, \"ranges\");\n const beat = (attribute, from, to) => from === void 0 || to === void 0 ? \"\" : ``;\n const [width, left, top, row] = [numeral(look(asked, \"width/figure\")), g.left, g.top, g.row];\n const right = width - g.right;\n const x = (v) => px(between(v, [cell2.hull.lo - g.pad, cell2.hull.hi + g.pad], [left, right]));\n const rows = [...cell2.claims.map((one2) => ({ label: one2.origin, ...one2.span, kind: \"claim\" })), { label: say(asked, \"cell/held-row\"), ...cell2.held, kind: \"held\" }];\n const [axis, meets] = [top + rows.length * row + g.axis, SPANS.inhabited(cell2.held)];\n const height = axis + (meets ? g.poles : g.tail);\n return [\n ``,\n `${say(asked, \"cell/title\")}`,\n `${escaped(described(asked, cell2))}`,\n ...style([css([[\"text\", { ...font(asked, \"text\", \"text\"), fill: painted(asked, \"text\").colour }]]), css([\n [\".claim\", { fill: alone?.colour }],\n [\".held\", { fill: held?.colour }],\n [\".pole\", { fill: held?.colour, \"font-weight\": look(asked, \"weight/strong\") }],\n [\".axis,.tick\", { stroke: alone?.colour, \"stroke-width\": look(asked, \"stroke/rule\") }],\n [\".touch\", { stroke: held?.colour, \"stroke-width\": look(asked, \"stroke/rule\"), \"stroke-dasharray\": look(asked, \"stroke/dash\") }]\n ])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ...meets ? [cell2.held.lo, cell2.held.hi].map((v) => ``) : [],\n ...rows.flatMap((bar, i) => [\n `${escaped(bar.label)}`,\n bar.kind === \"held\" && !meets ? `${escaped(prose(asked, \"apart\") ?? \"\")}` : ` moves2 ? `>${moves2}` : \"/>\")(bar.kind === \"held\" ? beat(\"opacity\", \"0\", \"1\") : beat(\"fill\", alone?.colour, meets ? held?.colour : apart(i) ? forked?.colour : void 0))}`\n ]),\n ``,\n ...[.../* @__PURE__ */ new Set([cell2.hull.lo, cell2.held.lo, cell2.held.hi, cell2.hull.hi])].sort((a, b) => a - b).flatMap((v) => [``, `${v}`]),\n ...meets ? [`${say(asked, \"cell/floor\")}`, `${say(asked, \"cell/ceiling\")}`] : [],\n \"\"\n ];\n};\n\n// ../provider-closure/world/dist/regions/reading.js\nvar render30 = (asked) => {\n const rows = receipts(asked, \"source\").filter((line) => of(line, \"scope\") === \"source/answers\");\n const named = (at) => rows.filter((one) => stem(placeOf(one)) === stem(at)).length > 1 ? (([last, parent = last]) => parent)([...steps(at)].reverse()) ?? stem(at) : stem(at);\n const order2 = listed(asked, \"docs/reading\");\n const rank = (name) => ((at) => at < 0 ? order2.length : at)(order2.indexOf(name));\n const answered = rows.map((line) => [named(placeOf(line)), of(line, \"value\")]).sort((a, b) => rank(a[0]) - rank(b[0])).map(([name, answer]) => say(asked, \"reading/view\", { name, answer })).filter(Boolean).map((one) => `- ${one}`);\n return answered.length ? [...titled(asked, \"reading\", [say(asked, \"reading/lead\")]), \"\", ...answered] : [];\n};\n\n// ../provider-closure/world/dist/regions/reference.js\nvar render31 = (asked) => {\n const forms = new Set(typedAs(asked, \"source/declared/\", value(asked, \"docs/forms\") ?? \"\", \"args\").map(([name, args]) => `- ${say(asked, \"reference/form\", { name, args: cellText(args) })}`));\n return [`# ${prose(asked, \"reference/heading\") ?? \"\"}`, \"\", say(asked, \"reference/lead\", { operations: offers(asked).length, laws: laws(asked).filter((line) => of(line, \"form\") !== \"formula\").length, forms: forms.size })];\n};\n\n// ../provider-closure/world/dist/regions/refuses.js\nvar render32 = (asked) => {\n const told = refusedCases(asked);\n const here = folder(asked.shape);\n const captured2 = told.map((one) => `- ${one.name}: ${one.why || one.input}`).filter((one) => one.length > 3);\n if (captured2.length) {\n return resolved(asked, [...section(asked, \"refuses\"), ...say(asked, \"refuses/lead\") ? [say(asked, \"refuses/lead\")] : [], \"\", ...captured2]);\n }\n const kept = laws(asked).filter((line) => of(line, \"kind\") !== \"conjecture\" && sample(asked, line, \"no\").recorded).sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\")));\n const law = kept.find((line) => of(line, \"scope\") === value(asked, \"notation/object\")) ?? kept[0];\n const no = law === void 0 ? void 0 : sample(asked, law, \"no\");\n const said = [law === void 0 ? \"\" : say(asked, \"refuses/lead\", { law: lawName(asked, law), at: relative(here, no?.at ?? \"\") })].filter(Boolean);\n return said.length ? resolved(asked, [\n ...section(asked, \"refuses\"),\n ...said,\n ...no?.about?.length ? [\"\", ...zoom(say(asked, \"refuses/full\"), no.about.flatMap((line) => [line, \"\"]).slice(0, -1))] : []\n ]) : [];\n};\n\n// ../provider-closure/world/dist/regions/regions.js\nvar rules = (asked) => ((held) => !held.length ? [] : [\n `# ${prose(asked, \"regions/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"regions/laws\", { count: count(asked, held.length, true) }),\n \"\",\n prose(asked, \"regions/laws-table\") ?? \"\",\n \"|---|---|\",\n ...held.map((line) => `| ${steps(steps(of(line, \"scope\")).slice(1))} | ${cellText(of(line, \"about\"))} |`)\n])(asked.lines.filter((line) => of(line, \"scope\").startsWith(\"audit/\") && of(line, \"role\") === \"demands\" && of(line, \"about\") !== \"\").sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))));\nvar render33 = (asked) => {\n const own = [...asked.lines, ...regionLines(asked, \"capsule\")];\n const said = (scope, measure) => own.filter((line) => of(line, \"scope\") === scope && (measure === void 0 || of(line, \"measure\") === measure)).flatMap((line) => alphabet(of(line, \"value\")).members);\n const names = [...new Set(own.filter((line) => of(line, \"scope\").startsWith(\"region/\") && of(line, \"measure\") === \"reads\" || of(line, \"scope\").startsWith(\"capsule/reads/\")).map((line) => of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1)))].sort();\n return resolved(asked, !names.length ? rules(asked) : [\n `# ${prose(asked, \"regions/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"regions/lead\", { count: count(asked, names.length, true), effects: listOf(asked, said(\"capsule/effects\")) || alphabet({ polarity: \"permit\", members: [] }) }),\n \"\",\n prose(asked, \"regions/table\") ?? \"\",\n \"|---|---|---|\",\n ...names.map((name) => `| ${name} | ${cellText([...said(`region/${name}`, \"reads\"), ...said(`capsule/reads/${name}`)].join(\" \\xB7 \"))} | ${cellText([...said(`region/${name}`, \"writes\"), ...said(`capsule/writes/${name}`)].join(\" \\xB7 \")) || say(asked, \"regions/leaf\")} |`)\n ]);\n};\n\n// ../provider-closure/world/dist/regions/rested-on-by.js\nvar render34 = (asked) => {\n const said = receipts(asked, \"state\").filter((line) => of(line, \"scope\").startsWith(\"rested/\"));\n const field = (place, name) => of(said.find((line) => of(line, \"scope\") === `rested/${place}/${name}`), \"value\");\n const places = [...new Set(said.map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))].filter((place) => field(place, \"source\")).sort(byBytes);\n return resolved(asked, places.length ? [...section(asked, \"rested\"), ...places.map((place) => `- ${say(asked, \"rested/place\", { place, repository: field(place, \"repository\") })}${field(place, \"what\") ? ` \\xB7 ${say(asked, \"rested/what\", { repository: field(place, \"repository\"), what: field(place, \"what\") })}` : \"\"}`)] : []);\n};\n\n// ../provider-closure/world/dist/regions/the-object.js\nvar machine = (asked) => {\n const [drawn3, renders] = [moves(asked), pairs(asked, \"notation/renders\")];\n if (drawn3 === void 0)\n return [];\n const colours = renders.flatMap(([state3, name]) => /* @__PURE__ */ ((colour) => colour === void 0 ? [] : [[state3, name, colour]])(painted(asked, state3).colour));\n return [\n \"```mermaid\",\n \"stateDiagram-v2\",\n ...renders.map(([state3, name]) => ` state \"${state3} \\xB7 ${name}\" as ${state3}`),\n ...drawn3.map((move) => ` ${move.from} --> ${move.to}${move.dangerous ? `: ${say(asked, \"states/dangerous\")}` : move.why ? `: ${move.why}` : \"\"}`),\n ...colours.flatMap(([, name, colour]) => classDef(name, colour, painted(asked, \"text-on\").colour)),\n ...colours.map(([state3, name]) => ` class ${state3} ${name}`),\n \"```\"\n ];\n};\nvar rests = (asked) => {\n const [held, on] = [object(asked), alphabet(of(object(asked), \"restsOn\")).members];\n if (held === void 0 || !on.length || !resting(asked, of(held, \"scope\")).length)\n return [];\n const colour = states(asked)[0]?.colour;\n return [\n `## ${prose(asked, \"reference/rests\") ?? \"\"}`,\n \"\",\n \"```mermaid\",\n \"flowchart BT\",\n ` o([\"${lawName(asked, held)}\"])`,\n ...on.map((scope, i) => ` r${i}([\"${labelOf(asked, scope)}\"])`),\n ...on.map((_, i) => ` o --> r${i}`),\n ...classDef(\"object\", colour, painted(asked, \"text-on\").colour),\n \" class o object\",\n \"```\"\n ];\n};\nvar render35 = (asked) => {\n if (reaches(asked, \"whole\"))\n return [`## ${prose(asked, \"reference/states\") ?? \"\"}`, \"\", ...machine(asked), \"\", ...rests(asked)];\n const head = tuple(asked);\n const written = head === void 0 ? [] : [\"```text\", head, ...aligned(asked), \"```\"];\n const [glyphs, rows] = [new Map(pairs(asked, \"notation/renders\").map(([state3]) => [state3, painted(asked, state3).glyph ?? \"\"])), pairs(asked, \"notation/states\")];\n const seen = /* @__PURE__ */ new Set();\n const unique = rows.filter(([, state3]) => seen.has(state3) ? false : (seen.add(state3), true));\n const [width, widest, gap] = [hull([0, ...unique.map(([when]) => when.length)]).hi, hull([0, ...unique.map(([, state3]) => state3.length)]).hi, spacing(asked, \"table/gap\")];\n const table2 = unique.length ? [\"```text\", ...unique.map(([when, state3]) => `${when.padEnd(width + gap.state)}${state3.padEnd(widest + gap.glyph)}${glyphs.get(state3) ?? \"\"}`), \"```\"] : [];\n return resolved(asked, !written.length && !table2.length ? [] : [`## ${prose(asked, \"the-object/heading\") ?? \"\"}`, \"\", ...written, ...table2.length ? [\"\", ...table2] : []]);\n};\n\n// ../provider-closure/world/dist/regions/the-paper.js\nvar render36 = (asked) => {\n const reference = (one) => {\n const doi = value(asked, \"sources/doi\") === void 0 ? void 0 : one.field(\"doi\");\n const address = doi === void 0 ? one.field(\"address\") : `${value(asked, \"sources/doi\")}${doi}`;\n const [authors, year, version, publisher] = [alphabet(one.field(\"author\") ?? \"\").members, one.field(\"year\"), one.field(\"version\"), one.field(\"publisher\")];\n return address === void 0 ? void 0 : [\n authors.length > 1 ? `${authors.slice(0, -1).join(\", \")}${say(asked, \"cite/and\")}${authors[authors.length - 1]}` : authors[0],\n year === void 0 ? void 0 : `(${year}).`,\n `${version === void 0 ? one.title : say(asked, \"cite/versioned\", { title: one.title, version })}.`,\n publisher === void 0 ? void 0 : `${publisher}.`,\n address\n ].filter(Boolean).join(\" \");\n };\n return resolved(asked, titled(asked, \"the-paper\", [...parted(asked, \"paper\"), ...entries(asked, \"cites\").flatMap((one) => reference(one) ?? [])]));\n};\n\n// ../provider-closure/world/dist/regions/units.js\nvar render37 = (asked) => [\n `## ${prose(asked, \"reference/units\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/units-table\") ?? \"\",\n \"|---|---|\",\n ...[...new Set(typedAs(asked, \"source/returns/\", value(asked, \"docs/units\") ?? \"\", \"params\").map(([name, params]) => `| ${name} | \\`${cellText(params)}\\` |`))].sort()\n];\n\n// ../provider-closure/world/dist/regions/what-holds.js\nvar table = (asked) => {\n const read = new Map(receipts(asked, \"laws\").map((line) => [of(line, \"scope\"), of(line, \"value\")]));\n const here = asked.shape.slice(0, asked.shape.lastIndexOf(\"/\"));\n const reproduced = (line) => ((got) => got === void 0 ? say(asked, \"reference/underived\") : say(asked, numeral(got) === 1 ? \"reference/yes\" : \"reference/no\"))([...read].find(([scope]) => scope.endsWith(`/${lawKey(line)}/reproduced`))?.[1]);\n const row = (line) => {\n const [yes, no, formula] = [sample(asked, line, \"yes\"), sample(asked, line, \"no\"), of(laws(asked).find((one) => of(one, \"form\") === \"formula\" && of(one, \"scope\").startsWith(`${of(line, \"scope\")}/`)), \"value\")];\n return `| ${lawKey(line)} | ${of(line, \"kind\") || say(asked, \"reference/unkinded\")} | ${of(line, \"view\") || say(asked, \"reference/any\")} | ${cellText(keys(asked, of(line, \"restsOn\"))) || say(asked, \"reference/nothing\")} | ${cellText(of(line, \"about\"))} | ${formula ? `\\`${cellText(formula)}\\`` : \"\"} | ${yes.recorded && yes.at ? `[${say(asked, \"reference/yes\")}](${relative(here, yes.at)})` : say(asked, \"reference/none\")} | ${cellText((no.about ?? [])[0] ?? say(asked, \"reference/derived\"))} | ${reproduced(line)} |`;\n };\n return [\n `## ${prose(asked, \"reference/laws\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/laws-table\") ?? \"\",\n \"|---|---|---|---|---|---|---|---|---|\",\n ...laws(asked).filter((line) => of(line, \"form\") !== \"formula\").sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))).map(row)\n ];\n};\nvar render38 = (asked) => {\n if (reaches(asked, \"whole\"))\n return table(asked);\n const rests2 = /* @__PURE__ */ new Map();\n for (const line of laws(asked))\n for (const on of alphabet(of(line, \"restsOn\")).members)\n rests2.set(on, (rests2.get(on) ?? 0) + 1);\n const held = laws(asked).filter((line) => of(line, \"kind\") === \"axiom\");\n if (!held.length)\n return [];\n const spelled = ((said) => said === void 0 ? 0 : numeral(said))(value(asked, \"docs/what-holds\"));\n const leaned = [...held].sort((a, b) => (rests2.get(of(b, \"scope\")) ?? 0) - (rests2.get(of(a, \"scope\")) ?? 0));\n const [rest, measured] = [held.filter((line) => !leaned.slice(0, spelled).includes(line)), lawAt(asked, value(asked, \"docs/measured\") ?? \"\")];\n return resolved(asked, [\n ...titled(asked, \"what-holds\", [\n say(asked, \"what-holds/lead\", { count: count(asked, held.length), spelled: count(asked, spelled, true) }),\n ...leaned.slice(0, spelled).map((line) => say(asked, \"what-holds/axiom\", { sentence: sentence(asked, of(line, \"about\")), name: lawName(asked, line), rests: rests2.get(of(line, \"scope\")) ?? 0 }))\n ]),\n ...rest.length ? [\"\", ...zoom(say(asked, \"what-holds/others\", { count: count(asked, rest.length) }), rest.map((line) => `- ${say(asked, \"what-holds/other\", { name: lawName(asked, line), about: of(line, \"about\") })}`))] : [],\n ...measured === void 0 ? [] : [\"\", say(asked, \"what-holds/measured\", { sentence: sentence(asked, of(measured, \"about\")), measured: (sample(asked, measured, \"yes\").about ?? []).slice(-1)[0] ?? \"\" }).trim()]\n ]);\n};\n\n// ../provider-closure/world/dist/regions/wire.js\nvar render39 = (asked) => {\n const [rules2, names, corpus] = [listed(asked, \"wire/rules\"), listed(asked, \"wire/reference\"), listed(asked, \"wire/corpus\")];\n if (!rules2.length && !names.length && !corpus.length)\n return [];\n const tokens = Object.fromEntries(pairs(asked, \"wire/tokens\"));\n const signed = (name) => of(receipts(asked, \"source\").find((one) => of(one, \"scope\") === `source/signature/${name}`), \"value\");\n const held = (name) => of(receipts(asked, \"vectors\").find((one) => of(one, \"scope\") === `vector/${name}`), \"value\");\n const reference = names.map((name) => `| \\`${name}\\` | \\`${cellText(signed(name))}\\` |`);\n return resolved(asked, [\n `# ${prose(asked, \"wire/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"wire/lead\", tokens),\n ...rules2.flatMap((rule2) => [\"\", ...titled(asked, `wire/${rule2}`, [say(asked, `wire/${rule2}`, tokens)])]),\n \"\",\n ...titled(asked, \"wire/reference\", [[prose(asked, \"wire/reference/table\") ?? \"\", \"|---|---|\", ...reference].join(\"\\n\")]),\n \"\",\n ...titled(asked, \"wire/corpus\", [corpus.map((name) => `- \\`vector/${name}\\` \\xB7 ${held(name)}`).join(\"\\n\")])\n ]);\n};\n\n// ../provider-closure/world/dist/regions/say.js\nvar render40 = (asked) => {\n const lines = asked.lines.filter((one) => {\n const scope = of(one, \"scope\");\n return (scope === `page/${asked.region}` || scope.startsWith(`page/${asked.region}/`)) && of(one, \"value\") !== \"withdraw\" && of(one, \"about\") !== \"\";\n });\n if (!lines.length)\n return [];\n const out = [];\n let heading2 = \"\";\n for (const line of lines) {\n const cap = of(line, \"shape\");\n if (cap && cap !== heading2 && !cap.includes(\".\")) {\n heading2 = cap;\n out.push(`## ${cap}`, \"\");\n }\n const strength = of(line, \"kind\") || \"declared\";\n out.push(`${sentence(asked, of(line, \"about\"))} \\xB7 ${strength}`);\n }\n return resolved(asked, out);\n};\n\n// ../provider-closure/world/dist/regions/term.js\nvar render41 = (asked) => {\n const line = asked.lines.find((one) => of(one, \"scope\").startsWith(\"term/\") && of(one, \"value\") !== \"withdraw\") ?? found(asked, `term/${asked.region}`) ?? found(asked, \"notation/object\");\n const word = of(line, \"value\");\n const meaning = of(line, \"about\");\n return !word && !meaning ? [] : resolved(asked, [`**${word}**${meaning ? ` \\u2014 ${meaning}` : \"\"}`]);\n};\n\n// ../provider-closure/world/dist/regions/count.js\nvar render42 = (asked) => {\n const receipts2 = Object.values(asked.regions).flatMap((region) => region.receipts);\n const named = asked.lines.filter((one) => of(one, \"scope\").startsWith(`page/${asked.region}/`) && of(one, \"value\") !== \"withdraw\").flatMap((one) => {\n const scope = of(one, \"scope\").slice(`page/${asked.region}/`.length);\n const matches2 = receipts2.filter((line) => of(line, \"scope\") === scope);\n if (matches2.length !== 1)\n return [];\n const got = of(matches2[0], \"value\");\n return got ? [`${of(one, \"about\") || scope} ${got}`] : [];\n });\n return resolved(asked, named);\n};\n\n// ../provider-closure/world/dist/regions/seq.js\nvar render43 = (asked) => {\n const lines = asked.lines.filter((one) => of(one, \"scope\").startsWith(`page/${asked.region}/`) && of(one, \"about\") !== \"\" && of(one, \"value\") !== \"withdraw\" && !of(one, \"scope\").endsWith(\"/heading\"));\n const steps2 = lines.length ? lines.map((one) => of(one, \"about\")) : alphabet(of(asked.regions[\"path\"]?.receipts.find((line) => of(line, \"scope\") === \"path/steps\") ?? {}, \"value\")).members.filter((one) => one !== \"none\");\n if (!steps2.length)\n return [];\n const heading2 = of(asked.lines.find((one) => of(one, \"scope\") === `page/${asked.region}/heading`), \"about\") || prose(asked, \"seq/heading\");\n return resolved(asked, [...heading2 ? [`## ${heading2}`, \"\"] : [], ...steps2.map((step, i) => `${i + 1}. ${step}`)]);\n};\n\n// ../provider-closure/world/dist/regions/exchange.js\nvar render44 = (asked) => {\n const held = examples(asked);\n const said = asked.lines.filter((one) => of(one, \"scope\").startsWith(`page/${asked.region}/`) && of(one, \"about\") !== \"\" && of(one, \"value\") !== \"withdraw\" && !of(one, \"scope\").endsWith(\"/heading\"));\n if (!held.length && !said.length)\n return [];\n const heading2 = of(asked.lines.find((one) => of(one, \"scope\") === `page/${asked.region}/heading`), \"about\");\n return resolved(asked, [\n ...heading2 ? [`## ${heading2}`, \"\"] : section(asked, \"exchange\"),\n ...held.flatMap((one, i) => [...i ? [\"\"] : [], ...glance(asked, one, folder(asked.shape))]),\n ...said.map((one) => of(one, \"about\"))\n ]);\n};\n\n// ../provider-closure/world/dist/regions/set.js\nvar render45 = (asked) => {\n const pins = alphabet(receiptValue(asked, \"rests\", \"rests-on/pins\") ?? \"\").members.filter((one) => one !== \"none\");\n const fromUses = asked.lines.filter((one) => of(one, \"scope\").startsWith(\"uses/\") && of(one, \"value\") !== \"withdraw\").map((one) => of(one, \"scope\").slice(\"uses/\".length).split(\"/\")[0] ?? \"\").filter(Boolean);\n const regions = alphabet(receiptValue(asked, \"rests\", \"rests-on/regions\") ?? \"\").members.filter((one) => one !== \"none\");\n const pinsHeld = [.../* @__PURE__ */ new Set([...pins, ...fromUses])];\n const members = [...pinsHeld.map((name) => ({ kind: \"pin\", name })), ...regions.map((name) => ({ kind: \"region\", name }))];\n if (!members.length)\n return [];\n return resolved(asked, [\n ...section(asked, \"set\"),\n \"| | |\",\n \"|---|---|\",\n ...members.map((one) => `| ${cellText(one.kind)} | ${cellText(one.name)} |`)\n ]);\n};\n\n// ../provider-closure/world/dist/regions/cell.js\nvar render46 = (asked) => {\n const lines = declaredSample(asked, figured(asked, asked.region, 1)[0]);\n const groups = /* @__PURE__ */ new Map();\n for (const line of lines) {\n const scope = of(line, \"scope\");\n const group = groups.get(scope) ?? [];\n group.push(line);\n groups.set(scope, group);\n }\n return [...groups.values()].flatMap((group) => {\n const cell2 = cellOfLines(group);\n if (cell2 === void 0)\n return [];\n const text = described(asked, cell2) || captioned(asked, cell2);\n return text ? [text] : [];\n });\n};\n\n// ../provider-closure/world/dist/regions/ref.js\nvar render47 = (asked) => {\n const views = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"view/\") && of(line, \"shape\").endsWith(\".md\"));\n const here = folder(asked.shape);\n const links = views.map((line) => {\n const at = of(line, \"shape\");\n const title = of(line, \"shape\").replace(/^.*\\//, \"\").replace(/\\.md$/, \"\") || of(line, \"scope\").slice(\"view/\".length);\n return `- [${title}](${relative(here, at)})`;\n });\n return links.length ? resolved(asked, links) : [];\n};\n\n// ../provider-closure/world/dist/regions/group.js\nvar render48 = (asked) => {\n const lines = asked.lines.filter((one) => {\n const scope = of(one, \"scope\");\n return (scope === `page/${asked.region}` || scope.startsWith(`page/${asked.region}/`)) && of(one, \"about\") !== \"\" && of(one, \"value\") !== \"withdraw\";\n });\n if (!lines.length)\n return [];\n return resolved(asked, lines.map((line) => {\n const scope = of(line, \"scope\");\n const mark2 = scope.endsWith(\"/title\") ? \"#\" : \"##\";\n return `${mark2} ${of(line, \"about\")}`;\n }));\n};\n\n// ../provider-closure/world/dist/index.js\nvar render49 = shell({ \"alphabet\": { reads: [\"lang\", \"prose/*/reference/*\", \"notation/*\"], region: render }, \"bond\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cell/*\", \"prose/*/apart\", \"notation/claim\", \"notation/renders\", \"examples/*\", \"region/examples\", \"region/source\", \"form/style/**\"], region: render2 }, \"cff\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cff/*\", \"cites/*\", \"name\", \"version\", \"author\", \"repository\", \"license\", \"sources/doi\", \"form/page/**\"], region: render3 }, \"check\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/check/*\", \"notation/renders\", \"fold\", \"repository\", \"repository/resolved\", \"check\", \"region/cases\", \"form/style/**\", \"form/page/**\"], region: render4 }, \"claims\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/claims/*\", \"claims/*\", \"dependencies\", \"audit/*\", \"region/state\", \"region/cases\", \"region/laws\", \"region/offers\", \"region/vectors\", \"region/examples\", \"form/page/**\"], region: render5 }, \"commands\": { reads: [\"lang\", \"prose/*/commands\", \"region/captures\", \"form/page/**\"], region: render6 }, \"door\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/door/*\", \"prose/*/cell/*\", \"prose/*/apart\", \"docs/what\", \"view/*\", \"notation/claim\", \"examples/*\", \"region/examples\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render7 }, \"figure\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cell/*\", \"prose/*/apart\", \"prose/*/marks\", \"view/*\", \"notation/claim\", \"examples/*\", \"region/examples\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render8 }, \"figure-fold\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"prose/*/cell/*\", \"form/figure/*\", \"notation/renders\", \"view/*\", \"samples/*\", \"region/laws\", \"form/style/**\"], region: render9 }, \"figure-line\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"form/figure/*\", \"notation/renders\", \"view/*\", \"samples/*\", \"region/laws\", \"form/style/**\"], region: render10 }, \"figure-refuses\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"notation/renders\", \"view/*\", \"region/vectors\", \"form/style/**\"], region: render11 }, \"figure-world\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"notation/renders\", \"view/*\", \"uses/*\", \"docs/world\", \"examples/*\", \"region/capsule\", \"region/examples\", \"region/source\", \"region/vectors\", \"form/runtime/*/regions\", \"form/style/**\"], region: render12 }, \"first-use\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/first-use/*\", \"prose/*/example/*\", \"examples/*\", \"region/examples\", \"form/runtime/*/run\", \"prose/*/figure/learn/*\", \"form/page/**\"], region: render13 }, \"forms\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reference/*\", \"docs/forms\", \"region/source\"], region: render14 }, \"guide-at-zero\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/guide/*\", \"prose/*/contributing\", \"check\", \"region/laws\", \"form/page/**\"], region: render15 }, \"hero\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/what\", \"prose/*/badge/*\", \"docs/logo\", \"docs/badges\", \"name\", \"notation/renders\", \"sources/*\", \"dependencies\", \"version\", \"license\", \"engines\", \"cites/*\", \"region/cases\", \"region/state\", \"docs/tagline\", \"form/style/**\", \"audit/wire/badges/world\"], region: render16 }, \"how-they-rest\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/rests/*\", \"prose/*/door/*\", \"name\", \"dependencies\", \"uses/*\", \"dep/**\", \"*/name\", \"*/dependencies\"], region: render17 }, \"idea\": { reads: [\"lang\", \"prose/*/idea\", \"prose/*/idea/*\", \"form/page/**\"], region: render18 }, \"install\": { reads: [\"install\", \"name\", \"uses/*\", \"sources/*\", \"host/resolve\", \"form/page/**\"], region: render20 }, \"line\": { reads: [\"sources/*\", \"uses/*\", \"host/resolve\", \"form/page/**\"], region: render19 }, \"learn\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/learn/**\", \"prose/*/cell/*\", \"prose/*/example/*\", \"prose/*/apart\", \"notation/*\", \"view/*\", \"examples/*\", \"region/examples\", \"region/source\", \"region/offers\", \"region/laws\", \"docs/learn\", \"form/runtime/*/run\", \"prose/*/figure/learn/*\", \"form/style/**\", \"form/page/**\"], region: render21 }, \"license\": { reads: [\"license\", \"form/page/**\"], region: render22 }, \"media\": { reads: [\"form/template/**\", \"form/style/**\", \"form/page/**\", \"media/**\"], region: render23 }, \"notation\": { reads: [\"lang\", \"form/prose/**\", \"prose/*/notation/*\", \"prose/*/reference/*\", \"notation/*\", \"region/laws\", \"region/offers\", \"region/source\", \"form/page/**\"], region: render24 }, \"open\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/open/*\", \"samples/*\", \"region/laws\", \"region/state\", \"form/page/**\"], region: render25 }, \"open-conjectures\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/open/*\", \"open/who\", \"samples/*\", \"region/laws\", \"form/page/**\"], region: render26 }, \"operations\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reference/*\", \"region/laws\", \"region/offers\", \"region/source\"], region: render27 }, \"pointers\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/pointers/*\", \"view/*\", \"region/state\", \"form/page/**\"], region: render28 }, \"ranges\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cell/*\", \"prose/*/apart\", \"notation/claim\", \"notation/renders\", \"notation/object\", \"examples/*\", \"samples/*\", \"region/examples\", \"region/laws\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render29 }, \"reading\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reading/*\", \"region/source\", \"docs/reading\"], region: render30 }, \"reference\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reference/*\", \"docs/forms\", \"region/laws\", \"region/offers\", \"region/source\"], region: render31 }, \"refuses\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/refuses/*\", \"notation/object\", \"samples/*\", \"region/laws\", \"region/vectors\", \"region/captures\", \"form/page/**\"], region: render32 }, \"regions\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/regions/*\", \"capsule/**\", \"audit/*\", \"region/**\", \"region/capsule\", \"form/page/**\"], region: render33 }, \"rested-on-by\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/rested/*\", \"region/state\", \"form/page/**\"], region: render34 }, \"the-object\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/the-object/*\", \"prose/*/reference/*\", \"prose/*/states/*\", \"notation/*\", \"region/laws\", \"region/offers\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render35 }, \"the-paper\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/paper\", \"prose/*/the-paper/*\", \"prose/*/cite/*\", \"cites/*\", \"sources/doi\", \"form/page/**\"], region: render36 }, \"units\": { reads: [\"lang\", \"prose/*/reference/*\", \"docs/units\", \"region/source\"], region: render37 }, \"what-holds\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/what-holds/*\", \"prose/*/reference/*\", \"docs/what-holds\", \"docs/measured\", \"samples/*\", \"region/laws\", \"form/page/**\"], region: render38 }, \"wire\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/wire/*\", \"prose/*/wire/*/*\", \"wire/*\", \"region/source\", \"region/vectors\", \"form/page/**\"], region: render39 }, \"say\": { reads: [\"lang\", \"page/**\", \"law/**\", \"docs/tagline\", \"form/page/**\", \"prose/**\"], region: render40 }, \"term\": { reads: [\"lang\", \"page/**\", \"term/**\", \"notation/**\", \"form/page/**\"], region: render41 }, \"count\": { reads: [\"lang\", \"name\", \"dependencies\", \"region/cases\", \"region/state\", \"form/page/**\", \"page/**\", \"prose/*/badge/**\"], region: render42 }, \"seq\": { reads: [\"lang\", \"page/**\", \"examples/*\", \"region/examples\", \"form/page/**\"], region: render43 }, \"exchange\": { reads: [\"lang\", \"page/**\", \"examples/*\", \"region/examples\", \"form/page/**\", \"form/runtime/*/run\", \"prose/*/figure/learn/*\"], region: render44 }, \"set\": { reads: [\"lang\", \"page/**\", \"uses/*\", \"dep/**\", \"region/state\", \"form/page/**\"], region: render45 }, \"cell\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"prose/*/cell/*\", \"form/figure/*\", \"notation/renders\", \"view/*\", \"samples/*\", \"region/laws\", \"form/style/**\", \"examples/*\", \"region/examples\", \"region/source\", \"region/vectors\", \"region/capsule\", \"docs/world\", \"uses/*\", \"form/runtime/*/regions\"], region: render46 }, \"ref\": { reads: [\"lang\", \"view/*\", \"form/page/**\"], region: render47 }, \"group\": { reads: [\"lang\", \"page/**\", \"prose/**\", \"form/page/**\"], region: render48 } });\nvar receipt2 = receiptShell({ \"unreceipted\": { reads: [\"lang\", \"prose/*/commands\", \"prose/*/idea\", \"region/state\", \"region/captures\", \"form/page/**\"], region: receipt } });\nexport {\n receipt2 as receipt,\n render49 as render\n};\n", + "providerDigest": "sha256:3c4bb28406ae7f56a8946ead2236a327fdaa29a44d05ae0ccf50af292c1f53ab", + "provenance": { + "artifact": "sha256:04feef01a8c59cae7ea842198d1faf0091b424129872a847b41c7da0bca6fabf", + "member": "dist/index.js", + "fixtureOnly": true, + "license": "MIT", + "licenseText": "MIT License\n\nCopyright (c) 2026 Lapxo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + "regions": [ + { + "name": "cff", + "reads": "lang|form/prose/**|form/template/**|prose/*/cff/*|cites/*|name|version|author|repository|license|sources/doi|form/page/**" + }, + { + "name": "seq", + "reads": "lang|page/**|examples/*|region/examples|form/page/**" + }, + { + "name": "term", + "reads": "lang|page/**|term/**|notation/**|form/page/**" + }, + { + "name": "set", + "reads": "lang|page/**|uses/*|dep/**|region/state|form/page/**" + }, + { + "name": "ref", + "reads": "lang|view/*|form/page/**" + }, + { + "name": "commands", + "reads": "lang|prose/*/commands|region/captures|form/page/**" + }, + { + "name": "hero", + "reads": "lang|form/prose/**|form/template/**|prose/*/what|prose/*/badge/*|docs/logo|docs/badges|name|notation/renders|sources/*|dependencies|version|license|engines|cites/*|region/cases|region/state|docs/tagline|form/style/**|audit/wire/badges/world" + }, + { + "name": "idea", + "reads": "lang|prose/*/idea|prose/*/idea/*|form/page/**" + }, + { + "name": "refuses", + "reads": "lang|form/prose/**|form/template/**|prose/*/refuses/*|notation/object|samples/*|region/laws|region/vectors|region/captures|form/page/**" + }, + { + "name": "what-holds", + "reads": "lang|form/prose/**|form/template/**|prose/*/what-holds/*|prose/*/reference/*|docs/what-holds|docs/measured|samples/*|region/laws|form/page/**" + } + ], + "wire": [ + [ + "fields", + "scope|role|form|measure|value|by|at|epoch|sig|needs|shape|about|kind|restsOn" + ], + [ + "required", + "scope|role|form|measure|value|by|at" + ], + [ + "forms", + "alphabet|interval" + ], + [ + "families", + "keys|signer|wire|sample|tree|write|leaf|view|reader|read|fold|receipts|rendered|resolved|beat|region|prose|uses|dep|name|version|author|repository|license|lang|form|page|term|sources|build" + ], + [ + "roles", + "reads|writes|demands" + ], + [ + "at-classes", + "policy|place|origin|witness|receipt" + ], + [ + "era", + "sample" + ], + [ + "signature-algorithms", + "ed25519:sample" + ], + [ + "digest-algorithms", + "sha256" + ], + [ + "region-measures", + "coordinates|leaves|reads|receipts" + ] + ], + "places": [ + { + "name": "specimen-register", + "version": "1.4.2", + "term": "specimen", + "meaning": "An item assigned a local identifier.", + "heading": "Prepare the register", + "steps": [ + "Assign a local identifier.", + "Record the observed properties." + ], + "buildOptions": { + "target": "ES2022", + "strict": "true", + "declaration": "true", + "include": "src/**/*.ts|types/**/*.ts" + }, + "idea": "Keep independent readings of specimen-register visible.", + "ideaHeading": "Reading specimen-register", + "tagline": "A declared place for specimen-register.", + "outputs": [ + { + "view": "usage-profile", + "path": "notes.md", + "body": "# Observations\n\nA field note belongs to its place.\n" + }, + { + "view": "manifest-render", + "path": "manifest.json", + "body": "{\"name\":\"field-notes\"}\n" + }, + { + "view": "release-workflow-render", + "path": "process.yml", + "body": "name: field-work\non: push\n" + } + ] + }, + { + "name": "route-notes", + "version": "3.2.1", + "term": "stop", + "meaning": "A location named in an itinerary.", + "heading": "Prepare the itinerary", + "steps": [ + "Name the intended stops.", + "Record each connection." + ], + "buildOptions": { + "target": "ES2020", + "strict": "false", + "module": "NodeNext", + "include": "lib/**/*.ts" + }, + "idea": "Keep independent readings of route-notes visible.", + "ideaHeading": "Reading route-notes", + "tagline": "A declared place for route-notes.", + "outputs": [ + { + "view": "usage-profile", + "path": "catalogue.md", + "body": "# Collection\n\nAn item keeps its provenance.\n" + }, + { + "view": "manifest-render", + "path": "catalogue.json", + "body": "{\"name\":\"collection\"}\n" + }, + { + "view": "release-workflow-render", + "path": "catalogue.yml", + "body": "name: catalogue\non: push\n" + } + ] + } + ], + "buildProvider": { + "providerSource": "var __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/index.ts\nvar index_exports = {};\n__export(index_exports, {\n render: () => render\n});\nmodule.exports = __toCommonJS(index_exports);\n\n// node_modules/@lapxo/topos/dist/capsule/asked.js\nvar of = (line, field) => line?.[field] ?? \"\";\nvar found = (asked, scope) => asked.lines.find((line) => of(line, \"scope\") === scope);\nvar value = (asked, scope) => found(asked, scope) === void 0 ? void 0 : of(found(asked, scope), \"value\");\nvar listed = (asked, scope) => (value(asked, scope) ?? \"\").split(\"|\").filter(Boolean);\nvar lang = (asked) => value(asked, \"lang\") ?? \"\";\nvar at = (asked, scope) => ((line) => line === void 0 ? void 0 : of(line, \"value\"))(asked.lines.find((line) => of(line, \"scope\") === scope && of(line, \"shape\") === asked.shape));\nvar under = (asked, head) => asked.lines.filter((line) => of(line, \"shape\") === asked.shape && (of(line, \"scope\") === head || of(line, \"scope\").startsWith(`${head}/`))).map((line) => [of(line, \"scope\").slice(head.length + (of(line, \"scope\") === head ? 0 : 1)), of(line, \"value\")]).sort((a, b) => a[0] === \"\" ? -1 : b[0] === \"\" ? 1 : a[0].localeCompare(b[0]));\nvar json = (held) => `${JSON.stringify(held, null, 2)}\n`.split(\"\\n\").slice(0, -1);\nvar truth = (text) => text === \"true\" ? true : text === \"false\" ? false : text;\nvar sentence = (asked, text) => {\n const rule = listed(asked, `form/prose/${lang(asked)}/sentence`);\n let end = text.length;\n while (end > 0 && \".;:, \\n\".includes(text.charAt(end - 1)))\n end -= 1;\n const start = rule.includes(\"capital\") ? `${text.charAt(0).toUpperCase()}${text.slice(1, end)}` : text.slice(0, end);\n return rule.includes(\"period\") ? `${start}.` : start;\n};\n\n// node_modules/@lapxo/topos/dist/capsule/shell.js\nfunction shell(regions) {\n return (asked) => {\n const one = regions[asked.region];\n if (one === void 0)\n throw new Error(`REFUSE\\xB7region ${asked.region}: no line of this capsule renders it`);\n const short = one.reads.filter((read) => !asked.reads.includes(read));\n if (short.length)\n throw new Error(`REFUSE\\xB7region ${asked.region}: handed less than it declares, without ${short.join(\" \\xB7 \")}`);\n return one.region(asked);\n };\n}\n\n// src/regions/build.ts\nvar build = (asked) => {\n const options = under(asked, \"build\").filter(([name]) => name !== \"\");\n const include = options.find(([name]) => name === \"include\")?.[1];\n return json({ compilerOptions: Object.fromEntries(options.filter(([name]) => name !== \"include\").map(([name, held]) => [name, truth(held)])), ...include === void 0 ? {} : { include: include.split(\"|\") } });\n};\n\n// src/regions/manifest.ts\nvar versioned = (text) => Object.fromEntries((text ?? \"\").split(\"|\").filter(Boolean).map((one) => [one.slice(0, one.lastIndexOf(\"@\")), one.slice(one.lastIndexOf(\"@\") + 1)]));\nvar manifest = (asked) => {\n const [subpaths, bins, source, what] = [under(asked, \"exports\"), under(asked, \"bin\").filter(([name]) => name !== \"\"), at(asked, \"source\"), found(asked, `prose/${lang(asked)}/what`)];\n const resolved = (built) => ({ ...source ? { source: `./${source}${built.slice(built.indexOf(\"/\"))}.ts` } : {}, types: `./${built}.d.ts`, default: `./${built}.js` });\n const [repository, kind, side] = [at(asked, \"repository\"), at(asked, \"type\"), at(asked, \"sideEffects\")];\n return json({\n name: at(asked, \"name\"),\n version: at(asked, \"version\"),\n description: what === void 0 ? void 0 : sentence(asked, of(what, \"about\")),\n ...kind ? { type: kind } : {},\n license: at(asked, \"license\"),\n author: at(asked, \"author\"),\n ...repository ? { repository: { type: \"git\", url: `git+${repository}.git` } } : {},\n keywords: (at(asked, \"keywords\") ?? \"\").split(\"|\").filter(Boolean),\n ...side === void 0 ? {} : { sideEffects: truth(side) },\n engines: { node: at(asked, \"engines\") },\n exports: { ...Object.fromEntries(subpaths.map(([sub, built]) => [sub === \"\" ? \".\" : `./${sub}`, resolved(built)])), [`./${asked.shape}`]: `./${asked.shape}` },\n ...bins.length ? { bin: Object.fromEntries(bins.map(([name, built]) => [name, `./${built}.js`])) } : {},\n files: listed(asked, \"audit/wire/ships\"),\n scripts: Object.fromEntries(under(asked, \"scripts\").filter(([name]) => name !== \"\")),\n ...at(asked, \"dependencies\") === void 0 ? {} : { dependencies: versioned(at(asked, \"dependencies\")) },\n ...at(asked, \"devDependencies\") === void 0 ? {} : { devDependencies: versioned(at(asked, \"devDependencies\")) }\n });\n};\n\n// src/regions/published-manifest.ts\nvar publishedManifest = (asked) => {\n const held = JSON.parse(manifest(asked).join(\"\\n\"));\n for (const one of Object.values(held[\"exports\"])) if (typeof one === \"object\" && one !== null) delete one[\"source\"];\n return json(held);\n};\n\n// src/index.ts\nvar render = shell({\n build: { reads: [\"build/**\"], region: build },\n manifest: { reads: [\"name\", \"version\", \"type\", \"license\", \"author\", \"repository\", \"keywords\", \"sideEffects\", \"engines\", \"exports/**\", \"bin/**\", \"scripts/**\", \"dependencies\", \"devDependencies\", \"source\", \"lang\", \"prose/*/what\", \"form/prose/*/sentence\", \"audit/wire/ships\"], region: manifest },\n \"published-manifest\": { reads: [\"name\", \"version\", \"type\", \"license\", \"author\", \"repository\", \"keywords\", \"sideEffects\", \"engines\", \"exports/**\", \"bin/**\", \"scripts/**\", \"dependencies\", \"devDependencies\", \"source\", \"lang\", \"prose/*/what\", \"form/prose/*/sentence\", \"audit/wire/ships\"], region: publishedManifest }\n});\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n render\n});\n", + "providerDigest": "sha256:53c974b95957f654f13398bd6b2f781cb4b86f9f93a54d7a59fb2e4d38a7e017", + "provenance": { + "artifact": "sha256:384a74b07eb8c7235e584b2801dbda1d78acd7ef6dac933ab05400a40658c55b", + "member": "dist/index.js", + "fixtureOnly": true + }, + "regions": [ + { + "name": "build", + "reads": "build/**" + } + ] + }, + "proseProvider": { + "providerSource": "/** Verbatim prose explicitly assigned to the requested output. The host chooses no format or project vocabulary. */\nexport const render = (asked) => {\n const bodies = [...new Set(asked.lines.filter(line => line.scope?.startsWith('prose/') && line.measure === 'text' && line.shape === asked.shape && line.value !== 'withdraw').map(line => line.about).filter((body) => body !== undefined))];\n if (bodies.length > 1)\n throw Error(`REFUSE\u00b7view conflicting prose names ${asked.shape}`);\n return bodies;\n};\n", + "providerDigest": "sha256:8e322a6ed813609ed6233c5c82812e63eec0480be1eaa46fef62b59cd4c01531" + } +} diff --git a/samples/yes/historical-presentation.json b/samples/yes/historical-presentation.json new file mode 100644 index 0000000..e04b600 --- /dev/null +++ b/samples/yes/historical-presentation.json @@ -0,0 +1,92 @@ +{ + "profile": "topos-doc-historical@0.1.2", + "providerSource": "// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/values.js\nfunction unpipe(value2) {\n const out = [];\n let at = \"\";\n for (let i = 0; i < value2.length; i++) {\n const c = value2[i];\n if (c === \"\\\\\") {\n const next = value2[i + 1];\n if (next !== \"|\" && next !== \"\\\\\")\n return null;\n at += next;\n i += 1;\n } else if (c === \"|\") {\n out.push(at);\n at = \"\";\n } else {\n at += c;\n }\n }\n out.push(at);\n return out;\n}\nvar OPEN = \"*\";\nvar num = (s) => {\n if (!/^-?\\d+(\\.\\d+)?$/.test(s))\n return null;\n const n = Number(s);\n return isFinite(n) ? n : null;\n};\nvar GRAMMARS = {\n interval: (value2) => {\n const at = value2.indexOf(\"..\");\n if (at < 0)\n return null;\n const lo = value2.slice(0, at);\n const hi = value2.slice(at + 2);\n const l = lo === OPEN ? null : num(lo);\n const h = hi === OPEN ? null : num(hi);\n if (lo !== OPEN && l === null || hi !== OPEN && h === null)\n return null;\n return { kind: \"interval\", lo: l, hi: h };\n },\n alphabet: (value2) => {\n const values = unpipe(value2);\n return values === null ? null : { kind: \"enumerated\", values };\n },\n ladder: (value2) => {\n const parts2 = unpipe(value2);\n if (parts2 === null || parts2.length !== 2)\n return null;\n return { kind: \"band\", floor: parts2[0] ?? \"\", ceiling: parts2[1] ?? \"\" };\n }\n};\nfunction boundOf(form2, value2, grammars) {\n const extra = Array.isArray(grammars) ? grammars.find((g) => g.form === form2) : void 0;\n if (extra)\n return extra.parse(value2);\n return GRAMMARS[form2]?.(value2) ?? null;\n}\nvar BOUND_FORMS = Object.keys(GRAMMARS);\nvar REF_RELATIONS = [\"within\", \"copies\", \"derives\"];\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/grammar.js\nvar [FORBID, EMPTY, MEMBER, PAIR, STEP, AT, EVERY, ESCAPE] = [\"not:\", \"none\", \"|\", \"=\", \"/\", \"@\", \"*\", \"\\\\\"];\nvar refuse = (grammar, why) => {\n throw new Error(`REFUSE\\xB7wire ${grammar}: ${why}`);\n};\nvar digits = (text) => text !== \"\" && [...text].every((one) => one >= \"0\" && one <= \"9\");\nfunction alphabet(given) {\n if (typeof given !== \"string\") {\n const written = given.members.map((one) => one.split(ESCAPE).join(ESCAPE + ESCAPE).split(MEMBER).join(ESCAPE + MEMBER)).join(MEMBER);\n if (given.polarity === \"forbid\")\n return FORBID + written;\n return written.startsWith(FORBID) || written === EMPTY ? refuse(\"alphabet\", \"a permitted alphabet neither begins with not: nor is the one word none\") : written || EMPTY;\n }\n const forbid = given.startsWith(FORBID);\n const body = forbid ? given.slice(FORBID.length) : given;\n const members = !forbid && body === EMPTY ? [] : unpipe(body) ?? refuse(\"alphabet\", \"a backslash escapes only a pipe or itself\");\n return { polarity: forbid ? \"forbid\" : \"permit\", members: members.filter((one) => one !== \"\") };\n}\nfunction fields(given) {\n if (typeof given !== \"string\")\n return alphabet({ polarity: \"permit\", members: given.map(([key, value2]) => key + PAIR + value2) });\n const read = alphabet(given);\n if (read.polarity === \"forbid\")\n refuse(\"fields\", \"fields carry no polarity\");\n return read.members.map((one) => one.indexOf(PAIR) > 0 ? [one.slice(0, one.indexOf(PAIR)), one.slice(one.indexOf(PAIR) + 1)] : refuse(\"fields\", `\\`${one}\\` is not key=value`));\n}\nfunction steps(given) {\n if (typeof given === \"string\")\n return given.split(STEP);\n return given.some((one) => one.includes(STEP)) ? refuse(\"steps\", \"a step holds no slash\") : given.join(STEP);\n}\nfunction atResolution(given) {\n if (typeof given !== \"string\")\n return given.at === void 0 ? given.name : given.name + AT + String(given.at);\n const at = given.lastIndexOf(AT);\n if (at < 0)\n return { name: given };\n const [name, said] = [given.slice(0, at), given.slice(at + 1)];\n if (name === \"\" || said !== EVERY && !digits(said))\n refuse(\"atResolution\", `\\`${given}\\` is not name@digits or name@*`);\n return { name, at: said === EVERY ? EVERY : Number(said) };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/capsule/asked.js\nvar of = (line, field) => line?.[field] ?? \"\";\nvar found = (asked, scope) => asked.lines.find((line) => of(line, \"scope\") === scope);\nvar value = (asked, scope) => found(asked, scope) === void 0 ? void 0 : of(found(asked, scope), \"value\");\nvar listed = (asked, scope) => alphabet(value(asked, scope) ?? \"\").members;\nvar lang = (asked) => value(asked, \"lang\") ?? \"\";\nvar receipts = (asked, region) => asked.regions[region]?.receipts ?? [];\nvar placeOf = (line) => of(line, \"at\").replace(/^[^:]*:/, \"\");\nvar regionLines = (asked, region) => asked.regions[region]?.lines ?? [];\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/classes.js\nfunction matchStar(pat, seg) {\n if (!pat.includes(\"*\"))\n return pat === seg;\n const bits = pat.split(\"*\");\n if (!seg.startsWith(bits[0]))\n return false;\n let i = bits[0].length;\n for (let b = 1; b < bits.length; b++) {\n const bit = bits[b];\n if (bit === \"\")\n return b === bits.length - 1 || matchStar(bits.slice(b).join(\"*\"), seg.slice(i));\n const hit = seg.indexOf(bit, i);\n if (hit < 0)\n return false;\n i = hit + bit.length;\n }\n return i === seg.length || pat.endsWith(\"*\");\n}\nfunction matchParts(g, gi, p, pi) {\n if (gi === g.length)\n return pi === p.length;\n if (g[gi] === \"**\") {\n if (gi + 1 === g.length)\n return true;\n for (let k = pi; k <= p.length; k++) {\n if (matchParts(g, gi + 1, p, k))\n return true;\n }\n return false;\n }\n if (pi === p.length)\n return false;\n if (!matchStar(g[gi], p[pi]))\n return false;\n return matchParts(g, gi + 1, p, pi + 1);\n}\nfunction matches(glob, place) {\n return matchParts(glob.split(\"/\"), 0, place.split(\"/\"), 0);\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/outcome.js\nvar fact = (value2) => ({ kind: \"fact\", value: value2 });\nvar abstain = (why) => ({ kind: \"abstain\", why });\nvar refuse2 = (why, named) => ({ kind: \"refuse\", why, ...named === void 0 ? {} : { named } });\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/line.js\nvar PROTOCOL = \"bound-lock/1\";\nvar NEEDS_QUOTE = /[ =\"\\n\\\\]/;\nfunction escape(value2) {\n if (!NEEDS_QUOTE.test(value2))\n return value2;\n return `\"${value2.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\"`;\n}\nfunction unescape(token) {\n if (!token.startsWith('\"'))\n return NEEDS_QUOTE.test(token) ? null : token;\n if (token.length < 2 || !token.endsWith('\"'))\n return null;\n const body = token.slice(1, -1);\n let out = \"\";\n for (let i = 0; i < body.length; i++) {\n const c = body[i];\n if (c !== \"\\\\\") {\n if (c === '\"')\n return null;\n out += c;\n continue;\n }\n const next = body[i + 1];\n if (next === '\"')\n out += '\"';\n else if (next === \"\\\\\")\n out += \"\\\\\";\n else if (next === \"n\")\n out += \"\\n\";\n else\n return null;\n i += 1;\n }\n return out;\n}\nvar UTF8 = new TextEncoder();\nfunction byBytes(a, b) {\n const x = UTF8.encode(a);\n const y = UTF8.encode(b);\n for (let i = 0; i < x.length && i < y.length; i++) {\n if (x[i] !== y[i])\n return x[i] - y[i];\n }\n return x.length - y.length;\n}\nvar unwritten = (fields2) => fields2[\"form\"] === \"interval\" && fields2[\"value\"] !== void 0 && fields2[\"value\"] !== \"withdraw\" && boundOf(\"interval\", fields2[\"value\"]) === null;\nfunction canonical(fields2, version = \"1\") {\n if (unwritten(fields2))\n throw new Error(`REFUSE\\xB7wire canonical: \\`${fields2[\"value\"]}\\` is no interval the wire writes: two ends, each decimal or *`);\n const keys2 = Object.keys(fields2).sort(byBytes);\n const tokens = keys2.map((k) => `${k}=${escape(fields2[k])}`);\n return [`${PROTOCOL.split(\"/\")[0]}/${version}`, ...tokens].join(\" \");\n}\nvar ABSENT = \"-\";\nfunction parse(text) {\n if (text.includes(\"\\n\")) {\n return refuse2(\"a line is one line \\u2014 a newline in a value must be escaped as `\\\\n`\");\n }\n const space = text.indexOf(\" \");\n const envelope = space === -1 ? text : text.slice(0, space);\n const [name, version] = envelope.split(\"/\");\n if (name !== PROTOCOL.split(\"/\")[0] || !version) {\n return refuse2(`no \\`bound-lock/\\` envelope \\u2014 found \\`${envelope.slice(0, 24)}\\``);\n }\n if (version !== PROTOCOL.split(\"/\")[1]) {\n return abstain(`\\`bound-lock/${version}\\` is a version this reader does not know`);\n }\n const fields2 = {};\n for (const token of tokensOf(space === -1 ? \"\" : text.slice(space + 1))) {\n if (token === null)\n return refuse2(\"a quoted value is not closed\");\n const at = token.indexOf(\"=\");\n if (at <= 0)\n return refuse2(`\\`${token.slice(0, 24)}\\` is not \\`key=value\\``);\n const key = token.slice(0, at);\n if (key in fields2)\n return refuse2(`\\`${key}\\` appears twice \\u2014 one line, one value per key`);\n const value2 = unescape(token.slice(at + 1));\n if (value2 === null)\n return refuse2(`\\`${key}\\` has an escaping this format does not define`);\n if (value2 !== ABSENT)\n fields2[key] = value2;\n }\n if (unwritten(fields2))\n return refuse2(`\\`${fields2[\"value\"]}\\` is no interval the wire reads: two ends, each decimal or *`);\n return fact({ version, fields: fields2 });\n}\nfunction* tokensOf(rest) {\n let at = 0;\n while (at < rest.length) {\n while (rest[at] === \" \")\n at += 1;\n if (at >= rest.length)\n return;\n let end = at;\n let quoted = false;\n while (end < rest.length && (quoted || rest[end] !== \" \")) {\n if (rest[end] === \"\\\\\" && quoted)\n end += 1;\n else if (rest[end] === '\"')\n quoted = !quoted;\n end += 1;\n }\n if (quoted) {\n yield null;\n return;\n }\n yield rest.slice(at, end);\n at = end;\n }\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/capsule/declaration.js\nvar standing = (lines) => lines.flatMap((line) => {\n const got = parse(line);\n return got.kind === \"fact\" && got.value.fields[\"value\"] !== \"withdraw\" ? [got.value.fields] : [];\n});\nfunction handed(reads, lines) {\n return standing(lines).filter((fields2) => reads.some((region) => matches(region, fields2[\"scope\"] ?? \"\")));\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/capsule/shell.js\nfunction shell(regions) {\n return typeof regions === \"string\" ? located(regions) : dispatch(regions, \"renders\");\n}\nvar dispatch = (regions, verb) => (asked) => {\n const one = regions[asked.region];\n if (one === void 0)\n throw new Error(`REFUSE\\xB7region ${asked.region}: no line of this capsule ${verb} it`);\n const short = one.reads.filter((read) => !asked.reads.includes(read));\n if (short.length)\n throw new Error(`REFUSE\\xB7region ${asked.region}: handed less than it declares, without ${short.join(\" \\xB7 \")}`);\n return one.region(asked);\n};\nvar located = (url) => Object.assign(() => {\n throw new Error(`REFUSE\\xB7world ${url}: its host answers it by the regions its own lock names`);\n}, { world: url });\nvar counted = (asked, what, n, measure) => [{ scope: `${asked.region}/${what}`, measure, role: \"reads\", bound: { kind: \"interval\", lo: n, hi: n } }];\nfunction receiptShell(regions) {\n return typeof regions === \"string\" ? located(regions) : dispatch(regions, \"answers\");\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/errors.js\nvar UnitError = class _UnitError extends Error {\n code;\n detail;\n constructor(code, message, detail = {}) {\n super(message);\n this.name = \"UnitError\";\n this.code = code;\n this.detail = Object.freeze({ ...detail });\n Object.setPrototypeOf(this, _UnitError.prototype);\n }\n};\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/order.js\nfunction build(levels, join, meet2) {\n const n = levels.length;\n for (let i = 0; i < n; i++) {\n if (levels.indexOf(levels[i]) !== i) {\n throw new UnitError(\"DUPLICATE_LEVEL\", `the level \\`${levels[i]}\\` is declared twice`, {\n level: levels[i]\n });\n }\n }\n const index = new Map(levels.map((l, i) => [l, i]));\n const leq = (a, b) => join[a][b] === b;\n const total = levels.every((_, i) => levels.every((__, j) => join[i][j] === i || join[i][j] === j));\n let simple = true;\n for (let x = 0; x < n && simple; x++) {\n for (let y = 0; y < n && simple; y++) {\n for (let z = 0; z < n; z++) {\n if (meet2[x][join[y][z]] !== join[meet2[x][y]][meet2[x][z]]) {\n simple = false;\n break;\n }\n }\n }\n }\n const all = [...levels.keys()];\n const bottomIx = all.find((i) => all.every((j) => leq(i, j))) ?? 0;\n const topIx = all.find((i) => all.every((j) => leq(j, i))) ?? n - 1;\n const joinIrr = all.filter((j) => j !== bottomIx && all.filter((x) => x !== j && leq(x, j)).reduce((acc, x) => join[acc][x], bottomIx) !== j);\n const meetIrr = all.filter((m) => m !== topIx && all.filter((x) => x !== m && leq(m, x)).reduce((acc, x) => meet2[acc][x], topIx) !== m);\n const seen = /* @__PURE__ */ new Set();\n const allDebits = [];\n for (const x of [...joinIrr, ...meetIrr]) {\n if (!seen.has(x)) {\n seen.add(x);\n allDebits.push(x);\n }\n }\n return {\n levels,\n isLadder: total,\n isSimple: simple,\n bottomIx,\n topIx,\n bottom: levels[bottomIx],\n top: levels[topIx],\n leq,\n higher: (a, b) => join[a][b],\n lower: (a, b) => meet2[a][b],\n rank(level) {\n const r = index.get(level);\n if (r === void 0) {\n throw new UnitError(\"UNKNOWN_LEVEL\", `no level \\`${level}\\` in this scale`, {\n level,\n levels\n });\n }\n return r;\n },\n stateOf(floor, ceiling) {\n if (!leq(floor, ceiling))\n return \"CONFLICT\";\n if (floor !== bottomIx)\n return \"REQUIRED\";\n if (ceiling !== topIx)\n return \"FORBIDDEN\";\n return \"FREE\";\n },\n joins: () => joinIrr.slice(),\n limits: () => meetIrr.slice(),\n debits: () => allDebits.slice(),\n intervalHeight(lo, hi) {\n if (!leq(lo, hi))\n return null;\n const inside = all.filter((x) => leq(lo, x) && leq(x, hi));\n const covers = (x) => inside.filter((y) => y !== x && leq(x, y) && !inside.some((z) => z !== x && z !== y && leq(x, z) && leq(z, y)));\n const long = /* @__PURE__ */ new Map([[lo, 0]]);\n const short = /* @__PURE__ */ new Map([[lo, 0]]);\n const walk = [...inside].sort((a, b) => inside.filter((z) => leq(z, a)).length - inside.filter((z) => leq(z, b)).length);\n for (const x of walk) {\n const lx = long.get(x);\n const sx = short.get(x);\n if (lx === void 0 || sx === void 0)\n continue;\n for (const y of covers(x)) {\n long.set(y, Math.max(long.get(y) ?? lx + 1, lx + 1));\n short.set(y, Math.min(short.get(y) ?? sx + 1, sx + 1));\n }\n }\n const l = long.get(hi);\n return l !== void 0 && l === short.get(hi) ? l : null;\n }\n };\n}\nfunction chain(levels) {\n if (!Array.isArray(levels) || levels.length === 0) {\n throw new UnitError(\"EMPTY_CHAIN\", \"a chain needs at least one level\");\n }\n const n = levels.length;\n const grid = (f) => [...Array(n)].map((_, i) => [...Array(n)].map((__, j) => f(i, j)));\n return build(levels, grid(Math.max), grid(Math.min));\n}\nfunction order(levels, leq) {\n if (!Array.isArray(levels) || levels.length === 0) {\n throw new UnitError(\"EMPTY_CHAIN\", \"an order needs at least one level\");\n }\n const n = levels.length;\n const bound = (a, b, up) => {\n const bs = [...Array(n).keys()].filter((x) => up ? leq[a][x] && leq[b][x] : leq[x][a] && leq[x][b]);\n const least = bs.filter((x) => bs.every((y) => up ? leq[x][y] : leq[y][x]));\n if (least.length !== 1) {\n throw new UnitError(\"MALFORMED\", `\\`${levels[a]}\\` and \\`${levels[b]}\\` have ${least.length} ${up ? \"lowest common\" : \"highest common\"} bounds, so this is not a usable scale`, { levels: [levels[a], levels[b]] });\n }\n return least[0];\n };\n const grid = (up) => [...Array(n)].map((_, i) => [...Array(n)].map((__, j) => bound(i, j, up)));\n return build(levels, grid(true), grid(false));\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/debit/unit.js\nfunction unit(subject, bounds) {\n return { subject, floor: bounds.floor, ceiling: bounds.ceiling };\n}\nvar permitAll = (c, subject) => unit(subject, { floor: c.bottom, ceiling: c.top });\nfunction state(c, u) {\n return c.stateOf(c.rank(u.floor), c.rank(u.ceiling));\n}\nfunction band(c, units, from, onFloor, onCeiling) {\n let floor = from.floor;\n let ceiling = from.ceiling;\n for (const u of units) {\n floor = onFloor(floor, c.rank(u.floor));\n ceiling = onCeiling(ceiling, c.rank(u.ceiling));\n }\n return { subject: units[0].subject, floor: c.levels[floor], ceiling: c.levels[ceiling] };\n}\nfunction fuse(c, units) {\n if (units.length === 0)\n return permitAll(c, \"\");\n return band(c, units, { floor: c.bottomIx, ceiling: c.topIx }, (a, b) => c.higher(a, b), (a, b) => c.lower(a, b));\n}\nfunction entails(c, a, b) {\n const [af, ac] = [c.rank(a.floor), c.rank(a.ceiling)];\n const [bf, bc] = [c.rank(b.floor), c.rank(b.ceiling)];\n return c.leq(bf, af) && c.leq(ac, bc);\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/debit/packed.js\nvar WIDTH = 32;\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/debit/masks.js\nfunction chunkCount(n) {\n if (n <= 0)\n return 0;\n return Math.ceil(n / WIDTH);\n}\nvar WideMask = class _WideMask {\n words;\n width;\n constructor(width, words2) {\n this.width = width;\n this.words = words2 ?? new Uint32Array(chunkCount(width));\n }\n static fromTokens(tokens, allowed) {\n const m = new _WideMask(tokens.length);\n tokens.forEach((t, i) => {\n if (allowed.has(t))\n m.set(i);\n });\n return m;\n }\n set(bit) {\n if (bit < 0 || bit >= this.width) {\n throw new UnitError(\"MALFORMED\", `bit ${bit} is outside a mask of width ${this.width}`, {\n bit,\n width: this.width\n });\n }\n this.words[bit >> 5] |= 1 << (bit & 31);\n }\n has(bit) {\n if (bit < 0 || bit >= this.width)\n return false;\n return (this.words[bit >> 5] & 1 << (bit & 31)) !== 0;\n }\n and(other) {\n const w = Math.max(this.width, other.width);\n const out = new _WideMask(w);\n const n = Math.min(this.words.length, other.words.length);\n for (let i = 0; i < n; i++)\n out.words[i] = this.words[i] & other.words[i];\n return out;\n }\n or(other) {\n const w = Math.max(this.width, other.width);\n const out = new _WideMask(w);\n for (let i = 0; i < out.words.length; i++) {\n out.words[i] = (this.words[i] ?? 0) | (other.words[i] ?? 0);\n }\n return out;\n }\n difference(other) {\n const w = Math.max(this.width, other.width);\n const out = new _WideMask(w);\n for (let i = 0; i < out.words.length; i++) {\n out.words[i] = (this.words[i] ?? 0) & ~(other.words[i] ?? 0);\n }\n const spare = w % 32;\n if (spare !== 0 && out.words.length > 0) {\n out.words[out.words.length - 1] &= (1 << spare) - 1;\n }\n return out;\n }\n subsetOf(other) {\n const n = Math.max(this.words.length, other.words.length);\n for (let i = 0; i < n; i++) {\n const a = this.words[i] ?? 0;\n const b = other.words[i] ?? 0;\n if ((a & ~b) !== 0)\n return false;\n }\n return true;\n }\n size() {\n let n = 0;\n for (let i = 0; i < this.width; i++)\n if (this.has(i))\n n++;\n return n;\n }\n members(tokens) {\n return tokens.filter((_, i) => this.has(i));\n }\n static filled(width) {\n const m = new _WideMask(width);\n if (width <= 0)\n return m;\n m.words.fill(4294967295);\n const spare = width % 32;\n if (spare !== 0)\n m.words[m.words.length - 1] = (1 << spare) - 1;\n return m;\n }\n};\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/scale-lattice.js\nfunction fromScale(c) {\n const inhabited = (x) => state(c, x) !== \"CONFLICT\";\n return {\n top: permitAll(c, \"\"),\n bottom: { subject: \"\", floor: c.levels[c.topIx] ?? \"\", ceiling: c.levels[c.bottomIx] ?? \"\" },\n leq: (a, b) => entails(c, a, b),\n meet: (a, b) => fuse(c, [a, b]),\n join: (a, b) => {\n if (!inhabited(a))\n return b;\n if (!inhabited(b))\n return a;\n return {\n subject: a.subject || b.subject,\n floor: c.levels[c.lower(c.rank(a.floor), c.rank(b.floor))] ?? a.floor,\n ceiling: c.levels[c.higher(c.rank(a.ceiling), c.rank(b.ceiling))] ?? a.ceiling\n };\n },\n show: (x) => `[${x.floor}, ${x.ceiling}]`,\n inhabited\n };\n}\nfunction subsets(tokens) {\n return {\n bottom: new WideMask(tokens.length),\n top: WideMask.filled(tokens.length),\n leq: (a, b) => a.subsetOf(b),\n meet: (a, b) => a.and(b),\n join: (a, b) => a.or(b),\n show: (x) => x.members(tokens).join(\",\"),\n inhabited: (x) => x.size() > 0\n };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/forms.js\nfunction intervals(lo, hi) {\n const low = Math.min(lo, hi);\n const high = Math.max(lo, hi);\n return {\n bottom: { lo: high, hi: low },\n top: { lo: low, hi: high },\n leq(a, b) {\n if (a.lo > a.hi)\n return true;\n if (b.lo > b.hi)\n return false;\n return b.lo <= a.lo && a.hi <= b.hi;\n },\n meet(a, b) {\n return { lo: Math.max(a.lo, b.lo), hi: Math.min(a.hi, b.hi) };\n },\n join(a, b) {\n if (a.lo > a.hi)\n return b;\n if (b.lo > b.hi)\n return a;\n return { lo: Math.min(a.lo, b.lo), hi: Math.max(a.hi, b.hi) };\n },\n show(x) {\n return x.lo > x.hi ? \"empty\" : `${x.lo}..${x.hi}`;\n },\n inhabited(x) {\n return x.lo <= x.hi;\n }\n };\n}\nfunction form(f) {\n const held = { lattice: f.lattice, parse: f.parse, emit: f.emit, count: f.count, show: f.show, points: f.points };\n const lacking = Object.entries(held).find(([, fn]) => typeof fn !== \"function\");\n if (lacking)\n throw new Error(`form \\`${f.id}\\` declared no ${lacking[0]}`);\n return f;\n}\nvar rec = (x) => x !== null && typeof x === \"object\" ? x : {};\nfunction strings(x) {\n return Array.isArray(x) ? x.map(String) : [];\n}\nvar drawn = (seed) => {\n let s = seed >>> 0;\n return () => {\n s = s + 1831565813 >>> 0;\n let t = Math.imul(s ^ s >>> 15, s | 1);\n t ^= t + Math.imul(t ^ t >>> 7, t | 61);\n return ((t ^ t >>> 14) >>> 0) / 4294967296;\n };\n};\nvar picked = (draw, xs) => xs[Math.floor(draw() * xs.length)];\nfunction bandCount(levels, folded) {\n if (levels.length === 0)\n return { kind: \"refused\", why: \"a ladder with no levels cannot be counted\" };\n const c = chain(levels);\n const f = c.rank(folded.floor);\n const cl = c.rank(folded.ceiling);\n if (!c.leq(f, cl))\n return { kind: \"finite\", n: 0 };\n const n = levels.filter((_, i) => c.leq(f, i) && c.leq(i, cl)).length;\n return { kind: \"finite\", n };\n}\nvar BAND = {\n parse(params, demand) {\n const L = this.lattice(params);\n const d = rec(demand);\n return {\n subject: String(d.subject ?? \"\"),\n floor: String(d.floor ?? L.top.floor),\n ceiling: String(d.ceiling ?? L.top.ceiling)\n };\n },\n emit(_params, value2) {\n return { subject: value2.subject, floor: value2.floor, ceiling: value2.ceiling };\n },\n count(folded, params) {\n return bandCount(strings(rec(params).levels), folded);\n },\n points(params, seed, n) {\n const L = this.lattice(params);\n const levels = strings(rec(params).levels);\n const draw = drawn(seed);\n const band2 = (floor, ceiling) => ({ subject: \"\", floor, ceiling });\n return Array.from({ length: n }, () => {\n const [a, b] = [picked(draw, levels), picked(draw, levels)];\n return [band2(a, b), band2(b, a)].find((x) => L.inhabited(x)) ?? band2(a, a);\n });\n }\n};\nvar ladderForm = form({\n id: \"ladder\",\n lattice(params) {\n const levels = strings(rec(params).levels);\n if (levels.length === 0)\n throw new Error(\"ladder needs levels\");\n return fromScale(chain(levels));\n },\n ...BAND,\n show(value2) {\n return value2.floor === value2.ceiling ? value2.floor : `${value2.floor}..${value2.ceiling}`;\n }\n});\nvar alphabetForm = form({\n id: \"alphabet\",\n lattice(params) {\n return subsets(strings(rec(params).tokens));\n },\n parse(params, demand) {\n const tokens = strings(rec(params).tokens);\n const d = rec(demand);\n const want = d.want !== void 0 ? strings(d.want) : tokens;\n return WideMask.fromTokens(tokens, new Set(want));\n },\n emit(params, value2) {\n return { want: value2.members(strings(rec(params).tokens)) };\n },\n count(folded) {\n return { kind: \"finite\", n: folded.size() };\n },\n show(value2) {\n return `${value2.size()}`;\n },\n points(params, seed, n) {\n const tokens = strings(rec(params).tokens);\n const draw = drawn(seed);\n return Array.from({ length: n }, () => WideMask.fromTokens(tokens, new Set(tokens.filter(() => draw() < 0.5))));\n }\n});\nvar continuousForm = form({\n id: \"continuous\",\n lattice(params) {\n const p = rec(params);\n return intervals(Number(p.lo ?? 0), Number(p.hi ?? 1));\n },\n parse(params, demand) {\n const L = this.lattice(params);\n const d = rec(demand);\n return {\n lo: d.lo === void 0 ? L.top.lo : Number(d.lo),\n hi: d.hi === void 0 ? L.top.hi : Number(d.hi)\n };\n },\n emit(_params, value2) {\n return { lo: value2.lo, hi: value2.hi };\n },\n count() {\n return { kind: \"refused\", why: \"a continuous band has no count; prefer not to exist over inventing one\" };\n },\n show(value2) {\n return value2.lo > value2.hi ? \"empty\" : `${value2.lo}..${value2.hi}`;\n },\n points(params, seed, n) {\n const p = rec(params);\n const lo = Number(p.lo ?? 0);\n const hi = Number(p.hi ?? 1);\n const draw = drawn(seed);\n const at = () => lo + Math.round(draw() * (hi - lo));\n return Array.from({ length: n }, () => ({ lo: at(), hi: at() }));\n }\n});\nvar latticeForm = form({\n id: \"lattice\",\n lattice(params) {\n const p = rec(params);\n const levels = strings(p.levels);\n const leq = p.leq;\n if (levels.length && leq)\n return fromScale(order(levels, leq));\n throw new Error(\"lattice needs levels+leq\");\n },\n ...BAND,\n show(value2) {\n return `${value2.floor}..${value2.ceiling}`;\n }\n});\nvar FORM_IMPLEMENTATIONS = [ladderForm, alphabetForm, continuousForm, latticeForm];\nvar FORMS = [...FORM_IMPLEMENTATIONS];\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/field.js\nfunction coordinate(name, steps2 = \"/\") {\n const at = name.split(new RegExp(`[${steps2.replace(/[.*+?^${}()|[\\]\\\\-]/g, \"\\\\$&\")}]`)).filter((s) => s !== \"\");\n while (at[at.length - 1] === \"*\" || at[at.length - 1] === \"**\")\n at.pop();\n return at;\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/lattice/obligatory.js\nfunction cell(at, epoch = 0, seen = [], restsOn2 = []) {\n return { at: coordinate(at), epoch, seen, restsOn: restsOn2 };\n}\nfunction live(lines) {\n const taken = new Set(lines.flatMap((line) => line.takes === void 0 ? [] : [line.takes]));\n return lines.filter((line) => line.takes === void 0 && (line.id === void 0 || !taken.has(line.id)));\n}\nfunction restOf(c, world = /* @__PURE__ */ new Map()) {\n const own = c.at.join(\"/\");\n const out = [];\n const held = /* @__PURE__ */ new Set();\n const edge = [...c.restsOn];\n for (let i = 0; i < edge.length; i += 1) {\n const name = edge[i];\n if (name === own)\n throw new UnitError(\"rest-cycle\", `obligations: REFUSE\\xB7rest ${own} rests on itself: an order of rest with a cycle has no fold to reach`, { at: own });\n if (held.has(name))\n continue;\n held.add(name);\n out.push(name);\n edge.push(...world.get(name)?.restsOn ?? []);\n }\n return out;\n}\nfunction parts(L, c, world = /* @__PURE__ */ new Map()) {\n const rest = restOf(c, world);\n const above = rest.flatMap((name) => live(world.get(name)?.marks ?? []).filter((one) => one.reach === \"travels\" && one.widens === void 0));\n const marks = [...live(c.marks ?? []), ...above].sort((a, b) => (a.at ?? 0) - (b.at ?? 0));\n let required = L.top;\n let signed = L.top;\n for (const one of marks) {\n if (one.pole === \"floor\")\n required = L.meet(required, one.span);\n else\n signed = one.widens === void 0 ? L.meet(signed, one.span) : L.join(signed, one.span);\n }\n const origins2 = live(c.seen);\n const held = origins2.reduce((acc, claim) => L.meet(acc, claim.span), L.top);\n return { floor: L.meet(required, held), ceiling: L.meet(signed, held), origins: origins2, rest, required, signed };\n}\nfunction state2(L, c, world = /* @__PURE__ */ new Map()) {\n const { floor, ceiling, origins: origins2, required, signed } = parts(L, c, world);\n if (!L.inhabited(L.meet(required, signed)))\n return \"CONFLICT\";\n if (new Set(origins2.map((claim) => claim.origin)).size < 2)\n return \"REQUIRED\";\n if (!L.inhabited(origins2.reduce((acc, claim) => L.meet(acc, claim.span), L.top)))\n return \"CONFLICT\";\n return L.inhabited(L.meet(floor, ceiling)) ? \"FREE\" : \"FORBIDDEN\";\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/meet.js\nfunction meet(L, c, world = /* @__PURE__ */ new Map()) {\n const { floor, ceiling } = parts(L, c, world);\n return L.meet(floor, ceiling);\n}\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/encounter.js\nfunction encounter(L, c, world = /* @__PURE__ */ new Map()) {\n return { origins: new Set(live(c.seen).map((claim) => claim.origin)).size, held: meet(L, c, world) };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/sig.js\nfunction parseSignature(value2) {\n const colon = value2.lastIndexOf(\":\");\n if (colon <= 0 || colon === value2.length - 1)\n return null;\n return { algorithm: value2.slice(0, colon), raw: value2.slice(colon + 1) };\n}\n\n// ../provider-closure/world/node_modules/@lapxo/topos/dist/wire/claimline.js\nvar WITHDRAW = \"withdraw\";\nfunction admittedDigest(value2, wire) {\n const colon = value2.indexOf(\":\");\n return colon > 0 && wire.digests.has(value2.slice(0, colon)) && /^[0-9a-f]+$/i.test(value2.slice(colon + 1));\n}\nfunction isRegion(need) {\n if (need.startsWith(\"/\") || /[\\s\\\\]/.test(need))\n return false;\n const steps2 = need.split(\"/\").filter((step) => step !== \"\");\n return steps2.length > 0 && steps2.every((step, i) => step !== \".\" && step !== \"..\" && (!step.includes(\"*\") || i === steps2.length - 1));\n}\nvar FIELD_FORMS = {\n region: (value2) => value2.split(\"|\").filter(Boolean).every(isRegion),\n class: (value2, wire) => {\n const colon = value2.indexOf(\":\");\n if (colon <= 0 || !wire.classes.has(value2.slice(0, colon)))\n return false;\n const rest = value2.slice(colon + 1);\n return !/^[a-z0-9-]+:[0-9a-f]{16,}$/i.test(rest) || admittedDigest(rest, wire);\n },\n signature: (value2, wire) => {\n const got = parseSignature(value2);\n if (got === null || !wire.signatures.has(got.algorithm))\n return false;\n const era = got.algorithm.slice(got.algorithm.lastIndexOf(\":\") + 1);\n return admittedDigest(got.algorithm, wire) || got.algorithm.includes(\":\") && (wire.lists.get(\"era\")?.has(era) ?? false);\n },\n count: (value2) => /^\\d+$/.test(value2)\n};\nfunction debit(field, why) {\n return refuse2(why, field);\n}\nfunction fromLine(text, wire, grammars) {\n const line = parse(text);\n if (line.kind !== \"fact\") {\n return line.kind === \"abstain\" ? abstain(line.why) : refuse2(line.why, line.named);\n }\n const f = line.value.fields;\n if (wire) {\n for (const k of Object.keys(f))\n if (!wire.fields.has(k))\n return debit(k, `\\`${k}=\\` is not a field of the wire at epoch ${wire.epoch}`);\n for (const k of wire.required)\n if (f[k] === void 0)\n return debit(k, `a claim with no \\`${k}\\``);\n for (const [k, form2] of wire.formOf) {\n const v = f[k];\n if (v === void 0)\n continue;\n const ids = wire.lists.get(form2);\n const reads = FIELD_FORMS[form2] ?? (ids ? (value2) => ids.has(value2) : void 0);\n if (!reads)\n return abstain(`\\`${k}\\` takes the form ${form2}, which this reader does not know`);\n if (!reads(v, wire))\n return debit(k, `\\`${k}=${v}\\` is not a ${form2} of the wire at epoch ${wire.epoch}`);\n }\n if (f.role !== void 0 && !wire.roles.has(f.role))\n return abstain(`\\`role=${f.role}\\` is a role this wire does not name`);\n if (!wire.forms.has(f.form ?? \"\"))\n return abstain(`\\`form=${f.form}\\` is a form this wire does not name`);\n }\n const listed2 = Array.isArray(grammars) ? grammars : void 0;\n const bound = f.value === WITHDRAW ? { kind: \"enumerated\", values: [WITHDRAW] } : boundOf(f.form ?? \"\", f.value ?? \"\", listed2);\n if (bound === null) {\n const mine = BOUND_FORMS.includes(f.form ?? \"\") || (listed2?.some((g) => g.form === f.form) ?? false);\n return mine ? debit(\"value\", `\\`${f.value}\\` is not a ${f.form}`) : abstain(`\\`form=${f.form}\\` is a form this reader does not know`);\n }\n const role = f.role === \"writes\" ? \"writes\" : f.role === \"demands\" ? \"demands\" : \"reads\";\n const extra = {};\n for (const [k, v] of Object.entries(f)) {\n if ([\"scope\", \"measure\", \"form\", \"value\", \"by\", \"at\", \"role\", \"unit\", \"multiplicity\", \"epoch\", \"ref\", \"to\", \"ref_by\"].includes(k))\n continue;\n extra[k] = v;\n }\n const rel = f.ref;\n const to = f.to === void 0 ? null : unpipe(f.to);\n const reference = rel && to && REF_RELATIONS.includes(rel) ? { rel, to, by: f.ref_by === \"declared\" ? \"declared\" : \"inferred\" } : null;\n return fact({\n scope: f.scope ?? \"\",\n measure: f.measure ?? \"\",\n bound,\n role,\n by: f.by ?? \"\",\n at: f.at ?? \"\",\n ...f.unit !== void 0 ? { unit: f.unit } : {},\n ...f.multiplicity === \"one\" || f.multiplicity === \"many\" || f.multiplicity === \"unknown\" ? { multiplicity: f.multiplicity } : {},\n ...f.epoch !== void 0 ? { epoch: f.epoch } : {},\n ...reference ? { reference } : {},\n extra\n });\n}\nvar EPOCHS = intervals(-Infinity, Infinity);\nvar QUORUMS = intervals(1, Infinity);\n\n// ../provider-closure/world/dist/helpers/asked.js\nvar pairs = (asked, scope) => fields(value(asked, scope) ?? \"\");\nvar receiptLine = (asked, region, scope, place, measure) => receipts(asked, region).find((line) => of(line, \"scope\") === scope && (place === void 0 || placeOf(line) === place) && (measure === void 0 || of(line, \"measure\") === measure));\nvar receiptValue = (asked, region, scope, place, measure) => ((line) => line === void 0 ? void 0 : of(line, \"value\"))(receiptLine(asked, region, scope, place, measure));\nvar numeral = (said) => {\n const read = (value2) => {\n try {\n const got = fromLine(canonical({ at: \"place:numeral\", by: \"reader\", form: \"interval\", measure: \"count\", role: \"reads\", scope: \"numeral\", value: value2 }), null);\n return got.kind === \"fact\" && got.value.bound.kind === \"interval\" ? got.value.bound.lo ?? void 0 : void 0;\n } catch {\n return void 0;\n }\n };\n return said === void 0 ? NaN : read(said) ?? read(`${said}..${said}`) ?? NaN;\n};\n\n// ../provider-closure/world/node_modules/@lapxo/obligations/dist/field/observe.js\nfunction observe(c, claim, s = claim.takes === void 0 ? 1 : -1) {\n const takes = s === 1 ? void 0 : claim.takes ?? claim.id;\n if (s === 1 && claim.takes !== void 0)\n throw new UnitError(\"sign-mismatch\", \"obligations: REFUSE\\xB7observe a claim that takes another back is observed at \\u22121, never at +1\");\n if (s === -1 && takes === void 0)\n throw new UnitError(\"withdrawal-unnamed\", \"obligations: REFUSE\\xB7observe a withdrawal names the claim it takes back, never a value that looks like it\");\n const line = takes === void 0 ? claim : { origin: claim.origin, span: claim.span, sign: -1, takes, ...claim.at === void 0 ? {} : { at: claim.at } };\n return { ...c, epoch: Math.max(c.epoch, claim.at ?? c.epoch), seen: [...c.seen, line] };\n}\n\n// ../provider-closure/world/dist/helpers/language.js\nvar rule = (asked, name) => listed(asked, `form/prose/${lang(asked)}/${name}`);\nvar upper = (text) => `${text.charAt(0).toUpperCase()}${text.slice(1)}`;\nvar words = (asked, slug) => rule(asked, \"words\").includes(\"spaces\") ? slug.split(\"-\").join(\" \") : slug;\nvar heading = (asked, slug) => rule(asked, \"heading\").includes(\"capital\") ? upper(words(asked, slug)) : words(asked, slug);\nvar count = (asked, n, first = false) => {\n const word = rule(asked, \"numbers\")[n] ?? String(n);\n return first && rule(asked, \"sentence\").includes(\"capital\") ? upper(word) : word;\n};\nvar listOf = (asked, items) => {\n const [comma = \", \", and = \" and \"] = rule(asked, \"list\");\n return items.length > 1 ? `${items.slice(0, -1).join(comma)}${and}${items[items.length - 1]}` : items.join(\"\");\n};\nvar stated = (asked, state3) => rule(asked, `state/${state3}`)[0] ?? \"\";\nvar prose = (asked, key) => ((line) => line === void 0 ? void 0 : of(line, \"about\"))(found(asked, `prose/${lang(asked)}/${key}`) ?? found(asked, `form/prose/${lang(asked)}/page/${key}`));\nvar fill = (asked, key, text, fields2 = {}) => listed(asked, `form/template/${key}`).reduce((said, field) => said.split(`{${field}}`).join(String(fields2[field] ?? \"\")), text);\nvar say = (asked, key, fields2 = {}) => fill(asked, key, prose(asked, key) ?? \"\", fields2);\nvar sentence = (asked, text) => {\n const said = rule(asked, \"sentence\");\n let end = text.length;\n while (end > 0 && \".;:, \\n\".includes(text.charAt(end - 1)))\n end -= 1;\n const start = said.includes(\"capital\") ? `${text.charAt(0).toUpperCase()}${text.slice(1, end)}` : text.slice(0, end);\n return said.includes(\"period\") ? `${start}.` : start;\n};\nvar parted = (asked, key) => ((said) => said === void 0 ? [] : [said.trim()])(prose(asked, key));\nvar section = (asked, key) => ((said) => said ? [`## ${said}`, \"\"] : [])(prose(asked, `${key}/heading`));\nvar titled = (asked, key, parts2) => parts2.length ? [...section(asked, key), ...parts2.flatMap((part) => [part, \"\"])].slice(0, -1) : [];\n\n// ../provider-closure/world/dist/helpers/laws.js\nvar laws = (asked) => regionLines(asked, \"laws\");\nvar offers = (asked) => regionLines(asked, \"offers\");\nvar lawId = (law) => placeOf(law);\nvar lawKey = (law) => of(law, \"scope\").slice(lawId(law).lastIndexOf(\"/\") + 1);\nvar lawName = (asked, law) => words(asked, of(law, \"scope\").slice(lawId(law).length + 1));\nvar lawAt = (asked, scope) => laws(asked).find((one) => of(one, \"scope\") === scope);\nvar keys = (asked, rested) => alphabet(rested).members.map((scope) => ((law) => law === void 0 ? scope : lawKey(law))(lawAt(asked, scope))).join(\", \");\nvar object = (asked) => lawAt(asked, value(asked, \"notation/object\") ?? \"\");\nvar resting = (asked, scope) => offers(asked).filter((line) => alphabet(of(line, \"restsOn\")).members.includes(scope));\nvar moduleOf = (asked, offer) => alphabet(of(offer, \"needs\")).members.find((need) => receiptValue(asked, \"source\", \"source/carries\", need) !== void 0 || receipts(asked, \"source\").some((one) => placeOf(one) === need));\nvar sample = (asked, law, side) => {\n const family = value(asked, `samples/${side}`);\n const at = family === void 0 ? void 0 : alphabet(of(law, \"needs\")).members.find((need) => need.startsWith(`${family.replace(/\\/$/, \"\")}/`));\n const said = (field) => at === void 0 ? void 0 : receiptValue(asked, \"laws\", `said/${field}`, at);\n return { recorded: at !== void 0 && receipts(asked, \"laws\").some((line) => placeOf(line) === at && of(line, \"scope\").startsWith(\"said/\")), at, about: said(\"about\")?.split(\"\\n\"), title: said(\"title\"), brief: said(\"brief\") };\n};\nvar conjectured = (asked, law) => ((yes, no) => say(asked, \"open/conjecture\", {\n title: yes.title ?? sentence(asked, lawName(asked, law)).slice(0, -1),\n brief: yes.brief ?? of(law, \"about\"),\n breaks: no.brief ?? (no.about ?? [])[0] ?? \"\"\n}))(sample(asked, law, \"yes\"), sample(asked, law, \"no\"));\n\n// ../provider-closure/world/dist/helpers/look.js\nvar stands = (said) => Object.entries(said).filter((pair) => Boolean(pair[1]));\nvar look = (asked, key) => value(asked, `form/style/${key}`);\nvar spacing = (asked, figure) => Object.fromEntries(asked.lines.filter((line) => of(line, \"scope\").startsWith(`form/style/${figure}/`)).map((line) => [of(line, \"scope\").slice(`form/style/${figure}/`.length), numeral(of(line, \"value\"))]));\nvar attrs = (said) => stands(said).map(([k, v]) => ` ${k}=\"${escaped(v)}\"`).join(\"\");\nvar css = (rules2) => rules2.map(([at, said]) => [at, stands(said).map(([k, v]) => `${k}:${v}`).join(\";\")]).filter(([, body]) => body).map(([at, body]) => `${at}{${body}}`).join(\"\");\nvar between = (v, [a, b], [c, d]) => c + (v - a) / (b - a) * (d - c);\nvar px = (n) => Number.isFinite(n) ? String(numeral(n.toFixed(1))) : void 0;\nvar secs = (n) => Number.isFinite(n) ? `${n.toFixed(1)}s` : void 0;\nvar font = (asked, family, size) => ((face, at) => face && at ? { font: `${at} ${face}` } : { \"font-family\": face, \"font-size\": at })(look(asked, `font/${family}`), look(asked, `size/${size}`));\nvar style = (light, night) => ((lit) => lit.length || night ? [\"\"] : [])(light.filter(Boolean));\nvar classDef = (name, fill2, text) => ((said) => said ? [` classDef ${name} ${said}`] : [])([fill2 && `fill:${fill2}`, text && `color:${text}`, fill2 && `stroke:${fill2}`].filter(Boolean).join(\",\"));\n\n// ../provider-closure/world/dist/helpers/prose.js\nvar zoom = (summary, lines) => lines.length ? [`
${summary}`, \"\", ...lines, \"\", \"
\"] : [];\nvar inCell = /* @__PURE__ */ new Map([[\"|\", \"\\\\|\"]]);\nvar cellText = (text) => [...text].map((one) => inCell.get(one) ?? one).join(\"\").split(\"\\n\").join(\" \").split(\" \").filter(Boolean).join(\" \");\nvar escaped = (text) => text.split(\"&\").join(\"&\").split(\"<\").join(\"<\").split(\">\").join(\">\").split('\"').join(\""\");\nvar folder = (at) => steps(steps(at).slice(0, -1));\nvar reaches = (asked, key) => asked.at >= numeral(value(asked, `form/page/${key}`));\nvar stem = (at) => {\n const name = at.slice(at.lastIndexOf(\"/\") + 1);\n return name.includes(\".\") ? name.slice(0, name.lastIndexOf(\".\")) : name;\n};\nvar relative = (from, to) => {\n const [a, b] = [steps(from).filter(Boolean), steps(to).filter(Boolean)];\n const differ = a.findIndex((step, i) => step !== b[i]);\n const shared = differ < 0 ? a.length : differ;\n return steps([...a.slice(shared).map(() => \"..\"), ...b.slice(shared)]);\n};\nvar painted = (asked, name) => ({ name, colour: look(asked, `colour/${name}`), glyph: look(asked, `glyph/${name}`) });\nvar glyph = (asked, name) => pairs(asked, \"notation/glue\").find(([one]) => one === name)?.[1] ?? \"\";\nvar states = (asked) => pairs(asked, \"notation/renders\").map(([state3, name]) => ({ ...painted(asked, state3), name }));\nvar rendered = (asked, state3) => ({ ...painted(asked, state3), name: pairs(asked, \"notation/renders\").find(([one]) => one === state3)?.[1] ?? state3 });\nvar resolved = (asked, body) => {\n if (reaches(asked, \"statement\") || !body.length)\n return body;\n const head = body.findIndex((line) => line.startsWith(\"```\"));\n if (head < 0)\n return asked.at > 1 ? body : ((lead) => lead < 0 ? body : body.slice(0, lead))(body.findIndex((line, i) => i > 1 && line === \"\" && body[i - 1] !== \"\"));\n const lines = body.slice(head + 1, body.lastIndexOf(\"```\"));\n if (asked.at <= 1)\n return [...body.slice(0, head + 1), ...lines.slice(0, 1), \"```\"];\n const [cut] = rule(asked, \"separator\");\n if (cut === void 0)\n throw new Error(`REFUSE\\xB7resolution ${asked.region}@${asked.at}: form/prose/${lang(asked)}/separator names no separator to cut its steps at`);\n return [...body.slice(0, head + 1), ...lines.map((line) => line.split(cut).slice(0, asked.at).join(cut)), \"```\"];\n};\n\n// ../provider-closure/world/dist/helpers/cells.js\nvar SPANS = intervals(-Infinity, Infinity);\nvar hull = (ns) => ns.reduce((all, n) => SPANS.join(all, { lo: n, hi: n }), SPANS.bottom);\nvar apartOf = (met, at) => ((left) => left.length === 1 ? left[0] : void 0)(met.seen.flatMap((one) => ((rest) => rest.origins > 1 && SPANS.inhabited(rest.held) ? [{ who: one.origin, held: rest.held, count: rest.origins }] : [])(encounter(SPANS, met.seen.filter((other) => other !== one).reduce((held, claim) => observe(held, claim), cell(at))))));\nfunction cellOf(asked, at) {\n const shape = new Map(pairs(asked, \"notation/claim\"));\n const role = (name) => shape.get(name) ?? \"\";\n const fielded = receipts(asked, \"source\").filter((one) => placeOf(one) === at && of(one, \"scope\").startsWith(\"source/literal/\")).map((one) => new Map(fields(of(one, \"value\"))));\n const met = fielded.filter((one) => [\"who\", \"lo\", \"hi\"].every((name) => one.has(role(name))) && !one.has(role(\"without\"))).reduce((held, one) => observe(held, { origin: one.get(role(\"who\")) ?? \"\", span: { lo: numeral(one.get(role(\"lo\"))), hi: numeral(one.get(role(\"hi\"))) } }), cell(at));\n return built(met, at);\n}\nvar cellOfLines = (lines) => ((at) => built(lines.reduce((held, line) => ((got) => got.kind === \"fact\" && got.value.bound.kind === \"interval\" && got.value.bound.lo !== null && got.value.bound.hi !== null ? observe(held, { origin: of(line, \"by\"), span: { lo: got.value.bound.lo, hi: got.value.bound.hi } }) : held)(fromLine(canonical(line), null)), cell(at)), at))(of(lines[0], \"scope\"));\nvar built = (met, at) => {\n const { origins: origins2, held } = encounter(SPANS, met);\n const rest = SPANS.inhabited(held) ? void 0 : apartOf(met, at);\n return origins2 > 1 ? { claims: met.seen, held, hull: met.seen.reduce((all, one) => SPANS.join(all, one.span), SPANS.bottom), state: state2(SPANS, met), ...rest === void 0 ? {} : { rest } } : void 0;\n};\nvar captioned = (asked, met) => (met.rest !== void 0 ? say(asked, \"cell/outlier\", { count: count(asked, met.rest.count), ...met.rest.held, who: met.rest.who, state: met.state.toLowerCase() }) : SPANS.inhabited(met.held) ? say(asked, \"cell/together\", { count: count(asked, met.claims.length), ...met.held, state: met.state.toLowerCase() }) : \"\") || stated(asked, met.state);\nvar described = (asked, met) => say(asked, \"cell/origins\", {\n count: count(asked, met.claims.length, true),\n claims: listOf(asked, met.claims.map((one) => say(asked, \"cell/claim\", { who: one.origin, ...one.span }))),\n held: SPANS.inhabited(met.held) ? say(asked, \"cell/held\", { ...met.held }) : prose(asked, \"apart\") ?? \"\"\n});\nvar image = (asked, at, met) => `\"${escaped(described(asked,

`;\nvar labelOf = (asked, scope) => ((law) => law === void 0 ? scope : lawName(asked, law))(lawAt(asked, scope));\n\n// ../provider-closure/world/dist/helpers/examples.js\nvar examples = (asked, at = \"\") => {\n const got = receipts(asked, \"examples\").filter((line) => placeOf(line) === at && matches(\"examples/*\", of(line, \"scope\")));\n return [...new Set(got.map((line) => of(line, \"scope\")))].map((scope) => {\n const read = (measure) => got.find((one) => of(one, \"scope\") === scope && of(one, \"measure\") === measure);\n const origins2 = [found(asked, scope), read(\"id\")].filter((line) => of(line, \"value\") !== \"\");\n const tokens = [...new Set(origins2.map((line) => of(line, \"value\")))];\n const met = origins2.reduce((at2, line) => observe(at2, { origin: of(line, \"by\"), span: WideMask.fromTokens(tokens, /* @__PURE__ */ new Set([of(line, \"value\")])) }), cell(scope));\n return { name: steps(scope)[1] ?? \"\", source: of(read(\"source\"), \"value\"), printed: of(read(\"printed\"), \"value\"), at: of(read(\"at\") ?? read(\"leaf\"), \"value\"), state: state2(alphabetForm.lattice({ tokens }), met) };\n });\n};\nvar shortest = (asked, at = \"\") => [...examples(asked, at)].sort((a, b) => a.source.split(\"\\n\").length - b.source.split(\"\\n\").length || byBytes(a.name, b.name))[0];\nvar fence = (asked, one) => receiptValue(asked, \"source\", \"source/lang\", one.at) ?? \"\";\nvar run = (asked, one) => [`\\`\\`\\`${fence(asked, one)}`, ...one.source.trim().split(\"\\n\"), \"```\", \"\", \"```\", ...one.printed.split(\"\\n\"), \"```\"];\nvar glance = (asked, one, here) => {\n const printed = one.printed.split(\"\\n\");\n const depth = (line) => line.length - line.trimStart().length;\n const next = (i) => printed.slice(i + 1).find((line) => line.trim()) ?? \"\";\n const runner = asked.lines.find((line) => matches(\"form/runtime/*/run\", of(line, \"scope\")));\n const command = runner === void 0 ? \"\" : fill(asked, steps(of(runner, \"scope\")).slice(1).join(\"/\"), of(runner, \"value\"), { at: one.at });\n const [at, most] = [((learn) => learn === void 0 ? asked.at : numeral(learn))(value(asked, \"form/page/learn\")), numeral(value(asked, \"form/page/example\"))];\n const outline = printed.filter((line, i) => line.trim() && !depth(line) && !depth(next(i)));\n const [ran, fenced] = [command ? [\"```bash\", command, \"```\"] : [], (body) => [\"```\", ...body, \"```\"]];\n const shown = at > 1 ? printed : Number.isFinite(most) ? outline.slice(0, hull([0, most - ran.length - fenced([]).length]).hi) : outline;\n const part = (key, body) => body.length ? [.../* @__PURE__ */ ((said) => said ? [said, \"\"] : [])(prose(asked, `figure/learn/${key}`)), ...body] : [];\n const blocks = [part(\"run\", ran), part(\"printed\", fenced(shown)), /* @__PURE__ */ ((link) => link ? [link] : [])(say(asked, \"figure/learn/source\", { at: relative(here, one.at) }))];\n return blocks.filter((block) => block.length).flatMap((block, i) => i ? [\"\", ...block] : block);\n};\n\n// ../provider-closure/world/dist/helpers/figures.js\nvar figured = (asked, region, at) => asked.lines.filter((line) => of(line, \"scope\").startsWith(\"view/\") && ((members) => members.length === 1 && members.some((token) => ((read) => read.name === region && read.at === at)(atResolution(token))))(alphabet(of(line, \"value\")).members));\nvar figureAt = (line) => of(line, \"shape\") || void 0;\nvar drawn2 = (asked, drawing, alt, key = \"\", beneath = []) => ((at) => !drawing.length || at === void 0 ? [] : asked.shape === at ? drawing : [\n ...key ? section(asked, key) : [],\n `\"${escaped(alt)}\"${attrs({

`,\n ...beneath.length ? [\"\", ...beneath] : []\n])(figured(asked, asked.region, 1).map(figureAt).find(Boolean));\n\n// ../provider-closure/world/dist/helpers/refused.js\nvar tail = (scope) => (([n = \"\", word = \"\", ...file]) => ({ n, word, file: steps(file.reverse()) }))([...steps(scope)].reverse());\nvar refusedCases = (asked) => {\n const step = \"refused\";\n const said = [...receipts(asked, \"vectors\"), ...receipts(asked, \"captures\")].filter((line) => tail(of(line, \"scope\")).word === step);\n const where = (scope) => placeOf(said.find((line) => of(line, \"scope\") === scope) ?? {});\n const scopes = [...new Set(said.filter((line) => of(line, \"measure\") === \"why\").map((line) => of(line, \"scope\")))].sort((a, b) => byBytes(tail(a).file, tail(b).file) || numeral(tail(a).n) - numeral(tail(b).n));\n const read = (first, measure) => of(said.find((line) => of(line, \"scope\") === first && of(line, \"measure\") === measure), \"value\");\n return scopes.map((first) => ({ input: read(first, \"input\"), why: read(first, \"why\"), at: where(first), name: read(first, \"name\") || tail(first).file }));\n};\nvar refusedCase = (asked) => refusedCases(asked)[0];\n\n// ../provider-closure/world/dist/helpers/samples.js\nvar sampled = (asked, prefer = \"\") => {\n const family = value(asked, \"samples/yes\");\n const said = receipts(asked, \"laws\").filter((line) => of(line, \"scope\") === \"said/lines\");\n const eligible = prefer ? said.filter((line) => placeOf(line) === prefer) : family === void 0 ? [] : said.filter((line) => placeOf(line).startsWith(`${family.replace(/\\/$/, \"\")}/`));\n const [one] = [...eligible].sort((a, b) => byBytes(placeOf(a), placeOf(b)));\n return one === void 0 ? void 0 : { at: placeOf(one), lines: handed([\"**\"], of(one, \"value\").split(\"\\n\")) };\n};\nvar declaredSample = (asked, view) => {\n const needs = alphabet(of(view, \"needs\")).members;\n if (needs.length)\n return needs.flatMap((need) => sampled(asked, need)?.lines ?? []);\n return sampled(asked)?.lines ?? [];\n};\n\n// ../provider-closure/world/dist/helpers/notation.js\nvar symbolOf = (asked, type, name) => type.endsWith(\"[]\") ? `[${symbolOf(asked, type.slice(0, -\"[]\".length), name)}]` : listed(asked, \"notation/named\").includes(type) ? name : new Map(pairs(asked, \"notation/types\")).get(type) ?? type;\nfunction formulas(asked) {\n const pending = laws(asked).filter((line) => of(line, \"form\") === \"formula\");\n const parent = (formula) => of(formula, \"scope\").slice(0, of(formula, \"scope\").lastIndexOf(\"/\"));\n const out = [];\n while (pending.length) {\n const waits = (formula) => alphabet(of(lawAt(asked, parent(formula)), \"restsOn\")).members.some((on) => pending.some((other) => other !== formula && parent(other) === on));\n const next = pending.findIndex((formula) => !waits(formula));\n out.push(...pending.splice(next < 0 ? 0 : next, 1));\n }\n return out;\n}\nvar moduleOfObject = (asked, held) => resting(asked, of(held, \"scope\")).map((offer) => moduleOf(asked, offer)).find(Boolean);\nvar tuple = (asked) => {\n const held = object(asked);\n if (held === void 0 || !pairs(asked, \"notation/cell\").length)\n return void 0;\n const module = moduleOfObject(asked, held);\n const carries = new Set(alphabet(module === void 0 ? \"\" : receiptValue(asked, \"source\", \"source/carries\", module) ?? \"\").members);\n const [symbols, gloss] = [new Map(pairs(asked, \"notation/symbols\")), listed(asked, \"notation/gloss\")];\n const members = pairs(asked, \"notation/cell\");\n const shown = (carries.size ? members.filter(([member]) => carries.has(member)) : members).map(([, sym]) => sym);\n if (!shown.length)\n return void 0;\n return `${symbols.get(\"object\")} = ${glyph(asked, \"open\")}${shown.join(\", \")}${glyph(asked, \"close\")}${gloss.length ? ` ${gloss.join(\" \")}` : \"\"}`;\n};\nvar aligned = (asked) => {\n const held = object(asked);\n const chosen = listed(asked, \"notation/formulas\");\n const own = (chosen.length ? chosen : [...alphabet(of(held, \"restsOn\")).members, of(held, \"scope\")]).flatMap((scope) => formulas(asked).filter((line) => of(line, \"scope\").startsWith(`${scope}/`))).map((line) => of(line, \"value\"));\n const cut = (text) => hull([\"=\", glyph(asked, \"iff\"), glyph(asked, \"member\")].map((mark2) => text.indexOf(` ${mark2} `)).concat(text.indexOf(\": \")).filter((i) => i > 0)).lo;\n const side = hull(own.map((text) => text.slice(0, cut(text)).length)).hi;\n return own.map((text) => `${text.slice(0, cut(text)).padEnd(side)} ${text.slice(cut(text)).trimStart()}`);\n};\nvar moves = (asked) => {\n const [renders, at] = [pairs(asked, \"notation/renders\"), value(asked, \"notation/moves\") ?? \"\"];\n const split = (edge) => [edge.slice(0, edge.indexOf(\"\\u2192\")), edge.slice(edge.indexOf(\"\\u2192\") + 1)];\n const edges = alphabet(receiptValue(asked, \"laws\", \"said/moves\", at) ?? \"\").members.map(split);\n const known = (state3) => renders.some(([one]) => one === state3);\n const said = receipts(asked, \"laws\").filter((one) => placeOf(one) === at);\n const dangerous = alphabet(of(said.find((one) => of(one, \"scope\").endsWith(\"/dangerous\")), \"value\")).members.map(split);\n const moved = (one) => split(of(one, \"scope\").slice(of(one, \"scope\").lastIndexOf(\"/why/\") + \"/why/\".length));\n const whyOf = ([from, to]) => of(said.find((one) => of(one, \"scope\").includes(\"/why/\") && moved(one)[0] === from && (moved(one)[1] === to || !known(moved(one)[1]))), \"value\");\n if (!renders.length || !edges.length)\n return void 0;\n return edges.filter(([from, to]) => from !== to && known(from) && known(to)).sort(([a, b], [c, d]) => a === c ? b < d ? -1 : b > d ? 1 : 0 : a < c ? -1 : 1).map((edge) => ({ from: edge[0], to: edge[1], dangerous: dangerous.some(([from, to]) => from === edge[0] && to === edge[1]), why: whyOf(edge) }));\n};\n\n// ../provider-closure/world/dist/helpers/records.js\nvar entries = (asked, family) => {\n const held = asked.lines.filter((line) => of(line, \"scope\").startsWith(`${family}/`));\n return [...new Set(held.map((line) => of(line, \"scope\")))].map((scope) => {\n const own = held.filter((line) => of(line, \"scope\") === scope);\n return {\n scope,\n title: own.map((line) => of(line, \"about\")).find(Boolean) ?? words(asked, scope.slice(scope.indexOf(\"/\") + 1)),\n field: (measure) => ((line) => line === void 0 ? void 0 : of(line, \"value\"))(own.find((line) => of(line, \"measure\") === measure))\n };\n });\n};\nvar typedAs = (asked, head, type, beside) => [...new Map(receipts(asked, \"source\").filter((line) => of(line, \"scope\").startsWith(head) && receiptValue(asked, \"source\", of(line, \"scope\"), placeOf(line), \"type\") === type).map((line) => [`${placeOf(line)} ${of(line, \"scope\")}`, [of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1), receiptValue(asked, \"source\", of(line, \"scope\"), placeOf(line), beside) ?? \"\"]])).values()];\n\n// ../provider-closure/world/dist/helpers/shown.js\nvar NUMBER = /(? [...receipts(asked, \"state\"), ...receipts(asked, \"cases\"), ...receipts(asked, \"captures\"), ...receipts(asked, \"laws\")].flatMap((line) => [of(line, \"value\"), of(line, \"scope\")]).filter(Boolean);\nvar captured = (asked, name) => {\n const got = receiptValue(asked, \"captures\", `capture/${name}`);\n return got && got !== \"none\" ? got : void 0;\n};\nfunction unreceipted(asked) {\n const held = new Set(receipted(asked));\n const commands = prose(asked, \"commands\") ?? \"\";\n const idea = prose(asked, \"idea\") ?? \"\";\n const typed = commands.split(\"\\n\").filter((line) => TYPED.test(line)).length;\n const loose = [...`${idea}\n${commands}`.matchAll(NUMBER)].map((one) => one[0]).filter((n) => ![...held].some((said) => said.includes(n))).length;\n return typed + loose;\n}\n\n// ../provider-closure/world/dist/regions/alphabet.js\nvar render = (asked) => [\n `## ${prose(asked, \"reference/alphabet\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/alphabet-table\") ?? \"\",\n \"|---|---|\",\n ...[\"notation/cell\", \"notation/types\"].flatMap((scope) => pairs(asked, scope).map(([members, symbol]) => `| ${cellText(symbol)} | ${cellText(members)} |`))\n];\n\n// ../provider-closure/world/dist/regions/bond.js\nvar render2 = (asked) => {\n const first = shortest(asked);\n const cell2 = first === void 0 ? void 0 : cellOf(asked, first.at);\n if (cell2 === void 0)\n return [];\n const [held, alone, broken] = states(asked);\n const last = states(asked)[states(asked).length - 1]?.name;\n const [meets, { r, top, bottom, apart, axis }, mark2] = [SPANS.inhabited(cell2.held), spacing(asked, \"bond\"), look(asked, \"width/mark\")];\n const [mid, stroke] = [px(numeral(mark2) * axis), { stroke: alone?.colour, \"stroke-width\": look(asked, \"stroke/mark\"), \"stroke-linecap\": look(asked, \"stroke/cap\") }];\n const title = meets ? say(asked, \"cell/bond\", { count: cell2.claims.length }) : `${cell2.claims.length} ${say(asked, \"cell/apart\", { apart: prose(asked, \"apart\") ?? \"\" })}`;\n return [\n ``,\n `${title}`,\n ...meets ? [``] : [],\n ``,\n ``,\n \"\"\n ];\n};\n\n// ../provider-closure/world/dist/regions/cff.js\nvar render3 = (asked) => {\n const doiOf = (field) => value(asked, \"sources/doi\") === void 0 ? void 0 : field(\"doi\");\n const [paper, name] = [entries(asked, \"cites\").find((one) => doiOf(one.field) !== void 0), value(asked, \"name\")];\n if (name === void 0)\n return [];\n const quoted = (text) => JSON.stringify(text);\n const person = (who, indent) => (([family = \"\", ...given]) => given.length ? [`${indent}- family-names: ${quoted(family)}`, `${indent} given-names: ${quoted(given.join(\", \"))}`] : [`${indent}- name: ${quoted(who)}`])(who.split(\", \"));\n const optional = (key, scope) => ((said) => said === void 0 ? [] : [`${key}: ${quoted(said)}`])(value(asked, scope));\n const [authors, year, version, publisher] = [alphabet(paper?.field(\"author\") ?? \"\").members, paper?.field(\"year\"), paper?.field(\"version\"), paper?.field(\"publisher\")];\n const preferred = paper === void 0 ? [] : [\n \"preferred-citation:\",\n \" type: article\",\n ` title: ${quoted(paper.title)}`,\n ...authors.length ? [\" authors:\", ...authors.flatMap((one) => person(one, \" \"))] : [],\n ...year !== void 0 && Number.isInteger(numeral(year)) ? [` year: ${year}`] : [],\n ...version === void 0 ? [] : [` version: ${quoted(version)}`],\n ...publisher === void 0 ? [] : [\" publisher:\", ` name: ${quoted(publisher)}`],\n ` doi: ${quoted(doiOf(paper.field) ?? \"\")}`\n ];\n return resolved(asked, [\n \"cff-version: 1.2.0\",\n `message: ${quoted(paper ? say(asked, \"cff/paper\", { title: paper.title }) : say(asked, \"cff/name\", { name }))}`,\n \"type: software\",\n `title: ${quoted(name)}`,\n ...optional(\"version\", \"version\"),\n ...((author) => author === void 0 ? [] : [\"authors:\", ...person(author, \" \")])(value(asked, \"author\")),\n ...optional(\"repository-code\", \"repository\"),\n ...optional(\"license\", \"license\"),\n ...preferred\n ]);\n};\n\n// ../provider-closure/world/dist/regions/check.js\nvar render4 = (asked) => {\n const [glyph2, folds] = [states(asked)[0]?.glyph ?? \"\", asked.lines.find((one) => of(one, \"scope\") === \"fold\" && of(one, \"role\") === \"writes\")];\n const [repository, resolvedAt, command] = [value(asked, \"repository\"), value(asked, \"repository/resolved\"), value(asked, \"check\")];\n const how = [\n ...repository === void 0 || resolvedAt === void 0 ? [] : [say(asked, \"check/repository\", { glyph: glyph2, repository })],\n ...command === void 0 ? [] : [say(asked, \"check/command\", { glyph: glyph2, check: command })],\n ...folds === void 0 ? [] : [say(asked, \"check/fold\", { fold: of(folds, \"value\"), about: of(folds, \"about\") })]\n ];\n return resolved(asked, [...section(asked, \"check\"), say(asked, \"check/held\", { glyph: glyph2, count: receiptValue(asked, \"cases\", \"cases/held\") ?? 0 }), ...how.length ? [\"\", how.join(\" \\xB7 \")] : []]);\n};\n\n// ../provider-closure/world/dist/regions/claims.js\nvar reading = (asked, glob) => {\n const held = Object.values(asked.regions).flatMap((region) => region.receipts).filter((line2) => matches(glob, of(line2, \"scope\")));\n if (held.length > 1)\n throw new Error(`REFUSE\\xB7claim ${asked.region}@${asked.at}: ${glob} names ${held.length} receipts without a resolved value`);\n if (held.length === 1)\n return of(held[0], \"value\");\n const line = found(asked, glob);\n if (line === void 0 || of(line, \"value\") === \"withdraw\")\n return void 0;\n return of(line, \"form\") === \"interval\" ? of(line, \"value\") : of(line, \"form\") === \"alphabet\" ? String(listed(asked, glob).length) : void 0;\n};\nvar render5 = (asked) => {\n const here = folder(asked.shape);\n const held = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"claims/\") && of(line, \"value\") !== \"withdraw\").sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\")));\n const bullet = (scope, value2, needs) => {\n const [page] = alphabet(needs).members;\n const read = fields(value2).map(([name, glob]) => [name, reading(asked, glob)]);\n if (read.some(([, got]) => got === void 0))\n return [];\n const said = sentence(asked, say(asked, scope, Object.fromEntries(read.map(([name, got]) => [name, got ?? \"\"]))));\n if (!said)\n return [];\n return [`- **${said}**${page === void 0 ? \"\" : ` \\xB7 [${prose(asked, \"claims/receipt\") ?? \"\"}](${relative(here, page)})`}`];\n };\n const rows = held.flatMap((line) => bullet(of(line, \"scope\"), of(line, \"value\"), of(line, \"needs\")));\n return resolved(asked, rows.length ? [...section(asked, \"claims\"), ...rows] : []);\n};\n\n// ../provider-closure/world/dist/regions/commands.js\nvar render6 = (asked) => {\n const said = prose(asked, \"commands\");\n const out = captured(asked, \"quickstart\");\n const usage = captured(asked, \"usage\");\n const blocks = [\n ...said ? [\"```bash\", said, \"```\"] : [],\n ...out ? [\"```\", out, \"```\"] : [],\n ...usage ? [\"```\", usage, \"```\"] : []\n ];\n return resolved(asked, blocks);\n};\n\n// ../provider-closure/world/dist/regions/door.js\nvar render7 = (asked) => {\n const drawn3 = figured(asked, \"ranges\", 1)[0];\n const figure = drawn3 === void 0 ? void 0 : figureAt(drawn3);\n const one = figure === void 0 ? void 0 : shortest(asked);\n const cell2 = one === void 0 ? void 0 : cellOf(asked, one.at);\n const [what] = alphabet(of(found(asked, \"docs/what\"), \"needs\")).members;\n const parts2 = [\n ...figure !== void 0 && cell2 !== void 0 ? [image(asked, figure, cell2)] : [],\n ...what === void 0 ? [] : [((link, words2) => words2 ? `${say(asked, `${asked.region}/what`)} [${words2}](${link})` : `[${say(asked, `${asked.region}/what`)}](${link})`)(relative(folder(asked.shape), what), prose(asked, `${asked.region}/words`))]\n ];\n return resolved(asked, parts2.flatMap((part, i) => i ? [\"\", part] : [part]));\n};\n\n// ../provider-closure/world/dist/regions/unreceipted.js\nvar receipt = (asked) => counted({ ...asked, region: \"door\" }, \"unreceipted\", unreceipted(asked), \"unreceipted\");\n\n// ../provider-closure/world/dist/regions/figure.js\nvar render8 = (asked) => {\n const first = shortest(asked);\n const cell2 = first === void 0 ? void 0 : cellOf(asked, first.at);\n const at = figured(asked, \"ranges\", 1).map(figureAt).find(Boolean);\n const marks = prose(asked, \"marks\");\n return resolved(asked, at === void 0 || cell2 === void 0 ? [] : [image(asked, at, cell2), ...marks === void 0 ? [] : [\"\", marks]]);\n};\n\n// ../provider-closure/world/dist/regions/figure-fold.js\nvar render9 = (asked) => {\n const lines = declaredSample(asked, figured(asked, asked.region, 1)[0]);\n const cell2 = cellOfLines(lines.filter((line) => of(line, \"scope\") === of(lines[0], \"scope\")));\n const named = listed(asked, \"form/figure/fold\");\n const [claimed, met, apart] = named.map((state3) => rendered(asked, state3));\n const [g, wide] = [spacing(asked, \"fold\"), numeral(look(asked, \"width/figure\"))];\n const away = cell2?.rest?.who;\n const held = cell2 === void 0 ? void 0 : SPANS.inhabited(cell2.held) ? cell2.held : cell2.rest?.held;\n const said = cell2 === void 0 ? [] : [\n held === void 0 ? \"\" : say(asked, \"figure/fold/together\", { ...held, state: (named[1] ?? \"\").toLowerCase() }),\n away === void 0 || held === void 0 ? \"\" : say(asked, \"figure/fold/apart\", { who: away, state: cell2.state.toLowerCase() }),\n away === void 0 || held === void 0 || !Number.isFinite(g.back) ? \"\" : say(asked, \"figure/fold/back\", { ...held })\n ].filter(Boolean);\n const x = (v) => cell2 === void 0 ? NaN : between(v, [cell2.hull.lo - g.pad, cell2.hull.hi + g.pad], [g.margin, wide - g.margin]);\n const rows = cell2 === void 0 ? [] : cell2.claims.filter((claim) => claim.origin !== away);\n const out = cell2?.claims.find((claim) => claim.origin === away);\n const height = (rows.length + (out ? 1 : 0) + 1) * g.row + said.length * g.say + g.say;\n const bar = (lo, hi, y, body) => `${body}`;\n const fade = (begin) => ``;\n const turn = (from, to, begin) => ``;\n return drawn2(asked, cell2 === void 0 || held === void 0 || !said.length ? [] : [\n ``,\n ...style([css([[\"text\", { ...font(asked, \"text\", \"text\"), fill: painted(asked, \"text\").colour }]])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ``,\n ...rows.map((claim, i) => bar(claim.span.lo, claim.span.hi, g.top + i * g.row, `${out ? turn(claimed?.colour, apart?.colour, g.set) : \"\"}${out && Number.isFinite(g.back) ? turn(apart?.colour, claimed?.colour, g.back) : \"\"}`)),\n bar(held.lo, held.hi, g.top + rows.length * g.row, `${turn(claimed?.colour, met?.colour, g.meet)}${out ? turn(met?.colour, apart?.colour, g.set) : \"\"}${out && Number.isFinite(g.back) ? turn(apart?.colour, met?.colour, g.back) : \"\"}`),\n ...out ? [bar(out.span.lo, out.span.hi, g.top + (rows.length + 1) * g.row + g.gap, `${turn(claimed?.colour, apart?.colour, g.set)}${Number.isFinite(g.back) ? `` : \"\"}`)] : [],\n ...said.map((one, i) => `${escaped(one)}${fade(g.speak + i * g.meet)}`),\n \"\"\n ], listOf(asked, said), \"figure/fold\", ((caption) => caption ? [sentence(asked, caption)] : [])(cell2 === void 0 ? \"\" : captioned(asked, cell2)));\n};\n\n// ../provider-closure/world/dist/regions/figure-line.js\nvar render10 = (asked) => {\n const line = declaredSample(asked, figured(asked, asked.region, 1)[0])[0];\n const rows = listed(asked, \"form/figure/line\").map((field) => [field, of(line, field)]).filter(([, said]) => said !== \"\");\n const [held] = states(asked);\n const [g, wide] = [spacing(asked, \"line\"), look(asked, \"width/figure\")];\n const alt = line === void 0 ? \"\" : say(asked, \"figure/line\", { scope: of(line, \"scope\"), count: rows.length });\n const height = px(g.top + rows.length * g.row);\n return drawn2(asked, rows.length ? [\n ``,\n ...style([css([[\"text\", { ...font(asked, \"code\", \"code\"), fill: painted(asked, \"text\").colour }], [\".field\", { fill: held?.colour, \"font-weight\": look(asked, \"weight/strong\") }]])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ...rows.flatMap(([field, said], i) => [`${escaped(field)}`, `${escaped(said)}`]),\n \"\"\n ] : [], alt, \"figure/line\", alt ? [sentence(asked, alt)] : []);\n};\n\n// ../provider-closure/world/dist/regions/figure-refuses.js\nvar render11 = (asked) => {\n const told = refusedCase(asked);\n const [, , forbidden] = states(asked);\n const [g, wide] = [spacing(asked, \"refuses\"), look(asked, \"width/figure\")];\n const alt = told === void 0 || !told.input || !told.why ? \"\" : say(asked, \"figure/refuses\", { input: told.input, why: told.why });\n return drawn2(asked, told !== void 0 && alt ? [\n ``,\n ...style([\n css([[\"text\", { ...font(asked, \"text\", \"text\"), fill: painted(asked, \"text\").colour }], [\".cross\", { fill: forbidden?.colour, \"font-weight\": look(asked, \"weight/strong\") }]]),\n css([[\".asked\", { ...font(asked, \"code\", \"code\"), fill: forbidden?.colour, \"text-decoration\": \"line-through\" }]])\n ], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n `${escaped(forbidden?.glyph ?? \"\")}`,\n `${escaped(told.input)}`,\n `${escaped(told.why)}`,\n \"\"\n ] : [], alt, \"figure/refuses\");\n};\n\n// ../provider-closure/world/dist/regions/figure-world.js\nvar render12 = (asked) => {\n const shown = examples(asked).find((one) => one.name === value(asked, \"docs/world\"));\n const own = shown === void 0 ? regionLines(asked, \"capsule\") : handed([\"**\"], shown.printed.split(\"\\n\"));\n const said = (scope) => of(own.find((line) => of(line, \"scope\") === scope), \"value\");\n const nameOf = (line) => of(line, \"scope\").slice(of(line, \"scope\").indexOf(\"/\") + 1);\n const declared = own.filter((line) => of(line, \"scope\").startsWith(\"region/\") && of(line, \"measure\") === \"reads\");\n const regions = [...new Set(declared.map(nameOf))].sort();\n const ordered = [...declared].sort((a, b) => nameOf(a) < nameOf(b) ? -1 : nameOf(a) > nameOf(b) ? 1 : 0);\n const dir = value(asked, `form/runtime/${said(\"capsule/runtime\")}/regions`);\n const files = dir === void 0 || shown !== void 0 ? [] : receipts(asked, \"source\").map(placeOf).filter((at) => at.startsWith(dir) && regions.includes(stem(at)));\n const longest = hull([0, ...[...new Set(files)].map((at) => numeral(receiptValue(asked, \"source\", \"source/lines\", at)) || 0)]).hi;\n const uses = own.find((line) => of(line, \"scope\").startsWith(\"uses/\"));\n const release = new Set([said(\"capsule/topos\"), shown === void 0 ? value(asked, `uses/${asked.name}`) ?? \"\" : \"\"].filter((one) => one.startsWith(\"sha256:\")));\n const blob = shown === void 0 ? \"\" : of(uses, \"value\");\n const pin = blob.startsWith(\"sha256:\") && !release.has(blob) ? blob : \"\";\n const stages = [\n say(asked, \"figure/world/declares\", { domain: said(\"capsule/domain\"), runtime: said(\"capsule/runtime\"), effects: said(\"capsule/effects\") }),\n ...shown === void 0 ? [say(asked, \"figure/world/regions\", { count: regions.length, longest }), say(asked, \"figure/world/vectors\", { count: receipts(asked, \"vectors\").length })] : ordered.map((line) => say(asked, \"figure/world/region\", { name: nameOf(line), reads: of(line, \"value\") })),\n ...pin ? [say(asked, \"figure/world/pinned\", { place: asked.name })] : [],\n ...shown !== void 0 && pin ? [say(asked, \"figure/world/adopted\", { scope: of(uses, \"scope\") })] : [],\n say(asked, \"figure/world/host\", { runtime: said(\"capsule/runtime\") })\n ].filter((stage) => Boolean(stage));\n const [held, alone] = states(asked);\n const g = spacing(asked, \"world\");\n const [height, wide] = [stages.length * g.pitch, hull([numeral(look(asked, \"width/figure\")), Math.ceil(g.margin + hull([0, ...stages.map((stage) => stage.length)]).hi * g.char)]).hi];\n return drawn2(asked, own.length && stages.length ? [\n ``,\n ...style([css([[\"text\", { ...font(asked, \"code\", \"small\"), fill: painted(asked, \"text\").colour }], [\"rect\", { fill: \"none\", stroke: alone?.colour }], [\"line\", { stroke: held?.colour }]])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ...stages.flatMap((stage, i) => [\n ``,\n `${escaped(stage)}`,\n ...i ? [``] : []\n ]),\n \"\"\n ] : [], listOf(asked, stages), \"figure/world\");\n};\n\n// ../provider-closure/world/dist/regions/first-use.js\nvar render13 = (asked) => ((first) => first === void 0 ? [] : [...section(asked, \"first-use\"), say(asked, \"first-use/lead\", { name: first.name }), \"\", ...glance(asked, first, folder(asked.shape))])(shortest(asked));\n\n// ../provider-closure/world/dist/regions/forms.js\nvar render14 = (asked) => [\n `## ${prose(asked, \"reference/forms\") ?? \"\"}`,\n \"\",\n ...[...new Set(typedAs(asked, \"source/declared/\", value(asked, \"docs/forms\") ?? \"\", \"args\").map(([name, args]) => `- ${say(asked, \"reference/form\", { name, args: cellText(args) })}`))].sort()\n];\n\n// ../provider-closure/world/dist/regions/guide-at-zero.js\nvar render15 = (asked) => resolved(asked, [\n `# ${prose(asked, \"guide/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"contributing\", { check: value(asked, \"check\") ?? say(asked, \"guide/owed\"), open: count(asked, laws(asked).filter((line) => of(line, \"kind\") === \"conjecture\").length, true) })\n]);\n\n// ../provider-closure/world/dist/regions/hero.js\nvar badges = (asked) => {\n const [held, alone] = states(asked);\n const part = (text) => encodeURIComponent(text.split(\"-\").join(\"--\").split(\"_\").join(\"__\").split(\" \").join(\"_\"));\n const shield = (label, message, colour) => `![${label} ${message}](${value(asked, \"sources/badges\") ?? \"\"}/${part(label)}-${part(message)}-${(colour?.colour ?? \"\").slice(1)})`;\n const measured = (region, scope) => {\n const said = receiptValue(asked, region, scope);\n if (said === void 0)\n return void 0;\n for (const text of [said, `${said}..${said}`]) {\n try {\n const got = fromLine(canonical({ at: \"place:badge\", by: \"reader\", form: \"interval\", measure: \"count\", role: \"reads\", scope, value: text }), null);\n if (got.kind !== \"fact\" || got.value.bound.kind !== \"interval\")\n continue;\n const { lo, hi } = got.value.bound;\n if (lo !== null && lo === hi && Number.isFinite(lo))\n return lo;\n } catch {\n }\n }\n return void 0;\n };\n const cases = measured(\"cases\", \"cases/held\");\n const depends = found(asked, \"dependencies\") === void 0 ? void 0 : listed(asked, \"dependencies\").length;\n const verdict = receiptValue(asked, \"state\", \"second/verdict\");\n const doi = entries(asked, \"cites\").map((one) => value(asked, \"sources/doi\") === void 0 ? void 0 : one.field(\"doi\")).find(Boolean);\n const valued = (key) => {\n const said = value(asked, key);\n if (said === void 0)\n return [];\n const label = say(asked, `badge/${key}`) || key;\n const message = said === label || said.startsWith(`${label} `) ? said.slice(label.length).trim() : said;\n return message === \"\" ? [] : [shield(label, message, alone)];\n };\n const n = (scope) => measured(\"state\", scope);\n const digest = receiptValue(asked, \"state\", \"release/digest\") ?? \"\";\n const lawCounts = [\"verdict/met\", \"verdict/short\", \"verdict/over\", \"verdict/refused\", \"verdict/forks\"].map(n);\n const complete = verdict !== void 0 && lawCounts.every((one) => one !== void 0);\n const broken = !complete || lawCounts.slice(1).some((one) => one !== 0) || verdict !== \"agrees\";\n const drawn3 = {\n dependencies: () => depends === void 0 ? [] : [shield(say(asked, \"badge/dependencies\"), String(depends), depends ? alone : held)],\n cases: () => cases !== void 0 ? [shield(say(asked, \"badge/cases\"), say(asked, \"badge/held\", { count: cases }), held)] : [],\n verify: () => verdict === void 0 ? [] : [shield(say(asked, \"badge/verify\") || \"verify\", verdict, verdict === \"agrees\" ? held : alone)],\n doi: () => doi === void 0 ? [] : [`[${shield(say(asked, \"badge/doi\"), doi, alone)}](${value(asked, \"sources/doi\") ?? \"\"}${doi})`],\n release: () => digest ? [shield(say(asked, \"badge/release\") || \"release\", digest.replace(/^[^:]*:/, \"\").slice(0, 12), held)] : [],\n claims: () => ((c) => c !== void 0 ? [shield(say(asked, \"badge/claims\") || \"claims\", String(c), held)] : [])(n(\"verdict/claims\")),\n second: () => ((c) => c === void 0 ? [] : [shield(say(asked, \"badge/second\") || \"second\", String(c), verdict === \"agrees\" ? held : alone)])(n(\"verdict/met\")),\n laws: () => complete ? [shield(say(asked, \"badge/laws\") || \"laws\", `${lawCounts[0]}/${lawCounts.slice(0, 4).reduce((sum, one) => sum + (one ?? 0), 0)}`, broken ? alone : held)] : []\n };\n const named = found(asked, \"docs/badges\") !== void 0 ? listed(asked, \"docs/badges\") : listed(asked, \"wire/badges/world\").length ? listed(asked, \"wire/badges/world\") : listed(asked, \"audit/wire/badges/world\");\n return [named.flatMap((name) => (drawn3[name] ?? (() => valued(name)))()).join(\" \")];\n};\nvar render16 = (asked) => [\n ...((logo) => logo === void 0 ? [] : [`\"\"${attrs({

`, \"\"])(value(asked, \"docs/logo\")),\n `# ${value(asked, \"name\") ?? asked.name}`,\n \"\",\n ...badges(asked),\n ...((what) => what === void 0 ? [] : [\"\", sentence(asked, what)])(of(found(asked, \"docs/tagline\"), \"about\") || prose(asked, \"what\"))\n];\n\n// ../provider-closure/world/dist/regions/how-they-rest.js\nvar render17 = (asked) => {\n const where = (glob) => asked.lines.filter((line) => matches(glob, of(line, \"scope\")));\n const packages = new Map(where(\"*/name\").map((line) => [of(line, \"value\"), steps(of(line, \"scope\"))[0] ?? \"\"]));\n const among = where(\"*/dependencies\").flatMap((line) => alphabet(of(line, \"value\")).members.map((spec) => [...packages].find(([name]) => spec.startsWith(`${name}@`))?.[1]).filter((to) => to !== void 0).map((to) => ` ${steps(of(line, \"scope\"))[0] ?? \"\"} --> ${to}`)).sort(byBytes);\n const summary = asked.lines.find((line) => of(line, \"scope\").startsWith(`prose/${lang(asked)}/`) && of(line, \"scope\").endsWith(\"/rests\"));\n if (among.length)\n return zoom(of(summary, \"about\"), [\"```mermaid\", \"flowchart RL\", ...among, \"```\"]);\n const prefix = ((name) => name.slice(0, name.lastIndexOf(\"/\") + 1))(value(asked, \"name\") ?? \"\");\n const depends = alphabet(value(asked, \"dependencies\") ?? \"\").members;\n const needed = [...new Set(where(\"needs/*\").map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))].filter((one) => one && one !== asked.name);\n const pinned = [...new Set(where(\"uses/*\").map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))].filter((one) => depends.some((spec) => spec.startsWith(`${prefix}${one}@`)));\n const read = [...new Set(where(\"dep/*\").filter((line) => of(line, \"role\") === \"reads\").map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))];\n const rests2 = (needed.length ? needed : pinned.length ? pinned : read).filter((one) => one && one !== asked.name).sort(byBytes);\n return rests2.length ? [...((heading2) => heading2 ? [`## ${heading2}`, \"\"] : [])(prose(asked, \"rests/heading\")), say(asked, \"rests/on\", { names: listOf(asked, rests2) })] : [];\n};\n\n// ../provider-closure/world/dist/regions/idea.js\nvar render18 = (asked) => resolved(asked, titled(asked, \"idea\", parted(asked, \"idea\")));\n\n// ../provider-closure/world/dist/regions/line.js\nvar render19 = (asked) => {\n const pin = value(asked, `sources/${asked.name}`);\n if (pin === void 0)\n return [];\n const uses = value(asked, `uses/${asked.name}`) ?? \"\";\n const shown = [pin, ...uses && !uses.startsWith(\"sha256:\") ? [uses] : []];\n return resolved(asked, shown);\n};\n\n// ../provider-closure/world/dist/regions/install.js\nvar render20 = (asked) => {\n if (found(asked, `uses/${asked.name}`) !== void 0 || found(asked, `sources/${asked.name}`) !== void 0)\n return render19(asked);\n const [how, name] = [value(asked, \"install\"), value(asked, \"name\")];\n return resolved(asked, how === void 0 || name === void 0 ? [] : [\"```bash\", `${how} ${name}`, \"```\"]);\n};\n\n// ../provider-closure/world/dist/regions/learn.js\nvar restsOn = (asked, called, shown) => {\n const ids = /* @__PURE__ */ new Map();\n const offered = (call) => offers(asked).find((line) => of(line, \"scope\").endsWith(`/${call}`));\n const calls = called.filter((call) => offers(asked).some((line) => of(line, \"scope\").endsWith(`/${call}`) && of(line, \"restsOn\") !== \"\"));\n const edges = calls.flatMap((call, i) => alphabet(of(offered(call), \"restsOn\")).members.map((on) => ` c${i} --> ${ids.get(on) ?? ids.set(on, `l${ids.size}`).get(on)}`));\n const colour = states(asked)[0]?.colour;\n return edges.length ? [\n \"```mermaid\",\n \"flowchart LR\",\n ...calls.map((call, i) => ` c${i}[\"${call}\"]`),\n ...[...ids].map(([scope, id]) => ` ${id}([\"${labelOf(asked, scope)}\"])`),\n ...edges,\n ...classDef(\"shown\", colour, painted(asked, \"text-on\").colour),\n ` class ${ids.get(shown) ?? \"\"} shown`,\n \"```\"\n ] : [];\n};\nvar render21 = (asked) => {\n const one = examples(asked).find((example) => example.name === stem(asked.shape));\n if (one === void 0)\n return ((first) => first === void 0 ? [] : [\n ...section(asked, \"learn\"),\n ...glance(asked, first, folder(asked.shape)),\n ...((caption) => caption ? [\"\", sentence(asked, caption)] : [])(((cell3) => cell3 === void 0 ? \"\" : captioned(asked, cell3))(cellOf(asked, first.at)))\n ])(examples(asked).find((example) => example.name === value(asked, \"docs/learn\")) ?? shortest(asked));\n const called = receipts(asked, \"source\").filter((line) => placeOf(line) === one.at && of(line, \"scope\") === \"source/calls\").flatMap((line) => alphabet(of(line, \"value\")).members);\n const rests2 = /* @__PURE__ */ new Map();\n for (const call of called)\n for (const on of alphabet(of(offers(asked).find((line) => of(line, \"scope\").endsWith(`/${call}`)), \"restsOn\")).members)\n rests2.set(on, (rests2.get(on) ?? 0) + 1);\n const shown = [...rests2].sort((a, b) => b[1] - a[1] || byBytes(a[0], b[0]))[0]?.[0];\n const stated2 = shown === void 0 ? void 0 : lawAt(asked, shown);\n const graph = stated2 === void 0 || shown === void 0 ? [] : restsOn(asked, called, shown);\n const [cell2, here] = [cellOf(asked, one.at), asked.shape.slice(0, asked.shape.lastIndexOf(\"/\"))];\n const drawn3 = figured(asked, \"ranges\", numeral(value(asked, \"form/page/statement\"))).map(figureAt).find((at) => at !== void 0 && stem(at) === one.name);\n const shownFigure = drawn3 !== void 0 && cell2 !== void 0 ? [image(asked, relative(here, drawn3), cell2), \"\", sentence(asked, captioned(asked, cell2))] : shown !== void 0 && shown === value(asked, \"notation/object\") ? graph : [];\n return resolved(asked, [\n `# ${heading(asked, one.name)}`,\n \"\",\n ...shownFigure.length ? [...shownFigure, \"\"] : [],\n ...stated2 ? [sentence(asked, of(stated2, \"about\")), \"\"] : [],\n `## ${prose(asked, \"learn/run\") ?? \"\"}`,\n \"\",\n ...run(asked, one),\n \"\",\n ...graph.length && shownFigure !== graph ? [`## ${prose(asked, \"learn/rests\") ?? \"\"}`, \"\", ...graph, \"\"] : [],\n ...titled(asked, \"learn/source\", [say(asked, \"learn/source\", { at: relative(here, one.at), place: asked.name })])\n ]);\n};\n\n// ../provider-closure/world/dist/regions/license.js\nvar render22 = (asked) => resolved(asked, asked.lines.filter((line) => of(line, \"scope\") === \"license\" && of(line, \"about\") !== \"\").flatMap((line) => of(line, \"about\").split(\"\\n\")));\n\n// ../provider-closure/world/dist/regions/media.js\nvar render23 = (asked) => {\n const [kept, sha] = [value(asked, \"form/page/media\"), \"sha256:\"];\n const [still, players] = [[\"svg\", \"png\", \"gif\"], [\"video\", \"audio\"]];\n const source = (said) => said.startsWith(sha) ? kept && fill(asked, \"page/media\", kept, { digest: said.slice(sha.length) }) : said;\n const embed = (form2, src, about) => still.includes(form2) ? `

` : players.includes(form2) ? `<${form2}${attrs({ src, width: form2 === players[0] ? look(asked, \"width/figure\") : void 0 })} controls>` : void 0;\n const lines = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"media/\")).sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\")));\n return lines.flatMap((line) => /* @__PURE__ */ ((one) => one ? [\"\", one] : [])(embed(of(line, \"measure\"), source(of(line, \"value\")), of(line, \"about\")))).slice(1);\n};\n\n// ../provider-closure/world/dist/regions/notation.js\nvar formulaLaw = (asked, formula) => lawAt(asked, of(formula, \"scope\").slice(0, of(formula, \"scope\").lastIndexOf(\"/\")));\nvar arrows = (asked) => {\n const held = object(asked);\n const module = held === void 0 ? void 0 : moduleOfObject(asked, held);\n const symbols = new Map(pairs(asked, \"notation/symbols\"));\n const made = module === void 0 || held === void 0 ? [] : resting(asked, of(held, \"scope\")).map((line) => of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1)).flatMap((name) => {\n const params = receiptLine(asked, \"source\", `source/arrow/${name}`, module, \"params\");\n const result = receiptValue(asked, \"source\", `source/arrow/${name}`, module, \"result\");\n if (params === void 0 || result === void 0)\n return [];\n const typed = fields(of(params, \"value\")).map(([name2, type]) => symbolOf(asked, type, name2));\n const makes = symbolOf(asked, result, \"value\") === symbols.get(\"object\") && !typed.some((one) => one === symbols.get(\"object\") || one === `[${symbols.get(\"object\")}]`);\n return makes ? [] : [[name, `${typed.join(` ${glyph(asked, \"product\")} `)} ${glyph(asked, \"maps\")} ${symbolOf(asked, result, \"value\")}`]];\n });\n const kind = pairs(asked, \"notation/types\").find(([, sym]) => sym === symbols.get(\"state\"))?.[0] ?? \"\";\n const union = alphabet(of([...receipts(asked, \"source\")].filter((one) => of(one, \"scope\") === `source/union/${kind}`).sort((a, b) => byBytes(placeOf(a), placeOf(b)))[0], \"value\")).members;\n const width = hull(made.map(([name]) => name.length)).hi;\n return [...made.map(([name, arrow]) => `${name.padEnd(width)} : ${arrow}`), ...union.length ? [`${symbols.get(\"state\")}(${symbols.get(\"object\")}) ${glyph(asked, \"member\")} {${union.join(\", \")}}`] : []];\n};\nvar render24 = (asked) => {\n const head = tuple(asked);\n if (head === void 0)\n return [];\n if (asked.at <= 0)\n return [\"```text\", head, \"```\"];\n if (asked.at <= 1)\n return [\"```text\", head, ...aligned(asked), \"```\"];\n const all = formulas(asked);\n if (!reaches(asked, \"whole\"))\n return [\"```text\", head, \"```\", \"\", ...all.map((line) => `- \\`${of(line, \"value\")}\\` \\u2014 ${of(formulaLaw(asked, line), \"about\")}.`)];\n return [\n `## ${prose(asked, \"reference/notation\") ?? \"\"}`,\n \"\",\n \"```text\",\n head,\n \"```\",\n \"\",\n prose(asked, \"notation/table\") ?? \"\",\n \"|---|---|---|\",\n ...all.map((line) => ((law) => `| \\`${cellText(of(line, \"value\"))}\\` | ${law === void 0 ? \"\" : lawName(asked, law)} | ${cellText(of(law, \"about\"))} |`)(formulaLaw(asked, line))),\n \"\",\n \"```text\",\n ...arrows(asked),\n \"```\"\n ];\n};\n\n// ../provider-closure/world/dist/regions/open.js\nvar render25 = (asked) => {\n const needed = asked.lines.filter((line) => matches(\"needs/*\", of(line, \"scope\")) && of(line, \"value\") !== \"withdraw\");\n if (needed.length)\n return resolved(asked, [...section(asked, \"open\"), \"\", ...needed.map((line) => `- ${of(line, \"about\") || of(line, \"scope\")}`)]);\n const facts = (family) => receipts(asked, \"state\").filter((line) => of(line, \"scope\").startsWith(`${family}/`)).sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))).map((line) => [of(line, \"scope\").slice(family.length + 1), of(line, \"value\")]);\n const said = (family) => facts(family).map(([scope, reading2]) => say(asked, `open/${family}`, { scope, reading: reading2 })).filter(Boolean).map((one) => `- ${one}`);\n const judged = facts(\"conjecture\").map(([scope, reading2]) => ((law) => law === void 0 ? say(asked, \"open/open\", { scope, reading: reading2 }) : conjectured(asked, law))(lawAt(asked, scope))).filter(Boolean);\n const held = judged.length ? judged : laws(asked).filter((line) => of(line, \"kind\") === \"conjecture\").map((law) => conjectured(asked, law));\n const [unpaid, outside] = [said(\"unpaid\"), said(\"outside\")];\n if (!held.length && !unpaid.length && !outside.length)\n return [];\n return resolved(asked, [...section(asked, \"open\"), ...[\n ...held.length ? [\"\", say(asked, judged.length ? \"open/judged\" : \"open/lead\", { count: count(asked, held.length, true) }), \"\", ...held.map((one) => `- ${one}`)] : [],\n ...unpaid.length ? [\"\", ...unpaid] : [],\n ...outside.length ? [\"\", ...outside] : []\n ].slice(1)]);\n};\n\n// ../provider-closure/world/dist/regions/open-conjectures.js\nvar render26 = (asked) => {\n const held = laws(asked).filter((line) => of(line, \"kind\") === \"conjecture\");\n if (!held.length)\n return [];\n const bullet = (line) => `- ${conjectured(asked, line)}`;\n const who = pairs(asked, \"open/who\");\n const groups = [...new Set(who.map(([group]) => group))].map((group) => [group, held.filter((line) => who.some(([g, one]) => g === group && lawKey(line) === one))]);\n const loose = held.filter((line) => !who.some(([, one]) => lawKey(line) === one));\n const full = held.map((line) => `${sentence(asked, of(line, \"about\"))} ${(sample(asked, line, \"no\").about ?? [])[0] ?? \"\"}`.trim());\n return resolved(asked, [\n `## ${prose(asked, \"open/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"open/lead\", { count: count(asked, held.length, true) }),\n ...groups.flatMap(([group, lines]) => lines.length ? [\"\", say(asked, \"open/group\", { count: count(asked, lines.length, true), group }), \"\", ...lines.map(bullet)] : []),\n ...loose.length ? [\"\", ...loose.map(bullet)] : [],\n \"\",\n ...zoom(say(asked, \"open/full\"), full.flatMap((part) => [part, \"\"]).slice(0, -1))\n ]);\n};\n\n// ../provider-closure/world/dist/regions/operations.js\nvar render27 = (asked) => {\n const read = new Map(receipts(asked, \"offers\").map((line) => [of(line, \"scope\"), of(line, \"value\")]));\n const signature = (line) => {\n const [op, module] = [of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1), moduleOf(asked, line)];\n const head = module === void 0 ? void 0 : receiptValue(asked, \"source\", `source/signature/${op}`, module);\n return head === void 0 ? say(asked, \"reference/owed\") : cellText(head);\n };\n return [\n `## ${prose(asked, \"reference/operations\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/operations-table\") ?? \"\",\n \"|---|---|---|---|---|\",\n ...[...offers(asked)].sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))).map((line) => {\n const [view = \"\", op = \"\"] = steps(of(line, \"scope\")).slice(1);\n return `| ${op} | ${view} | \\`${signature(line)}\\` | ${((n) => Number.isNaN(n) ? 0 : n)(numeral(read.get(`${of(line, \"scope\")}/no-samples`)))} | ${cellText(keys(asked, of(line, \"restsOn\"))) || say(asked, \"reference/unrested\")} |`;\n })\n ];\n};\n\n// ../provider-closure/world/dist/regions/pointers.js\nvar render28 = (asked) => {\n const written = new Set(receipts(asked, \"state\").filter((one) => of(one, \"measure\") === \"fact\" && of(one, \"value\") === \"present\").map((one) => of(one, \"scope\").slice(of(one, \"scope\").indexOf(\"/\") + 1)));\n const views = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"view/\") && of(line, \"role\") === \"demands\");\n const pages = [...new Map(views.filter((view) => of(view, \"shape\").endsWith(\".md\") && of(view, \"shape\").includes(\"/\") && written.has(of(view, \"shape\"))).map((view) => [of(view, \"shape\"), view])).values()];\n const learn = pages.filter((view) => alphabet(of(view, \"value\")).members.some((token) => atResolution(token).name === \"learn\")).sort((a, b) => byBytes(of(a, \"shape\"), of(b, \"shape\")));\n const rest = pages.filter((view) => !learn.includes(view)).map((view) => [heading(asked, stem(of(view, \"shape\")).toLowerCase()), of(view, \"shape\")]).sort((a, b) => byBytes(a[0], b[0]));\n const bullets = [\n ...rest.map(([title, shape]) => `- [${title}](${shape})`),\n ...learn.length ? [`- ${say(asked, \"pointers/learn\", { pages: learn.map((view) => `[${words(asked, stem(of(view, \"shape\")))}](${of(view, \"shape\")})`).join(\", \") })}`] : []\n ];\n return resolved(asked, bullets.length ? [...section(asked, \"pointers\"), ...bullets] : []);\n};\n\n// ../provider-closure/world/dist/regions/ranges.js\nvar render29 = (asked) => {\n const one = reaches(asked, \"statement\") ? examples(asked).find((example) => example.name === stem(asked.shape)) : shortest(asked);\n const lines = reaches(asked, \"statement\") ? [] : sampled(asked, ((law) => law === void 0 ? \"\" : sample(asked, law, \"yes\").at ?? \"\")(object(asked)))?.lines ?? [];\n const cell2 = cellOfLines(lines.filter((line) => of(line, \"scope\") === of(lines[0], \"scope\"))) ?? (one === void 0 ? void 0 : cellOf(asked, one.at));\n if (cell2 === void 0)\n return [];\n const [held, alone, , forked] = states(asked);\n const apart = (i) => SPANS.inhabited(cell2.claims.filter((_, j) => j !== i).reduce((all, other) => SPANS.meet(all, other.span), SPANS.top));\n const g = spacing(asked, \"ranges\");\n const beat = (attribute, from, to) => from === void 0 || to === void 0 ? \"\" : ``;\n const [width, left, top, row] = [numeral(look(asked, \"width/figure\")), g.left, g.top, g.row];\n const right = width - g.right;\n const x = (v) => px(between(v, [cell2.hull.lo - g.pad, cell2.hull.hi + g.pad], [left, right]));\n const rows = [...cell2.claims.map((one2) => ({ label: one2.origin, ...one2.span, kind: \"claim\" })), { label: say(asked, \"cell/held-row\"), ...cell2.held, kind: \"held\" }];\n const [axis, meets] = [top + rows.length * row + g.axis, SPANS.inhabited(cell2.held)];\n const height = axis + (meets ? g.poles : g.tail);\n return [\n ``,\n `${say(asked, \"cell/title\")}`,\n `${escaped(described(asked, cell2))}`,\n ...style([css([[\"text\", { ...font(asked, \"text\", \"text\"), fill: painted(asked, \"text\").colour }]]), css([\n [\".claim\", { fill: alone?.colour }],\n [\".held\", { fill: held?.colour }],\n [\".pole\", { fill: held?.colour, \"font-weight\": look(asked, \"weight/strong\") }],\n [\".axis,.tick\", { stroke: alone?.colour, \"stroke-width\": look(asked, \"stroke/rule\") }],\n [\".touch\", { stroke: held?.colour, \"stroke-width\": look(asked, \"stroke/rule\"), \"stroke-dasharray\": look(asked, \"stroke/dash\") }]\n ])], css([[\"text\", { fill: painted(asked, \"text-dark\").colour }]])),\n ...meets ? [cell2.held.lo, cell2.held.hi].map((v) => ``) : [],\n ...rows.flatMap((bar, i) => [\n `${escaped(bar.label)}`,\n bar.kind === \"held\" && !meets ? `${escaped(prose(asked, \"apart\") ?? \"\")}` : ` moves2 ? `>${moves2}` : \"/>\")(bar.kind === \"held\" ? beat(\"opacity\", \"0\", \"1\") : beat(\"fill\", alone?.colour, meets ? held?.colour : apart(i) ? forked?.colour : void 0))}`\n ]),\n ``,\n ...[.../* @__PURE__ */ new Set([cell2.hull.lo, cell2.held.lo, cell2.held.hi, cell2.hull.hi])].sort((a, b) => a - b).flatMap((v) => [``, `${v}`]),\n ...meets ? [`${say(asked, \"cell/floor\")}`, `${say(asked, \"cell/ceiling\")}`] : [],\n \"\"\n ];\n};\n\n// ../provider-closure/world/dist/regions/reading.js\nvar render30 = (asked) => {\n const rows = receipts(asked, \"source\").filter((line) => of(line, \"scope\") === \"source/answers\");\n const named = (at) => rows.filter((one) => stem(placeOf(one)) === stem(at)).length > 1 ? (([last, parent = last]) => parent)([...steps(at)].reverse()) ?? stem(at) : stem(at);\n const order2 = listed(asked, \"docs/reading\");\n const rank = (name) => ((at) => at < 0 ? order2.length : at)(order2.indexOf(name));\n const answered = rows.map((line) => [named(placeOf(line)), of(line, \"value\")]).sort((a, b) => rank(a[0]) - rank(b[0])).map(([name, answer]) => say(asked, \"reading/view\", { name, answer })).filter(Boolean).map((one) => `- ${one}`);\n return answered.length ? [...titled(asked, \"reading\", [say(asked, \"reading/lead\")]), \"\", ...answered] : [];\n};\n\n// ../provider-closure/world/dist/regions/reference.js\nvar render31 = (asked) => {\n const forms = new Set(typedAs(asked, \"source/declared/\", value(asked, \"docs/forms\") ?? \"\", \"args\").map(([name, args]) => `- ${say(asked, \"reference/form\", { name, args: cellText(args) })}`));\n return [`# ${prose(asked, \"reference/heading\") ?? \"\"}`, \"\", say(asked, \"reference/lead\", { operations: offers(asked).length, laws: laws(asked).filter((line) => of(line, \"form\") !== \"formula\").length, forms: forms.size })];\n};\n\n// ../provider-closure/world/dist/regions/refuses.js\nvar render32 = (asked) => {\n const told = refusedCases(asked);\n const here = folder(asked.shape);\n const captured2 = told.map((one) => `- ${one.name}: ${one.why || one.input}`).filter((one) => one.length > 3);\n if (captured2.length) {\n return resolved(asked, [...section(asked, \"refuses\"), ...say(asked, \"refuses/lead\") ? [say(asked, \"refuses/lead\")] : [], \"\", ...captured2]);\n }\n const kept = laws(asked).filter((line) => of(line, \"kind\") !== \"conjecture\" && sample(asked, line, \"no\").recorded).sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\")));\n const law = kept.find((line) => of(line, \"scope\") === value(asked, \"notation/object\")) ?? kept[0];\n const no = law === void 0 ? void 0 : sample(asked, law, \"no\");\n const said = [law === void 0 ? \"\" : say(asked, \"refuses/lead\", { law: lawName(asked, law), at: relative(here, no?.at ?? \"\") })].filter(Boolean);\n return said.length ? resolved(asked, [\n ...section(asked, \"refuses\"),\n ...said,\n ...no?.about?.length ? [\"\", ...zoom(say(asked, \"refuses/full\"), no.about.flatMap((line) => [line, \"\"]).slice(0, -1))] : []\n ]) : [];\n};\n\n// ../provider-closure/world/dist/regions/regions.js\nvar rules = (asked) => ((held) => !held.length ? [] : [\n `# ${prose(asked, \"regions/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"regions/laws\", { count: count(asked, held.length, true) }),\n \"\",\n prose(asked, \"regions/laws-table\") ?? \"\",\n \"|---|---|\",\n ...held.map((line) => `| ${steps(steps(of(line, \"scope\")).slice(1))} | ${cellText(of(line, \"about\"))} |`)\n])(asked.lines.filter((line) => of(line, \"scope\").startsWith(\"audit/\") && of(line, \"role\") === \"demands\" && of(line, \"about\") !== \"\").sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))));\nvar render33 = (asked) => {\n const own = [...asked.lines, ...regionLines(asked, \"capsule\")];\n const said = (scope, measure) => own.filter((line) => of(line, \"scope\") === scope && (measure === void 0 || of(line, \"measure\") === measure)).flatMap((line) => alphabet(of(line, \"value\")).members);\n const names = [...new Set(own.filter((line) => of(line, \"scope\").startsWith(\"region/\") && of(line, \"measure\") === \"reads\" || of(line, \"scope\").startsWith(\"capsule/reads/\")).map((line) => of(line, \"scope\").slice(of(line, \"scope\").lastIndexOf(\"/\") + 1)))].sort();\n return resolved(asked, !names.length ? rules(asked) : [\n `# ${prose(asked, \"regions/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"regions/lead\", { count: count(asked, names.length, true), effects: listOf(asked, said(\"capsule/effects\")) || alphabet({ polarity: \"permit\", members: [] }) }),\n \"\",\n prose(asked, \"regions/table\") ?? \"\",\n \"|---|---|---|\",\n ...names.map((name) => `| ${name} | ${cellText([...said(`region/${name}`, \"reads\"), ...said(`capsule/reads/${name}`)].join(\" \\xB7 \"))} | ${cellText([...said(`region/${name}`, \"writes\"), ...said(`capsule/writes/${name}`)].join(\" \\xB7 \")) || say(asked, \"regions/leaf\")} |`)\n ]);\n};\n\n// ../provider-closure/world/dist/regions/rested-on-by.js\nvar render34 = (asked) => {\n const said = receipts(asked, \"state\").filter((line) => of(line, \"scope\").startsWith(\"rested/\"));\n const field = (place, name) => of(said.find((line) => of(line, \"scope\") === `rested/${place}/${name}`), \"value\");\n const places = [...new Set(said.map((line) => steps(of(line, \"scope\"))[1] ?? \"\"))].filter((place) => field(place, \"source\")).sort(byBytes);\n return resolved(asked, places.length ? [...section(asked, \"rested\"), ...places.map((place) => `- ${say(asked, \"rested/place\", { place, repository: field(place, \"repository\") })}${field(place, \"what\") ? ` \\xB7 ${say(asked, \"rested/what\", { repository: field(place, \"repository\"), what: field(place, \"what\") })}` : \"\"}`)] : []);\n};\n\n// ../provider-closure/world/dist/regions/the-object.js\nvar machine = (asked) => {\n const [drawn3, renders] = [moves(asked), pairs(asked, \"notation/renders\")];\n if (drawn3 === void 0)\n return [];\n const colours = renders.flatMap(([state3, name]) => /* @__PURE__ */ ((colour) => colour === void 0 ? [] : [[state3, name, colour]])(painted(asked, state3).colour));\n return [\n \"```mermaid\",\n \"stateDiagram-v2\",\n ...renders.map(([state3, name]) => ` state \"${state3} \\xB7 ${name}\" as ${state3}`),\n ...drawn3.map((move) => ` ${move.from} --> ${move.to}${move.dangerous ? `: ${say(asked, \"states/dangerous\")}` : move.why ? `: ${move.why}` : \"\"}`),\n ...colours.flatMap(([, name, colour]) => classDef(name, colour, painted(asked, \"text-on\").colour)),\n ...colours.map(([state3, name]) => ` class ${state3} ${name}`),\n \"```\"\n ];\n};\nvar rests = (asked) => {\n const [held, on] = [object(asked), alphabet(of(object(asked), \"restsOn\")).members];\n if (held === void 0 || !on.length || !resting(asked, of(held, \"scope\")).length)\n return [];\n const colour = states(asked)[0]?.colour;\n return [\n `## ${prose(asked, \"reference/rests\") ?? \"\"}`,\n \"\",\n \"```mermaid\",\n \"flowchart BT\",\n ` o([\"${lawName(asked, held)}\"])`,\n ...on.map((scope, i) => ` r${i}([\"${labelOf(asked, scope)}\"])`),\n ...on.map((_, i) => ` o --> r${i}`),\n ...classDef(\"object\", colour, painted(asked, \"text-on\").colour),\n \" class o object\",\n \"```\"\n ];\n};\nvar render35 = (asked) => {\n if (reaches(asked, \"whole\"))\n return [`## ${prose(asked, \"reference/states\") ?? \"\"}`, \"\", ...machine(asked), \"\", ...rests(asked)];\n const head = tuple(asked);\n const written = head === void 0 ? [] : [\"```text\", head, ...aligned(asked), \"```\"];\n const [glyphs, rows] = [new Map(pairs(asked, \"notation/renders\").map(([state3]) => [state3, painted(asked, state3).glyph ?? \"\"])), pairs(asked, \"notation/states\")];\n const seen = /* @__PURE__ */ new Set();\n const unique = rows.filter(([, state3]) => seen.has(state3) ? false : (seen.add(state3), true));\n const [width, widest, gap] = [hull([0, ...unique.map(([when]) => when.length)]).hi, hull([0, ...unique.map(([, state3]) => state3.length)]).hi, spacing(asked, \"table/gap\")];\n const table2 = unique.length ? [\"```text\", ...unique.map(([when, state3]) => `${when.padEnd(width + gap.state)}${state3.padEnd(widest + gap.glyph)}${glyphs.get(state3) ?? \"\"}`), \"```\"] : [];\n return resolved(asked, !written.length && !table2.length ? [] : [`## ${prose(asked, \"the-object/heading\") ?? \"\"}`, \"\", ...written, ...table2.length ? [\"\", ...table2] : []]);\n};\n\n// ../provider-closure/world/dist/regions/the-paper.js\nvar render36 = (asked) => {\n const reference = (one) => {\n const doi = value(asked, \"sources/doi\") === void 0 ? void 0 : one.field(\"doi\");\n const address = doi === void 0 ? one.field(\"address\") : `${value(asked, \"sources/doi\")}${doi}`;\n const [authors, year, version, publisher] = [alphabet(one.field(\"author\") ?? \"\").members, one.field(\"year\"), one.field(\"version\"), one.field(\"publisher\")];\n return address === void 0 ? void 0 : [\n authors.length > 1 ? `${authors.slice(0, -1).join(\", \")}${say(asked, \"cite/and\")}${authors[authors.length - 1]}` : authors[0],\n year === void 0 ? void 0 : `(${year}).`,\n `${version === void 0 ? one.title : say(asked, \"cite/versioned\", { title: one.title, version })}.`,\n publisher === void 0 ? void 0 : `${publisher}.`,\n address\n ].filter(Boolean).join(\" \");\n };\n return resolved(asked, titled(asked, \"the-paper\", [...parted(asked, \"paper\"), ...entries(asked, \"cites\").flatMap((one) => reference(one) ?? [])]));\n};\n\n// ../provider-closure/world/dist/regions/units.js\nvar render37 = (asked) => [\n `## ${prose(asked, \"reference/units\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/units-table\") ?? \"\",\n \"|---|---|\",\n ...[...new Set(typedAs(asked, \"source/returns/\", value(asked, \"docs/units\") ?? \"\", \"params\").map(([name, params]) => `| ${name} | \\`${cellText(params)}\\` |`))].sort()\n];\n\n// ../provider-closure/world/dist/regions/what-holds.js\nvar table = (asked) => {\n const read = new Map(receipts(asked, \"laws\").map((line) => [of(line, \"scope\"), of(line, \"value\")]));\n const here = asked.shape.slice(0, asked.shape.lastIndexOf(\"/\"));\n const reproduced = (line) => ((got) => got === void 0 ? say(asked, \"reference/underived\") : say(asked, numeral(got) === 1 ? \"reference/yes\" : \"reference/no\"))([...read].find(([scope]) => scope.endsWith(`/${lawKey(line)}/reproduced`))?.[1]);\n const row = (line) => {\n const [yes, no, formula] = [sample(asked, line, \"yes\"), sample(asked, line, \"no\"), of(laws(asked).find((one) => of(one, \"form\") === \"formula\" && of(one, \"scope\").startsWith(`${of(line, \"scope\")}/`)), \"value\")];\n return `| ${lawKey(line)} | ${of(line, \"kind\") || say(asked, \"reference/unkinded\")} | ${of(line, \"view\") || say(asked, \"reference/any\")} | ${cellText(keys(asked, of(line, \"restsOn\"))) || say(asked, \"reference/nothing\")} | ${cellText(of(line, \"about\"))} | ${formula ? `\\`${cellText(formula)}\\`` : \"\"} | ${yes.recorded && yes.at ? `[${say(asked, \"reference/yes\")}](${relative(here, yes.at)})` : say(asked, \"reference/none\")} | ${cellText((no.about ?? [])[0] ?? say(asked, \"reference/derived\"))} | ${reproduced(line)} |`;\n };\n return [\n `## ${prose(asked, \"reference/laws\") ?? \"\"}`,\n \"\",\n prose(asked, \"reference/laws-table\") ?? \"\",\n \"|---|---|---|---|---|---|---|---|---|\",\n ...laws(asked).filter((line) => of(line, \"form\") !== \"formula\").sort((a, b) => byBytes(of(a, \"scope\"), of(b, \"scope\"))).map(row)\n ];\n};\nvar render38 = (asked) => {\n if (reaches(asked, \"whole\"))\n return table(asked);\n const rests2 = /* @__PURE__ */ new Map();\n for (const line of laws(asked))\n for (const on of alphabet(of(line, \"restsOn\")).members)\n rests2.set(on, (rests2.get(on) ?? 0) + 1);\n const held = laws(asked).filter((line) => of(line, \"kind\") === \"axiom\");\n if (!held.length)\n return [];\n const spelled = ((said) => said === void 0 ? 0 : numeral(said))(value(asked, \"docs/what-holds\"));\n const leaned = [...held].sort((a, b) => (rests2.get(of(b, \"scope\")) ?? 0) - (rests2.get(of(a, \"scope\")) ?? 0));\n const [rest, measured] = [held.filter((line) => !leaned.slice(0, spelled).includes(line)), lawAt(asked, value(asked, \"docs/measured\") ?? \"\")];\n return resolved(asked, [\n ...titled(asked, \"what-holds\", [\n say(asked, \"what-holds/lead\", { count: count(asked, held.length), spelled: count(asked, spelled, true) }),\n ...leaned.slice(0, spelled).map((line) => say(asked, \"what-holds/axiom\", { sentence: sentence(asked, of(line, \"about\")), name: lawName(asked, line), rests: rests2.get(of(line, \"scope\")) ?? 0 }))\n ]),\n ...rest.length ? [\"\", ...zoom(say(asked, \"what-holds/others\", { count: count(asked, rest.length) }), rest.map((line) => `- ${say(asked, \"what-holds/other\", { name: lawName(asked, line), about: of(line, \"about\") })}`))] : [],\n ...measured === void 0 ? [] : [\"\", say(asked, \"what-holds/measured\", { sentence: sentence(asked, of(measured, \"about\")), measured: (sample(asked, measured, \"yes\").about ?? []).slice(-1)[0] ?? \"\" }).trim()]\n ]);\n};\n\n// ../provider-closure/world/dist/regions/wire.js\nvar render39 = (asked) => {\n const [rules2, names, corpus] = [listed(asked, \"wire/rules\"), listed(asked, \"wire/reference\"), listed(asked, \"wire/corpus\")];\n if (!rules2.length && !names.length && !corpus.length)\n return [];\n const tokens = Object.fromEntries(pairs(asked, \"wire/tokens\"));\n const signed = (name) => of(receipts(asked, \"source\").find((one) => of(one, \"scope\") === `source/signature/${name}`), \"value\");\n const held = (name) => of(receipts(asked, \"vectors\").find((one) => of(one, \"scope\") === `vector/${name}`), \"value\");\n const reference = names.map((name) => `| \\`${name}\\` | \\`${cellText(signed(name))}\\` |`);\n return resolved(asked, [\n `# ${prose(asked, \"wire/heading\") ?? \"\"}`,\n \"\",\n say(asked, \"wire/lead\", tokens),\n ...rules2.flatMap((rule2) => [\"\", ...titled(asked, `wire/${rule2}`, [say(asked, `wire/${rule2}`, tokens)])]),\n \"\",\n ...titled(asked, \"wire/reference\", [[prose(asked, \"wire/reference/table\") ?? \"\", \"|---|---|\", ...reference].join(\"\\n\")]),\n \"\",\n ...titled(asked, \"wire/corpus\", [corpus.map((name) => `- \\`vector/${name}\\` \\xB7 ${held(name)}`).join(\"\\n\")])\n ]);\n};\n\n// ../provider-closure/world/dist/regions/say.js\nvar render40 = (asked) => {\n const lines = asked.lines.filter((one) => {\n const scope = of(one, \"scope\");\n return (scope === `page/${asked.region}` || scope.startsWith(`page/${asked.region}/`)) && of(one, \"value\") !== \"withdraw\" && of(one, \"about\") !== \"\";\n });\n if (!lines.length)\n return [];\n const out = [];\n let heading2 = \"\";\n for (const line of lines) {\n const cap = of(line, \"shape\");\n if (cap && cap !== heading2 && !cap.includes(\".\")) {\n heading2 = cap;\n out.push(`## ${cap}`, \"\");\n }\n const strength = of(line, \"kind\") || \"declared\";\n out.push(`${sentence(asked, of(line, \"about\"))} \\xB7 ${strength}`);\n }\n return resolved(asked, out);\n};\n\n// ../provider-closure/world/dist/regions/term.js\nvar render41 = (asked) => {\n const line = asked.lines.find((one) => of(one, \"scope\").startsWith(\"term/\") && of(one, \"value\") !== \"withdraw\") ?? found(asked, `term/${asked.region}`) ?? found(asked, \"notation/object\");\n const word = of(line, \"value\");\n const meaning = of(line, \"about\");\n return !word && !meaning ? [] : resolved(asked, [`**${word}**${meaning ? ` \\u2014 ${meaning}` : \"\"}`]);\n};\n\n// ../provider-closure/world/dist/regions/count.js\nvar render42 = (asked) => {\n const receipts2 = Object.values(asked.regions).flatMap((region) => region.receipts);\n const named = asked.lines.filter((one) => of(one, \"scope\").startsWith(`page/${asked.region}/`) && of(one, \"value\") !== \"withdraw\").flatMap((one) => {\n const scope = of(one, \"scope\").slice(`page/${asked.region}/`.length);\n const matches2 = receipts2.filter((line) => of(line, \"scope\") === scope);\n if (matches2.length !== 1)\n return [];\n const got = of(matches2[0], \"value\");\n return got ? [`${of(one, \"about\") || scope} ${got}`] : [];\n });\n return resolved(asked, named);\n};\n\n// ../provider-closure/world/dist/regions/seq.js\nvar render43 = (asked) => {\n const lines = asked.lines.filter((one) => of(one, \"scope\").startsWith(`page/${asked.region}/`) && of(one, \"about\") !== \"\" && of(one, \"value\") !== \"withdraw\" && !of(one, \"scope\").endsWith(\"/heading\"));\n const steps2 = lines.length ? lines.map((one) => of(one, \"about\")) : alphabet(of(asked.regions[\"path\"]?.receipts.find((line) => of(line, \"scope\") === \"path/steps\") ?? {}, \"value\")).members.filter((one) => one !== \"none\");\n if (!steps2.length)\n return [];\n const heading2 = of(asked.lines.find((one) => of(one, \"scope\") === `page/${asked.region}/heading`), \"about\") || prose(asked, \"seq/heading\");\n return resolved(asked, [...heading2 ? [`## ${heading2}`, \"\"] : [], ...steps2.map((step, i) => `${i + 1}. ${step}`)]);\n};\n\n// ../provider-closure/world/dist/regions/exchange.js\nvar render44 = (asked) => {\n const held = examples(asked);\n const said = asked.lines.filter((one) => of(one, \"scope\").startsWith(`page/${asked.region}/`) && of(one, \"about\") !== \"\" && of(one, \"value\") !== \"withdraw\" && !of(one, \"scope\").endsWith(\"/heading\"));\n if (!held.length && !said.length)\n return [];\n const heading2 = of(asked.lines.find((one) => of(one, \"scope\") === `page/${asked.region}/heading`), \"about\");\n return resolved(asked, [\n ...heading2 ? [`## ${heading2}`, \"\"] : section(asked, \"exchange\"),\n ...held.flatMap((one, i) => [...i ? [\"\"] : [], ...glance(asked, one, folder(asked.shape))]),\n ...said.map((one) => of(one, \"about\"))\n ]);\n};\n\n// ../provider-closure/world/dist/regions/set.js\nvar render45 = (asked) => {\n const pins = alphabet(receiptValue(asked, \"rests\", \"rests-on/pins\") ?? \"\").members.filter((one) => one !== \"none\");\n const fromUses = asked.lines.filter((one) => of(one, \"scope\").startsWith(\"uses/\") && of(one, \"value\") !== \"withdraw\").map((one) => of(one, \"scope\").slice(\"uses/\".length).split(\"/\")[0] ?? \"\").filter(Boolean);\n const regions = alphabet(receiptValue(asked, \"rests\", \"rests-on/regions\") ?? \"\").members.filter((one) => one !== \"none\");\n const pinsHeld = [.../* @__PURE__ */ new Set([...pins, ...fromUses])];\n const members = [...pinsHeld.map((name) => ({ kind: \"pin\", name })), ...regions.map((name) => ({ kind: \"region\", name }))];\n if (!members.length)\n return [];\n return resolved(asked, [\n ...section(asked, \"set\"),\n \"| | |\",\n \"|---|---|\",\n ...members.map((one) => `| ${cellText(one.kind)} | ${cellText(one.name)} |`)\n ]);\n};\n\n// ../provider-closure/world/dist/regions/cell.js\nvar render46 = (asked) => {\n const lines = declaredSample(asked, figured(asked, asked.region, 1)[0]);\n const groups = /* @__PURE__ */ new Map();\n for (const line of lines) {\n const scope = of(line, \"scope\");\n const group = groups.get(scope) ?? [];\n group.push(line);\n groups.set(scope, group);\n }\n return [...groups.values()].flatMap((group) => {\n const cell2 = cellOfLines(group);\n if (cell2 === void 0)\n return [];\n const text = described(asked, cell2) || captioned(asked, cell2);\n return text ? [text] : [];\n });\n};\n\n// ../provider-closure/world/dist/regions/ref.js\nvar render47 = (asked) => {\n const views = asked.lines.filter((line) => of(line, \"scope\").startsWith(\"view/\") && of(line, \"shape\").endsWith(\".md\"));\n const here = folder(asked.shape);\n const links = views.map((line) => {\n const at = of(line, \"shape\");\n const title = of(line, \"shape\").replace(/^.*\\//, \"\").replace(/\\.md$/, \"\") || of(line, \"scope\").slice(\"view/\".length);\n return `- [${title}](${relative(here, at)})`;\n });\n return links.length ? resolved(asked, links) : [];\n};\n\n// ../provider-closure/world/dist/regions/group.js\nvar render48 = (asked) => {\n const lines = asked.lines.filter((one) => {\n const scope = of(one, \"scope\");\n return (scope === `page/${asked.region}` || scope.startsWith(`page/${asked.region}/`)) && of(one, \"about\") !== \"\" && of(one, \"value\") !== \"withdraw\";\n });\n if (!lines.length)\n return [];\n return resolved(asked, lines.map((line) => {\n const scope = of(line, \"scope\");\n const mark2 = scope.endsWith(\"/title\") ? \"#\" : \"##\";\n return `${mark2} ${of(line, \"about\")}`;\n }));\n};\n\n// ../provider-closure/world/dist/index.js\nvar render49 = shell({ \"alphabet\": { reads: [\"lang\", \"prose/*/reference/*\", \"notation/*\"], region: render }, \"bond\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cell/*\", \"prose/*/apart\", \"notation/claim\", \"notation/renders\", \"examples/*\", \"region/examples\", \"region/source\", \"form/style/**\"], region: render2 }, \"cff\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cff/*\", \"cites/*\", \"name\", \"version\", \"author\", \"repository\", \"license\", \"sources/doi\", \"form/page/**\"], region: render3 }, \"check\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/check/*\", \"notation/renders\", \"fold\", \"repository\", \"repository/resolved\", \"check\", \"region/cases\", \"form/style/**\", \"form/page/**\"], region: render4 }, \"claims\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/claims/*\", \"claims/*\", \"dependencies\", \"audit/*\", \"region/state\", \"region/cases\", \"region/laws\", \"region/offers\", \"region/vectors\", \"region/examples\", \"form/page/**\"], region: render5 }, \"commands\": { reads: [\"lang\", \"prose/*/commands\", \"region/captures\", \"form/page/**\"], region: render6 }, \"door\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/door/*\", \"prose/*/cell/*\", \"prose/*/apart\", \"docs/what\", \"view/*\", \"notation/claim\", \"examples/*\", \"region/examples\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render7 }, \"figure\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cell/*\", \"prose/*/apart\", \"prose/*/marks\", \"view/*\", \"notation/claim\", \"examples/*\", \"region/examples\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render8 }, \"figure-fold\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"prose/*/cell/*\", \"form/figure/*\", \"notation/renders\", \"view/*\", \"samples/*\", \"region/laws\", \"form/style/**\"], region: render9 }, \"figure-line\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"form/figure/*\", \"notation/renders\", \"view/*\", \"samples/*\", \"region/laws\", \"form/style/**\"], region: render10 }, \"figure-refuses\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"notation/renders\", \"view/*\", \"region/vectors\", \"form/style/**\"], region: render11 }, \"figure-world\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"notation/renders\", \"view/*\", \"uses/*\", \"docs/world\", \"examples/*\", \"region/capsule\", \"region/examples\", \"region/source\", \"region/vectors\", \"form/runtime/*/regions\", \"form/style/**\"], region: render12 }, \"first-use\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/first-use/*\", \"prose/*/example/*\", \"examples/*\", \"region/examples\", \"form/runtime/*/run\", \"prose/*/figure/learn/*\", \"form/page/**\"], region: render13 }, \"forms\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reference/*\", \"docs/forms\", \"region/source\"], region: render14 }, \"guide-at-zero\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/guide/*\", \"prose/*/contributing\", \"check\", \"region/laws\", \"form/page/**\"], region: render15 }, \"hero\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/what\", \"prose/*/badge/*\", \"docs/logo\", \"docs/badges\", \"name\", \"notation/renders\", \"sources/*\", \"dependencies\", \"version\", \"license\", \"engines\", \"cites/*\", \"region/cases\", \"region/state\", \"docs/tagline\", \"form/style/**\", \"audit/wire/badges/world\"], region: render16 }, \"how-they-rest\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/rests/*\", \"prose/*/door/*\", \"name\", \"dependencies\", \"uses/*\", \"dep/**\", \"*/name\", \"*/dependencies\"], region: render17 }, \"idea\": { reads: [\"lang\", \"prose/*/idea\", \"prose/*/idea/*\", \"form/page/**\"], region: render18 }, \"install\": { reads: [\"install\", \"name\", \"uses/*\", \"sources/*\", \"host/resolve\", \"form/page/**\"], region: render20 }, \"line\": { reads: [\"sources/*\", \"uses/*\", \"host/resolve\", \"form/page/**\"], region: render19 }, \"learn\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/learn/**\", \"prose/*/cell/*\", \"prose/*/example/*\", \"prose/*/apart\", \"notation/*\", \"view/*\", \"examples/*\", \"region/examples\", \"region/source\", \"region/offers\", \"region/laws\", \"docs/learn\", \"form/runtime/*/run\", \"prose/*/figure/learn/*\", \"form/style/**\", \"form/page/**\"], region: render21 }, \"license\": { reads: [\"license\", \"form/page/**\"], region: render22 }, \"media\": { reads: [\"form/template/**\", \"form/style/**\", \"form/page/**\", \"media/**\"], region: render23 }, \"notation\": { reads: [\"lang\", \"form/prose/**\", \"prose/*/notation/*\", \"prose/*/reference/*\", \"notation/*\", \"region/laws\", \"region/offers\", \"region/source\", \"form/page/**\"], region: render24 }, \"open\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/open/*\", \"samples/*\", \"region/laws\", \"region/state\", \"form/page/**\"], region: render25 }, \"open-conjectures\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/open/*\", \"open/who\", \"samples/*\", \"region/laws\", \"form/page/**\"], region: render26 }, \"operations\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reference/*\", \"region/laws\", \"region/offers\", \"region/source\"], region: render27 }, \"pointers\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/pointers/*\", \"view/*\", \"region/state\", \"form/page/**\"], region: render28 }, \"ranges\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/cell/*\", \"prose/*/apart\", \"notation/claim\", \"notation/renders\", \"notation/object\", \"examples/*\", \"samples/*\", \"region/examples\", \"region/laws\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render29 }, \"reading\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reading/*\", \"region/source\", \"docs/reading\"], region: render30 }, \"reference\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/reference/*\", \"docs/forms\", \"region/laws\", \"region/offers\", \"region/source\"], region: render31 }, \"refuses\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/refuses/*\", \"notation/object\", \"samples/*\", \"region/laws\", \"region/vectors\", \"region/captures\", \"form/page/**\"], region: render32 }, \"regions\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/regions/*\", \"capsule/**\", \"audit/*\", \"region/**\", \"region/capsule\", \"form/page/**\"], region: render33 }, \"rested-on-by\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/rested/*\", \"region/state\", \"form/page/**\"], region: render34 }, \"the-object\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/the-object/*\", \"prose/*/reference/*\", \"prose/*/states/*\", \"notation/*\", \"region/laws\", \"region/offers\", \"region/source\", \"form/style/**\", \"form/page/**\"], region: render35 }, \"the-paper\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/paper\", \"prose/*/the-paper/*\", \"prose/*/cite/*\", \"cites/*\", \"sources/doi\", \"form/page/**\"], region: render36 }, \"units\": { reads: [\"lang\", \"prose/*/reference/*\", \"docs/units\", \"region/source\"], region: render37 }, \"what-holds\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/what-holds/*\", \"prose/*/reference/*\", \"docs/what-holds\", \"docs/measured\", \"samples/*\", \"region/laws\", \"form/page/**\"], region: render38 }, \"wire\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/wire/*\", \"prose/*/wire/*/*\", \"wire/*\", \"region/source\", \"region/vectors\", \"form/page/**\"], region: render39 }, \"say\": { reads: [\"lang\", \"page/**\", \"law/**\", \"docs/tagline\", \"form/page/**\", \"prose/**\"], region: render40 }, \"term\": { reads: [\"lang\", \"page/**\", \"term/**\", \"notation/**\", \"form/page/**\"], region: render41 }, \"count\": { reads: [\"lang\", \"name\", \"dependencies\", \"region/cases\", \"region/state\", \"form/page/**\", \"page/**\", \"prose/*/badge/**\"], region: render42 }, \"seq\": { reads: [\"lang\", \"page/**\", \"examples/*\", \"region/examples\", \"form/page/**\"], region: render43 }, \"exchange\": { reads: [\"lang\", \"page/**\", \"examples/*\", \"region/examples\", \"form/page/**\", \"form/runtime/*/run\", \"prose/*/figure/learn/*\"], region: render44 }, \"set\": { reads: [\"lang\", \"page/**\", \"uses/*\", \"dep/**\", \"region/state\", \"form/page/**\"], region: render45 }, \"cell\": { reads: [\"lang\", \"form/prose/**\", \"form/template/**\", \"prose/*/figure/**\", \"prose/*/cell/*\", \"form/figure/*\", \"notation/renders\", \"view/*\", \"samples/*\", \"region/laws\", \"form/style/**\", \"examples/*\", \"region/examples\", \"region/source\", \"region/vectors\", \"region/capsule\", \"docs/world\", \"uses/*\", \"form/runtime/*/regions\"], region: render46 }, \"ref\": { reads: [\"lang\", \"view/*\", \"form/page/**\"], region: render47 }, \"group\": { reads: [\"lang\", \"page/**\", \"prose/**\", \"form/page/**\"], region: render48 } });\nvar receipt2 = receiptShell({ \"unreceipted\": { reads: [\"lang\", \"prose/*/commands\", \"prose/*/idea\", \"region/state\", \"region/captures\", \"form/page/**\"], region: receipt } });\nexport {\n receipt2 as receipt,\n render49 as render\n};\n", + "providerDigest": "sha256:3c4bb28406ae7f56a8946ead2236a327fdaa29a44d05ae0ccf50af292c1f53ab", + "provenance": { + "artifact": "sha256:04feef01a8c59cae7ea842198d1faf0091b424129872a847b41c7da0bca6fabf", + "member": "dist/index.js", + "fixtureOnly": true, + "license": "MIT", + "licenseText": "MIT License\n\nCopyright (c) 2026 Lapxo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, + "regions": [ + { + "name": "commands", + "reads": "lang|prose/*/commands|region/captures|form/page/**" + }, + { + "name": "hero", + "reads": "lang|form/prose/**|form/template/**|prose/*/what|prose/*/badge/*|docs/logo|docs/badges|name|notation/renders|sources/*|dependencies|version|license|engines|cites/*|region/cases|region/state|docs/tagline|form/style/**|audit/wire/badges/world" + }, + { + "name": "idea", + "reads": "lang|prose/*/idea|prose/*/idea/*|form/page/**" + }, + { + "name": "refuses", + "reads": "lang|form/prose/**|form/template/**|prose/*/refuses/*|notation/object|samples/*|region/laws|region/vectors|region/captures|form/page/**" + }, + { + "name": "what-holds", + "reads": "lang|form/prose/**|form/template/**|prose/*/what-holds/*|prose/*/reference/*|docs/what-holds|docs/measured|samples/*|region/laws|form/page/**" + } + ], + "wire": [ + [ + "fields", + "scope|role|form|measure|value|by|at|epoch|sig|needs|shape|about|kind|restsOn" + ], + [ + "required", + "scope|role|form|measure|value|by|at" + ], + [ + "forms", + "alphabet|interval" + ], + [ + "families", + "keys|signer|wire|sample|tree|write|leaf|view|reader|read|fold|receipts|rendered|resolved|beat|region|prose|uses|dep|name|version|author|repository|license|lang|form|page|term|sources|build" + ], + [ + "roles", + "reads|writes|demands" + ], + [ + "at-classes", + "policy|place|origin|witness|receipt" + ], + [ + "era", + "sample" + ], + [ + "signature-algorithms", + "ed25519:sample" + ], + [ + "digest-algorithms", + "sha256" + ], + [ + "region-measures", + "coordinates|leaves|reads|receipts" + ] + ], + "places": [ + { + "name": "specimen-register", + "version": "1.4.2", + "heading": "Reading specimen-register", + "idea": "Keep independent readings of specimen-register visible.", + "tagline": "A declared place for specimen-register." + }, + { + "name": "route-notes", + "version": "3.2.1", + "heading": "Reading route-notes", + "idea": "Keep independent readings of route-notes visible.", + "tagline": "A declared place for route-notes." + } + ] +} diff --git a/samples/yes/native-views.json b/samples/yes/native-views.json new file mode 100644 index 0000000..1a2e165 --- /dev/null +++ b/samples/yes/native-views.json @@ -0,0 +1,16 @@ +{ + "keyClasses": [ + "authorize", + "read", + "access", + "attest" + ], + "lines": [ + "bound-lock/1 at=policy:evidence by=target form=alphabet measure=class role=writes scope=keys/views-fold value=fold", + "bound-lock/1 at=policy:evidence by=target form=alphabet measure=id role=demands scope=view/help value=help", + "bound-lock/1 at=policy:evidence by=target form=alphabet measure=id role=demands scope=view/lines value=lines", + "bound-lock/1 at=policy:evidence by=target form=alphabet measure=id role=writes scope=wire/receipt-fields value=scope|role|form|measure|value|by|at", + "bound-lock/1 at=policy:evidence by=target form=alphabet measure=id role=demands scope=view/receipts value=receipts@8|receipts@0|receipts@1", + "bound-lock/1 at=policy:evidence by=target form=alphabet measure=id role=demands scope=view/not-provided-by-this-place value=never-offered" + ] +} diff --git a/samples/yes/program-views.json b/samples/yes/program-views.json new file mode 100644 index 0000000..5cd10c1 --- /dev/null +++ b/samples/yes/program-views.json @@ -0,0 +1,66 @@ +{ + "wire": [ + [ + "fields", + "scope|role|form|measure|value|by|at|epoch|sig|needs|shape|about|kind|restsOn" + ], + [ + "required", + "scope|role|form|measure|value|by|at" + ], + [ + "forms", + "alphabet|interval" + ], + [ + "families", + "keys|signer|wire|tree|write|leaf|view|region|uses|dep|tasks|clock|reader|read|fold|receipts|rendered|resolved|beat" + ], + [ + "roles", + "reads|writes|demands" + ], + [ + "at-classes", + "policy|place|origin|witness|receipt" + ], + [ + "era", + "sample" + ], + [ + "signature-algorithms", + "ed25519:sample" + ], + [ + "digest-algorithms", + "sha256" + ], + [ + "kinds", + "capsule" + ], + [ + "region-measures", + "receipts|reads|coordinates" + ] + ], + "providerMember": "dist/views/programs.js", + "providerDigest": "sha256:abe30bfa3bebf8131b10789de963ca3498a313cdbba6055397cbff5869c5cc10", + "places": [ + { + "name": "collection-review", + "steps": [ + "collect", + "catalogue" + ] + }, + { + "name": "transformation-review", + "steps": [ + "prepare", + "transform" + ] + } + ] +} diff --git a/samples/yes/prose-views.json b/samples/yes/prose-views.json new file mode 100644 index 0000000..bd91a64 --- /dev/null +++ b/samples/yes/prose-views.json @@ -0,0 +1,88 @@ +{ + "providerSource": "/** Verbatim prose explicitly assigned to the requested output. The host chooses no format or project vocabulary. */\nexport const render = (asked) => {\n const bodies = [...new Set(asked.lines.filter(line => line.scope?.startsWith('prose/') && line.measure === 'text' && line.shape === asked.shape && line.value !== 'withdraw').map(line => line.about).filter((body) => body !== undefined))];\n if (bodies.length > 1)\n throw Error(`REFUSE\u00b7view conflicting prose names ${asked.shape}`);\n return bodies;\n};\n", + "providerDigest": "sha256:8e322a6ed813609ed6233c5c82812e63eec0480be1eaa46fef62b59cd4c01531", + "wire": [ + [ + "fields", + "scope|role|form|measure|value|by|at|epoch|sig|needs|shape|about|kind|restsOn" + ], + [ + "required", + "scope|role|form|measure|value|by|at" + ], + [ + "forms", + "alphabet|interval" + ], + [ + "families", + "keys|signer|wire|sample|tree|write|leaf|view|reader|read|fold|receipts|rendered|resolved|beat|region|prose|uses|dep" + ], + [ + "roles", + "reads|writes|demands" + ], + [ + "at-classes", + "policy|place|origin|witness|receipt" + ], + [ + "era", + "sample" + ], + [ + "signature-algorithms", + "ed25519:sample" + ], + [ + "digest-algorithms", + "sha256" + ], + [ + "region-measures", + "coordinates|leaves|reads|receipts" + ] + ], + "places": [ + { + "name": "field-notes", + "outputs": [ + { + "view": "usage-profile", + "path": "notes.md", + "body": "# Observations\n\nA field note belongs to its place.\n" + }, + { + "view": "manifest-render", + "path": "manifest.json", + "body": "{\"name\":\"field-notes\"}\n" + }, + { + "view": "release-workflow-render", + "path": "process.yml", + "body": "name: field-work\non: push\n" + } + ] + }, + { + "name": "collection", + "outputs": [ + { + "view": "usage-profile", + "path": "catalogue.md", + "body": "# Collection\n\nAn item keeps its provenance.\n" + }, + { + "view": "manifest-render", + "path": "catalogue.json", + "body": "{\"name\":\"collection\"}\n" + }, + { + "view": "release-workflow-render", + "path": "catalogue.yml", + "body": "name: catalogue\non: push\n" + } + ] + } + ] +} diff --git a/samples/yes/query-views.json b/samples/yes/query-views.json new file mode 100644 index 0000000..7ae83fa --- /dev/null +++ b/samples/yes/query-views.json @@ -0,0 +1,56 @@ +{ + "wire": [ + [ + "fields", + "scope|role|form|measure|value|by|at|epoch|sig|needs" + ], + [ + "required", + "scope|role|form|measure|value|by|at" + ], + [ + "forms", + "alphabet|interval" + ], + [ + "families", + "keys|signer|wire|sample|tree|write|leaf|view|reader|read|fold|receipts|rendered|resolved|beat|region" + ], + [ + "roles", + "reads|writes|demands" + ], + [ + "at-classes", + "policy|place|origin|witness|receipt" + ], + [ + "era", + "sample" + ], + [ + "signature-algorithms", + "ed25519:sample" + ], + [ + "digest-algorithms", + "sha256" + ] + ], + "places": [ + { + "name": "source-review", + "scope": "sample/selection", + "value": "source", + "coordinate": "source.txt", + "content": "Source input\\n" + }, + { + "name": "release-review", + "scope": "sample/package", + "value": "release", + "coordinate": "release.txt", + "content": "Release input\\n" + } + ] +} diff --git a/samples/yes/signing-port.json b/samples/yes/signing-port.json new file mode 100644 index 0000000..1a707d9 --- /dev/null +++ b/samples/yes/signing-port.json @@ -0,0 +1 @@ +{"rows":[{"scope":"sample/a","measure":"id","value":"yes"},{"scope":"sample/b","measure":"id","value":"yes"}]} diff --git a/samples/yes/typed-object.json b/samples/yes/typed-object.json new file mode 100644 index 0000000..f375bf9 --- /dev/null +++ b/samples/yes/typed-object.json @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "scope": "B", + "restsOn": "none" + }, + { + "scope": "C", + "restsOn": "B" + }, + { + "scope": "G", + "restsOn": "C" + }, + { + "scope": "D", + "restsOn": "none" + } + ], + "acts": [ + { + "type": "mark", + "scope": "B", + "id": "s-B", + "sign": "+1", + "pole": "ceiling", + "reach": "travels", + "value": "0..50" + }, + { + "type": "mark", + "scope": "B", + "id": "j-B", + "sign": "+1", + "pole": "ceiling", + "reach": "local", + "widens": "local-opening", + "value": "0..100" + }, + { + "type": "mark", + "scope": "B", + "id": "r-B", + "sign": "+1", + "pole": "floor", + "reach": "travels", + "value": "40..*" + }, + { + "type": "claim", + "scope": "C", + "id": "c-C", + "sign": "+1", + "origin": "ana", + "value": "42..48" + }, + { + "type": "claim", + "scope": "C", + "id": "c-L", + "sign": "+1", + "origin": "luis", + "value": "44..47" + } + ], + "form": "interval", + "measure": "count", + "params": { + "lo": 0, + "hi": 100 + }, + "scenarios": { + "conflicting": "40..43", + "outside": "65..75", + "floorConflict": "60..*" + }, + "place": "range" +} diff --git a/samples/yes/walk.json b/samples/yes/walk.json new file mode 100644 index 0000000..9ca66be --- /dev/null +++ b/samples/yes/walk.json @@ -0,0 +1,100 @@ +{ + "contract": "whole-region@1", + "places": [ + "measurement", + "artifact" + ], + "declarations": [ + [ + "wire/digest-algorithms", + "id", + "sha256" + ], + [ + "wire/signature-algorithms", + "id", + "ed25519:sample" + ], + [ + "wire/era", + "id", + "sample" + ], + [ + "wire/families", + "id", + "keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|view|region|uses|walk|sample" + ], + [ + "wire/fields", + "id", + "scope|role|form|measure|value|by|at|epoch|sig|condition|needs" + ], + [ + "wire/required", + "id", + "scope|role|form|measure|value|by|at" + ], + [ + "wire/forms", + "id", + "alphabet|interval" + ], + [ + "wire/roles", + "id", + "reads|writes|demands" + ], + [ + "wire/at-classes", + "id", + "origin|place|receipt|witness|policy" + ], + [ + "wire/walk/contract", + "id", + "whole-region@1" + ], + [ + "wire/walk/fields", + "id", + "scope|role|form|measure|value|by|at|epoch|condition|needs" + ], + [ + "wire/walk/metadata-fields", + "id", + "at|by|condition|epoch|form|measure|role|scope|sig|value" + ], + [ + "wire/walk/resolutions", + "id", + "0|1|4|6|8" + ], + [ + "signer/timeout", + "milliseconds", + "5000..5000", + "interval" + ], + [ + "signer/response-bytes", + "bytes", + "65536..65536", + "interval" + ], + [ + "wire/walk/projections", + "id", + "0:inventory|1:summary|4:summary|6:history|8:history" + ] + ], + "requirements": [ + "@0/@1/@8 escalation", + "authenticated whole-region prefixes", + "two clocks", + "union retains both origins", + "unchanged exchange zero payload", + "atomic native receipt", + "replay zero writes" + ] +} diff --git a/src/cli/accept.ts b/src/cli/accept.ts index 1f0f010..f4a6ffb 100644 --- a/src/cli/accept.ts +++ b/src/cli/accept.ts @@ -11,7 +11,7 @@ import { fieldOf, isConfig, foldClaims, sayingOf, selfName } from '../fold/claim import { isReaderLock } from '../fold/observed.ts'; import { authorityFor, publicKeyOf, rootSigner, writerFor } from '../fold/signers.ts'; import { lockLines, lockStanding } from '../fold/keys.ts'; -import { keepVerdict, keptVerdict, land, landBlob, storeOf } from '../land/ledger.ts'; +import { keepVerdict, keptVerdict, land, landBlob, ledgerLines, storeOf } from '../land/ledger.ts'; import { signConsentLot, verifiesOwnerLine } from '../land/sign.ts'; import { signerFor } from '../host/signing.ts'; import { appliedIn, ownLockOf } from '../fold/signed.ts'; @@ -19,7 +19,7 @@ import { wordOf } from '../fold/wire.ts'; import { hasVouchedTree, landCoordinates, locationsOf, vouchedCoordinates } from '../land/vouched.ts'; import { entriesIn, observeFile, observeText } from '../observe/files.ts'; import { coneOf, standingOf } from './place.ts'; -import { ownLock, ownRoot, ownStore } from '../observe/runner.ts'; +import { ownLock, ownRoot } from '../observe/runner.ts'; import { widenedWithoutWitness } from '../judge/widening.ts'; import { retractedTogether, withdrawal } from '../land/withdraw.ts'; import { isCeiling } from '../fold/configures.ts'; @@ -37,7 +37,7 @@ import { lateFacts } from '../judge/late.ts'; import { paidOf } from '../fold/paid.ts'; import { aliasPinned } from '../land/alias.ts'; import { coordinatesWithdrawn } from '../land/leaving.ts'; -import { ownerOf, epochOf, forksItself, forksJoinedBy, renderInto, sideOf, signedDemands, signedOwnerLines } from './owner.ts'; +import { ownerOf, epochOf, localActLines, forksItself, forksJoinedBy, renderInto, sideOf, signedDemands, signedOwnerLines } from './owner.ts'; import { claimLinesIn, entryOf, namedPlaces, placesOfFile, positionalsOf, valueOf } from './args.ts'; import { FLAGS } from './names.ts'; import { judgeDemand, landTake } from './takes.ts'; @@ -56,7 +56,15 @@ function admissionEvidence(root: string, signed: readonly string[], standing: re const coordinates = coordinatesWithdrawn(root, store, signed, [...signed, ...standing]); if (coordinates.refused.length) throw Error(`REFUSE·withdraw a file is still read: ${coordinates.refused.map(one => `${one.path} by ${one.by}`).join(' · ')}`); const view = `${wordOf(standing, 'families', 'view')}/`; - const judged = signed.filter(one => isConfig(one) && fieldOf(one, 'role') === 'demands' && fieldOf(one, 'value') !== 'withdraw' && !fieldOf(one, 'scope').startsWith(view)).map(one => judgeDemand(root, one)); + const judged: Judged[] = signed.filter(one => isConfig(one) && fieldOf(one, 'role') === 'demands' && fieldOf(one, 'value') !== 'withdraw' && !fieldOf(one, 'scope').startsWith(view)).map(one => { + const scope = fieldOf(one, 'scope'); + const alreadyDemanded = standing.some(held => isConfig(held) && fieldOf(held, 'role') === 'demands' + && fieldOf(held, 'value') !== 'withdraw' && fieldOf(held, 'scope') === scope + && fieldOf(held, 'form') === fieldOf(one, 'form') && fieldOf(held, 'measure') === fieldOf(one, 'measure')); + // Declaring an obligation is not a claim to have discharged it. + return alreadyDemanded ? judgeDemand(root, one) + : {kind: 'owed', scope, why: 'new demand declared; no conformance reading is claimed'}; + }); const refused = judged.filter(one => one.kind === 'refused' || (one.kind === 'judged' && one.verdict.kind === 'refuse')); if (refused.length) throw Error(`REFUSE·takes ${refused.map(one => `${one.scope}: ${one.kind === 'judged' ? one.verdict.why : one.kind === 'refused' ? one.why : ''}`).join(' · ')}`); return { coordinates, judged, fold }; @@ -125,7 +133,7 @@ export async function signedBatch(root: string, args: readonly string[], files: process.stderr.write(`${selfName()}: REFUSE·place nothing landed · ${stray.join(', ')} is no place of the tree, and no line of the root founds it: --place names the own lock a line lands in\n`); return {kind:'exit',code:2}; } - const epoch = epochOf([...lockLines(store), ...destinations.flatMap((place) => appliedIn(root, place))]) + 1; + const epoch = epochOf(localActLines(root,destinations)) + 1; const stale = proposed.filter((line) => fieldOf(line, 'sig')).flatMap((line) => ((by, key) => (key === undefined || !verifiesOwnerLine(line, key, signaturesOf(store).admitted) ? [`${fieldOf(line, 'scope')} · the signature does not hold for ${by || '∅'}`] : []))(fieldOf(line, 'by'), publicKeyOf(root, fieldOf(line, 'by')))); @@ -137,9 +145,13 @@ export async function signedBatch(root: string, args: readonly string[], files: const [named, places] = [namedPlaces(args), placesIn(root)]; const inLock = new Set(lockLines(store).map(sayingOf)); const inPlace = new Map(places.map((place) => [place, new Set(appliedIn(root, place).map(sayingOf))] as const)); + const deliveryAuthority = authorityFor(lockLines(store), rootSigner(root), signaturesOf(store).admitted); + const delivered = (line: string): boolean => Boolean(fieldOf(line, 'sig')) + && deliveryAuthority.of(line).kind === 'admitted' + && ledgerLines(store, fieldOf(line, 'by')).includes(line); const held = (line: string, at = named.length ? named : byFile.flatMap(([heads, lines]) => (lines.includes(line) ? heads : []))): boolean => at.length ? at.every((place) => inPlace.get(place)?.has(sayingOf(line))) - : inLock.has(sayingOf(line)) || places.some((place) => inPlace.get(place)?.has(sayingOf(line))); + : delivered(line) || inLock.has(sayingOf(line)) || places.some((place) => inPlace.get(place)?.has(sayingOf(line))); if (proposed.every((line) => held(line))) { if(proposed.some(line=>!isConfig(line))) {try {await admittedObjects(root,[...signedOwnerLines(store),...proposed]);}catch(e){process.stderr.write(`${selfName()}: ${String(e)} · nothing landed\n`);return {kind:'exit',code:1};}} return { kind: 'once', proposed }; @@ -293,7 +305,7 @@ async function acceptNow(root: string, batch: Extract standingOf(root, undefined, signed)); for (const name of openedBy(descent, told.standing, signed)) process.stderr.write(`OPEN ${name}\n`); - if (owned.own.size) layReleases(store, ownRoot(), ownLock(), ownStore()); + if (owned.own.size) layReleases(store, root, told.standing, store); const landed = took('land', () => [...new Set(signed.map((line) => fieldOf(line, 'by')))].map((by) => land(store, by, signed.filter((line) => fieldOf(line, 'by') === by)))); for (const [place, lines] of owned.own) landOwned(root, place, lines); landSaid(store, writerFor(told.standing, 'fold'), []); @@ -340,7 +352,7 @@ async function acceptNow(root: string, batch: Extract `${one.appended} in ${one.at}`).join(' · ') : '0'}${[...owned.own].map(([place, lines]) => ` · ${lines.length} in ${place}/${LOCK}`).join('')} · epoch ${epoch}\n` - + `TARGET ${rendered.standing} claims · ${rendered.forks.length} forks · ${rendered.vacuous.length} vacuous · ${rendered.grey.length} grey · ${rendered.refused.length} refused · ${Date.now() - started} ms\n` + + `TARGET ${rendered.standing} claims · ${rendered.forks.length} forks · ${rendered.vacuous.length} vacuous · ${rendered.grey.length} grey · ${rendered.refused.length} refused · readings · no encounters computed · ${Date.now() - started} ms\n` + `SPENT ${spent.join(' ms · ')} ms · ${signed.length} lines\n`, ); if (withdrawn) { @@ -388,7 +400,7 @@ function repaid(root: string, proposed: readonly string[], started: number): num } const rendered = renderInto(root, store); process.stdout.write(`RENDER 0\n`); - process.stdout.write(`TARGET ${rendered.standing} claims · ${rendered.forks.length} forks · ${rendered.vacuous.length} vacuous · ${rendered.grey.length} grey · ${rendered.refused.length} refused · ${Date.now() - started} ms\n`); + process.stdout.write(`TARGET ${rendered.standing} claims · ${rendered.forks.length} forks · ${rendered.vacuous.length} vacuous · ${rendered.grey.length} grey · ${rendered.refused.length} refused · readings · no encounters computed · ${Date.now() - started} ms\n`); return 0; } diff --git a/src/cli/owner.ts b/src/cli/owner.ts index e416c49..7129543 100644 --- a/src/cli/owner.ts +++ b/src/cli/owner.ts @@ -1,8 +1,10 @@ +import {fileURLToPath} from 'node:url'; +import {ingressReceipts} from '../host/ports/ingress.ts'; import {readOnly} from '../host/read-only.ts'; import { keyFor, lockLines, releaseOf, signedLockLines } from '../fold/keys.ts'; import { existsSync, renameSync, writeFileSync } from 'node:fs'; import { join, resolve } from 'node:path'; -import { bytesDigest, fullDigest, memoized, signaturesOf } from '../fold/digests.ts'; +import { bytesDigest, fullDigest, memoized, signaturesOf, instrumentDigest } from '../fold/digests.ts'; import { claimKey, isConfig, fieldOf, foldClaims, LOCK, selfName } from '../fold/claims.ts'; import { asksThePlace } from '../fold/configures.ts'; import { receiptsIn } from '../fold/receipts.ts'; @@ -10,6 +12,7 @@ import { authorityFor, releaseSigner, rootSigner } from '../fold/signers.ts'; import { storeRoot } from '../host/ports/store.ts'; import { blobAt, landBlob, ledgerLines, storeOf } from '../land/ledger.ts'; import { observeText } from '../observe/files.ts'; +import {appliedIn} from '../fold/signed.ts'; import { everLanded, inside, locationsOf } from '../land/vouched.ts'; import { renderTarget } from '../render/target.ts'; @@ -55,6 +58,18 @@ export function forkedScopes(store: string): Set { return new Set(foldClaims(lines, forkReceipts(store, lines)).forks.flatMap((f) => f.lines.map((line) => fieldOf(line, 'scope')))); } +/** Import receipts are local acts; foreign evidence and sender epochs never enter this input. */ +export function localActLines(root: string, placed: readonly string[] = []): readonly string[] { + const store=storeOf(root),local=lockLines(store),receipts=ingressReceipts(store); + if(receipts.length){ + const authority=authorityFor(local,rootSigner(root),signaturesOf(store).admitted); + for(const receipt of receipts){ + if(fieldOf(receipt,'scope')!=='receipts'||fieldOf(receipt,'role')!=='writes'||fieldOf(receipt,'form')!=='alphabet'||fieldOf(receipt,'measure')!=='digest'||authority.of(receipt).kind!=='admitted')throw Error('REFUSE·ingress local import receipt is not admitted'); + } + } + return [...local,...receipts,...placed.flatMap(place=>appliedIn(root,place))]; +} + export function epochOf(lines: readonly string[]): number { return lines.reduce((top, line) => Math.max(top, Number(fieldOf(line, 'epoch')) || 0), 0); } @@ -108,7 +123,7 @@ export function renderedLock(root: string, store: string, told: readonly string[ } const anchor = [join(storeRoot(root), `${selfName()}.keys`), join(storeOf(root), `${selfName()}.keys`)].map((at) => observeText(at) ?? '').join('\n'); const judged = ledgerLines(store, 'judge'); - const key = `lock ${fullDigest(store, [new Date().toISOString().slice(0, 10), anchor, `${judged.length} ${judged.at(-1) ?? ''}`, ...owned])}`; + const key = `lock ${fullDigest(store, [instrumentDigest(store, fileURLToPath(import.meta.url), [], root), new Date().toISOString().slice(0, 10), anchor, `${judged.length} ${judged.at(-1) ?? ''}`, ...owned])}`; const held = memoized(store, key, () => { const bytes = new TextEncoder().encode(JSON.stringify(render())); const digest = bytesDigest(store, bytes); diff --git a/src/cli/pass.ts b/src/cli/pass.ts index c2869d6..c4df136 100644 --- a/src/cli/pass.ts +++ b/src/cli/pass.ts @@ -7,9 +7,9 @@ import type { PlaceFold } from './place.ts'; import { fieldOf, selfName } from '../fold/claims.ts'; import { observedClaims } from '../fold/observed.ts'; import { layReleases, resolvedOf } from '../host/release.ts'; -import { ownLock, ownRoot, ownStore, processOf } from '../observe/runner.ts'; +import { ownLock, ownRoot, processOf } from '../observe/runner.ts'; import { landLaid } from '../fold/laid.ts'; -import { actSeconds, idleCount, instrumentKeep, instrumentKept, meets, noteIdle, receiptPlaces, receiptsSeen } from '../fold/closed.ts'; +import { actSeconds, closeReceipts, idleCount, instrumentKeep, instrumentKept, meets, noteIdle, receiptPlaces, receiptsSeen } from '../fold/closed.ts'; import { algorithmCost, instrumentOf, instrumentDigest } from '../fold/digests.ts'; import { writerFor } from '../fold/signers.ts'; import { defaulted, placesOf, viewsOf } from '../fold/views.ts'; @@ -26,6 +26,7 @@ import { releasePolicyLines } from '../fold/release-policy.ts'; import { carriedFrom } from '../fold/resolved.ts'; import { wireLine } from '../fold/wire.ts'; import { isWire, RECEIPTS } from '../fold/claims.ts'; +import {withoutEffects} from '../host/read-only.ts'; /** * The pass of a place, in one process: the releases its instrument names are laid out first, its readers observe @@ -76,7 +77,7 @@ async function checked(root: string, entry: string, under: string | undefined): export async function pass(root: string, entry: string, under: string | undefined, check: boolean): Promise { if (check) { // Verification reads existing evidence; it grants no admission authority. - return emptyLedger(storeOf(root)) ? checked(root, entry, under) : underTheLock(storeOf(root), 'check', () => checked(root, entry, under)); + return withoutEffects(() => emptyLedger(storeOf(root)) ? checked(root, entry, under) : underTheLock(storeOf(root), 'check', () => checked(root, entry, under))); } if (!under && emptyLedger(storeOf(root))) { sayStranger(root); @@ -86,8 +87,10 @@ export async function pass(root: string, entry: string, under: string | undefine const run = async (): Promise => { const swept = await sweep(root, entry, under, check, []); for (const coordinate of check ? swept.written : []) process.stdout.write(`DIFFERS ${coordinate}\n`); + // Byte seals describe the completed render pass, not its intermediate outputs. + if (!swept.written.length) await closeReceipts(root, storeOf(root)); const closed = meets(root, storeOf(root), under ?? '') && !swept.written.length; - const fold = foldPlace(root, entry, under, false, { standing: swept.standingAt.get(under ?? '') ?? standingOf(root, under), observed: swept.observed.length ? swept.observed : observedClaims(root, storeOf(root), { wait: false }), free: true }); + const fold = foldPlace(root, entry, under, false, { standing: swept.standingAt.get(under ?? '') ?? standingOf(root, under), observed: swept.settled ? [] : swept.observed.length ? swept.observed : observedClaims(root, storeOf(root), { wait: false }), free: !swept.settled }); for (const line of releasePolicyLines(fold.release)) process.stdout.write(`${line}\n`); if (closed) { instrumentKeep(storeOf(root), instrumentOf(storeOf(root), entry, standingOf(root).standing, root, ownLock())); @@ -119,6 +122,7 @@ async function sweep(root: string, entry: string, under: string | undefined, che readonly standingAt: ReadonlyMap>; readonly folds: ReadonlyMap; readonly said: readonly string[]; + readonly settled: boolean; }> { const store = storeOf(root); const digestAt = Date.now(); @@ -147,14 +151,15 @@ async function sweep(root: string, entry: string, under: string | undefined, che else process.stderr.write(`CLOSED ${under} · lock ${lock} ms · hash ${hash} ms\n`); const seconds = actSeconds(); process.stderr.write(`COST act ${seconds} s\n`); - return { same: 0, written: [], places: under === undefined ? read.count : 1, observed: [], standingAt: new Map(), folds: new Map(), said: [] }; + return { same: 0, written: [], places: under === undefined ? read.count : 1, observed: [], standingAt: new Map(), folds: new Map(), said: [], settled: true }; } - layReleases(store, ownRoot(), ownLock(), ownStore()); + const lock = standingOf(root, undefined, told); + // A place asks for its own mounts; the instrument catalog is not a consumer dependency. + layReleases(store, root, lock.standing, store); const descent = reach ?? (under ? [under.replace(/\/$/, '')] : undefined); const limited = descent !== undefined; const observed = given ?? observedClaims(root, store, { wait: true, ...(descent !== undefined ? { reach: descent } : {}) }); - const lock = standingOf(root, undefined, told); - landLaid(store, ownRoot(), ownLock(), writerFor(lock.standing, 'fold')); + landLaid(store, root, lock.standing, writerFor(lock.standing, 'fold')); const shaped = (standing: readonly string[]): readonly View[] => [...viewsOf(standing).values()].flatMap((view) => ('regions' in view && view.shape ? [view] : [])); const views = shaped(lock.standing); const tree = viewsOf(lock.lock); @@ -257,8 +262,8 @@ async function sweep(root: string, entry: string, under: string | undefined, che } } const said = [...answered.values()].flat(); - if (!check && journal === undefined) landSaid(store, writerFor(lock.standing, 'fold'), [...resolvedOf(store, ownRoot(), ownLock(), ownStore()), ...said]); - return { same, written, places: places.length + (under ? 0 : 1), observed, standingAt, folds, said: journal === undefined ? [] : said }; + if (!check && journal === undefined) landSaid(store, writerFor(lock.standing, 'fold'), [...resolvedOf(store, root, lock.standing, store), ...said]); + return { same, written, places: places.length + (under ? 0 : 1), observed, standingAt, folds, said: journal === undefined ? [] : said, settled: false }; } type Drawn = { readonly shape: string; readonly missing: readonly string[]; readonly text: string; readonly said: readonly string[] }; diff --git a/src/cli/place.ts b/src/cli/place.ts index e259fe3..565e275 100644 --- a/src/cli/place.ts +++ b/src/cli/place.ts @@ -10,7 +10,7 @@ import { observeText } from '../observe/files.ts'; import { placesOf, viewsOf } from '../fold/views.ts'; import type { View } from '../fold/views.ts'; import { prerender, viewOf } from '../render/view.ts'; -import { meets } from '../fold/closed.ts'; +import { meets, instrumentKept } from '../fold/closed.ts'; import { foldPoints, keepFold, keptPlace } from '../fold/kept.ts'; import { openCells } from '../render/open.ts'; import { boundOf, packRegions, regionsNamed, regionsOf, unlikeReplay } from '../fold/region.ts'; @@ -221,6 +221,12 @@ function inheritedOf(root: string, standing: readonly string[]): readonly string export function coneOf(root: string, entry: string, ceilings: readonly string[], descent?: readonly string[]): { readonly standing: readonly string[]; readonly observed: readonly string[]; readonly own: Readonly>; readonly kept: boolean } { const store = storeOf(root); const { standing, rendered } = standingOf(root); + // Admission consumes the verified completed fold; it does not ask providers again. + // Receipt bytes, reader history and instrument identity must all still agree. + if (meets(root, store, '') && instrumentKept(store) === instrumentOf(store, entry, standing, root, ownLock())) { + const held = keptPlace(store); + if (held !== undefined) return { standing, observed: held.observed, own: held.own, kept: true }; + } const named = regionsNamed(standing); const reach = descent !== undefined && descent.length ? [...descent] : [...new Set(ceilings.map((line) => boundOf(named, line).region))]; const read = observedClaims(root, store, { wait: false, ...(reach.includes('') ? {} : { reach }) }); diff --git a/src/cli/verb.ts b/src/cli/verb.ts index f2e6c0d..e04286d 100644 --- a/src/cli/verb.ts +++ b/src/cli/verb.ts @@ -45,6 +45,9 @@ import { claimLinesIn, entryOf, namedPlaces, positionalsOf, valueOf } from './ar import { EXIT, FLAGS, NAMED_VIEWS, helpLines } from './names.ts'; import type { VerbName } from './names.ts'; import { accept, signedBatch } from './accept.ts'; +import {renderWalk,landWalk,foreignWalkLines} from '../host/walk.ts'; +import {isWalkHeader} from '@lapxo/topos/walk'; +import {ingressBundles,ingressReceipts} from '../host/ports/ingress.ts'; /** The first land of a lock: TARGET.bound into an empty owner ledger, then the sources that lock names. */ async function firstLand(root: string, args: readonly string[]): Promise { @@ -176,6 +179,15 @@ async function view(root: string, under: string | undefined, asked: string, told process.stderr.write(`${selfName()}: the owner ledger is empty; land it before rendering a view\n`); return EXIT.refuse; } + if(name==='evidence'&&!under&&!told.length&&ingressBundles(storeOf(root)).length){ + const declared=viewsOf(lockStanding(storeOf(root))).get(name); + if(!declared||declared.shape||!declared.regions.some(region=>region.name==='evidence'))throw Error('REFUSE·view foreign evidence requires a declared evidence view'); + const received=await foreignWalkLines(root),authority=authorityFor(lockLines(storeOf(root)),rootSigner(root),signaturesOf(storeOf(root)).admitted); + const local=[...new Set(authority.admitted.flatMap(key=>ledgerLines(storeOf(root),key.id)))].filter(line=>authority.of(line).kind==='admitted'); + for(const line of [...new Set([...local,...ingressReceipts(storeOf(root)),...received])])process.stdout.write(line+'\n'); + process.stdout.write('FACT authenticated histories · readings · no encounters computed\n'); + return EXIT.closed; + } const at = Date.now(); const place = under?.replace(/\/$/, ''); const released = releaseOf(storeOf(root)); @@ -341,6 +353,11 @@ async function landVerb(root: string, rest: readonly string[]): Promise process.once('uncaughtException', (error) => die(error instanceof Error ? error.message : String(error))); process.once('unhandledRejection', (error) => die(error instanceof Error ? error.message : String(error))); try { + const proposed=batch.flatMap(claimLinesIn); + if(proposed.some(isWalkHeader)){ + for(const line of await landWalk(root,proposed,valueOf(rest,FLAGS.key),valueOf(rest,FLAGS.keyFile),valueOf(rest,FLAGS.signer)))process.stdout.write(line+'\n'); + return EXIT.closed; + } return await accept(root, rest); } catch (error) { const message = error instanceof Error ? error.message : String(error); @@ -365,7 +382,7 @@ function foldFile(at: string): number { } for (const line of folded.standing) process.stdout.write(`${line}\n`); for (const fork of folded.forks) process.stdout.write(`FORK ${fork.key}${fork.state ? ` · ${fork.state}` : ''}\n`); - process.stdout.write(`FACT ${folded.standing.length} standing · ${folded.forks.length} forks · ${basename(at)}\n`); + process.stdout.write(`FACT ${folded.standing.length} standing · ${folded.forks.length} forks · ${basename(at)} · readings · no encounters computed\n`); return EXIT.closed; } @@ -402,6 +419,15 @@ async function foldResolved(root: string, under: string | undefined, argv: reado // A named view does not request mounting every release of the instrument. const receiptCheck = as === undefined && argv.includes(FLAGS.check); + if(as?.split('@')[0]==='walk'){ + if(argv.includes(FLAGS.check))throw Error('REFUSE·walk check does not initiate or sign an exchange'); + if(under||inputs.length>1)throw Error('REFUSE·walk one place and one authenticated peer inventory per fold'); + const depth=as.split('@')[1];if(depth!==undefined&&(!/^(0|[1-9][0-9]*)$/.test(depth)||!Number.isSafeInteger(Number(depth))))throw Error('REFUSE·walk invalid resolution'); + const peer=inputs.length?claimLinesIn(inputs[0]!):[]; + for(const line of await renderWalk(root,depth===undefined?undefined:Number(depth),peer,valueOf(argv,FLAGS.key),valueOf(argv,FLAGS.keyFile),valueOf(argv,FLAGS.signer)))process.stdout.write(line+'\n'); + return EXIT.closed; + } + if(as===OBJECT_VIEW){const inputs=positionalsOf(argv).filter(one=>existsSync(resolve(one))&&!lstatSync(resolve(one)).isDirectory());if(inputs.length>1)throw Error('REFUSE·object one history snapshot per fold');const history=inputs.length?claimLinesIn(inputs[0]!):signedOwnerLines(storeOf(root));const held=await admittedObjects(root,history,text=>process.stdout.write(text+'\n'));const cells=objectFold(held.records,held.context);for(const c of cells)process.stdout.write('CELL '+JSON.stringify(c)+'\n');process.stdout.write(`FACT object fold ${cells.length} cells\n`);return EXIT.closed;} const key = valueOf(argv, FLAGS.key); if (as === undefined) { diff --git a/src/fold/claims.ts b/src/fold/claims.ts index c7224b0..231492b 100644 --- a/src/fold/claims.ts +++ b/src/fold/claims.ts @@ -46,7 +46,10 @@ function regionsOf(line: string): readonly Region[] { function contracted(line: string, sides: readonly string[], receipts: readonly { readonly scope: string; readonly moved: readonly string[] }[]): boolean { const scope = fieldsOf(line)['scope'] ?? ''; - const mine = exclusive(regionsOf(line), sides.filter((other) => other !== line).map(regionsOf)); + const named = regionsOf(line); + // File receipts can discharge only declared file regions. No region is not an empty proof. + if (named.length === 0) return false; + const mine = exclusive(named, sides.filter((other) => other !== line).map(regionsOf)); const touched = receipts.filter((r) => r.scope === scope).flatMap((r) => r.moved.map((coordinate) => point(coordinate))); return contracts(mine, touched); } diff --git a/src/fold/closed.ts b/src/fold/closed.ts index 5a9d729..8f73bba 100644 --- a/src/fold/closed.ts +++ b/src/fold/closed.ts @@ -1,6 +1,8 @@ +import {actCosts} from '../host/act-cost.ts'; +import {verifiedReadingReceipts} from '../host/reading-closures.ts'; import { dirname, existsSync, join, mkdirSync, relative, resolve, statSync, writeFileSync } from '../host/io.ts'; -import { canonical, LOCK, parse, roleAt, roleClaimsOf } from '@lapxo/topos/wire'; -import { RECEIPTS, fieldOf, isWire } from './claims.ts'; +import { byBytes, canonical, LOCK, parse, publicationOf, roleAt, roleClaimsOf } from '@lapxo/topos/wire'; +import { RECEIPTS, fieldOf, foldClaims, isConfig, isWire } from './claims.ts'; import { bytesDigest as hashBytes, fullDigest as hashFull } from '../host/digest.ts'; import { worldAt } from './places.ts'; import { ownLockOf } from './signed.ts'; @@ -10,9 +12,8 @@ import { coordinatesUnder, observeFile, observeText } from '../observe/files.ts' import { carriedFrom } from './resolved.ts'; import { takenFor } from '../fold/place-inputs.ts'; -/** A region is closed when the digest of its bytes is the one its receipt names. Folding a closed region is idle: idleCount is how many were already closed, actSeconds how long this act has run, receiptsSeen how many receipts were read and how long that took. */ +/** A region is closed when the digest of its bytes is the one its receipt names. Folding a closed region is idle: idleCount is how many were already closed, actSeconds the largest measured act or unpartitioned host work, receiptsSeen how many receipts were read and how long that took. */ let idle = 0; -const began = Date.now(); let seen = { count: 0, ms: 0 }; export const idleCount = (): number => idle; @@ -21,7 +22,7 @@ export const noteIdle = (): void => { idle += 1; }; -export const actSeconds = (): number => Math.max(0, Math.round((Date.now() - began) / 1000)); +export const actSeconds = (): number => actCosts.seconds(); export const receiptsSeen = (): { readonly count: number; readonly ms: number } => seen; @@ -62,13 +63,20 @@ function filesOf(root: string, place: string, region: string, inputs: readonly s const rooted = new Map(); +function publicConfiguration(lines: readonly string[]): readonly string[] { + if (!lines.length || !lines.every(isConfig)) return lines; + const folded = foldClaims(lines); + if (folded.forks.length) throw Error('REFUSE·receipt disputed configuration standing'); + return publicationOf(folded.standing.filter(line => fieldOf(line, 'value') !== 'withdraw')); +} + function rootLines(root: string, place: string): readonly string[] { const name = place.replace(/\/$/, ''); if (!name) return []; const key = `${root}\0${name}\0${lockStamp(root, '')}`; const held = rooted.get(key); if (held !== undefined) return held; - const standing = (observeText(join(root, LOCK)) ?? '').split('\n').filter(isWire); + const standing = publicConfiguration((observeText(join(root, LOCK)) ?? '').split('\n').filter(isWire)); // Authority validates admission separately; it is not a rendered file input. const lines = standing.filter((line) => fieldOf(line, 'value') !== 'withdraw' && !fieldOf(line, 'scope').startsWith('keys/')); const take = takenFor(lines, `${name}/`, worldAt(root, name) ? { own: ownLockOf(root, name), tree: viewsOf(standing) } : undefined); @@ -79,8 +87,18 @@ function rootLines(root: string, place: string): readonly string[] { /** File-fold identity uses public inputs; admission history stays in its separate ledger guard. */ export function fileRegionDigest(root: string, place: string, region: string, algorithm: string, inputs: readonly string[] = []): string { - const files = filesOf(root, place, region, inputs); - return hashFull([...files.map((rel) => `${relative(join(root, place), join(root, rel))} ${hashBytes(observeFile(join(root, rel)) ?? new Uint8Array(), algorithm)}`), ...rootLines(root, place)], algorithm); + const files = [...filesOf(root, place, region, inputs)].sort(byBytes); + const own = join(root, place, LOCK); + const bytesOf = (rel: string): Uint8Array => { + const at = join(root, rel), bytes = observeFile(at) ?? new Uint8Array(); + if (resolve(at) !== resolve(own)) return bytes; + const lines = new TextDecoder().decode(bytes).split('\n').filter(isWire); + // Object history keeps its own contract. Configuration's public identity is + // the existing Topos publication projection, not its admission envelopes. + if (!lines.length || !lines.every(isConfig)) return bytes; + return new TextEncoder().encode(publicConfiguration(lines).join('\n') + '\n'); + }; + return hashFull([...files.map((rel) => `${relative(join(root, place), join(root, rel))} ${hashBytes(bytesOf(rel), algorithm)}`), ...rootLines(root, place)], algorithm); } function namedReceipts(root: string, store: string): ReadonlyMap { @@ -95,14 +113,17 @@ function namedReceipts(root: string, store: string): ReadonlyMap return out; } +// Only the instrument's file seals describe file-region bytes. Reader receipts keep their own semantic identity. +const fileSeal = (line:string):boolean => isWire(line) && fieldOf(line,'measure') === 'bytes' && fieldOf(line,'by') === 'bound'; + function ownBytes(root: string): readonly string[] { - return (observeText(join(root, RECEIPTS)) ?? '').split('\n').filter(line => isWire(line) && fieldOf(line, 'measure') === 'bytes'); + return (observeText(join(root, RECEIPTS)) ?? '').split('\n').filter(fileSeal); } function bytesMeet(root: string, place: string): boolean { const shipped = (observeText(join(root, place, RECEIPTS)) ?? '').split('\n').filter(isWire); const inputs = carriedFrom(storeOf(root), shipped) ?? []; - const lines = shipped.filter(line => fieldOf(line, 'measure') === 'bytes'); + const lines = shipped.filter(fileSeal); const algorithm = algorithmIn(lines.join('\n')); return lines.length > 0 && algorithm !== '' && lines.map((line) => fieldOf(line, 'value')).join('\n') === lines.map((line) => fileRegionDigest(root, place, fieldOf(line, 'scope'), algorithm, inputs)).join('\n'); } @@ -126,8 +147,8 @@ function rewritePlace(root: string, place: string): void { const text = observeText(at) ?? ''; const algorithm = algorithmIn(text); if (algorithm === '') return; - const kept = text.split('\n').filter((line) => line === '' || !isWire(line) || fieldOf(line, 'measure') !== 'bytes'); - const regions = kept.filter((line) => isWire(line) && fieldOf(line, 'measure') === 'count' && fieldOf(line, 'scope').startsWith('receipts/')); + const kept = text.split('\n').filter((line) => line === '' || !fileSeal(line)); + const regions = kept.filter((line) => isWire(line) && fieldOf(line, 'measure') === 'count' && fieldOf(line,'by') === 'bound' && fieldOf(line, 'scope').startsWith('receipts/')); const bytes = regions.map((line) => { const scope = fieldOf(line, 'scope'); const inputs = carriedFrom(storeOf(root), kept.filter(isWire)) ?? []; @@ -159,11 +180,12 @@ export function meets(root: string, store: string, place: string): boolean { const own = ownBytes(root); const carried = own.length ? carriedFrom(store, (observeText(join(root, RECEIPTS)) ?? '').split('\n').filter(isWire)) : undefined; const ownClosed = own.length > 0 && carried !== undefined && carried.length > 0 && bytesMeet(root, ''); - const closed = (own.length > 0 ? ownClosed : named.size > 0) && [...named].every(([one, expected]) => { + let closed = (own.length > 0 ? ownClosed : named.size > 0) && [...named].every(([one, expected]) => { const bytes = observeFile(join(root, one, RECEIPTS)); const algorithm = expected.split(':')[0]; return bytes !== undefined && hashBytes(bytes, algorithm) === expected && meets(root, store, `${one}/`); }); + if(closed && carried){const algorithm=algorithmIn(own.join('\n'));const readings=verifiedReadingReceipts(store,carried,text=>hashFull(text,algorithm));if(readings===undefined)closed=false;else if(readings)process.stderr.write(`RECEIPTS ${readings} read · 0 opened · reading closures\n`);} seen = { count: named.size + (own.length > 0 ? 1 : 0), ms: Date.now() - at }; return closed; } diff --git a/src/fold/digests.ts b/src/fold/digests.ts index 3f2213d..1da15b3 100644 --- a/src/fold/digests.ts +++ b/src/fold/digests.ts @@ -7,6 +7,7 @@ import { EXTENSION, fieldOf, foldClaims, selfName } from './claims.ts'; import { wireLine } from './wire.ts'; import { publicLock, LOCK } from '@lapxo/topos/wire'; import {builtinModules,createRequire} from 'node:module'; +import {moduleImports} from '../host/adapters/modules/javascript.ts'; const held = new Map(); let algorithmMs = 0; @@ -106,6 +107,7 @@ const memoOf = (store: string): Map => stamped.get(store) ?? sta export function coordinateDigest(store: string, at: string): string | undefined { const stamp = stampOf(at); if (stamp?.kind !== 'file') return stamp === undefined ? undefined : bytesDigest(store, observeFile(at) ?? new Uint8Array()); + if (readOnly()) return bytesDigest(store, observeFile(at) ?? new Uint8Array()); const key = `${at} ${stamp.stamp}`; const memo = memoOf(store); const held = memo.get(key); @@ -134,9 +136,9 @@ const imported = new Map(); const importsOf = (store: string, at: string, digest: string): readonly string[] => { const key = `imports ${fullDigest(store,importsOf.toString())} ${digest}`; const memo = memoOf(store); - const held = imported.get(digest) ?? memo.get(key)?.split('|').filter(Boolean); + const held = imported.get(digest) ?? (readOnly() ? undefined : memo.get(key)?.split('|').filter(Boolean)); if (held !== undefined) return held; - const found = [...new TextDecoder().decode(observeFile(at) ?? new Uint8Array()).matchAll(/(?:\bfrom\s*|\bimport\s*\(\s*|\bimport\s*)['"]([^'"]*)['"]/g)].map((m) => m[1] ?? ''); + const found = moduleImports(new TextDecoder().decode(observeFile(at) ?? new Uint8Array()),at); imported.set(digest, found); memo.set(key, found.join('|')); if (!readOnly()) appendFileSync(join(store, 'cas', `stamps${EXTENSION}`), `${key}\t${found.join('|')}\n`); diff --git a/src/fold/observed.ts b/src/fold/observed.ts index 0f67c0a..0c90085 100644 --- a/src/fold/observed.ts +++ b/src/fold/observed.ts @@ -1,3 +1,5 @@ +import {actCosts} from '../host/act-cost.ts'; +import {readingClosures} from '../host/reading-closures.ts'; import {readerLifetime,readerAllowsEmpty,assertReaderInputs,parse as parseLifetime} from '@lapxo/topos/wire'; import {readOnly} from '../host/read-only.ts'; import { basename, dirname, existsSync, mkdirSync, resolve, rmSync, spawn, statSync, writeFileSync } from '../host/io.ts'; @@ -260,6 +262,15 @@ export function observedClaims(root: string, store: string, options: { readonly function observeOne(reader: ReaderClaim, started: number): boolean { const module = resolve(root, reader.module); const asked = reader.capsule === undefined ? undefined : reader.capsule.selected??capsuleAt(reader.capsule.digest, reader.capsule.entry); + const projection = reader.capsule === undefined ? [] : (asked?.lines ?? []).filter(line=>fieldOf(line,'scope')===`region/${reader.capsule!.region}`&&fieldOf(line,'measure')==='input-projection'&&fieldOf(line,'value')!=='withdraw'); + if(projection.length){ + if(projection.length!==1||!asked)throw Error('REFUSE·input projection is ambiguous '+reader.module); + const files=[...new Set(reader.where.flatMap(where=>handedAt(root,reader,roleOf,look,where)))].sort().map(place=>({place,text:observeText(resolve(root,place))??''})); + const result=readingClosures({root,store,reader:reader.module,speaker,digest:text=>bytesDigest(store,Buffer.from(text)),capsule:asked,region:reader.capsule!.region,projection:fieldOf(projection[0]!,'value'),allowsEmpty:readerAllowsEmpty(standing.flatMap(line=>{const p=parseLifetime(line);return p.kind==='fact'?[p.value.fields]:[];}),reader.module),files,emit:line=>process.stderr.write(line+'\n')}); + out.push(...result.lines);ran+=result.executed;read+=result.read-result.opened; + return false; + } + const endAct=actCosts.begin();try{ const source = reader.capsule === undefined ? observeFile(module) : asked === undefined ? undefined : new Uint8Array(); const bundle = source && reader.capsule === undefined ? bundleOf(module) ?? bytesDigest(store, source) : 'none'; const offered = offersOf(root, store, reader, roleOf, look, (where) => reached(trimmed(where))); @@ -435,9 +446,11 @@ export function observedClaims(root: string, store: string, options: { readonly if (Date.now() - started > 250) spent.push(`${reader.module.split('/').pop()} ${identified - started}+${Date.now() - identified}`); if (kept !== undefined) landMemo(store, `observed/${kept}`, new TextEncoder().encode(out.slice(mark).join('\n'))); return false; + }finally{endAct();} } if (spent.length) process.stderr.write(`SPENT observe ${spent.join(' · ')} ms\n`); if (legacy) setAside(store, speaker); process.stderr.write(`OBSERVE ${ran} run · ${read} read by key${whole_ ? ` · ${whole_} readers kept whole` : ''} · ${Date.now() - began} ms\n`); + if (wait && refused.length) throw new Error(refused.join('\n')); return [...new Set(out)].sort(); } diff --git a/src/fold/resolved.ts b/src/fold/resolved.ts index 09c7707..32830be 100644 --- a/src/fold/resolved.ts +++ b/src/fold/resolved.ts @@ -94,17 +94,20 @@ export function keepCarried(store: string, lines: readonly string[], from?: stri * the caller refuses rather than read the lines that only name it. */ export function carriedFrom(store: string, shipped: readonly string[]): readonly string[] | undefined { - const named = shipped.find((line) => fieldOf(line, 'scope') === 'receipts' && fieldOf(line, 'measure') === 'digest'); + // Signed receipts inside the observed set are evidence, not its framing. + const headerOf = (line: string): boolean => fieldOf(line, 'scope') === 'receipts' && fieldOf(line, 'measure') === 'digest' && fieldOf(line, 'by') === 'bound' && !fieldOf(line, 'sig'); + const named = shipped.find(headerOf); if (named === undefined) return shipped; // Resolution 8 may precede its authenticated summary in the same public file. // It is evidence only if its exact bytes meet the summary's carrier digest. for (let i = 1; i < shipped.length; i += 1) { const header = shipped[i]!; - if (fieldOf(header, 'scope') !== 'receipts' || fieldOf(header, 'measure') !== 'digest') continue; + if (!headerOf(header)) continue; const digest = fieldOf(header, 'at').replace(/^place:sha256:/, ''); const body = shipped.slice(0, i); if (/^[0-9a-f]{64}$/.test(digest) && createHash('sha256').update(body.map(line => `${line}\n`).join('')).digest('hex') === digest) return body; } + if (shipped.indexOf(named) > 0) throw Error('REFUSE·receipt public carrier bytes mismatch; a cached carrier cannot replace supplied evidence'); const hex = fieldOf(named, 'at').replace(/^place:(?:sha256:)?/, ''); const text = /^[0-9a-f]{64}$/.test(hex) ? verifiedCarried(storeAt(store, 'cas', 'carried', hex), hex) : undefined; return text === undefined ? undefined : text.split('\n').filter(isWire); diff --git a/src/host/act-cost.ts b/src/host/act-cost.ts new file mode 100644 index 0000000..d2038b5 --- /dev/null +++ b/src/host/act-cost.ts @@ -0,0 +1,16 @@ +/** A sequence of declared acts is not one act. Unpartitioned host work still has a cost. */ +export class ActCosts { + private readonly began:number; + private occupied=0; + private largest=0; + private depth=0; + private readonly clock:()=>number; + constructor(clock:()=>number=()=>performance.now()){this.clock=clock;this.began=clock();} + begin():()=>void { + const started=this.clock(),outer=this.depth++===0;let closed=false; + return()=>{if(closed)throw Error('Act measurement closed twice');closed=true;const elapsed=Math.max(0,this.clock()-started);this.depth--;this.largest=Math.max(this.largest,elapsed);if(outer)this.occupied+=elapsed;}; + } + measure(work:()=>T):T{const end=this.begin();try{return work();}finally{end();}} + seconds():number{return Math.max(0,Math.round(Math.max(this.largest,this.clock()-this.began-this.occupied)/1000));} +} +export const actCosts=new ActCosts(); diff --git a/src/host/adapters/modules/javascript.ts b/src/host/adapters/modules/javascript.ts new file mode 100644 index 0000000..f1da5c6 --- /dev/null +++ b/src/host/adapters/modules/javascript.ts @@ -0,0 +1,36 @@ +import type {parse as Parser} from 'acorn'; +import * as nodeModule from 'node:module'; +import {extname} from 'node:path'; + +/** Host module syntax, never wire or domain interpretation. Reading imports executes no module. */ +// The package's minimum Node runtime provides this API; older build-only Node types do not. +const require=nodeModule.createRequire(import.meta.url); +const {parse}=require('acorn') as {parse:typeof Parser}; +const stripTypeScriptTypes=(nodeModule as unknown as {stripTypeScriptTypes:(source:string,options:{mode:'transform'})=>string}).stripTypeScriptTypes; +export function moduleImports(source: string, coordinate: string): readonly string[] { + const code=extname(coordinate)==='.ts'?stripTypeScriptTypes(source,{mode:'transform'}):source; + let tree: unknown; + try{tree=parse(code,{ecmaVersion:'latest',sourceType:'module',allowReturnOutsideFunction:true,allowHashBang:true})} + catch{throw Error('REFUSE·source module syntax cannot be read: '+coordinate)} + const found=new Set(); + const literal=(node:unknown):string|undefined=>{ + if(!node||typeof node!=='object')return; + const n=node as Record; + return n['type']==='Literal'&&typeof n['value']==='string'?n['value']:undefined; + }; + const visit=(node:unknown):void=>{ + if(!node||typeof node!=='object')return; + if(Array.isArray(node)){for(const child of node)visit(child);return;} + const n=node as Record; + let specifier:string|undefined; + if(n['type']==='ImportDeclaration'||n['type']==='ExportNamedDeclaration'||n['type']==='ExportAllDeclaration'||n['type']==='ImportExpression')specifier=literal(n['source']); + if(n['type']==='CallExpression'){ + const callee=n['callee'] as Record|undefined; + if(callee?.['type']==='Identifier'&&callee['name']==='require')specifier=literal((n['arguments'] as unknown[])[0]); + } + if(specifier!==undefined)found.add(specifier); + for(const child of Object.values(n))visit(child); + }; + visit(tree); + return [...found]; +} diff --git a/src/host/capsule-process.ts b/src/host/capsule-process.ts index 3290834..9887451 100644 --- a/src/host/capsule-process.ts +++ b/src/host/capsule-process.ts @@ -1,3 +1,4 @@ +import {actCosts} from './act-cost.ts'; import {boundedProcess} from './process-lifetime.ts'; import type {ReaderLifetime} from '@lapxo/topos/wire'; import { spawnSync } from 'node:child_process'; @@ -39,6 +40,7 @@ export function validResponse(value: unknown, request: Request): value is Respon /** Last-line JSON is the wire framing. No partial batch, failed exit or synthetic missing response is accepted. */ export function executeCapsule(command: string, args: readonly string[], requests: readonly Request[], limits: Pick = {}, lifetime?:ReaderLifetime): readonly Response[] { + return actCosts.measure(()=>{ const run = lifetime===undefined?spawnSync(command, args, { input: JSON.stringify(requests), encoding: 'utf8', maxBuffer: 1 << 26, ...limits }):boundedProcess(command,args,JSON.stringify(requests),lifetime); if ('error' in run && run.error) throw new CapsuleProcessError(`failed: ${run.error.message}`, run); if (run.signal !== null || run.status !== 0) throw new CapsuleProcessError(`exited ${run.status ?? `with signal ${run.signal}`}`, run); @@ -51,4 +53,5 @@ export function executeCapsule(command: string, args: readonly string[], request } if (run.stderr) process.stderr.write(run.stderr); return values as readonly Response[]; + }); } diff --git a/src/host/capsule.ts b/src/host/capsule.ts index 0277889..030ec24 100644 --- a/src/host/capsule.ts +++ b/src/host/capsule.ts @@ -44,9 +44,9 @@ function unpacked(digest: string, bytes: Uint8Array): string { /** * A capsule is the bytes a digest names in the instrument's own store, and only when they hash to it: its own lock is - * read from them, and the coordinate a lock names runs as a process of its own, like a reader. Each answer is kept in one - * slot of the capsule, the place and the region; the body of the request is the hit, so a file that moved misses and - * overwrites the slot, and a request asked again for the same bytes is read back and never run twice. Operational failures never enter the cache; refusals and abstentions are asked again. + * read from them, and the coordinate a lock names runs as a process of its own, like a reader. Each answer is kept by the + * digest of its complete declared request and implementation; distinct views retain distinct answers, and the same + * request reads its verified answer without running again. Operational failures never enter the cache; refusals and abstentions are asked again. */ const capsules = new Map(); @@ -101,10 +101,9 @@ function answered(digest: string, bytes: Uint8Array, requests: readonly Request[ return requests.map(() => undefined); } const loader = entry !== undefined ? `${createHash('sha256').update(`${relative(tree!, entry)}\n`).digest('hex')}\n` : child.length > 1 ? `${createHash('sha256').update(observeFile(child[0]!) ?? new Uint8Array()).digest('hex')}\n` : ''; - const slotOf = (request: Request): string => sha(`${digest}\n${loader}${request.verb}\n${request.rootScope}\n${request.region ?? ''}`); const hitOf = (request: Request): string => sha(`${digest}\n${loader}${JSON.stringify(request)}`); - const kept = requests.map((request) => storeAt(cacheStore, 'cas', 'answers', slotOf(request))); const hits = requests.map(hitOf); + const kept = hits.map(hit => storeAt(cacheStore, 'cas', 'answers', hit)); const held = kept.map((at, i) => { const text = observeText(at); if (text === undefined) return undefined; @@ -126,7 +125,7 @@ function answered(digest: string, bytes: Uint8Array, requests: readonly Request[ if (said?.kind === 'fact') { const text = JSON.stringify({ format: 'capsule-answer/2', hit: hits[i], said }); replaceWhole(kept[i]!, text); - holdStore(cacheStore, 'answers', slotOf(request), Buffer.byteLength(text)); + holdStore(cacheStore, 'answers', hits[i]!, Buffer.byteLength(text)); } return said; }); diff --git a/src/host/ports/ingress.ts b/src/host/ports/ingress.ts new file mode 100644 index 0000000..93dab17 --- /dev/null +++ b/src/host/ports/ingress.ts @@ -0,0 +1,67 @@ +import {randomUUID} from 'node:crypto'; +import {closeSync,existsSync,fsyncSync,mkdirSync,openSync,readFileSync,readdirSync,renameSync,rmSync,writeFileSync} from 'node:fs'; +import {join} from 'node:path'; +import {requireEffects} from '../read-only.ts'; +import {underTheLock} from '../../land/act.ts'; + +/** Prepared by the admitted Topos contract and receiver signer. The host does not infer origins, coverage or epochs. */ +export interface IngressBundle {readonly evidence: string; readonly receipt: string} +export interface IngressResult extends IngressBundle {readonly kind: 'landed' | 'once'; readonly evidenceBytes: number; readonly receiptBytes: number} +export interface IngressStorage { + publish(staged: string, committed: string): void; +} +const syncDirectory = (path: string): void => {const fd=openSync(path,'r');try{fsyncSync(fd)}finally{closeSync(fd)}}; +const durableFile = (path: string, text: string): void => {const fd=openSync(path,'wx',0o600);try{writeFileSync(fd,text);fsyncSync(fd)}finally{closeSync(fd)}}; +/** Directory publication makes the pair visible together; there is no later ledger append that can expose half. */ +export const nativeIngressStorage: IngressStorage = {publish(staged,committed){renameSync(staged,committed);syncDirectory(join(committed,'..'))}}; +const directory = (store: string): string => join(store,'ingress'); +const nameOf = (identity: string): string => { + if(!identity||identity.includes('\0'))throw Error('REFUSE·ingress missing import identity'); + return 'committed-'+encodeURIComponent(identity); +}; +const read = (at: string): IngressBundle => ({evidence:readFileSync(join(at,'evidence.bound'),'utf8'),receipt:readFileSync(join(at,'receipt.bound'),'utf8')}); +const measured = (kind: 'landed'|'once', bundle: IngressBundle): IngressResult => ({kind,...bundle,evidenceBytes:Buffer.byteLength(bundle.evidence),receiptBytes:Buffer.byteLength(bundle.receipt)}); + +/** Native signed receipt lines only. Foreign bytes are never added to the local ledger or epoch allocator. */ +export function ingressReceipts(store: string): readonly string[] { + const root=directory(store);if(!existsSync(root))return []; + return readdirSync(root).filter(name=>name.startsWith('committed-')).sort().flatMap(name=>read(join(root,name)).receipt.split('\n').filter(Boolean)); +} +/** Private staging directories are invisible to readers and may be discarded after host recovery. */ +export function ingressEvidence(store: string, identity: string): IngressBundle | undefined { + const at=join(directory(store),nameOf(identity));return existsSync(at)?read(at):undefined; +} + +export function ingressBundles(store: string): readonly IngressBundle[] { + const root=directory(store);if(!existsSync(root))return []; + return readdirSync(root).filter(name=>name.startsWith('committed-')).sort().map(name=>read(join(root,name))); +} + +/** Verification and signing complete before staging. Replay performs no signer invocation or persistent write. */ +export async function commitIngress(store: string, identity: string, + prepare: (localImportReceipts: readonly string[]) => Promise, + verify: (bundle: IngressBundle) => boolean, + storage: IngressStorage = nativeIngressStorage): Promise { + requireEffects('foreign evidence ingress'); + return underTheLock(store,'ingress',async()=>{ + const root=directory(store),at=join(root,nameOf(identity)); + if(existsSync(at)){const prior=read(at);if(verify(prior)!==true)throw Error('REFUSE·ingress committed bytes do not verify');return measured('once',prior)} + const bundle=await prepare(ingressReceipts(store)); + if(!bundle.evidence||!bundle.receipt||verify(bundle)!==true)throw Error('REFUSE·ingress evidence and receipt do not verify'); + mkdirSync(root,{recursive:true}); + const staged=join(root,'.stage-'+randomUUID());mkdirSync(staged,{mode:0o700}); + try { + durableFile(join(staged,'evidence.bound'),bundle.evidence); + durableFile(join(staged,'receipt.bound'),bundle.receipt); + syncDirectory(staged); + storage.publish(staged,at); + }finally{rmSync(staged,{recursive:true,force:true})} + return measured('landed',bundle); + }); +} + +/** Costs distinguish delivered bytes from newly committed bytes; no count is called information or freedom. */ +export function ingressCost(result: IngressResult, deliveredBytes: number, protocolBytes: number): string { + if(!Number.isSafeInteger(deliveredBytes)||deliveredBytes<0||!Number.isSafeInteger(protocolBytes)||protocolBytes<0)throw Error('REFUSE·ingress invalid exchange byte measurement'); + return `EXCHANGE ${deliveredBytes} payload bytes · ${protocolBytes} protocol bytes · ${result.kind==='once'?0:result.evidenceBytes} new evidence bytes · ${result.kind==='once'?0:result.receiptBytes} new receipt bytes`; +} diff --git a/src/host/reading-closures.ts b/src/host/reading-closures.ts new file mode 100644 index 0000000..921898c --- /dev/null +++ b/src/host/reading-closures.ts @@ -0,0 +1,92 @@ +import {actCosts} from './act-cost.ts'; +import {mkdirSync,readFileSync,existsSync} from 'node:fs'; +import {join,dirname} from 'node:path'; +import {canonical,parse,PROTOCOL,byBytes} from '@lapxo/topos/wire'; +import type {Capsule} from './capsule.ts'; +import {replaceWhole,landShard,shardLines} from '../land/ledger.ts'; +import {fieldOf} from '../fold/claims.ts'; +import {readOnly} from './read-only.ts'; + +type File={readonly place:string;readonly text:string}; +type Plan={scope:string;inputs:readonly string[];needs:readonly string[];resolution:number;line:string}; +const fields=(line:string)=>{const got=parse(line);if(got.kind!=='fact')throw Error('REFUSE·input projection contains a non-wire line');return got.value.fields;}; +export const inputLines=(files:readonly File[]):readonly string[]=>files.map(file=>canonical({scope:file.place,form:'alphabet',measure:'text',role:'writes',value:'lock',shape:file.place,about:file.text,by:'host',at:'policy:handed-input'})); +/** The selected world owns input projection and reading. The host only verifies closures and keeps native count/bytes receipts. */ +export function readingClosures(options:{root:string;store:string;reader:string;speaker:string;digest:(text:string)=>string;capsule:Capsule;region:string;projection:string;allowsEmpty?:boolean;files:readonly File[];emit?:(line:string)=>void}):{lines:readonly string[];read:number;opened:number;executed:number}{ + const {root,store,reader,speaker,digest:hash,capsule,region,projection,files}=options,emit=options.emit??(()=>{}); + const algorithm=hash('').split(':')[0]!,handed=new Map(files.map(file=>[file.place,file.text])); + if(handed.size!==files.length)throw Error('REFUSE·input projection has duplicate handed coordinates'); + const verify=()=>{for(const file of files)if(!readFileSync(join(root,file.place)).equals(Buffer.from(file.text)))throw Error('REFUSE·input changed '+file.place);}; + verify(); + const projected=capsule.ask([{protocol:PROTOCOL,verb:'render',rootScope:'',region:projection,at:1,reads:['**'],lines:inputLines(files),files:[]}])[0]; + if(projected?.kind!=='fact'||!Array.isArray(projected.lines))throw Error('REFUSE·input projection '+(projected?.why??'no lines')); + const plans=new Map(); + for(const line of projected.lines){const f=fields(line),scope=f.scope??'',resolution=/^receipt:(\d+)$/.exec(f.at??''); + if(!scope||plans.has(scope)||f.form!=='alphabet'||f.measure!=='reads'||f.role!=='reads'||!resolution)throw Error('REFUSE·input projection ambiguous reading '+scope); + const inputs=(f.value??'').split('|').filter(Boolean),needs=(f.needs??'').split('|').filter(Boolean); + if(!inputs.length||new Set(inputs).size!==inputs.length||inputs.some(input=>!handed.has(input))||new Set(needs).size!==needs.length)throw Error('REFUSE·input projection has unhanded or duplicate dependencies '+scope); + const n=Number(resolution[1]);if(!Number.isSafeInteger(n))throw Error('REFUSE·input projection invalid resolution '+scope); + plans.set(scope,{scope,inputs,needs,resolution:n,line:canonical({scope,form:f.form,measure:f.measure,role:f.role,value:inputs.join('|'),needs:needs.join('|'),at:f.at})}); + } + if(!plans.size)throw Error('REFUSE·input projection returned no readings'); + const ordered:Plan[]=[],visiting=new Set(),done=new Set(); + const visit=(scope:string)=>{if(done.has(scope))return;if(visiting.has(scope))throw Error('REFUSE·input projection dependency cycle '+scope);const p=plans.get(scope);if(!p)throw Error('REFUSE·input projection missing reading '+scope);visiting.add(scope);for(const need of p.needs)visit(need);visiting.delete(scope);done.add(scope);ordered.push(p);}; + for(const scope of plans.keys())visit(scope); + const identity=hash([capsule.selection??'',capsule.digest,region,projection].join('\n')),by=speaker+':'+identity.split(':')[1]!.slice(0,12),journal='reading-closures/'+identity.split(':')[1]; + const prior=shardLines(store,speaker,journal),results=new Map(),out:string[]=[]; + const carried=(digest:string)=>join(store,'cas','carried',digest.split(':')[1]??''); + const saved=(text:string)=>{const digest=hash(text),path=carried(digest);mkdirSync(dirname(path),{recursive:true});if(!existsSync(path)||hash(readFileSync(path,'utf8'))!==digest)replaceWhole(path,text);return digest;}; + const load=(digest:string)=>{if(!digest.startsWith(algorithm+':')||! /^[a-f0-9]+$/.test(digest.split(':')[1]??''))return;const path=carried(digest);if(!existsSync(path))return;const text=readFileSync(path,'utf8');return hash(text)===digest?text:undefined;}; + let read=0,opened=0,executed=0; + for(const plan of ordered){actCosts.measure(()=>{ + const closure=[plan.line,canonical({scope:'implementation',role:'writes',form:'alphabet',measure:'digest',value:identity,by:'host',at:'policy:input-identity'}),...plan.inputs.map(input=>canonical({scope:input,role:'writes',form:'alphabet',measure:'digest',value:hash(handed.get(input)!),by:'host',at:'policy:input-identity'})),...plan.needs.map(need=>canonical({scope:need,role:'writes',form:'alphabet',measure:'digest',value:results.get(need)!.digest,by:'host',at:'policy:input-identity'}))].sort(byBytes).join('\n')+'\n'; + const input=hash(closure),scope='receipts/readings/'+hash(plan.scope).split(':')[1]+'/'+input.split(':')[1],matching=prior.filter(line=>fieldOf(line,'scope')===scope&&fieldOf(line,'measure')==='bytes'&&fieldOf(line,'value')===input).at(-1); + const count=matching&&prior.filter(line=>fieldOf(line,'scope')===scope&&fieldOf(line,'measure')==='count'&&fieldOf(line,'by')===by).at(-1); + const heldOutput=count&&load(fieldOf(count,'at').replace(/^place:/,'')); + const heldLines=heldOutput?.split('\n').filter(Boolean); + const output=heldLines!==undefined&&fieldOf(count!,'value')===`${heldLines.length}..${heldLines.length}`&&heldLines.every(line=>{const f=fields(line);return f.by===by&&f.at==='place:'+input;})?heldOutput:undefined; + let lines:readonly string[],payload:string; + if(output!==undefined&&load(input)===closure){if(output===''&&!options.allowsEmpty)throw Error('REFUSE·reading empty response is not admitted '+plan.scope);lines=output.split('\n').filter(Boolean);for(const line of lines)fields(line);payload=fieldOf(count!,'at').replace(/^place:/,'');} + else { + if(readOnly())throw Error('REFUSE·preview reading closure is unpaid '+plan.scope); + const started=process.hrtime.bigint(); + const dependencies=plan.needs.flatMap(need=>results.get(need)!.lines),answer=capsule.ask([{protocol:PROTOCOL,verb:'read',rootScope:plan.scope,name:plan.scope,region,at:plan.resolution,reads:['**'],lines:[...inputLines(plan.inputs.map(place=>({place,text:handed.get(place)!}))),...dependencies],files:[]}])[0]; + if(answer?.kind!=='fact'||!Array.isArray(answer.claims))throw Error('REFUSE·reading '+plan.scope+' · '+(answer?.why??'no claims')); + lines=answer.claims.map((unknown:any)=>{if(typeof unknown?.scope!=='string'||typeof unknown?.measure!=='string'||typeof unknown?.role!=='string'||!unknown.bound||!['interval','enumerated'].includes(unknown.bound.kind))throw Error('REFUSE·reading malformed claim '+plan.scope);const span=unknown.bound;const text=canonical({scope:unknown.scope,measure:unknown.measure,role:unknown.role,form:span.kind==='interval'?'interval':'alphabet',value:span.kind==='interval'?`${span.lo}..${span.hi}`:Array.isArray(span.values)?span.values.join('|'):'',by,at:'place:'+input});fields(text);return text;}); + if(!lines.length&&!options.allowsEmpty)throw Error('REFUSE·reading empty response is not admitted '+plan.scope); + executed++;verify();payload=saved(lines.length?[...lines].sort(byBytes).join('\n')+'\n':'');if(saved(closure)!==input)throw Error('REFUSE·receipt input closure mismatch'); + const seconds=(Number(process.hrtime.bigint()-started)/1e9).toFixed(6); + landShard(store,speaker,journal,[canonical({scope,role:'writes',form:'interval',measure:'count',value:`${lines.length}..${lines.length}`,by,at:'place:'+payload}),canonical({scope,role:'writes',form:'alphabet',measure:'bytes',value:input,by,at:'place:'+input}),canonical({scope,role:'writes',form:'interval',measure:'s',value:seconds+'..'+seconds,by,at:'place:'+input})]); + if(plan.resolution===1)opened++; + } + results.set(plan.scope,{digest:payload,lines});out.push(canonical({scope:plan.scope,role:'writes',form:'alphabet',measure:'observed',value:input,by,at:'place:'+input}),...lines); + if(plan.resolution===1){read++;const native=shardLines(store,speaker,journal).filter(line=>fieldOf(line,'scope')===scope&&((fieldOf(line,'measure')==='bytes'&&fieldOf(line,'value')===input)||(fieldOf(line,'measure')==='count')||(fieldOf(line,'measure')==='s'&&fieldOf(line,'at')==='place:'+input))).map(line=>{ + const f=fields(line),id=f.measure==='bytes'?f.value:f.measure==='count'?(f.at??'').replace(/^place:/,''):undefined; + if(id===undefined)return line; + const bytes=load(id);if(bytes===undefined)throw Error('REFUSE·receipt missing verified carrier '+id); + // The full-resolution native row carries the actual verified UTF-8 bytes. + // Its semantic count/digest is unchanged; a public copy needs no private CAS. + return canonical({...f,about:bytes}); + });out.push(canonical({scope,role:'writes',form:'alphabet',measure:'observed',value:payload,by,at:'place:'+payload}),...native);} + });} + verify();emit(`RECEIPTS ${read} read · ${opened} opened · reading closures`); + return{lines:out,read,opened,executed}; +} + +/** Verify the native reading carriers before a file seal may reuse them. These are semantic receipts, not file-region seals. */ +export function verifiedReadingReceipts(store:string,lines:readonly string[],digest:(text:string)=>string):number|undefined { + const units=lines.filter(line=>fieldOf(line,'scope').startsWith('receipts/readings/')&&fieldOf(line,'measure')==='bytes'&&fieldOf(line,'role')==='writes'); + const load=(id:string,row:string)=>{const hex=id.split(':')[1];if(!hex||!/^[a-f0-9]+$/.test(hex))return; + const supplied=fields(row).about; + // A supplied carrier must authenticate even if an old local copy still exists. + if(supplied!==undefined)return digest(supplied)===id?supplied:undefined; + const path=join(store,'cas','carried',hex);if(!existsSync(path))return;const bytes=readFileSync(path,'utf8');return digest(bytes)===id?bytes:undefined;}; + for(const unit of units){ + const input=fieldOf(unit,'value'),scope=fieldOf(unit,'scope'),by=fieldOf(unit,'by'),counts=lines.filter(line=>fieldOf(line,'scope')===scope&&fieldOf(line,'measure')==='count'&&fieldOf(line,'by')===by&&fieldOf(line,'role')==='writes'); + if(counts.length!==1||load(input,unit)===undefined)return; + const count=counts[0]!,output=load(fieldOf(count,'at').replace(/^place:/,''),count);if(output===undefined)return; + const rows=output.split('\n').filter(Boolean); + if(fieldOf(count,'value')!==`${rows.length}..${rows.length}`||rows.some(line=>fieldOf(line,'by')!==by||fieldOf(line,'at')!=='place:'+input))return; + } + return units.length; +} diff --git a/src/host/release.ts b/src/host/release.ts index 5a01324..93c2134 100644 --- a/src/host/release.ts +++ b/src/host/release.ts @@ -51,10 +51,22 @@ function layDir(from: string, into: string): void { } } -function swapPlace(place: string, next: string, digest: string): void { +function swapPlace(place: string, next: string, digest: string, ready?: () => boolean): void { const old = `${next}.old`; if (lstatSync(old, { throwIfNoEntry: false }) !== undefined) throw new Error(`REFUSE·release recovery required for ${old}`); writeFileSync(join(next, laidMark), digest, { flag: 'wx' }); + if (ready !== undefined) { + // Digest-addressed trees publish once. A verified concurrent winner is reused, + // never moved aside while another process may be importing its members. + if (ready()) { rmSync(next, { recursive: true, force: true }); return; } + try { renameSync(next, place); return; } + catch (error) { + const code = (error as NodeJS.ErrnoException).code; + if (code !== 'EEXIST' && code !== 'ENOTEMPTY') throw error; + if (ready()) { rmSync(next, { recursive: true, force: true }); return; } + // An existing invalid cache retains the repair/rollback path below. + } + } let moved = false; try { if (lstatSync(place, { throwIfNoEntry: false }) !== undefined) { renameSync(place, old); moved = true; } @@ -204,7 +216,7 @@ export function runtimeTreeAt(store: string, own: string, digest: string, conten if (observeText(join(place, laidMark)) === digest && layoutMatches(place, files)) return selected; for (const member of members(bytes)) landBlob(store, digestOf(member.bytes), member.bytes); const next = nextPlace(place); - try { layFiles(store, own, files, next); swapPlace(place, next, digest); } + try { layFiles(store, own, files, next); swapPlace(place, next, digest, () => observeText(join(place, laidMark)) === digest && layoutMatches(place, files)); } catch (error) { rmSync(next, { recursive: true, force: true }); throw error; } return selected; } diff --git a/src/host/walk.ts b/src/host/walk.ts new file mode 100644 index 0000000..2b1d795 --- /dev/null +++ b/src/host/walk.ts @@ -0,0 +1,142 @@ +import {walkProjection,walkAt,walkSnapshot,walkHeaders,readWalkHeaders,readForeignWalk,walkAuthority,walkOrigin,walkInventory,walkSelection,isWalkHeader} from '@lapxo/topos/walk'; +import type {WalkSnapshot,WalkRegion} from '@lapxo/topos/walk'; +import {canonical,parse,fromLine,wireAt,matches,objectHistory,validateObjectContext} from '@lapxo/topos/wire'; +import {objectProvider} from '@lapxo/topos/object-provider'; +import {standingBytes} from '@lapxo/topos/standing'; +import {fieldOf} from '../fold/claims.ts'; +import {lockStanding,lockLines} from '../fold/keys.ts'; +import {authorityFor,rootSigner} from '../fold/signers.ts'; +import {publicKeyOf} from '../fold/signers.ts'; +import {signaturesOf} from '../fold/digests.ts'; +import {fullDigest} from './digest.ts'; +import {toposAt,contextModuleAt} from './selected-topos.ts'; +import {signerFor} from './signing.ts'; +import {signConsentLot,verifiesFields} from '../land/sign.ts'; +import {storeOf} from '../land/ledger.ts'; +import {signedOwnerLines,epochOf,localActLines,ownerOf} from '../cli/owner.ts'; +import {commitIngress,ingressBundles,ingressCost} from './ports/ingress.ts'; +import type {IngressBundle} from './ports/ingress.ts'; + +const refuse=(why:string):never=>{throw Error('REFUSE·walk '+why)}; +const fields=(line:string)=>{const p=parse(line);if(p.kind!=='fact')return refuse('not a wire line');return p.value.fields}; +const one=(lines:readonly string[],scope:string,measure:string):string=>{ + const rows=lines.filter(line=>fieldOf(line,'scope')===scope&&fieldOf(line,'measure')===measure&&fieldOf(line,'value')!=='withdraw'); + if(rows.length!==1)return refuse('missing or conflicting '+scope+' '+measure); + return fieldOf(rows[0]!,'value'); +}; +function policy(root:string){ + const store=storeOf(root),standing=lockStanding(store),contract=walkSelection(standing); + const view=one(standing,'view/walk','id');if(view!=='walk@*')refuse('view/walk must declare walk@*'); + const masks=standing.filter(line=>fieldOf(line,'scope')==='view/walk').flatMap(line=>fieldOf(line,'needs').split('|')).filter(Boolean); + if(!masks.length)refuse('view/walk has no declared history inputs'); + const wire=wireAt(standing.map(fields),Number.MAX_SAFE_INTEGER),algorithm=wire?.digests.values().next().value; + if(!algorithm)refuse('no admitted digest algorithm'); + return {store,standing,contract,masks,digest:(bytes:string)=>fullDigest(bytes,algorithm!)}; +} +function context(root:string,pin:string,own=false){ + const p=policy(root); + if(!own&&!p.standing.some(line=>fieldOf(line,'scope').startsWith('uses/')&&fieldOf(line,'value')===pin))refuse('origin context is not selected by digest'); + const topos=toposAt(pin,p.store),authority=walkAuthority(topos.parts,verifiesFields); + const configuration=topos.parts.map(f=>canonical({...f,by:'target',epoch:'0'})); + return {pin,topos,authority,configuration,origin:walkOrigin(topos.parts),contract:walkSelection(topos.lines)}; +} +function local(root:string):WalkSnapshot { + const p=policy(root),authority=authorityFor(lockLines(p.store),rootSigner(root),signaturesOf(p.store).admitted); + const history=signedOwnerLines(p.store).filter(line=>p.masks.some(mask=>matches(mask,fieldOf(line,'scope')))); + if(history.some(line=>authority.of(line).kind!=='admitted'))refuse('local history is not authenticated'); + const selected=context(root,one(p.standing,'walk/context','digest'),true); + return walkSnapshot(history,selected.contract.fields,p.digest,selected.origin,selected.contract.partition); +} +const headerInfo=(lines:readonly string[])=>{ + const roots=lines.filter(line=>isWalkHeader(line)&&fieldOf(line,'scope')==='walk/root'); + if(roots.length!==1)return refuse('one signed root is required'); + const at=fieldOf(roots[0]!,'at');if(!at.startsWith('receipt:'))return refuse('root has no declared context'); + return {pin:at.slice(8),base:fieldOf(roots[0]!,'condition')}; +}; +async function validateHistory(root:string,selected:ReturnType,history:readonly string[]):Promise{ + if(!selected.authority.authenticate(history))refuse('origin history is not authenticated'); + for(const line of history){const f=fields(line),decoded=fromLine(line,wireAt(selected.topos.parts,Number(f.epoch)));if(decoded.kind!=='fact')refuse('origin wire '+decoded.why);} + const decoded=objectHistory([...selected.configuration,...history]);if(decoded.kind!=='fact')return refuse('origin history '+decoded.why); + if(!decoded.value.objects.length)return; + const pinned=new Set(selected.topos.lines); + const admit=(f:Readonly>)=>Boolean(f.sig)?selected.authority.of(canonical(f)).kind==='admitted':pinned.has(standingBytes([canonical(f)]).trim()); + const provider=await objectProvider(decoded.value.objects,decoded.value.configuration,{admit,emit:()=>{},topos:pin=>toposAt(pin,storeOf(root)),module:pin=>contextModuleAt(pin,storeOf(root))}); + const checked=validateObjectContext(decoded.value.objects,provider);if(checked.kind!=='fact')refuse('origin context '+checked.why); +} +async function readBundle(root:string,bundle:IngressBundle,earlier:readonly string[]=[]){ + const lines=bundle.evidence.split('\n').filter(Boolean),info=headerInfo(lines),p=policy(root); + const receipts=bundle.receipt.split('\n').filter(Boolean),authority=authorityFor(lockLines(p.store),rootSigner(root),signaturesOf(p.store).admitted); + if(receipts.length!==1||fieldOf(receipts[0]!,'scope')!=='receipts'||fieldOf(receipts[0]!,'role')!=='writes'||fieldOf(receipts[0]!,'form')!=='alphabet'||fieldOf(receipts[0]!,'measure')!=='digest'||fieldOf(receipts[0]!,'at')!=='receipt:'+info.pin||authority.of(receipts[0]!).kind!=='admitted')refuse('retained import receipt is not authenticated'); + const selected=context(root,info.pin); + const got=readForeignWalk(lines,{origin:selected.origin,regionOrigin:selected.origin,context:info.pin,base:info.base,fields:selected.contract.fields,partition:selected.contract.partition,digest:p.digest,previousPrefixes:[],authenticatePrefix:selected.authority.authenticate,authenticateEvidence:selected.authority.authenticate,validateOriginHistory:()=>true}); + if(fieldOf(receipts[0]!,'value')!==got.identity)refuse('retained import receipt does not authenticate this ingress'); + await validateHistory(root,selected,[...new Set([...earlier,...got.records])]); + return {...got,context:info.pin,regions:walkSnapshot(got.records,selected.contract.fields,p.digest,got.origin,selected.contract.partition).regions}; +} +async function verifiedIngress(root:string){ + const result:Awaited>[]=[],history=new Map>(); + const bundles=[...ingressBundles(storeOf(root))].sort((a,b)=>epochOf(a.receipt.split('\n'))-epochOf(b.receipt.split('\n'))); + for(const bundle of bundles){const info=headerInfo(bundle.evidence.split('\n').filter(Boolean)),origin=context(root,info.pin).origin;if(result.some(prior=>prior.origin===origin&&prior.context!==info.pin))refuse('origin context changed without declared lineage');const prior=history.get(origin)??new Set();const got=await readBundle(root,bundle,[...prior]);for(const line of got.records)prior.add(line);history.set(origin,prior);result.push(got)} + return result; +} +async function inventory(root:string){ + const p=policy(root),regions=new Map(local(root).regions.map(region=>[region.scope,region])); + for(const got of (await verifiedIngress(root)).sort((a,b)=>a.senderEpoch-b.senderEpoch))for(const region of got.regions)regions.set(region.scope,region); + return walkInventory([[...regions.values()]],p.digest,context(root,one(p.standing,'walk/context','digest'),true).contract.partition); +} +/** Verified foreign histories stay separate from the local authority and local epoch inputs. */ +export async function foreignWalkLines(root:string):Promise{ + const verified=await verifiedIngress(root); + return [...new Set(verified.flatMap(got=>got.records))]; +} +/** A declared origin exports its own signed history. Foreign packets are retained with their contexts, never re-signed as local history. */ +export async function renderWalk(root:string,resolution:number|undefined,peer:readonly string[],key?:string,keyFile?:string,signer?:string):Promise{ + const p=policy(root),pin=one(p.standing,'walk/context','digest'),selected=context(root,pin,true),own=local(root); + const known=peer.length?(()=>{const info=headerInfo(peer),remote=context(root,info.pin);return readWalkHeaders(peer,info.pin,info.base,remote.authority.authenticate)})():walkSnapshot([],p.contract.fields,p.digest); + const projection=walkProjection(selected.contract.projections,resolution); + const ownInventory=projection==='history'?own:await inventory(root); + const selectedPacket=walkAt(ownInventory,known,resolution,selected.contract.projections),by=key??ownerOf(p.store),publicKey=publicKeyOf(root,by); + if(!publicKey)refuse('unknown local signer '+by); + const drafted=walkHeaders(selectedPacket,pin,known.root,projection!=='inventory'),epoch=epochOf(localActLines(root)); + const got=await signConsentLot(drafted,{by,epoch,algorithm:signaturesOf(p.store).era},publicKey!,signaturesOf(p.store).admitted,signerFor(p.standing,by,signer,keyFile)); + if(got.kind!=='fact')return refuse(got.why); + if(!selected.authority.authenticate(got.lines)||!selected.authority.authenticate(selectedPacket.records))refuse('local context does not authenticate exported history'); + return [...got.lines,...selectedPacket.records,`EXCHANGE ${selectedPacket.touched} touched regions · ${selectedPacket.open} open regions · ${Buffer.byteLength(selectedPacket.records.join('\n')+(selectedPacket.records.length?'\n':''))} payload bytes`]; +} +/** The SDK proves the foreign prefix; the host admits the pair at one publication point. */ +export async function landWalk(root:string,lines:readonly string[],key?:string,keyFile?:string,signer?:string):Promise{ + const p=policy(root),info=headerInfo(lines),selected=context(root,info.pin); + const retained=await verifiedIngress(root); + if(retained.some(prior=>prior.origin===selected.origin&&prior.context!==info.pin))refuse('origin context changed without declared lineage'); + const previous=(verified:typeof retained)=>{const prefixes=new Map();for(const prior of verified.filter(got=>got.origin===selected.origin).sort((a,b)=>a.senderEpoch-b.senderEpoch))for(const region of prior.regions)prefixes.set(region.scope,{...region,senderEpoch:prior.senderEpoch});return [...prefixes.values()]}; + const payload=lines.filter(line=>!isWalkHeader(line)); + const proof=(prefixes:ReturnType)=>readForeignWalk(lines,{origin:selected.origin,regionOrigin:selected.origin,context:info.pin,base:info.base,fields:selected.contract.fields,partition:selected.contract.partition,digest:p.digest,previousPrefixes:prefixes,authenticatePrefix:selected.authority.authenticate,authenticateEvidence:selected.authority.authenticate,validateOriginHistory:()=>true}); + const raw=proof([]),known=retained.find(prior=>prior.identity===raw.identity),got=known?raw:proof(previous(retained)); + const history=(prior:typeof retained)=>[...new Set([...prior.filter(item=>item.origin===selected.origin).flatMap(item=>item.records),...payload])]; + await validateHistory(root,selected,history(retained)); + if(!known&&info.base!==(await inventory(root)).root)refuse('stale receiver base'); + if(!payload.length&&!readWalkHeaders(lines,info.pin,info.base,selected.authority.authenticate).regions.length)return ['ONCE 0 new evidence lines · 0 import receipts · no regions offered',`EXCHANGE 0 payload bytes · ${Buffer.byteLength(lines.join('\n')+'\n')} protocol bytes · 0 new evidence bytes · 0 new receipt bytes`]; + const by=key??ownerOf(p.store),pub=publicKeyOf(root,by);if(!pub)refuse('unknown receiver signer '+by); + const result=await commitIngress(p.store,got.identity,async()=>{ + if(info.base!==(await inventory(root)).root)refuse('receiver changed before ingress'); + const current=await verifiedIngress(root); + proof(previous(current)); + await validateHistory(root,selected,history(current)); + const next=epochOf(localActLines(root))+1; + const signed=await signConsentLot([got.importReceiptProposal],{by,epoch:next,algorithm:signaturesOf(p.store).era},pub!,signaturesOf(p.store).admitted,signerFor(p.standing,by,signer,keyFile)); + if(signed.kind!=='fact')return refuse(signed.why); + const authority=authorityFor(lockLines(p.store),rootSigner(root),signaturesOf(p.store).admitted); + if(authority.of(signed.lines[0]!).kind!=='admitted')refuse('receiver signer does not cover the import receipt'); + const grammar=fromLine(signed.lines[0]!,wireAt(p.standing.map(fields),next));if(grammar.kind!=='fact')refuse('receiver receipt wire '+grammar.why); + return {evidence:lines.join('\n')+'\n',receipt:signed.lines.join('\n')+'\n'}; + },bundle=>{ + try{ + const retainedLines=bundle.evidence.split('\n').filter(Boolean),retainedInfo=headerInfo(retainedLines); + if(retainedInfo.pin!==info.pin)return false; + const retainedProof=readForeignWalk(retainedLines,{origin:selected.origin,regionOrigin:selected.origin,context:info.pin,base:retainedInfo.base,fields:selected.contract.fields,partition:selected.contract.partition,digest:p.digest,previousPrefixes:[],authenticatePrefix:selected.authority.authenticate,authenticateEvidence:selected.authority.authenticate,validateOriginHistory:()=>true}); + const receipts=bundle.receipt.split('\n').filter(Boolean),receipt=receipts[0]??''; + return receipts.length===1&&retainedProof.identity===got.identity&&fieldOf(receipt,'scope')==='receipts'&&fieldOf(receipt,'value')===got.identity&&fieldOf(receipt,'at')==='receipt:'+info.pin&&authorityFor(lockLines(p.store),rootSigner(root),signaturesOf(p.store).admitted).of(receipt).kind==='admitted'; + }catch{return false} + }); + return [`${result.kind==='once'?'ONCE':'INGRESS'} ${result.kind==='once'?0:got.records.length} new evidence lines · 1 ${result.kind==='once'?'retained':'signed local'} import receipt`,result.receipt.trim(),ingressCost(result,Buffer.byteLength(payload.join('\n')+(payload.length?'\n':'')),Buffer.byteLength(lines.filter(isWalkHeader).join('\n')+'\n'))]; +} diff --git a/src/observe/regions.ts b/src/observe/regions.ts index aa0e8da..9008d1d 100644 --- a/src/observe/regions.ts +++ b/src/observe/regions.ts @@ -7,13 +7,11 @@ import { CAPSULE, LOCK, canonical, matches, PROTOCOL } from '@lapxo/topos/wire'; import { handed, readsOf } from '@lapxo/topos/capsule'; import type { Declaration } from '@lapxo/topos/capsule'; import type { Request } from '@lapxo/topos/contract'; -import { STATES } from '@lapxo/obligations'; import { foldCeilings } from '../fold/ceilings.ts'; import { fieldOf, wireLinesOf as linesOf } from '../fold/claims.ts'; import { isCeiling } from '../fold/configures.ts'; import { keyFor } from '../fold/keys.ts'; import { casesHeld, placedReadings } from '../fold/observed.ts'; -import { verdictsFor } from '../fold/paid.ts'; import { capsuleAt as isWorld, placesIn, spoken } from '../fold/places.ts'; import { rolesOf } from '../fold/roles.ts'; import { ownLockOf } from '../fold/signed.ts'; @@ -86,9 +84,8 @@ function askedOf(fold: PlaceFold): readonly string[] { .map((name) => ((n) => fact(`asked/${name}`, `${n}..${n}`, 'interval', 'count'))(pinnersOf(fold).map(at).filter((names) => names.has(name)).length)) : []; } -/** The place's verdict line as counts: what the fold lands, forks and refuses, each of the object's four states, and the ceilings it meets. */ +/** File-fold readings and their ceilings; this path computes no object encounters. */ function verdictOf(fold: PlaceFold): readonly string[] { - const states = Object.values(verdictsFor(fold)); const named = (line: string): readonly [string, string] => ((cut) => [line.slice(0, cut < 0 ? line.length : cut).trim(), line.slice(cut < 0 ? line.length : cut + 3).trim() || line] as const)(line.indexOf(' · ')); const here = (fold.under ?? '').replace(/\/$/, ''); const others = new Set(here ? placesIn(fold.root).filter((place) => place !== here) : []); @@ -99,7 +96,8 @@ function verdictOf(fold: PlaceFold): readonly string[] { return !others.has(head); }; return ([['claims', fold.claims], ['forks', fold.forks.length + (fold.second.verdict === 'forks' ? 1 : 0)], ['refused', fold.refused.length], ['vacuous', fold.vacuous], ['history', fold.history.length], - ['met', fold.ceilings.read], ['short', fold.ceilings.short.length], ['over', fold.ceilings.over.length], ...STATES.map((one) => [one, states.filter((state) => state === one).length])] as const).map(([name, n]) => fact(`verdict/${name}`, `${n}..${n}`, 'interval', 'count')) + ['met', fold.ceilings.read], ['short', fold.ceilings.short.length], ['over', fold.ceilings.over.length]] as const).map(([name, n]) => fact(`verdict/${name}`, `${n}..${n}`, 'interval', 'count')) + .concat([fact('verdict/computation', 'readings'), fact('verdict/encounters', 'uncomputed')]) .concat(fold.ceilings.short.filter((one) => mine(named(one)[0])).map((one) => (([scope, reading]) => fact(`unpaid/${scope}`, reading))(named(one)))) .concat(fold.ceilings.over.filter((one) => mine(named(one)[0])).map((one) => (([scope, reading]) => fact(`outside/${scope}`, reading))(named(one)))) .concat(fold.ceilings.unread.filter(mine).map((scope) => fact(`unpaid/${scope}`, 'unread'))) diff --git a/src/render/field.ts b/src/render/field.ts index 39e22a3..4a95389 100644 --- a/src/render/field.ts +++ b/src/render/field.ts @@ -5,18 +5,12 @@ import { placedAt } from '../fold/reach.ts'; import { polesOf, rankOf, unpackRegions } from '../fold/region.ts'; import { INTERVALS } from '@lapxo/topos/forms'; -type State = 'CONFLICT' | 'FORBIDDEN' | 'REQUIRED' | 'FREE'; -const WORST: readonly State[] = ['CONFLICT', 'FORBIDDEN', 'REQUIRED', 'FREE']; +type Status = 'disagreement' | 'outside' | 'unanswered' | 'met'; +const WORST: readonly Status[] = ['disagreement', 'outside', 'unanswered', 'met']; const empty = (ceiling: { readonly lo: number; readonly hi: number } | readonly string[] | undefined): boolean => ceiling !== undefined && 'lo' in ceiling && !INTERVALS.inhabited(ceiling); -/** - * The field of a place at resolution N: every bound placed at the place or at none, in the state its poles give, and - * every coordinate cut to its first N steps in the worst state it holds. Interval poles with no value in common - * conflict, as two signers on one key do; an alphabet that permits none is a ceiling like any other. A value read - * outside the poles is forbidden; a bound nothing read, a reader that refused and a demand unpaid are required; the - * rest is free. It is read off the region summaries and the landed readings, and no reader runs. - */ +/** Host file-region readings, grouped by coordinate prefix. These statuses do not compute object encounters. */ export function field(fold: PlaceFold, at: number): readonly string[] { if (fold.regions === undefined) return ['GREY field · this fold carries no region summaries; it is read again at the next fold']; const regions = unpackRegions(fold.regions); @@ -25,16 +19,16 @@ export function field(fold: PlaceFold, at: number): readonly string[] { const here = (line: string): boolean => place === undefined || [place, undefined].includes(placedAt(places, line)); const own = { ...fold.own, unread: fold.ceilings.unread.length + fold.ceilings.vacuous.length }; const poles = new Map>(); - const states: (readonly [string, State])[] = [ + const states: (readonly [string, Status])[] = [ ...regions.bounds.filter((bound) => here(bound.line)).map((bound) => { const ceiling = (poles.get(bound.region) ?? poles.set(bound.region, polesOf(regions, bound.region)).get(bound.region)!).get(`${bound.question} ${bound.measure}`)?.ceiling; const got = rankOf(regions, bound, own); - return [fieldOf(bound.line, 'scope'), empty(ceiling) ? 'CONFLICT' : got.bars || got.sums ? 'FORBIDDEN' : got.met ? 'FREE' : 'REQUIRED'] as const; + return [fieldOf(bound.line, 'scope'), empty(ceiling) ? 'disagreement' : got.bars || got.sums ? 'outside' : got.met ? 'met' : 'unanswered'] as const; }), - ...fold.missing.filter(here).map((line) => [fieldOf(line, 'scope'), 'REQUIRED'] as const), - ...fold.forks.flatMap((fork) => fork.lines.slice(0, 1)).filter(here).map((line) => [fieldOf(line, 'scope'), 'CONFLICT'] as const), + ...fold.missing.filter(here).map((line) => [fieldOf(line, 'scope'), 'unanswered'] as const), + ...fold.forks.flatMap((fork) => fork.lines.slice(0, 1)).filter(here).map((line) => [fieldOf(line, 'scope'), 'disagreement'] as const), ]; - const cells = new Map(); + const cells = new Map(); for (const [scope, state] of states) { const cell = scope.split('/').slice(0, Math.max(1, at)).join('/'); const held = cells.get(cell); @@ -43,7 +37,7 @@ export function field(fold: PlaceFold, at: number): readonly string[] { const ordered = [...cells].sort((a, b) => WORST.indexOf(a[1].state) - WORST.indexOf(b[1].state) || a[0].localeCompare(b[0])); return [ '## field', '', '```', - `FIELD @${at} · ${cells.size} cells · ${states.length} bounds · ${WORST.map((state) => `${state} ${ordered.filter(([, one]) => one.state === state).length}`).join(' · ')}`, + `FIELD @${at} · ${cells.size} groups · ${states.length} bounds · readings · no encounters computed · ${WORST.map((state) => `${state} ${ordered.filter(([, one]) => one.state === state).length}`).join(' · ')}`, ...ordered.map(([cell, one]) => `FIELD ${cell} · ${one.state} · ${one.bounds} bounds`), '```', ]; diff --git a/src/render/names.ts b/src/render/names.ts index c607b84..436d1ef 100644 --- a/src/render/names.ts +++ b/src/render/names.ts @@ -1,6 +1,6 @@ /** The regions bound renders itself, by name: a view that asks any other is answered by a capsule that declares it, or refused whole. */ export const REGION_NAMES = [ - 'receipts', 'help', 'lines', 'red', 'forks', 'programs', 'why', 'sign', 'take', 'history', 'field', + 'receipts', 'help', 'lines', 'red', 'forks', 'programs', 'why', 'sign', 'take', 'history', 'field', 'evidence', ] as const; export type RegionName = (typeof REGION_NAMES)[number]; diff --git a/src/render/view.ts b/src/render/view.ts index d7fd8bb..709e62f 100644 --- a/src/render/view.ts +++ b/src/render/view.ts @@ -8,32 +8,36 @@ import { declaredBy } from '../observe/regions.ts'; import type { RegionName } from './names.ts'; import { readersBehind } from '../fold/observed.ts'; import { LOCK, canonical, matches } from '@lapxo/topos/wire'; -import { STATES } from '@lapxo/obligations'; import type { PlaceFold } from '../cli/place.ts'; import type { View } from '../fold/views.ts'; import { fieldOf, foldClaims, selfName } from '../fold/claims.ts'; import { keepRender, keptRender } from '../fold/kept.ts'; -import { bytesDigest } from '../fold/digests.ts'; -import { writerFor } from '../fold/signers.ts'; +import { bytesDigest, signaturesOf } from '../fold/digests.ts'; +import { authorityFor, rootSigner, writerFor } from '../fold/signers.ts'; import { lockLines } from '../fold/keys.ts'; +import { appliedIn } from '../fold/signed.ts'; +import { ledgerLines } from '../land/ledger.ts'; import { horizonOf, moved, shapeLines } from './shape.ts'; import { rankLines } from '../fold/rank.ts'; import { differing, regionsOf } from '../fold/region.ts'; -import { verdictsFor } from '../fold/paid.ts'; import { field } from './field.ts'; import { helpLines } from '../cli/names.ts'; type Region = (fold: PlaceFold) => readonly string[]; +/** Authenticated delivery history is evidence, not the place's normative standing. */ +const evidence: Region = (fold) => { + const authority = authorityFor(lockLines(fold.store), rootSigner(fold.root), signaturesOf(fold.store).admitted); + const place = (fold.under ?? '').replace(/\/$/, ''); + const deliveries = place ? appliedIn(fold.root, place) + : [...new Set(authority.admitted.flatMap(key => ledgerLines(fold.store, key.id)))]; + return deliveries + .filter(line => authority.of(line).kind === 'admitted'); +}; + const block = (name: string, lines: readonly string[]): readonly string[] => (lines.length ? [`## ${name}`, '', '```', ...lines, '```'] : []); const seconds = (ms: number): string => `${(ms / 1000).toFixed(1)} s`; -const statesOf = (fold: PlaceFold): readonly string[] => { - const held = new Map(); - for (const one of Object.values(verdictsFor(fold))) held.set(one, (held.get(one) ?? 0) + 1); - return STATES.flatMap((one) => (held.get(one) ? [`${one} ${held.get(one)}`] : [])); -}; - const programs: Region = (fold) => { const median = fold.costs.length ? [...fold.costs].sort((a, b) => a - b)[Math.floor(fold.costs.length / 2)] ?? 0 : 0; const turned = moved(fold); @@ -41,12 +45,13 @@ const programs: Region = (fold) => { const refusedByReader = fold.observed.filter((line) => fieldOf(line, 'scope') === 'refuse/reader').length; const c = fold.ceilings; return block('programs', [ - `PROGRAMS${fold.under ? ` ${fold.under}` : ''} ${[`${fold.claims} claims`, ...statesOf(fold), `${fold.history.length} history`].join(' · ')}` + `PROGRAMS${fold.under ? ` ${fold.under}` : ''} ${[`${fold.claims} claims`, `${fold.history.length} history`].join(' · ')}` + ` · ${fold.forks.length + (fold.second.verdict === 'forks' ? 1 : 0)} forks · ${fold.grey.length} grey · ${fold.refused.length} refused · ${fold.vacuous} vacuous` + ` · ${secondName()} ${fold.second.verdict}${fold.second.verdict === 'agrees' && !fold.second.external ? ', never disagreed' : ''}` + ` · store ${fold.observed.length} observed${refusedByReader ? ` · ${refusedByReader} refuse·reader` : ''}` + (fold.under ? ` · ceilings ${c.read} met here · ${c.short.length} short · ${c.over.length} over` : ` · ceilings ${c.read}/${c.total} read · ${c.short.length} short · ${c.over.length} over · ${c.unread.length} unread${c.vacuous.length ? ` · ${c.vacuous.length} vacuous unread` : ''}`) + + ' · readings · no encounters computed' + ` · ${fold.effects} · take ${fold.costs.length ? seconds(fold.costs[fold.costs.length - 1] ?? 0) : 'none'} last` + (fold.costs.length > 1 ? ` · ${seconds(median)} median of ${fold.costs.length}` : '') , @@ -149,6 +154,7 @@ const REGIONS: Readonly> = { receipts: (fold) => receiptRegion(fold, 1), help: () => helpLines(), lines: (fold) => fold.standing, + evidence, red, forks, programs, why, sign, take, history, field: (fold) => field(fold, 3), } satisfies Record; diff --git a/test/act-cost.test.ts b/test/act-cost.test.ts new file mode 100644 index 0000000..9ca46c9 --- /dev/null +++ b/test/act-cost.test.ts @@ -0,0 +1,21 @@ +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {ActCosts} from '../src/host/act-cost.ts'; + +test('separate declared readings do not turn their sum into an indivisible act',()=>{ + let now=0;const cost=new ActCosts(()=>now); + cost.measure(()=>{now+=35000;});cost.measure(()=>{now+=38000;}); + assert.equal(now,73000);assert.equal(cost.seconds(),38); +}); +test('one slow reading, failed readings and unpartitioned host work keep their cost',()=>{ + let now=0;const cost=new ActCosts(()=>now);assert.throws(()=>cost.measure(()=>{now+=73000;throw Error('refused');}),/refused/);assert.equal(cost.seconds(),73); + now+=75000;assert.equal(cost.seconds(),75); +}); +test('nested host execution is charged once without hiding the enclosing reading',()=>{ + let now=0;const cost=new ActCosts(()=>now); + cost.measure(()=>{now+=10000;cost.measure(()=>{now+=20000;});now+=5000;}); + assert.equal(cost.seconds(),35);now+=9000;assert.equal(cost.seconds(),35); +}); +test('an unfinished indivisible act remains measurable',()=>{ + let now=0;const cost=new ActCosts(()=>now),end=cost.begin();now=73000;assert.equal(cost.seconds(),73);end();assert.equal(cost.seconds(),73);assert.throws(end,/closed twice/); +}); diff --git a/test/admission-boundary.test.ts b/test/admission-boundary.test.ts index 9cb5409..435667c 100644 --- a/test/admission-boundary.test.ts +++ b/test/admission-boundary.test.ts @@ -18,6 +18,8 @@ test('a prospective lot uses the consumer authority, preserves bytes, and cannot const seed=[['keys/device','class','authorize'],['keys/device','coverage','*'],['keys/device','public-key',pub],['keys/device','signer','file'],['keys/reader','class','read'],['keys/folder','class','fold'],['signer/timeout','milliseconds','5000..5000','interval'],['signer/response-bytes','bytes','65536..65536','interval'],['wire/digest-algorithms','id','sha256'],['wire/signature-algorithms','id','ed25519:sample'],['wire/era','id','sample'],['wire/families','id','keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|view|region|sample'],['wire/fields','id','scope|role|form|measure|value|by|at|needs|sig|epoch|shape|restsOn|condition|about|kind|view'],['wire/required','id','scope|role|form|measure|value|by|at'],['wire/forms','id','alphabet|interval'],['wire/roles','id','reads|writes|demands'],['wire/at-classes','id','origin|place|receipt|witness|policy']].map(v=>row(...v)); for(const [name,shape] of [['summary',''],['page','summary.md']]) seed.push(canonical({scope:`view/${name}`,role:'demands',form:'alphabet',measure:'id',value:'field@3',shape,at:'policy:sample',by:'target'})); seed.push(canonical({scope:'sample/limit',form:'interval',role:'reads',measure:'count',value:'0..5',at:'policy:sample',by:'target'})); + // This negative attempts to discharge an existing obligation, not declare a new one. + seed.push(canonical({scope:'sample/required',form:'alphabet',role:'demands',measure:'id',value:'present',needs:'missing.txt',at:'policy:sample',by:'target'})); const run=(cwd,args)=>spawnSync(process.execPath,[reader,...args],{cwd,encoding:'utf8',timeout:20000}); const digest=root=>{const all=[];const visit=(dir,base='')=>{for(const n of readdirSync(dir).sort()){const at=join(dir,n),rel=join(base,n);if(statSync(at).isDirectory())visit(at,rel);else all.push([rel,createHash('sha256').update(readFileSync(at)).digest('hex')]);}};visit(root);return all;}; const stamp=(line)=>{const got=parse(line);assert.equal(got.kind,'fact');const fields={...got.value.fields,by:'device',epoch:'2'};return canonical({...fields,sig:formatSignature('ed25519:sample',sign(null,Buffer.from(signedBytes(fields)),pair.privateKey).toString('base64'))});}; @@ -38,7 +40,7 @@ test('a prospective lot uses the consumer authority, preserves bytes, and cannot for(const root of roots){const before=digest(root);for(const args of[['fold',root,'--as','lines',invalid],['land',invalid]]){const p=run(root,args);assert.equal(p.status,1,p.stderr);assert.match(p.stderr,/REFUSE·widening/);assert.deepEqual(digest(root),before);}} for(const fields of [ {scope:'write/src/removed.txt',form:'alphabet',role:'writes',measure:'digest',value:'withdraw',at:'policy:sample',by:'target'}, - {scope:'sample/required',form:'alphabet',role:'demands',measure:'id',value:'present',needs:'missing.txt',at:'policy:sample',by:'target'}, + {scope:'sample/required',form:'alphabet',role:'demands',measure:'id',value:'present',needs:'missing-revision.txt',at:'policy:sample',by:'target'}, ]) { writeFileSync(invalid,stamp(canonical(fields))+'\n'); for(const root of roots){const before=digest(root);for(const args of [['fold',root,'--as','lines',invalid],['land',invalid]]){const p=run(root,args);assert.equal(p.status,1,p.stderr);assert.match(p.stderr,/REFUSE·(?:withdraw|takes)/);assert.deepEqual(digest(root),before,'evidence-based admission refuses identically without acquiring readings');}} diff --git a/test/archive.test.ts b/test/archive.test.ts index 751a9b3..c11a370 100644 --- a/test/archive.test.ts +++ b/test/archive.test.ts @@ -1,3 +1,4 @@ +import {spawn} from 'node:child_process'; import { strict as assert } from 'node:assert'; import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, readdirSync, rmSync, symlinkSync, existsSync } from 'node:fs'; import { tmpdir } from 'node:os'; @@ -194,3 +195,22 @@ test('reading authentic capsule declarations needs no runtime; asking a missing assert.throws(()=>capsuleAt(digest,'../escape.js',root),/REFUSE·capsule .* unavailable/); } finally {rmSync(root,{recursive:true,force:true});} }); + + +test('two processes publish the same verified runtime tree without replacing its winner', async () => { + const root=mkdtempSync(join(tmpdir(),'runtime-publication-')),store=join(root,'store'),barrier=join(root,'barrier'); + try { + mkdirSync(barrier);const bytes=tar(record('dist/member.js','export const value=7;')),digest=sha(bytes);save(store,digest,bytes); + const destination=join(store,'cas/runtime/sha256',digest.slice('sha256:'.length)),helper=join(root,'reader.mjs'); + writeFileSync(helper,`import fs from 'node:fs';import {syncBuiltinESMExports} from 'node:module'; + const [store,digest,destination,barrier]=process.argv.slice(2),rename=fs.renameSync; + fs.renameSync=(from,to)=>{if(to===destination){fs.writeFileSync(barrier+'/'+process.pid,'ready');const deadline=Date.now()+5000;while(fs.readdirSync(barrier).length<2){if(Date.now()>deadline)throw Error('test publication barrier timed out');Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,5);}}return rename(from,to);};syncBuiltinESMExports(); + const {runtimeTreeAt}=await import(${JSON.stringify(new URL('../src/host/release.ts',import.meta.url).href)}); + const at=runtimeTreeAt(store,store,digest,store);console.log(fs.readFileSync(at+'/dist/member.js','utf8')); + `); + const run=()=>new Promise<{status:number|null;out:string;err:string}>((resolve,reject)=>{const child=spawn(process.execPath,[helper,store,digest,destination,barrier],{stdio:['ignore','pipe','pipe']});let out='',err='';child.stdout.on('data',b=>out+=b);child.stderr.on('data',b=>err+=b);child.once('error',reject);child.once('close',status=>resolve({status,out,err}));}); + for(const got of await Promise.all([run(),run()])){assert.equal(got.status,0,got.err);assert.equal(got.out.trim(),'export const value=7;');} + assert.equal(readFileSync(join(destination,'.laid'),'utf8'),digest);assert.equal(readFileSync(join(destination,'dist/member.js'),'utf8'),'export const value=7;'); + assert.deepEqual(readdirSync(join(store,'cas/runtime/sha256')),[digest.slice('sha256:'.length)]); + }finally{rmSync(root,{recursive:true,force:true});} +}); diff --git a/test/capsule-entry.test.ts b/test/capsule-entry.test.ts index 544bf06..11474ab 100644 --- a/test/capsule-entry.test.ts +++ b/test/capsule-entry.test.ts @@ -1,6 +1,6 @@ import { test } from 'node:test'; import { strict as assert } from 'node:assert'; -import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; +import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { gzipSync } from 'node:zlib'; @@ -38,3 +38,14 @@ test('a declared capsule entry runs exactly that member and cannot reuse another assert.deepEqual(chosen.ask([request]),[{protocol:'bound-lock/1',kind:'fact',lines:['chosen']}]); } finally {process.argv[1]=prior;rmSync(store,{recursive:true,force:true});} }); + + +test('render requests retain independent receipts by digest, across another view',()=>{ + const store=mkdtempSync(join(tmpdir(),'capsule-render-reuse-')),prior=process.argv[1];process.argv[1]=new URL('../src/cli/verb.ts',import.meta.url).pathname; + try{ + const calls=join(store,'calls'),module="import{appendFileSync}from'node:fs';export const render=asked=>{appendFileSync("+JSON.stringify(calls)+",'1');return [asked.shape];};"; + const bytes=tar(record('capsule.bound',canonical({scope:'region/prose',role:'render',form:'alphabet',measure:'reads',value:'**',by:'fixture',at:'policy:test'})+'\n'),record('entry.js',module)),digest=sha(bytes);save(store,digest,bytes);const capsule=capsuleAt(digest,'entry.js',store)!; + const ask=(shape:string)=>capsule.ask([{protocol:'bound-lock/1',verb:'render',rootScope:'fixture',region:'prose',files:[],shape}]); + const first=ask('first'),second=ask('second');assert.deepEqual(ask('first'),first);assert.deepEqual(ask('second'),second);assert.equal(readFileSync(calls,'utf8'),'11','an intervening view cannot evict a closed render'); + }finally{process.argv[1]=prior;rmSync(store,{recursive:true,force:true});} +}); diff --git a/test/capsule-failure.test.ts b/test/capsule-failure.test.ts index d26be33..8e0dab5 100644 --- a/test/capsule-failure.test.ts +++ b/test/capsule-failure.test.ts @@ -96,7 +96,7 @@ test('a failed actual capsule ask leaves its answer cache slot absent', async () const sha = (text: string | Uint8Array): string => createHash('sha256').update(text).digest('hex'); const loader = sha(readFileSync(processOf('located', 'host'))); const request = { ...requests[0]!, rootScope: root }; - const slot = sha(`${capsule.digest}\n${loader}\n${request.verb}\n${request.rootScope}\n${request.region ?? ''}`); + const slot = sha(`${capsule.digest}\n${loader}\n${JSON.stringify(request)}`); const cache = join(cacheStore, 'cas', 'answers', slot); equal(existsSync(cache), false); throws(() => capsule.ask([request]), CapsuleProcessError); diff --git a/test/capture.test.ts b/test/capture.test.ts index b4e4a0e..70c400b 100644 --- a/test/capture.test.ts +++ b/test/capture.test.ts @@ -29,6 +29,10 @@ test('host capture retains readings without interpreting their domain', () => { const forked=capture(bytes('5..6'),'water.bound'); assert.match(agreed,/FACT\s+2 standing · 0 forks · water\.bound/); assert.match(forked,/FACT\s+2 standing · 0 forks · water\.bound/); + for (const output of [agreed, forked]) { + assert.match(output, /readings · no encounters computed/); + assert.doesNotMatch(output, /^CELL /m); + } assert.ok(!agreed.includes('meeting')); }); @@ -42,3 +46,17 @@ test('scenario tooling retains the same-signer malformed-history negative contro assert.equal(run.status,1);assert.match(run.stderr,/REFUSE·document/);assert.ok(!run.stdout.includes('CONFLICT')); } finally {rmSync(root,{recursive:true,force:true});} }); + +// A host summary cannot imply object freedom from a missing configuration reading. +test('file field labels its computation without object states', async () => { + const {field}=await import('../src/render/field.ts'); + const root=mkdtempSync(join(tmpdir(),'bound-field-output-')); + try { + const missing=canonical({scope:'requirement/input',role:'demands',form:'alphabet',measure:'status',value:'present',by:'target',at:'policy:sample'}); + const output=field({root,regions:{named:[],bounds:[],summaries:[]},own:{},ceilings:{unread:[],vacuous:[]},missing:[missing],forks:[]} as unknown as import('../src/cli/place.ts').PlaceFold,3).join('\n'); + assert.match(output,/readings · no encounters computed/); + assert.match(output,/requirement\/input · unanswered/); + assert.doesNotMatch(output,/\b(?:REQUIRED|FREE|CONFLICT|FORBIDDEN)\b/); + assert.doesNotMatch(output,/\d+ cells/); + } finally {rmSync(root,{recursive:true,force:true});} +}); diff --git a/test/demand-declaration.test.ts b/test/demand-declaration.test.ts new file mode 100644 index 0000000..bcfdadf --- /dev/null +++ b/test/demand-declaration.test.ts @@ -0,0 +1,25 @@ +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {generateKeyPairSync} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,rmSync,existsSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join} from 'node:path'; +import {spawnSync} from 'node:child_process'; +import {canonical} from '@lapxo/topos/wire'; + +for(const name of ['sowing','calibration'])test(`an admitted new ${name} demand remains owed without invented sources or payment`,()=>{ + const temp=mkdtempSync(join(tmpdir(),'bound-new-demand-')),root=join(temp,'place');mkdirSync(root); + const pair=generateKeyPairSync('ed25519'),key=join(temp,'device.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const row=(scope:string,measure:string,value:string,extra:Record={})=>canonical({scope,measure,value,role:'writes',form:'alphabet',at:'policy:sample',by:'target',...extra}); + const run=(args:string[])=>spawnSync(process.execPath,[new URL('../dist/cli/verb.js',import.meta.url).pathname,...args],{cwd:root,encoding:'utf8',timeout:20000}); + try{ + const seed=[row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/reader','class','read'),row('keys/folder','class','fold'),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'}),row('wire/digest-algorithms','id','sha256'),row('wire/signature-algorithms','id','ed25519:sample'),row('wire/era','id','sample'),row('wire/families','id','keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|requirement|view'),row('wire/fields','id','scope|role|form|measure|value|by|at|epoch|sig|needs|about'),row('wire/required','id','scope|role|form|measure|value|by|at'),row('wire/forms','id','alphabet|interval'),row('wire/roles','id','reads|writes|demands'),row('wire/at-classes','id','policy|origin|place|receipt|witness')]; + writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n');let p=run(['land','--key','device','--key-file',key]);assert.equal(p.status,0,p.stderr); + const proposal=join(temp,'requirement.txt');writeFileSync(proposal,row('requirement/'+name,'status','present',{role:'demands',needs:'missing/'+name+'.json'})+'\n'); + const before=readFileSync(join(root,'.bound/ledger/device.bound'),'utf8');p=run(['sign',proposal,'--key','device','--key-file',key]);assert.equal(p.status,0,p.stderr);assert.equal(readFileSync(join(root,'.bound/ledger/device.bound'),'utf8'),before,'sign is prospective'); + p=run(['land',proposal,'--key','device','--key-file',key]);assert.equal(p.status,0,p.stderr);assert.match(p.stdout,/OWED.*new demand declared/);assert.doesNotMatch(p.stdout,/FACT.*take requirement/);assert.ok(!existsSync(join(root,'missing'))); + const judge=join(root,'.bound/ledger/judge.bound');assert.ok(!existsSync(judge)||!readFileSync(judge,'utf8').includes('scope=requirement/'+name),'no payment receipt'); + const ledger=readFileSync(join(root,'.bound/ledger/device.bound'),'utf8');assert.match(ledger,new RegExp('scope=requirement/'+name)); + writeFileSync(proposal,row('requirement/'+name,'status','present',{role:'demands',needs:'missing/revised.json',at:'witness:revision'})+'\n');p=run(['sign',proposal,'--key','device','--key-file',key]);assert.notEqual(p.status,0,'existing demand revision still needs its witness');assert.equal(readFileSync(join(root,'.bound/ledger/device.bound'),'utf8'),ledger); + }finally{rmSync(temp,{recursive:true,force:true});} +}); diff --git a/test/device-evidence.test.ts b/test/device-evidence.test.ts index 0684832..bfda8ed 100644 --- a/test/device-evidence.test.ts +++ b/test/device-evidence.test.ts @@ -1,36 +1,6 @@ import {test} from 'node:test'; -import assert from 'node:assert/strict'; -import {generateKeyPairSync,verify} from 'node:crypto'; -import {mkdtempSync,mkdirSync,writeFileSync,rmSync} from 'node:fs'; -import {tmpdir} from 'node:os'; -import {join} from 'node:path'; -import {spawnSync} from 'node:child_process'; -import {canonical,parse,signedBytes,parseSignature} from '@lapxo/topos/wire'; +import {runEvidenceSample} from '../tools/samples/run-evidence.mjs'; -for(const keyClass of ['authorize','read','access'])test(`native lines preserve admitted ${keyClass} evidence, exact withdrawals and signature refusals`,()=>{ - const reader=process.env.BOUND_TEST_READER??new URL('../src/cli/verb.ts',import.meta.url).pathname; - const temp=mkdtempSync(join(tmpdir(),'bound-device-evidence-')),root=join(temp,'place'); - const devices=['north','south'].map(id=>({id,pair:generateKeyPairSync('ed25519'),key:join(temp,`${id}.pem`)})); - devices.push({id:'alias',pair:devices[1].pair,key:join(temp,'alias.pem')}); - const row=(scope,measure,value)=>canonical({scope,measure,value,form:'alphabet',role:'writes',at:'policy:evidence',by:'target'}); - const captures=[];const run=args=>{const started=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});captures.push({reader,args:args.map(arg=>arg.endsWith('.pem')?'[ephemeral key path]':arg),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-started});return p;}; - const rows=text=>text.split('\n').map(line=>parse(line)).filter(p=>p.kind==='fact').map(p=>p.value.fields); - try { - mkdirSync(root); - const seed=[row('wire/era','id','sample'),row('wire/signature-algorithms','id','ed25519:sample'),row('wire/digest-algorithms','id','sha256')]; - for(const [name,value] of [['fields','scope|role|form|measure|value|by|at|epoch|sig'],['required','scope|role|form|measure|value|by|at'],['forms','alphabet|interval'],['roles','reads|writes|demands'],['at-classes','policy|place|origin|witness|receipt'],['families','keys|signer|wire|sample|tree|write|leaf|view|reader|read|fold|receipts|rendered|resolved|beat|region']])seed.push(row(`wire/${name}`,'id',value)); - for(const d of devices){writeFileSync(d.key,d.pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600});seed.push(row(`keys/${d.id}`,'class',d.id==='north'?'authorize':keyClass),row(`keys/${d.id}`,'coverage',d.id==='north'?'*':`sample/${d.id}`),row(`keys/${d.id}`,'public-key',d.pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row(`keys/${d.id}`,'signer','file'),canonical({scope:`keys/${d.id}`,role:'writes',form:'interval',measure:'resolution',value:'1..16',by:'target',at:'policy:evidence'}));} - seed.push(canonical({scope:'signer/timeout',form:'interval',measure:'milliseconds',value:'5000..5000',role:'writes',at:'policy:evidence',by:'target'}),canonical({scope:'signer/response-bytes',form:'interval',measure:'bytes',value:'65536..65536',role:'writes',at:'policy:evidence',by:'target'})); - writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n'); - const boot=run(['land','--key','north','--key-file',devices[0].key]);assert.equal(boot.status,0,boot.stderr); - const signed=[]; - for(const d of devices){const lot=join(temp,`${d.id}.proposal`);writeFileSync(lot,row(`sample/${d.id}`,'observed',`evidence-${d.id}`)+'\n');const sign=run(['sign',lot,'--key',d.id,'--key-file',d.key]);assert.equal(sign.status,0,sign.stderr);const text=sign.stdout.split('\n').filter(line=>parse(line).kind==='fact').join('\n')+'\n';signed.push(text);writeFileSync(lot,text);const land=run(['land',lot]);assert.equal(land.status,0,land.stderr);const again=run(['land',lot]);assert.equal(again.status,0,again.stderr);assert.match(again.stdout,/ONCE/);} - const view=run(['fold','--as','lines']);assert.equal(view.status,0,view.stderr); - for(const d of devices){const facts=rows(view.stdout).filter(f=>f.scope===`sample/${d.id}`);assert.equal(facts.length,1);const f=facts[0],sig=parseSignature(f.sig);assert.ok(sig);assert.equal(f.by,d.id);assert.equal(verify(null,Buffer.from(signedBytes(f)),d.pair.publicKey,Buffer.from(sig.raw,'base64')),true);} - const uncovered=join(temp,'uncovered.proposal');writeFileSync(uncovered,row('sample/north','observed','uncovered')+'\n');const denied=run(['sign',uncovered,'--key','south','--key-file',devices[1].key]);assert.equal(denied.status,1);assert.match(denied.stderr,/REFUSE·signer south uncovered/); - const tampered=join(temp,'altered.bound');writeFileSync(tampered,signed[1].replace('evidence-south','altered'));const bad=run(['land',tampered]);assert.equal(bad.status,1);assert.match(bad.stderr,/REFUSE·signed/); - const f=rows(signed[0])[0],{sig,epoch,by,...selector}=f; - const withdraw=join(temp,'withdraw.proposal');writeFileSync(withdraw,canonical({...selector,value:'withdraw',by:'target'})+'\n');const taken=run(['land',withdraw,'--key','north','--key-file',devices[0].key]);assert.equal(taken.status,0,taken.stderr); - const after=run(['fold','--as','lines']);assert.equal(after.status,0,after.stderr);assert.equal(rows(after.stdout).filter(f=>f.scope==='sample/north'&&f.value!=='withdraw').length,0);assert.equal(rows(after.stdout).filter(f=>f.scope==='sample/south').length,1);assert.equal(rows(after.stdout).filter(f=>f.scope==='sample/alias').length,1);assert.deepEqual(devices[1].pair.publicKey.export({type:'spki',format:'der'}),devices[2].pair.publicKey.export({type:'spki',format:'der'})); - }finally {if(process.env.BOUND_TEST_CAPTURE)writeFileSync(process.env.BOUND_TEST_CAPTURE+'.'+keyClass+'.json',JSON.stringify(captures,null,2)+'\n');rmSync(temp,{recursive:true,force:true});} +for(const keyClass of ['authorize','read','access','attest'])test(`native views preserve admitted ${keyClass} evidence, exact withdrawals and signature refusals`,()=>{ + runEvidenceSample(process.env.BOUND_TEST_READER??new URL('../src/cli/verb.ts',import.meta.url).pathname,keyClass,{uncovered:{scope:'sample/north',value:'uncovered'},tamperedValue:'altered'},process.env.BOUND_TEST_CAPTURE?process.env.BOUND_TEST_CAPTURE+'.'+keyClass+'.json':undefined); }); diff --git a/test/ingress-clock.test.ts b/test/ingress-clock.test.ts new file mode 100644 index 0000000..a2cca06 --- /dev/null +++ b/test/ingress-clock.test.ts @@ -0,0 +1,36 @@ +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {createHash,generateKeyPairSync,sign} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,rmSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join} from 'node:path'; +import {spawnSync} from 'node:child_process'; +import {canonical,parse,signedBytes,formatSignature} from '@lapxo/topos/wire'; +import {commitIngress} from '../src/host/ports/ingress.ts'; + +// Host ingress is prepared here; this vector tests the ordinary CLI's local clock, +// not foreign-walk admission or a fabricated native fold observation. +for(const name of ['measurement','artifact'])test(`local signing advances past import receipts, not foreign epochs: ${name}`,async()=>{ + const temp=mkdtempSync(join(tmpdir(),'bound-ingress-clock-')),root=join(temp,'place'),pair=generateKeyPairSync('ed25519'); + const key=join(temp,'device.pem'),reader=process.env.BOUND_TEST_READER??new URL('../src/cli/verb.ts',import.meta.url).pathname; + const row=(scope:string,measure:string,value:string,form='alphabet')=>canonical({scope,measure,value,form,role:'writes',at:'policy:clock',by:'target'}); + const signed=(fields:Record)=>canonical({...fields,sig:formatSignature('ed25519:sample',sign(null,Buffer.from(signedBytes(fields)),pair.privateKey).toString('base64'))}); + const run=(args:string[])=>spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000}); + try{ + mkdirSync(root);writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const seed=[['keys/device','class','authorize'],['keys/device','coverage','*'],['keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')],['keys/device','signer','file'],['keys/reader','class','read'],['signer/timeout','milliseconds','5000..5000','interval'],['signer/response-bytes','bytes','65536..65536','interval'],['wire/digest-algorithms','id','sha256'],['wire/signature-algorithms','id','ed25519:sample'],['wire/era','id','sample'],['wire/families','id','keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|view|region|sample'],['wire/fields','id','scope|role|form|measure|value|by|at|epoch|sig'],['wire/required','id','scope|role|form|measure|value|by|at'],['wire/forms','id','alphabet|interval'],['wire/roles','id','reads|writes|demands'],['wire/at-classes','id','origin|place|receipt|witness|policy']].map(v=>row(v[0],v[1],v[2],v[3])); + writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n'); + const boot=run(['land','--key','device','--key-file',key]);assert.equal(boot.status,0,boot.stderr); + const evidence=signed({scope:`sample/${name}`,role:'writes',form:'alphabet',measure:'id',value:'foreign',at:'origin:remote',by:'remote',epoch:'900'}); + const identity='sha256:'+createHash('sha256').update(evidence).digest('hex'); + const receipt=signed({scope:'receipts',role:'writes',form:'alphabet',measure:'digest',value:identity,at:'receipt:import',by:'device',epoch:'2'}); + await commitIngress(join(root,'.bound'),identity,async()=>({evidence:evidence+'\n',receipt:receipt+'\n'}),bundle=>bundle.receipt===receipt+'\n'&&bundle.evidence===evidence+'\n'); + const proposal=join(temp,'local.proposal');writeFileSync(proposal,row('sample/local','id','local')+'\n'); + const next=run(['sign',proposal,'--key','device','--key-file',key]);assert.equal(next.status,0,next.stderr); + const facts=next.stdout.split('\n').map(parse).filter(p=>p.kind==='fact');assert.equal(facts.length,1);assert.equal(facts[0].value.fields.epoch,'3'); + process.stdout.write('CLOCK foreign 900 unchanged · local import 2 · next local sign 3\n'); + // Corrupting local receipt authentication must prevent further signing. + writeFileSync(join(root,'.bound','ingress','committed-'+encodeURIComponent(identity),'receipt.bound'),receipt.replace('epoch=2','epoch=8')+'\n'); + const refused=run(['sign',proposal,'--key','device','--key-file',key]);assert.notEqual(refused.status,0);assert.match(refused.stderr,/REFUSE·ingress/); + }finally{rmSync(temp,{recursive:true,force:true})} +}); diff --git a/test/instrument-closure.test.ts b/test/instrument-closure.test.ts index ea75b66..3d5b10c 100644 --- a/test/instrument-closure.test.ts +++ b/test/instrument-closure.test.ts @@ -16,7 +16,8 @@ test('implementation identity follows compiled imports, package exports and decl writeFileSync(join(root,'node_modules','fixture-provider','package.json'),'{"type":"module","exports":"./index.js"}'); const provider=join(root,'node_modules','fixture-provider','index.js'); writeFileSync(provider,'export const value=1;\n'); - writeFileSync(join(root,'entry.js'),'import "node:fs"; export {value} from "fixture-provider"; import("./helper.js");\n'); + writeFileSync(join(root,'entry.js'),`import "node:fs"; export {value} from "fixture-provider"; import("./helper.js"); const record={scope: 'receipts/import', role: 'writes'}; const text="import 'missing-string'"; const pattern=/import 'missing-regex'/; // import 'missing-comment' +`); writeFileSync(join(root,'helper.js'),'export const helper=1;\n'); writeFileSync(join(root,'worker.js'),'export const worker=1;\n'); const process=canonical({scope:'process/test',kind:'process',role:'writes',form:'alphabet',measure:'id',value:'present',needs:'worker.js',by:'target',at:'policy:process'}); diff --git a/test/native-walk-refinement.test.ts b/test/native-walk-refinement.test.ts new file mode 100644 index 0000000..dffcaea --- /dev/null +++ b/test/native-walk-refinement.test.ts @@ -0,0 +1,3 @@ +import {test} from 'node:test'; +import {runWalkRefinement} from '../tools/samples/run-walk-refinement.mjs'; +for(const family of ['measurement','artifact'])test('native CLI refines declared regions: '+family,()=>runWalkRefinement(process.env.BOUND_TEST_READER??new URL('../dist/cli/verb.js',import.meta.url).pathname,process.env.BOUND_TEST_CAPTURE,family)); diff --git a/test/native-walk.test.ts b/test/native-walk.test.ts new file mode 100644 index 0000000..470fb0b --- /dev/null +++ b/test/native-walk.test.ts @@ -0,0 +1,3 @@ +import {test} from 'node:test'; +import {runWalkSample} from '../tools/samples/run-walk.mjs'; +for (const family of ['measurement','artifact']) test(`native CLI imports an authenticated regional prefix atomically: ${family}`,()=>runWalkSample(process.env.BOUND_TEST_READER??new URL('../dist/cli/verb.js',import.meta.url).pathname,process.env.BOUND_TEST_CAPTURE,family)); diff --git a/test/nonregional-claims.test.ts b/test/nonregional-claims.test.ts new file mode 100644 index 0000000..1de3038 --- /dev/null +++ b/test/nonregional-claims.test.ts @@ -0,0 +1,15 @@ +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {canonical} from '@lapxo/topos/wire'; +import {foldClaims} from '../src/fold/claims.ts'; + +for(const scope of ['wire/fields','region/proofs'])test(`file receipts never erase nonregional declarations at ${scope}`,()=>{ + const row=(value:string,by:string)=>canonical({scope,role:'writes',form:'alphabet',measure:'id',value,by,at:'policy:declaration',epoch:'1'}); + const lines=[row('left','one'),row('right','two')]; + for(const receipts of [[],[{scope,moved:['unrelated.txt']}], [{scope,moved:[]}]]){ + const got=foldClaims(lines,receipts); + assert.deepEqual(new Set(got.standing),new Set(lines)); + assert.deepEqual(got.vacuous,[],'absence of file regions cannot be evidence of payment'); + } + const single=foldClaims([lines[0]!],[]);assert.deepEqual(single.standing,[lines[0]]); +}); diff --git a/test/pass-receipt-order.test.ts b/test/pass-receipt-order.test.ts new file mode 100644 index 0000000..941f96b --- /dev/null +++ b/test/pass-receipt-order.test.ts @@ -0,0 +1,45 @@ +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {generateKeyPairSync} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,rmSync,cpSync,existsSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join} from 'node:path'; +import {spawnSync} from 'node:child_process'; +import {canonical,publicationOf} from '@lapxo/topos/wire'; +import {foldClaims,isWire} from '../src/fold/claims.ts'; + +for(const name of ['calibration','inventory'])test(`completed ${name} renders seal native file receipts before check; unchanged pass is idle`,()=>{ + const temp=mkdtempSync(join(tmpdir(),'bound-pass-order-')),root=join(temp,name),key=join(temp,'device.pem'); + const reader=process.env.BOUND_TEST_READER??new URL('../dist/cli/verb.js',import.meta.url).pathname; + const pair=generateKeyPairSync('ed25519'); + const row=(scope:string,measure:string,value:string,extra:Record={})=>canonical({scope,measure,value,form:'alphabet',role:'writes',by:'target',at:'policy:pass',...extra}); + const captures:unknown[]=[]; + const run=(args:string[])=>{const p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});captures.push({args,status:p.status,stdout:p.stdout,stderr:p.stderr});return p;}; + const ok=(args:string[])=>{const p=run(args);assert.equal(p.status,0,p.stderr+p.stdout);return p;}; + try{ + mkdirSync(join(root,'src'),{recursive:true});writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const seed=[row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/reader','class','read'),row('keys/folder','class','fold'),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'}),row('wire/era','id','test'),row('wire/signature-algorithms','id','ed25519:test'),row('wire/digest-algorithms','id','sha256')]; + for(const [k,v] of Object.entries({families:'keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|view|region|sample|vector|cost|source|class|pipeline|host|store',fields:'scope|role|form|measure|value|by|at|needs|sig|epoch|shape|restsOn|condition|about|kind|view',required:'scope|role|form|measure|value|by|at',forms:'alphabet|interval',roles:'reads|writes|demands','at-classes':'origin|place|receipt|witness|policy',shapes:'run|input.txt|receipts.bound|src/'+name+'.txt','receipt-fields':'scope|role|form|measure|value|by|at'}))seed.push(row('wire/'+k,'id',v)); + seed.push(row('reader/extent','reader','extent.mjs',{shape:'input.txt',needs:'src/'}),row('view/a-receipts','id','receipts@8|receipts@0|receipts@1',{role:'demands',shape:'receipts.bound',needs:'receipts.bound'}),row('view/z-readout','id','lines@8',{role:'demands',shape:'src/'+name+'.txt',needs:'src/'+name+'.txt'})); + writeFileSync(join(root,'src/input.txt'),name+'\n');writeFileSync(join(root,'extent.mjs'),"export const observe=bytes=>[{name:'sample/extent',bound:{form:'interval',lo:bytes.length,hi:bytes.length}}];");writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n'); + ok(['land','--key','device','--key-file',key]); + writeFileSync(join(root,'src',name+'.txt'),'previous rendered edition\n'); + ok(['fold','--as','a-receipts']); + const first=ok(['fold']);assert.match(first.stdout,/RENDERED .*\.txt/);assert.match(first.stdout,/PASS\s+closed/); + ok(['fold','--check']);const receipt=readFileSync(join(root,'receipts.bound'),'utf8'),output=readFileSync(join(root,'src',name+'.txt'),'utf8'); + const idle=ok(['fold']);assert.match(idle.stderr,/RECEIPTS \d+ read · 0 opened/);assert.match(idle.stdout,/PASS\s+closed/);assert.doesNotMatch(idle.stderr,/OWN\s|CAPSULE .* run|READER\s|OBSERVE\s/,'idle must not reopen providers or readers');assert.equal(readFileSync(join(root,'receipts.bound'),'utf8'),receipt);assert.equal(readFileSync(join(root,'src',name+'.txt'),'utf8'),output); + const publicRoot=join(temp,name+'-public');mkdirSync(publicRoot); + cpSync(join(root,'src'),join(publicRoot,'src'),{recursive:true});cpSync(join(root,'extent.mjs'),join(publicRoot,'extent.mjs')); + const published=publicationOf(foldClaims(readFileSync(join(root,'TARGET.bound'),'utf8').split('\n').filter(isWire)).standing); + writeFileSync(join(publicRoot,'TARGET.bound'),published.join('\n')+'\n');writeFileSync(join(publicRoot,'receipts.bound'),receipt); + const publicCheck=spawnSync(process.execPath,[reader,'fold','--check'],{cwd:publicRoot,encoding:'utf8',timeout:20000}); + captures.push({args:['public-checkout','fold','--check'],status:publicCheck.status,stdout:publicCheck.stdout,stderr:publicCheck.stderr}); + assert.equal(publicCheck.status,0,publicCheck.stderr+publicCheck.stdout);assert.match(publicCheck.stdout,/PASS\s+closed/);assert.match(publicCheck.stderr,/0 opened/); + assert.equal(existsSync(join(publicRoot,'.bound')),false,'public verification writes neither history nor caches'); + writeFileSync(join(publicRoot,'src/input.txt'),'changed public input');const alteredCheck=spawnSync(process.execPath,[reader,'fold','--check'],{cwd:publicRoot,encoding:'utf8',timeout:20000});assert.equal(alteredCheck.status,1);assert.match(alteredCheck.stderr,/REFUSE·check receipts are open/); + const proposal=join(temp,'store-limit.proposal');writeFileSync(proposal,row('store/bytes','bytes','0..1000000000',{form:'interval',role:'reads'})+'\n'); + const signed=ok(['sign',proposal,'--key','device','--key-file',key]);assert.match(signed.stdout,/sig=/);assert.doesNotMatch(signed.stderr,/CAPSULE .* run|READER\s|OBSERVE\s|OWN\s/,'sign consumes the verified completed snapshot without provider work');assert.equal(readFileSync(join(root,'receipts.bound'),'utf8'),receipt); + const unreadProposal=join(temp,'unread-limit.proposal');writeFileSync(unreadProposal,row('sample/unmeasured','count','0..0',{form:'interval',role:'reads'})+'\n');const unread=run(['sign',unreadProposal,'--key','device','--key-file',key]);assert.equal(unread.status,1);assert.match(unread.stderr,/REFUSE·inert/,'a closed snapshot cannot invent a missing reading');assert.equal(readFileSync(join(root,'receipts.bound'),'utf8'),receipt); + writeFileSync(join(root,'src/input.txt'),'tampered measured input\n');const refused=run(['fold','--check']);assert.equal(refused.status,1);assert.match(refused.stderr,/REFUSE·check receipts are open/); + }finally{if(process.env.BOUND_TEST_CAPTURE)writeFileSync(process.env.BOUND_TEST_CAPTURE+'.'+name+'.json',JSON.stringify(captures,null,2)+'\n');rmSync(temp,{recursive:true,force:true});} +}); diff --git a/test/public-receipt-portability.test.ts b/test/public-receipt-portability.test.ts new file mode 100644 index 0000000..170c38c --- /dev/null +++ b/test/public-receipt-portability.test.ts @@ -0,0 +1,60 @@ +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {mkdtempSync,writeFileSync,readFileSync,rmSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {canonical,parse,publicationOf,PROTOCOL} from '@lapxo/topos/wire'; +import {fullDigest} from '../src/host/digest.ts'; +import {carriedFrom,keepCarried} from '../src/fold/resolved.ts'; +import {fileRegionDigest} from '../src/fold/closed.ts'; +import {readingClosures,verifiedReadingReceipts} from '../src/host/reading-closures.ts'; +import type {Capsule} from '../src/host/capsule.ts'; +const digest=(text:string)=>fullDigest(text,'sha256'); +for(const name of ['calibration','conversion'])test(`public native receipts authenticate without a store: ${name}`,()=>{ + const root=mkdtempSync(join(tmpdir(),'bound-public-receipt-'));let calls=0; + try{ + writeFileSync(join(root,'input.txt'),name+'\n'); + const capsule={digest:digest(name),declaration:{regions:{}},lines:[],ask:(requests:any[])=>requests.map(req=>req.verb==='render'?{protocol:PROTOCOL,kind:'fact',lines:[canonical({scope:name,role:'reads',form:'alphabet',measure:'reads',value:'input.txt',at:'receipt:1',by:'world'})]}:(calls++,{protocol:PROTOCOL,kind:'fact',claims:[{scope:'result/'+name,role:'writes',measure:'status',bound:{kind:'enumerated',values:['met']}}]}))} as Capsule; + const options={root,store:join(root,'.bound'),reader:name,speaker:'reader',digest,capsule,region:'reading',projection:'inputs',files:[{place:'input.txt',text:readFileSync(join(root,'input.txt'),'utf8')}]}; + const first=readingClosures(options);assert.equal(first.opened,1); + const copied=first.lines.map(line=>canonical(parse(line).value.fields)); + assert.equal(verifiedReadingReceipts(join(root,'no-store'),copied,digest),1); + const idle=readingClosures(options);assert.equal(idle.opened,0);assert.equal(calls,1);assert.deepEqual(idle.lines,copied); + const corrupt=copied.map(line=>{const f=parse(line).value.fields;return f.measure==='bytes'?canonical({...f,about:f.about+'tampered'}):line;}); + assert.equal(verifiedReadingReceipts(options.store,corrupt,digest),undefined,'valid local CAS cannot hide corrupt shipped bytes'); + const missing=copied.map(line=>{const f=parse(line).value.fields;const {about,...rest}=f;return f.measure==='count'?canonical(rest):line;}); + assert.equal(verifiedReadingReceipts(join(root,'no-store'),missing,digest),undefined,'absence is not verified closure'); + }finally{rmSync(root,{recursive:true,force:true});} +}); +for(const name of ['calibration','inventory'])test(`configuration public projection preserves file seal: ${name}`,()=>{ + const root=mkdtempSync(join(tmpdir(),'bound-public-lock-')); + try{ + const lock=join(root,'TARGET.bound');writeFileSync(join(root,'input.txt'),name); + const row=(epoch:string,sig:string)=>canonical({scope:'name',role:'writes',form:'alphabet',measure:'id',value:name,at:'policy:identity',by:'device',epoch,sig}); + const original=row('2','signature-a');writeFileSync(lock,original+'\n');const before=fileRegionDigest(root,'','receipts/.','sha256'); + writeFileSync(lock,row('7','signature-b')+'\n');assert.equal(fileRegionDigest(root,'','receipts/.','sha256'),before,'delivery envelopes do not enter public file identity'); + writeFileSync(lock,publicationOf([original]).join('\n')+'\n');assert.equal(fileRegionDigest(root,'','receipts/.','sha256'),before); + writeFileSync(lock,canonical({...parse(original).value.fields,value:name+'-changed'})+'\n');assert.notEqual(fileRegionDigest(root,'','receipts/.','sha256'),before,'a live configuration change invalidates the seal'); + writeFileSync(lock,original+'\n');writeFileSync(join(root,'input.txt'),'different bytes');assert.notEqual(fileRegionDigest(root,'','receipts/.','sha256'),before); + }finally{rmSync(root,{recursive:true,force:true});} +}); + +test('a cached authentic carrier cannot hide altered public full-resolution evidence',()=>{ + const root=mkdtempSync(join(tmpdir(),'bound-receipt-carrier-')); + try{ + const body=[canonical({scope:'read/source',role:'writes',form:'alphabet',measure:'status',value:'met',at:'place:source',by:'reader'})]; + const id=keepCarried(root,body),header=canonical({scope:'receipts',role:'writes',form:'alphabet',measure:'digest',value:digest('summary'),at:'place:'+id,by:'bound'}); + assert.deepEqual(carriedFrom(join(root,'empty'),[...body,header]),body); + assert.throws(()=>carriedFrom(root,[body[0].replace('value=met','value=failed'),header]),/REFUSE·receipt public carrier bytes mismatch/); + assert.deepEqual(carriedFrom(root,[header]),body,'a summary-only local view keeps its existing CAS contract'); + }finally{rmSync(root,{recursive:true,force:true});} +}); + +test('signed native receipt evidence is not mistaken for the public carrier header',()=>{ + const root=mkdtempSync(join(tmpdir(),'bound-receipt-evidence-')); + try{ + const body=[canonical({scope:'receipts',role:'writes',form:'alphabet',measure:'digest',value:digest('earlier'),at:'place:'+digest('earlier-body'),by:'device',epoch:'3',sig:'signed-evidence'})]; + const id=keepCarried(root,body),header=canonical({scope:'receipts',role:'writes',form:'alphabet',measure:'digest',value:digest('summary'),at:'place:'+id,by:'bound'}); + assert.deepEqual(carriedFrom(join(root,'empty'),[...body,header]),body); + }finally{rmSync(root,{recursive:true,force:true});} +}); diff --git a/test/reader-completion.test.ts b/test/reader-completion.test.ts index da72489..d764869 100644 --- a/test/reader-completion.test.ts +++ b/test/reader-completion.test.ts @@ -8,7 +8,7 @@ import {spawnSync} from 'node:child_process'; import {canonical} from '@lapxo/topos/wire'; for(const bounded of [false,true])test(`a requested native view waits for its ${bounded?'bounded':'historical'} declared reading and reuses the unchanged answer`,()=>{ - const reader=process.env.BOUND_TEST_READER ?? new URL('../src/cli/verb.ts',import.meta.url).pathname; + const reader=process.env.BOUND_TEST_READER ?? new URL('../dist/cli/verb.js',import.meta.url).pathname; const temp=mkdtempSync(join(tmpdir(),'bound-completion-')),root=join(temp,'place'),pair=generateKeyPairSync('ed25519'); const key=join(temp,'key.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); const row=(scope,measure,value,form='alphabet')=>canonical({scope,measure,value,form,role:'writes',at:'policy:sample',by:'target'}); @@ -31,6 +31,11 @@ for(const bounded of [false,true])test(`a requested native view waits for its ${ const second=run(['fold','--as','evidence']);assert.equal(second.status,0,second.stderr);assert.match(second.stdout,/scope=extent .*value=5\.\.5/);assert.equal(readFileSync(join(root,'calls'),'utf8'),calls);assert.match(second.stderr,/OBSERVE\s+0 run/); writeFileSync(join(root,'src/input.txt'),'changed'); const changed=run(['fold','--as','evidence']);assert.equal(changed.status,0,changed.stderr);assert.match(changed.stdout,/scope=extent .*value=7\.\.7/);assert.equal(readFileSync(join(root,'calls'),'utf8'),calls+'run\n'); + // An operational refusal cannot seal unchanged inputs as a completed fold. + writeFileSync(join(root,'extent.mjs'),"import {existsSync,writeFileSync} from 'node:fs'; export const observe = bytes => {if(!existsSync('attempt')){writeFileSync('attempt','started');throw Error('temporary reader unavailable');}return [{scope:'extent',role:'writes',measure:'bytes',bound:{kind:'interval',lo:bytes.length,hi:bytes.length}}];};"); + const failedPass=run(['fold']);assert.equal(failedPass.status,1,failedPass.stderr);assert.match(failedPass.stderr,/temporary reader unavailable/);assert.doesNotMatch(failedPass.stdout,/PASS\s+closed/); + const recoveredPass=run(['fold']);assert.equal(recoveredPass.status,0,recoveredPass.stderr);assert.doesNotMatch(recoveredPass.stderr,/temporary reader unavailable/); + const recoveredView=run(['fold','--as','evidence']);assert.equal(recoveredView.status,0,recoveredView.stderr);assert.match(recoveredView.stdout,/scope=extent .*value=7\.\.7/); writeFileSync(join(root,'extent.mjs'),"export const observe = () => { throw Error('declared reading refused'); };"); const refused=run(['fold','--as','evidence']);assert.equal(refused.status,1,refused.stderr);assert.match(refused.stderr,/REFUSE·reader .*declared reading refused/);assert.equal(refused.stdout.includes('scope=extent'),false,'no stale result is presented as a completed reading'); if(bounded){ diff --git a/test/reading-closures.test.ts b/test/reading-closures.test.ts new file mode 100644 index 0000000..530d92a --- /dev/null +++ b/test/reading-closures.test.ts @@ -0,0 +1,36 @@ +import {fullDigest} from '../src/host/digest.ts'; +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,rmSync,readdirSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {canonical,PROTOCOL} from '@lapxo/topos/wire'; +import {readingClosures} from '../src/host/reading-closures.ts'; +import type {Capsule} from '../src/host/capsule.ts'; +for(const name of ['specification','conversion'])test('native input closure: '+name,()=>{ + const root=mkdtempSync(join(tmpdir(),'bound-input-closure-')),store=join(root,'.bound'); + try{ + writeFileSync(join(root,'left.txt'),'left');writeFileSync(join(root,'right.txt'),'right');let run=0; + const plan=(scope:string,file:string,needs='',at='receipt:1')=>canonical({scope,role:'reads',form:'alphabet',measure:'reads',value:file,...(needs?{needs}:{}),at,by:'world'}); + let projected=[plan('left','left.txt'),plan('right','right.txt'),plan('summary','left.txt','left|right','receipt:0')]; + const capsule={digest:'sha256:'+'1'.repeat(64),declaration:{regions:{}},lines:[],ask:(requests:any[])=>requests.map(req=>{if(req.verb==='render')return {protocol:PROTOCOL,kind:'fact',lines:projected};run++;return {protocol:PROTOCOL,kind:'fact',claims:[{scope:'seen/'+req.rootScope,role:'reads',measure:'status',bound:{kind:'enumerated',values:['met']}}]};})} as Capsule; + const read=()=>readingClosures({root,store,reader:name,speaker:'reader',digest:text=>fullDigest(text,'sha256'),capsule,region:'reading',projection:'inputs',files:['left.txt','right.txt'].map(place=>({place,text:readFileSync(join(root,place),'utf8')}))}); + const first=read();assert.equal(first.opened,2);assert.equal(run,3);const costs=first.lines.filter(line=>line.includes('measure=s '));assert.equal(costs.length,2);for(const cost of costs){const span=/value=(\d+\.\d+)\.\.(\d+\.\d+)/.exec(cost)!;assert.ok(span);assert.equal(span[1],span[2]);assert.ok(Number(span[1])>=0);}const idle=read();assert.equal(idle.opened,0);assert.equal(run,3);assert.deepEqual(idle.lines.filter(line=>line.includes('measure=s ')),costs,'reuse retains the measured regional cost without measuring a fresh execution'); + writeFileSync(join(root,'left.txt'),'changed');assert.equal(read().opened,1);assert.equal(run,5,'only changed leaf and its dependent reading execute'); + const carried=join(store,'cas','carried');for(const name of readdirSync(carried))writeFileSync(join(carried,name),'corrupt');assert.equal(read().opened,2);assert.equal(run,8,'corrupt authentic carriers recompute'); + const before=run;projected=[plan('left','left.txt','right'),plan('right','right.txt','left')];assert.throws(read,/dependency cycle/);assert.equal(run,before,'cyclic projection refuses before any reading'); + projected=[plan('outside','not-handed')];assert.throws(read,/unhanded/);assert.equal(run,before); + }finally{rmSync(root,{recursive:true,force:true});} +}); + +test('empty readings follow the declared policy and retain native zero-row receipts',()=>{ + const root=mkdtempSync(join(tmpdir(),'bound-empty-closure-'));let calls=0; + try{ + writeFileSync(join(root,'input.txt'),'input'); + const capsule={digest:'sha256:'+'2'.repeat(64),declaration:{regions:{}},lines:[],ask:(requests:any[])=>requests.map(req=>req.verb==='render'?{protocol:PROTOCOL,kind:'fact',lines:[canonical({scope:'empty',role:'reads',form:'alphabet',measure:'reads',value:'input.txt',at:'receipt:1',by:'world'})]}:(calls++,{protocol:PROTOCOL,kind:'fact',claims:[]}))} as Capsule; + const read=(allowsEmpty:boolean)=>readingClosures({root,store:join(root,'.bound'),reader:'reader',speaker:'reader',digest:text=>fullDigest(text,'sha256'),capsule,region:'reading',projection:'inputs',allowsEmpty,files:[{place:'input.txt',text:'input'}]}); + assert.throws(()=>read(false),/empty response is not admitted/); + assert.equal(read(true).opened,1);assert.equal(read(true).opened,0);assert.equal(calls,2); + assert.throws(()=>read(false),/empty response is not admitted/);assert.equal(calls,2,'cached emptiness cannot override the policy'); + }finally{rmSync(root,{recursive:true,force:true});} +}); diff --git a/test/receipt-carrier.test.ts b/test/receipt-carrier.test.ts index 1d787f6..5b814fe 100644 --- a/test/receipt-carrier.test.ts +++ b/test/receipt-carrier.test.ts @@ -66,7 +66,7 @@ test('resolution 8 authenticates an inline carrier in an empty store; summaries const digest='sha256:'+createHash('sha256').update(line+'\n').digest('hex'); assert.deepEqual(carriedFrom(store,[line,rootLine(digest)]),[line]); assert.equal(carriedFrom(store,[rootLine(digest)]),undefined); - assert.equal(carriedFrom(store,[line.replace('place/receipts','other/receipts'),rootLine(digest)]),undefined); + assert.throws(()=>carriedFrom(store,[line.replace('place/receipts','other/receipts'),rootLine(digest)]),/REFUSE·receipt public carrier bytes mismatch/); assert.deepEqual(carriedIn(store),[],'public verification does not manufacture a private carrier'); })); diff --git a/test/signing-port.test.ts b/test/signing-port.test.ts index d1071a0..64b27b0 100644 --- a/test/signing-port.test.ts +++ b/test/signing-port.test.ts @@ -1,35 +1,3 @@ -import {generateKeyPairSync,createHash} from 'node:crypto'; -import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,existsSync,rmSync} from 'node:fs'; -import {tmpdir} from 'node:os';import {join,resolve} from 'node:path';import {spawnSync} from 'node:child_process';import {strict as assert} from 'node:assert'; -import {canonical,parse} from '@lapxo/topos/wire'; import {test} from 'node:test'; -test('declared signing ports are equivalent and CLI refusals are atomic',()=>{ -const reader=process.env.BOUND_TEST_READER??new URL('../src/cli/verb.ts',import.meta.url).pathname,temp=mkdtempSync(join(tmpdir(),'bound-sign-cli-')); -const report={reader,dependency:'Topos 0.1.8 signing-lot/1',runs:[],complete:false}; -const pair=generateKeyPairSync('ed25519'),key=join(temp,'device.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); -const pub=pair.publicKey.export({type:'spki',format:'der'}).toString('base64');const wire=new URL('../node_modules/@lapxo/topos/dist/wire/index.js',import.meta.url).pathname; -const counter=join(temp,'counter'),command=join(temp,'signer.mjs'),registry=join(temp,'bindings.json'); -writeFileSync(command,`import{readFileSync,appendFileSync}from'node:fs';import{sign,createPrivateKey}from'node:crypto';import{parse,canonical,formatSignature}from ${JSON.stringify(wire)};appendFileSync(process.argv[2],'1');const rows=readFileSync(0,'utf8').trimEnd().split('\\n');process.stdout.write(rows.map(bytes=>canonical({by:parse(bytes).value.fields.by,sig:formatSignature('ed25519:fixture',sign(null,Buffer.from(bytes),createPrivateKey(process.env.PORT_TEST_KEY)).toString('base64'))})).join('\\n')+'\\n');`); -const good={kind:'command',executable:process.execPath,args:[command,counter]};writeFileSync(registry,JSON.stringify({local:good})); -function run(root,label,args,expected=0){const p=spawnSync(process.execPath,[reader,...args],{cwd:root,env:{...process.env,BOUND_SIGNERS:registry,PORT_TEST_KEY:pair.privateKey.export({type:'pkcs8',format:'pem'})},encoding:'utf8',timeout:10000});report.runs.push({label,status:p.status,stdout:p.stdout,stderr:p.stderr});assert.equal(p.status,expected,p.stdout+p.stderr);return p;} -const row=(scope,measure,value,form='alphabet')=>canonical({scope,measure,value,form,role:'writes',at:'policy:fixture',by:'target'}); -function seed(root,name){mkdirSync(root);const rows=[['keys/device','class','authorize'],['keys/device','coverage','*'],['keys/device','public-key',pub],['keys/device','signer',name],['signer/timeout','milliseconds','500..500','interval'],['signer/response-bytes','bytes','65536..65536','interval'],['wire/digest-algorithms','id','sha256'],['wire/signature-algorithms','id','ed25519:fixture'],['wire/era','id','fixture'],['wire/families','id','keys|signer|wire|tree|write|leaf|read|fold|receipts|rendered|resolved|beat|view|region|sample'],['wire/fields','id','scope|role|form|measure|value|by|at|needs|sig|epoch|shape|restsOn|condition|about|kind|view'],['wire/required','id','scope|role|form|measure|value|by|at'],['wire/forms','id','alphabet|interval'],['wire/roles','id','reads|writes|demands'],['wire/at-classes','id','origin|place|receipt|witness|policy']];writeFileSync(join(root,'TARGET.bound'),rows.map(v=>row(...v)).join('\n')+'\n');} -const file=join(temp,'file'),remote=join(temp,'command'); -try{seed(file,'file');seed(remote,'local');run(file,'file bootstrap',['land','--key','device','--key-file',key]);run(remote,'command bootstrap',['land','--key','device','--signer','local']); - const draft=join(temp,'lot.proposal');writeFileSync(draft,[row('sample/a','id','yes'),row('sample/b','id','yes')].join('\n')+'\n'); - const f=run(file,'file signs whole lot',['sign','--key','device','--key-file',key,draft]);const before=readFileSync(counter,'utf8').length; - const c=run(remote,'command signs whole lot',['sign','--key','device','--signer','local',draft]);assert.equal(readFileSync(counter,'utf8').length-before,1);const signed=p=>p.stdout.split('\n').filter(l=>parse(l).kind==='fact');assert.deepEqual(signed(f),signed(c)); - const signedFile=join(temp,'signed.proposal');writeFileSync(signedFile,signed(c).join('\n')+'\n');run(file,'file consumer admits signed lot',['land',signedFile]);run(remote,'command consumer admits identical lot',['land',signedFile]); - writeFileSync(draft,[row('sample/failure-a','id','yes'),row('sample/failure-b','id','yes')].join('\n')+'\n'); - const ledger=join(remote,'.bound/ledger/device.bound'),hash=()=>createHash('sha256').update(readFileSync(ledger)).digest('hex'); - const absent=join(temp,'absent');seed(absent,'local');writeFileSync(join(absent,'TARGET.bound'),readFileSync(join(absent,'TARGET.bound'),'utf8').split('\n').filter(l=>!l.includes('measure=signer')).join('\n'));const miss=run(absent,'no declared signer',['land','--signer','local'],1);assert.match(miss.stderr,/missing.*keys\/device/);assert.equal(existsSync(join(absent,'.bound/ledger')),false); - for(const [label,code,pattern]of[['exit',"process.stdout.write('SECRET_OUTPUT');process.stderr.write('SECRET_ERROR');process.exit(7)",/status=7/],['timeout','setInterval(()=>{},100)',/timeout/],['malformed',"process.stdout.write('SECRET_OUTPUT\\n')",/invalid response/],['partial',"process.stdout.write('bound-lock/1 by=device sig=bad\\n')",/invalid response/]]){ - writeFileSync(registry,JSON.stringify({local:{kind:'command',executable:process.execPath,args:['--eval',code]}}));const beforeHash=hash();const p=run(remote,label,['land','--key','device','--signer','local',draft],1);assert.match(p.stderr,pattern);assert.ok(!(p.stdout+p.stderr).includes('SECRET'));assert.equal(hash(),beforeHash); - } - writeFileSync(registry,JSON.stringify({local:good}));run(remote,'selection conflict',['sign','--signer','file',draft],1);run(remote,'retired inert out refuses',['sign','--out','ignored',draft],2); - const invalid=join(temp,'invalid.proposal');writeFileSync(invalid,row('sample/valid','id','yes')+'\n'+row('sample/unknown','id','yes').replace('bound-lock/1','bound-lock/0')+'\n'); - const invalidBefore=hash();const refused=run(remote,'unknown wire row refuses whole lot',['land','--signer','local',invalid],1);assert.match(refused.stderr,/version this reader does not know/);assert.equal(hash(),invalidBefore);assert.equal(refused.stdout,''); - report.complete=true;report.fileCommandIdentical=true;report.oneInvocationPerLot=true;report.failureAtomic=true; -}finally{rmSync(temp,{recursive:true,force:true});} - -}); +import {runSigningSample} from '../tools/samples/run-signing.mjs'; +test('declared signing ports are equivalent and CLI refusals are atomic',()=>{runSigningSample(process.env.BOUND_TEST_READER??new URL('../src/cli/verb.ts',import.meta.url).pathname,{rows:[{scope:'sample/a',measure:'id',value:'yes'},{scope:'sample/b',measure:'id',value:'yes'}]},{unknownVersion:'bound-lock/0'});}); diff --git a/test/typed-publication.test.ts b/test/typed-publication.test.ts new file mode 100644 index 0000000..9d04f3e --- /dev/null +++ b/test/typed-publication.test.ts @@ -0,0 +1,11 @@ +import {test} from 'node:test'; +import {runTypedSample} from '../tools/samples/run-typed.mjs'; + +test('typed sample lands from a new standing closure and prints object states through the installed-compatible CLI',()=>{ + runTypedSample(process.env.BOUND_TEST_READER ?? new URL('../dist/cli/verb.js',import.meta.url).pathname,process.env.BOUND_TEST_CAPTURE); +}); + +test('a repository-artifact place uses the same object contract with a different selected codec',()=>{ + const capture=process.env.BOUND_TEST_CAPTURE?.replace(/\.json$/,'.artifacts.json'); + runTypedSample(process.env.BOUND_TEST_READER ?? new URL('../dist/cli/verb.js',import.meta.url).pathname,capture,'artifacts.json'); +}); diff --git a/test/typed-walk-publication.test.ts b/test/typed-walk-publication.test.ts new file mode 100644 index 0000000..e389fed --- /dev/null +++ b/test/typed-walk-publication.test.ts @@ -0,0 +1,3 @@ +import {test} from 'node:test'; +import {runTypedWalkSample} from '../tools/samples/run-typed-walk.mjs'; +for(const sample of ['yes.json','artifacts.json'])test(`typed foreign history preserves origin-local withdrawals without taking receiver IDs: ${sample}`,()=>runTypedWalkSample(process.env.BOUND_TEST_READER??new URL('../dist/cli/verb.js',import.meta.url).pathname,process.env.BOUND_TEST_CAPTURE,sample)); diff --git a/tools/samples/check-publication.mjs b/tools/samples/check-publication.mjs new file mode 100644 index 0000000..138f5c7 --- /dev/null +++ b/tools/samples/check-publication.mjs @@ -0,0 +1,77 @@ +import {readFileSync} from 'node:fs'; +import {fileURLToPath} from 'node:url'; +import assert from 'node:assert/strict'; +import {runTypedSample} from './run-typed.mjs'; +import {runSigningSample} from './run-signing.mjs'; +import {Worker} from 'node:worker_threads'; +const [profile, yes, no, requestedReader=new URL('../../dist/cli/verb.js',import.meta.url).pathname]=process.argv.slice(2); +const {publicInstrument}=await import('./public-instrument.mjs'); +const instrument=await publicInstrument(requestedReader),reader=instrument.reader; +process.once('exit',()=>instrument.close()); +if(profile==='typed-object') { + const result=runTypedSample(reader,undefined,'yes.json',undefined,{yes,no}); + for(const snapshot of result.snapshots){console.log('SCENE '+snapshot.label);for(const row of snapshot.cells)console.log('CELL '+JSON.stringify(row));} + for(const event of result.events.filter(e=>e.case))console.log('NEGATIVE '+event.case+' '+event.stderr.trim()); +} else if(profile==='evidence'||profile==='native-views') { + const positive=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); + assert.deepEqual(positive.keyClasses,['authorize','read','access','attest']); + assert.equal(typeof negative.uncovered?.scope,'string');assert.equal(typeof negative.tamperedValue,'string'); + const results=await Promise.all(positive.keyClasses.map(keyClass=>new Promise((resolve,reject)=>{ + const worker=new Worker(new URL('./evidence-worker.mjs',import.meta.url),{workerData:{reader,keyClass,negative,options:profile==='native-views'?{lines:positive.lines,views:true}:undefined}}); + let completed=false;worker.once('message',events=>{completed=true;resolve({keyClass,events});});worker.once('error',reject);worker.once('exit',code=>{if(code!==0||!completed)reject(Error('Evidence worker did not complete: '+keyClass+' '+code));}); + }))); + for(const {keyClass,events}of results){console.log('KEY-CLASS '+keyClass);for(const event of events)console.log(event.stdout+event.stderr);} +} else if(profile==='signing') { + const result=runSigningSample(reader,JSON.parse(readFileSync(yes,'utf8')),JSON.parse(readFileSync(no,'utf8'))); + for(const event of result.runs)console.log(event.label+'\n'+event.stdout+event.stderr); + console.log('SIGNING file-command-equivalent; one invocation per lot; atomic refusals'); +} else if(profile==='query-views') { + const {runQueryViews}=await import('./run-query-views.mjs'); + const events=runQueryViews(reader,JSON.parse(readFileSync(yes,'utf8')),JSON.parse(readFileSync(no,'utf8'))); + for(const event of events)console.log(event.stdout+event.stderr); + console.log('QUERY why: two places; exact coordinate; absent OPEN; missing view refused'); +} else if(profile==='prose-views') { + const positive=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); + assert.equal(positive.places.length,2); + const results=await Promise.all(positive.places.map(place=>new Promise((resolve,reject)=>{ + const worker=new Worker(new URL('./prose-worker.mjs',import.meta.url),{workerData:{reader,positive,negative,place:place.name}}); + let received=false;worker.once('message',events=>{received=true;resolve(events);});worker.once('error',reject);worker.once('exit',code=>{if(code!==0||!received)reject(Error('Prose sample worker did not complete: '+place.name+' '+code));}); + }))); + for(const events of results)for(const event of events)console.log(event.stdout+event.stderr); + console.log('PROSE three named views; two places; two exact readings; disagreement refused'); +} else if(profile==='historical-presentation') { + const positive=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); + assert.equal(positive.places.length,2); + const results=await Promise.all(positive.places.map(place=>new Promise((resolve,reject)=>{ + const worker=new Worker(new URL('./historical-presentation-worker.mjs',import.meta.url),{workerData:{reader,positive,negative,place:place.name}}); + let received=false;worker.once('message',events=>{received=true;resolve(events);});worker.once('error',reject);worker.once('exit',code=>{if(code!==0||!received)reject(Error('Historical presentation worker did not complete: '+place.name+' '+code));}); + }))); + for(const events of results)for(const event of events)console.log(event.stdout+event.stderr); + console.log('HISTORICAL explanation and README; two places; exact prose; absent evidence not invented; unoffered view refused'); +} else if(profile==='historical-document-views') { + const positive=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); + assert.equal(positive.places.length,2); + const results=await Promise.all(positive.places.map(place=>new Promise((resolve,reject)=>{ + const worker=new Worker(new URL('./historical-document-worker.mjs',import.meta.url),{workerData:{reader,positive,negative,place:place.name}}); + let received=false;worker.once('message',events=>{received=true;resolve(events);});worker.once('error',reject);worker.once('exit',code=>{if(code!==0||!received)reject(Error('Historical document sample worker did not complete: '+place.name+' '+code));}); + }))); + for(const events of results)for(const event of events)console.log(event.stdout+event.stderr); + console.log('HISTORICAL citation, guide, reference; two places; two exact readings; unoffered view refused'); +} else if(profile==='historical-build') { + const positive=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); + const results=await Promise.all(positive.places.map(place=>new Promise((resolve,reject)=>{ + const worker=new Worker(new URL('./historical-build-worker.mjs',import.meta.url),{workerData:{reader,positive,negative,place:place.name}}); + let received=false;worker.once('message',events=>{received=true;resolve(events);});worker.once('error',reject);worker.once('exit',code=>{if(code!==0||!received)reject(Error('Build sample worker did not complete: '+place.name+' '+code));}); + }))); + for(const events of results)for(const event of events)console.log(event.stdout+event.stderr); + console.log('BUILD two places; exact configuration; two equal readings; unoffered view refused'); +} else if(profile==='program-views') { + const positive=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); + assert.equal(positive.places.length,2); + const results=await Promise.all(positive.places.map(place=>new Promise((resolve,reject)=>{ + const worker=new Worker(new URL('./program-worker.mjs',import.meta.url),{workerData:{reader,positive,negative,place:place.name}}); + let received=false;worker.once('message',events=>{received=true;resolve(events);});worker.once('error',reject);worker.once('exit',code=>{if(code!==0||!received)reject(Error('Program sample worker did not complete: '+place.name+' '+code));}); + }))); + for(const events of results)for(const event of events)console.log(event.stdout+event.stderr); + console.log('PROGRAMS two places; card and programs; two equal readings; unread stays unread; cycle refused'); +} else throw Error('Unknown sample profile: '+profile); diff --git a/tools/samples/check-walk-publication.mjs b/tools/samples/check-walk-publication.mjs new file mode 100644 index 0000000..f19dc5c --- /dev/null +++ b/tools/samples/check-walk-publication.mjs @@ -0,0 +1,21 @@ +import assert from 'node:assert/strict'; +import {readFileSync} from 'node:fs'; +import {Worker} from 'node:worker_threads'; +const [yes,no,reader=new URL('../../dist/cli/verb.js',import.meta.url).pathname]=process.argv.slice(2); +const positive=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); +assert.ok(positive.declarations.length);assert.equal(negative.contract,'whole-region@1'); +const families=['measurement','artifact']; +// Separate event loops keep a sample's synchronous CLI calls from delaying +// another sample's real interruption. Each worker owns its instrument and places. +const results=await Promise.allSettled(families.map(family=>new Promise((resolve,reject)=>{ + const worker=new Worker(new URL('./walk-sample-worker.mjs',import.meta.url),{workerData:{family,reader,positive}}); + let answered=false; + worker.once('message',events=>{answered=true;resolve(events);}); + worker.once('error',reject); + worker.once('exit',code=>{if(!answered)reject(Error('Walk sample exited without evidence: '+code));}); +}))); +for(const [index,result] of results.entries()){ + if(result.status==='rejected')throw result.reason; + console.log('PLACE '+families[index]); + for(const event of result.value)console.log(event.stdout+event.stderr); +} diff --git a/tools/samples/evidence-worker.mjs b/tools/samples/evidence-worker.mjs new file mode 100644 index 0000000..3d75597 --- /dev/null +++ b/tools/samples/evidence-worker.mjs @@ -0,0 +1,4 @@ +import {parentPort,workerData} from 'node:worker_threads'; +import {runEvidenceSample} from './run-evidence.mjs'; +const {reader,keyClass,negative,options}=workerData; +parentPort.postMessage(runEvidenceSample(reader,keyClass,negative,undefined,options)); diff --git a/tools/samples/historical-build-worker.mjs b/tools/samples/historical-build-worker.mjs new file mode 100644 index 0000000..5022876 --- /dev/null +++ b/tools/samples/historical-build-worker.mjs @@ -0,0 +1,3 @@ +import {parentPort,workerData} from 'node:worker_threads'; +import {runHistoricalBuild} from './run-historical-build.mjs'; +parentPort.postMessage(runHistoricalBuild(workerData.reader,workerData.positive,workerData.negative,workerData.place)); diff --git a/tools/samples/historical-document-worker.mjs b/tools/samples/historical-document-worker.mjs new file mode 100644 index 0000000..1d6397c --- /dev/null +++ b/tools/samples/historical-document-worker.mjs @@ -0,0 +1,4 @@ +import {parentPort,workerData} from 'node:worker_threads'; +import {runHistoricalDocumentViews} from './run-historical-document-views.mjs'; +const {reader,positive,negative,place}=workerData; +parentPort.postMessage(runHistoricalDocumentViews(reader,positive,negative,place)); diff --git a/tools/samples/historical-presentation-worker.mjs b/tools/samples/historical-presentation-worker.mjs new file mode 100644 index 0000000..fd119b0 --- /dev/null +++ b/tools/samples/historical-presentation-worker.mjs @@ -0,0 +1,4 @@ +import {parentPort,workerData} from 'node:worker_threads'; +import {runHistoricalPresentationViews} from './run-historical-presentation.mjs'; +const {reader,positive,negative,place}=workerData; +parentPort.postMessage(runHistoricalPresentationViews(reader,positive,negative,place)); diff --git a/tools/samples/module-closure.mjs b/tools/samples/module-closure.mjs new file mode 100644 index 0000000..28b21eb --- /dev/null +++ b/tools/samples/module-closure.mjs @@ -0,0 +1,29 @@ +import {createHash} from 'node:crypto'; +import {readFileSync} from 'node:fs'; +import {createRequire} from 'node:module'; +import {fileURLToPath} from 'node:url'; + +// A sample host adapter: every imported module is an artifact with its own hash. +// Rewriting module specifiers removes installation paths from the offered bytes. +// This is not standing identity; Topos still encodes the folded standing. +export function moduleClosure(entry) { + const complete = new Map(), active = new Set(), blobs = new Map(); + function visit(url) { + const path = fileURLToPath(url); + if (complete.has(path)) return complete.get(path); + if (active.has(path)) throw Error('Sample closure does not support cyclic module imports'); + active.add(path); + const require = createRequire(url); + const text = readFileSync(url, 'utf8').replace(/(\bfrom\s*|\bimport\s*)(['"])([^'"\n]+)\2/g, + (match, prefix, quote, specifier) => { + if (specifier.startsWith('node:')) return match; + const dependency = specifier.startsWith('.') ? new URL(specifier, url) : new URL(`file://${require.resolve(specifier)}`); + return `${prefix}${quote}./${visit(dependency)}${quote}`; + }); + const hex = createHash('sha256').update(text).digest('hex'); + blobs.set(`sha256:${hex}`, text); complete.set(path, hex); active.delete(path); + return hex; + } + const digest = `sha256:${visit(entry)}`; + return {digest, blobs}; +} diff --git a/tools/samples/program-worker.mjs b/tools/samples/program-worker.mjs new file mode 100644 index 0000000..4963573 --- /dev/null +++ b/tools/samples/program-worker.mjs @@ -0,0 +1,4 @@ +import {parentPort,workerData} from 'node:worker_threads'; +import {runProgramViews} from './run-program-views.mjs'; +const {reader,positive,negative,place}=workerData; +parentPort.postMessage(runProgramViews(reader,positive,negative,place)); diff --git a/tools/samples/prose-worker.mjs b/tools/samples/prose-worker.mjs new file mode 100644 index 0000000..cfbfaf8 --- /dev/null +++ b/tools/samples/prose-worker.mjs @@ -0,0 +1,4 @@ +import {parentPort,workerData} from 'node:worker_threads'; +import {runProseViews} from './run-prose-views.mjs'; +const {reader,positive,negative,place}=workerData; +parentPort.postMessage(runProseViews(reader,positive,negative,place)); diff --git a/tools/samples/public-instrument.mjs b/tools/samples/public-instrument.mjs new file mode 100644 index 0000000..734081d --- /dev/null +++ b/tools/samples/public-instrument.mjs @@ -0,0 +1,31 @@ +import {mkdtempSync,mkdirSync,linkSync,readdirSync,renameSync,readFileSync,writeFileSync,existsSync,symlinkSync,rmSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join,dirname} from 'node:path'; +import {pathToFileURL} from 'node:url'; +import {createHash} from 'node:crypto'; +import {publicationOf,parse} from '@lapxo/topos/wire'; + +/** Test the public instrument's standing, not the authorship ledger of the build checkout. + * Dry runs link verified content-addressed implementation bytes; they never copy an instrument tree or node_modules. Library resolution shares installed dependencies for this source conformance vector. + * This is not installed-package acceptance; that witness uses the exact npm archive. + */ +const content=join(tmpdir(),'bound-sample-content'); +function overlay(bytes,to){const hex=createHash('sha256').update(bytes).digest('hex'),from=join(content,hex);mkdirSync(content,{recursive:true});if(!existsSync(from)){const next=from+'.'+process.pid;writeFileSync(next,bytes,{mode:0o444});renameSync(next,from);}if(!readFileSync(from).equals(bytes))throw Error('REFUSE·sample content digest differs '+hex);mkdirSync(dirname(to),{recursive:true});linkSync(from,to);} +function overlayTree(from,to){for(const entry of readdirSync(from,{withFileTypes:true})){const a=join(from,entry.name),b=join(to,entry.name);if(entry.isDirectory())overlayTree(a,b);else if(entry.isFile())overlay(readFileSync(a),b);else throw Error('REFUSE·sample non-file implementation member');}} +export async function publicInstrument(reader) { + const source=dirname(dirname(dirname(reader))),root=mkdtempSync(join(tmpdir(),'bound-public-instrument-')); + try { + const {ownLock,ownStore}=await import(pathToFileURL(join(source,'dist/observe/runner.js')).href); + const published=publicationOf(ownLock()); + overlayTree(join(source,'dist'),join(root,'dist')); + writeFileSync(join(root,'TARGET.bound'),published.join('\n')+'\n'); + overlay(readFileSync(join(source,'package.json')),join(root,'package.json')); + symlinkSync(join(source,'node_modules'),join(root,'node_modules'),'dir'); + const store=join(root,'.bound');mkdirSync(join(store,'ledger'),{recursive:true});mkdirSync(join(store,'cas/blobs'),{recursive:true}); + const wanted=new Set(published.map(parse).filter(p=>p.kind==='fact'&&p.value.fields.scope.startsWith('dep/')&&p.value.fields.value.includes(':')).map(p=>p.value.fields.value)); + for(const digest of wanted){const [algorithm,hex]=digest.split(':');const from=join(ownStore(),'cas/blobs',hex);// Preserve absence: the product CLI still resolves and refuses a missing named dependency if it asks for it. + if(!existsSync(from))continue;const bytes=readFileSync(from);if(createHash(algorithm).update(bytes).digest('hex')!==hex)throw Error('REFUSE·sample instrument blob mismatch '+digest);overlay(bytes,join(store,'cas/blobs',hex));} + const entry=join(root,'dist/cli/verb.js');if(!readFileSync(entry).equals(readFileSync(reader)))throw Error('REFUSE·sample instrument reader bytes differ'); + return {reader:entry,close:()=>rmSync(root,{recursive:true,force:true})}; + }catch(error){rmSync(root,{recursive:true,force:true});throw error;} +} diff --git a/tools/samples/run-archive.mjs b/tools/samples/run-archive.mjs new file mode 100644 index 0000000..9782d98 --- /dev/null +++ b/tools/samples/run-archive.mjs @@ -0,0 +1,41 @@ +import assert from 'node:assert/strict'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,cpSync,rmSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join,resolve} from 'node:path'; +import {createHash} from 'node:crypto'; +import {spawnSync} from 'node:child_process'; +const [yes,no]=process.argv.slice(2); +const profile=JSON.parse(readFileSync(yes,'utf8')),negative=JSON.parse(readFileSync(no,'utf8')); +assert.equal(profile.places.length,2);assert.equal(negative.cause,'digest-mismatch'); +const root=mkdtempSync(join(tmpdir(),'archive-conformance-')); +const hash=bytes=>createHash(profile.algorithm).update(bytes).digest('hex'); +const events=[]; +const run=(program,args,cwd)=>{ + const r=spawnSync(program,args,{cwd,encoding:'utf8',timeout:profile.timeoutMs,maxBuffer:profile.maxBytes}); + events.push({program,args,status:r.status,signal:r.signal,stdout:r.stdout,stderr:r.stderr}); + assert.equal(r.status,0,r.stderr||r.stdout||String(r.error));return r.stdout; +}; +const readVerified=(path,digest)=>{const bytes=readFileSync(path);if(hash(bytes)!==digest)throw Error('REFUSE·artifact digest-mismatch');return bytes;}; +try { + for(const place of profile.places){ + const source=join(root,place.name),consumer=join(root,place.name+'-consumer'),cache=join(root,place.name+'-cache');mkdirSync(source);mkdirSync(consumer); + const manifest={name:place.name,version:place.version,type:'module',files:Object.keys(place.files),bin:{sample:'entry.mjs'}}; + writeFileSync(join(source,'package.json'),JSON.stringify(manifest,null,2)+'\n'); + for(const[path,body]of Object.entries(place.files)){assert.ok(!path.startsWith('/')&&!path.split('/').includes('..'));writeFileSync(join(source,path),body);} + const report=JSON.parse(run(profile.packageProgram,['pack','--ignore-scripts','--json','--cache',cache],source))[0]; + const archive=join(source,report.filename),digest=hash(readFileSync(archive)); + // Both destinations receive this one archive, not another pack invocation. + const destinations=['forge','registry'].map(name=>join(root,place.name+'-'+name+'.tgz')); + for(const destination of destinations){cpSync(archive,destination);readVerified(destination,digest);} + writeFileSync(join(consumer,'package.json'),'{"private":true}\n'); + run(profile.packageProgram,['install','--offline','--ignore-scripts','--no-audit','--no-fund','--cache',cache,resolve(archive)],consumer); + const installed=join(consumer,'node_modules',place.name); + for(const member of report.files){assert.ok(!member.path.startsWith('/')&&!member.path.split('/').includes('..'));assert.ok(readFileSync(join(source,member.path)).equals(readFileSync(join(installed,member.path))),member.path);console.log('MEMBER '+place.name+'/'+member.path+' · '+profile.algorithm+':'+hash(readFileSync(join(installed,member.path))));} + const output=run(process.execPath,[join(installed,'entry.mjs')],consumer);assert.equal(output,place.stdout); + const corrupt=Buffer.from(readFileSync(archive));corrupt[negative.byteOffset]^=1;const refused=join(root,place.name+'-changed.tgz');writeFileSync(refused,corrupt); + assert.throws(()=>readVerified(refused,digest),/REFUSE·artifact digest-mismatch/); + console.log('ARCHIVE '+place.name+' · '+profile.algorithm+':'+digest+' · '+report.files.length+' members equal · one archive, two destinations'); + console.log('INSTALLED '+place.name+' · '+output.trim());console.log('REFUSE·artifact digest-mismatch · '+place.name); + } + console.log('ARTIFACT two unrelated places · installed bytes equal · changed bytes refused'); +} finally {rmSync(root,{recursive:true,force:true});} diff --git a/tools/samples/run-evidence.mjs b/tools/samples/run-evidence.mjs new file mode 100644 index 0000000..9c3c38d --- /dev/null +++ b/tools/samples/run-evidence.mjs @@ -0,0 +1,61 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,verify} from 'node:crypto'; +import {mkdtempSync,mkdirSync,readFileSync,writeFileSync,rmSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join} from 'node:path'; +import {spawnSync} from 'node:child_process'; +import {canonical,parse,signedBytes,parseSignature} from '@lapxo/topos/wire'; + +export function runEvidenceSample(reader, keyClass, negative, capture, options={}) { + const temp=mkdtempSync(join(tmpdir(),'bound-device-evidence-')),root=join(temp,'place'); + const devices=['north','south'].map(id=>({id,pair:generateKeyPairSync('ed25519'),key:join(temp,`${id}.pem`)})); + devices.push({id:'alias',pair:devices[1].pair,key:join(temp,'alias.pem')}); + const row=(scope,measure,value)=>canonical({scope,measure,value,form:'alphabet',role:'writes',at:'policy:evidence',by:'target'}); + const captures=[];const run=args=>{const started=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});captures.push({reader,args:args.map(arg=>arg.endsWith('.pem')?'[ephemeral key path]':arg),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-started});return p;}; + const rows=text=>text.split('\n').map(line=>parse(line)).filter(p=>p.kind==='fact').map(p=>p.value.fields); + try { + mkdirSync(root); + const seed=[row('wire/era','id','sample'),row('wire/signature-algorithms','id','ed25519:sample'),row('wire/digest-algorithms','id','sha256')]; + seed.push(canonical({scope:'view/evidence',role:'demands',form:'alphabet',measure:'id',value:'evidence@8',by:'target',at:'policy:evidence'})); + seed.push(row('keys/local-reader','class','read')); + if(keyClass==='attest'){seed.push(row('keys/local-fold','class','fold'),row('wire/receipt-fields','id','scope|role|form|measure|value|by|at'));if(!options.views)seed.push(canonical({scope:'view/receipts',role:'demands',form:'alphabet',measure:'id',value:'receipts@0',by:'target',at:'policy:evidence'}));} + for(const [name,value] of [['fields','scope|role|form|measure|value|by|at|epoch|sig'],['required','scope|role|form|measure|value|by|at'],['forms','alphabet|interval'],['roles','reads|writes|demands'],['at-classes','policy|place|origin|witness|receipt'],['families','keys|signer|wire|sample|tree|write|leaf|view|reader|read|fold|receipts|rendered|resolved|beat|region']])seed.push(row(`wire/${name}`,'id',value)); + for(const d of devices){writeFileSync(d.key,d.pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600});seed.push(row(`keys/${d.id}`,'class',d.id==='north'?'authorize':keyClass),row(`keys/${d.id}`,'coverage',d.id==='north'?'*':keyClass==='attest'?`sample/${d.id}|receipts`:`sample/${d.id}`),row(`keys/${d.id}`,'public-key',d.pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row(`keys/${d.id}`,'signer','file'),canonical({scope:`keys/${d.id}`,role:'writes',form:'interval',measure:'resolution',value:'1..16',by:'target',at:'policy:evidence'}));} + seed.push(canonical({scope:'signer/timeout',form:'interval',measure:'milliseconds',value:'5000..5000',role:'writes',at:'policy:evidence',by:'target'}),canonical({scope:'signer/response-bytes',form:'interval',measure:'bytes',value:'65536..65536',role:'writes',at:'policy:evidence',by:'target'})); + seed.push(...(options.lines??[])); + writeFileSync(join(root,'TARGET.bound'),[...new Set(seed)].join('\n')+'\n'); + const boot=run(['land','--key','north','--key-file',devices[0].key]);assert.equal(boot.status,0,boot.stderr); + const signed=[]; + for(const d of devices){const lot=join(temp,`${d.id}.proposal`);writeFileSync(lot,row(`sample/${d.id}`,'observed',`evidence-${d.id}`)+'\n');const sign=run(['sign',lot,'--key',d.id,'--key-file',d.key]);assert.equal(sign.status,0,sign.stderr);const text=sign.stdout.split('\n').filter(line=>parse(line).kind==='fact').join('\n')+'\n';signed.push(text);writeFileSync(lot,text);const land=run(['land',lot]);assert.equal(land.status,0,land.stderr);} + // Re-deliver the retained first signed lot after later deliveries: one identity test per key class. + const replay=run(['land',join(temp,devices[0].id+'.proposal')]);assert.equal(replay.status,0,replay.stderr);assert.match(replay.stdout,/ONCE/); + if(keyClass==='authorize'){const summary=run(['fold']);assert.equal(summary.status,0,summary.stderr);assert.match(summary.stdout,/PROGRAMS .*readings · no encounters computed/);assert.doesNotMatch(summary.stdout,/^PROGRAMS .*\b(?:REQUIRED|FREE|CONFLICT|FORBIDDEN) \d+/m,'file summary must not report object states without an object encounter');} + const view=run(['fold','--as',keyClass==='attest'?'evidence':'lines']);assert.equal(view.status,0,view.stderr); + for(const d of devices){const facts=rows(view.stdout).filter(f=>f.scope===`sample/${d.id}`);assert.equal(facts.length,1);const f=facts[0],sig=parseSignature(f.sig);assert.ok(sig);assert.equal(f.by,d.id);assert.equal(verify(null,Buffer.from(signedBytes(f)),d.pair.publicKey,Buffer.from(sig.raw,'base64')),true);} + if(keyClass==='attest'){ + const native=run(['fold','--as','receipts@0']);assert.equal(native.status,0,native.stderr); + const receipt=rows(native.stdout).find(f=>f.scope==='receipts'&&f.measure==='digest');assert.ok(receipt,'native fold supplies the receipt identity'); + const {sig,epoch,by,...body}=receipt; + const file=join(temp,'native-receipt.proposal');writeFileSync(file,canonical({...body,by:'target'})+'\n'); + const signedReceipt=run(['sign',file,'--key','south','--key-file',devices[1].key]);assert.equal(signedReceipt.status,0,signedReceipt.stderr); + writeFileSync(file,signedReceipt.stdout.split('\n').filter(line=>parse(line).kind==='fact').join('\n')+'\n'); + const receiptLand=run(['land',file]);assert.equal(receiptLand.status,0,receiptLand.stderr); + const receiptReplay=run(['land',file]);assert.equal(receiptReplay.status,0,receiptReplay.stderr);assert.match(receiptReplay.stdout,/ONCE/); + const delivered=run(['fold','--as','evidence']);assert.equal(delivered.status,0,delivered.stderr); + const attested=rows(delivered.stdout).find(f=>f.scope==='receipts'&&f.by==='south'&&f.value===receipt.value);assert.ok(attested,'admitted attest receipt is visible by its actual native digest'); + const signature=parseSignature(attested.sig);assert.ok(signature);assert.equal(verify(null,Buffer.from(signedBytes(attested)),devices[1].pair.publicKey,Buffer.from(signature.raw,'base64')),true); + } + if(options.views){ + const help=run(['fold','--as','help']);assert.equal(help.status,0,help.stderr);assert.match(help.stdout,/verbs fold land sign/); + const receipts=run(['fold','--as','receipts']);assert.equal(receipts.status,0,receipts.stderr);assert.ok(rows(receipts.stdout).some(f=>f.scope==='receipts'&&f.measure==='digest'),'native receipt view identifies its actual observed set'); + const missing=run(['fold','--as',negative.missingView]);assert.equal(missing.status,1,missing.stderr);assert.match(missing.stderr,/REFUSE·view/); + } + const uncovered=join(temp,'uncovered.proposal');writeFileSync(uncovered,row(negative.uncovered.scope,'observed',negative.uncovered.value)+'\n');const denied=run(['sign',uncovered,'--key','south','--key-file',devices[1].key]);assert.equal(denied.status,1);assert.match(denied.stderr,/REFUSE·signer south uncovered/); + const tampered=join(temp,'altered.bound');writeFileSync(tampered,signed[1].replace('evidence-south',negative.tamperedValue));const bad=run(['land',tampered]);assert.equal(bad.status,1);assert.match(bad.stderr,/REFUSE·signed/); + const f=rows(signed[0])[0],{sig,epoch,by,...selector}=f; + const withdraw=join(temp,'withdraw.proposal');writeFileSync(withdraw,canonical({...selector,value:'withdraw',by:'target'})+'\n');const taken=run(['land',withdraw,'--key','north','--key-file',devices[0].key]);assert.equal(taken.status,0,taken.stderr); + const after=run(['fold','--as','lines']);assert.equal(after.status,0,after.stderr);assert.equal(rows(after.stdout).filter(f=>f.scope==='sample/north'&&f.value!=='withdraw').length,0);if(keyClass!=='attest'){assert.equal(rows(after.stdout).filter(f=>f.scope==='sample/south').length,1);assert.equal(rows(after.stdout).filter(f=>f.scope==='sample/alias').length,1);}else{assert.equal(rows(after.stdout).filter(f=>f.scope==='sample/south').length,0,'evidence does not become normative standing');}assert.deepEqual(devices[1].pair.publicKey.export({type:'spki',format:'der'}),devices[2].pair.publicKey.export({type:'spki',format:'der'})); + return captures; + }finally {if(capture)writeFileSync(capture,JSON.stringify(captures,null,2)+'\n');rmSync(temp,{recursive:true,force:true});} +} + diff --git a/tools/samples/run-historical-build.mjs b/tools/samples/run-historical-build.mjs new file mode 100644 index 0000000..8f000bf --- /dev/null +++ b/tools/samples/run-historical-build.mjs @@ -0,0 +1,43 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {mkdtempSync,mkdirSync,readFileSync,writeFileSync,rmSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {spawnSync,execFileSync} from 'node:child_process'; +import {canonical} from '@lapxo/topos/wire'; +import {standingBytes} from '@lapxo/topos/standing'; + +/** Byte-fixed historical profile fixture, never a document parser in Bound. */ +export function runHistoricalBuild(reader,positive,negative,selectedPlace) { + const temp=mkdtempSync(join(tmpdir(),'bound-build-')),events=[]; + const sha=b=>'sha256:'+createHash('sha256').update(b).digest('hex'); + const row=(scope,measure,value,extra={})=>canonical({scope,measure,value,form:'alphabet',role:'writes',at:'policy:historical-sample',by:'target',...extra}); + try { + assert.equal(sha(positive.providerSource),positive.providerDigest); + assert.equal(positive.places.length,2); + if(selectedPlace!==undefined)assert.ok(positive.places.some(p=>p.name===selectedPlace)); + const world=join(temp,'provider');mkdirSync(world);writeFileSync(join(world,'index.cjs'),positive.providerSource);writeFileSync(join(world,'package.json'),'{"type":"module"}\n'); + writeFileSync(join(world,'capsule.bound'),positive.regions.map(r=>row('region/'+r.name,'reads',r.reads,{role:'render'})).join('\n')+'\n'); + const archive=join(temp,'profile.tgz');execFileSync('tar',['-czf',archive,'-C',world,'capsule.bound','index.cjs','package.json']);const bytes=readFileSync(archive),artifact=sha(bytes); + const standing=standingBytes([row('region/world','reads','offers/**'),row('offers/document','digest',artifact,{kind:'capsule',restsOn:artifact})]),pin=sha(standing); + for(const place of positive.places.filter(p=>selectedPlace===undefined||p.name===selectedPlace)) { + const root=join(temp,place.name);mkdirSync(root);mkdirSync(join(root,'docs')); + const pair=generateKeyPairSync('ed25519'),key=join(temp,place.name+'.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const seed=positive.wire.map(([n,v])=>row('wire/'+n,'id',v)); + seed.push(row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/device','resolution','1..16',{form:'interval'}),row('keys/reader','class','read'),row('keys/fold','class','fold'),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'}),row('reader/timeout','milliseconds','30000..30000',{form:'interval'}),row('reader/response-bytes','bytes','67108864..67108864',{form:'interval'}),row('reader/inputs','id','required'),row('reader/empty','id','refuse'),row('uses/historical','digest',pin),row('dep/historical','digest',artifact,{shape:'index.cjs'})); + seed.push(...Object.entries(place.options).map(([name,value])=>row('build/'+name,'id',value,{shape:'tsconfig.json'})),row('view/tsconfig','id','build',{role:'demands',shape:'tsconfig.json',needs:'tsconfig.json'})); + writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n');const cas=join(root,'.bound/cas/blobs');mkdirSync(cas,{recursive:true});writeFileSync(join(cas,pin.split(':')[1]),standing);writeFileSync(join(cas,artifact.split(':')[1]),bytes); + const run=args=>{const start=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});events.push({place:place.name,args:args.map(a=>a===key?'[ephemeral key]':a),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-start});return p;}; + const boot=run(['land','--key','device','--key-file',key]);assert.equal(boot.status,0,boot.stderr); + const expected={compilerOptions:Object.fromEntries(Object.entries(place.options).filter(([n])=>n!=='include').map(([n,v])=>[n,v==='true'?true:v==='false'?false:v])),include:place.options.include.split('|')}; + let first; + for(let reading=0;reading<2;reading++){ + const answer=run(['fold','--as','tsconfig']);assert.equal(answer.status,0,answer.stderr); + const bytes=readFileSync(join(root,'tsconfig.json'),'utf8');assert.deepEqual(JSON.parse(bytes),expected); + if(first){assert.equal(bytes,first.bytes);assert.equal(answer.stdout,first.stdout);}else first={bytes,stdout:answer.stdout}; + } + const missing=join(temp,place.name+'-missing.proposal');writeFileSync(missing,row('view/'+negative.view,'id',negative.region,{role:'demands'})+'\n');const admitted=run(['land',missing,'--key','device','--key-file',key]);assert.equal(admitted.status,0,admitted.stderr);const refused=run(['fold','--as',negative.view]);assert.equal(refused.status,1,refused.stderr);assert.match(refused.stderr,/REFUSE·view/);assert.ok(refused.stderr.includes(negative.view)); + } + return events; + } finally {rmSync(temp,{recursive:true,force:true});} +} diff --git a/tools/samples/run-historical-document-views.mjs b/tools/samples/run-historical-document-views.mjs new file mode 100644 index 0000000..c577cfe --- /dev/null +++ b/tools/samples/run-historical-document-views.mjs @@ -0,0 +1,56 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {mkdtempSync,mkdirSync,readFileSync,writeFileSync,rmSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {spawnSync,execFileSync} from 'node:child_process'; +import {canonical} from '@lapxo/topos/wire'; +import {standingBytes} from '@lapxo/topos/standing'; + +/** Byte-fixed historical profile fixture, never a document parser in Bound. */ +export function runHistoricalDocumentViews(reader,positive,negative,selectedPlace) { + const temp=mkdtempSync(join(tmpdir(),'bound-historical-')),events=[]; + const sha=b=>'sha256:'+createHash('sha256').update(b).digest('hex'); + const row=(scope,measure,value,extra={})=>canonical({scope,measure,value,form:'alphabet',role:'writes',at:'policy:historical-sample',by:'target',...extra}); + try { + assert.equal(sha(positive.providerSource),positive.providerDigest); + assert.equal(positive.places.length,2); + if(selectedPlace!==undefined)assert.ok(positive.places.some(p=>p.name===selectedPlace)); + const world=join(temp,'provider');mkdirSync(world);writeFileSync(join(world,'index.mjs'),positive.providerSource);writeFileSync(join(world,'package.json'),'{"type":"module"}\n'); + writeFileSync(join(world,'capsule.bound'),positive.regions.map(r=>row('region/'+r.name,'reads',r.reads,{role:'render'})).join('\n')+'\n'); + const archive=join(temp,'profile.tgz');execFileSync('tar',['-czf',archive,'-C',world,'capsule.bound','index.mjs','package.json']);const bytes=readFileSync(archive),artifact=sha(bytes); + const build=positive.buildProvider;assert.equal(sha(build.providerSource),build.providerDigest); + const buildWorld=join(temp,'build-provider');mkdirSync(buildWorld);writeFileSync(join(buildWorld,'index.cjs'),build.providerSource);writeFileSync(join(buildWorld,'package.json'),'{"type":"commonjs"}\n'); + writeFileSync(join(buildWorld,'capsule.bound'),build.regions.map(r=>row('region/'+r.name,'reads',r.reads,{role:'render'})).join('\n')+'\n'); + const buildArchive=join(temp,'build.tgz');execFileSync('tar',['-czf',buildArchive,'-C',buildWorld,'capsule.bound','index.cjs','package.json']);const buildBytes=readFileSync(buildArchive),buildArtifact=sha(buildBytes); + const prose=positive.proseProvider;assert.equal(sha(prose.providerSource),prose.providerDigest);const proseWorld=join(temp,'prose-provider');mkdirSync(proseWorld);writeFileSync(join(proseWorld,'provider.mjs'),prose.providerSource);writeFileSync(join(proseWorld,'package.json'),'\x7b"type":"module"\x7d\n');writeFileSync(join(proseWorld,'capsule.bound'),row('region/text','reads','prose/**',{role:'render'})+'\n');const proseArchive=join(temp,'prose.tgz');execFileSync('tar',['-czf',proseArchive,'-C',proseWorld,'capsule.bound','provider.mjs','package.json']);const proseBytes=readFileSync(proseArchive),proseArtifact=sha(proseBytes); + const standing=standingBytes([row('region/world','reads','offers/**'),row('offers/document','digest',artifact,{kind:'capsule',restsOn:artifact}),row('offers/build','digest',buildArtifact,{kind:'capsule',restsOn:buildArtifact}),row('offers/prose','digest',proseArtifact,{kind:'capsule',restsOn:proseArtifact})]),pin=sha(standing); + for(const place of positive.places.filter(p=>selectedPlace===undefined||p.name===selectedPlace)) { + const root=join(temp,place.name);mkdirSync(root);mkdirSync(join(root,'docs')); + const pair=generateKeyPairSync('ed25519'),key=join(temp,place.name+'.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const seed=positive.wire.map(([n,v])=>row('wire/'+n,'id',v)); + seed.push(row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/device','resolution','1..16',{form:'interval'}),row('keys/reader','class','read'),row('keys/fold','class','fold'),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'}),row('reader/timeout','milliseconds','30000..30000',{form:'interval'}),row('reader/response-bytes','bytes','67108864..67108864',{form:'interval'}),row('reader/inputs','id','required'),row('reader/empty','id','refuse'),row('uses/historical','digest',pin),row('dep/historical','digest',artifact,{shape:'index.mjs'})); + seed.push(row('dep/build','digest',buildArtifact,{shape:'index.cjs'}),...Object.entries(place.buildOptions).map(([name,value])=>row('build/'+name,'id',value,{shape:'tsconfig.json'})),row('view/tsconfig','id','build',{role:'demands',shape:'tsconfig.json',needs:'tsconfig.json'})); + seed.push(row('name','id',place.name),row('version','id',place.version),row('license','id','MIT'),row('lang','id','en'),row('form/page/statement','id','3'),row('form/template/cff/name','id','name'),row('prose/en/cff/name','text','lock',{about:'Cite {name}.'}),row('term/item','id',place.term,{about:place.meaning}),row('page/seq/heading','text','lock',{about:place.heading}),...place.steps.map((step,i)=>row('page/seq/step-'+i,'text','lock',{about:step})),row('view/citation-file','id','cff@3',{role:'demands',shape:'CITATION.cff',needs:'CITATION.cff'}),row('view/guide','id','seq@3',{role:'demands',shape:'docs/guide.md',needs:'docs/guide.md'}),row('view/reference','id','term@3|set@3|ref@3',{role:'demands',shape:'docs/reference.md',needs:'docs/reference.md'})); + seed.push(row('form/prose/en/sentence','id','capital|period'),row('docs/tagline','text','lock',{about:place.tagline}),row('prose/en/idea/heading','text','lock',{about:place.ideaHeading}),row('prose/en/idea','text','lock',{about:place.idea}),row('view/explanation','id','idea|what-holds|refuses',{role:'demands',shape:'docs/why.md',needs:'docs/why.md'}),row('view/readme-historical','id','hero@3|commands@3|idea@3',{role:'demands',shape:'README.md',needs:'README.md'})); + seed.push(row('dep/prose','digest',proseArtifact,{shape:'provider.mjs'}));for(const output of place.outputs)seed.push(row('prose/'+output.view,'text','lock',{shape:output.path,about:output.body}),row('view/'+output.view,'id','text@3',{role:'demands',shape:output.path,needs:output.path})); + writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n');const cas=join(root,'.bound/cas/blobs');mkdirSync(cas,{recursive:true});writeFileSync(join(cas,pin.split(':')[1]),standing);writeFileSync(join(cas,artifact.split(':')[1]),bytes);writeFileSync(join(cas,buildArtifact.split(':')[1]),buildBytes);writeFileSync(join(cas,proseArtifact.split(':')[1]),proseBytes); + const run=args=>{const start=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});events.push({place:place.name,args:args.map(a=>a===key?'[ephemeral key]':a),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-start});return p;}; + const boot=run(['land','--key','device','--key-file',key]);assert.equal(boot.status,0,boot.stderr); + const first=run(['fold']);assert.equal(first.status,0,first.stderr);const before=new Map(['CITATION.cff','docs/guide.md','docs/reference.md','tsconfig.json','docs/why.md','README.md',...place.outputs.map(o=>o.path)].map(path=>[path,readFileSync(join(root,path),'utf8')]));const second=run(['fold']);assert.equal(second.status,0,second.stderr);assert.match(second.stdout,/9 renders · 9 same/);for(const [path,body]of before)assert.equal(readFileSync(join(root,path),'utf8'),body); + const expected={'citation-file':`cff-version: 1.2.0\nmessage: "Cite ${place.name}."\ntype: software\ntitle: "${place.name}"\nversion: "${place.version}"\nlicense: "MIT"\n`,'guide':`## ${place.heading}\n\n${place.steps.map((s,i)=>`${i+1}. ${s}`).join('\n')}\n`}; + for(const [view,path]of [['citation-file','CITATION.cff'],['guide','docs/guide.md'],['reference','docs/reference.md']]) { + const a=run(['fold','--as',view]);assert.equal(a.status,0,a.stderr);const rendered=readFileSync(join(root,path),'utf8'); + if(expected[view]!==undefined)assert.equal(rendered,expected[view]);else {assert.ok(rendered.includes(`**${place.term}** — ${place.meaning}`));assert.match(rendered,/\| pin \| historical \|/);assert.match(rendered,/\[guide\]\(guide.md\)/);} + } + const buildExpected={compilerOptions:Object.fromEntries(Object.entries(place.buildOptions).filter(([n])=>n!=='include').map(([n,v])=>[n,v==='true'?true:v==='false'?false:v])),include:place.buildOptions.include.split('|')}; + const buildFirst=run(['fold','--as','tsconfig']);assert.equal(buildFirst.status,0,buildFirst.stderr);const buildText=readFileSync(join(root,'tsconfig.json'),'utf8');assert.deepEqual(JSON.parse(buildText),buildExpected); + assert.equal(readFileSync(join(root,'tsconfig.json'),'utf8'),before.get('tsconfig.json')); + const why=`## ${place.ideaHeading}\n\n${place.idea}\n`;assert.equal(readFileSync(join(root,'docs/why.md'),'utf8'),why);const readme=readFileSync(join(root,'README.md'),'utf8');assert.equal(readme.trim().split(/\n+/).join('\n'),`# ${place.name}\n${place.tagline}\n## ${place.ideaHeading}\n${place.idea}`);for(const [view,path]of [['explanation','docs/why.md'],['readme-historical','README.md']]){const got=run(['fold','--as',view]);assert.equal(got.status,0,got.stderr);assert.equal(readFileSync(join(root,path),'utf8'),before.get(path));} + for(const output of place.outputs)assert.equal(readFileSync(join(root,output.path),'utf8'),output.body); + const missing=join(temp,place.name+'-missing.proposal');writeFileSync(missing,row('view/'+negative.view,'id',negative.region,{role:'demands'})+'\n');const admitted=run(['land',missing,'--key','device','--key-file',key]);assert.equal(admitted.status,0,admitted.stderr);const refused=run(['fold','--as',negative.view]);assert.equal(refused.status,1,refused.stderr);assert.match(refused.stderr,/REFUSE·view/);assert.ok(refused.stderr.includes(negative.view)); const conflict=negative.conflict,disagreement=join(temp,place.name+'-disagreement.proposal');writeFileSync(disagreement,[...conflict.bodies.map((body,i)=>row('prose/disagreement-'+i,'text','lock',{shape:conflict.path,about:body})),row('view/disagreement','id','text@3',{role:'demands',shape:conflict.path,needs:conflict.path})].join('\n')+'\n');const conflictLand=run(['land',disagreement,'--key','device','--key-file',key]);assert.equal(conflictLand.status,0,conflictLand.stderr);const conflictFold=run(['fold','--as','disagreement']);assert.equal(conflictFold.status,1,conflictFold.stderr);assert.match(conflictFold.stderr,/REFUSE·view conflicting prose/);for(const [path,body]of before)assert.equal(readFileSync(join(root,path),'utf8'),body); + + } + return events; + } catch(error){const last=events.at(-1);if(last)process.stderr.write('SAMPLE failure '+JSON.stringify(last)+'\n');throw error;}finally{rmSync(temp,{recursive:true,force:true});} +} diff --git a/tools/samples/run-historical-presentation.mjs b/tools/samples/run-historical-presentation.mjs new file mode 100644 index 0000000..68431f1 --- /dev/null +++ b/tools/samples/run-historical-presentation.mjs @@ -0,0 +1,41 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {mkdtempSync,mkdirSync,readFileSync,writeFileSync,rmSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {spawnSync,execFileSync} from 'node:child_process'; +import {canonical} from '@lapxo/topos/wire'; +import {standingBytes} from '@lapxo/topos/standing'; + +/** Byte-fixed historical profile fixture, never a document parser in Bound. */ +export function runHistoricalPresentationViews(reader,positive,negative,selectedPlace) { + const temp=mkdtempSync(join(tmpdir(),'bound-historical-')),events=[]; + const sha=b=>'sha256:'+createHash('sha256').update(b).digest('hex'); + const row=(scope,measure,value,extra={})=>canonical({scope,measure,value,form:'alphabet',role:'writes',at:'policy:historical-sample',by:'target',...extra}); + try { + assert.equal(sha(positive.providerSource),positive.providerDigest); + assert.equal(positive.places.length,2); + if(selectedPlace!==undefined)assert.ok(positive.places.some(p=>p.name===selectedPlace)); + const world=join(temp,'provider');mkdirSync(world);writeFileSync(join(world,'index.mjs'),positive.providerSource);writeFileSync(join(world,'package.json'),'{"type":"module"}\n'); + writeFileSync(join(world,'capsule.bound'),positive.regions.map(r=>row('region/'+r.name,'reads',r.reads,{role:'render'})).join('\n')+'\n'); + const archive=join(temp,'profile.tgz');execFileSync('tar',['-czf',archive,'-C',world,'capsule.bound','index.mjs','package.json']);const bytes=readFileSync(archive),artifact=sha(bytes); + const standing=standingBytes([row('region/world','reads','offers/**'),row('offers/document','digest',artifact,{kind:'capsule',restsOn:artifact})]),pin=sha(standing); + for(const place of positive.places.filter(p=>selectedPlace===undefined||p.name===selectedPlace)) { + const root=join(temp,place.name);mkdirSync(root);mkdirSync(join(root,'docs')); + const pair=generateKeyPairSync('ed25519'),key=join(temp,place.name+'.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const seed=positive.wire.map(([n,v])=>row('wire/'+n,'id',v)); + seed.push(row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/device','resolution','1..16',{form:'interval'}),row('keys/reader','class','read'),row('keys/fold','class','fold'),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'}),row('reader/timeout','milliseconds','30000..30000',{form:'interval'}),row('reader/response-bytes','bytes','67108864..67108864',{form:'interval'}),row('reader/inputs','id','required'),row('reader/empty','id','refuse'),row('uses/historical','digest',pin),row('dep/historical','digest',artifact,{shape:'index.mjs'})); + seed.push(row('name','id',place.name),row('lang','id','en'),row('form/page/statement','id','3'),row('form/prose/en/sentence','id','capital|period'),row('docs/tagline','text','lock',{about:place.tagline}),row('prose/en/idea/heading','text','lock',{about:place.heading}),row('prose/en/idea','text','lock',{about:place.idea}),row('view/explanation','id','idea|what-holds|refuses',{role:'demands',shape:'docs/why.md',needs:'docs/why.md'}),row('view/readme-historical','id','hero@3|commands@3|idea@3',{role:'demands',shape:'README.md',needs:'README.md'})); + writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n');const cas=join(root,'.bound/cas/blobs');mkdirSync(cas,{recursive:true});writeFileSync(join(cas,pin.split(':')[1]),standing);writeFileSync(join(cas,artifact.split(':')[1]),bytes); + const run=args=>{const start=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});events.push({place:place.name,args:args.map(a=>a===key?'[ephemeral key]':a),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-start});return p;}; + const boot=run(['land','--key','device','--key-file',key]);assert.equal(boot.status,0,boot.stderr); + const why=`## ${place.heading}\n\n${place.idea}\n`; + const first=run(['fold']);assert.equal(first.status,0,first.stderr);const before=new Map(['docs/why.md','README.md'].map(path=>[path,readFileSync(join(root,path),'utf8')]));const second=run(['fold']);assert.equal(second.status,0,second.stderr);assert.match(second.stdout,/2 renders · 2 same/);for(const [path,body]of before)assert.equal(readFileSync(join(root,path),'utf8'),body); + assert.equal(readFileSync(join(root,'docs/why.md'),'utf8'),why); + const readme=readFileSync(join(root,'README.md'),'utf8');assert.equal(readme.trim().split(/\n+/).join('\n'),`# ${place.name}\n${place.tagline}\n## ${place.heading}\n${place.idea}`); + for(const [view,path,body]of [['explanation','docs/why.md',why],['readme-historical','README.md',readme]]){const got=run(['fold','--as',view]);assert.equal(got.status,0,got.stderr);assert.equal(readFileSync(join(root,path),'utf8'),body);} + const missing=join(temp,place.name+'-missing.proposal');writeFileSync(missing,row('view/'+negative.view,'id',negative.region,{role:'demands'})+'\n');const admitted=run(['land',missing,'--key','device','--key-file',key]);assert.equal(admitted.status,0,admitted.stderr);const refused=run(['fold','--as',negative.view]);assert.equal(refused.status,1,refused.stderr);assert.match(refused.stderr,/REFUSE·view/);assert.ok(refused.stderr.includes(negative.view)); + } + return events; + } finally {rmSync(temp,{recursive:true,force:true});} +} diff --git a/tools/samples/run-program-views.mjs b/tools/samples/run-program-views.mjs new file mode 100644 index 0000000..73bd066 --- /dev/null +++ b/tools/samples/run-program-views.mjs @@ -0,0 +1,52 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {mkdtempSync,mkdirSync,readFileSync,writeFileSync,rmSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {fileURLToPath} from 'node:url'; +import {spawnSync,execFileSync} from 'node:child_process'; +import {canonical} from '@lapxo/topos/wire'; +import {standingBytes} from '@lapxo/topos/standing'; +import {moduleClosure} from './module-closure.mjs'; + +/** The selected SDK projects declared demands; this sample implements no program algebra. */ +export function runProgramViews(reader,positive,negative,selectedPlace) { + const temp=mkdtempSync(join(tmpdir(),'bound-program-sample-')),events=[]; + const digest=b=>'sha256:'+createHash('sha256').update(b).digest('hex'); + const row=(scope,measure,value,more={})=>canonical({scope,measure,value,role:'writes',form:'alphabet',by:'target',at:'policy:sample',...more}); + try { + const sdk=new URL(positive.providerMember,new URL('./',import.meta.resolve('@lapxo/topos/package.json'))); + assert.equal(digest(readFileSync(sdk)),positive.providerDigest,'published provider member must match its named bytes'); + const world=join(temp,'provider');mkdirSync(world); + const wrapper=join(world,'entry.mjs');writeFileSync(wrapper,`import {renderPrograms} from ${JSON.stringify(fileURLToPath(sdk))};export const render=asked=>renderPrograms(asked);`); + const closure=moduleClosure(new URL('file://'+wrapper)); + for(const[d,b]of closure.blobs)writeFileSync(join(world,d.split(':')[1]),b); + writeFileSync(join(world,'package.json'),'{"type":"module"}\n'); + writeFileSync(join(world,'capsule.bound'),['demand-status','demand-card'].map(n=>row('region/'+n,'reads','**|region/proofs',{role:'render'})).join('\n')+'\n'); + const archive=join(temp,'provider.tgz');execFileSync('tar',['-czf',archive,'-C',world,'capsule.bound','package.json',...[...closure.blobs.keys()].map(d=>d.split(':')[1])]);const bytes=readFileSync(archive),artifact=digest(bytes); + const selectors={profile:'admitted-demands@1',selection:'tasks/selection',minimum:'tasks/minimum',evidence:'proofs',elapsed:'clock/elapsed',ceiling:'clock/ceiling'}; + const standing=standingBytes([row('region/world','reads','wire/**|offers/**'),row('wire/provider-inputs','id','standing-projection@1'),...Object.entries(selectors).map(([n,v])=>row('wire/programs/'+n,'id',v)),row('offers/programs','digest',artifact,{kind:'capsule',restsOn:artifact}),...['demand-status','demand-card'].map(n=>row('offers/programs/inputs/'+n,'reads','wire/programs/**',{role:'demands'}))]),pin=digest(standing); + assert.equal(positive.places.length,2); + if(selectedPlace!==undefined)assert.ok(positive.places.some(p=>p.name===selectedPlace)); + for(const place of positive.places.filter(p=>selectedPlace===undefined||p.name===selectedPlace)){ + const root=join(temp,place.name);mkdirSync(root);const pair=generateKeyPairSync('ed25519'),key=join(temp,place.name+'.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const [first,last]=place.steps; + const seed=positive.wire.map(([n,v])=>row('wire/'+n,'id',v)); + seed.push(row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/device','resolution','1..16',{form:'interval'}),row('keys/reader','class','read'),row('keys/fold','class','fold'),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'}),row('reader/timeout','milliseconds','30000..30000',{form:'interval'}),row('reader/response-bytes','bytes','67108864..67108864',{form:'interval'}),row('reader/inputs','id','required'),row('reader/empty','id','refuse'),row('uses/programs','digest',pin),row('dep/programs','digest',artifact,{shape:closure.digest.split(':')[1]}),row('view/programs','id','demand-status@8',{role:'demands'}),row('view/card','id','demand-card@8',{role:'demands'}),row('region/proofs','receipts','proof/**'),row('tasks/selection','id',`tasks/${first}|tasks/${last}`),row('tasks/minimum','id',`tasks/${first}|tasks/${last}`),row('tasks/'+first,'status','present',{role:'demands',needs:'proof/'+first}),row('tasks/'+last,'status','present',{role:'demands',needs:'proof/'+last,restsOn:'tasks/'+first}),row('clock/ceiling','days','0..14',{role:'demands',form:'interval'})); + const lay=place=>{mkdirSync(join(place,'.bound/cas/blobs'),{recursive:true});writeFileSync(join(place,'.bound/cas/blobs',pin.split(':')[1]),standing);writeFileSync(join(place,'.bound/cas/blobs',artifact.split(':')[1]),bytes);};lay(root); + writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n'); + const run=(root,args)=>{const start=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});events.push({place:place.name,args:args.map(a=>a===key?'[ephemeral key]':a),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-start});return p;}; + const boot=run(root,['land','--key','device','--key-file',key]);assert.equal(boot.status,0,boot.stderr); + for(const view of ['programs','card']){ + const a=run(root,['fold','--as',view]),b=run(root,['fold','--as',view]);assert.equal(a.status,0,a.stderr);assert.equal(b.status,0,b.stderr);assert.equal(a.stdout,b.stdout); + assert.match(a.stdout,/PROGRAM deadline=unread closed=false/);assert.ok(a.stdout.includes('DEMAND tasks/'+first+' unread'));assert.ok(a.stdout.includes('DEMAND tasks/'+last+' blocked'));assert.ok(a.stdout.includes('NEXT tasks/'+first));assert.ok(!a.stdout.includes('NEXT tasks/'+last));assert.doesNotMatch(a.stdout,/CELL |\bFREE\b/); + } + assert.equal(negative.cycle,true); + const cyclic=join(temp,place.name+'-cycle');mkdirSync(cyclic);lay(cyclic); + const cycle=seed.map(line=>line.includes('scope=tasks/'+first+' ')?canonical({scope:'tasks/'+first,measure:'status',value:'present',role:'demands',form:'alphabet',by:'target',at:'policy:sample',needs:'proof/'+first,restsOn:'tasks/'+last}):line); + writeFileSync(join(cyclic,'TARGET.bound'),cycle.join('\n')+'\n');const cb=run(cyclic,['land','--key','device','--key-file',key]);assert.equal(cb.status,0,cb.stderr); + for(const view of ['programs','card']){const bad=run(cyclic,['fold','--as',view]);assert.equal(bad.status,1,bad.stderr);assert.match(bad.stderr,/dependency cycle/);} + } + return events; + } catch(error){const last=events.at(-1);if(last)process.stderr.write('SAMPLE failure '+JSON.stringify(last)+'\n');throw error;}finally{rmSync(temp,{recursive:true,force:true});} +} diff --git a/tools/samples/run-prose-views.mjs b/tools/samples/run-prose-views.mjs new file mode 100644 index 0000000..03078d0 --- /dev/null +++ b/tools/samples/run-prose-views.mjs @@ -0,0 +1,48 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,rmSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {spawnSync,execFileSync} from 'node:child_process'; +import {canonical} from '@lapxo/topos/wire'; +import {standingBytes} from '@lapxo/topos/standing'; + +/** The sample offers exact admitted prose implementation bytes; an archive is not standing identity. */ +export function runProseViews(reader,positive,negative,selectedPlace) { + const temp=mkdtempSync(join(tmpdir(),'bound-prose-sample-')),events=[]; + const digest=bytes=>'sha256:'+createHash('sha256').update(bytes).digest('hex'); + const row=(scope,measure,value,extra={})=>canonical({scope,measure,value,form:'alphabet',role:'writes',at:'policy:prose-sample',by:'target',...extra}); + try { + assert.equal(digest(positive.providerSource),positive.providerDigest); + const world=join(temp,'provider');mkdirSync(world); + writeFileSync(join(world,'provider.mjs'),positive.providerSource);writeFileSync(join(world,'package.json'),'{"type":"module"}\n'); + writeFileSync(join(world,'capsule.bound'),row('region/text','reads','prose/**',{role:'render'})+'\n'); + const archive=join(temp,'provider.tgz');execFileSync('tar',['-czf',archive,'-C',world,'capsule.bound','provider.mjs','package.json']); + const bytes=readFileSync(archive),artifact=digest(bytes),standing=standingBytes([row('region/world','reads','offers/**'),row('offers/prose','digest',artifact,{kind:'capsule',restsOn:artifact})]),pin=digest(standing); + assert.equal(positive.places.length,2); + if(selectedPlace!==undefined)assert.ok(positive.places.some(p=>p.name===selectedPlace)); + for(const place of positive.places.filter(p=>selectedPlace===undefined||p.name===selectedPlace)) { + const root=join(temp,place.name);mkdirSync(root); + const pair=generateKeyPairSync('ed25519'),key=join(temp,place.name+'.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const seed=positive.wire.map(([name,value])=>row('wire/'+name,'id',value)); + seed.push(row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/device','resolution','1..16',{form:'interval'}),row('keys/reader','class','read'),row('keys/fold','class','fold'),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'}),row('reader/timeout','milliseconds','30000..30000',{form:'interval'}),row('reader/response-bytes','bytes','67108864..67108864',{form:'interval'}),row('reader/inputs','id','required'),row('reader/empty','id','refuse'),row('uses/prose','digest',pin),row('dep/prose','digest',artifact,{shape:'provider.mjs'})); + for(const output of place.outputs)seed.push(row('prose/'+output.view,'text','lock',{shape:output.path,about:output.body}),row('view/'+output.view,'id','text@3',{role:'demands',shape:output.path,needs:output.path})); + writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n');const cas=join(root,'.bound/cas/blobs');mkdirSync(cas,{recursive:true});writeFileSync(join(cas,pin.split(':')[1]),standing);writeFileSync(join(cas,artifact.split(':')[1]),bytes); + const run=args=>{const start=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:30000});events.push({place:place.name,args:args.map(a=>a===key?'[ephemeral key]':a),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-start});return p;}; + const boot=run(['land','--key','device','--key-file',key]);assert.equal(boot.status,0,boot.stderr); + for(const output of place.outputs) { + const first=run(['fold','--as',output.view]);assert.equal(first.status,0,first.stderr); + assert.equal(readFileSync(join(root,output.path),'utf8'),output.body); + const second=run(['fold','--as',output.view]);assert.equal(second.status,0,second.stderr); + assert.equal(second.stdout,first.stdout); + assert.equal(readFileSync(join(root,output.path),'utf8'),output.body); + } + const disagreement=join(temp,place.name+'-disagreement.proposal'); + writeFileSync(disagreement,[...negative.bodies.map((body,i)=>row('prose/disagreement-'+i,'text','lock',{shape:negative.path,about:body})),row('view/disagreement','id','text@3',{role:'demands',shape:negative.path,needs:negative.path})].join('\n')+'\n'); + const admitted=run(['land',disagreement,'--key','device','--key-file',key]);assert.equal(admitted.status,0,admitted.stderr); + const refused=run(['fold','--as','disagreement']);assert.equal(refused.status,1,refused.stderr);assert.match(refused.stderr,/REFUSE·view conflicting prose/); + for(const output of place.outputs)assert.equal(readFileSync(join(root,output.path),'utf8'),output.body); + } + return events; + }finally{rmSync(temp,{recursive:true,force:true});} +} diff --git a/tools/samples/run-query-views.mjs b/tools/samples/run-query-views.mjs new file mode 100644 index 0000000..d717a7f --- /dev/null +++ b/tools/samples/run-query-views.mjs @@ -0,0 +1,31 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,rmSync} from 'node:fs'; +import {join} from 'node:path'; +import {tmpdir} from 'node:os'; +import {spawnSync} from 'node:child_process'; +import {canonical} from '@lapxo/topos/wire'; + +/** Published CLI sample: a coordinate is explained by its admitted declarations, not inferred from prose. */ +export function runQueryViews(reader,positive,negative) { + const temp=mkdtempSync(join(tmpdir(),'bound-query-')),events=[]; + const row=(scope,measure,value,extra={})=>canonical({scope,measure,value,form:'alphabet',role:'writes',at:'policy:query',by:'target',...extra}); + try { + assert.equal(positive.places.length,2); + for(const place of positive.places) { + const root=join(temp,place.name);mkdirSync(root); + const pair=generateKeyPairSync('ed25519'),key=join(temp,place.name+'.pem'); + writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const seed=positive.wire.map(([name,value])=>row('wire/'+name,'id',value)); + seed.push(row('keys/device','class','authorize'),row('keys/device','coverage','*'),row('keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/device','signer','file'),row('keys/reader','class','read'),row('keys/fold','class','fold'),row('keys/device','resolution','1..16',{form:'interval'}),row('signer/timeout','milliseconds','5000..5000',{form:'interval'}),row('signer/response-bytes','bytes','65536..65536',{form:'interval'})); + seed.push(row('view/why','id','why',{role:'demands'}),row(place.scope,'id',place.value,{needs:place.coordinate}),row('view/missing','id','not-offered',{role:'demands'})); + writeFileSync(join(root,place.coordinate),place.content);writeFileSync(join(root,'TARGET.bound'),seed.join('\n')+'\n'); + const run=args=>{const start=Date.now(),p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});events.push({place:place.name,args:args.map(a=>a===key?'[ephemeral key]':a),status:p.status,stdout:p.stdout,stderr:p.stderr,runtimeMs:Date.now()-start});return p;}; + const boot=run(['land','--key','device','--key-file',key]);assert.equal(boot.status,0,boot.stderr); + const why=run(['fold',place.coordinate,'--as','why']);assert.equal(why.status,0,why.stderr);assert.ok(why.stdout.includes('WHY '+place.scope+' · policy:query · '+place.value),why.stdout); + const absent=run(['fold',negative.absentCoordinate,'--as','why']);assert.equal(absent.status,0,absent.stderr);assert.ok(absent.stdout.includes('OPEN '+negative.absentCoordinate));assert.doesNotMatch(absent.stdout,/WHY/); + const missing=run(['fold','--as','missing']);assert.equal(missing.status,1,missing.stderr);assert.match(missing.stderr,/REFUSE·view/); + } + return events; + } finally {rmSync(temp,{recursive:true,force:true});} +} diff --git a/tools/samples/run-signing.mjs b/tools/samples/run-signing.mjs new file mode 100644 index 0000000..0de45a3 --- /dev/null +++ b/tools/samples/run-signing.mjs @@ -0,0 +1,35 @@ +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,existsSync,rmSync} from 'node:fs'; +import {tmpdir} from 'node:os';import {join,resolve} from 'node:path';import {spawnSync} from 'node:child_process';import {strict as assert} from 'node:assert'; +import {canonical,parse} from '@lapxo/topos/wire'; +import {createRequire} from 'node:module'; +export function runSigningSample(reader, accepted, negativeInput) { +const temp=mkdtempSync(join(tmpdir(),'bound-sign-cli-')); +const report={reader,dependency:'Topos 0.1.8 signing-lot/1',runs:[],complete:false}; +const pair=generateKeyPairSync('ed25519'),key=join(temp,'device.pem');writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); +const pub=pair.publicKey.export({type:'spki',format:'der'}).toString('base64');const wire=createRequire(import.meta.url).resolve('@lapxo/topos/wire'); +const counter=join(temp,'counter'),command=join(temp,'signer.mjs'),registry=join(temp,'bindings.json'); +writeFileSync(command,`import{readFileSync,appendFileSync}from'node:fs';import{sign,createPrivateKey}from'node:crypto';import{parse,canonical,formatSignature}from ${JSON.stringify(wire)};appendFileSync(process.argv[2],'1');const rows=readFileSync(0,'utf8').trimEnd().split('\\n');process.stdout.write(rows.map(bytes=>canonical({by:parse(bytes).value.fields.by,sig:formatSignature('ed25519:fixture',sign(null,Buffer.from(bytes),createPrivateKey(process.env.PORT_TEST_KEY)).toString('base64'))})).join('\\n')+'\\n');`); +const good={kind:'command',executable:process.execPath,args:[command,counter]};writeFileSync(registry,JSON.stringify({local:good})); +function run(root,label,args,expected=0){const p=spawnSync(process.execPath,[reader,...args],{cwd:root,env:{...process.env,BOUND_SIGNERS:registry,PORT_TEST_KEY:pair.privateKey.export({type:'pkcs8',format:'pem'})},encoding:'utf8',timeout:10000});report.runs.push({label,status:p.status,stdout:p.stdout,stderr:p.stderr});assert.equal(p.status,expected,p.stdout+p.stderr);return p;} +const row=(scope,measure,value,form='alphabet')=>canonical({scope,measure,value,form,role:'writes',at:'policy:fixture',by:'target'}); +function seed(root,name){mkdirSync(root);const rows=[['keys/device','class','authorize'],['keys/device','coverage','*'],['keys/device','public-key',pub],['keys/device','signer',name],['signer/timeout','milliseconds','500..500','interval'],['signer/response-bytes','bytes','65536..65536','interval'],['wire/digest-algorithms','id','sha256'],['wire/signature-algorithms','id','ed25519:fixture'],['wire/era','id','fixture'],['wire/families','id','keys|signer|wire|tree|write|leaf|read|fold|receipts|rendered|resolved|beat|view|region|sample'],['wire/fields','id','scope|role|form|measure|value|by|at|needs|sig|epoch|shape|restsOn|condition|about|kind|view'],['wire/required','id','scope|role|form|measure|value|by|at'],['wire/forms','id','alphabet|interval'],['wire/roles','id','reads|writes|demands'],['wire/at-classes','id','origin|place|receipt|witness|policy']];writeFileSync(join(root,'TARGET.bound'),rows.map(v=>row(...v)).join('\n')+'\n');} +const file=join(temp,'file'),remote=join(temp,'command'); +try{seed(file,'file');seed(remote,'local');run(file,'file bootstrap',['land','--key','device','--key-file',key]);run(remote,'command bootstrap',['land','--key','device','--signer','local']); + const draft=join(temp,'lot.proposal');writeFileSync(draft,accepted.rows.map(f=>row(f.scope,f.measure,f.value)).join('\n')+'\n'); + const f=run(file,'file signs whole lot',['sign','--key','device','--key-file',key,draft]);const before=readFileSync(counter,'utf8').length; + const c=run(remote,'command signs whole lot',['sign','--key','device','--signer','local',draft]);assert.equal(readFileSync(counter,'utf8').length-before,1);const signed=p=>p.stdout.split('\n').filter(l=>parse(l).kind==='fact');assert.deepEqual(signed(f),signed(c)); + const signedFile=join(temp,'signed.proposal');writeFileSync(signedFile,signed(c).join('\n')+'\n');run(file,'file consumer admits signed lot',['land',signedFile]);run(remote,'command consumer admits identical lot',['land',signedFile]); + writeFileSync(draft,[row('sample/failure-a','id','yes'),row('sample/failure-b','id','yes')].join('\n')+'\n'); + const ledger=join(remote,'.bound/ledger/device.bound'),hash=()=>createHash('sha256').update(readFileSync(ledger)).digest('hex'); + const absent=join(temp,'absent');seed(absent,'local');writeFileSync(join(absent,'TARGET.bound'),readFileSync(join(absent,'TARGET.bound'),'utf8').split('\n').filter(l=>!l.includes('measure=signer')).join('\n'));const miss=run(absent,'no declared signer',['land','--signer','local'],1);assert.match(miss.stderr,/missing.*keys\/device/);assert.equal(existsSync(join(absent,'.bound/ledger')),false); + for(const [label,code,pattern]of[['exit',"process.stdout.write('SECRET_OUTPUT');process.stderr.write('SECRET_ERROR');process.exit(7)",/status=7/],['timeout','setInterval(()=>{},100)',/timeout/],['malformed',"process.stdout.write('SECRET_OUTPUT\\n')",/invalid response/],['partial',"process.stdout.write('bound-lock/1 by=device sig=bad\\n')",/invalid response/]]){ + writeFileSync(registry,JSON.stringify({local:{kind:'command',executable:process.execPath,args:['--eval',code]}}));const beforeHash=hash();const p=run(remote,label,['land','--key','device','--signer','local',draft],1);assert.match(p.stderr,pattern);assert.ok(!(p.stdout+p.stderr).includes('SECRET'));assert.equal(hash(),beforeHash); + } + writeFileSync(registry,JSON.stringify({local:good}));run(remote,'selection conflict',['sign','--signer','file',draft],1);run(remote,'retired inert out refuses',['sign','--out','ignored',draft],2); + const invalid=join(temp,'invalid.proposal');writeFileSync(invalid,row('sample/valid','id','yes')+'\n'+row('sample/unknown','id','yes').replace('bound-lock/1',negativeInput.unknownVersion)+'\n'); + const invalidBefore=hash();const refused=run(remote,'unknown wire row refuses whole lot',['land','--signer','local',invalid],1);assert.match(refused.stderr,/version this reader does not know/);assert.equal(hash(),invalidBefore);assert.equal(refused.stdout,''); + report.complete=true;report.fileCommandIdentical=true;report.oneInvocationPerLot=true;report.failureAtomic=true;return report; +}finally{rmSync(temp,{recursive:true,force:true});} + +} diff --git a/tools/samples/run-typed-walk.mjs b/tools/samples/run-typed-walk.mjs new file mode 100644 index 0000000..a9ace30 --- /dev/null +++ b/tools/samples/run-typed-walk.mjs @@ -0,0 +1,53 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {readFileSync,writeFileSync,mkdirSync,readdirSync} from 'node:fs'; +import {join} from 'node:path'; +import {spawnSync} from 'node:child_process'; +import {canonical,parse} from '@lapxo/topos/wire'; +import {runTypedSample} from './run-typed.mjs'; + +/** Authenticated typed history stays origin-qualified evidence; it grants no receiver authority. */ +export function runTypedWalkSample(reader,capture,sample='yes.json') { + const events=[]; + const facts=text=>text.split('\n').filter(l=>parse(l).kind==='fact'); + const row=(scope,measure,value,extra={})=>canonical({scope,measure,value,role:'writes',form:'alphabet',at:'policy:typed-walk',by:'target',...extra}); + try {return runTypedSample(reader,undefined,sample,({root,place:sender,seed,pin,closure,yes,key})=>{ + const receiver=join(root,'receiver');mkdirSync(receiver); + const pair=generateKeyPairSync('ed25519'),receiverKey=join(root,'receiver.pem');writeFileSync(receiverKey,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const run=(place,args)=>{const p=spawnSync(process.execPath,[reader,...args],{cwd:place,encoding:'utf8',timeout:30000});events.push({args:args.map(a=>a.startsWith(root)?'/'+a.slice(root.length+1):a),status:p.status,stdout:p.stdout,stderr:p.stderr});return p;}; + const ok=(place,args)=>{const p=run(place,args);assert.equal(p.status,0,p.stderr||p.stdout);return p;}; + const doc=(name,lines)=>{const f=join(root,name+'.bound');writeFileSync(f,lines.join('\n')+'\n');return f;}; + const selected=JSON.parse(readFileSync(new URL('../../samples/walk/yes.json',import.meta.url),'utf8')).declarations.map(([scope,measure,value])=>row(scope,measure,value)).filter(l=>parse(l).value.fields.scope.startsWith('wire/walk/')); + const config=seed.filter(l=>parse(l).value.fields.scope!=='wire/families'); + const families=row('wire/families','id','B|C|D|G|keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|view|region|evidence|uses|walk'); + const contexts=[['sender',seed],['receiver',config.map(l=>{const f=parse(l).value.fields;return f.scope==='keys/device'&&f.measure==='public-key'?canonical({...f,value:pair.publicKey.export({type:'spki',format:'der'}).toString('base64')}):l;})]].map(([name,rows])=>{ + const declarations=[row('keys/device','resolution','1..16',{form:'interval'}),...rows.filter(l=>!parse(l).value.fields.scope.startsWith('view/')),...selected.map(l=>{const f=parse(l).value.fields;return f.scope==='wire/walk/fields'?canonical({...f,value:[...new Set([...f.value.split('|'),...parse(seed.find(l=>parse(l).value.fields.scope==='wire/fields')).value.fields.value.split('|')])].filter(k=>k!=='sig').sort().join('|')}):l;}),row('walk/origin','id',name+'-typed-ledger'),row('region/context','reads','keys/**|wire/**|walk/origin|uses/**')]; + const folded=ok(receiver,['fold',doc(name+'-context',declarations)]),digest=/^PIN (\S+)$/m.exec(folded.stdout)?.[1];assert.ok(digest); + const bytes=folded.stdout.split('\n').filter(l=>l.startsWith('TOPOS ')).map(l=>l.slice(6)).join('\n')+'\n';assert.equal('sha256:'+createHash('sha256').update(bytes).digest('hex'),digest); + return {name,digest,bytes,declarations}; + }); + for(const place of [sender,receiver]){ + const cas=join(place,'.bound/cas/blobs');mkdirSync(cas,{recursive:true}); + for(const c of contexts)writeFileSync(join(cas,c.digest.split(':')[1]),c.bytes); + for(const [d,b] of closure.blobs)writeFileSync(join(cas,d.split(':')[1]),b); + writeFileSync(join(cas,pin.split(':')[1]),readFileSync(join(sender,'.bound/cas/blobs',pin.split(':')[1]))); + } + const additions=c=>[...c.declarations.filter(l=>parse(l).value.fields.scope.startsWith('wire/walk/')),row('keys/device','resolution','1..16',{form:'interval'}),families,row('walk/context','digest',c.digest),row('uses/peer','digest',contexts.find(o=>o!==c).digest),row('view/walk','id','walk@*',{role:'demands',needs:'B|C|D|G|evidence/**'}),row('view/evidence','id','evidence@8',{role:'demands'})]; + ok(sender,['land',doc('sender-walk',additions(contexts[0])),'--key','device','--key-file',key]); + writeFileSync(join(receiver,'TARGET.bound'),[...config.map(l=>{const f=parse(l).value.fields;return f.scope==='keys/device'&&f.measure==='public-key'?canonical({...f,value:pair.publicKey.export({type:'spki',format:'der'}).toString('base64')}):l;}),...additions(contexts[1])].join('\n')+'\n'); + ok(receiver,['land','--key','device','--key-file',receiverKey]); + const cell={...yes.cells.find(c=>c.scope==='C'),type:'cell',id:'receiver-definition',restsOn:'none',form:yes.form,measure:yes.measure,params:JSON.stringify(yes.params),topos:pin,by:'target'}; + ok(receiver,['land',doc('receiver-cell',[canonical(cell)]),'--key','device','--key-file',receiverKey]); + ok(receiver,['land',doc('receiver-claim',[canonical({type:'claim',scope:'C',id:'c-C',sign:'+1',origin:'ana',value:yes.acts.find(a=>a.id==='c-C').value,by:'target'})]),'--key','device','--key-file',receiverKey]); + const baseline=ok(receiver,['fold','--as','cells']); + const peer=doc('peer-inventory',facts(ok(receiver,['fold','--as','walk@0','--key','device','--key-file',receiverKey]).stdout)); + const packet=doc('typed-history',facts(ok(sender,['fold','--as','walk@8',peer,'--key','device','--key-file',key]).stdout)); + const incoming=ok(receiver,['land',packet,'--key','device','--key-file',receiverKey]);assert.match(incoming.stdout,/INGRESS \d+ new evidence lines · 1 signed local import receipt/); + const retained=ok(receiver,['fold','--as','evidence']);assert.ok(facts(retained.stdout).some(l=>{const f=parse(l).value.fields;return f.type==='claim'&&f.takes==='c-C'&&f.sign==='-1'})); + const after=ok(receiver,['fold','--as','cells']);const cells=p=>p.stdout.split('\n').filter(l=>l.startsWith('CELL ')).join('\n');assert.equal(cells(after),cells(baseline),'foreign withdrawal cannot take a local ID');assert.match(after.stdout,/0 opened.*idle.*provider 0/); + assert.ok(JSON.parse(after.stdout.split('\n').find(l=>l.startsWith('CELL ')).slice(5)).ownClaims.some(c=>c.id==='c-C')); + const hash=()=>readdirSync(join(receiver,'.bound/ledger')).map(n=>[n,createHash('sha256').update(readFileSync(join(receiver,'.bound/ledger',n))).digest('hex')]);const before=hash();assert.match(ok(receiver,['land',packet]).stdout,/ONCE 0 new evidence lines/);assert.deepEqual(hash(),before); + if(capture)writeFileSync(capture,JSON.stringify({contract:'foreign typed evidence, not cross-origin object reconstruction',events},null,2)+'\n'); + console.log('TYPED WALK '+sample+' · foreign exact withdrawal retained · local ID live · receipts idle · replay ONCE'); + });} finally {if(capture)writeFileSync(capture,JSON.stringify({contract:'foreign typed evidence, not cross-origin object reconstruction',events},null,2)+'\n');} +} diff --git a/tools/samples/run-typed.mjs b/tools/samples/run-typed.mjs new file mode 100644 index 0000000..b193203 --- /dev/null +++ b/tools/samples/run-typed.mjs @@ -0,0 +1,153 @@ +import {strict as assert} from 'node:assert'; +import {createHash, generateKeyPairSync, sign} from 'node:crypto'; +import {mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join, dirname} from 'node:path'; +import {createRequire} from 'node:module'; +import {fileURLToPath} from 'node:url'; +import {spawnSync} from 'node:child_process'; +import {canonical, signedBytes, formatSignature} from '@lapxo/topos/wire'; +import {standingBytes} from '@lapxo/topos/standing'; +import {moduleClosure} from './module-closure.mjs'; +import {intervalForm, alphabetOfForm} from '@lapxo/topos/forms'; +import {cell, parts, state, live, sign as ceiling, join as opening, require as floor, observe} from '@lapxo/obligations/views/field'; + +export function runTypedSample(reader, capture, sample='yes.json', continuation, inputs={}) { + const root = mkdtempSync(join(tmpdir(), 'bound-typed-sample-')); + const pair = generateKeyPairSync('ed25519'); + const key = join(root, 'device.pem'); + writeFileSync(key, pair.privateKey.export({type:'pkcs8', format:'pem'}), {mode:0o600}); + const place = join(root, 'place'); mkdirSync(place); + const events = []; + const run = args => { + const started=performance.now(); + const p = spawnSync(process.execPath, [reader, ...args], {cwd:place, encoding:'utf8', timeout:30000}); + events.push({args:args.map(a=>a===key?'':a.startsWith(root)?'/'+a.slice(root.length+1):a), status:p.status, runtimeMs:performance.now()-started, stdout:p.stdout, stderr:p.stderr}); + return p; + }; + const ok = p => assert.equal(p.status, 0, p.stderr || p.stdout); + const row = (scope, measure, value, more={}) => canonical({scope, measure, value, role:'writes', form:'alphabet', at:'policy:sample', by:'target', ...more}); + const yes=JSON.parse(readFileSync(inputs.yes ?? new URL('../../samples/typed/'+sample,import.meta.url),'utf8')); + const closure = moduleClosure(new URL('./typed-provider.mjs', import.meta.url)); + const toposLines = [ + row('region/context', 'reads', 'offers/**|wire/**'), + row('wire/forms','id',yes.form), + row('offers/form','digest',closure.digest,{kind:'form',restsOn:closure.digest}), + row('wire/topos/context-view', 'id', 'sample-context'), + row('offers/context', 'digest', closure.digest, {kind:'check',view:'sample-context', restsOn:[...closure.blobs.keys()].sort().join('|')}), + ]; + const standing = standingBytes(toposLines); + const pin = 'sha256:'+createHash('sha256').update(standing).digest('hex'); + const seed = [ + ['keys/device','class','authorize'], ['keys/device','coverage','*'], + ['keys/device','public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')], + ['keys/device','signer','file'], ['keys/reader','class','read'], ['keys/folder','class','fold'], + ['signer/timeout','milliseconds','5000..5000'], ['signer/response-bytes','bytes','65536..65536'], + ['wire/digest-algorithms','id','sha256'], ['wire/signature-algorithms','id','ed25519:sample'], + ['wire/era','id','sample'], ['wire/families','id','B|C|D|G|keys|signer|wire|tree|write|leaf|reader|read|fold|receipts|rendered|resolved|beat|view|region|evidence|uses'], + ['wire/forms','id','alphabet|interval'], ['wire/roles','id','reads|writes|demands'], + ['wire/at-classes','id','origin|place|receipt|witness|policy'], + ['wire/receipt-inputs','id','semantic-live@1'], + ['wire/region-measures','id','coordinates|leaves'], + ['view/cells','id','cells@1'], ['uses/sample','digest',pin], + ].map(([scope,measure,value])=>row(scope,measure,value,{ + form:measure==='milliseconds'||measure==='bytes'?'interval':'alphabet', + role:scope.startsWith('view/')?'demands':'writes', + })); + const grammar = JSON.parse(readFileSync(new URL('../../samples/typed/wire.json',import.meta.url),'utf8')); + seed.push(...grammar); + for (const [family,id,condition] of [['origin','ana','C'],['origin','luis','C'],['witness','local-opening','B']]) + seed.push(row(`evidence/${family}/${id}`,'id',id,{condition})); + const directory = join(place, '.bound/cas/blobs'); + mkdirSync(directory,{recursive:true}); + for (const [digest,bytes] of [...closure.blobs, [pin,standing]]) { + assert.equal('sha256:'+createHash('sha256').update(bytes).digest('hex'),digest); + writeFileSync(join(directory,digest.split(':')[1]),bytes); + } + writeFileSync(join(place,'TARGET.bound'),seed.join('\n')+'\n'); + let epoch=2; + let world = new Map(); + const params=yes.params, form=[intervalForm,alphabetOfForm].find(f=>f.id===yes.form), lattice=form.lattice(params); + const oracle = (f, at) => { + if(f.type==='cell') {world.set(f.scope,cell(f.scope,at,[],f.restsOn==='none'?[]:f.restsOn.split('|')));return;} + const c=world.get(f.scope), line={id:f.id,at}; + if(f.sign==='-1') { + if(f.type==='claim') world.set(f.scope,observe(c,{...line,origin:'',span:lattice.bottom,sign:-1,takes:f.takes},-1)); + else world.set(f.scope,{...c,marks:[...(c.marks??[]),{...line,sign:-1,takes:f.takes,pole:'ceiling',reach:'local',span:lattice.top}]}); + return; + } + const span=form.parse(params,f.value); + if(f.type==='claim')world.set(f.scope,observe(c,{...line,origin:f.origin,span})); + else if(f.pole==='floor')world=new Map(floor(lattice,world,f.scope,span,line)); + else if(f.reach==='travels')world=new Map(ceiling(lattice,world,f.scope,span,line)); + else {const next=opening(lattice,c,span,f.widens,at);world.set(f.scope,{...next,marks:next.marks.map((m,i)=>i===next.marks.length-1?{...m,id:f.id}:m)});} + }; + const land = fields => { + const records = fields.map(f=>{const stamped={...f, by:'device',epoch:String(epoch)};return canonical({...stamped,sig:formatSignature('ed25519:sample',sign(null,Buffer.from(signedBytes(stamped)),pair.privateKey).toString('base64'))});}); + const at=epoch; + const path=join(root,'lot.txt');writeFileSync(path,records.join('\n')+'\n');const result=run(['land',path]);if(result.status===0){epoch++;for(const f of fields)oracle(f,at);}return result; + }; + try { + const worldLock=join(root,'topos.bound');writeFileSync(worldLock,toposLines.join('\n')+'\n'); + const foldedTopos=run(['fold',worldLock]);ok(foldedTopos); + assert.ok(foldedTopos.stdout.includes('PIN '+pin),foldedTopos.stdout); + assert.match(foldedTopos.stdout,/TOPOS/); + ok(run(['land','--key','device','--key-file',key])); + ok(land(yes.cells.map(c=>({...c,type:'cell',id:'def-'+c.scope,form:yes.form,measure:yes.measure,params:JSON.stringify(params),topos:pin})))); + for(const act of yes.acts) ok(land([act])); + const snapshots=[]; + const read = label => { + const folded=run(['fold','--as','cells']);ok(folded); + const cells=folded.stdout.split('\n').filter(line=>line.startsWith('CELL ')).map(line=>JSON.parse(line.slice(5))); + assert.equal(cells.length,4,folded.stdout); + for(const reading of cells) { + const c=world.get(reading.cell); + assert.equal(reading.state,state(lattice,c,world),label+' '+reading.cell); + assert.deepEqual(reading.parts,JSON.parse(JSON.stringify(parts(lattice,c,world))),label+' '+reading.cell); + assert.deepEqual(reading.ownMarks,live(c.marks??[]).map(m=>m.id)); + } + snapshots.push({label,cells});return cells; + }; + const cells=read('compatible independent observations'); + assert.equal(cells.find(c=>c.cell==='C').state,'FREE'); + assert.deepEqual(cells.find(c=>c.cell==='B').ownMarks,['s-B','j-B','r-B']); + const idle=run(['fold','--as','cells']);ok(idle);assert.match(idle.stdout,/0 opened.*idle.*provider 0/); + ok(land([{type:'claim',scope:'C',id:'disagreement',sign:'+1',origin:'ana',value:yes.scenarios.conflicting}])); + assert.equal(read('conflicting observations').find(c=>c.cell==='C').state,'CONFLICT'); + for(const id of ['disagreement','c-C','c-L'])ok(land([{type:'claim',scope:'C',id:'withdraw-'+id,sign:'-1',takes:id}])); + assert.equal(read('exact claim withdrawals').find(c=>c.cell==='C').state,'REQUIRED'); + for(const [id,origin] of [['outside-a','ana'],['outside-b','luis']])ok(land([{type:'claim',scope:'C',id,sign:'+1',origin,value:yes.scenarios.outside}])); + assert.equal(read('outside travelling ceiling').find(c=>c.cell==='C').state,'FORBIDDEN'); + ok(land([{type:'mark',scope:'G',id:'incompatible-floor',sign:'+1',pole:'floor',reach:'travels',value:yes.scenarios.floorConflict}])); + assert.equal(read('bounds conflict before origins').find(c=>c.cell==='G').state,'CONFLICT'); + ok(land([{type:'mark',scope:'B',id:'withdraw-j',sign:'-1',takes:'j-B'}])); + assert.deepEqual(read('local opening withdrawn').find(c=>c.cell==='B').parts.signed,JSON.parse(JSON.stringify(form.parse(params,yes.acts[0].value)))); + const invalid=JSON.parse(readFileSync(inputs.no ?? new URL('../../samples/typed/no.json',import.meta.url),'utf8')); + for(const example of invalid) { + const record={...example.record}; + if(yes.form==='alphabet'&&record.value)record.value=({'44..47':'lock','0..100':'lock|readme|source','0..49':'readme','40..*':'lock'})[record.value]??record.value; + const ledger=join(place,'.bound/ledger/device.bound'); + const before=createHash('sha256').update(readFileSync(ledger)).digest('hex'); + const refused=land([record]);assert.notEqual(refused.status,0,example.name);assert.match(refused.stderr,new RegExp(example.refusal),example.name); + const after=createHash('sha256').update(readFileSync(ledger)).digest('hex'); + assert.equal(after,before,example.name+' must not append refused bytes'); + Object.assign(events.at(-1),{case:example.name,ledgerSHA256Before:before,ledgerSHA256After:after}); + } + if(continuation)continuation({root,place,pair,key,seed,pin,standing,closure,yes,run,epoch,events}); + return {pin, artifact:closure.digest, artifacts:closure.blobs.size, cells, snapshots, events}; + } finally { + if(capture)writeFileSync(capture,JSON.stringify({pin,artifact:closure.digest,place:yes.place,events},null,2)+'\n'); + rmSync(root,{recursive:true,force:true}); + } +} + +if(process.argv[1]===fileURLToPath(import.meta.url)) { + const require=createRequire(import.meta.url); + const reader=process.argv[2]??join(dirname(require.resolve('@lapxo/bound/package.json')),'dist/cli/verb.js'); + const result=runTypedSample(reader,process.env.BOUND_TEST_CAPTURE); + console.log('SAMPLE '+result.pin); + for(const snapshot of result.snapshots) { + console.log('SCENE '+snapshot.label); + for(const reading of snapshot.cells)console.log('CELL '+JSON.stringify(reading)); + } +} diff --git a/tools/samples/run-walk-refinement.mjs b/tools/samples/run-walk-refinement.mjs new file mode 100644 index 0000000..50fe094 --- /dev/null +++ b/tools/samples/run-walk-refinement.mjs @@ -0,0 +1,43 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,rmSync} from 'node:fs'; +import {tmpdir} from 'node:os';import {join} from 'node:path';import {spawnSync} from 'node:child_process'; +import {canonical,parse} from '@lapxo/topos/wire'; +export async function runWalkRefinement(reader,capture,family){ + const temp=mkdtempSync(join(tmpdir(),'bound-refinement-')),captures=[]; + const row=(scope,measure,value,form='alphabet')=>canonical({scope,measure,value,form,role:'writes',at:'policy:sample',by:'target'}); + const base=JSON.parse(readFileSync(new URL('../../samples/walk/yes.json',import.meta.url),'utf8')).declarations.map(v=>row(...v)); + const profile=JSON.parse(readFileSync(new URL('../../samples/walk/refinement.json',import.meta.url),'utf8')); + const declarations=base.filter(l=>!profile.some(p=>parse(p).value.fields.scope===parse(l).value.fields.scope)).concat(profile); + const facts=text=>text.split('\n').filter(l=>parse(l).kind==='fact'); + const run=(world,args)=>{const p=spawnSync(process.execPath,[reader,...args],{cwd:world.root,encoding:'utf8',timeout:20000});captures.push({args:args.map(v=>v.endsWith('.pem')?'[ephemeral key]':v),status:p.status,stdout:p.stdout,stderr:p.stderr});assert.equal(p.status,0,p.stderr);return p;}; + const worlds=['left','right'].map(name=>{const root=join(temp,name),pair=generateKeyPairSync('ed25519'),key=join(temp,name+'.pem');mkdirSync(root);writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600});return {root,key,name,decl:[...declarations,row('walk/origin','id',name+'-ledger'),row('keys/'+name,'class','authorize'),row('keys/'+name,'coverage','*'),row('keys/'+name,'public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/'+name,'resolution','1..16','interval'),row('keys/'+name,'signer','file'),row('keys/local-reader','class','read')]};}); + const file=(name,lines)=>{const path=join(temp,name+'.bound');writeFileSync(path,lines.join('\n')+'\n');return path;}; + const walk=(world,depth,peer)=>run(world,['fold','--as','walk@'+depth,...peer?[peer]:[],'--key',world.name,'--key-file',world.key]); + const regions=text=>facts(text).map(l=>parse(l).value.fields).filter(f=>f.scope.startsWith('walk/regions/')&&f.measure==='digest'); + const root=text=>facts(text).map(l=>parse(l).value.fields).find(f=>f.scope==='walk/root').value; + const payload=text=>facts(text).filter(l=>parse(l).value.fields.scope.startsWith('sample/')); + try{ + for(const world of worlds){const folded=run(world,['fold',file(world.name+'-context',[...world.decl,row('region/context','reads','keys/**|wire/**|walk/origin')])]);world.pin=/^PIN (\S+)$/m.exec(folded.stdout)[1];world.bytes=folded.stdout.split('\n').filter(l=>l.startsWith('TOPOS ')).map(l=>l.slice(6)).join('\n')+'\n';assert.equal(world.pin,'sha256:'+createHash('sha256').update(world.bytes).digest('hex'));} + for(const world of worlds){const cas=join(world.root,'.bound','cas','blobs');mkdirSync(cas,{recursive:true});for(const other of worlds)writeFileSync(join(cas,other.pin.split(':')[1]),other.bytes);writeFileSync(join(world.root,'TARGET.bound'),[...world.decl,row('walk/context','digest',world.pin),row('uses/peer','digest',worlds.find(w=>w!==world).pin),canonical({scope:'view/walk',role:'demands',form:'alphabet',measure:'id',value:'walk@*',needs:'sample/**',at:'policy:sample',by:'target'}),canonical({scope:'view/evidence',role:'demands',form:'alphabet',measure:'id',value:'evidence@8',at:'policy:sample',by:'target'})].join('\n')+'\n');run(world,['land','--key',world.name,'--key-file',world.key]);} + const [left,right]=worlds; + const scopes=['north/first','south/second','north/third'].map(s=>'sample/'+family+'/'+s); + run(left,['land',file('initial',scopes.map((s,i)=>row(s,'id','value-'+i))),'--key',left.name,'--key-file',left.key]); + const peer=file('empty-right',facts(walk(right,0).stdout)); + const coarse=walk(left,0,peer),medium=walk(left,4,peer),fine=walk(left,6,peer); + assert.equal(regions(coarse.stdout).length,1);assert.equal(regions(medium.stdout).length,2);assert.equal(regions(fine.stdout).length,3);assert.equal(root(coarse.stdout),root(medium.stdout));assert.equal(root(medium.stdout),root(fine.stdout));assert.equal(payload(fine.stdout).length,3); + console.log('REFINEMENT '+family+' · 1 coarse · 2 intermediate · 3 complete coordinates · same history root'); + const invalid=file('grouped-fragment',[...facts(medium.stdout),...payload(fine.stdout)]); + const refused=spawnSync(process.execPath,[reader,'land',invalid,'--key',right.name,'--key-file',right.key],{cwd:right.root,encoding:'utf8',timeout:20000}); + captures.push({args:['land','[grouped-fragment]'],status:refused.status,stdout:refused.stdout,stderr:refused.stderr});assert.notEqual(refused.status,0);assert.match(refused.stderr,/REFUSE·walk partial or extra payload|REFUSE·walk region digest or count mismatch/);console.log(refused.stderr.trim()); + const packet=file('payload',facts(fine.stdout));assert.match(run(right,['land',packet,'--key',right.name,'--key-file',right.key]).stdout,/INGRESS 3 new evidence lines/); + assert.match(run(right,['land',packet]).stdout,/ONCE 0 new evidence lines/); + const ack=file('fine-ack',facts(walk(right,5).stdout));assert.equal(payload(walk(left,6,ack).stdout).length,0); + run(left,['land',file('new-coordinate',[row('sample/'+family+'/north/fourth','id','new')]),'--key',left.name,'--key-file',left.key]); + const next=walk(left,6,ack);assert.equal(regions(next.stdout).length,1);assert.equal(payload(next.stdout).length,1);assert.ok(payload(next.stdout)[0].includes('/north/fourth'));assert.match(next.stdout,/EXCHANGE 1 touched regions · 1 open regions/); + console.log('REFINEMENT '+family+' · new coordinate opens only itself · verified siblings reused'); + run(right,['land',file('next-payload',facts(next.stdout)),'--key',right.name,'--key-file',right.key]); + const evidence=run(right,['fold','--as','evidence']);for(const scope of scopes)assert.ok(facts(evidence.stdout).some(l=>parse(l).value.fields.scope===scope)); + const result={family,status:'native CLI refinement passed',captures};if(capture)writeFileSync(capture,JSON.stringify(result,null,2)+'\n');return result; + }finally{rmSync(temp,{recursive:true,force:true});} +} diff --git a/tools/samples/run-walk.mjs b/tools/samples/run-walk.mjs new file mode 100644 index 0000000..a5c8020 --- /dev/null +++ b/tools/samples/run-walk.mjs @@ -0,0 +1,109 @@ +import assert from 'node:assert/strict'; +import {generateKeyPairSync,createHash,sign} from 'node:crypto'; +import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,readdirSync,rmSync} from 'node:fs'; +import {tmpdir} from 'node:os'; +import {join} from 'node:path'; +import {spawnSync,spawn} from 'node:child_process'; +import {canonical,parse,signedBytes,formatSignature} from '@lapxo/topos/wire'; +import {walkSelection,walkSnapshot,walkAt,walkHeaders,readWalkHeaders} from '@lapxo/topos/walk'; + +export async function runWalkSample(reader, capture, family='measurement', profile) { + const temp=mkdtempSync(join(tmpdir(),'bound-native-walk-')),captures=[]; + const row=(scope,measure,value,form='alphabet')=>canonical({scope,measure,value,form,role:'writes',at:'policy:walk-fixture',by:'target'}); + const base=(profile??JSON.parse(readFileSync(new URL('../../samples/walk/yes.json',import.meta.url),'utf8'))).declarations.map(v=>row(v[0],v[1],v[2],v[3])); + const facts=(text)=>text.split('\n').filter(line=>parse(line).kind==='fact'); + const run=(root,args)=>{const p=spawnSync(process.execPath,[reader,...args],{cwd:root,encoding:'utf8',timeout:20000});captures.push({args:args.map(a=>a.endsWith('.pem')?'[ephemeral key]':a),status:p.status,stdout:p.stdout,stderr:p.stderr});return p;}; + const passed=(root,args)=>{const p=run(root,args);assert.equal(p.status,0,p.stderr);return p;}; + const worlds=['left','right'].map(name=>{ + const root=join(temp,name),pair=generateKeyPairSync('ed25519'),key=join(temp,name+'.pem');mkdirSync(root);writeFileSync(key,pair.privateKey.export({type:'pkcs8',format:'pem'}),{mode:0o600}); + const declarations=[...base,row('walk/origin','id',name+'-ledger'),row('keys/'+name,'class','authorize'),row('keys/'+name,'coverage','*'),row('keys/'+name,'public-key',pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/'+name,'resolution','1..16','interval'),row('keys/'+name,'signer','file'),row('keys/local-reader','class','read')]; + const file=join(temp,name+'-context.bound');writeFileSync(file,[...declarations,row('region/context','reads','keys/**|wire/**|walk/origin')].join('\n')+'\n'); + const conflict=join(temp,name+'-conflicting-wire.bound'); + writeFileSync(conflict,[...declarations,row('wire/fields','id','scope|value'),row('region/context','reads','keys/**|wire/**|walk/origin')].join('\n')+'\n'); + const ambiguity=run(root,['fold',conflict]);assert.notEqual(ambiguity.status,0);assert.match(ambiguity.stderr,/REFUSE·document wire\/fields writes id · target has two live inscriptions without withdrawal/); + const folded=passed(root,['fold',file]),pin=/^PIN (\S+)$/m.exec(folded.stdout)?.[1];assert.ok(pin); + const bytes=folded.stdout.split('\n').filter(line=>line.startsWith('TOPOS ')).map(line=>line.slice(6)).join('\n')+'\n';assert.equal('sha256:'+createHash('sha256').update(bytes).digest('hex'),pin); + return {name,root,key,declarations,pin,bytes,pair}; + }); + const document=(name,lines)=>{const file=join(temp,name+'.bound');writeFileSync(file,lines.join('\n')+'\n');return file;}; + const snapshot=(root)=>{ + const visit=(at)=>readdirSync(at,{withFileTypes:true}).sort((a,b)=>a.name.localeCompare(b.name)).flatMap(d=>d.isDirectory()?visit(join(at,d.name)):[join(at,d.name)+':'+createHash('sha256').update(readFileSync(join(at,d.name))).digest('hex')]); + return visit(root); + }; + try{ + for(const world of worlds){ + const cas=join(world.root,'.bound','cas','blobs');mkdirSync(cas,{recursive:true});for(const origin of worlds)writeFileSync(join(cas,origin.pin.split(':')[1]),origin.bytes); + const seed=[...world.declarations,row('walk/context','digest',world.pin),row('uses/peer','digest',worlds.find(w=>w!==world).pin),canonical({scope:'view/walk',role:'demands',form:'alphabet',measure:'id',value:'walk@*',needs:'sample/**',at:'policy:walk-fixture',by:'target'}),canonical({scope:'view/evidence',role:'demands',form:'alphabet',measure:'id',value:'evidence@8',at:'policy:walk-fixture',by:'target'})]; + if(world.name==='right')seed.push(row('keys/importer','class','authorize'),row('keys/importer','coverage','receipts'),row('keys/importer','public-key',world.pair.publicKey.export({type:'spki',format:'der'}).toString('base64')),row('keys/importer','resolution','1..16','interval'),row('keys/importer','signer','waiting-command')); + writeFileSync(join(world.root,'TARGET.bound'),seed.join('\n')+'\n');passed(world.root,['land','--key',world.name,'--key-file',world.key]); + } + const [left,right]=worlds; + const inventory=(world,depth,file)=>passed(world.root,['fold','--as','walk@'+depth,...file?[file]:[],'--key',world.name,'--key-file',world.key]); + const equalLeft=inventory(left,0),equalRight=inventory(right,0);assert.equal(facts(equalLeft.stdout).find(l=>l.includes('scope=walk/root'))?.match(/value=(\S+)/)?.[1],facts(equalRight.stdout).find(l=>l.includes('scope=walk/root'))?.match(/value=(\S+)/)?.[1]); + for(const world of worlds){const lot=document(world.name+'-local',[row('sample/'+family,'id',world.name)]);passed(world.root,['land',lot,'--key',world.name,'--key-file',world.key]);} + const remoteInventory=document('right-inventory',facts(inventory(right,0).stdout)); + const summary=inventory(left,1,remoteInventory);assert.ok(!facts(summary.stdout).some(l=>l.includes('scope=sample/'))); + const intermediate=inventory(left,4,remoteInventory);assert.ok(!facts(intermediate.stdout).some(l=>l.includes('scope=sample/'))); + const detailed=inventory(left,6,remoteInventory);assert.ok(facts(detailed.stdout).some(l=>l.includes('scope=sample/'))); + const packet=inventory(left,8,remoteInventory);assert.match(packet.stdout,/EXCHANGE 1 touched regions · 1 open regions · \d+ payload bytes/); + const offered=facts(packet.stdout),file=document('left-payload',offered),before=snapshot(right.root); + const altered=document('altered',offered.map(l=>l.replace('value=left','value=altered')));const bad=run(right.root,['land',altered,'--key',right.name,'--key-file',right.key]);assert.notEqual(bad.status,0);assert.match(bad.stderr,/REFUSE·walk/);assert.deepEqual(snapshot(right.root),before); + const resign=(world,fields)=>{const {sig,...body}=fields;return canonical({...body,sig:formatSignature('ed25519:sample',sign(null,Buffer.from(signedBytes(body)),world.pair.privateKey).toString('base64'))})}; + const refuses=(name,lines,reason)=>{const unchanged=snapshot(right.root),p=run(right.root,['land',document(name,lines),'--key',right.name,'--key-file',right.key]);assert.notEqual(p.status,0);assert.match(p.stderr,reason);assert.deepEqual(snapshot(right.root),unchanged,name+' must admit nothing')}; + refuses('partial-payload',offered.filter(l=>!l.includes('scope=sample/')),/REFUSE·walk/); + refuses('outside-prefix',offered.map(l=>l.includes('scope=sample/')?resign(left,{...parse(l).value.fields,epoch:'99'}):l),/REFUSE·walk foreign epoch is outside the authenticated prefix/); + refuses('unauthorized-prefix',offered.map(l=>l.includes('scope=walk/')?resign(left,{...parse(l).value.fields,by:'outsider'}):l),/REFUSE·walk/); + refuses('stale-base',offered.map(l=>l.includes('scope=walk\/root')?resign(left,{...parse(l).value.fields,condition:'sha256:'+('0'.repeat(64))}):l),/REFUSE·walk stale receiver base/); + const untouched=snapshot(left.root),unsupported=run(left.root,['fold','--as','walk@2','--key',left.name,'--key-file',left.key]);assert.notEqual(unsupported.status,0);assert.match(unsupported.stderr,/REFUSE·walk/);assert.deepEqual(snapshot(left.root),untouched); + const landed=passed(right.root,['land',file,'--key',right.name,'--key-file',right.key]);assert.match(landed.stdout,/INGRESS 1 new evidence lines · 1 signed local import receipt/);assert.match(landed.stdout,/EXCHANGE \d+ payload bytes · \d+ protocol bytes · \d+ new evidence bytes · \d+ new receipt bytes/); + const receipt=facts(landed.stdout).find(l=>l.includes('scope=receipts'));assert.ok(receipt);assert.match(receipt,/epoch=3/); + const replayBefore=snapshot(right.root),replay=passed(right.root,['land',file]);assert.match(replay.stdout,/ONCE 0 new evidence lines · 1 retained import receipt/);assert.deepEqual(snapshot(right.root),replayBefore); + const prefixFields=parse(left.declarations.find(l=>l.includes('scope=wire/walk/fields'))).value.fields.value.split('|'); + const digest=bytes=>'sha256:'+createHash('sha256').update(bytes).digest('hex'); + const packetFor=(history,cut)=>{ + const peerHeaders=facts(inventory(right,0).stdout),peerRoot=peerHeaders.find(l=>l.includes('scope=walk/root')),peer=readWalkHeaders(peerHeaders,right.pin,parse(peerRoot).value.fields.condition,()=>true); + const selected=walkAt(walkSnapshot(history,prefixFields,digest,left.name+'-ledger'),peer,8,walkSelection(left.declarations).projections); + return [...walkHeaders(selected,left.pin,peer.root,true).map(l=>resign(left,{...parse(l).value.fields,by:left.name,epoch:String(cut)})),...selected.records]; + }; + const original=offered.find(l=>l.includes('scope=sample/')); + refuses('missing-earlier-prefix',packetFor([resign(left,{...parse(original).value.fields,epoch:'3',value:'replaced'})],3),/REFUSE·walk foreign history is not an extension of its verified prefix/); + refuses('inserted-at-verified-epoch',packetFor([original,resign(left,{...parse(original).value.fields,scope:'sample/extra',epoch:'2'})],3),/REFUSE·walk foreign epoch does not match the verified prefix/); + const acknowledged=document('right-acknowledged',facts(inventory(right,0).stdout)); + const noPayload=inventory(left,8,acknowledged);assert.match(noPayload.stdout,/EXCHANGE 0 touched regions · 0 open regions · 0 payload bytes/); + const none=document('no-payload',facts(noPayload.stdout)),idleBefore=snapshot(right.root),idle=passed(right.root,['land',none]);assert.match(idle.stdout,/ONCE 0 new evidence lines · 0 import receipts/);assert.deepEqual(snapshot(right.root),idleBefore); + const leftInventory=document('left-inventory',facts(inventory(left,0).stdout)),rightPayload=document('right-payload',facts(inventory(right,8,leftInventory).stdout)); + passed(left.root,['land',rightPayload,'--key',left.name,'--key-file',left.key]); + const bothLeft=inventory(left,0),bothRight=inventory(right,0),rootValue=text=>facts(text).find(l=>l.includes('scope=walk/root'))?.match(/value=(\S+)/)?.[1]; + assert.equal(rootValue(bothLeft.stdout),rootValue(bothRight.stdout),'two heads retain both origin prefixes and converge by the wire'); + const evidence=passed(right.root,['fold','--as','evidence']);assert.ok(facts(evidence.stdout).some(l=>l.includes('scope=sample/'+family)&&l.includes('value=left')&&l.includes('epoch=2')));assert.ok(facts(evidence.stdout).some(l=>l.includes('scope=sample/'+family)&&l.includes('value=right'))); + const local=document('next-local',[row('sample/after','id','local')]),signed=passed(right.root,['sign',local,'--key',right.name,'--key-file',right.key]);assert.match(signed.stdout,/epoch=4/); + const changed=passed(right.root,['land',local,'--key',right.name,'--key-file',right.key]);assert.match(changed.stdout,/epoch 4/); + const historicalReplay=snapshot(right.root);assert.match(passed(right.root,['land',file]).stdout,/ONCE 0 new evidence lines/);assert.deepEqual(snapshot(right.root),historicalReplay,'a valid old delivery stays idempotent after a local change'); + assert.ok(!readFileSync(join(right.root,'.bound','ledger',right.name+'.bound'),'utf8').includes('by=left'),'foreign keys/history never enter local owner ledger'); + const alternate=document('alternate-origin-context',[...left.declarations,row('wire/walk/profile','id','alternate'),row('region/context','reads','keys/**|wire/**|walk/origin')]),alternateFold=passed(right.root,['fold',alternate]); + const alternatePin=/^PIN (\S+)$/m.exec(alternateFold.stdout)[1],alternateBytes=alternateFold.stdout.split('\n').filter(l=>l.startsWith('TOPOS ')).map(l=>l.slice(6)).join('\n')+'\n'; + assert.equal(digest(alternateBytes),alternatePin);writeFileSync(join(right.root,'.bound','cas','blobs',alternatePin.split(':')[1]),alternateBytes); + passed(right.root,['land',document('select-alternate',[row('uses/alternate','digest',alternatePin)]),'--key',right.name,'--key-file',right.key]); + refuses('undeclared-context-lineage',offered.map(l=>l.includes('scope=walk/')?resign(left,{...parse(l).value.fields,at:'receipt:'+alternatePin}):l),/REFUSE·walk origin context changed without declared lineage/); + const extended=document('new-left-local',[row('sample/new','id','next')]);passed(left.root,['land',extended,'--key',left.name,'--key-file',left.key]); + const finalPeer=document('right-final-inventory',facts(inventory(right,0).stdout)),interruptionFile=document('interruption-payload',facts(inventory(left,8,finalPeer).stdout)); + // Interrupt a real CLI while its declared receiver signer is still preparing the receipt. + const waiting=join(temp,'waiting-signer.mjs'),marker=join(temp,'signer-ready'),registry=join(temp,'host-signers.json'); + writeFileSync(waiting,"import {writeFileSync} from 'node:fs'; process.stdin.resume(); process.stdin.on('end',()=>{writeFileSync(process.argv[2],'ready');setInterval(()=>{},1000)});\n"); + writeFileSync(registry,JSON.stringify({'waiting-command':{kind:'command',executable:process.execPath,args:[waiting,marker]}})); + const ingressBefore=snapshot(join(right.root,'.bound','ingress')),ledgerBefore=snapshot(join(right.root,'.bound','ledger')),lockBefore=readFileSync(join(right.root,'TARGET.bound'),'utf8'); + const interrupted=spawn(process.execPath,[reader,'land',interruptionFile,'--key','importer'],{cwd:right.root,env:{...process.env,BOUND_SIGNERS:registry},detached:true,stdio:['ignore','pipe','pipe']}); + let interruptedOut='',interruptedErr='';interrupted.stdout.on('data',b=>interruptedOut+=b);interrupted.stderr.on('data',b=>interruptedErr+=b); + const completion=new Promise(resolve=>interrupted.on('close',(status,signal)=>resolve({status,signal}))); + try { + const until=Date.now()+4000;while(Date.now()setTimeout(resolve,10)); + assert.ok(readdirSync(temp).includes('signer-ready'),'real receiver signer must be invoked before interruption'); + } finally {try{process.kill(-interrupted.pid,'SIGKILL')}catch{}} + const interruptedStatus=await completion;captures.push({args:['land','','--key','importer'],...interruptedStatus,stdout:interruptedOut,stderr:interruptedErr}); + assert.equal(interruptedStatus.signal,'SIGKILL');assert.deepEqual(snapshot(join(right.root,'.bound','ledger')),ledgerBefore);assert.equal(readFileSync(join(right.root,'TARGET.bound'),'utf8'),lockBefore); + assert.deepEqual(snapshot(join(right.root,'.bound','ingress')),ingressBefore,'interrupted ingress adds neither evidence nor receipt'); + const stale=run(right.root,['land',interruptionFile,'--key',right.name,'--key-file',right.key]);assert.notEqual(stale.status,0);assert.match(stale.stderr,/REFUSE·stale .*host recovery required/);assert.deepEqual(snapshot(join(right.root,'.bound','ingress')),ingressBefore); + + return captures; + }finally{if(capture)writeFileSync(capture+'.'+family+'.json',JSON.stringify(captures,null,2)+'\n');rmSync(temp,{recursive:true,force:true})} +} diff --git a/tools/samples/typed-provider.mjs b/tools/samples/typed-provider.mjs new file mode 100644 index 0000000..8a516e3 --- /dev/null +++ b/tools/samples/typed-provider.mjs @@ -0,0 +1,18 @@ +import {intervalForm, alphabetOfForm} from '@lapxo/topos/forms'; + +// This sample world grants origins and local openings only from admitted records. +// Signing authority and observation origin are separate inputs. +export function context({digest, records, admit}) { + const granted = (family, id, by, scope) => records.filter(row => + row.scope === `${family}/${id}` && row.value === id && row.by === by && admit(row) + && (row.condition ?? '').split('|').includes(scope)).length === 1; + return { + resolve(cell) { + const form=[intervalForm,alphabetOfForm].find(one=>one.id===cell.fields.form); + if(!form)throw Error('REFUSE·codec sample has no selected form'); + return {digest,form,params:JSON.parse(cell.fields.params)}; + }, + origin: (id, by, scope) => granted('evidence/origin', id, by, scope), + witness: (id, by, scope) => granted('evidence/witness', id, by, scope), + }; +} diff --git a/tools/samples/walk-sample-worker.mjs b/tools/samples/walk-sample-worker.mjs new file mode 100644 index 0000000..0af635a --- /dev/null +++ b/tools/samples/walk-sample-worker.mjs @@ -0,0 +1,6 @@ +import {parentPort,workerData} from 'node:worker_threads'; +import {publicInstrument} from './public-instrument.mjs'; +import {runWalkSample} from './run-walk.mjs'; +const instrument=await publicInstrument(workerData.reader); +try {parentPort.postMessage(await runWalkSample(instrument.reader,undefined,workerData.family,workerData.positive));} +finally {instrument.close();} diff --git a/vectors/archive-conformance.json b/vectors/archive-conformance.json new file mode 100644 index 0000000..69b99b3 --- /dev/null +++ b/vectors/archive-conformance.json @@ -0,0 +1,47 @@ +{ + "scope": "pipeline/archive-conformance", + "execution": "independent", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/run-archive.mjs", + "samples/yes/archive-conformance.json", + "samples/no/archive-conformance.json" + ], + "cwd": ".", + "timeoutMs": 15000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "ARCHIVE specimen-index" + }, + { + "stream": "stdout", + "pattern": "ARCHIVE route-notes" + }, + { + "stream": "stdout", + "pattern": "members equal \u00b7 one archive, two destinations" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7artifact digest-mismatch" + }, + { + "stream": "stdout", + "pattern": "ARTIFACT two unrelated places" + } + ], + "inputs": [ + "tools/samples/run-archive.mjs", + "samples/yes/archive-conformance.json", + "samples/no/archive-conformance.json" + ] + } + ] +} diff --git a/vectors/attest-evidence.json b/vectors/attest-evidence.json new file mode 100644 index 0000000..814a408 --- /dev/null +++ b/vectors/attest-evidence.json @@ -0,0 +1,163 @@ +{ + "scope": "contract/published/attest-evidence-view", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "evidence", + "samples/yes/attest-evidence.json", + "samples/no/attest-evidence.json" + ], + "cwd": ".", + "timeoutMs": 25000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "KEY-CLASS attest" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7signer south uncovered" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7signed" + }, + { + "stream": "stdout", + "pattern": "ONCE" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/typed/artifacts.json", + "samples/typed/artifacts.vector.json", + "samples/typed/contract.json", + "samples/typed/no.json", + "samples/typed/range.vector.json", + "samples/typed/wire.json", + "samples/typed/yes.json", + "samples/yes/attest-evidence.json", + "samples/no/attest-evidence.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ] +} diff --git a/vectors/historical-build.json b/vectors/historical-build.json new file mode 100644 index 0000000..72a3b20 --- /dev/null +++ b/vectors/historical-build.json @@ -0,0 +1,164 @@ +{ + "scope": "historical-build/conformance", + "execution": "independent", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "historical-build", + "samples/yes/historical-build.json", + "samples/no/historical-build.json" + ], + "cwd": ".", + "timeoutMs": 15000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "RENDERED tsconfig.json \u00b7 view/tsconfig" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7view view/unoffered" + }, + { + "stream": "stdout", + "pattern": "BUILD two places; exact configuration; two equal readings; unoffered view refused" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/historical-build-worker.mjs", + "tools/samples/historical-document-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/program-worker.mjs", + "tools/samples/prose-worker.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-historical-build.mjs", + "tools/samples/run-historical-document-views.mjs", + "tools/samples/run-program-views.mjs", + "tools/samples/run-prose-views.mjs", + "tools/samples/run-query-views.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/historical-build.json", + "samples/no/historical-build.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ] +} diff --git a/vectors/historical-document-views.json b/vectors/historical-document-views.json new file mode 100644 index 0000000..59f3150 --- /dev/null +++ b/vectors/historical-document-views.json @@ -0,0 +1,190 @@ +{ + "scope": "historical-document-views/conformance", + "execution": "independent", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "historical-document-views", + "samples/yes/historical-document-views.json", + "samples/no/historical-document-views.json" + ], + "cwd": ".", + "timeoutMs": 20000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "HISTORICAL citation, guide, reference; two places; two exact readings; unoffered view refused" + }, + { + "stream": "stdout", + "pattern": "RENDERED CITATION.cff \u00b7 view/citation-file" + }, + { + "stream": "stdout", + "pattern": "RENDERED docs/guide.md \u00b7 view/guide" + }, + { + "stream": "stdout", + "pattern": "RENDERED docs/reference.md \u00b7 view/reference" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7view view/unoffered" + }, + { + "stream": "stdout", + "pattern": "RENDERED tsconfig.json \u00b7 view/tsconfig" + }, + { + "stream": "stdout", + "pattern": "RENDERED docs/why.md" + }, + { + "stream": "stdout", + "pattern": "RENDERED README.md" + }, + { + "stream": "stdout", + "pattern": "9 renders \u00b7 9 same" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7view conflicting prose" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/historical-document-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/program-worker.mjs", + "tools/samples/prose-worker.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-historical-document-views.mjs", + "tools/samples/run-program-views.mjs", + "tools/samples/run-prose-views.mjs", + "tools/samples/run-query-views.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/historical-document-views.json", + "samples/no/historical-document-views.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ] +} diff --git a/vectors/historical-presentation.json b/vectors/historical-presentation.json new file mode 100644 index 0000000..4ca12c5 --- /dev/null +++ b/vectors/historical-presentation.json @@ -0,0 +1,174 @@ +{ + "scope": "historical-presentation/conformance", + "execution": "independent", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "historical-presentation", + "samples/yes/historical-presentation.json", + "samples/no/historical-presentation.json" + ], + "cwd": ".", + "timeoutMs": 15000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "RENDERED docs/why.md" + }, + { + "stream": "stdout", + "pattern": "RENDERED README.md" + }, + { + "stream": "stdout", + "pattern": "2 renders \u00b7 2 same" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7view view/unoffered" + }, + { + "stream": "stdout", + "pattern": "HISTORICAL explanation and README; two places; exact prose; absent evidence not invented; unoffered view refused" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/historical-build-worker.mjs", + "tools/samples/historical-document-worker.mjs", + "tools/samples/historical-presentation-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/program-worker.mjs", + "tools/samples/prose-worker.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-historical-build.mjs", + "tools/samples/run-historical-document-views.mjs", + "tools/samples/run-historical-presentation.mjs", + "tools/samples/run-program-views.mjs", + "tools/samples/run-prose-views.mjs", + "tools/samples/run-query-views.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/historical-presentation.json", + "samples/no/historical-presentation.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ] +} diff --git a/vectors/native-views.json b/vectors/native-views.json new file mode 100644 index 0000000..9fa7665 --- /dev/null +++ b/vectors/native-views.json @@ -0,0 +1,159 @@ +{ + "scope": "native-views/conformance", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "native-views", + "samples/yes/native-views.json", + "samples/no/native-views.json" + ], + "cwd": ".", + "timeoutMs": 25000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "verbs fold land sign" + }, + { + "stream": "stdout", + "pattern": "scope=receipts .*measure=digest|measure=digest .*scope=receipts" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7view" + }, + { + "stream": "stdout", + "pattern": "KEY-CLASS attest" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/native-views.json", + "samples/no/native-views.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ], + "execution": "independent" +} diff --git a/vectors/native-walk.json b/vectors/native-walk.json new file mode 100644 index 0000000..77333ac --- /dev/null +++ b/vectors/native-walk.json @@ -0,0 +1,1058 @@ +{ + "status": "Native compiled development CLI captures; not release acceptance", + "reader": "dist/cli/verb.js", + "sourceConditions": false, + "receiptSource": "Native signed import receipt; no harness-written receipt", + "places": [ + { + "place": "measurement", + "captureSha256": "91b8ab4ddcb3ace3c800b6dd58d53bfc80a26bf4a13e66c2aa6873a8b6e16d62", + "commands": [ + { + "args": [ + "fold", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/left-conflicting-wire.bound" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7document wire/fields writes id \u00b7 target has two live inscriptions without withdrawal\n" + }, + { + "args": [ + "fold", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/right-conflicting-wire.bound" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7document wire/fields writes id \u00b7 target has two live inscriptions without withdrawal\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 0 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 0 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 1 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@1", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/right-inventory.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 1 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/right-inventory.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 1 touched regions \u00b7 1 open regions \u00b7 235 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/altered.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk region digest or count mismatch receipts/left-ledger/sample\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/partial-payload.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk partial or extra payload\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/outside-prefix.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk foreign epoch is outside the authenticated prefix\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/unauthorized-prefix.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk metadata is not authenticated\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/stale-base.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk stale receiver base\n" + }, + { + "args": [ + "fold", + "--as", + "walk@2", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk unsupported resolution\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/left-payload.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "INGRESS 1 new evidence lines \u00b7 1 signed local import receipt", + "EXCHANGE 235 payload bytes \u00b7 1311 protocol bytes \u00b7 1546 new evidence bytes \u00b7 357 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/left-payload.bound" + ], + "status": 0, + "signal": null, + "stdout": [ + "ONCE 0 new evidence lines \u00b7 1 retained import receipt", + "EXCHANGE 235 payload bytes \u00b7 1311 protocol bytes \u00b7 0 new evidence bytes \u00b7 0 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/missing-earlier-prefix.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk foreign history is not an extension of its verified prefix\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/inserted-at-verified-epoch.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk foreign epoch does not match the verified prefix\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/right-acknowledged.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 0 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/no-payload.bound" + ], + "status": 0, + "signal": null, + "stdout": [ + "ONCE 0 new evidence lines \u00b7 0 import receipts \u00b7 no regions offered", + "EXCHANGE 0 payload bytes \u00b7 439 protocol bytes \u00b7 0 new evidence bytes \u00b7 0 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 1 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/left-inventory.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 1 touched regions \u00b7 1 open regions \u00b7 237 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/right-payload.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "INGRESS 1 new evidence lines \u00b7 1 signed local import receipt", + "EXCHANGE 237 payload bytes \u00b7 1316 protocol bytes \u00b7 1553 new evidence bytes \u00b7 356 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "evidence" + ], + "status": 0, + "signal": null, + "stdout": [ + "FACT authenticated histories \u00b7 readings \u00b7 no encounters computed" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/left-payload.bound" + ], + "status": 0, + "signal": null, + "stdout": [ + "ONCE 0 new evidence lines \u00b7 1 retained import receipt", + "EXCHANGE 235 payload bytes \u00b7 1311 protocol bytes \u00b7 0 new evidence bytes \u00b7 0 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/undeclared-context-lineage.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk origin context changed without declared lineage\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/right-final-inventory.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 1 touched regions \u00b7 1 open regions \u00b7 462 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "", + "--key", + "importer" + ], + "status": null, + "signal": "SIGKILL", + "stdout": [], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-R6lbBD/interruption-payload.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7crash source: REFUSE\u00b7stale the store belongs to exited process 13710; host recovery required\n" + } + ] + }, + { + "place": "artifact", + "captureSha256": "4c8fe9c46cd8cc0111631c411b471cfca5688c4174fb18c75a400ee395ca9134", + "commands": [ + { + "args": [ + "fold", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/left-conflicting-wire.bound" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7document wire/fields writes id \u00b7 target has two live inscriptions without withdrawal\n" + }, + { + "args": [ + "fold", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/right-conflicting-wire.bound" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7document wire/fields writes id \u00b7 target has two live inscriptions without withdrawal\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 0 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 0 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 1 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@1", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/right-inventory.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 1 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/right-inventory.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 1 touched regions \u00b7 1 open regions \u00b7 232 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/altered.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk region digest or count mismatch receipts/left-ledger/sample\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/partial-payload.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk partial or extra payload\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/outside-prefix.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk foreign epoch is outside the authenticated prefix\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/unauthorized-prefix.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk metadata is not authenticated\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/stale-base.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk stale receiver base\n" + }, + { + "args": [ + "fold", + "--as", + "walk@2", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk unsupported resolution\n" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/left-payload.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "INGRESS 1 new evidence lines \u00b7 1 signed local import receipt", + "EXCHANGE 232 payload bytes \u00b7 1311 protocol bytes \u00b7 1543 new evidence bytes \u00b7 357 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/left-payload.bound" + ], + "status": 0, + "signal": null, + "stdout": [ + "ONCE 0 new evidence lines \u00b7 1 retained import receipt", + "EXCHANGE 232 payload bytes \u00b7 1311 protocol bytes \u00b7 0 new evidence bytes \u00b7 0 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/missing-earlier-prefix.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk foreign history is not an extension of its verified prefix\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/inserted-at-verified-epoch.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk foreign epoch does not match the verified prefix\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/right-acknowledged.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 0 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/no-payload.bound" + ], + "status": 0, + "signal": null, + "stdout": [ + "ONCE 0 new evidence lines \u00b7 0 import receipts \u00b7 no regions offered", + "EXCHANGE 0 payload bytes \u00b7 439 protocol bytes \u00b7 0 new evidence bytes \u00b7 0 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 1 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/left-inventory.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 1 touched regions \u00b7 1 open regions \u00b7 234 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/right-payload.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "INGRESS 1 new evidence lines \u00b7 1 signed local import receipt", + "EXCHANGE 234 payload bytes \u00b7 1316 protocol bytes \u00b7 1550 new evidence bytes \u00b7 356 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "evidence" + ], + "status": 0, + "signal": null, + "stdout": [ + "FACT authenticated histories \u00b7 readings \u00b7 no encounters computed" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/left-payload.bound" + ], + "status": 0, + "signal": null, + "stdout": [ + "ONCE 0 new evidence lines \u00b7 1 retained import receipt", + "EXCHANGE 232 payload bytes \u00b7 1311 protocol bytes \u00b7 0 new evidence bytes \u00b7 0 new receipt bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/undeclared-context-lineage.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7walk origin context changed without declared lineage\n" + }, + { + "args": [ + "fold", + "--as", + "walk@0", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 0 touched regions \u00b7 2 open regions \u00b7 0 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "fold", + "--as", + "walk@8", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/right-final-inventory.bound", + "--key", + "left", + "--key-file", + "[ephemeral key]" + ], + "status": 0, + "signal": null, + "stdout": [ + "EXCHANGE 1 touched regions \u00b7 1 open regions \u00b7 459 payload bytes" + ], + "stderr": "" + }, + { + "args": [ + "land", + "", + "--key", + "importer" + ], + "status": null, + "signal": "SIGKILL", + "stdout": [], + "stderr": "" + }, + { + "args": [ + "land", + "/var/folders/tp/mb5pflh94rxbjrtbkvwpg8v00000gn/T/bound-native-walk-sVHJP2/interruption-payload.bound", + "--key", + "right", + "--key-file", + "[ephemeral key]" + ], + "status": 1, + "signal": null, + "stdout": [], + "stderr": "source: REFUSE\u00b7crash source: REFUSE\u00b7stale the store belongs to exited process 13770; host recovery required\n" + } + ] + } + ] +} diff --git a/vectors/process/admission-boundary.vector.json b/vectors/process/admission-boundary.vector.json index 704766e..c9c8106 100644 --- a/vectors/process/admission-boundary.vector.json +++ b/vectors/process/admission-boundary.vector.json @@ -2,17 +2,39 @@ "scope": "admission/one-boundary", "measure": "count", "result": "failures", - "cases": [{ - "program": "runtime", - "args": ["vectors/process/source-tests.mjs", "test/admission-boundary.test.ts"], - "cwd": ".", - "timeoutMs": 70000, - "maxBytes": 4194304, - "exit": 0, - "matches": [ - {"stream":"stdout","pattern":"# fail 0(?:\\n|$)"}, - {"stream":"stdout","pattern":"# pass [1-9][0-9]*(?:\\n|$)"} - ], - "inputs": ["vectors/process/source-tests.mjs", "src/cli/verb.ts", "src/cli/accept.ts", "src/host/selected-topos.ts", "test/admission-boundary.test.ts", "samples/admission/yes/one-boundary.json", "samples/admission/no/one-boundary.json", "TARGET.bound", "package.json"] - }] + "cases": [ + { + "program": "runtime", + "args": [ + "vectors/process/source-tests.mjs", + "test/admission-boundary.test.ts" + ], + "cwd": ".", + "timeoutMs": 70000, + "maxBytes": 4194304, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "# fail 0(?:\\n|$)" + }, + { + "stream": "stdout", + "pattern": "# pass [1-9][0-9]*(?:\\n|$)" + } + ], + "inputs": [ + "vectors/process/source-tests.mjs", + "src/cli/verb.ts", + "src/cli/accept.ts", + "src/host/selected-topos.ts", + "test/admission-boundary.test.ts", + "samples/admission/yes/one-boundary.json", + "samples/admission/no/one-boundary.json", + "TARGET.bound", + "package.json" + ] + } + ], + "execution": "independent" } diff --git a/vectors/process/closed.vector.json b/vectors/process/closed.vector.json index 933c233..f290748 100644 --- a/vectors/process/closed.vector.json +++ b/vectors/process/closed.vector.json @@ -31,5 +31,6 @@ "dist/cli/verb.js" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/flags.vector.json b/vectors/process/flags.vector.json index cdec804..e53ad41 100644 --- a/vectors/process/flags.vector.json +++ b/vectors/process/flags.vector.json @@ -29,5 +29,6 @@ "dist/cli/verb.js" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/help.capture.json b/vectors/process/help.capture.json index 897d1d9..68a7367 100644 --- a/vectors/process/help.capture.json +++ b/vectors/process/help.capture.json @@ -25,5 +25,6 @@ "dist/cli/verb.js" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/idempotent.vector.json b/vectors/process/idempotent.vector.json index 05f3c45..1c2eb40 100644 --- a/vectors/process/idempotent.vector.json +++ b/vectors/process/idempotent.vector.json @@ -32,5 +32,6 @@ "test/bootstrap.test.ts" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/meeting.capture.json b/vectors/process/meeting.capture.json index b422d21..fe6af3b 100644 --- a/vectors/process/meeting.capture.json +++ b/vectors/process/meeting.capture.json @@ -31,5 +31,6 @@ "package.json" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/nothing-deleted.vector.json b/vectors/process/nothing-deleted.vector.json index c70a44a..ef60961 100644 --- a/vectors/process/nothing-deleted.vector.json +++ b/vectors/process/nothing-deleted.vector.json @@ -31,5 +31,6 @@ "test/owned-history.test.ts" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/offline.vector.json b/vectors/process/offline.vector.json index c83894f..c4a7bf3 100644 --- a/vectors/process/offline.vector.json +++ b/vectors/process/offline.vector.json @@ -32,5 +32,6 @@ "test/source-content.test.ts" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/one-writer.vector.json b/vectors/process/one-writer.vector.json index 14844f7..6b01607 100644 --- a/vectors/process/one-writer.vector.json +++ b/vectors/process/one-writer.vector.json @@ -31,5 +31,6 @@ "test/act.test.ts" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/refuse.vector.json b/vectors/process/refuse.vector.json index d7881ce..682fcc1 100644 --- a/vectors/process/refuse.vector.json +++ b/vectors/process/refuse.vector.json @@ -25,5 +25,6 @@ "dist/cli/verb.js" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/resolve-by-url.vector.json b/vectors/process/resolve-by-url.vector.json index 6011431..a047b89 100644 --- a/vectors/process/resolve-by-url.vector.json +++ b/vectors/process/resolve-by-url.vector.json @@ -32,5 +32,6 @@ "test/source-content.test.ts" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/stranger.vector.json b/vectors/process/stranger.vector.json index 3cfdc80..3395851 100644 --- a/vectors/process/stranger.vector.json +++ b/vectors/process/stranger.vector.json @@ -41,5 +41,6 @@ "dist/cli/verb.js" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/process/usage.vector.json b/vectors/process/usage.vector.json index 90c7836..bb2ec32 100644 --- a/vectors/process/usage.vector.json +++ b/vectors/process/usage.vector.json @@ -25,5 +25,6 @@ "dist/cli/verb.js" ] } - ] + ], + "execution": "independent" } diff --git a/vectors/program-views.json b/vectors/program-views.json new file mode 100644 index 0000000..42b7252 --- /dev/null +++ b/vectors/program-views.json @@ -0,0 +1,168 @@ +{ + "scope": "program-views/conformance", + "execution": "independent", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "program-views", + "samples/yes/program-views.json", + "samples/no/program-views.json" + ], + "cwd": ".", + "timeoutMs": 20000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "PROGRAM deadline=unread closed=false" + }, + { + "stream": "stdout", + "pattern": "DEMAND tasks/collect unread" + }, + { + "stream": "stdout", + "pattern": "DEMAND tasks/prepare unread" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7program dependency cycle" + }, + { + "stream": "stdout", + "pattern": "PROGRAMS two places; card and programs; two equal readings" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-program-views.mjs", + "tools/samples/run-prose-views.mjs", + "tools/samples/run-query-views.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/program-views.json", + "samples/no/program-views.json", + "tools/samples/program-worker.mjs", + "tools/samples/prose-worker.mjs", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ] +} diff --git a/vectors/prose-views.json b/vectors/prose-views.json new file mode 100644 index 0000000..b9f8972 --- /dev/null +++ b/vectors/prose-views.json @@ -0,0 +1,155 @@ +{ + "scope": "prose-views/conformance", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "prose-views", + "samples/yes/prose-views.json", + "samples/no/prose-views.json" + ], + "cwd": ".", + "timeoutMs": 25000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "PROSE three named views; two places; two exact readings; disagreement refused" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7view conflicting prose" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-prose-views.mjs", + "tools/samples/run-query-views.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/prose-views.json", + "samples/no/prose-views.json", + "tools/samples/program-worker.mjs", + "tools/samples/prose-worker.mjs", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ], + "execution": "independent" +} diff --git a/vectors/query-views.json b/vectors/query-views.json new file mode 100644 index 0000000..6e2e5cc --- /dev/null +++ b/vectors/query-views.json @@ -0,0 +1,160 @@ +{ + "scope": "query-views/conformance", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "query-views", + "samples/yes/query-views.json", + "samples/no/query-views.json" + ], + "cwd": ".", + "timeoutMs": 15000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "WHY +sample/selection" + }, + { + "stream": "stdout", + "pattern": "WHY +sample/package" + }, + { + "stream": "stdout", + "pattern": "OPEN +not-declared.txt" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7view" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-query-views.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/query-views.json", + "samples/no/query-views.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ], + "execution": "independent" +} diff --git a/vectors/signing-port.json b/vectors/signing-port.json new file mode 100644 index 0000000..062c3ea --- /dev/null +++ b/vectors/signing-port.json @@ -0,0 +1,150 @@ +{ + "scope": "signing-port/conformance", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "signing", + "samples/yes/signing-port.json", + "samples/no/signing-port.json" + ], + "cwd": ".", + "timeoutMs": 15000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "SIGNING file-command-equivalent; one invocation per lot; atomic refusals" + }, + { + "stream": "stdout", + "pattern": "REFUSE" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/signing-port.json", + "samples/no/signing-port.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ], + "execution": "independent" +} diff --git a/vectors/typed-object.json b/vectors/typed-object.json new file mode 100644 index 0000000..5c143b5 --- /dev/null +++ b/vectors/typed-object.json @@ -0,0 +1,164 @@ +{ + "scope": "contract/published/typed-object-sample", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-publication.mjs", + "typed-object", + "samples/yes/typed-object.json", + "samples/no/typed-object.json" + ], + "cwd": ".", + "timeoutMs": 25000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "\"state\":\"FREE\"" + }, + { + "stream": "stdout", + "pattern": "\"state\":\"FORBIDDEN\"" + }, + { + "stream": "stdout", + "pattern": "\"state\":\"CONFLICT\"" + }, + { + "stream": "stdout", + "pattern": "NEGATIVE floor-local .*REFUSE" + } + ], + "inputs": [ + "package.json", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "tools/samples/check-publication.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/typed/artifacts.json", + "samples/typed/artifacts.vector.json", + "samples/typed/contract.json", + "samples/typed/no.json", + "samples/typed/range.vector.json", + "samples/typed/wire.json", + "samples/typed/yes.json", + "samples/yes/typed-object.json", + "samples/no/typed-object.json", + "tools/samples/public-instrument.mjs", + "TARGET.bound", + "dist/host/act-cost.js" + ] + } + ], + "execution": "independent" +} diff --git a/vectors/walk-publication.json b/vectors/walk-publication.json new file mode 100644 index 0000000..b63e3f7 --- /dev/null +++ b/vectors/walk-publication.json @@ -0,0 +1,181 @@ +{ + "scope": "walk/conformance", + "execution": "independent", + "measure": "count", + "result": "failures", + "cases": [ + { + "program": "runtime", + "args": [ + "tools/samples/check-walk-publication.mjs", + "samples/yes/walk.json", + "samples/no/walk.json" + ], + "cwd": ".", + "timeoutMs": 20000, + "maxBytes": 1048576, + "exit": 0, + "matches": [ + { + "stream": "stdout", + "pattern": "PLACE measurement" + }, + { + "stream": "stdout", + "pattern": "PLACE artifact" + }, + { + "stream": "stdout", + "pattern": "EXCHANGE [0-9]+ payload bytes" + }, + { + "stream": "stdout", + "pattern": "INGRESS [0-9]+ new evidence lines" + }, + { + "stream": "stdout", + "pattern": "ONCE 0 new evidence lines" + }, + { + "stream": "stdout", + "pattern": "REFUSE\u00b7walk" + } + ], + "inputs": [ + "TARGET.bound", + "dist/cli/accept.js", + "dist/cli/args.js", + "dist/cli/host.js", + "dist/cli/names.js", + "dist/cli/observe.js", + "dist/cli/owner.js", + "dist/cli/pass.js", + "dist/cli/place.js", + "dist/cli/takes.js", + "dist/cli/verb.js", + "dist/fold/ceilings.js", + "dist/fold/claims.js", + "dist/fold/closed.js", + "dist/fold/configures.js", + "dist/fold/digests.js", + "dist/fold/evidence.js", + "dist/fold/fold-worker.js", + "dist/fold/kept.js", + "dist/fold/keys.js", + "dist/fold/laid.js", + "dist/fold/nos.js", + "dist/fold/object.js", + "dist/fold/observed.js", + "dist/fold/opened.js", + "dist/fold/own.js", + "dist/fold/paid.js", + "dist/fold/place-inputs.js", + "dist/fold/places.js", + "dist/fold/rank.js", + "dist/fold/reach.js", + "dist/fold/readers.js", + "dist/fold/receipts.js", + "dist/fold/region-declarations.js", + "dist/fold/region.js", + "dist/fold/release-policy.js", + "dist/fold/resolved.js", + "dist/fold/roles.js", + "dist/fold/second.js", + "dist/fold/shards.js", + "dist/fold/signed.js", + "dist/fold/signers.js", + "dist/fold/stranger.js", + "dist/fold/views.js", + "dist/fold/wire.js", + "dist/fold/zoom.js", + "dist/host/adapters/keys/ed25519.js", + "dist/host/adapters/modules/javascript.js", + "dist/host/adapters/transport/http.js", + "dist/host/archive.js", + "dist/host/capsule-process.js", + "dist/host/capsule.js", + "dist/host/cell-receipts.js", + "dist/host/content-needed.js", + "dist/host/content-store.js", + "dist/host/digest.js", + "dist/host/hash.js", + "dist/host/io.js", + "dist/host/lifetime.js", + "dist/host/located.js", + "dist/host/objects.js", + "dist/host/ports/ingress.js", + "dist/host/ports/signing.js", + "dist/host/ports/store.js", + "dist/host/ports/transport.js", + "dist/host/process-lifetime.js", + "dist/host/provide.js", + "dist/host/read-only.js", + "dist/host/release.js", + "dist/host/selected-capsules.js", + "dist/host/selected-topos.js", + "dist/host/signing.js", + "dist/host/source-content.js", + "dist/host/timing.js", + "dist/host/walk.js", + "dist/judge/late.js", + "dist/judge/take.js", + "dist/judge/widening.js", + "dist/land/act.js", + "dist/land/alias.js", + "dist/land/held.js", + "dist/land/inert.js", + "dist/land/leaving.js", + "dist/land/ledger.js", + "dist/land/owned.js", + "dist/land/sign.js", + "dist/land/vouched.js", + "dist/land/withdraw.js", + "dist/observe/files.js", + "dist/observe/identity.js", + "dist/observe/match.js", + "dist/observe/regions.js", + "dist/observe/run.js", + "dist/observe/runner.js", + "dist/render/capsule.js", + "dist/render/field.js", + "dist/render/names.js", + "dist/render/open.js", + "dist/render/page.js", + "dist/render/receipts.js", + "dist/render/shape.js", + "dist/render/target.js", + "dist/render/view.js", + "package.json", + "samples/walk/no.json", + "samples/walk/yes.json", + "tools/samples/check-publication.mjs", + "tools/samples/check-walk-publication.mjs", + "tools/samples/evidence-worker.mjs", + "tools/samples/historical-build-worker.mjs", + "tools/samples/historical-document-worker.mjs", + "tools/samples/historical-presentation-worker.mjs", + "tools/samples/module-closure.mjs", + "tools/samples/program-worker.mjs", + "tools/samples/prose-worker.mjs", + "tools/samples/public-instrument.mjs", + "tools/samples/run-evidence.mjs", + "tools/samples/run-historical-build.mjs", + "tools/samples/run-historical-document-views.mjs", + "tools/samples/run-historical-presentation.mjs", + "tools/samples/run-program-views.mjs", + "tools/samples/run-prose-views.mjs", + "tools/samples/run-query-views.mjs", + "tools/samples/run-signing.mjs", + "tools/samples/run-typed-walk.mjs", + "tools/samples/run-typed.mjs", + "tools/samples/run-walk-refinement.mjs", + "tools/samples/run-walk.mjs", + "tools/samples/typed-provider.mjs", + "samples/yes/walk.json", + "samples/no/walk.json", + "tools/samples/walk-sample-worker.mjs", + "dist/host/act-cost.js" + ] + } + ] +}