approval-md 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SPEC.md +11 -0
- package/cli.js +72 -4
- package/dist/src/channels/contract.d.ts +53 -0
- package/dist/src/channels/contract.js +56 -0
- package/dist/src/channels/contract.js.map +1 -1
- package/dist/src/channels/tagging.d.ts +25 -0
- package/dist/src/channels/tagging.js +57 -5
- package/dist/src/channels/tagging.js.map +1 -1
- package/dist/src/channels/telegram-minimal.d.ts +251 -0
- package/dist/src/channels/telegram-minimal.js +618 -0
- package/dist/src/channels/telegram-minimal.js.map +1 -0
- package/dist/src/channels/telegram.d.ts +454 -19
- package/dist/src/channels/telegram.js +931 -80
- package/dist/src/channels/telegram.js.map +1 -1
- package/dist/src/cli/amend.js +8 -1
- package/dist/src/cli/amend.js.map +1 -1
- package/dist/src/cli/attest.js +2 -1
- package/dist/src/cli/attest.js.map +1 -1
- package/dist/src/cli/audit-card.d.ts +1 -1
- package/dist/src/cli/audit-card.js +40 -1
- package/dist/src/cli/audit-card.js.map +1 -1
- package/dist/src/cli/audit.d.ts +7 -5
- package/dist/src/cli/audit.js +25 -12
- package/dist/src/cli/audit.js.map +1 -1
- package/dist/src/cli/channel-telegram-webhook.d.ts +2 -0
- package/dist/src/cli/channel-telegram-webhook.js +7 -0
- package/dist/src/cli/channel-telegram-webhook.js.map +1 -1
- package/dist/src/cli/channel-telegram.d.ts +75 -2
- package/dist/src/cli/channel-telegram.js +172 -16
- package/dist/src/cli/channel-telegram.js.map +1 -1
- package/dist/src/cli/channel-web.js +2 -1
- package/dist/src/cli/channel-web.js.map +1 -1
- package/dist/src/cli/channel.js +2 -1
- package/dist/src/cli/channel.js.map +1 -1
- package/dist/src/cli/doctor.js +1 -1
- package/dist/src/cli/doctor.js.map +1 -1
- package/dist/src/cli/execute.d.ts +12 -0
- package/dist/src/cli/execute.js +50 -4
- package/dist/src/cli/execute.js.map +1 -1
- package/dist/src/cli/gate.js +2 -1
- package/dist/src/cli/gate.js.map +1 -1
- package/dist/src/cli/help.d.ts +1 -0
- package/dist/src/cli/help.js +39 -18
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/hook.d.ts +121 -3
- package/dist/src/cli/hook.js +719 -79
- package/dist/src/cli/hook.js.map +1 -1
- package/dist/src/cli/log-checkpoint.js +2 -1
- package/dist/src/cli/log-checkpoint.js.map +1 -1
- package/dist/src/cli/log-unlock.d.ts +23 -0
- package/dist/src/cli/log-unlock.js +110 -0
- package/dist/src/cli/log-unlock.js.map +1 -0
- package/dist/src/cli/main.js +23 -6
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/setup-common.js +2 -1
- package/dist/src/cli/setup-common.js.map +1 -1
- package/dist/src/cli/up.js +5 -0
- package/dist/src/cli/up.js.map +1 -1
- package/dist/src/cli/vault.js +2 -1
- package/dist/src/cli/vault.js.map +1 -1
- package/dist/src/cli/verb-registry.js +1 -0
- package/dist/src/cli/verb-registry.js.map +1 -1
- package/dist/src/cli/wordmark.d.ts +2 -2
- package/dist/src/cli/wordmark.js +2 -2
- package/dist/src/core/attest-bootstrap.js +2 -1
- package/dist/src/core/attest-bootstrap.js.map +1 -1
- package/dist/src/core/attest.js +5 -4
- package/dist/src/core/attest.js.map +1 -1
- package/dist/src/core/audit.d.ts +113 -9
- package/dist/src/core/audit.js +382 -18
- package/dist/src/core/audit.js.map +1 -1
- package/dist/src/core/budgets.d.ts +12 -0
- package/dist/src/core/budgets.js +54 -1
- package/dist/src/core/budgets.js.map +1 -1
- package/dist/src/core/checkpoint.js +3 -2
- package/dist/src/core/checkpoint.js.map +1 -1
- package/dist/src/core/command-class.js +6 -0
- package/dist/src/core/command-class.js.map +1 -1
- package/dist/src/core/decision-refusal.js +2 -1
- package/dist/src/core/decision-refusal.js.map +1 -1
- package/dist/src/core/delegation.d.ts +109 -0
- package/dist/src/core/delegation.js +244 -0
- package/dist/src/core/delegation.js.map +1 -0
- package/dist/src/core/execute.js +12 -3
- package/dist/src/core/execute.js.map +1 -1
- package/dist/src/core/gate-window.js +4 -3
- package/dist/src/core/gate-window.js.map +1 -1
- package/dist/src/core/gate.d.ts +84 -43
- package/dist/src/core/gate.js +114 -6
- package/dist/src/core/gate.js.map +1 -1
- package/dist/src/core/gesture-refusal.js +2 -1
- package/dist/src/core/gesture-refusal.js.map +1 -1
- package/dist/src/core/identity.d.ts +105 -0
- package/dist/src/core/identity.js +122 -0
- package/dist/src/core/identity.js.map +1 -0
- package/dist/src/core/log-lock.d.ts +435 -0
- package/dist/src/core/log-lock.js +1093 -0
- package/dist/src/core/log-lock.js.map +1 -0
- package/dist/src/core/log.d.ts +82 -3
- package/dist/src/core/log.js +285 -40
- package/dist/src/core/log.js.map +1 -1
- package/dist/src/core/loop.d.ts +11 -0
- package/dist/src/core/loop.js +63 -4
- package/dist/src/core/loop.js.map +1 -1
- package/dist/src/core/policy-diff.js +20 -1
- package/dist/src/core/policy-diff.js.map +1 -1
- package/dist/src/core/policy-explain.js +18 -2
- package/dist/src/core/policy-explain.js.map +1 -1
- package/dist/src/core/policy-load.d.ts +38 -1
- package/dist/src/core/policy-load.js +34 -2
- package/dist/src/core/policy-load.js.map +1 -1
- package/dist/src/core/policy-match.js +30 -5
- package/dist/src/core/policy-match.js.map +1 -1
- package/dist/src/core/policy-proposal.d.ts +17 -0
- package/dist/src/core/policy-proposal.js +32 -16
- package/dist/src/core/policy-proposal.js.map +1 -1
- package/dist/src/core/prompt-layout.d.ts +186 -1
- package/dist/src/core/prompt-layout.js +345 -3
- package/dist/src/core/prompt-layout.js.map +1 -1
- package/dist/src/core/sender-identity.d.ts +24 -1
- package/dist/src/core/sender-identity.js +31 -0
- package/dist/src/core/sender-identity.js.map +1 -1
- package/dist/src/core/token.js +11 -0
- package/dist/src/core/token.js.map +1 -1
- package/dist/src/core/tool-map.d.ts +125 -0
- package/dist/src/core/tool-map.js +179 -0
- package/dist/src/core/tool-map.js.map +1 -0
- package/dist/src/core/validate.d.ts +20 -6
- package/dist/src/core/validate.js +0 -0
- package/dist/src/core/validate.js.map +1 -1
- package/dist/src/daemon/git-evidence.d.ts +2 -2
- package/dist/src/daemon/git-evidence.js +1 -1
- package/dist/src/serve/archive.d.ts +8 -0
- package/dist/src/serve/archive.js +11 -2
- package/dist/src/serve/archive.js.map +1 -1
- package/docs/README-extended.md +15 -0
- package/docs/cli-reference.md +571 -28
- package/package.json +2 -2
- package/schema/event.schema.json +387 -29
- package/schema/fixtures/event/invalid/audit-lock-reclaimed-age-without-created.json +19 -0
- package/schema/fixtures/event/invalid/audit-lock-reclaimed-agent-actor.json +14 -0
- package/schema/fixtures/event/invalid/audit-lock-reclaimed-lockfile-path.json +14 -0
- package/schema/fixtures/event/invalid/audit-lock-reclaimed-operator-cleared-system-actor.json +14 -0
- package/schema/fixtures/event/invalid/audit-lock-reclaimed-unknown-reason.json +14 -0
- package/schema/fixtures/event/invalid/audit-lock-reclaimed-without-age.json +13 -0
- package/schema/fixtures/event/invalid/audit-reviewed-agent-actor.json +6 -1
- package/schema/fixtures/event/invalid/audit-reviewed-bad-payload-hash.json +21 -0
- package/schema/fixtures/event/invalid/audit-reviewed-loved-no-note.json +5 -0
- package/schema/fixtures/event/invalid/audit-reviewed-model-actor.json +20 -0
- package/schema/fixtures/event/invalid/audit-reviewed-no-subject-hash.json +19 -0
- package/schema/fixtures/event/invalid/audit-reviewed-no-subject-seq.json +19 -0
- package/schema/fixtures/event/invalid/audit-reviewed-no-verdict-source.json +19 -0
- package/schema/fixtures/event/invalid/audit-reviewed-no-verdict.json +19 -0
- package/schema/fixtures/event/invalid/audit-reviewed-system-actor.json +6 -1
- package/schema/fixtures/event/invalid/audit-reviewed-verdict-source-model.json +20 -0
- package/schema/fixtures/event/invalid/audit-sampled-no-policy-hash.json +14 -0
- package/schema/fixtures/event/invalid/execution-started-harness-tool-space.json +18 -0
- package/schema/fixtures/event/valid/audit-lock-reclaimed-implausible-created.json +18 -0
- package/schema/fixtures/event/valid/audit-lock-reclaimed-legacy.json +14 -0
- package/schema/fixtures/event/valid/audit-lock-reclaimed-unlock.json +19 -0
- package/schema/fixtures/event/valid/audit-lock-reclaimed.json +19 -0
- package/schema/fixtures/event/valid/audit-reviewed-reaction.json +5 -0
- package/schema/fixtures/event/valid/audit-reviewed.json +6 -1
- package/schema/fixtures/event/valid/audit-sampled.json +2 -1
- package/schema/fixtures/event/valid/daemon-identity.json +2 -1
- package/schema/fixtures/event/valid/execution-started-harness-tool.json +19 -0
- package/schema/fixtures/policy/invalid/delegation-advice-string.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-class-duplicate.json +18 -0
- package/schema/fixtures/policy/invalid/delegation-class-wildcard.json +17 -0
- package/schema/fixtures/policy/invalid/delegation-daily-cap-fractional.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-daily-cap-negative.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-daily-cap-too-high.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-escalate-duplicate.json +18 -0
- package/schema/fixtures/policy/invalid/delegation-escalate-unknown.json +17 -0
- package/schema/fixtures/policy/invalid/delegation-max-autonomy-alias.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-max-autonomy-autonomous.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-model-no-version.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-model-provider-form.json +15 -0
- package/schema/fixtures/policy/invalid/delegation-null.json +7 -0
- package/schema/fixtures/policy/invalid/delegation-reviewer-agent.json +17 -0
- package/schema/fixtures/policy/invalid/delegation-reviewer-bare-id.json +17 -0
- package/schema/fixtures/policy/invalid/delegation-unknown-key.json +16 -0
- package/schema/fixtures/policy/invalid/tools-class-wildcard.json +9 -0
- package/schema/fixtures/policy/invalid/tools-match-double-star.json +9 -0
- package/schema/fixtures/policy/invalid/unmapped-tool-unknown.json +7 -0
- package/schema/fixtures/policy/valid/delegation-empty.json +7 -0
- package/schema/fixtures/policy/valid/delegation-grammar-full.json +41 -0
- package/schema/fixtures/policy/valid/delegation-off.json +15 -0
- package/schema/fixtures/policy/valid/tools-mapping.json +17 -0
- package/schema/policy.schema.json +178 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.1",
|
|
3
|
+
"defaults": {
|
|
4
|
+
"autonomy": "manual",
|
|
5
|
+
"unmapped_tool": "record"
|
|
6
|
+
},
|
|
7
|
+
"classes": {
|
|
8
|
+
"marketplace.*": { "autonomy": "manual" },
|
|
9
|
+
"marketplace.app.read": { "autonomy": "autonomous" },
|
|
10
|
+
"harness.tool.unmapped": { "autonomy": "supervised-retro" }
|
|
11
|
+
},
|
|
12
|
+
"tools": [
|
|
13
|
+
{ "match": "mcp__contextsling__publish", "class": "marketplace.contextsling.publish" },
|
|
14
|
+
{ "match": "mcp__contextsling__*", "class": "marketplace.app.read" },
|
|
15
|
+
{ "match": "*", "class": "marketplace.app.read" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -41,6 +41,12 @@
|
|
|
41
41
|
"default": "manual",
|
|
42
42
|
"examples": ["manual", "sealed"]
|
|
43
43
|
},
|
|
44
|
+
"unmapped_tool": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"enum": ["record", "ask"],
|
|
47
|
+
"description": "SPEC.md §5.2 (APRV-499, proposed): what a harness hook does with a tool call that neither the harness adapter's own tables (its shell, file, read and pass-through tools and its hard-coded rule table) nor any `tools` entry claims. `record`: the call is classified `harness.tool.unmapped`, which resolves `autonomous` when no `classes` rule matches it, so it proceeds and leaves an `execution.started` naming the tool. `ask`: the same class resolves `manual` when no rule matches it, so the call waits for a human. A `classes` rule matching `harness.tool.unmapped` decides it instead, exactly as a rule decides any class over `defaults.autonomy`. ABSENT, the behaviour of every policy written before the key existed: such a call is not a gate question, is allowed, and leaves no record.",
|
|
48
|
+
"examples": ["record", "ask"]
|
|
49
|
+
},
|
|
44
50
|
"on_expiry": {
|
|
45
51
|
"type": "string",
|
|
46
52
|
"enum": ["reject"],
|
|
@@ -85,6 +91,112 @@
|
|
|
85
91
|
]
|
|
86
92
|
]
|
|
87
93
|
},
|
|
94
|
+
"tools": {
|
|
95
|
+
"type": "array",
|
|
96
|
+
"description": "SPEC.md §5.2 (APRV-499, proposed): the classes a harness's OWN tool calls are judged under, by tool name, for the calls the harness adapter's built-in tables do not claim (every MCP tool, `mcp__<server>__<tool>` on Claude Code, among them). ORDERED: the first entry whose `match` matches the tool name decides, and later entries are not read. The adapter's own tables keep precedence over every entry, because they read the call's arguments and an entry reads only its name: an entry matching `terminal`, `Bash` or a Hermes `cronjob_manage` is inert. An entry's `class` must be declared by `classes`, as an exact key or under a trailing family key `<prefix>.*` whose literal prefix it extends (checked at load); an undeclared class fails the policy closed, because a mapping to a class nothing prices would resolve by `defaults.autonomy` and read as a decision nobody made. Absent or empty: no tool is mapped.",
|
|
97
|
+
"items": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"additionalProperties": false,
|
|
100
|
+
"required": ["match", "class"],
|
|
101
|
+
"properties": {
|
|
102
|
+
"match": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"minLength": 1,
|
|
105
|
+
"maxLength": 256,
|
|
106
|
+
"pattern": "^(?:[A-Za-z0-9_.:-]|\\*(?!\\*))+$",
|
|
107
|
+
"description": "The harness tool name this entry claims, compared case-sensitively against the WHOLE name. `*` is the only wildcard and matches any run of characters, including none, so `mcp__contextsling__*` claims every tool of that MCP server and `*` claims every tool nothing earlier claimed. Two `*` in a row, and every character outside letters, digits, `_`, `.`, `:` and `-`, are schema violations: a pattern language half-implemented here would be a mapping the author believed was in force and the runtime did not apply.",
|
|
108
|
+
"examples": ["mcp__contextsling__*", "mcp__zzz__post", "web_search"]
|
|
109
|
+
},
|
|
110
|
+
"class": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"minLength": 1,
|
|
113
|
+
"maxLength": 256,
|
|
114
|
+
"pattern": "^[a-z0-9][a-z0-9_-]*(?:\\.[a-z0-9][a-z0-9_-]*)*$",
|
|
115
|
+
"description": "The concrete class (no wildcard) the call is judged under. It must be an exact key of `classes` or extend the literal prefix of a declared trailing family key (`marketplace.*` covers `marketplace.contextsling.publish`), and it may not be `harness.tool.unmapped`, which names the calls no entry claimed (both checked at load).",
|
|
116
|
+
"examples": ["marketplace.contextsling.publish", "marketplace.app.read"]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"examples": [
|
|
121
|
+
[
|
|
122
|
+
{ "match": "mcp__contextsling__publish", "class": "marketplace.contextsling.publish" },
|
|
123
|
+
{ "match": "mcp__contextsling__*", "class": "marketplace.app.read" }
|
|
124
|
+
]
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"delegation": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"additionalProperties": false,
|
|
130
|
+
"description": "SPEC.md §5.2 (APRV-500, proposed; RESERVED in 0.4.2, no behaviour): the judge, a pinned model that may later review supervised samples, advise on manual cards, and decide manual cards in named classes within bounds. This release parses and validates the block and does nothing with it. It loads only in its OFF form (`model` null or absent, `classes` empty, `max_autonomy: manual`, `daily_cap: 0`, `escalate_on` empty, `advice: false`, `reviewers` empty; an empty mapping is the same thing), and the off form changes no resolution, no request and no record. ANY other value fails the policy closed with the load code `delegation-not-supported`, so every class resolves `manual`: a core that accepted `daily_cap: 10` and did nothing would be a setting its author believed was in force and the runtime silently ignored, which this closed schema exists to prevent. The relationships between keys (classes are exact keys of `classes`, the `max_autonomy` pin, the escalation floors, reviewer identities) are checked at load before the off-form check and fail closed as `schema-invalid`. Absent: the behaviour of every policy written before the key existed.",
|
|
131
|
+
"properties": {
|
|
132
|
+
"model": {
|
|
133
|
+
"anyOf": [{ "$ref": "#/$defs/modelIdentity" }, { "type": "null" }],
|
|
134
|
+
"description": "The judge identity whose records a later core would accept, `model:<name>@<major>.<minor>.<patch>`. The version pins the judge release (prompt, rubric and model snapshot). `null` or absent: no judge, and every other key is inert. RESERVED: any non-null value is `delegation-not-supported` in 0.4.2.",
|
|
135
|
+
"examples": [null, "model:judge@0.3.0"]
|
|
136
|
+
},
|
|
137
|
+
"classes": {
|
|
138
|
+
"type": "array",
|
|
139
|
+
"uniqueItems": true,
|
|
140
|
+
"items": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"minLength": 1,
|
|
143
|
+
"maxLength": 256,
|
|
144
|
+
"pattern": "^[a-z0-9][a-z0-9_-]*(?:\\.[a-z0-9][a-z0-9_-]*)*$"
|
|
145
|
+
},
|
|
146
|
+
"description": "The classes the judge may act on. Each entry is a concrete class (no wildcard, no `*`) and must be an EXACT key of `classes` whose own autonomy is neither `human-only` nor `autonomous` (checked at load): the delegated set is a set of lines the operator wrote by name, the reasoning `agent_may_request` uses. RESERVED: a non-empty list is `delegation-not-supported` in 0.4.2.",
|
|
147
|
+
"examples": [[], ["intent.publish.inferred.index"]]
|
|
148
|
+
},
|
|
149
|
+
"max_autonomy": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"enum": ["manual", "supervised-live", "supervised-retro"],
|
|
152
|
+
"default": "manual",
|
|
153
|
+
"description": "A non-loosening PIN between this block and the class rows. Every class listed in `classes` must declare an autonomy at least as strict as this value in SPEC.md §5.2's strictness order (checked at load, `schema-invalid` otherwise). It is a tamper pin rather than a dial: loosening a delegated class's row without rewriting this block fails the load, so the judge's scope never grows as a side effect of an unrelated edit. Absent means `manual`. RESERVED: any value other than `manual` is `delegation-not-supported` in 0.4.2.",
|
|
154
|
+
"examples": ["manual"]
|
|
155
|
+
},
|
|
156
|
+
"daily_cap": {
|
|
157
|
+
"type": "integer",
|
|
158
|
+
"minimum": 0,
|
|
159
|
+
"maximum": 1000,
|
|
160
|
+
"default": 0,
|
|
161
|
+
"description": "The most judge grants in any rolling 24 hours, across every delegated class together. 0 means the delegated approver is off. A value above 0 requires `escalate_on` to contain `irreversible` and `unknown_class` and requires `model` (checked at load). RESERVED: any value other than 0 is `delegation-not-supported` in 0.4.2.",
|
|
162
|
+
"examples": [0]
|
|
163
|
+
},
|
|
164
|
+
"escalate_on": {
|
|
165
|
+
"type": "array",
|
|
166
|
+
"uniqueItems": true,
|
|
167
|
+
"items": {
|
|
168
|
+
"type": "string",
|
|
169
|
+
"enum": ["deny", "low_confidence", "irreversible", "unknown_class"]
|
|
170
|
+
},
|
|
171
|
+
"description": "The judge outcomes that go to a human instead of standing, from a fixed set. RESERVED: a non-empty list is `delegation-not-supported` in 0.4.2.",
|
|
172
|
+
"examples": [[], ["deny", "low_confidence", "irreversible", "unknown_class"]]
|
|
173
|
+
},
|
|
174
|
+
"advice": {
|
|
175
|
+
"type": "boolean",
|
|
176
|
+
"default": false,
|
|
177
|
+
"description": "Whether the judge writes advice on manual cards in `classes`. `true` requires `model` (checked at load). RESERVED: `true` is `delegation-not-supported` in 0.4.2.",
|
|
178
|
+
"examples": [false]
|
|
179
|
+
},
|
|
180
|
+
"reviewers": {
|
|
181
|
+
"type": "array",
|
|
182
|
+
"uniqueItems": true,
|
|
183
|
+
"items": { "$ref": "#/$defs/delegationReviewer" },
|
|
184
|
+
"description": "Identities admitted to review samples of `classes`, in addition to each class's `approvers` roster: `human:<approver id>`, naming a key of `approvers`, or `model:<name>@<version>`, which must equal `model` exactly (both checked at load). This list is the ONLY place a `model:` identity is admitted: grants, attestations, reviews and channel decisions still require `human:`. RESERVED: a non-empty list is `delegation-not-supported` in 0.4.2.",
|
|
185
|
+
"examples": [[], ["model:judge@0.3.0", "human:alice"]]
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"examples": [
|
|
189
|
+
{
|
|
190
|
+
"model": null,
|
|
191
|
+
"classes": [],
|
|
192
|
+
"max_autonomy": "manual",
|
|
193
|
+
"daily_cap": 0,
|
|
194
|
+
"escalate_on": [],
|
|
195
|
+
"advice": false,
|
|
196
|
+
"reviewers": []
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
},
|
|
88
200
|
"read_scope": {
|
|
89
201
|
"type": "object",
|
|
90
202
|
"additionalProperties": false,
|
|
@@ -333,6 +445,20 @@
|
|
|
333
445
|
}
|
|
334
446
|
},
|
|
335
447
|
"$defs": {
|
|
448
|
+
"modelIdentity": {
|
|
449
|
+
"type": "string",
|
|
450
|
+
"maxLength": 128,
|
|
451
|
+
"pattern": "^model:[a-z0-9][a-z0-9-]{0,63}@[0-9]+\\.[0-9]+\\.[0-9]+$",
|
|
452
|
+
"description": "SPEC.md §5.2 (APRV-500, proposed; RESERVED): a judge identity, `model:<name>@<major>.<minor>.<patch>`. `<name>` is the judge service (lowercase alphanumerics and `-`, at most 64 characters) and the version pins one judge release. No record written by this release carries one: the event schema's actor patterns are unchanged, so a `model:` actor is refused at the write boundary.",
|
|
453
|
+
"examples": ["model:judge@0.3.0"]
|
|
454
|
+
},
|
|
455
|
+
"delegationReviewer": {
|
|
456
|
+
"type": "string",
|
|
457
|
+
"maxLength": 128,
|
|
458
|
+
"pattern": "^(?:human:[a-z0-9][a-z0-9_-]*|model:[a-z0-9][a-z0-9-]{0,63}@[0-9]+\\.[0-9]+\\.[0-9]+)$",
|
|
459
|
+
"description": "SPEC.md §5.2 (APRV-500, proposed; RESERVED): a reviewer identity in `delegation.reviewers`. `human:<approver id>` (the approver identifier grammar) or a `modelIdentity`.",
|
|
460
|
+
"examples": ["human:alice", "model:judge@0.3.0"]
|
|
461
|
+
},
|
|
336
462
|
"promptRow": {
|
|
337
463
|
"type": "string",
|
|
338
464
|
"enum": [
|
|
@@ -386,6 +512,58 @@
|
|
|
386
512
|
"$ref": "#/$defs/promptRows",
|
|
387
513
|
"description": "Visibility DOWN: the row never renders on this channel. Refused for the rows required for a decision — `action_key`, `class`, `command_breakdown`, `protected_path`, `policy_diff`, `policy_load` — and refused at policy load with the machine-readable keyword `prompt-row-required`, which fails the whole policy closed. `payload_hash` is NOT among them because the bound hash is stated inside the canonical block on every channel, so hiding the row removes a duplicate rather than the binding. Naming one row in both `always` and `hide` is refused rather than resolved by precedence: an author who wrote both believes one of them, and picking for them would be a guess.",
|
|
388
514
|
"examples": [["provenance", "chain", "requested_ts"]]
|
|
515
|
+
},
|
|
516
|
+
"style": {
|
|
517
|
+
"type": "string",
|
|
518
|
+
"enum": ["technical", "minimal"],
|
|
519
|
+
"default": "technical",
|
|
520
|
+
"description": "SPEC.md §5.2/§10.3 (APRV-489): how this channel lays out a prompt. `technical`, the default and what an absent key means, is the card every earlier build sent, byte for byte. `minimal` is a short card in plain words: a headline the runtime computes from the class, the payload's own words quoted from the bound bytes, a deadline in plain words, and the whole technical card, canonical rendering included, collapsed inside the same message as the Approve and Deny buttons (SPEC.md §10.3, amended APRV-489). Only Telegram draws it in this release; on `web` and `cli` the key is validated and IGNORED, which shows more than was asked for and never less. A request the minimal card cannot draw honestly (an opaque payload without a `say` declaration naming every key, an attestation, a policy edit, a digest, a truncated payload, an abnormal health row, a card over the message limit) is sent as the technical card. Review cards never change. The enum is closed: an unknown style fails validation, which fails the policy closed to all-`manual`.",
|
|
521
|
+
"examples": ["minimal"]
|
|
522
|
+
},
|
|
523
|
+
"say": {
|
|
524
|
+
"type": "object",
|
|
525
|
+
"propertyNames": { "type": "string", "pattern": "^[a-z0-9][a-z0-9_-]*(?:\\.[a-z0-9][a-z0-9_-]*)*$" },
|
|
526
|
+
"additionalProperties": { "$ref": "#/$defs/promptSay" },
|
|
527
|
+
"description": "SPEC.md §5.2 (APRV-489): what the minimal card says about a class, keyed by EXACT class name (no wildcard: one friendly phrase must never stand for several classes). Operator text the approver attests, never agent text. Read only under `style: minimal`.",
|
|
528
|
+
"examples": [
|
|
529
|
+
{
|
|
530
|
+
"digest.share": {
|
|
531
|
+
"does": "share a note about you",
|
|
532
|
+
"quote": { "scope": "Shared with", "expires_at": "Until", "text": "Note", "digest_id": null },
|
|
533
|
+
"note": "none"
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
]
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
"promptSay": {
|
|
541
|
+
"type": "object",
|
|
542
|
+
"additionalProperties": false,
|
|
543
|
+
"description": "SPEC.md §5.2 (APRV-489): one class's minimal-card declaration. `does` is required for a class core does not phrase itself and refused for one it does, or for a class the command classifier emits (checked at load). It is drawn only over an opaque payload: over a command, a file change or an email the runtime draws its own kind phrase.",
|
|
544
|
+
"properties": {
|
|
545
|
+
"does": {
|
|
546
|
+
"type": "string",
|
|
547
|
+
"minLength": 1,
|
|
548
|
+
"maxLength": 120,
|
|
549
|
+
"description": "The plain-words verb phrase the headline completes: `Your agent wants to <does>`. Starts with a letter; no line break, sentence punctuation (. ! ? … : ;), markup or ⚠ (checked at load). Not allowed for a class core phrases itself or a class the command classifier emits (`prompt-say-kind`). Drawn only over an opaque payload: over a command, a file change or an email the runtime's kind phrase is drawn instead and the decision record notes `say_does_ignored`. The runtime chooses the entry by the exact class the log records."
|
|
550
|
+
},
|
|
551
|
+
"quote": {
|
|
552
|
+
"type": "object",
|
|
553
|
+
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
|
|
554
|
+
"additionalProperties": {
|
|
555
|
+
"oneOf": [
|
|
556
|
+
{ "type": "string", "maxLength": 24 },
|
|
557
|
+
{ "type": "null" }
|
|
558
|
+
]
|
|
559
|
+
},
|
|
560
|
+
"description": "The closed field set for an OPAQUE payload: every top-level key the payload may carry, mapped to the label its value is quoted under (`\"\"` for no label), or `~` for a key known and deliberately left off the simple card (the card then names it under the quotations). At least one key must be shown (checked at load). A payload carrying any key this map does not name is sent as the technical card. Ignored for command, file-change and email payloads, whose excerpt is built in."
|
|
561
|
+
},
|
|
562
|
+
"note": {
|
|
563
|
+
"type": "string",
|
|
564
|
+
"enum": ["summary", "none"],
|
|
565
|
+
"default": "summary",
|
|
566
|
+
"description": "Whether the agent's own summary is shown, labelled as the agent's and as not checked: `summary` (the default) or `none`."
|
|
389
567
|
}
|
|
390
568
|
}
|
|
391
569
|
},
|