The generated contracts write date-time as time.Time (seatgen of B5d); the conditions and vault clients follow (ADR 0634; issue 1966)

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-05 15:06:14 +01:00
parent 25da1f8879
commit 181441e91b
14 changed files with 194 additions and 173 deletions
+26 -25
View File
@@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"strings"
"time"
)
// Seat is the seat's name.
@@ -348,7 +349,7 @@ func DecodeFindingsByKeyValue(raw []byte) (FindingsByKeyValue, error) {
// AccountsHanded is the hashes of the users of the list, sealed to the vault.
type AccountsHanded struct {
// when
At string `json:"at"`
At time.Time `json:"at"`
Box SealedBox `json:"box"`
From string `json:"from"`
// the fingerprint of the vault's key
@@ -557,8 +558,8 @@ type FailedUnit struct {
Result string `json:"result,omitempty"`
Scope string `json:"scope"`
// since when
Since string `json:"since"`
Unit string `json:"unit"`
Since time.Time `json:"since"`
Unit string `json:"unit"`
}
// FindingAction is one answer the operator may give from a notification.
@@ -579,8 +580,8 @@ const (
// FindingEvidence is one observation, as it was said.
type FindingEvidence struct {
At string `json:"at"`
Said string `json:"said"`
At time.Time `json:"at"`
Said string `json:"said"`
}
// FindingSubject is what the condition is about.
@@ -598,10 +599,10 @@ type FindingSubject struct {
// LoginFallback is a login that fell back to another node.
type LoginFallback struct {
// when
At string `json:"at"`
From string `json:"from"`
Node string `json:"node"`
Why string `json:"why"`
At time.Time `json:"at"`
From string `json:"from"`
Node string `json:"node"`
Why string `json:"why"`
}
// ManifestReadsChanged is what a node-engine says when what it reads changed or its node returned (ADR 0618 §4).
@@ -651,7 +652,7 @@ const (
type NetworkHealth struct {
Parts []NetworkPart `json:"parts"`
// since when
Since string `json:"since"`
Since time.Time `json:"since"`
// running, degraded or unknown
State string `json:"state"`
}
@@ -663,12 +664,12 @@ type NetworkPart struct {
Reason string `json:"reason,omitempty"`
Said string `json:"said,omitempty"`
// since when
Since string `json:"since"`
State string `json:"state"`
Streak int64 `json:"streak,omitempty"`
Targets []string `json:"targets,omitempty"`
Toward []string `json:"toward,omitempty"`
Writer string `json:"writer,omitempty"`
Since time.Time `json:"since"`
State string `json:"state"`
Streak int64 `json:"streak,omitempty"`
Targets []string `json:"targets,omitempty"`
Toward []string `json:"toward,omitempty"`
Writer string `json:"writer,omitempty"`
}
// NodeAccount is an account the node needs to log in again.
@@ -678,7 +679,7 @@ type NodeAccount struct {
Reason string `json:"reason"`
Resource string `json:"resource,omitempty"`
// since when
Since string `json:"since"`
Since time.Time `json:"since"`
}
// NodeDirectory is a directory found where the node expected none.
@@ -688,7 +689,7 @@ type NodeDirectory struct {
Reason string `json:"reason"`
Resource string `json:"resource"`
// since when
Since string `json:"since"`
Since time.Time `json:"since"`
}
// NodeOwn is what a node's own composition carries beside its resources.
@@ -744,14 +745,14 @@ type PlacedDataItem struct {
// PullWait is the pull from a store a failed apply waits on.
type PullWait struct {
// when the pull began
Began string `json:"began"`
Began time.Time `json:"began"`
// that seat's holder, whose settling the apply waits for
Holder string `json:"holder"`
Image string `json:"image"`
// what triggered the last try again, in words
Retried string `json:"retried,omitempty"`
// when the apply was last tried again
RetriedAt string `json:"retried-at,omitempty"`
RetriedAt *time.Time `json:"retried-at,omitempty"`
// the seat the pull came through
Seat string `json:"seat,omitempty"`
}
@@ -779,8 +780,8 @@ type RootAccountVerdict struct {
Reason string `json:"reason,omitempty"`
Resource string `json:"resource"`
// since when
Since string `json:"since"`
State string `json:"state"`
Since time.Time `json:"since"`
State string `json:"state"`
}
// RootVerdict is the engine's root-free verdict (ADR 0563 §6).
@@ -859,7 +860,7 @@ type UnitsHealth struct {
// UserListWritten is the bus's user list as the engine of the bus node wrote it to the bus module's file.
type UserListWritten struct {
// when
At string `json:"at"`
At time.Time `json:"at"`
// the digest of the file on the machine after the write
Digest string `json:"digest,omitempty"`
// why a write failed
@@ -1361,7 +1362,7 @@ type PackagesByNodeValue struct {
// HealthByNodeValue is one value of the state health under the key <node>.
type HealthByNodeValue struct {
// when
At string `json:"at"`
At time.Time `json:"at"`
Contract int64 `json:"contract,omitempty"`
Fallback *LoginFallback `json:"fallback,omitempty"`
Found []NodeDirectory `json:"found,omitempty"`
@@ -1377,7 +1378,7 @@ type HealthByNodeValue struct {
// FindingsByKeyValue is one value of the state findings under the key <key>.
type FindingsByKeyValue struct {
Actions []FindingAction `json:"actions,omitempty"`
At string `json:"at"`
At time.Time `json:"at"`
// newest first, at most 10
Evidence []FindingEvidence `json:"evidence,omitempty"`
Explanation string `json:"explanation,omitempty"`
@@ -146,7 +146,7 @@ func CheckFinding(f seat.FindingsByKeyValue) error {
// Order sorts conditions as a person reads them: urgent first, then oldest raised, then by key.
func Order(list []seat.ConditionsByKeyValue) {
raised := func(c seat.ConditionsByKeyValue) time.Time { t, _ := time.Parse(time.RFC3339Nano, c.Raised); return t }
raised := func(c seat.ConditionsByKeyValue) time.Time { return c.Raised }
sort.SliceStable(list, func(i, j int) bool {
if list[i].Severity != list[j].Severity {
return list[i].Severity == Urgent
@@ -163,8 +163,8 @@ func SilencedAt(c seat.ConditionsByKeyValue, now time.Time) bool {
if c.Silenced == nil {
return false
}
until, err := time.Parse(time.RFC3339Nano, c.Silenced.Until)
return err == nil && now.Before(until)
until := c.Silenced.Until
return until != nil && now.Before(*until)
}
// Escalated says the condition waits on the operator after healers tried.
@@ -191,7 +191,7 @@ var _ views.FindingWriter = FindingWriter{}
// FindingFor is the value and key of the seat's finding for f.
func FindingFor(f views.Finding) seat.FindingsByKeyValue {
at := f.At.UTC().Format(time.RFC3339Nano)
at := f.At.UTC()
return seat.FindingsByKeyValue{V: FindingVersion, Key: Key(ScopeModule, f.ID, f.Kind), Kind: f.Kind,
Subject: seat.Subject{Scope: ScopeModule, ID: f.ID}, Severity: Warning, Summary: f.Summary, Headline: f.Headline,
Explanation: f.Explanation, Evidence: []seat.Evidence{{At: at, Said: f.Summary}}, Source: f.Observer + "." + f.Kind,
@@ -41,9 +41,9 @@ func TestAFindingsKeyAndTheOrderOfConditions(t *testing.T) {
}
}
list := []seat.ConditionsByKeyValue{
{Key: "b", Severity: Warning, Raised: "2026-11-01T10:00:00Z"},
{Key: "c", Severity: Urgent, Raised: "2026-11-02T10:00:00Z"},
{Key: "a", Severity: Urgent, Raised: "2026-11-01T10:00:00.5Z", Silenced: &seat.ConditionsByKeyValueSilenced{Until: "2026-11-03T00:00:00Z"}},
{Key: "b", Severity: Warning, Raised: when("2026-11-01T10:00:00Z")},
{Key: "c", Severity: Urgent, Raised: when("2026-11-02T10:00:00Z")},
{Key: "a", Severity: Urgent, Raised: when("2026-11-01T10:00:00.5Z"), Silenced: &seat.ConditionsByKeyValueSilenced{Until: ptr(when("2026-11-03T00:00:00Z"))}},
}
Order(list)
if got := list[0].Key + list[1].Key + list[2].Key; got != "acb" {
@@ -99,3 +99,13 @@ func TestTheFindingWriterWritesAndClearsAModulesFindingInTheSeatsLayout(t *testi
t.Error("a finding that says nothing was written")
}
}
func when(s string) time.Time {
t, err := time.Parse(time.RFC3339Nano, s)
if err != nil {
panic(err)
}
return t
}
func ptr(t time.Time) *time.Time { return &t }
@@ -7,6 +7,7 @@ import (
"bytes"
"encoding/json"
"errors"
"time"
)
// Seat is the seat's name.
@@ -134,50 +135,50 @@ const (
// ConditionEventGapsItem is a type of the contract.
type ConditionEventGapsItem struct {
Cleared string `json:"cleared,omitempty"`
Reopened string `json:"reopened,omitempty"`
Cleared *time.Time `json:"cleared,omitempty"`
Reopened *time.Time `json:"reopened,omitempty"`
}
// ConditionEventSilenced is a type of the contract.
type ConditionEventSilenced struct {
By string `json:"by,omitempty"`
Since string `json:"since,omitempty"`
Until string `json:"until,omitempty"`
Why string `json:"why,omitempty"`
By string `json:"by,omitempty"`
Since *time.Time `json:"since,omitempty"`
Until *time.Time `json:"until,omitempty"`
Why string `json:"why,omitempty"`
}
// ConditionEventTriedItem is a type of the contract.
type ConditionEventTriedItem struct {
At string `json:"at,omitempty"`
By string `json:"by,omitempty"`
Outcome string `json:"outcome,omitempty"`
What string `json:"what,omitempty"`
At *time.Time `json:"at,omitempty"`
By string `json:"by,omitempty"`
Outcome string `json:"outcome,omitempty"`
What string `json:"what,omitempty"`
}
// ConditionEvent is a condition and what changed.
type ConditionEvent struct {
Actions []Action `json:"actions,omitempty"`
At string `json:"at"`
Change string `json:"change"`
Cleared string `json:"cleared,omitempty"`
Count int64 `json:"count,omitempty"`
Epoch int64 `json:"epoch,omitempty"`
Event string `json:"event"`
Actions []Action `json:"actions,omitempty"`
At time.Time `json:"at"`
Change string `json:"change"`
Cleared *time.Time `json:"cleared,omitempty"`
Count int64 `json:"count,omitempty"`
Epoch int64 `json:"epoch,omitempty"`
Event string `json:"event"`
// newest first, at most 10
Evidence []Evidence `json:"evidence,omitempty"`
Explanation string `json:"explanation,omitempty"`
First string `json:"first,omitempty"`
First *time.Time `json:"first,omitempty"`
Gaps []ConditionEventGapsItem `json:"gaps,omitempty"`
Headline string `json:"headline,omitempty"`
// scope.id.token
Key string `json:"key"`
Kind string `json:"kind,omitempty"`
LastObserved string `json:"last-observed,omitempty"`
LooksUnread string `json:"looks-unread,omitempty"`
Needs string `json:"needs,omitempty"`
Observations int64 `json:"observations,omitempty"`
Raised string `json:"raised,omitempty"`
Resolved string `json:"resolved,omitempty"`
Key string `json:"key"`
Kind string `json:"kind,omitempty"`
LastObserved *time.Time `json:"last-observed,omitempty"`
LooksUnread string `json:"looks-unread,omitempty"`
Needs string `json:"needs,omitempty"`
Observations int64 `json:"observations,omitempty"`
Raised *time.Time `json:"raised,omitempty"`
Resolved string `json:"resolved,omitempty"`
// self, operator, agent or healer:<name>
Resolver string `json:"resolver,omitempty"`
Severity string `json:"severity,omitempty"`
@@ -214,8 +215,8 @@ const (
// Evidence is one observation, as it was said.
type Evidence struct {
At string `json:"at"`
Said string `json:"said"`
At time.Time `json:"at"`
Said string `json:"said"`
}
// Subject is what the condition is about.
@@ -288,24 +289,24 @@ type ConditionClearedEvent = ConditionEvent
// ConditionsByKeyValueGapsItem is a type of the contract.
type ConditionsByKeyValueGapsItem struct {
Cleared string `json:"cleared,omitempty"`
Reopened string `json:"reopened,omitempty"`
Cleared *time.Time `json:"cleared,omitempty"`
Reopened *time.Time `json:"reopened,omitempty"`
}
// ConditionsByKeyValueSilenced is a type of the contract.
type ConditionsByKeyValueSilenced struct {
By string `json:"by,omitempty"`
Since string `json:"since,omitempty"`
Until string `json:"until,omitempty"`
Why string `json:"why,omitempty"`
By string `json:"by,omitempty"`
Since *time.Time `json:"since,omitempty"`
Until *time.Time `json:"until,omitempty"`
Why string `json:"why,omitempty"`
}
// ConditionsByKeyValueTriedItem is a type of the contract.
type ConditionsByKeyValueTriedItem struct {
At string `json:"at,omitempty"`
By string `json:"by,omitempty"`
Outcome string `json:"outcome,omitempty"`
What string `json:"what,omitempty"`
At *time.Time `json:"at,omitempty"`
By string `json:"by,omitempty"`
Outcome string `json:"outcome,omitempty"`
What string `json:"what,omitempty"`
}
// ConditionsByKeyValue is one value of the state conditions under the key <key>.
@@ -316,18 +317,18 @@ type ConditionsByKeyValue struct {
// newest first, at most 10
Evidence []Evidence `json:"evidence,omitempty"`
Explanation string `json:"explanation,omitempty"`
First string `json:"first,omitempty"`
First *time.Time `json:"first,omitempty"`
Gaps []ConditionsByKeyValueGapsItem `json:"gaps,omitempty"`
Headline string `json:"headline,omitempty"`
// scope.id.token
Key string `json:"key"`
Kind string `json:"kind"`
LastObserved string `json:"last-observed"`
LooksUnread string `json:"looks-unread,omitempty"`
Needs string `json:"needs,omitempty"`
Observations int64 `json:"observations,omitempty"`
Raised string `json:"raised"`
Resolved string `json:"resolved,omitempty"`
Key string `json:"key"`
Kind string `json:"kind"`
LastObserved time.Time `json:"last-observed"`
LooksUnread string `json:"looks-unread,omitempty"`
Needs string `json:"needs,omitempty"`
Observations int64 `json:"observations,omitempty"`
Raised time.Time `json:"raised"`
Resolved string `json:"resolved,omitempty"`
// self, operator, agent or healer:<name>
Resolver string `json:"resolver,omitempty"`
Severity string `json:"severity"`
@@ -348,8 +349,8 @@ const (
// FindingsByKeyValue is one value of the state findings under the key <key>.
type FindingsByKeyValue struct {
Actions []Action `json:"actions,omitempty"`
At string `json:"at"`
Actions []Action `json:"actions,omitempty"`
At time.Time `json:"at"`
// newest first, at most 10
Evidence []Evidence `json:"evidence,omitempty"`
Explanation string `json:"explanation,omitempty"`
@@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"strings"
"time"
)
// Seat is the seat's name.
@@ -116,9 +117,9 @@ func DecodeWarrantsByAskerAskValue(raw []byte) (WarrantsByAskerAskValue, error)
// Act is one act done by hand.
type Act struct {
Arguments []string `json:"arguments,omitempty"`
Ask string `json:"ask,omitempty"`
At string `json:"at"`
Arguments []string `json:"arguments,omitempty"`
Ask string `json:"ask,omitempty"`
At time.Time `json:"at"`
// the caller the runtime proved
By string `json:"by"`
Carried []string `json:"carried,omitempty"`
@@ -191,9 +192,9 @@ type ActRecordedEvent = Act
// ActsByIDValue is one value of the state acts under the key <id>.
type ActsByIDValue struct {
Arguments []string `json:"arguments,omitempty"`
Ask string `json:"ask,omitempty"`
At string `json:"at"`
Arguments []string `json:"arguments,omitempty"`
Ask string `json:"ask,omitempty"`
At time.Time `json:"at"`
// the caller the runtime proved
By string `json:"by"`
Carried []string `json:"carried,omitempty"`
@@ -214,9 +215,9 @@ type ActsByIDValue struct {
// WarrantsByAskerAskValue is one value of the state warrants under the key <asker>.<ask>.
type WarrantsByAskerAskValue struct {
Ask string `json:"ask"`
Asker string `json:"asker"`
At string `json:"at,omitempty"`
By string `json:"by,omitempty"`
Option string `json:"option,omitempty"`
Ask string `json:"ask"`
Asker string `json:"asker"`
At *time.Time `json:"at,omitempty"`
By string `json:"by,omitempty"`
Option string `json:"option,omitempty"`
}
@@ -7,6 +7,7 @@ import (
"bytes"
"encoding/json"
"errors"
"time"
)
// Seat is the seat's name.
@@ -143,17 +144,17 @@ type DrillAnswer = map[string]any
// HealerActedEvent is the body of the event healer-acted.
type HealerActedEvent struct {
Act string `json:"act,omitempty"`
At string `json:"at"`
Budget string `json:"budget,omitempty"`
By string `json:"by,omitempty"`
Condition string `json:"condition"`
Event string `json:"event"`
Healer string `json:"healer"`
Kind string `json:"kind,omitempty"`
Outcome string `json:"outcome"`
Said string `json:"said,omitempty"`
Show string `json:"show,omitempty"`
Act string `json:"act,omitempty"`
At time.Time `json:"at"`
Budget string `json:"budget,omitempty"`
By string `json:"by,omitempty"`
Condition string `json:"condition"`
Event string `json:"event"`
Healer string `json:"healer"`
Kind string `json:"kind,omitempty"`
Outcome string `json:"outcome"`
Said string `json:"said,omitempty"`
Show string `json:"show,omitempty"`
}
// The values of HealerActedEvent's outcome.
@@ -166,16 +167,16 @@ const (
// AttemptsByAttemptValue is one value of the state attempts under the key <attempt>.
type AttemptsByAttemptValue struct {
Act string `json:"act"`
Begun string `json:"begun"`
Act string `json:"act"`
Begun time.Time `json:"begun"`
// what the budget counts by: the condition's key unless the healer says another
BudgetKey string `json:"budget-key"`
Condition string `json:"condition"`
Finished string `json:"finished,omitempty"`
Healer string `json:"healer"`
Kind string `json:"kind"`
Outcome string `json:"outcome"`
Said string `json:"said,omitempty"`
BudgetKey string `json:"budget-key"`
Condition string `json:"condition"`
Finished *time.Time `json:"finished,omitempty"`
Healer string `json:"healer"`
Kind string `json:"kind"`
Outcome string `json:"outcome"`
Said string `json:"said,omitempty"`
}
// The values of AttemptsByAttemptValue's outcome.
@@ -188,10 +189,10 @@ const (
// WouldByWouldValue is one value of the state would under the key <would>.
type WouldByWouldValue struct {
Act string `json:"act"`
At string `json:"at"`
Condition string `json:"condition"`
Healer string `json:"healer"`
Kind string `json:"kind,omitempty"`
Why string `json:"why,omitempty"`
Act string `json:"act"`
At time.Time `json:"at"`
Condition string `json:"condition"`
Healer string `json:"healer"`
Kind string `json:"kind,omitempty"`
Why string `json:"why,omitempty"`
}
@@ -3,6 +3,8 @@
// Package meshselfcheck is the contract of the seat "mesh-self-check", defined whole (seats/mesh-self-check/seat.json): The mesh checking itself (ADR 0564): probes run every five minutes, each failure a finding the seat's conditions raise.
package meshselfcheck
import "time"
// Seat is the seat's name.
const Seat = "mesh-self-check"
@@ -88,13 +90,13 @@ type CheckedEventCounts struct {
// CheckedEvent is the body of the event checked.
type CheckedEvent struct {
At string `json:"at"`
At time.Time `json:"at"`
Controller string `json:"controller,omitempty"`
Counts *CheckedEventCounts `json:"counts,omitempty"`
IntervalSeconds int64 `json:"interval-seconds,omitempty"`
Probes []ProbeVerdict `json:"probes"`
Run string `json:"run"`
Started string `json:"started,omitempty"`
Started *time.Time `json:"started,omitempty"`
Took string `json:"took,omitempty"`
Unsaid int64 `json:"unsaid,omitempty"`
Why string `json:"why,omitempty"`
@@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"strings"
"time"
)
// Seat is the seat's name.
@@ -258,9 +259,9 @@ type StuckByBucketKeyValue struct {
Bucket string `json:"bucket"`
Key string `json:"key"`
// it has moved again
Moved bool `json:"moved,omitempty"`
Since string `json:"since"`
V int64 `json:"v,omitempty"`
Moved bool `json:"moved,omitempty"`
Since time.Time `json:"since"`
V int64 `json:"v,omitempty"`
// what it waited for, in words
Waited string `json:"waited,omitempty"`
}
@@ -36,7 +36,7 @@ func TestSigningNodeLoginsAndOwnDrift(t *testing.T) {
}
// A node's two logins: the first, the second, a rotation to the other only, a stage only with a rotation.
since := "2026-11-02T01:00:00Z"
since := time.Date(2026, 11, 2, 1, 0, 0, 0, time.UTC)
for name, c := range map[string]struct {
l seat.NodeLoginsByNodeValue
ok bool
@@ -56,7 +56,7 @@ func TestSigningNodeLoginsAndOwnDrift(t *testing.T) {
} else if back, err := DecodeNodeLogin(raw); err != nil || Rotates(back) {
t.Errorf("round trip: %+v %v", back, err)
}
if _, err := DecodeNodeLogin([]byte(`{"v":9,"node":"g14","login":"node.g14","since":"` + since + `"}`)); err == nil {
if _, err := DecodeNodeLogin([]byte(`{"v":9,"node":"g14","login":"node.g14","since":"` + since.Format(time.RFC3339) + `"}`)); err == nil {
t.Error("version 9 was taken")
}
if n, ok := LoginNode("node.g14--b"); !ok || n != "g14" {
@@ -87,7 +87,7 @@ func ParseCertificate(text string) (*x509.Certificate, error) {
// NewSignerKey is the value of `key` for pub.
func NewSignerKey(pub ed25519.PublicKey, made time.Time) seat.SignersByKeyValue {
return seat.SignersByKeyValue{V: 1, Key: base64.StdEncoding.EncodeToString(pub), Fingerprint: SignerFingerprint(pub), Made: made.UTC().Format(time.RFC3339Nano)}
return seat.SignersByKeyValue{V: 1, Key: base64.StdEncoding.EncodeToString(pub), Fingerprint: SignerFingerprint(pub), Made: made.UTC()}
}
// PublicKey is k's key, checked: an ed25519 public key whose fingerprint is the one k names.
@@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"strings"
"time"
)
// Seat is the seat's name.
@@ -137,14 +138,14 @@ func DecodeEnrolmentsByAddressAddressValue(raw []byte) (EnrolmentsByAddressAddre
// Enrolment is one open enrolment.
type Enrolment struct {
Address string `json:"address"`
Ask string `json:"ask,omitempty"`
Caller string `json:"caller,omitempty"`
Expires string `json:"expires,omitempty"`
Issued string `json:"issued,omitempty"`
KeysDigest string `json:"keys-digest,omitempty"`
Node string `json:"node"`
OverlayKey string `json:"overlay-key,omitempty"`
Address string `json:"address"`
Ask string `json:"ask,omitempty"`
Caller string `json:"caller,omitempty"`
Expires *time.Time `json:"expires,omitempty"`
Issued *time.Time `json:"issued,omitempty"`
KeysDigest string `json:"keys-digest,omitempty"`
Node string `json:"node"`
OverlayKey string `json:"overlay-key,omitempty"`
// asked, live or redeeming
Stage string `json:"stage"`
V int64 `json:"v,omitempty"`
@@ -266,8 +267,8 @@ type EnrolmentsByNodeNodeValue = Enrolment
// EnrolmentsByAddressAddressValue is one value of the state enrolments under the key address.<address>.
type EnrolmentsByAddressAddressValue struct {
Ask string `json:"ask,omitempty"`
Issued string `json:"issued,omitempty"`
Node string `json:"node"`
V int64 `json:"v,omitempty"`
Ask string `json:"ask,omitempty"`
Issued *time.Time `json:"issued,omitempty"`
Node string `json:"node"`
V int64 `json:"v,omitempty"`
}
@@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"strings"
"time"
)
// Seat is the seat's name.
@@ -539,18 +540,18 @@ type OwnRetiredHolderEvent struct {
type SignersByKeyValue struct {
Fingerprint string `json:"fingerprint"`
// the signing key's public half, standard base64
Key string `json:"key"`
Made string `json:"made"`
V int64 `json:"v,omitempty"`
Key string `json:"key"`
Made time.Time `json:"made"`
V int64 `json:"v,omitempty"`
}
// SignersByAuthorityValue is one value of the state signers under the key authority.
type SignersByAuthorityValue struct {
// the authority certificate, PEM
Certificate string `json:"certificate"`
Fingerprint string `json:"fingerprint"`
Made string `json:"made"`
V int64 `json:"v,omitempty"`
Certificate string `json:"certificate"`
Fingerprint string `json:"fingerprint"`
Made time.Time `json:"made"`
V int64 `json:"v,omitempty"`
}
// NodeLoginsByNodeValue is one value of the state node-logins under the key <node>.
@@ -562,8 +563,8 @@ type NodeLoginsByNodeValue struct {
Login string `json:"login"`
Node string `json:"node"`
// the login rotating to, empty when none
Rotating string `json:"rotating,omitempty"`
Since string `json:"since"`
Rotating string `json:"rotating,omitempty"`
Since time.Time `json:"since"`
// begun, ready or confirmed; empty when no rotation
Stage string `json:"stage,omitempty"`
V int64 `json:"v,omitempty"`
@@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"strings"
"time"
)
// Seat is the seat's name.
@@ -403,9 +404,9 @@ type Placement struct {
// PlacementEventWarrant is who approved it, through which channel, when.
type PlacementEventWarrant struct {
At string `json:"at"`
Warrant string `json:"warrant"`
Words string `json:"words"`
At time.Time `json:"at"`
Warrant string `json:"warrant"`
Words string `json:"words"`
}
// PlacementEvent is what each placement event carries.
@@ -421,9 +422,9 @@ type PlacementEvent struct {
// Proposal is an open proposal.
type Proposal struct {
Again string `json:"again,omitempty"`
Ask string `json:"ask,omitempty"`
At string `json:"at"`
Again *time.Time `json:"again,omitempty"`
Ask string `json:"ask,omitempty"`
At time.Time `json:"at"`
// by node whose key it changes, the revision of the key it was laid over (0: none)
Base map[string]int64 `json:"base"`
By string `json:"by"`
@@ -434,14 +435,14 @@ type Proposal struct {
Must []string `json:"must,omitempty"`
Seed bool `json:"seed,omitempty"`
// answering, failed or asked
State string `json:"state"`
V int64 `json:"v,omitempty"`
Verdict *Verdict `json:"verdict,omitempty"`
Warrant *Warrant `json:"warrant,omitempty"`
Why string `json:"why"`
Withdrawn string `json:"withdrawn,omitempty"`
Words string `json:"words,omitempty"`
Written string `json:"written,omitempty"`
State string `json:"state"`
V int64 `json:"v,omitempty"`
Verdict *Verdict `json:"verdict,omitempty"`
Warrant *Warrant `json:"warrant,omitempty"`
Why string `json:"why"`
Withdrawn string `json:"withdrawn,omitempty"`
Words string `json:"words,omitempty"`
Written *time.Time `json:"written,omitempty"`
}
// ProposalChangeKeys is the public halves of a joining node's keys.
@@ -507,7 +508,7 @@ type SeatHolders struct {
type Verdict struct {
// every node's answer to its candidate, by node
Answers map[string]map[string]any `json:"answers,omitempty"`
At string `json:"at"`
At time.Time `json:"at"`
Carried map[string][]string `json:"carried,omitempty"`
Fails []string `json:"fails,omitempty"`
Intended map[string][]string `json:"intended,omitempty"`
@@ -516,7 +517,7 @@ type Verdict struct {
// waits, pass or fail
State string `json:"state"`
Unintended map[string][]string `json:"unintended,omitempty"`
Until string `json:"until,omitempty"`
Until *time.Time `json:"until,omitempty"`
}
// Warrant is the enrolment's warrant an add-node carries.
@@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"strings"
"time"
)
// Seat is the seat's name.
@@ -217,16 +218,16 @@ type ProvisionsByNodeConsumerProvisionValueReference struct {
// ProvisionsByNodeConsumerProvisionValueWarrant is a type of the contract.
type ProvisionsByNodeConsumerProvisionValueWarrant struct {
Ask string `json:"ask,omitempty"`
At string `json:"at,omitempty"`
By string `json:"by,omitempty"`
Option string `json:"option,omitempty"`
Ask string `json:"ask,omitempty"`
At *time.Time `json:"at,omitempty"`
By string `json:"by,omitempty"`
Option string `json:"option,omitempty"`
}
// ProvisionsByNodeConsumerProvisionValue is one value of the state provisions under the key <node>.<consumer>.<provision>.
type ProvisionsByNodeConsumerProvisionValue struct {
Ask string `json:"ask,omitempty"`
At string `json:"at"`
At time.Time `json:"at"`
Consumer ProvisionsByNodeConsumerProvisionValueConsumer `json:"consumer"`
DependsOn []string `json:"depends-on,omitempty"`
Local string `json:"local,omitempty"`
@@ -289,16 +290,16 @@ type ProvisionsByNodeConsumerProvisionLocalValueReference struct {
// ProvisionsByNodeConsumerProvisionLocalValueWarrant is a type of the contract.
type ProvisionsByNodeConsumerProvisionLocalValueWarrant struct {
Ask string `json:"ask,omitempty"`
At string `json:"at,omitempty"`
By string `json:"by,omitempty"`
Option string `json:"option,omitempty"`
Ask string `json:"ask,omitempty"`
At *time.Time `json:"at,omitempty"`
By string `json:"by,omitempty"`
Option string `json:"option,omitempty"`
}
// ProvisionsByNodeConsumerProvisionLocalValue is one value of the state provisions under the key <node>.<consumer>.<provision>.<local>.
type ProvisionsByNodeConsumerProvisionLocalValue struct {
Ask string `json:"ask,omitempty"`
At string `json:"at"`
At time.Time `json:"at"`
Consumer ProvisionsByNodeConsumerProvisionLocalValueConsumer `json:"consumer"`
DependsOn []string `json:"depends-on,omitempty"`
Local string `json:"local,omitempty"`