Skip to content

capsulectl v0.1.0-rc14

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 09 Oct 17:29
· 48 commits to main since this release
49651e2

capsulectl v0.1.0-rc14, from commit 49651e2.

Disclosure first. A shared copy no longer names the per-profile payee companion record: it is still listed as a withheld step, so the copy stays complete, but under a neutral kind. The user's floor and spending limit are now recognised in any written money form (symbols, codes, locale separators, k, a bare number after a money word), compared by value. A shared copy that states the floor, or a counterparty copy that states the limit, is refused. A message the agent writes, and when the user sells an agent's claim, is refused before sealing if it states either. The user's own words are recorded as said.

Fails closed. When a seller's floor is in force but its opening can't be built, the deal check is refused before anything is sealed, instead of running without it.

Wire changes and release pairing. New deal records seal action taxonomy version "6", and every deal check now sends party_role at the top level of the rules checker's input. A rules checker compares the taxonomy version exactly, and a checker built before this release refuses an input carrying party_role, so this release needs a rules checker that holds taxonomy 6 and accepts party_role. Records sealed before re-derive unchanged.

Changes

A shared copy lists the counterparty_profile step under a neutral kind

  • Changed: a shared copy (counterparty or adjudicator) lists every step of the log, withheld
    ones included, so a verifier can tell withheld from missing. The check's counterparty_profile
    companion was listed by that kind, which tells the reader the user keeps a fingerprint of
    merchants across deals. It is now listed as kind private, still withheld, with the line "A
    record kept for the user only (withheld)".
  • Unchanged: the record itself, and the user's own copy, which names it as it is.

The user's floor and limit are recognised in any written form

  • Fixed: the check that keeps a seller's floor (min_total_minor) and a spending limit
    (max_total_minor) out of a shared copy only matched the form capsulectl writes ("$1700.00").
    It now reads money as prose writes it, and compares by value:

    • currency symbols before or after the amount ($, €, £, ¥ and others), ISO codes
      (USD 1,700, 1700 usd, also written against the number: USD1,700, 1700usd) and
      currency words (dollars, euros);
    • thousands separators as locales use them (comma, dot, space, apostrophe, no-break or thin
      space), with or without cents (1.700,00 €, 1'700.00 CHF), and k ($1.7k);
    • a bare number a few words after a money word ("the lowest I'll take is 1700").

    Dates, times, ids and digests are not read as money. An amount the other party is shown anyway
    (the asked price, an offer, a payment) is still not protected.

  • Added: a message the agent writes (from: agent), and, where the user sells, an agent's
    claim (which the buyer's copy opens), is refused before it is sealed when it states the floor or
    the limit in any of these forms. The refusal names the field, never the value. The user's own
    words are recorded as said.

A floor in force goes to the rules checker opened, or the check is refused

  • Fixed (fail closed). A rules checker reads a floor only from its verified
    commercial_bounds_opening, and given none it finds the floor rule not applicable. When a floor
    was in force but its opening could not be built, the checker was run without it. Now:
    • deal check refuses before sealing anything, naming the cause and never the floor. The causes
      are: the deal's limits cannot be read, no opening on this device recomputes to the commitment,
      or the opening is not a commercial-bounds document.
    • A floor is in force when the limits in force set one, whatever can be recomputed from its
      opening.
    • With no floor in force, nothing changes.
  • Fixed: typed deals sent the wrong opening. In a typed deal, the opening sent was the open
    step's, but a checker verifies it against the task authority it is given, which seals the floor
    under its own nonce. The two never matched, so a checker verifying the opening failed every such
    check. The task authority's own opening is now sent.

New deal records seal action taxonomy version 6

  • Changed (wire; records sealed before re-derive unchanged). A deal record's
    taxonomy_version is now "6": capsule-engine's capsule_engine/guards/action_taxonomy.json
    at 7ae6b95b37a3a1c4955af90f56ae4c1c0c404aa9 (file sha256
    7563fcaeb6c192a27877fae3131bca1021526046c8976475c46eebf4fb374272, JCS sha256
    fc12eb90bc2b3c85bb49c4d3d7be8f384c6e0b8e189bc3b68a753a4f1af5cd94).
  • Every action_class is unchanged. Against version 5 (e5ec2c1), version 6 changes only
    approver_role (to account_holder) on agreement.accept, marketplace.offer and
    marketplace.sale. No class is renamed, removed or added, and none changes trigger class.
    • A seller's steps carry: an offer external_commitment.other, a commit (accepting a buyer)
      agreement.accept, and telling the buyer where the item is disclosure.personal. A rental's
      or service's commit or sign is also agreement.accept, whose meaning is unchanged.
    • Deal records never carry marketplace.offer or marketplace.sale.
  • Each step keeps its own version. A record sealed under "2", "3", "4" or "5" re-derives
    with it.
  • Release pairing. A rules checker compares taxonomy_version exactly, so a record sealing
    "6" needs a checker that holds version 6. The next release from main ships with such a
    checker; none is cut from main before one is available.

A rules checker is told which side of the deal the user is on

  • Changed (checker input). Every deal check now sends party_role (buyer or seller) at the
    top level of external-check-input/v0. It is the side the deal's opening intent sealed, or
    buyer when it names none, and it is always explicit, so a checker selects its rules without
    inferring the side.
  • Release pairing. The input's top level refuses members it does not list, so a checker built
    before this change refuses every check that carries party_role. A release that sends it ships
    with a checker that accepts it.
  • The deal id has one source per record: an x-deal-v0 record's deal_id, or a typed record's
    chain_id, which is exactly that value. No record carries both, and a test now holds it.

A typed deal's history acts carry the profile payee key

  • Fixed (checker input only; nothing sealed changes). A history act in a deal recorded with typed
    records now carries counterparty_profile, resolved from the check its authorization rests on,
    whether that act needed an approval or not. Before, it was resolved only through an approval, so a
    repeated payment in a typed deal was not seen as a repeat by a rules checker. Untyped deals are
    unchanged.

Verify

Prebuilt binaries: linux/amd64, linux/arm64, darwin/arm64.

V=v0.1.0-rc14; R=action-state-group/capsule-cli
gh release download "$V" --repo "$R"
sha256sum -c SHA256SUMS
for f in capsulectl-"$V"-*-*; do
  gh attestation verify "$f" --bundle "capsulectl-$V.sigstore.json" --repo "$R" \
    --signer-workflow "$R/.github/workflows/release.yml"
done

The deal skill is installed from this tag's source archive; its skills/deal/SKILL.md equals the tagged commit's.