/inspect shows the public note under the verdict, as text of the creator
that nobody checked, with the warning of Go's showNote. The pages no longer
show the message of an unexpected exception: unexpectedProblem says in
Spanish what to do, and logs the exception. vite.config.ts pre-bundles the
dependencies the pages load on demand, so that the dev server does not
reload the page on the first opening and break the import in flight.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As the spec v0.11 draft decides after its review (38.1), and as the Go
reference does from 2213b8c:
- dkc/wordkey.ts replaces inspector/wordkey.ts. The salt carries the
capsule_id too, so the same words give another key in each capsule;
the words are lowered with the new LOWERCASE table of pathrule.ts,
loaded on demand; checkWords refuses controls, invisible and
unassigned code points and counts only different words of three
letters or more, with the errors of Go. New vector of 38.1.
- encryptFiles takes the words and derives their key once it has drawn
capsule_id; the creator passes them, and the opener salts them with
the capsule_id of the capsule.
- /create asks for the words twice and shows how they are kept; the form
checks them with the tables of the platform, and the writer again with
those of Unicode 18.0.0.
- The tables, regenerated with the lower case, and testdata synced from
2213b8c; the frozen texts of Go for the invalid options, updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The author wanted a key that people can keep without files. A capsule
"solo con una llave" can now take words the person chooses, at least
six, on /create, and /inspect opens it with them. wordkey.ts derives
the X25519 identity with PBKDF2-SHA256 of Web Crypto, 600 000 rounds,
salted with the chain and the round of the capsule, after making case,
accents and extra spaces not matter; its public key is one more
recipient, so the format does not change. The writer wipes the private
half at once; the opener adds it to the identities it tries.
Checked in Chromium: a capsule created with "Perro luna casa verde
trén mar" and no .dkk opened with "perro LUNA casa verde tren mar",
with the release fetched from drand by the page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The author found copying the release of the round tedious. A button,
"Pedir la firma a drand", fetches it from the three public relays of
the CLI of the reference, as its client does: raced, 6 s, at most
8 KiB an answer, no redirects, and the randomness checked against the
signature; step 10 still verifies the signature with the pinned key,
so a relay cannot make the page accept a false one. It is the only
connection the page makes to another site, and only on that click: the
CSP allows those three origins in connect-src, check-build.mjs
requires exactly them, and the footer says so. Pasting by hand still
works. Checked in Chromium: api2.drand.sh gave the release of round
32668196 and the capsule opened.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The drop zone stretched to the height of the list of test capsules
beside it, with its words lost in the middle of the screen, and that
list, developer material in English, filled the page. Now the page
asks for the capsule in one column, with a drop zone of its own size,
and the examples are folded under "Probar con una cápsula de ejemplo".
The menu says "Abrir", and the fields of a capsule that needs a key
speak of the key and of the secret key of age, as /create does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The author found the pages too technical and did not want a dark
background. With the frontend design guidance:
- The site is always light, whatever the system asks.
- A capsule is a letter posted to the future: white paper, blue ink,
an old-style serif for the voice of the page (Palatino, Iowan) and a
DIN-like sans for the form (Bahnschrift), all system fonts, as the
CSP allows no other origin. Blue is what you act on.
- /create asks three questions, with short sentences: what it keeps,
when it opens, who can open it. The date it opens is set large on an
airmail envelope with the button that creates the capsule; quick
dates of 1, 5 and 10 years; sizes in KB and MB; everything technical
folded in "Detalles técnicos". The messages of the rules no longer
name R4 or §29.6.
Fixes of the review of the pages:
- /inspect labels the start of a single file as content of the
creator, unchecked, so that it cannot pass for a verdict; keeps ZWNJ
and ZWJ in the comment and the author, which R4b allows; and says
the right thing without files and without a comment.
- /create pins at most 500 more rows with problems and counts the
rest; shows what happened with a drop, not only to screen readers;
a comment or an author over its limit is its own problem, not that
of the files; a writing cannot start after the page is destroyed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The page opens capsules of format 3. The files go to the temporary
file through a ZipSink, a lone file of one segment as it is and a ZIP
otherwise, or to memory; the page shows the verdicts first, then the
declared author and the comment as unchecked text of the creator, and
then each path as text in a bdi, with its size, its mtime and the
warnings of the CLI of the reference, compared by their key of R7.
- files.ts: pathWarnings, fileFacts, and the names and order of the
downloads: the file itself when it is the only one, with the ZIP of
its folder second (decision 8), or the ZIP and each file.
- opener.ts: OpenedFiles, and noRoom when the ZIP does not fit.
- zipsink.ts: NoRoom, thrown by begin before writing anything.
- check-build.mjs: the tables of pathrule-tables.ts never come with
the first load of a page, and do come with the code on demand of
/inspect and /create.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Syncs testdata with datekeys-go at the tag spec-v0.10 (cc35d2c) and
moves the reader to the DateKeys Protocol Specification v0.10. The
three capsule formats are read.
- framing: FORMAT_3, and isPadded for formats 2 and 3. control: schema
version 3, with the keys 6 and 7 of version 2. SPEC_VERSION is 0.10.
- open: OpenOptions.sink receives the files of a format 3 capsule
(sink.ts: Sink with begin, create, commit and abort, as capsule.Sink,
and MemorySink). Without one, open rejects with a TypeError right
after step 2, before any request, as ErrSinkRequired. Opened gains
head, verdicts, areaLen and unusableHeadExtensions.
- open3.ts: step 17 of format 3 in its substeps 17.2 to 17.8, as
openBody of the reference: a failure of age or a plaintext whose
length is not P prevails, the first failing substep decides, and the
codes other than ERR_INTEGRITY are reported only after reading
PAYLOAD_AGE to its end. Reads grow with the bytes received, never
with the lengths BODY declares. A failure of the sink is ERR_INTEGRITY
with its text, and the sink is aborted once after begin.
- The page: opener.ts opens the fixtures of format 3 into a
MemorySink; the open panel says that it does not deliver their files
yet, and the glosses of the steps name format 3. check-build.mjs
refuses to ship the heads, salts, comments and paths of the format 3
fixtures.
Tests: the 21 fixtures, format 3 laid out byte by byte from its record
and opened into a sink with its files and verdicts; the 209 cases of
the corpus from memory and from a Blob, with the code, the step and,
new, the exact text of capsule.Open, frozen by
scripts/mutation-go-texts.go in testing/mutation-texts.json, which
replays the corpus as internal/testkit does (its extension validator
texts included); the 5110 differential cases over 14 bases; paths,
path_fold, head_schema and security vectors; the control of schema
version 3 in cbor.json; and step 17 on crafted plaintexts sealed again
to I_PAYLOAD, whose texts capsule.Open gives on the same plaintexts.
ibe-vectors.json gains the nine format 3 fixtures from
scripts/ibe-go-vectors.go; the twelve before are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a capsule opens, /inspect now shows its content right under the
verdict, before steps 9 to 18. A capsule does not keep the name of the
file it seals (spec §6, §55.2), and the capsula-<date>.dkc of /create
has no extension of its own, so the download was nameless for the
system: contentExtension now gives it .txt for a text, or the
extension of a common type of file by its first bytes (.pdf, .png,
.jpg, .zip…).
vite preview served the pages without Cache-Control, and a tab
reloaded after a build could keep the old page, whose chunks are gone;
a small plugin, before SvelteKit's, has the pages revalidated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/inspect showed the plaintext only of the official fixtures; a capsule
of one's own was only offered for download. Now the start of the
plaintext is shown whenever the capsule opens and it is text:
opener.ts reads its first 128 KiB (PREVIEW_BYTES), from memory or from
the temporary file, and plaintextPreview in opening.ts shows up to
100 000 characters of printable UTF-8, cut on a whole character. A text
written on Windows shows too: CR LF as a line feed, no BOM. The
download keeps the exact bytes.
The pages now explain age keys: /create, in a folding block, what an
age1… recipient is and how to get one with age-keygen; /inspect, next
to the identities, which line of the age-keygen file to paste.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After steps 1 to 8, a valid capsule whose date has passed on the device
clock can be opened in the page: steps 9 to 18 of spec section 63 with
open, loaded on demand with a dynamic import (opener.ts), so noble and
age-encryption stay out of the first load of every page.
- The release is supplied directly by the person (spec 63, step 10):
drand's JSON answer or the bare signature, pasted after opening the
drand URL the page links to, or the release in the record of an
official fixture. The page never fetches it and reads only its round
and signature (spec 11, 13). The CSP is unchanged.
- time_and_key credentials: a .dkk (readAccessKey reads at most
12 bytes + 16 MiB + 1) or age identities, one per line.
- The plaintext of the person's own file goes to a temporary OPFS file
(tempfile.ts), committed only after step 18 (spec 56), offered for
download and deleted on request, with another capsule, on pagehide
and, if left over, on the next visit. One directory and one Web Lock
per tab keep other tabs' clean-up away from files in use. Without
OPFS, or when the browser refuses it, capsules up to 64 MiB open in
memory. An opening in progress stops when another capsule is loaded.
- opening.ts builds the page model of steps 9 to 18 as the reference
records them; fixtures show their plaintext and compare its SHA-256
with their record.
- licenses.txt: the notices of tlock-js (ibe.ts) and age (bech32.ts),
the license of every package in the client bundle, Vite's and
rolldown's runtime code, and the site's own license. check-build now
fails if a notice is missing, or if a page loads noble, @scure/base
or age-encryption with its first load.
- The home page no longer says that the page never asks for keys.
Checked in the browser on the production build: the time_only,
time_and_key_portable (with its .dkk) and time_and_key_recipients (with
a pasted identity) fixtures open with the SHA-256 of their records; a
tampered signature fails at step 10 and a tampered STREAM chunk at step
17, with no download and no file left; an own file opens to OPFS,
downloads without a CSP violation and is deleted with its lock; a left
over directory goes on the next visit; no request leaves the origin.
An adversarial review (four dimensions, each finding checked by a
refuter) confirmed 15 findings, all fixed here.
2611 tests; coverage 100 % of the new modules, now a threshold.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>