AM-D3/AM-H1 path: the node's record carries the runner's reading; mesh-grants gains withheld
The grants part must tell a reading of the running tool runner from an older one, and the node-engine's composition reads the withheld subjects through a verb of the seat, never the grants part's state. Builds: design 46 7 §6 (the node's record takes the runner's capabilities and fingerprint; the seat mesh-grants' verb withheld, class read, callers the node-engine, persons and the operator, input node, with a fixture), lead answer A-203 (runner-capabilities, runner-fingerprint; withheld's input and answer) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -813,11 +813,15 @@ type NodeRecord struct {
|
||||
NetworksSaid bool `json:"networks-said,omitempty"`
|
||||
Node string `json:"node"`
|
||||
OutwardLinks []string `json:"outward-links,omitempty"`
|
||||
SealingKey string `json:"sealing-key,omitempty"`
|
||||
ServingKey string `json:"serving-key,omitempty"`
|
||||
Trusts []string `json:"trusts,omitempty"`
|
||||
TunnelKey string `json:"tunnel-key,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
// the capabilities this node's tool runner states of the calls it answers, as its announcement carries them (design 46 approval mark 6)
|
||||
RunnerCapabilities []string `json:"runner-capabilities,omitempty"`
|
||||
// the fingerprint of the tool runner that stated runner-capabilities, as its announcement carries it; empty when it stated none
|
||||
RunnerFingerprint string `json:"runner-fingerprint,omitempty"`
|
||||
SealingKey string `json:"sealing-key,omitempty"`
|
||||
ServingKey string `json:"serving-key,omitempty"`
|
||||
Trusts []string `json:"trusts,omitempty"`
|
||||
TunnelKey string `json:"tunnel-key,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// PeerSeen is a tunnel peer and whether it is seen.
|
||||
|
||||
@@ -85,7 +85,7 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v HaveByNodeModuleValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "the bus module's have carries the user list written (typed from the engine's values)", subject: "", given: "{\"health\":\"ok\",\"phase\":\"running\",\"user-list\":{\"at\":\"2026-11-05T12:00:00Z\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"follows\":\"grants\",\"handed\":{\"at\":\"2026-11-05T12:00:00Z\",\"box\":{\"ct\":\"c\",\"eph\":\"e\",\"iv\":\"i\",\"tag\":\"t\",\"v\":1},\"from\":\"ace\",\"to\":\"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"users\":3},\"key\":\"-----BEGIN PUBLIC KEY-----\",\"revision\":7,\"source\":\"user-list\",\"users\":3,\"wanted\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"v\":1}", wire: "{\"health\":\"ok\",\"phase\":\"running\",\"user-list\":{\"at\":\"2026-11-05T12:00:00Z\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"follows\":\"grants\",\"handed\":{\"at\":\"2026-11-05T12:00:00Z\",\"box\":{\"ct\":\"c\",\"eph\":\"e\",\"iv\":\"i\",\"tag\":\"t\",\"v\":1},\"from\":\"ace\",\"to\":\"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"users\":3},\"key\":\"-----BEGIN PUBLIC KEY-----\",\"revision\":7,\"source\":\"user-list\",\"users\":3,\"wanted\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v HaveByNodeModuleValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a node's own facts with its record and an answer to a candidate (typed from the engine's values)", subject: "", given: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"ace\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}", wire: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"ace\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}",
|
||||
{name: "a node's own facts with its record and an answer to a candidate (typed from the engine's values)", subject: "", given: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"approval-mark/1\",\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"ace\",\"runner-capabilities\":[\"approval-mark/1\"],\"runner-fingerprint\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}", wire: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"approval-mark/1\",\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"ace\",\"runner-capabilities\":[\"approval-mark/1\"],\"runner-fingerprint\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v HaveByNodeNodeValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a module's data items on a node (typed from the engine's values)", subject: "", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"items\":[{\"class\":\"database\",\"covered_by\":\"/var/lib/postgres\",\"item\":\"cluster\",\"measure\":\"dataset\",\"module\":\"postgres\",\"path\":\"/var/lib/postgres\",\"protection\":\"backup\"}],\"module\":\"postgres\",\"node\":\"ace\",\"v\":1}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"items\":[{\"class\":\"database\",\"covered_by\":\"/var/lib/postgres\",\"item\":\"cluster\",\"measure\":\"dataset\",\"module\":\"postgres\",\"path\":\"/var/lib/postgres\",\"protection\":\"backup\"}],\"module\":\"postgres\",\"node\":\"ace\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v DataByNodeModuleValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
|
||||
@@ -10,6 +10,7 @@ const Seat = "mesh-grants"
|
||||
|
||||
const (
|
||||
VerbGrantsFor = "grants-for"
|
||||
VerbWithheld = "withheld"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,7 +22,7 @@ const (
|
||||
|
||||
// Verbs is every verb the seat serves, in its definition's order: a new copy each call.
|
||||
func Verbs() []string {
|
||||
return []string{VerbGrantsFor}
|
||||
return []string{VerbGrantsFor, VerbWithheld}
|
||||
}
|
||||
|
||||
// Events is every event published on the seat's subject: a new copy each call.
|
||||
@@ -113,6 +114,24 @@ const (
|
||||
WaitStepGrant = "grant"
|
||||
)
|
||||
|
||||
// WithheldModulesItem is a type of the contract.
|
||||
type WithheldModulesItem struct {
|
||||
Module string `json:"module"`
|
||||
Subjects []WithheldSubject `json:"subjects"`
|
||||
}
|
||||
|
||||
// Withheld is a node's withheld subjects, by module.
|
||||
type Withheld struct {
|
||||
Modules []WithheldModulesItem `json:"modules"`
|
||||
Node string `json:"node"`
|
||||
}
|
||||
|
||||
// WithheldSubject is one subject withheld, and why.
|
||||
type WithheldSubject struct {
|
||||
Subject string `json:"subject"`
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// GrantsForInput is what grants-for takes.
|
||||
type GrantsForInput struct {
|
||||
// its watched branch
|
||||
@@ -126,6 +145,15 @@ type GrantsForInput struct {
|
||||
// GrantsForAnswer is what grants-for answers.
|
||||
type GrantsForAnswer = GrantsFor
|
||||
|
||||
// WithheldInput is what withheld takes.
|
||||
type WithheldInput struct {
|
||||
// the node whose runtime's withheld subjects are asked
|
||||
Node string `json:"node"`
|
||||
}
|
||||
|
||||
// WithheldAnswer is what withheld answers.
|
||||
type WithheldAnswer = Withheld
|
||||
|
||||
// WaitHeldEvent is the body of the event wait-held.
|
||||
type WaitHeldEvent = Wait
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v GrantsForAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "grants-for asks a source revision on a branch", subject: "", given: "{\"branch\":\"main\",\"source\":\"a1b2c3d4\"}", wire: "{\"branch\":\"main\",\"source\":\"a1b2c3d4\"}",
|
||||
decode: func(b []byte) (any, error) { var v GrantsForInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "withheld answers a node's withheld subjects by module", subject: "", given: "{\"modules\":[{\"module\":\"zsh\",\"subjects\":[{\"subject\":\"mesh.mod.zsh.tool.execute\",\"why\":\"its tool runner does not state approval-mark/1\"},{\"subject\":\"mesh.mod.zsh.tool.execute.*\",\"why\":\"its tool runner does not state approval-mark/1\"},{\"subject\":\"mesh.mod.zsh.call.execute.\\u003e\",\"why\":\"its tool runner does not state approval-mark/1\"}]}],\"node\":\"workstation\"}", wire: "{\"modules\":[{\"module\":\"zsh\",\"subjects\":[{\"subject\":\"mesh.mod.zsh.tool.execute\",\"why\":\"its tool runner does not state approval-mark/1\"},{\"subject\":\"mesh.mod.zsh.tool.execute.*\",\"why\":\"its tool runner does not state approval-mark/1\"},{\"subject\":\"mesh.mod.zsh.call.execute.\\u003e\",\"why\":\"its tool runner does not state approval-mark/1\"}]}],\"node\":\"workstation\"}",
|
||||
decode: func(b []byte) (any, error) { var v WithheldAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "withheld asks a node", subject: "", given: "{\"node\":\"workstation\"}", wire: "{\"node\":\"workstation\"}",
|
||||
decode: func(b []byte) (any, error) { var v WithheldInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
}
|
||||
for _, c := range cases {
|
||||
v, err := c.decode([]byte(c.given))
|
||||
|
||||
@@ -24,5 +24,38 @@
|
||||
"source": "a1b2c3d4",
|
||||
"branch": "main"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withheld answers a node's withheld subjects by module",
|
||||
"of": "verb:withheld.answer",
|
||||
"given": {
|
||||
"node": "workstation",
|
||||
"modules": [
|
||||
{
|
||||
"module": "zsh",
|
||||
"subjects": [
|
||||
{
|
||||
"subject": "mesh.mod.zsh.tool.execute",
|
||||
"why": "its tool runner does not state approval-mark/1"
|
||||
},
|
||||
{
|
||||
"subject": "mesh.mod.zsh.tool.execute.*",
|
||||
"why": "its tool runner does not state approval-mark/1"
|
||||
},
|
||||
{
|
||||
"subject": "mesh.mod.zsh.call.execute.>",
|
||||
"why": "its tool runner does not state approval-mark/1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withheld asks a node",
|
||||
"of": "verb:withheld.input",
|
||||
"given": {
|
||||
"node": "workstation"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -41,6 +41,32 @@
|
||||
"answer": {
|
||||
"$ref": "#/defs/GrantsFor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withheld",
|
||||
"description": "The marked subjects withheld from each module a node's runtime carries, and why: where its tool runner does not state approval-mark/1, or its reading is not the running runner's (design 46 approval mark 6).",
|
||||
"class": "read",
|
||||
"callers": [
|
||||
"seat:node-engine",
|
||||
"persons",
|
||||
"operator"
|
||||
],
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"node": {
|
||||
"type": "string",
|
||||
"description": "the node whose runtime's withheld subjects are asked"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"node"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"answer": {
|
||||
"$ref": "#/defs/Withheld"
|
||||
}
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
@@ -217,6 +243,56 @@
|
||||
"description": "why it could not be answered: the catalog half of the candidate is not held"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Withheld": {
|
||||
"type": "object",
|
||||
"description": "a node's withheld subjects, by module",
|
||||
"properties": {
|
||||
"node": {
|
||||
"type": "string"
|
||||
},
|
||||
"modules": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"module": {
|
||||
"type": "string"
|
||||
},
|
||||
"subjects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/defs/WithheldSubject"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"module",
|
||||
"subjects"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"node",
|
||||
"modules"
|
||||
]
|
||||
},
|
||||
"WithheldSubject": {
|
||||
"type": "object",
|
||||
"description": "one subject withheld, and why",
|
||||
"properties": {
|
||||
"subject": {
|
||||
"type": "string"
|
||||
},
|
||||
"why": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"subject",
|
||||
"why"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ export declare const seat: "mesh-grants";
|
||||
|
||||
export declare const verbs: {
|
||||
readonly grantsFor: "grants-for";
|
||||
readonly withheld: "withheld";
|
||||
};
|
||||
|
||||
export declare const events: {
|
||||
@@ -78,6 +79,23 @@ export interface Wait {
|
||||
"version": string;
|
||||
}
|
||||
|
||||
export interface WithheldModulesItem {
|
||||
"module": string;
|
||||
"subjects": WithheldSubject[];
|
||||
}
|
||||
|
||||
/** a node's withheld subjects, by module */
|
||||
export interface Withheld {
|
||||
"modules": WithheldModulesItem[];
|
||||
"node": string;
|
||||
}
|
||||
|
||||
/** one subject withheld, and why */
|
||||
export interface WithheldSubject {
|
||||
"subject": string;
|
||||
"why": string;
|
||||
}
|
||||
|
||||
/** is what grants-for takes. */
|
||||
export interface GrantsForInput {
|
||||
/** its watched branch */
|
||||
@@ -91,6 +109,15 @@ export interface GrantsForInput {
|
||||
/** is what grants-for answers. */
|
||||
export type GrantsForAnswer = GrantsFor;
|
||||
|
||||
/** is what withheld takes. */
|
||||
export interface WithheldInput {
|
||||
/** the node whose runtime's withheld subjects are asked */
|
||||
"node": string;
|
||||
}
|
||||
|
||||
/** is what withheld answers. */
|
||||
export type WithheldAnswer = Withheld;
|
||||
|
||||
/** is the body of the event wait-held. */
|
||||
export type WaitHeldEvent = Wait;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ export const seat = "mesh-grants";
|
||||
|
||||
export const verbs = {
|
||||
grantsFor: "grants-for",
|
||||
withheld: "withheld",
|
||||
};
|
||||
|
||||
export const events = {
|
||||
|
||||
@@ -388,6 +388,7 @@
|
||||
"node": "ace",
|
||||
"tunnel-key": "k",
|
||||
"capabilities": [
|
||||
"approval-mark/1",
|
||||
"docker"
|
||||
],
|
||||
"networks": [
|
||||
@@ -397,7 +398,11 @@
|
||||
}
|
||||
],
|
||||
"networks-said": true,
|
||||
"contract": 3
|
||||
"contract": 3,
|
||||
"runner-capabilities": [
|
||||
"approval-mark/1"
|
||||
],
|
||||
"runner-fingerprint": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||
},
|
||||
"composes": "own",
|
||||
"candidates": {
|
||||
|
||||
@@ -2342,6 +2342,17 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"runner-capabilities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "the capabilities this node's tool runner states of the calls it answers, as its announcement carries them (design 46 approval mark 6)"
|
||||
},
|
||||
"runner-fingerprint": {
|
||||
"type": "string",
|
||||
"description": "the fingerprint of the tool runner that stated runner-capabilities, as its announcement carries it; empty when it stated none"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
Vendored
+4
@@ -473,6 +473,10 @@ export interface NodeRecord {
|
||||
"networks-said"?: boolean;
|
||||
"node": string;
|
||||
"outward-links"?: string[];
|
||||
/** the capabilities this node's tool runner states of the calls it answers, as its announcement carries them (design 46 approval mark 6) */
|
||||
"runner-capabilities"?: string[];
|
||||
/** the fingerprint of the tool runner that stated runner-capabilities, as its announcement carries it; empty when it stated none */
|
||||
"runner-fingerprint"?: string;
|
||||
"sealing-key"?: string;
|
||||
"serving-key"?: string;
|
||||
"trusts"?: string[];
|
||||
|
||||
Reference in New Issue
Block a user