Initial implementation of the DateKeys Protocol v0.8.1
Reference implementation in Go, built from the implementation plan
(milestones M0 to M5): datekey, profile, provider, codec, agewrap,
extension, capsule, accesskey, the datekeys CLI, official vectors and
fixtures, the mutation corpus, fuzz targets, interop and live tests,
CI workflows, traceability and policy documents.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 weeks ago
|
|
|
package datekeys_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
datekeys "g.activething.com/go/DateKeys"
|
Initial implementation of the DateKeys Protocol v0.8.1
Reference implementation in Go, built from the implementation plan
(milestones M0 to M5): datekey, profile, provider, codec, agewrap,
extension, capsule, accesskey, the datekeys CLI, official vectors and
fixtures, the mutation corpus, fuzz targets, interop and live tests,
CI workflows, traceability and policy documents.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 weeks ago
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// The catalogue matches spec §69 exactly, in order.
|
|
|
|
|
func TestCatalogueMatchesSpec(t *testing.T) {
|
Version constants: the specification and the module
- datekeys.SpecVersion ("0.8.2") names the specification the module
implements. A test ties it to the spec file, its title and
spec/README.md, and TestCatalogueMatchesSpec and the vector files use
it (testkit.SpecVersion now aliases it), so the vectors regenerate
unchanged.
- datekeys.Version() is the version of the module as the go command
recorded it. That is a tag, or for a binary built in a checkout the
pseudo-version of its commit (for example
v0.0.0-20260928105528-9ac9cd952f04), or (devel) when it is unknown, as
in tests or under a replace directive to a directory. It works as the
main module and as a dependency, whatever the module path, which it
reads from the root package.
- `datekeys version` (also -version and --version) prints both and the
Go toolchain.
- README.md and README.es.md explain the three versions (format,
specification, module) and what the code on main covers.
traceability §70 and CHANGELOG follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
spec, err := os.ReadFile("spec/DateKeys_Protocol_Specification_v" + datekeys.SpecVersion + ".md")
|
Initial implementation of the DateKeys Protocol v0.8.1
Reference implementation in Go, built from the implementation plan
(milestones M0 to M5): datekey, profile, provider, codec, agewrap,
extension, capsule, accesskey, the datekeys CLI, official vectors and
fixtures, the mutation corpus, fuzz targets, interop and live tests,
CI workflows, traceability and policy documents.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 weeks ago
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
s := string(spec)
|
|
|
|
|
start := strings.Index(s, "## 69. Errores normativos")
|
|
|
|
|
end := strings.Index(s, "## 70.")
|
|
|
|
|
if start < 0 || end < start {
|
|
|
|
|
t.Fatal("section 69 not found")
|
|
|
|
|
}
|
|
|
|
|
var want []string
|
|
|
|
|
for _, line := range strings.Split(s[start:end], "\n") {
|
|
|
|
|
if line = strings.TrimSpace(line); strings.HasPrefix(line, "ERR_") {
|
|
|
|
|
want = append(want, line)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var got []string
|
|
|
|
|
for _, e := range datekeys.All() {
|
|
|
|
|
got = append(got, e.Code())
|
|
|
|
|
}
|
|
|
|
|
if strings.Join(got, ",") != strings.Join(want, ",") {
|
|
|
|
|
t.Fatalf("catalogue\n got %v\nwant %v", got, want)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestCode(t *testing.T) {
|
|
|
|
|
err := fmt.Errorf("capsule: step 8: %w", fmt.Errorf("agewrap: %w", datekeys.ErrRoundMismatch))
|
|
|
|
|
if datekeys.Code(err) != "ERR_ROUND_MISMATCH" || !errors.Is(err, datekeys.ErrRoundMismatch) || errors.Is(err, datekeys.ErrIntegrity) {
|
|
|
|
|
t.Fatal("wrapping")
|
|
|
|
|
}
|
Spec v0.8.2: second-round corrections from the formal review
The second round of the formal review confirmed the nine corrections of
c57ed48 and asked for these, recorded in §76 as corrections 4 to 6 and
an editorial note:
- §72: an encoder MUST NOT write a registered extension in an object or
array it is not registered for; §54: a reader MUST NOT interpret the
data of a noncritical one it ignores for that reason. capsule.Encrypt
and accesskey.Encode take no Registry, so the application applies the
rule; their documentation and extension.Placement say so.
- §17 and §51 give the step-10 codes only for a directly supplied
release, as step 10 does; a network source discards a failing one at
step 9.
- Step 9 reports ERR_RELEASE_UNAVAILABLE and no other code, whatever the
failure of the source. provider/drand.Client keeps each relay's failure
as text only (errors.Join made a relay's ERR_ROUND_MISMATCH match with
errors.Is), and capsule.Open keeps only the text of a source error that
carries another code (a caller's source failing with
ERR_RELEASE_INVALID gave that code at step 9). A context that ended
stays detectable: Fetch now has a single failure path, so the canceled
and deadline cases are deterministic.
- TestExtensionPlacement covers the noncritical array of a .dkk: with
the object-blind extension.CheckNoncritical at step 9.a it fails.
- Editorial: §28.1 "analizan solo la cabecera age", one arrow at step 9,
two §76 introductions; §73 lines for release sources and placement.
- testdata/README.md says the corpus registers its extensions in both
arrays of every object; traceability, CHANGELOG and both READMEs
(integrity holds against whoever lacks the file keys, §27, §55.1)
follow. Spec dated 28 September 2026; new SHA-256 in spec/README.md.
No fixture or vector changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
// The failure of a relay kept as text, as provider/drand.Client keeps
|
|
|
|
|
// it, adds no code: the error wraps exactly one normative error.
|
|
|
|
|
relays := fmt.Errorf("drand: no relay returned a verified release for round 1000: %v: %w",
|
|
|
|
|
fmt.Errorf("relay: %w", datekeys.ErrRoundMismatch), datekeys.ErrReleaseUnavailable)
|
|
|
|
|
if datekeys.Code(relays) != "ERR_RELEASE_UNAVAILABLE" || errors.Is(relays, datekeys.ErrRoundMismatch) || !strings.Contains(relays.Error(), "ERR_ROUND_MISMATCH") {
|
|
|
|
|
t.Fatal("a failure kept as text")
|
|
|
|
|
}
|
|
|
|
|
// No error of this module wraps two codes. For one from elsewhere, such
|
|
|
|
|
// as the error of a caller's release source, Code returns the first in
|
|
|
|
|
// the tree.
|
|
|
|
|
joined := fmt.Errorf("source: %w: %w", datekeys.ErrReleaseUnavailable, errors.Join(errors.New("x"), datekeys.ErrReleaseInvalid))
|
|
|
|
|
if datekeys.Code(joined) != "ERR_RELEASE_UNAVAILABLE" {
|
Initial implementation of the DateKeys Protocol v0.8.1
Reference implementation in Go, built from the implementation plan
(milestones M0 to M5): datekey, profile, provider, codec, agewrap,
extension, capsule, accesskey, the datekeys CLI, official vectors and
fixtures, the mutation corpus, fuzz targets, interop and live tests,
CI workflows, traceability and policy documents.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 weeks ago
|
|
|
t.Fatal("joined errors")
|
|
|
|
|
}
|
|
|
|
|
if datekeys.Code(errors.New("plain")) != "" || datekeys.Code(nil) != "" {
|
|
|
|
|
t.Fatal("non-DateKeys errors have no code")
|
|
|
|
|
}
|
|
|
|
|
if datekeys.ErrIntegrity.Error() != "ERR_INTEGRITY" {
|
|
|
|
|
t.Fatal("message")
|
|
|
|
|
}
|
|
|
|
|
data := fmt.Errorf("capsule: step 4: %w", datekeys.ErrExtensionDataInvalid)
|
|
|
|
|
if datekeys.Code(data) != "ERR_EXTENSION_DATA_INVALID" || errors.Is(data, datekeys.ErrExtensionCriticalUnknown) {
|
|
|
|
|
t.Fatal("ERR_EXTENSION_DATA_INVALID")
|
|
|
|
|
}
|
Initial implementation of the DateKeys Protocol v0.8.1
Reference implementation in Go, built from the implementation plan
(milestones M0 to M5): datekey, profile, provider, codec, agewrap,
extension, capsule, accesskey, the datekeys CLI, official vectors and
fixtures, the mutation corpus, fuzz targets, interop and live tests,
CI workflows, traceability and policy documents.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 weeks ago
|
|
|
}
|