@flashyos/artifact
v0.1.0
Published
artifact/1 — a dated public commitment to content nobody can read yet. Existence precedes discovery.
Maintainers
Readme
artifact/1
A dated public commitment to content nobody can read yet.
Existence precedes discovery. An artifact sealed today is provably older than the day somebody opens it, and no amount of later effort manufactures that gap. That is the whole property, and it is why this format is worth starting before the thing built on top of it is designed: its value is elapsed time, so the cost of delay is measured in years rather than sprints.
npm i @flashyos/artifactimport { seal, opens, salt, problems } from '@flashyos/artifact';
const s = salt(); // 128 bits. Keep it with the secret.
const a = seal({
property: 'flashyos.com',
createdBy: 'agent/claude', // public from day one
condition: 'Read the source of the page that says it does not know the answer.',
secret: 'the content nobody can read yet',
salt: s,
});
problems(a); // [] — every way a record can be wrong, as codes
opens(a, s, 'a guess'); // falseWhat is public, and why all of it is
The commitment, property, creator, date and discovery condition are public from the moment of sealing. Only the content is hidden.
That split is a governance requirement rather than an aesthetic one. A primitive that let an agent write sealed, undisclosed material into an organisation's archive with no way to enumerate what exists is a control weakness — an auditor, an acquirer or counsel will ask, and they should.
So the mystery is what an artifact says, never whether it is there. Anyone can list every sealed artifact, who sealed it and when. Nobody can read one early.
A salt is required
bolt/1 commits to ten shards of [A-Z]{4,12} joined by hyphens. As an ordered
set of ten that is safe. A single short secret under a bare sha256 is not:
an attacker holding the commitment runs a dictionary and opens it in seconds, and
an artifact anyone can brute-force is discovered by whoever owns the most compute
rather than by whoever went looking.
Every seal carries 128 bits of unpublished salt and seal() refuses less. Salt
is per-artifact, so an observer cannot notice that the same word is hidden in two
places — which would leak the shape of a puzzle without opening any of it.
What it refuses
Each refusal is a property somebody would otherwise discover was missing years later, which is the one timescale on which nothing can be repaired.
| Refusal | Why |
|---|---|
| A created date in the future | The entire claim is that the artifact is at least as old as it says |
| A createdBy that is not agent/… or person/… | Existence must be auditable even when content is not |
| An empty condition | A puzzle nobody can attempt is not one |
| An empty property | An artifact hidden nowhere cannot be found |
| Salt under 128 bits, or not hex | See above |
| A record carrying secret, salt or preimage | The failure that would make the format theatre — checked over the serialised bytes, because a type says nothing about what an emitter wrote |
| An id that does not derive from its own commitment | An id somebody picks is one somebody can reuse; a renamed artifact wearing an old date is the forgery this prevents |
opens() is constant-time, for the same reason bolt/1 never says which
shard was wrong: a check that narrows the answer is brute-forceable in a way the
whole answer is not.
What it is not
It is not proof of when anything happened. The publisher computes the commitment, publishes it and holds the secret; nothing here stops a publisher backdating a record they control. What makes a date checkable is a witness who is not the publisher — a head cosigned into a public append-only medium the publisher does not control.
That is deliberately outside this package, so nobody reading it mistakes a commitment for a timestamp.
Apache-2.0.
