provared 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1062 -0
- package/LICENSE +202 -0
- package/LICENSE-CC-BY-4.0.txt +396 -0
- package/README.md +689 -0
- package/bin/provared-check.mjs +565 -0
- package/bin/provared-headers.mjs +110 -0
- package/docs/threat-model.md +997 -0
- package/net/headers.js +403 -0
- package/package.json +57 -0
- package/page/check-page.js +162 -0
- package/page/index.html +47 -0
- package/page/render.js +530 -0
- package/page/style.css +150 -0
- package/samples/office-supplies.expected.json +82 -0
- package/samples/office-supplies.jsonl +10 -0
- package/samples/office-supplies.show.json +59 -0
- package/spec/provared-format.md +1672 -0
- package/src/actions.js +90 -0
- package/src/approval.js +73 -0
- package/src/blockstamp.js +198 -0
- package/src/book.js +2232 -0
- package/src/check.d.ts +21 -0
- package/src/check.js +15 -0
- package/src/compare.js +276 -0
- package/src/cover.js +198 -0
- package/src/der.js +192 -0
- package/src/encoding.js +286 -0
- package/src/fields.js +94 -0
- package/src/guard.js +171 -0
- package/src/headers.js +380 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +37 -0
- package/src/jws.js +235 -0
- package/src/keys.js +149 -0
- package/src/pass.js +67 -0
- package/src/passkey-browser.d.ts +20 -0
- package/src/passkey-browser.js +171 -0
- package/src/recorder.js +1115 -0
- package/src/seal.js +133 -0
- package/src/service.js +124 -0
- package/src/signatures.js +147 -0
- package/src/slip.js +401 -0
- package/src/standing.js +181 -0
- package/src/stub.js +140 -0
- package/src/timestamp.js +351 -0
- package/src/tools.js +192 -0
- package/src/tree.js +143 -0
- package/src/types.d.ts +628 -0
- package/src/webauthn.js +119 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1062 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
Draft version 0 of the format. Nothing is published or frozen.
|
|
6
|
+
|
|
7
|
+
- 2026-10-05: `provared-headers` is marked as experimental, in the
|
|
8
|
+
README and in what the command prints.
|
|
9
|
+
- 2026-10-05: faults found by an independent review of the chain of
|
|
10
|
+
block headers. It found no way to have a block counted unless real
|
|
11
|
+
work made it: no chain file and no answer from a node did. Each fault
|
|
12
|
+
is fixed and each is now a test (`test/headers.test.mjs`).
|
|
13
|
+
- The second node did not have to show anything: an empty answer
|
|
14
|
+
counted as agreeing, a node behind could agree, and other nodes could
|
|
15
|
+
cut the end of the chain or swap it for a branch with no more work,
|
|
16
|
+
after which the file was written shorter. Now the second node is
|
|
17
|
+
asked for the latest six blocks on a copy of the chain and must hand
|
|
18
|
+
them back itself; it must be on a network apart from every node that
|
|
19
|
+
gave headers, judged by the address reached, not the name given; a
|
|
20
|
+
branch near the end is taken on only if it carries more work; and a
|
|
21
|
+
chain file is never written shorter than it was.
|
|
22
|
+
- A node could keep `provared-headers` waiting for ever with messages
|
|
23
|
+
of its own, and grow its memory with requests to answer. Now a node
|
|
24
|
+
is given fifteen minutes at most, only answers to what was asked keep
|
|
25
|
+
a session open, and answers to its own messages stop while it does
|
|
26
|
+
not read them.
|
|
27
|
+
- The list of threats said that a branch after the last known block
|
|
28
|
+
must carry the real chain's work for every block. The rules on
|
|
29
|
+
difficulty let a branch with dates pushed forward ease its targets at
|
|
30
|
+
each change. Now, after the last known block, no target may be more
|
|
31
|
+
than four times easier than that block's, and the list of threats
|
|
32
|
+
states what a false block then costs, and that a chain file someone
|
|
33
|
+
else hands over is only as good as they are.
|
|
34
|
+
- With `--headers`, the checker said that a block found in the chain
|
|
35
|
+
was one "you named as trusted", and that a block named with
|
|
36
|
+
`--block` was not counted. It now says why each block counts, and
|
|
37
|
+
`--json` gives what the chain showed beside the result.
|
|
38
|
+
- A file that could not be written ended the command with an error of
|
|
39
|
+
its own, and a run that fetched nothing wrote the first block alone.
|
|
40
|
+
Now both are said plainly, nothing is written, and a chain file is
|
|
41
|
+
made sure to be on the disk before it takes the old one's place.
|
|
42
|
+
- Also: the lowest header version after the upgrades of 2013 and 2015,
|
|
43
|
+
and a target of zero, are refused, as nodes refuse them; node
|
|
44
|
+
addresses are read strictly, and lines of a file of nodes that are
|
|
45
|
+
not addresses are counted and said.
|
|
46
|
+
|
|
47
|
+
- 2026-10-05: a block time-stamp can be checked with no node of your
|
|
48
|
+
own. A new command, `provared-headers`, fetches the chain of Bitcoin
|
|
49
|
+
block headers from nodes the person names, and from no one else, and
|
|
50
|
+
keeps it in a file; a second node on another network must hold the same
|
|
51
|
+
latest block. `provared-check --headers <file>` checks that file on the
|
|
52
|
+
device, from the chain's first block, by the rules every Bitcoin node
|
|
53
|
+
applies to headers, and against ten blocks known to be part of the
|
|
54
|
+
chain; a block time-stamp then counts if its block is in the chain with
|
|
55
|
+
at least six blocks after it. In the library: `checkHeaderChain` and
|
|
56
|
+
`blocksInChain`. The network code sits apart, in `net/`, and only the
|
|
57
|
+
new command uses it: the library and the checker still make no
|
|
58
|
+
request. New code: `headers-invalid`. Tried once against the real
|
|
59
|
+
network: the whole chain, 970,076 headers checked from the first
|
|
60
|
+
block, in about six minutes, the same headers as the test against real
|
|
61
|
+
proofs fetched; a second run fetched only what was new. Built from the
|
|
62
|
+
script of that test.
|
|
63
|
+
|
|
64
|
+
- 2026-10-05: faults found by a broad final review of the package as it
|
|
65
|
+
is to be published. It found nothing that made a changed record read
|
|
66
|
+
as intact, nothing that crashed the checker, and no request made by
|
|
67
|
+
the checking page built as one file. Each fault is fixed and each is
|
|
68
|
+
now a test (`test/review20.test.mjs`).
|
|
69
|
+
- **Exit code 0, and the checking page's green answer, now need the
|
|
70
|
+
keys you named:** the passkey you trust and, where the record has a
|
|
71
|
+
seal, the recorder you expect. Before, a stranger's record, or a book
|
|
72
|
+
cut short and sealed again with other recorder keys, gave code 0
|
|
73
|
+
with nothing trusted named. The command-line checker now says
|
|
74
|
+
whether the check rests on keys you named. The library's own answer
|
|
75
|
+
is unchanged.
|
|
76
|
+
- The command-line checker refuses a trust value that is not a
|
|
77
|
+
fingerprint (a typing error had left a time-stamp quietly not
|
|
78
|
+
counted), refuses an option given twice where it may be given once,
|
|
79
|
+
ends with code 0 for `--help`, and does not repeat Node.js's warning
|
|
80
|
+
that its ML-DSA and SLH-DSA are experimental.
|
|
81
|
+
- A run of more than three marks drawn on one letter (accents, for
|
|
82
|
+
one) is shown as three and one visible mark, on the page and in the
|
|
83
|
+
terminal, and each value on the page stays inside its own box. A
|
|
84
|
+
purpose of one letter and 999 such marks had been drawn over the
|
|
85
|
+
page's answer.
|
|
86
|
+
- Checking the sample on the page no longer leaves the sample's
|
|
87
|
+
fingerprints in the boxes, where they made the next record chosen
|
|
88
|
+
read as signed by a passkey not trusted.
|
|
89
|
+
- A stub whose slip fails is no longer counted as one-sided: its
|
|
90
|
+
countersignature, not checked, is `unchecked`.
|
|
91
|
+
- In a browser, a slip can now be cancelled with its passkey
|
|
92
|
+
(`cancelWithPasskey`), and anything prepared for a passkey, such as
|
|
93
|
+
a slip with covered fields, signed (`signChallengeWithPasskey`).
|
|
94
|
+
- A line that ends with a carriage return before its line feed, a
|
|
95
|
+
byte-order mark, or an empty line is now named as such. The codes
|
|
96
|
+
are unchanged.
|
|
97
|
+
- The README says how to install and import the package, and which
|
|
98
|
+
commands need a copy of the repository. Two of its claims went
|
|
99
|
+
further than the code: the check before acting refuses more than a
|
|
100
|
+
checker reports in one case, and a seal fixes what is before it only
|
|
101
|
+
for a recorder you named. Both now say so. `package.json` names both
|
|
102
|
+
licences and the repository. Out-of-date sentences in the list of
|
|
103
|
+
threats and the format description are corrected, and a time-stamp
|
|
104
|
+
shows that entries "existed by" a time, for both kinds.
|
|
105
|
+
|
|
106
|
+
- 2026-10-05: faults found by a nineteenth independent review, of the
|
|
107
|
+
eighteenth review's fixes. Each is fixed and each is now a test
|
|
108
|
+
(`test/review19.test.mjs`). In 3,900 random steps the review found
|
|
109
|
+
no action taken after the person's cancellation was handed over, no
|
|
110
|
+
difference between the stub writer's view of its book and a whole
|
|
111
|
+
check, and no line written that made the book fail its check.
|
|
112
|
+
- The entry below for the eighteenth review says that a value too
|
|
113
|
+
large to be a line of a book is refused before it is written out.
|
|
114
|
+
The limit counted values, not their length, and each member of an
|
|
115
|
+
entry by itself. So a long text met many times, or one long list
|
|
116
|
+
named by many members, could make `add` use gigabytes of memory, or
|
|
117
|
+
end the process, before the call waited its turn. The copy is now
|
|
118
|
+
measured by the length its text would have: each of the three
|
|
119
|
+
members of a cancellation has room for a line, and the other
|
|
120
|
+
members share one line's room. Past that, the entry is not written
|
|
121
|
+
as it was handed over, and the cancellation in it still stops the
|
|
122
|
+
writer. Anything but an object, such as a list, is no longer written
|
|
123
|
+
out, and one that cannot even be looked into is refused through the
|
|
124
|
+
answer, not thrown.
|
|
125
|
+
- A list whose length is not a whole number (a Proxy can say
|
|
126
|
+
anything) was copied as a list that held that value. A list of
|
|
127
|
+
trusted passkeys whose length was a passkey's thumbprint then
|
|
128
|
+
trusted that passkey, and in `add` a list of time-stamps whose
|
|
129
|
+
length was a time-stamp put it into the book. In the options such a
|
|
130
|
+
list is now kept as it was handed over; in `add` it is not plain
|
|
131
|
+
data.
|
|
132
|
+
- An option for the signing methods to treat as not built in that
|
|
133
|
+
could not be read made a whole check and a carried checker throw.
|
|
134
|
+
It is now a problem with the whole check (`check-failed`).
|
|
135
|
+
- A value more than 16 levels down in the options was kept as it was
|
|
136
|
+
handed over. Through a value met twice it could appear near the top
|
|
137
|
+
of a carried checker's options, so that a change made afterwards
|
|
138
|
+
changed its answer. Nothing past that depth is kept now: it cannot
|
|
139
|
+
be read.
|
|
140
|
+
- The stub writer copied the passkeys it trusts with the platform's
|
|
141
|
+
own copy, which refuses a list wrapped in a Proxy. They are now read
|
|
142
|
+
through the same fixed copy as the other options.
|
|
143
|
+
- The check before acting no longer copies its options twice, and a
|
|
144
|
+
gap at the end of a list in the options is now held by a test.
|
|
145
|
+
|
|
146
|
+
- 2026-10-05: the block time-stamp checked once against real proofs.
|
|
147
|
+
Two complete proofs that others had published, one made by hand and
|
|
148
|
+
one made by public calendar services, were read with this library's
|
|
149
|
+
reader against the headers of the real blocks they name: each led to
|
|
150
|
+
its blocks (five in all), and each was refused with another block's
|
|
151
|
+
header or with its file changed by one bit. The headers came from the
|
|
152
|
+
whole chain of headers, checked from its first block. The proofs and
|
|
153
|
+
their files are not copied into the repository, and the tests still
|
|
154
|
+
use made-up blocks. The README and the list of threats say so.
|
|
155
|
+
|
|
156
|
+
- 2026-10-05: faults found by an eighteenth independent review, of the
|
|
157
|
+
seventeenth review's fixes. Each is fixed and each is now a test
|
|
158
|
+
(`test/review18.test.mjs`). In 18,000 random steps the review found
|
|
159
|
+
no action taken after the person's cancellation was handed over, no
|
|
160
|
+
difference between the stub writer's view of its book and a whole
|
|
161
|
+
check, and no line written that made the book fail its check.
|
|
162
|
+
- Since the seventeenth review's fixes, a whole check, a Show and the
|
|
163
|
+
check before acting read their options through a fixed copy. Options
|
|
164
|
+
that shared values many times over, or that held themselves, then
|
|
165
|
+
took more than twenty seconds to copy, or used up the memory. A
|
|
166
|
+
value met twice is now copied once, so the copy costs no more than
|
|
167
|
+
the options hold.
|
|
168
|
+
- An option that cannot even be looked into (a revoked Proxy) made a
|
|
169
|
+
whole check, a carried checker and the stub writer throw an error of
|
|
170
|
+
the platform's own, where they should answer. It is now a problem
|
|
171
|
+
with the whole check (`check-failed`), and the stub writer refuses it
|
|
172
|
+
when it is opened (`bad-field`).
|
|
173
|
+
- What is handed to `add` was copied in two steps where it could not
|
|
174
|
+
be copied at once (a Proxy beside it), so a member could be read
|
|
175
|
+
twice, and a member that changed between the two readings could let
|
|
176
|
+
the writer act after the person's cancellation was handed over. It
|
|
177
|
+
is now copied in one pass, each member and each place read once. In
|
|
178
|
+
the same way, a sound time-stamp beside a gap or a faulty item, in a
|
|
179
|
+
list wrapped in a Proxy, is no longer lost. A value too large to be a
|
|
180
|
+
line of a book is refused before it is written out.
|
|
181
|
+
- An acknowledgement that waits, carried by a copy given at opening,
|
|
182
|
+
was the first to give way where more than sixteen were held. The
|
|
183
|
+
acknowledgements that wait now give way newest first.
|
|
184
|
+
- A copy of a cancellation given at opening that could not be copied
|
|
185
|
+
as plain data was kept as the caller's own object, and a later `add`
|
|
186
|
+
could then fail on it. It is now refused when the writer is opened.
|
|
187
|
+
- The check before acting read the passkeys it trusts once for the
|
|
188
|
+
book and again for its decision. It now reads its options once.
|
|
189
|
+
- Three fixes of the seventeenth review are now held by tests. The
|
|
190
|
+
list of threats said that an entry which does not fit made the
|
|
191
|
+
stub writer read its book again from the start; it costs one line's
|
|
192
|
+
check, and the list now says so.
|
|
193
|
+
|
|
194
|
+
- 2026-10-04: faults found by a seventeenth independent review, of the
|
|
195
|
+
sixteenth review's fixes. Each is fixed and each is now a test
|
|
196
|
+
(`test/review17.test.mjs`). In 25,800 random steps the review found
|
|
197
|
+
no action taken after the person's cancellation was handed over, no
|
|
198
|
+
difference between the stub writer's view of its book and a whole
|
|
199
|
+
check, and no line written that made the book fail its check.
|
|
200
|
+
- A sound cancellation handed to `add` wrapped in a Proxy (as some
|
|
201
|
+
user-interface libraries wrap objects) could not be copied, was taken
|
|
202
|
+
as unreadable, and did not stop the writer. This came from the
|
|
203
|
+
sixteenth review's fixes. What cannot be copied as it stands is now
|
|
204
|
+
copied through its canonical text, still read once.
|
|
205
|
+
- An acknowledgement that waits, carried by a copy given at opening,
|
|
206
|
+
was counted neither in the room the writer keeps nor among the
|
|
207
|
+
waiting ones, and could be cut off. It now counts with the waiting
|
|
208
|
+
ones.
|
|
209
|
+
- With the clock failing, an acknowledgement of the agent's own handed
|
|
210
|
+
over with a cancellation the book holds was taken but neither
|
|
211
|
+
written nor handed back. It now waits, and is handed back and
|
|
212
|
+
written as one that could not be written at once.
|
|
213
|
+
- Opening the stub writer with a very long, nearly empty list of
|
|
214
|
+
cancellations took time in proportion to its length. It no longer
|
|
215
|
+
does.
|
|
216
|
+
- A whole check and a carried checker could still read some unusual
|
|
217
|
+
lists in the options differently (a list with its own way of
|
|
218
|
+
walking through itself, or its own `includes`, or of a class). A
|
|
219
|
+
whole check now reads its options through the same fixed copy, and
|
|
220
|
+
a copy's acknowledgements and a slip's disclosures are read place by
|
|
221
|
+
place.
|
|
222
|
+
- A Show said that cancellations were handed over beside it where the
|
|
223
|
+
list was empty. An empty list is now none, as for a whole book.
|
|
224
|
+
- Tests now hold in place the room kept for the writer's own
|
|
225
|
+
cancellations given at opening, and the limit of 100,000 trusted
|
|
226
|
+
blocks.
|
|
227
|
+
|
|
228
|
+
- 2026-10-04: preparing the first publication. The package version is
|
|
229
|
+
0.1.0. The package holds the library, the command-line checker, the
|
|
230
|
+
format description, the list of threats, the sample record, the
|
|
231
|
+
checking page, the licences, the README and this change log; the
|
|
232
|
+
tests and the demonstration stay in the repository. The README now
|
|
233
|
+
says, as the list of threats did, that no complete block time-stamp
|
|
234
|
+
from a real service has been checked yet.
|
|
235
|
+
|
|
236
|
+
- 2026-10-04: faults found by a sixteenth independent review, of the
|
|
237
|
+
fifteenth review's fixes. Each is fixed and each is now a test
|
|
238
|
+
(`test/review16.test.mjs`). In 9,600 random steps the review found no
|
|
239
|
+
action taken after the person's cancellation was handed over (but for
|
|
240
|
+
the case below of a member whose value changes), no line written that
|
|
241
|
+
made the book fail its check, and no difference between the stub
|
|
242
|
+
writer's view of its book and a whole check.
|
|
243
|
+
- An acknowledgement that waits to follow its cancellation into the
|
|
244
|
+
book could be cut off by cancellations kept after it, and copies of
|
|
245
|
+
other slips' cancellations given at opening could crowd out the
|
|
246
|
+
writer's own. The writer now holds its own slip's cancellations
|
|
247
|
+
first, then the acknowledgements that wait, then the other copies,
|
|
248
|
+
which give way.
|
|
249
|
+
- `add` read what it was handed more than once: a member whose value
|
|
250
|
+
changed from one reading to the next could leave the writer
|
|
251
|
+
unstopped. It is now read once, member by member.
|
|
252
|
+
- An option, or a place in a list, that cannot be read made a carried
|
|
253
|
+
checker and the stub writer crash where a whole check answers. It
|
|
254
|
+
now fails exactly where a whole check reads it; the stub writer
|
|
255
|
+
refuses such options when it is opened.
|
|
256
|
+
- The list of blocks and a copy's time-stamps were read through a
|
|
257
|
+
list's own way of walking through itself; they are now read place
|
|
258
|
+
by place. A very long list with no items in it made a carried
|
|
259
|
+
checker hang; only the places that hold an item are now copied, and
|
|
260
|
+
the list of blocks holds at most 100,000.
|
|
261
|
+
- A copy of a cancellation given at opening as an object of a class
|
|
262
|
+
was changed by the writer, and one that was frozen made every `add`
|
|
263
|
+
fail. Such a copy is now copied as plain data.
|
|
264
|
+
- A writer opened from a book with two acknowledgements of its own
|
|
265
|
+
agent handed back the second; a copy given at opening could end up
|
|
266
|
+
with two. The first is taken, and a copy takes no second one.
|
|
267
|
+
- The empty list that a writer holding no cancellation hands back was
|
|
268
|
+
refused when it was handed in again. An empty list of cancellations
|
|
269
|
+
is now accepted as none.
|
|
270
|
+
- Of the time-stamps the writer counts on a cancellation it holds, the
|
|
271
|
+
earliest are now kept.
|
|
272
|
+
- The documents now say that a writer keeps every cancellation of its
|
|
273
|
+
slip, and that where the clock fails the error is the clock's own.
|
|
274
|
+
|
|
275
|
+
- 2026-10-04: the checking page tried again in current browsers: three
|
|
276
|
+
test builds and two installed desktop browsers at version 154, with
|
|
277
|
+
and without experimental features. None has ML-DSA or SLH-DSA built
|
|
278
|
+
in; each says plainly that the check is not complete, and none shows
|
|
279
|
+
a pass. No horizontal scrolling at phone width. The page built as one
|
|
280
|
+
file refused every request made from inside it. One fault, fixed: in
|
|
281
|
+
the page built as one file, a record chosen before the page's script
|
|
282
|
+
had started was ignored without a word (seen in one browser build). A
|
|
283
|
+
record already chosen when the script starts is now checked.
|
|
284
|
+
|
|
285
|
+
- 2026-10-04: faults found by a fifteenth independent review, of the
|
|
286
|
+
fourteenth review's fixes. Each is fixed and each is now a test
|
|
287
|
+
(`test/review15.test.mjs`). In 2,500 random calls the review found no
|
|
288
|
+
action taken after the person's cancellation was handed over, no line
|
|
289
|
+
written that made the book fail its check, and no difference between
|
|
290
|
+
the stub writer's view of its book and a whole check.
|
|
291
|
+
- A list with a gap in it, beside a cancellation, was written as text
|
|
292
|
+
that is not JSON. With the clock failing, the cancellation was then
|
|
293
|
+
lost: a writer opened again took actions. A list with a gap is now
|
|
294
|
+
refused as not JSON (`payload-not-canonical`), and the sound
|
|
295
|
+
time-stamps in such a list are still kept.
|
|
296
|
+
- A time-stamp from a service the writer was not told to trust, kept
|
|
297
|
+
with a cancellation, kept out a trusted one handed over later; so
|
|
298
|
+
did a trusted one that was late. The writer now merges the
|
|
299
|
+
time-stamps it holds with those handed over: each is judged by
|
|
300
|
+
itself, the ones it counts come first, four at most. Of a list with
|
|
301
|
+
a faulty time-stamp in it, the sound ones are kept.
|
|
302
|
+
- With the clock failing, the acknowledgements handed over with a
|
|
303
|
+
cancellation were dropped, and a writer signed a second one later. A
|
|
304
|
+
copy could hold two acknowledgements of the writer's own agent, and
|
|
305
|
+
a writer opened again took the last of them where `add` took the
|
|
306
|
+
first. They are now kept on a clock failure; only the first of the
|
|
307
|
+
agent's own is taken, everywhere; the agent's own is found among more
|
|
308
|
+
than four.
|
|
309
|
+
- A copy of a cancellation given at opening with a member that is not
|
|
310
|
+
enumerable was checked with it and handed back without it. Such a
|
|
311
|
+
copy is now made plain data before it is checked.
|
|
312
|
+
- The copy of the options read a member that a whole check never
|
|
313
|
+
reads, and turned a gap in a list into an empty place. A member that
|
|
314
|
+
cannot be read is now kept as it is, and a gap stays a gap; a gap in
|
|
315
|
+
the list of blocks, or of a copy's time-stamps, is refused.
|
|
316
|
+
- Where a kept cancellation was written into the book in the same
|
|
317
|
+
call, the error said it was not added. It now says what was done.
|
|
318
|
+
- An acknowledgement still waiting to follow its cancellation into the
|
|
319
|
+
book was not handed back, and was lost to a writer opened again. It
|
|
320
|
+
is now handed back with the cancellation, and written by a writer
|
|
321
|
+
opened again.
|
|
322
|
+
- With the clock failing, the error for a cancellation that cannot be
|
|
323
|
+
kept, because the writer already holds 16, now says so.
|
|
324
|
+
- Tests now hold in place nine fixes of the fourteenth review that
|
|
325
|
+
could be undone without any test failing. Each fix of this review,
|
|
326
|
+
and each of those nine, was then undone in turn in a copy of the
|
|
327
|
+
code: a test caught every one.
|
|
328
|
+
|
|
329
|
+
- 2026-10-04: faults found by a fourteenth independent review, of the
|
|
330
|
+
thirteenth review's fixes. Each is fixed and each is now a test
|
|
331
|
+
(`test/review14.test.mjs`). In 3,000 random calls the review found no
|
|
332
|
+
action taken after the person's cancellation was handed over, no line
|
|
333
|
+
written that made the book fail its check, and no difference between
|
|
334
|
+
the stub writer's view of its book and a whole check.
|
|
335
|
+
- `add`, handed a cancellation with several acknowledgements, could
|
|
336
|
+
take one that does not check (signed with other keys, or given for
|
|
337
|
+
another cancellation) as its own agent's, hand it back, and keep it
|
|
338
|
+
with the cancellation, so that nothing more could be added to the
|
|
339
|
+
book. Each acknowledgement is now checked by itself, and only one
|
|
340
|
+
that checks is taken.
|
|
341
|
+
- A sound time-stamp on a cancellation was lost where the clock
|
|
342
|
+
failed, and where it was handed over only after the date of a kept
|
|
343
|
+
cancellation had come. The writer now keeps the cancellation with
|
|
344
|
+
its sound time-stamps, and takes a time-stamp into a kept
|
|
345
|
+
cancellation before it writes anything into the book.
|
|
346
|
+
- Where a copy already held four acknowledgements of helper agents,
|
|
347
|
+
the writer's own was handed back and not kept, and a writer opened
|
|
348
|
+
again signed a second one. The writer's own is now always kept; the
|
|
349
|
+
last of the others gives way. Sound acknowledgements of other agents
|
|
350
|
+
that come with a cancellation stay with the kept copy.
|
|
351
|
+
- A member that is not enumerable, one level down in the options, was
|
|
352
|
+
made enumerable by a carried checker, which then refused what a
|
|
353
|
+
whole check does not see. It now stays as it was.
|
|
354
|
+
- A tool's function that kept the object it gave as `amount`, or the
|
|
355
|
+
list it gave as `details`, could change it before the second try,
|
|
356
|
+
after the person's approval. What these functions give is now
|
|
357
|
+
copied. Each member of a tool's description is read once.
|
|
358
|
+
- The error for a cancellation that cannot be kept, because the writer
|
|
359
|
+
already holds 16, now says so.
|
|
360
|
+
|
|
361
|
+
- 2026-10-04: faults found by a thirteenth independent review, of the
|
|
362
|
+
eleventh and twelfth reviews' fixes. Each is fixed, or stated, and
|
|
363
|
+
each is now a test (`test/review13.test.mjs`). The review found no way
|
|
364
|
+
to make a whole book or a Show read as intact, or as within its slip,
|
|
365
|
+
when it is not, and no way to make the stub writer's view of its book
|
|
366
|
+
differ from a whole check.
|
|
367
|
+
- The stub writer could date its acknowledgement before a pass that
|
|
368
|
+
its agent had handed on (a pass may be dated up to 300 seconds
|
|
369
|
+
ahead of the clock), so that an honest pass, and the stubs under
|
|
370
|
+
it, read as made after the agent was told. It no longer does.
|
|
371
|
+
- A tool's own function could change what the tool was recorded as,
|
|
372
|
+
through `this`. Each function is now called by itself, and the
|
|
373
|
+
description is frozen.
|
|
374
|
+
- A cancellation given when the writer was opened was handed back
|
|
375
|
+
without the acknowledgement signed for it, and did not take a
|
|
376
|
+
time-stamp handed over later. It now does both, and stops the
|
|
377
|
+
writer from the start.
|
|
378
|
+
- `add`, handed the form that `cancellations()` gives back, dropped a
|
|
379
|
+
sound time-stamp. It now adds the cancellation with its
|
|
380
|
+
time-stamps, and goes on handing back an acknowledgement of its own
|
|
381
|
+
agent that came with it.
|
|
382
|
+
- A clock that failed while the person's cancellation was handed over
|
|
383
|
+
lost the cancellation, and the writer acted on. The writer is now
|
|
384
|
+
stopped, and keeps the cancellation, before the clock is read.
|
|
385
|
+
- A clock that gave no time (`NaN`) switched off the rule that
|
|
386
|
+
nothing is written dated ahead of the clock. It now counts as a
|
|
387
|
+
clock that failed.
|
|
388
|
+
- An acknowledgement dated ahead of the clock was never written into
|
|
389
|
+
the book. It is now tried again.
|
|
390
|
+
- The words a stub was given depended on the order of the
|
|
391
|
+
acknowledgements in one copy. They no longer do.
|
|
392
|
+
- A member of the options that is not enumerable was dropped by a
|
|
393
|
+
carried checker and read by a whole check. Both now read it.
|
|
394
|
+
- `argumentsFingerprint` threw at once for arguments that are not
|
|
395
|
+
JSON; it now refuses through its promise. Stated: `0` and `-0`
|
|
396
|
+
share a fingerprint, as RFC 8785 sets out.
|
|
397
|
+
|
|
398
|
+
- 2026-10-04: the author is named in the format description's copyright
|
|
399
|
+
line, in the README and in `package.json`.
|
|
400
|
+
|
|
401
|
+
- 2026-10-04: faults found by a twelfth independent review, of the
|
|
402
|
+
acknowledgement and of the connector for an agent's tools. Each is
|
|
403
|
+
fixed and each is now a test (`test/review12.test.mjs`). The review
|
|
404
|
+
found no way to have an acknowledgement counted that the agent's side
|
|
405
|
+
did not sign, to have a stub excused through one, or to run a tool
|
|
406
|
+
that the slip does not allow.
|
|
407
|
+
- The stub writer could date its acknowledgement before its own last
|
|
408
|
+
stub (a stub may be dated up to 300 seconds ahead of the clock), so
|
|
409
|
+
that an honest stub read as made after the agent was told. It no
|
|
410
|
+
longer does.
|
|
411
|
+
- Different arguments could share one fingerprint: a list with a gap
|
|
412
|
+
in it, or with a named member, was written as if it had neither. It
|
|
413
|
+
is now refused as not JSON, and the tool is not run.
|
|
414
|
+
- What a tool is was copied one level deep, and one object went to
|
|
415
|
+
all of a tool's functions and then to the tool. Each now gets a copy
|
|
416
|
+
of its own, and a tool's description is fixed through and through.
|
|
417
|
+
- The person was asked to approve an action that could not be taken
|
|
418
|
+
anyway (the slip also asks for a countersignature, and the tool has
|
|
419
|
+
no way to ask for one). They are no longer asked, and the stub
|
|
420
|
+
writer's answer names both things that are missing.
|
|
421
|
+
- An acknowledgement in a book still passed after the cancellation it
|
|
422
|
+
names had failed its check further on in the book. It no longer
|
|
423
|
+
does (`cancellation-not-found`).
|
|
424
|
+
- Which words a stub was given depended on the order in which copies
|
|
425
|
+
were handed over. The time-stamp rule is now applied first, for
|
|
426
|
+
every copy; a stub it reports keeps that finding, and is told in
|
|
427
|
+
addition where it is also dated after the acknowledgement.
|
|
428
|
+
- An acknowledgement was given as confirmed where the device could
|
|
429
|
+
not confirm the slip or the copy. It is now given as not checked.
|
|
430
|
+
The command-line checker no longer shows what such a copy says.
|
|
431
|
+
- Changed after the reviewer's design remarks: a pass handed on after
|
|
432
|
+
the agent's side acknowledged, every pass handed on from it, and
|
|
433
|
+
every stub under them, are reported; an acknowledgement that does
|
|
434
|
+
not check is still a problem with the whole check, but the person's
|
|
435
|
+
copy of the cancellation is used all the same; a stub writer opened
|
|
436
|
+
with keys that are not the agent's hands back no acknowledgement.
|
|
437
|
+
- The type declarations said that `cancellations()` hands back
|
|
438
|
+
cancellations with their time-stamps only. They now say that each
|
|
439
|
+
comes with the acknowledgement the writer signed.
|
|
440
|
+
|
|
441
|
+
- 2026-10-04: faults found by an eleventh independent review, of the
|
|
442
|
+
checker that can be carried on, of the stub writer that carries its
|
|
443
|
+
book on, and of the tenth review's fixes. Each is fixed, or stated as
|
|
444
|
+
a limit, and each is now a test (`test/review11.test.mjs`). In 240
|
|
445
|
+
random books the reviewer's carried checker never differed from a
|
|
446
|
+
whole check, and in 2,483 random calls the stub writer never differed
|
|
447
|
+
from a whole check of its book.
|
|
448
|
+
- A clock that failed part of the way through `add` left the stub
|
|
449
|
+
writer's reader holding a line that its book did not. Every line is
|
|
450
|
+
now tried on a reader split off the book's own, which takes the
|
|
451
|
+
book's place only if the line is written. An entry that does not
|
|
452
|
+
fit now costs one line's check, where it cost a reading of the
|
|
453
|
+
whole book.
|
|
454
|
+
- Options that were inherited, worked out when asked for, or objects
|
|
455
|
+
of a class were dropped or changed when a carried checker or the
|
|
456
|
+
stub writer copied them, so that the answer could differ from a
|
|
457
|
+
whole check's. They are now read once, as a whole check reads them.
|
|
458
|
+
- A new rule: a seal dated more than 300 seconds before a time-stamp
|
|
459
|
+
that it covers (a service's time-stamp on a seal before it) is
|
|
460
|
+
reported (`time-went-backwards`). Stated beside it: what a Show
|
|
461
|
+
cannot show where the earlier seal is left out of its pages.
|
|
462
|
+
- A cancellation given when the stub writer is opened is now written
|
|
463
|
+
into the book once its date has come; every cancellation of its
|
|
464
|
+
slip that the writer is handed is kept, not only the first; one
|
|
465
|
+
kept without a time-stamp takes the time-stamp it is handed over
|
|
466
|
+
with later; and `cancellations()` hands each back with the
|
|
467
|
+
acknowledgement the writer signed, so that a writer opened again
|
|
468
|
+
hands back the same one.
|
|
469
|
+
|
|
470
|
+
- 2026-10-04: the checking page as one file. `node
|
|
471
|
+
tools/make-single-page.mjs` writes `provared-check.html`: the page, its
|
|
472
|
+
style, the checker and the sample record in one file, copied in
|
|
473
|
+
unchanged, which opens in a browser from the disk with no server. Its
|
|
474
|
+
content security policy allows no request of any kind. Tests:
|
|
475
|
+
`test/single-page.test.mjs`. Tried in three browser builds.
|
|
476
|
+
|
|
477
|
+
- 2026-10-04: a connector between an agent's tools and the stub writer.
|
|
478
|
+
`recordTools(recorder, tools)` puts each tool behind the stub writer:
|
|
479
|
+
a call asks first, runs the tool only if the slip allows the action,
|
|
480
|
+
and writes the stub. A call that is not allowed throws `NotTaken`.
|
|
481
|
+
Where the slip asks for the person's approval, the tool's `approve`
|
|
482
|
+
function is asked for it once. By default the stub names one
|
|
483
|
+
document, `arguments`: the fingerprint of the call's arguments,
|
|
484
|
+
written in the one form of RFC 8785 (`argumentsFingerprint`). It
|
|
485
|
+
names no agent software. Tests: `test/tools.test.mjs`.
|
|
486
|
+
|
|
487
|
+
- 2026-10-04: the acknowledgement, a new kind of record (format
|
|
488
|
+
description, section 26). The agent's side states, with the agent's
|
|
489
|
+
own keys, that it was handed the person's cancellation of a slip, and
|
|
490
|
+
when. A cancellation shows when the person signed it; until now
|
|
491
|
+
nothing showed that the agent's side was told.
|
|
492
|
+
- The record: `provared.acknowledgement.v0`, with the label
|
|
493
|
+
`vnd.provared.acknowledgement.v0+json`, signed with the two keys of
|
|
494
|
+
the slip's agent, or of a helper agent under its pass.
|
|
495
|
+
`writeAcknowledgement` writes one.
|
|
496
|
+
- In a book it is an entry of its own, `{"acknowledgement": ...}`,
|
|
497
|
+
after the cancellation it names. A new code:
|
|
498
|
+
`cancellation-not-found`.
|
|
499
|
+
- The person hands it to a checker with their own copy of the
|
|
500
|
+
cancellation (`acknowledgements`, up to four). Every stub of that
|
|
501
|
+
agent dated after the acknowledgement is then reported, in words of
|
|
502
|
+
its own, even where the copy has no time-stamp. Where the book
|
|
503
|
+
leaves the cancellation out, the checker says that the agent's side
|
|
504
|
+
had acknowledged it. A new code: `acknowledgement-mismatch`.
|
|
505
|
+
- The stub writer signs an acknowledgement whenever the person's
|
|
506
|
+
cancellation of its slip is handed to `add`, writes it into the book
|
|
507
|
+
after the cancellation, and hands it back: in the answer of `add`,
|
|
508
|
+
or in the `acknowledgement` member of the error where `add` fails.
|
|
509
|
+
- The checker's answer: a new kind of entry, `acknowledgement`; a new
|
|
510
|
+
count, `summary.counts.acknowledgements`; and `acknowledgements` on
|
|
511
|
+
each cancellation handed over beside the book. The command-line
|
|
512
|
+
checker and the checking page show them.
|
|
513
|
+
- Tests: `test/acknowledgement.test.mjs`, and the two new codes in
|
|
514
|
+
`test/refusals.test.mjs`.
|
|
515
|
+
|
|
516
|
+
- 2026-10-04: a checker that can be carried on. No record and no rule of
|
|
517
|
+
the format changes: only how fast the free library works.
|
|
518
|
+
- `openChecker(book, options)` reads a book once and then takes more
|
|
519
|
+
lines (`add`), without reading the earlier ones again. Its answer
|
|
520
|
+
(`result`) is the answer `checkBook` gives for the same text. A
|
|
521
|
+
whole check is now: start, read every line, give the answer; there
|
|
522
|
+
is one way of reading a line.
|
|
523
|
+
- The stub writer carries its book on. One action no longer checks
|
|
524
|
+
every signature in the book twice. Measured on one computer, with
|
|
525
|
+
countersigned stubs: 9, 14 and 23 thousandths of a second for one
|
|
526
|
+
action after 400, 1,600 and 6,400 stubs, where it took 2.0 seconds
|
|
527
|
+
after 400 and 7.7 after 1,600.
|
|
528
|
+
- `recorder.check()` gives the checker's answer for the writer's book
|
|
529
|
+
as it stands. `recorder.before()` now waits its turn with the other
|
|
530
|
+
calls.
|
|
531
|
+
- What can be found only once every stub has been read (a limit "in
|
|
532
|
+
any period", what a cancellation handed over beside the book shows)
|
|
533
|
+
is worked out afresh for each answer, and is no longer written into
|
|
534
|
+
what the checker keeps while it reads.
|
|
535
|
+
- New tests (`test/carried.test.mjs`): the carried checker against a
|
|
536
|
+
whole check after every line of a book with every kind of entry;
|
|
537
|
+
trying a stub leaves the book's reader as it was; the stub writer's
|
|
538
|
+
view of its book against a whole check after every call.
|
|
539
|
+
|
|
540
|
+
- 2026-10-04: faults found by a tenth independent review, of the ninth
|
|
541
|
+
review's fixes. Each is fixed, or stated as a limit, and each is now a
|
|
542
|
+
test (`test/review10.test.mjs`). With time-stamps that tell the truth,
|
|
543
|
+
the review found no way to make a whole book or a Show read as intact,
|
|
544
|
+
or as within its slip, when it is not, apart from the two narrow cases
|
|
545
|
+
below (the seal of a Show, and a rare kind of block).
|
|
546
|
+
- The stub writer lost a cancellation that the person had signed when
|
|
547
|
+
something beside it could not be written as a line of a book
|
|
548
|
+
(`stamps: undefined`, for example), and went on taking actions.
|
|
549
|
+
`add` now adds the cancellation by itself where what stands beside
|
|
550
|
+
it is at fault, and the call still fails and says what was done.
|
|
551
|
+
- A cancellation that the stub writer kept, because it was dated ahead
|
|
552
|
+
of the clock, was never written into the book, and a writer opened
|
|
553
|
+
again from the book took actions again. The writer now writes it
|
|
554
|
+
into the book once its clock has reached that date, whole, with the
|
|
555
|
+
person's time-stamps. Until then `cancellations()` hands back what
|
|
556
|
+
the writer holds, to be kept with the book. Stated as a limit: a
|
|
557
|
+
writer opened from the book alone knows nothing of it.
|
|
558
|
+
- A cancellation with no counted time-stamp of its own was shown as
|
|
559
|
+
"counts as cancelled at" the time of a later seal. The checker's
|
|
560
|
+
answer now keeps two times apart: `existedBy`, the time by which a
|
|
561
|
+
later seal shows that an entry existed, and `stampedAt`, the time
|
|
562
|
+
that a seal's or a cancellation's own time-stamps give it. **This
|
|
563
|
+
changes the answer's shape:** for a slip, a stub and the other kinds
|
|
564
|
+
of entry, what was `stampedAt` is now `existedBy`.
|
|
565
|
+
- The seal that comes with a Show was not held to the rule that no
|
|
566
|
+
unique number appears twice. It now is, against the pages.
|
|
567
|
+
- A block time-stamp beside a later seal that stated a time before a
|
|
568
|
+
service's time-stamp on an earlier seal was credited, and could
|
|
569
|
+
excuse a stub made after a cancellation. It is now set aside, and
|
|
570
|
+
the checker says so. It needs a block that states a time far behind
|
|
571
|
+
the true time.
|
|
572
|
+
- A seal or a cancellation that did not pass its check no longer shows
|
|
573
|
+
a time of its own.
|
|
574
|
+
- A date was reported against the time-stamp of a cancellation whose
|
|
575
|
+
passkey signature the device could not check. It no longer is, as
|
|
576
|
+
for a seal.
|
|
577
|
+
- The format description and the list of threats said that a page
|
|
578
|
+
dated after a seal's time-stamp is the page reported in a Show. The
|
|
579
|
+
seal is.
|
|
580
|
+
|
|
581
|
+
- 2026-10-03: faults found by a ninth independent review, of the eighth
|
|
582
|
+
review's fixes. Each is fixed, or stated as a limit, and each is now a
|
|
583
|
+
test (`test/review9.test.mjs`). The review found no way to make a
|
|
584
|
+
whole book read as intact, or as within its slip, when it is not.
|
|
585
|
+
- A cancellation dated ahead, put into a block at once and
|
|
586
|
+
time-stamped by a service on its date, counted from the block's
|
|
587
|
+
time: days before the date the person signed. Honest stubs were then
|
|
588
|
+
reported. A cancellation is now never taken to have been made before
|
|
589
|
+
its own date, and the checker says that the two time-stamps do not
|
|
590
|
+
agree.
|
|
591
|
+
- A seal with an early block time-stamp and a later one from a service
|
|
592
|
+
counted from the later. Every counted time-stamp of a seal is now
|
|
593
|
+
taken, and the earliest counts. A block that states a time long
|
|
594
|
+
before the seal's own date, beside a service's time-stamp, is still
|
|
595
|
+
set aside, and the checker says so.
|
|
596
|
+
- In a Show, an old seal that did not belong to the book marked the
|
|
597
|
+
honest page before it. The finding is now given for the seal.
|
|
598
|
+
- In a Show, a seal was not held to the chain of seals. It now is, as
|
|
599
|
+
far as the pages show the chain.
|
|
600
|
+
- The stub writer wrote an approval dated up to 600 seconds ahead of
|
|
601
|
+
its clock. It now writes none dated more than 300 seconds ahead.
|
|
602
|
+
- The stub writer kept at most 16 cancellations that it could not add,
|
|
603
|
+
of any slip in the book, and dropped the next: its own slip's
|
|
604
|
+
cancellation could be the one dropped. It now keeps one, of its own
|
|
605
|
+
slip.
|
|
606
|
+
- Stated as limits in the documents: the time-stamps beside the seal
|
|
607
|
+
of a Show, and beside the last seal of a book, can be swapped for
|
|
608
|
+
later ones (the gain is at most 300 seconds); a person can keep a
|
|
609
|
+
cancellation back and hand it over later; only a late time, not a
|
|
610
|
+
late time-stamp beside a prompt one, is pointed out on a
|
|
611
|
+
cancellation.
|
|
612
|
+
|
|
613
|
+
- 2026-10-03: the checking page takes what the command-line checker
|
|
614
|
+
takes. A fifth box names the blocks you trust. A second panel takes the
|
|
615
|
+
person's own copies of cancellations (up to 16 files) and one file of
|
|
616
|
+
disclosures for covered fields; each handed-over cancellation is shown
|
|
617
|
+
as a card, saying whether the book holds it. A file that is not JSON
|
|
618
|
+
stops the check. The sample record is checked without those files.
|
|
619
|
+
Tried in three browser builds at phone width.
|
|
620
|
+
|
|
621
|
+
- 2026-10-03: faults found by an eighth independent review, of the stub
|
|
622
|
+
writer, of which time-stamps give a record its time, and of ten passes
|
|
623
|
+
in a row. Each is fixed and each is now a test
|
|
624
|
+
(`test/review8.test.mjs`). Passing on up to ten times was found sound.
|
|
625
|
+
- A later time-stamp from a service, put beside an earlier block
|
|
626
|
+
time-stamp on a cancellation, moved the cancellation's time later,
|
|
627
|
+
and excused stubs made after the person cancelled; in the person's
|
|
628
|
+
own copy too. Every counted time-stamp beside a cancellation is now
|
|
629
|
+
taken, and the earliest counts.
|
|
630
|
+
- A block time-stamp on a cancellation is no longer taken as earlier
|
|
631
|
+
than the date the person signed in the cancellation. Before, a stub
|
|
632
|
+
that an outside time-stamp showed to have existed before that date
|
|
633
|
+
could still be reported.
|
|
634
|
+
- Where a service's time-stamp and a block time-stamp beside one seal
|
|
635
|
+
do not agree, the checker now says so.
|
|
636
|
+
- A service's time-stamps could step backwards without end, 300 seconds
|
|
637
|
+
at a time. Each is now compared with the latest before it.
|
|
638
|
+
- A Show under a later seal passed where the whole book failed, even
|
|
639
|
+
with the earlier seal among its pages. A seal among the pages is now
|
|
640
|
+
held against the pages and the seals before it. With that seal left
|
|
641
|
+
out of the pages a Show cannot show it, and the documents now say so.
|
|
642
|
+
- The stub writer wrote its line from the caller's own objects after it
|
|
643
|
+
had checked them, so a later change could put a line into the book
|
|
644
|
+
that failed the book's check. What it is handed is now copied when it
|
|
645
|
+
is handed over.
|
|
646
|
+
- `record` handed the stub to the other side before the check of the
|
|
647
|
+
whole book, so the other side could hold two signed stubs for one
|
|
648
|
+
place in the chain. It now checks first.
|
|
649
|
+
- `act` accepted a date in the past, so an action could be taken after
|
|
650
|
+
the slip had ended and dated inside it. A date handed to `act` must
|
|
651
|
+
now be within 300 seconds of the writer's clock.
|
|
652
|
+
- After an other side that never answered, a later call that stemmed
|
|
653
|
+
from that request was refused as "from inside an action". The mark
|
|
654
|
+
now ends when the time to countersign runs out.
|
|
655
|
+
- A countersignature dated up to 598 seconds ahead of the clock was
|
|
656
|
+
written. It is now compared with the clock alone: 300 seconds.
|
|
657
|
+
- The check before acting refuses an action that would add to a period
|
|
658
|
+
which a later-dated stub already overfills, though a checker reports
|
|
659
|
+
nothing new for it. That stays, and the format description now says
|
|
660
|
+
so, where it said the two agree exactly.
|
|
661
|
+
|
|
662
|
+
- 2026-10-03: a slip may allow up to ten passes in a row (`passes`: 1 to
|
|
663
|
+
10); an eleventh is refused. It was three. Ten is the upper number
|
|
664
|
+
commonly set for chains of delegated access between services, and is a
|
|
665
|
+
first-draft number.
|
|
666
|
+
- 2026-10-03: faults found by a seventh independent review, of how
|
|
667
|
+
time-stamps are credited and of the stub writer. Each is fixed and
|
|
668
|
+
each is now a test (`test/review7.test.mjs`). The review found no way
|
|
669
|
+
to make a whole book read as intact, or as within its slip, when it is
|
|
670
|
+
not.
|
|
671
|
+
- A Show under a seal passed where the whole book failed: the seal's
|
|
672
|
+
own date was not compared with the pages. It is now.
|
|
673
|
+
- The stub writer refused a cancellation it could not add (a faulty
|
|
674
|
+
time-stamp beside it, a date ahead of the clock) and went on allowing
|
|
675
|
+
actions. A cancellation the person signed now stops it either way.
|
|
676
|
+
- `act` wrote its line without the whole-book check that `record`
|
|
677
|
+
makes. The stub is now written and checked with the whole book
|
|
678
|
+
before the action is taken; the other side is handed a copy of the
|
|
679
|
+
stub; a stub added through `add` moves the writer's place on.
|
|
680
|
+
- An approval that was not a record let the action be taken and then
|
|
681
|
+
lost its stub. It now stops the action before it is taken.
|
|
682
|
+
- The stub writer accepted its own stub dated ahead of its clock. It
|
|
683
|
+
writes nothing dated ahead of it.
|
|
684
|
+
- A call made after an action had ended could be refused as "from
|
|
685
|
+
inside the action". The mark now holds only while the action runs.
|
|
686
|
+
- A later seal was reported because of an entry that had already
|
|
687
|
+
failed its own check, and one misdated entry excused a seal from
|
|
688
|
+
every other. Each entry is now looked at by itself.
|
|
689
|
+
- A date was reported against a time-stamp that the device could not
|
|
690
|
+
count. It no longer is, and the seal says that the time-stamp was
|
|
691
|
+
not counted.
|
|
692
|
+
- Where a service states the time, its time-stamps now give the time,
|
|
693
|
+
and a block time-stamp beside them is a second witness. A block that
|
|
694
|
+
states a time far behind no longer makes such a seal fail.
|
|
695
|
+
- A time limit of "for ever" for the other side became one
|
|
696
|
+
millisecond; it is now refused. An empty list of documents is the
|
|
697
|
+
same as none in `act` as in `record`.
|
|
698
|
+
|
|
699
|
+
- 2026-10-03: faults found by a sixth independent review, of the block
|
|
700
|
+
time-stamp and the stub writer. Each is fixed and each is now a test
|
|
701
|
+
(`test/review6.test.mjs`). The review found no way to have a block
|
|
702
|
+
time-stamp counted without a proof that leads to a block the reader
|
|
703
|
+
named, and nothing that crashed or hung the checker.
|
|
704
|
+
- On a cancellation, a block time-stamp's two hours of looseness were
|
|
705
|
+
taken the unsafe way, so a stub made after the cancellation could
|
|
706
|
+
escape. A cancellation now counts from two hours before the time the
|
|
707
|
+
block states, and the time used is shown.
|
|
708
|
+
- A seal dated before an entry it covers was not reported once any
|
|
709
|
+
counted time-stamp existed, even one that settled nothing. It is now.
|
|
710
|
+
- An entry kept the time of the first seal after it, even where a later
|
|
711
|
+
seal showed an earlier time; naming a true block could then turn an
|
|
712
|
+
honest stub into one "after the cancellation". An entry now has the
|
|
713
|
+
earliest time that any seal after it shows.
|
|
714
|
+
- The stub writer accepted a countersignature, or an entry, dated years
|
|
715
|
+
ahead, after which its book could not be sealed. Both are refused.
|
|
716
|
+
- The stub writer could be blocked for good by an other side that never
|
|
717
|
+
answered, or by a call from inside its own action. The other side now
|
|
718
|
+
has a set time; such a call is refused at once (in Node.js).
|
|
719
|
+
- The stub writer relied on an approval's fingerprint as handed over.
|
|
720
|
+
It now works it out from the approval itself.
|
|
721
|
+
- `record` could write a stub that made the book fail its check. It
|
|
722
|
+
now writes nothing unless the book still passes with it.
|
|
723
|
+
- The check before acting ignored the longest line a book may hold. An
|
|
724
|
+
action whose record would not fit is not allowed.
|
|
725
|
+
- `act` took an action that was certain to be outside the slip, where
|
|
726
|
+
the slip asks for a countersignature and no way to ask for one was
|
|
727
|
+
given. It no longer does.
|
|
728
|
+
- Disclosures handed over beside a Show were ignored where the page
|
|
729
|
+
carried its own. Both are now used together.
|
|
730
|
+
- The note about a late time-stamp on a cancellation appeared for
|
|
731
|
+
almost every block time-stamp. It now goes by the earliest time the
|
|
732
|
+
time-stamp allows.
|
|
733
|
+
- A block's number above about four thousand million was refused,
|
|
734
|
+
against the format description; a header of the wrong length had two
|
|
735
|
+
codes. Both follow the description now, which allows 255 steps in a
|
|
736
|
+
row, as the format's own reader does.
|
|
737
|
+
- Where two passes above a stub both set a limit within a period, the
|
|
738
|
+
checker and the check before acting named different passes. Both now
|
|
739
|
+
name the nearer one.
|
|
740
|
+
- A unit could hold spaces and capitals and be read as the checker's
|
|
741
|
+
own words. A unit is now 1 to 16 characters with no spaces.
|
|
742
|
+
- On a device that cannot check all three signatures of a seal, the
|
|
743
|
+
seal now says that its time-stamp was not counted.
|
|
744
|
+
|
|
745
|
+
- 2026-10-03: the block time-stamp, a second kind of time-stamp beside a
|
|
746
|
+
seal or a cancellation. It is a proof, in the open format
|
|
747
|
+
OpenTimestamps, that the fingerprint was written into a block of the
|
|
748
|
+
Bitcoin blockchain, with the block's header beside it. The chain is
|
|
749
|
+
used purely as a clock: no coin, wallet, account or payment. It rests
|
|
750
|
+
on SHA-256 only, not on a signature. The person checking names the
|
|
751
|
+
blocks they trust by fingerprint (`blocks`, `--block`); a block's time
|
|
752
|
+
counts as right to within two hours. The library sends nothing
|
|
753
|
+
anywhere and names no service. Tested with made-up blocks; published
|
|
754
|
+
sample proofs of the format were read with the reader, and no complete
|
|
755
|
+
proof from a real service has been checked yet.
|
|
756
|
+
|
|
757
|
+
- 2026-10-03: faults found by a fifth independent review, of the fixes
|
|
758
|
+
below and of the person's own copy of a cancellation. Each is fixed and
|
|
759
|
+
each is now a test (`test/review5.test.mjs`). The review found no way
|
|
760
|
+
to make a book or a Show read as intact, or as within its slip, when it
|
|
761
|
+
is not, and nothing that crashed or hung.
|
|
762
|
+
- The stub writer let two actions asked for at the same moment both
|
|
763
|
+
pass the check before acting. Its calls now wait for one another.
|
|
764
|
+
- The stub writer put the other side's countersignature into the book
|
|
765
|
+
unchecked; one made with other keys made the whole book fail. It is
|
|
766
|
+
now checked first, and left out if it does not check. `add` adds an
|
|
767
|
+
entry only if the book still passes its check with it.
|
|
768
|
+
- The check before acting allowed an action that could never be
|
|
769
|
+
countersigned where the slip asks for a countersignature. It no
|
|
770
|
+
longer does.
|
|
771
|
+
- A name padded with the blank Braille pattern could draw a line that
|
|
772
|
+
looked like the checker's own, a variation selector passed unmarked,
|
|
773
|
+
and a name could carry the checker's words. Every character that is
|
|
774
|
+
not drawn is now marked, a name or a purpose is shown in quotation
|
|
775
|
+
marks, and the page folds runs of spaces as the command line does.
|
|
776
|
+
- The signer of a slip could cover a name with a value a slip may not
|
|
777
|
+
hold, so that the slip was sound only while the name stayed covered.
|
|
778
|
+
Disclosures that do not pass are now refused and reported apart, and
|
|
779
|
+
the slip is checked as it would be without them.
|
|
780
|
+
- A finding about a period was given twice on a helper's stub where the
|
|
781
|
+
slip and the pass both set such a limit. It is given once.
|
|
782
|
+
- Only four passes were compared for one stub, so two checkers could
|
|
783
|
+
differ on the totals of a pass far up. A fourth pass in a row is now
|
|
784
|
+
refused (`pass-too-deep`), and a stub is compared with every pass
|
|
785
|
+
above its own.
|
|
786
|
+
- Any text was accepted in the place of a covered field. It must now be
|
|
787
|
+
a SHA-256 fingerprint in base64url.
|
|
788
|
+
- Disclosures handed over in the wrong form were ignored without a
|
|
789
|
+
word. They are now refused.
|
|
790
|
+
- The format description said an action may not be dated before the
|
|
791
|
+
last stub "under the slip"; the code, rightly, uses the last stub of
|
|
792
|
+
its own chain. The description is corrected.
|
|
793
|
+
- The notes about the person's own copy of a cancellation said the book
|
|
794
|
+
left it out where the book held it with a broken time-stamp, and did
|
|
795
|
+
not point out a late time-stamp on the copy. Both are corrected.
|
|
796
|
+
- A finding about a period may be given for a stub of another chain
|
|
797
|
+
than the one written last. That is as the format sets out; it is now
|
|
798
|
+
stated.
|
|
799
|
+
|
|
800
|
+
- 2026-10-03: the person's own copy of a cancellation. The checker takes
|
|
801
|
+
it beside the book (`cancellations`, `--cancellation`). It counts even
|
|
802
|
+
where whoever keeps the book left the cancellation out, or holds it
|
|
803
|
+
with a later time-stamp: every stub that no outside time-stamp shows
|
|
804
|
+
to have existed before it is reported, and the check before acting
|
|
805
|
+
allows nothing under the slip. A copy that does not pass its check is
|
|
806
|
+
a problem, never set aside. The answer has a new member, `held`.
|
|
807
|
+
|
|
808
|
+
- 2026-10-03: faults found by a fourth independent review, of
|
|
809
|
+
cancelling, vouching, covered fields and passing on. Each is fixed and
|
|
810
|
+
each is now a test (`test/review4.test.mjs`). The review found no way
|
|
811
|
+
to crash the checker, and found the checks of who signed a
|
|
812
|
+
cancellation, a vouching record, a withdrawal and a pass sound.
|
|
813
|
+
- A slip could cover an item of a list: a limit, a condition, an
|
|
814
|
+
action, a service or a key. One signed slip then read differently to
|
|
815
|
+
different readers, and the check before acting allowed anything. An
|
|
816
|
+
item of a list can no longer be covered in a slip.
|
|
817
|
+
- A member named `__proto__` in a slip was accepted, hidden from every
|
|
818
|
+
check, and what it held was inherited unchecked: software names sent
|
|
819
|
+
to the terminal as they were, keys for a service that nobody had
|
|
820
|
+
checked, a stand-in for a covered name. It is now a member like any
|
|
821
|
+
other, and is refused as unknown.
|
|
822
|
+
- A limit "within any period" could be emptied by a later-dated stub in
|
|
823
|
+
a helper's chain. A period now goes by the times the stubs state, in
|
|
824
|
+
whichever chain and at whichever place in the book, and is worked out
|
|
825
|
+
once every stub has been read. The check before acting counts the
|
|
826
|
+
periods of later-dated stubs too.
|
|
827
|
+
- Where the person cancelled twice, only the first cancellation in the
|
|
828
|
+
book counted, and whoever kept the book chose the order. Every
|
|
829
|
+
cancellation now counts.
|
|
830
|
+
- A time-stamp beside a cancellation can be swapped for a later one.
|
|
831
|
+
No check can show that; the checker now points out a time-stamp dated
|
|
832
|
+
more than 300 seconds after the cancellation's own date, and the
|
|
833
|
+
documents state the limit.
|
|
834
|
+
- A helper could pass on and so escape the limits, actions and times of
|
|
835
|
+
its own pass. A stub is now compared with every pass above its own,
|
|
836
|
+
and so is an action in the check before acting.
|
|
837
|
+
- A Show applied the strict rule for a time-stamped cancellation, which
|
|
838
|
+
single pages cannot settle, and reported a stub that the whole book
|
|
839
|
+
clears. It now uses only the place of each page, and says so.
|
|
840
|
+
- A Show did not say that a cancellation or a withdrawal may be on a
|
|
841
|
+
page that is not shown. It does now.
|
|
842
|
+
- A vouching record that had run out still stood behind a slip that
|
|
843
|
+
began inside its time. It must now be in force for the whole of the
|
|
844
|
+
slip's time, and for a seal at the time-stamped time too.
|
|
845
|
+
- A pass that the device could not check, with no stub under it, still
|
|
846
|
+
gave "within its slip". It no longer does.
|
|
847
|
+
- Looking up who vouches took time that grew with the number of
|
|
848
|
+
vouching records multiplied by the number of names. It no longer does:
|
|
849
|
+
a book of 45 megabytes that took 46 seconds takes 4.
|
|
850
|
+
- A service whose id is `constructor` was shown as vouched for by
|
|
851
|
+
"undefined". Every service now has a place of its own in the answer.
|
|
852
|
+
- An empty list of covered fields let a name be absent and shown as
|
|
853
|
+
covered. A list now holds exactly one fingerprint, the fingerprint
|
|
854
|
+
method is named exactly where something is covered, and a decoy is
|
|
855
|
+
not accepted.
|
|
856
|
+
- Disclosures handed over with a page that is not a slip were ignored.
|
|
857
|
+
They are now refused; disclosures for a slip that is not there are
|
|
858
|
+
pointed out.
|
|
859
|
+
- The command-line checker and the page did not show how often a slip
|
|
860
|
+
may be passed on. They do now.
|
|
861
|
+
- The type declarations said a covered name is always text, and left
|
|
862
|
+
out the pass on a helper's stub. Both are corrected.
|
|
863
|
+
- Also: a disclosure for a slip must be JSON in the canonical form, so
|
|
864
|
+
that two checkers cannot read one disclosure in two ways.
|
|
865
|
+
|
|
866
|
+
- 2026-10-03: `openRecorder`, the stub writer beside an agent. It keeps the
|
|
867
|
+
agent's place in its chain, asks the check before acting, takes the
|
|
868
|
+
action only if the answer is yes, and writes the stub.
|
|
869
|
+
- 2026-10-03: faults found by a third independent review, of the seal
|
|
870
|
+
and the time-stamp. Each is fixed and each is now a test
|
|
871
|
+
(`test/review3.test.mjs`). The review found no way to have a time-stamp
|
|
872
|
+
counted without the trusted service's key, and nothing that crashed.
|
|
873
|
+
- A Show under a seal did not report a page dated after the time-stamp
|
|
874
|
+
that covers it. It does now, for a countersignature's and an
|
|
875
|
+
approval's date too.
|
|
876
|
+
- A seal shown as a single page was compared with nothing. Its place is
|
|
877
|
+
now checked, the page says it could not be compared, and its
|
|
878
|
+
time-stamp is credited to no other page.
|
|
879
|
+
- On the checking page, a line that was not a fingerprint was dropped,
|
|
880
|
+
which switched the check off. It now stops the check and says which
|
|
881
|
+
box.
|
|
882
|
+
- A time-stamp from a service nobody named could make a sound record
|
|
883
|
+
fail. It is now compared with nothing.
|
|
884
|
+
- A time-stamp is now read in full and must be strict DER, laid out as
|
|
885
|
+
its standards set out. It must name the certificate that signed it,
|
|
886
|
+
in its signed part; that certificate, wherever it sits, is the one
|
|
887
|
+
that counts. A time-stamp that states its time too loosely, or carries
|
|
888
|
+
an extension it insists on, is refused.
|
|
889
|
+
- A seal dated before an entry it covers, and a later seal time-stamped
|
|
890
|
+
before an earlier one, are reported.
|
|
891
|
+
- A time-stamp is credited only when all three signatures of the seal
|
|
892
|
+
were checked.
|
|
893
|
+
- A name padded with spaces could wrap into a line that looked like the
|
|
894
|
+
checker's own. Runs of spaces are now shown as one.
|
|
895
|
+
- Smaller: the same time-stamp twice is refused; checking a time-stamp
|
|
896
|
+
no longer changes the caller's copy; a small file can no longer cost
|
|
897
|
+
much work.
|
|
898
|
+
- 2026-10-03: passing a slip on. A slip can allow its agent to hand part
|
|
899
|
+
of its permission to a helper agent, up to three times in a row. The
|
|
900
|
+
pass is a new record, signed by the agent that passes on. A helper's
|
|
901
|
+
stubs form a chain of their own and are compared with the pass and with
|
|
902
|
+
the slip; the slip's totals take in the agent and every helper
|
|
903
|
+
together. New codes: `pass-missing`, `pass-mismatch` (refused);
|
|
904
|
+
`pass-not-allowed`, `pass-wider` (reported).
|
|
905
|
+
- 2026-10-03: covered fields. A slip can be written with its names and
|
|
906
|
+
its purpose covered, by the standard "Selective Disclosure for JSON Web
|
|
907
|
+
Tokens" (RFC 9901) as it stands. A reader sees a covered field only if
|
|
908
|
+
handed its disclosure; the signature, the chain and the tree check
|
|
909
|
+
either way. The standard's worked example is a test, with every case
|
|
910
|
+
the standard says must be rejected. New: `prepareSlip(fields, { cover })`,
|
|
911
|
+
the `disclosures` option, disclosures on a page of a Show,
|
|
912
|
+
`--disclosures`, and the code `cover-invalid`.
|
|
913
|
+
- 2026-10-03: type declarations for the whole library, for the checker
|
|
914
|
+
alone and for the browser's passkey part. Checked once with a type
|
|
915
|
+
checker against a developer's use of the library; a test keeps them in
|
|
916
|
+
step with what the library exports.
|
|
917
|
+
- 2026-10-03: cancelling a slip, and vouching for a name.
|
|
918
|
+
- The person who signed a slip can cancel it with the same passkey, and
|
|
919
|
+
have the cancellation time-stamped at once. Stubs after it are
|
|
920
|
+
reported (`after-cancellation`). With a time-stamp on the
|
|
921
|
+
cancellation, a stub counts as earlier only if an outside time-stamp
|
|
922
|
+
shows that it existed by then.
|
|
923
|
+
- A vouching record: an organisation states that a key belongs to a
|
|
924
|
+
name, for a person, an agent, a service or a recorder. The person
|
|
925
|
+
checking says which organisations they trust (`vouchers`,
|
|
926
|
+
`--voucher`), and a name those vouch for is shown as vouched for.
|
|
927
|
+
The organisation can withdraw the record.
|
|
928
|
+
- A slip may state the fingerprints of the agent's program and
|
|
929
|
+
settings. It is shown as a statement, not as proof of what ran.
|
|
930
|
+
- Three new records, with their own labels: the cancellation, the
|
|
931
|
+
vouching record and the withdrawal.
|
|
932
|
+
- 2026-10-03: faults found by a second independent review, of the
|
|
933
|
+
framework of limits. Each is fixed and each is now a test. The review
|
|
934
|
+
found no way to make a whole book read as intact, or as within its
|
|
935
|
+
slip, when it was not.
|
|
936
|
+
- The check before acting allowed an action dated before the last stub,
|
|
937
|
+
which then broke the book. It allowed an action on a device that
|
|
938
|
+
could check only one signature of two. It allowed an action under a
|
|
939
|
+
slip signed by any key. It now refuses all three, must be told whose
|
|
940
|
+
passkey it trusts, and where the slip asks for the person's approval
|
|
941
|
+
allows the action only with the signed approval in hand.
|
|
942
|
+
- A Show did not say that single pages cannot show an approval used
|
|
943
|
+
twice. It now says so.
|
|
944
|
+
- A stub or a refusal under a slip that the device could not confirm
|
|
945
|
+
was shown as if it were evidence. It is now hidden.
|
|
946
|
+
- A service's terms signed by a stranger, under the service's name,
|
|
947
|
+
were shown with nothing to tell them apart. Terms and refusals now
|
|
948
|
+
show the fingerprint of the keys that signed them.
|
|
949
|
+
- An approval's own date was compared with nothing and shown nowhere.
|
|
950
|
+
It is now shown, and an approval dated later than its stub is
|
|
951
|
+
refused (`approval-dated-after-stub`).
|
|
952
|
+
- Characters that cannot be seen (zero-width characters, soft hyphens,
|
|
953
|
+
line separators) passed through to the screen. They are now shown as
|
|
954
|
+
a mark, as control characters already were.
|
|
955
|
+
- The name of an unknown field was copied into the message about it.
|
|
956
|
+
No word from a record goes into a message now.
|
|
957
|
+
- The format description said less than the code about which letters a
|
|
958
|
+
unit and an action name may hold. It now says the same.
|
|
959
|
+
- Smaller: an approval whose number equals another record's number was
|
|
960
|
+
called "reused"; terms could accept what they forbid; a service could
|
|
961
|
+
not write down a refused request for an unlisted reserved name; a
|
|
962
|
+
period kept everything it had ever counted in memory.
|
|
963
|
+
- 2026-10-03: the Seal and the outside time-stamp.
|
|
964
|
+
- A seal is a new record: whoever keeps a book signs its top
|
|
965
|
+
fingerprint and its number of entries, with three signatures
|
|
966
|
+
(Ed25519, ML-DSA-87 and SLH-DSA-SHA2-256s). Each seal names the one
|
|
967
|
+
before it.
|
|
968
|
+
- A seal may carry up to four time-stamps in the standard form of RFC
|
|
969
|
+
3161. The checker reads them offline with a small strict reader of
|
|
970
|
+
its own, and trusts a service only by the fingerprint of its
|
|
971
|
+
certificate, which the person checking gives. No service is named
|
|
972
|
+
anywhere.
|
|
973
|
+
- The latest stubs before a seal can no longer be removed unnoticed. An
|
|
974
|
+
entry dated later than the time-stamp that covers it is reported.
|
|
975
|
+
- A Show can be made under a seal, and then proves when its pages
|
|
976
|
+
existed with no other copy of the top fingerprint.
|
|
977
|
+
- New options: `sealKeys`, `stampServices`, `--sealer`,
|
|
978
|
+
`--stamp-service`. The checking page has boxes for what the person
|
|
979
|
+
trusts.
|
|
980
|
+
- Tested against time-stamps made by the OpenSSL program.
|
|
981
|
+
- What is still open: the last seal, with everything after it, can be
|
|
982
|
+
removed unnoticed, unless someone else holds a copy.
|
|
983
|
+
- 2026-10-03: a framework of limits, in five layers.
|
|
984
|
+
- Amounts: besides a total, a slip can limit each single action, the
|
|
985
|
+
number of actions, and a total or a number within any period.
|
|
986
|
+
- Boundaries: a slip can ask that the other side countersign an action.
|
|
987
|
+
- Approvals: a slip can ask for the person's own approval of an action,
|
|
988
|
+
always or above an amount. The approval is a new record, signed with
|
|
989
|
+
the same passkey as the slip, for exactly one action.
|
|
990
|
+
- Stated rules: a slip can name kinds of action the agent must never
|
|
991
|
+
do, which a checker compares with the stubs, and rules of conduct,
|
|
992
|
+
which are the person's signed instruction.
|
|
993
|
+
- The other side's records: a service can sign a refusal, and its terms
|
|
994
|
+
for agents. Both are new records.
|
|
995
|
+
- A shared list of 30 action names in 8 kinds, a first draft. Names
|
|
996
|
+
that begin `provared.` are reserved for it.
|
|
997
|
+
- `checkBefore`: would this action be outside the slip? It uses the
|
|
998
|
+
checker's own comparison.
|
|
999
|
+
- The demonstration and the sample record show all of these. The
|
|
1000
|
+
person approves one order with the passkey.
|
|
1001
|
+
- Every slip now holds `requires` and `never`, so a draft slip written
|
|
1002
|
+
before this change no longer checks.
|
|
1003
|
+
- 2026-10-03: the quantum-safe method for agents and services is now
|
|
1004
|
+
ML-DSA-87, the strongest of the three strengths of FIPS 204, in place
|
|
1005
|
+
of ML-DSA-65. The test uses the ML-DSA-87 worked example of RFC 9964.
|
|
1006
|
+
The sample record was made again. A key set is larger, so one slip now
|
|
1007
|
+
holds about a dozen services with keys at most.
|
|
1008
|
+
- 2026-10-03: the checking page marks the agent's name and the services'
|
|
1009
|
+
names as labels that are not checked, as it already did for the
|
|
1010
|
+
person's name.
|
|
1011
|
+
- 2026-10-03: faults found by an independent review, each fixed and each
|
|
1012
|
+
now a test.
|
|
1013
|
+
- A small record made with no key crashed the checker (content whose
|
|
1014
|
+
"type" was not text). Nothing from a record is put into a message
|
|
1015
|
+
unchecked any more, and anything the checker does not expect is
|
|
1016
|
+
reported as the problem `check-failed`, never as a pass.
|
|
1017
|
+
- "Intact" was reported on a device that could check no signature. It
|
|
1018
|
+
is now said only when no problem was found and every signature was
|
|
1019
|
+
checked; `summary.problemFound` says whether a problem was found. An
|
|
1020
|
+
entry none of whose signatures could be checked is not shown and not
|
|
1021
|
+
compared with its slip.
|
|
1022
|
+
- A Show reported "within its slip" for a single stub over the limit.
|
|
1023
|
+
- "Every signature checked" was reported when nothing was checked.
|
|
1024
|
+
- A flood of line feeds could end the process. Lines are now counted as
|
|
1025
|
+
they are split.
|
|
1026
|
+
- A trusted top fingerprint was ignored for a book, and a trusted number
|
|
1027
|
+
of entries could not be given: `expectedRoot`, `expectedSize`,
|
|
1028
|
+
`--root`, `--size`.
|
|
1029
|
+
- The writers could make a slip too large for the checker.
|
|
1030
|
+
- `--json` printed characters that can disturb a terminal; the page did
|
|
1031
|
+
not neutralise characters that reorder text.
|
|
1032
|
+
- Smaller: an RSA key of 2,041 bits was accepted; lengths were counted
|
|
1033
|
+
in a way that differs between languages; the threat model said only
|
|
1034
|
+
"the end" of a book could be removed.
|
|
1035
|
+
- 2026-10-03: a damaged record no longer reads as "every signature
|
|
1036
|
+
checked"; what a failed entry says is no longer shown.
|
|
1037
|
+
- 2026-10-03: the pages no longer scroll sideways on a phone; times are
|
|
1038
|
+
shown in words.
|
|
1039
|
+
- 2026-10-03: the first build.
|
|
1040
|
+
- `docs/threat-model.md`: who might attack a record, what each part
|
|
1041
|
+
protects and what it does not, written before the code.
|
|
1042
|
+
- `spec/provared-format.md`: the format, draft version 0: the Slip, the
|
|
1043
|
+
Stub, the countersignature, the chain, the book, the tree and the
|
|
1044
|
+
Show.
|
|
1045
|
+
- `src/`: the checker (`checkBook`, `checkShow`, `checkSlip`) and the
|
|
1046
|
+
writers (`prepareSlip`, `assembleSlip`, `writeStub`, `countersign`,
|
|
1047
|
+
`writeBook`, `makeShow`), with no dependencies. Agents and services
|
|
1048
|
+
sign with Ed25519 and ML-DSA-65 together; a person signs a slip with
|
|
1049
|
+
a passkey.
|
|
1050
|
+
- `bin/provared-check.mjs`: the checker for the command line.
|
|
1051
|
+
- `page/`: the checking page and the demonstration page.
|
|
1052
|
+
- `demo/`: the demonstration, an invented office agent that orders
|
|
1053
|
+
supplies within a limit, with a local server.
|
|
1054
|
+
- `samples/`: a sample record written once, and what a checker must
|
|
1055
|
+
find in it.
|
|
1056
|
+
- `test/`: the tests, including the worked examples of RFC 8032, RFC
|
|
1057
|
+
8037, RFC 9964 and the test trees of RFC 6962, and one test for every
|
|
1058
|
+
refusal the threat model lists.
|
|
1059
|
+
- Licences: Apache License 2.0 for the code, Creative Commons
|
|
1060
|
+
Attribution 4.0 for the documents.
|
|
1061
|
+
- 2026-10-03: the folder created; no code yet.
|
|
1062
|
+
- 2026-10-03: named Provared.
|