@delorenj/pjangler 1.4.2 → 1.4.4
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/README.md +528 -0
- package/contracts/fleet-contract.yaml +513 -0
- package/dist/index.js +9333 -1509
- package/dist/mcp-server.js +6634 -1096
- package/dist/prompt.js +2 -1
- package/package.json +10 -4
- package/templates/hermes-agent/copier.yml +16 -3
- package/templates/hermes-agent/template/.runtime-scaffold/memories/MEMORY.md +7 -4
- package/templates/hermes-agent/template/.scripts/10-hermes-profile.sh +88 -94
- package/templates/hermes-agent/template/.scripts/20-runtime-repo.sh +44 -21
- package/templates/hermes-agent/template/.scripts/30-telegram.sh +182 -171
- package/templates/hermes-agent/template/.scripts/31-slack.sh +260 -165
- package/templates/hermes-agent/template/.scripts/40-plane.sh +45 -36
- package/templates/hermes-agent/template/.scripts/42-ticket-provider.sh +210 -41
- package/templates/hermes-agent/template/.scripts/70-systemd.sh +129 -15
- package/templates/hermes-agent/template/.scripts/80-registry.sh +42 -6
- package/templates/hermes-agent/template/.scripts/99-summary.sh +69 -16
- package/templates/hermes-agent/template/.scripts/_lib.sh +773 -0
- package/templates/hermes-agent/template/.scripts/channel-transaction.py +2340 -0
- package/templates/hermes-agent/template/.scripts/config.example.toml +8 -2
- package/templates/hermes-agent/template/.scripts/credential-launch.sh +5 -1
- package/templates/hermes-agent/template/.scripts/heartbeat.sh +2 -3
- package/templates/hermes-agent/template/.scripts/lib/profile-config-lock.py +182 -0
- package/templates/hermes-agent/template/.scripts/lib/profile-config-seed.py +108 -0
- package/templates/hermes-agent/template/.scripts/lib/ticket-provider.sh +93 -4
- package/templates/hermes-agent/template/.scripts/lib/voice-config.py +546 -0
- package/templates/hermes-agent/template/.scripts/providers/linear.sh +138 -25
- package/templates/hermes-agent/template/.scripts/providers/plane.sh +408 -51
- package/templates/hermes-agent/template/.scripts/providers/trello.sh +54 -6
- package/templates/hermes-agent/template/.scripts/sentinel/bin/issue-autonomous-review.sh +257 -43
- package/templates/hermes-agent/template/.scripts/sentinel/bin/issue-close-gate.sh +142 -25
- package/templates/hermes-agent/template/.scripts/sentinel/docs/autonomous-delegated-review.md +13 -19
- package/templates/hermes-agent/template/.scripts/sentinel/docs/bloodbank-events.md +29 -36
- package/templates/hermes-agent/template/.scripts/sentinel/docs/continuous-ticket-orchestration.md +3 -1
- package/templates/hermes-agent/template/.scripts/sentinel.prompt.md.jinja +7 -8
- package/templates/hermes-agent/template/.scripts/store-onepassword-secret.py +260 -0
- package/templates/hermes-agent/template/SOUL.md.jinja +14 -16
- package/templates/hermes-agent/template/hermes.jinja +1 -1
- package/templates/hermes-agent/template/role.yaml.jinja +15 -4
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
# 33GOD fleet authority and managed-state contract.
|
|
2
|
+
#
|
|
3
|
+
# DECLARATION ONLY. This file records versions, authority owners,
|
|
4
|
+
# one-directional projections, lifecycle classes, the canonical service model,
|
|
5
|
+
# the activation gate, and retired modes. It carries no runtime observation, no
|
|
6
|
+
# credential, no host secret, and no absolute host path: stores are named by
|
|
7
|
+
# the environment keys that resolve them and every variable segment of a field
|
|
8
|
+
# path is a {placeholder}.
|
|
9
|
+
#
|
|
10
|
+
# Field paths are dotted key paths that exist in the live stores today. Roots:
|
|
11
|
+
# projects.* PJangler project registry
|
|
12
|
+
# agents.* Hermes agent registry, per-agent rows
|
|
13
|
+
# gateways.* Hermes agent registry, fleet-shared gateway block
|
|
14
|
+
# profiles.* generated Hermes profile tree
|
|
15
|
+
# scaffold.* tracked per-agent role scaffold
|
|
16
|
+
# units.* systemd user units
|
|
17
|
+
# processes.* observed Hermes processes (read-only)
|
|
18
|
+
#
|
|
19
|
+
# Namespaced `x-` keys at any depth round-trip verbatim and are never
|
|
20
|
+
# interpreted as policy.
|
|
21
|
+
#
|
|
22
|
+
# `service_model` and `activation` accept keys beyond the required ones on
|
|
23
|
+
# purpose: an unknown healthy-mode declaration must reach the retired-mode scan
|
|
24
|
+
# rather than be rejected as an unknown key, because rejecting it would hide the
|
|
25
|
+
# very drift this contract exists to name.
|
|
26
|
+
|
|
27
|
+
schema_version: 2
|
|
28
|
+
contract_version: 1.1.0
|
|
29
|
+
|
|
30
|
+
compatibility:
|
|
31
|
+
min_schema_version: 1
|
|
32
|
+
max_schema_version: 2
|
|
33
|
+
|
|
34
|
+
x-delonet/provenance:
|
|
35
|
+
assessment: fleet-convergence-live-assessment-2026-08-31
|
|
36
|
+
epic: registry-wide-fleet-convergence-control-plane
|
|
37
|
+
|
|
38
|
+
authorities:
|
|
39
|
+
project_identity:
|
|
40
|
+
owner: project-registry
|
|
41
|
+
store: pjangler-project-registry
|
|
42
|
+
store_env:
|
|
43
|
+
- PJ_PROJECT_REGISTRY
|
|
44
|
+
notes:
|
|
45
|
+
- Project identity and project-to-board binding.
|
|
46
|
+
- Board provenance fields exist only here, never in the agent registry.
|
|
47
|
+
writable_fields:
|
|
48
|
+
- projects.{slug}.name
|
|
49
|
+
- projects.{slug}.slug
|
|
50
|
+
- projects.{slug}.repo_path
|
|
51
|
+
- projects.{slug}.description
|
|
52
|
+
- projects.{slug}.status
|
|
53
|
+
- projects.{slug}.source_artifacts
|
|
54
|
+
- projects.{slug}.template
|
|
55
|
+
- projects.{slug}.ticket_provider.type
|
|
56
|
+
- projects.{slug}.ticket_provider.workspace
|
|
57
|
+
- projects.{slug}.ticket_provider.identifier
|
|
58
|
+
- projects.{slug}.ticket_provider.identifier_source
|
|
59
|
+
- projects.{slug}.ticket_provider.identifier_fetched_at
|
|
60
|
+
- projects.{slug}.ticket_provider.board_id
|
|
61
|
+
- projects.{slug}.ticket_provider.board_confirmed_at
|
|
62
|
+
- projects.{slug}.ticket_provider.board_url
|
|
63
|
+
- projects.{slug}.ticket_provider.state
|
|
64
|
+
- projects.{slug}.agents.{role}.role
|
|
65
|
+
- projects.{slug}.agents.{role}.provisioning_state
|
|
66
|
+
- projects.{slug}.agents.{role}.role_dir
|
|
67
|
+
- projects.{slug}.automation
|
|
68
|
+
- projects.{slug}.notebook
|
|
69
|
+
- projects.{slug}.created_at
|
|
70
|
+
- projects.{slug}.updated_at
|
|
71
|
+
|
|
72
|
+
agent_operational_records:
|
|
73
|
+
owner: hermes-agent-registry
|
|
74
|
+
store: hermes-agent-registry
|
|
75
|
+
store_env:
|
|
76
|
+
- HERMES_AGENTS_REGISTRY
|
|
77
|
+
- HERMES_FLEET_REGISTRY_FILE
|
|
78
|
+
notes:
|
|
79
|
+
- Operational agent, profile, and routing records.
|
|
80
|
+
- The two store_env keys disagree today. The TypeScript reader honours
|
|
81
|
+
HERMES_AGENTS_REGISTRY, the shell provisioner honours
|
|
82
|
+
HERMES_FLEET_REGISTRY_FILE. Both are recorded so convergence is a
|
|
83
|
+
declared task, not a silent surprise.
|
|
84
|
+
- Bloodbank routing metadata is discovery, not execution authority. The
|
|
85
|
+
single activation flag lives under the bloodbank_activation authority.
|
|
86
|
+
writable_fields:
|
|
87
|
+
- agents.{agent_id}.repo
|
|
88
|
+
- agents.{agent_id}.role
|
|
89
|
+
- agents.{agent_id}.display_name
|
|
90
|
+
- agents.{agent_id}.project_path
|
|
91
|
+
- agents.{agent_id}.role_dir
|
|
92
|
+
- agents.{agent_id}.profile_name
|
|
93
|
+
- agents.{agent_id}.provisioned_at
|
|
94
|
+
- agents.{agent_id}.runtime_repo
|
|
95
|
+
- agents.{agent_id}.telegram.provisioning_status
|
|
96
|
+
- agents.{agent_id}.slack.provisioning_status
|
|
97
|
+
- agents.{agent_id}.bloodbank.gateway_scope
|
|
98
|
+
- agents.{agent_id}.bloodbank.target_agent_id
|
|
99
|
+
- agents.{agent_id}.hermes.bin
|
|
100
|
+
- agents.{agent_id}.hermes.repo
|
|
101
|
+
- agents.{agent_id}.hermes.git_url
|
|
102
|
+
- agents.{agent_id}.hermes.git_ref
|
|
103
|
+
- agents.{agent_id}.hermes.git_sha
|
|
104
|
+
- agents.{agent_id}.hermes.fleet_env
|
|
105
|
+
- gateways.bloodbank.scope
|
|
106
|
+
- gateways.bloodbank.profile_name
|
|
107
|
+
- gateways.bloodbank.command_subject
|
|
108
|
+
- gateways.bloodbank.target_field
|
|
109
|
+
- gateways.bloodbank.systemd_unit
|
|
110
|
+
|
|
111
|
+
board_identity_projection:
|
|
112
|
+
owner: project-registry
|
|
113
|
+
store: hermes-agent-registry
|
|
114
|
+
store_env:
|
|
115
|
+
- HERMES_AGENTS_REGISTRY
|
|
116
|
+
- HERMES_FLEET_REGISTRY_FILE
|
|
117
|
+
notes:
|
|
118
|
+
- The one cross-store write that actually happens today. `pj project
|
|
119
|
+
identity --apply` copies confirmed board identity from the project
|
|
120
|
+
registry into the agent registry.
|
|
121
|
+
- Held as its own block so the agent registry's own writers cannot claim
|
|
122
|
+
these fields, and so the projections that target them have something
|
|
123
|
+
real to point at.
|
|
124
|
+
writable_fields:
|
|
125
|
+
- agents.{agent_id}.plane.workspace
|
|
126
|
+
- agents.{agent_id}.plane.project_id
|
|
127
|
+
- agents.{agent_id}.plane.identifier
|
|
128
|
+
|
|
129
|
+
generated_profile_inputs:
|
|
130
|
+
owner: hermes-profile-renderer
|
|
131
|
+
store: hermes-profile-tree
|
|
132
|
+
store_env:
|
|
133
|
+
- HERMES_FLEET_HOME
|
|
134
|
+
notes:
|
|
135
|
+
- config.yaml is generated by deep-merging the shared base with the
|
|
136
|
+
per-profile config.delta.yaml. It is never hand-edited.
|
|
137
|
+
- The rest of config.delta.yaml is the operator-owned override SSOT. Only
|
|
138
|
+
the three fleet-owned dotted paths listed here are rewritten by the
|
|
139
|
+
renderer.
|
|
140
|
+
writable_fields:
|
|
141
|
+
- profiles.{profile_name}.config.yaml
|
|
142
|
+
- profiles.{profile_name}.config.delta.memory.provider
|
|
143
|
+
- profiles.{profile_name}.config.delta.memory.memory_enabled
|
|
144
|
+
- profiles.{profile_name}.config.delta.memory.user_profile_enabled
|
|
145
|
+
|
|
146
|
+
tracked_role_scaffold:
|
|
147
|
+
owner: hermes-agent-template
|
|
148
|
+
store: hermes-agent-role-scaffold
|
|
149
|
+
store_env:
|
|
150
|
+
- HERMES_TEMPLATE_RUNTIME_SCAFFOLD
|
|
151
|
+
- RUNTIME_SCAFFOLD_DIR
|
|
152
|
+
notes:
|
|
153
|
+
- The committed template at its pinned gitlink owns every tracked asset in
|
|
154
|
+
a per-agent role directory. Role-local runtime bytes are ignored and are
|
|
155
|
+
owned by nobody.
|
|
156
|
+
writable_fields:
|
|
157
|
+
- scaffold.role.yaml
|
|
158
|
+
- scaffold.SOUL.md
|
|
159
|
+
- scaffold.hermes
|
|
160
|
+
- scaffold.momo
|
|
161
|
+
- scaffold.sentinel.prompt.md
|
|
162
|
+
- scaffold.gitignore
|
|
163
|
+
- scaffold.scripts
|
|
164
|
+
- scaffold.runtime-scaffold
|
|
165
|
+
|
|
166
|
+
systemd_lifecycle:
|
|
167
|
+
owner: hermes-fleet-provisioner
|
|
168
|
+
store: systemd-user-manager
|
|
169
|
+
store_env:
|
|
170
|
+
- XDG_CONFIG_HOME
|
|
171
|
+
notes:
|
|
172
|
+
- Unit files and the registry rows that name them are written by the
|
|
173
|
+
provisioner, not by registry editing paths.
|
|
174
|
+
writable_fields:
|
|
175
|
+
- units.hermes-{agent_id}-gateway.service
|
|
176
|
+
- units.hermes-{agent_id}-heartbeat.service
|
|
177
|
+
- units.hermes-{agent_id}-heartbeat.timer
|
|
178
|
+
- units.hermes-fleet-bloodbank-gateway.service
|
|
179
|
+
- agents.{agent_id}.systemd.gateway_unit
|
|
180
|
+
- agents.{agent_id}.systemd.heartbeat_timer
|
|
181
|
+
|
|
182
|
+
live_process_observations:
|
|
183
|
+
owner: fleet-observer
|
|
184
|
+
store: process-table
|
|
185
|
+
store_env: []
|
|
186
|
+
read_only: true
|
|
187
|
+
notes:
|
|
188
|
+
- Observation only. A process is attributed and classified; it is never
|
|
189
|
+
written to, and a drain is a separately authorized effect owned by a
|
|
190
|
+
later story.
|
|
191
|
+
writable_fields: []
|
|
192
|
+
|
|
193
|
+
bloodbank_activation:
|
|
194
|
+
owner: hermes-agent-registry
|
|
195
|
+
store: hermes-agent-registry
|
|
196
|
+
store_env:
|
|
197
|
+
- HERMES_AGENTS_REGISTRY
|
|
198
|
+
- HERMES_FLEET_REGISTRY_FILE
|
|
199
|
+
notes:
|
|
200
|
+
- The single field that can grant execution authority. Held apart from the
|
|
201
|
+
operational records so discovery can never widen into dispatch.
|
|
202
|
+
writable_fields:
|
|
203
|
+
- agents.{agent_id}.bloodbank.enabled
|
|
204
|
+
|
|
205
|
+
projections:
|
|
206
|
+
- field: project_repository_path
|
|
207
|
+
source: projects.{slug}.repo_path
|
|
208
|
+
target: agents.{agent_id}.project_path
|
|
209
|
+
direction: pjangler_project_registry_to_hermes_agent_registry
|
|
210
|
+
writable_by: hermes-agent-registry
|
|
211
|
+
|
|
212
|
+
- field: project_slug
|
|
213
|
+
source: projects.{slug}.slug
|
|
214
|
+
target: agents.{agent_id}.repo
|
|
215
|
+
direction: pjangler_project_registry_to_hermes_agent_registry
|
|
216
|
+
writable_by: hermes-agent-registry
|
|
217
|
+
|
|
218
|
+
- field: board_identifier
|
|
219
|
+
source: projects.{slug}.ticket_provider.identifier
|
|
220
|
+
target: agents.{agent_id}.plane.identifier
|
|
221
|
+
direction: pjangler_project_registry_to_hermes_agent_registry
|
|
222
|
+
writable_by: project-registry
|
|
223
|
+
|
|
224
|
+
- field: board_id
|
|
225
|
+
source: projects.{slug}.ticket_provider.board_id
|
|
226
|
+
target: agents.{agent_id}.plane.project_id
|
|
227
|
+
direction: pjangler_project_registry_to_hermes_agent_registry
|
|
228
|
+
writable_by: project-registry
|
|
229
|
+
|
|
230
|
+
- field: board_workspace
|
|
231
|
+
source: projects.{slug}.ticket_provider.workspace
|
|
232
|
+
target: agents.{agent_id}.plane.workspace
|
|
233
|
+
direction: pjangler_project_registry_to_hermes_agent_registry
|
|
234
|
+
writable_by: project-registry
|
|
235
|
+
|
|
236
|
+
- field: agent_role_directory
|
|
237
|
+
source: agents.{agent_id}.role_dir
|
|
238
|
+
target: projects.{slug}.agents.{role}.role_dir
|
|
239
|
+
direction: hermes_agent_registry_to_pjangler_project_registry
|
|
240
|
+
writable_by: project-registry
|
|
241
|
+
|
|
242
|
+
classifications:
|
|
243
|
+
managed_agent:
|
|
244
|
+
notes:
|
|
245
|
+
- A registered agent row. Instances are registry rows, not contract
|
|
246
|
+
entries, so this class declares its required shape and carries none.
|
|
247
|
+
required_fields:
|
|
248
|
+
- id
|
|
249
|
+
- kind
|
|
250
|
+
- owner
|
|
251
|
+
- source
|
|
252
|
+
- lifecycle_state
|
|
253
|
+
entries: []
|
|
254
|
+
|
|
255
|
+
managed_shared_service:
|
|
256
|
+
notes:
|
|
257
|
+
- Shared or specialist fleet state that is deliberately managed but is not
|
|
258
|
+
a per-agent row.
|
|
259
|
+
required_fields:
|
|
260
|
+
- id
|
|
261
|
+
- kind
|
|
262
|
+
- owner
|
|
263
|
+
- source
|
|
264
|
+
- lifecycle_state
|
|
265
|
+
- rationale
|
|
266
|
+
- policy_domains
|
|
267
|
+
entries:
|
|
268
|
+
- id: fleet-bloodbank-gateway
|
|
269
|
+
kind: shared-service
|
|
270
|
+
owner: hermes-fleet-provisioner
|
|
271
|
+
source: gateways.bloodbank
|
|
272
|
+
lifecycle_state: managed
|
|
273
|
+
rationale: One shared gateway owns Bloodbank command ingress fleet-wide.
|
|
274
|
+
policy_domains:
|
|
275
|
+
- systemd
|
|
276
|
+
- bloodbank
|
|
277
|
+
- profile
|
|
278
|
+
- id: fleet-shared-profile-base
|
|
279
|
+
kind: shared-config
|
|
280
|
+
owner: hermes-profile-renderer
|
|
281
|
+
source: profiles.base.config.yaml
|
|
282
|
+
lifecycle_state: managed
|
|
283
|
+
rationale: Every generated profile config is a merge of this base.
|
|
284
|
+
policy_domains:
|
|
285
|
+
- profile
|
|
286
|
+
|
|
287
|
+
intentionally_unmanaged:
|
|
288
|
+
notes:
|
|
289
|
+
- State an operator has decided the control plane must observe, report,
|
|
290
|
+
and leave alone. Instances are recorded when an observation is
|
|
291
|
+
classified; nothing is declared up front.
|
|
292
|
+
required_fields:
|
|
293
|
+
- id
|
|
294
|
+
- kind
|
|
295
|
+
- owner
|
|
296
|
+
- source
|
|
297
|
+
- lifecycle_state
|
|
298
|
+
- rationale
|
|
299
|
+
- policy_domains
|
|
300
|
+
entries: []
|
|
301
|
+
|
|
302
|
+
retired:
|
|
303
|
+
notes:
|
|
304
|
+
- Drift that used to be a supported mode. The retired block below is the
|
|
305
|
+
authoritative list; entries here are per-instance sightings.
|
|
306
|
+
required_fields:
|
|
307
|
+
- id
|
|
308
|
+
- kind
|
|
309
|
+
- owner
|
|
310
|
+
- source
|
|
311
|
+
- lifecycle_state
|
|
312
|
+
- rationale
|
|
313
|
+
- policy_domains
|
|
314
|
+
entries: []
|
|
315
|
+
|
|
316
|
+
unclassified:
|
|
317
|
+
notes:
|
|
318
|
+
- The default for anything observed that no rule above claims. It is a
|
|
319
|
+
finding for an operator, never a licence to delete.
|
|
320
|
+
required_fields:
|
|
321
|
+
- id
|
|
322
|
+
- kind
|
|
323
|
+
- owner
|
|
324
|
+
- source
|
|
325
|
+
- lifecycle_state
|
|
326
|
+
- rationale
|
|
327
|
+
- policy_domains
|
|
328
|
+
entries: []
|
|
329
|
+
|
|
330
|
+
service_model:
|
|
331
|
+
per_agent:
|
|
332
|
+
gateway_unit: hermes-{agent_id}-gateway.service
|
|
333
|
+
heartbeat_service: hermes-{agent_id}-heartbeat.service
|
|
334
|
+
heartbeat_timer: hermes-{agent_id}-heartbeat.timer
|
|
335
|
+
fleet_shared:
|
|
336
|
+
bloodbank_gateway_unit: hermes-fleet-bloodbank-gateway.service
|
|
337
|
+
bloodbank_gateway_profile: fleet-bloodbank-gateway
|
|
338
|
+
command_subject: bloodbank.cmd.agent.invocation.start
|
|
339
|
+
target_field: data.target_agent_id
|
|
340
|
+
profile_layout:
|
|
341
|
+
root: "{HERMES_FLEET_HOME}/profiles/{profile_name}"
|
|
342
|
+
symlink_allowed: false
|
|
343
|
+
identity_file: profile.yaml
|
|
344
|
+
override_file: config.delta.yaml
|
|
345
|
+
generated_file: config.yaml
|
|
346
|
+
generated_marker: GENERATED FILE -- DO NOT EDIT
|
|
347
|
+
|
|
348
|
+
# Which gaps are AUTHORIZED, and nothing else.
|
|
349
|
+
#
|
|
350
|
+
# Optional, and schema 1 contracts that omit it still load. What it changes is
|
|
351
|
+
# what an aggregate may CLAIM: a skip, a warning, a deferred capability, or a
|
|
352
|
+
# managed exception is "justified" only if it is named here, and anything
|
|
353
|
+
# unjustified keeps the fleet from claiming proof. Nothing in this block grants
|
|
354
|
+
# a capability, relaxes the activation gate, or turns an observation into a
|
|
355
|
+
# pass -- an authorized gap is still reported with its own state.
|
|
356
|
+
health_policy:
|
|
357
|
+
# Domains an aggregate must have observed before it may claim proof. All nine
|
|
358
|
+
# are required; the deferred_capabilities below are what carve out the halves
|
|
359
|
+
# no adapter exists for in this release.
|
|
360
|
+
required_domains:
|
|
361
|
+
- registry
|
|
362
|
+
- project_binding
|
|
363
|
+
- template_scaffold
|
|
364
|
+
- profile
|
|
365
|
+
- runtime
|
|
366
|
+
- systemd
|
|
367
|
+
- live_process
|
|
368
|
+
- bloodbank
|
|
369
|
+
- release_provenance
|
|
370
|
+
|
|
371
|
+
# A capability no observer in this release can answer, and the story that owns
|
|
372
|
+
# it. Each entry authorizes ONE unsupported answer; it never authorizes
|
|
373
|
+
# inferring the answer from something else.
|
|
374
|
+
deferred_capabilities:
|
|
375
|
+
- domain: systemd
|
|
376
|
+
capability: unit_topology
|
|
377
|
+
reason: >-
|
|
378
|
+
No systemd observer exists in this release. The unit names reported for
|
|
379
|
+
an agent are the patterns service_model.per_agent derives, carried as
|
|
380
|
+
expectations and never as observations of the user manager.
|
|
381
|
+
owner_story: "1.8"
|
|
382
|
+
- domain: live_process
|
|
383
|
+
capability: process_attribution
|
|
384
|
+
reason: >-
|
|
385
|
+
No process observer exists in this release: nothing in the build reads
|
|
386
|
+
the process table, so no running Hermes process can be attributed to a
|
|
387
|
+
registry row or classified as sprawl.
|
|
388
|
+
owner_story: "1.9"
|
|
389
|
+
- domain: bloodbank
|
|
390
|
+
capability: routing_liveness
|
|
391
|
+
reason: >-
|
|
392
|
+
The stored routing record is observed; whether the fleet-shared gateway
|
|
393
|
+
can dispatch to it is not. Routing readiness is a separate authority
|
|
394
|
+
from the record and must never be inferred from it.
|
|
395
|
+
owner_story: "1.10"
|
|
396
|
+
- domain: template_scaffold
|
|
397
|
+
capability: scaffold.template_ref
|
|
398
|
+
reason: >-
|
|
399
|
+
A deployed role scaffold records no template ref, so there is no
|
|
400
|
+
recorded value on this host to compare against the pinned gitlink and
|
|
401
|
+
none may be invented.
|
|
402
|
+
owner_story: "1.6"
|
|
403
|
+
- domain: release_provenance
|
|
404
|
+
capability: profile.render_generation
|
|
405
|
+
reason: >-
|
|
406
|
+
A generated profile config carries only the generated-file marker. The
|
|
407
|
+
renderer records no generation identity, so nothing comparable exists
|
|
408
|
+
until generated profile health is proven.
|
|
409
|
+
owner_story: "1.7"
|
|
410
|
+
- domain: release_provenance
|
|
411
|
+
capability: fleet.registry_file
|
|
412
|
+
reason: >-
|
|
413
|
+
The host config names the agent registry through an unexpanded shell
|
|
414
|
+
variable and this control plane must not resolve one. It is the same
|
|
415
|
+
declared divergence the agent_operational_records authority records in
|
|
416
|
+
its two store_env keys.
|
|
417
|
+
owner_story: "1.1"
|
|
418
|
+
|
|
419
|
+
# A rule whose warn is upstream cadence rather than fleet drift.
|
|
420
|
+
allowed_warnings:
|
|
421
|
+
- rule_id: bmad.version
|
|
422
|
+
reason: >-
|
|
423
|
+
A currency check against the published BMAD release, cached for an hour
|
|
424
|
+
and degraded to a skip offline. A newer upstream release is upstream
|
|
425
|
+
cadence, not drift in this fleet.
|
|
426
|
+
owner: bmad-method
|
|
427
|
+
|
|
428
|
+
# A rule or domain whose skip is a deliberate property of a read-only default
|
|
429
|
+
# run rather than an observation nobody got round to.
|
|
430
|
+
allowed_skips:
|
|
431
|
+
- rule_id: notebook.remote-notebook
|
|
432
|
+
reason: >-
|
|
433
|
+
A default audit makes no network request, so remote notebook state is
|
|
434
|
+
not applicable to it.
|
|
435
|
+
- rule_id: notebook.overview-note
|
|
436
|
+
reason: >-
|
|
437
|
+
A default audit makes no network request, so the remote Overview note is
|
|
438
|
+
not applicable to it.
|
|
439
|
+
- rule_id: notebook.skill-installed
|
|
440
|
+
reason: >-
|
|
441
|
+
A default audit reads no global path, so the host skill projection is
|
|
442
|
+
not applicable to it.
|
|
443
|
+
- rule_id: notebook.hooks-projected
|
|
444
|
+
reason: >-
|
|
445
|
+
A default audit reads no global settings file, so the host hook
|
|
446
|
+
projection is not applicable to it.
|
|
447
|
+
|
|
448
|
+
# How long a recorded timestamp may go unrefreshed before the value it stamps
|
|
449
|
+
# stops counting as current evidence. Reported as a BUCKET and never as an
|
|
450
|
+
# age: an age in seconds would make two runs over unchanged state differ.
|
|
451
|
+
freshness:
|
|
452
|
+
- field: projects.{slug}.ticket_provider.board_confirmed_at
|
|
453
|
+
max_age_days: 180
|
|
454
|
+
applies_to: project_binding
|
|
455
|
+
- field: projects.{slug}.ticket_provider.identifier_fetched_at
|
|
456
|
+
max_age_days: 180
|
|
457
|
+
applies_to: project_binding
|
|
458
|
+
- field: agents.{agent_id}.provisioned_at
|
|
459
|
+
max_age_days: 365
|
|
460
|
+
applies_to: registry
|
|
461
|
+
|
|
462
|
+
activation:
|
|
463
|
+
states:
|
|
464
|
+
- discovered
|
|
465
|
+
- installed
|
|
466
|
+
- healthy
|
|
467
|
+
- routing_ready
|
|
468
|
+
- activated
|
|
469
|
+
execution_authority:
|
|
470
|
+
field: agents.{agent_id}.bloodbank.enabled
|
|
471
|
+
owner: hermes-agent-registry
|
|
472
|
+
strict: true
|
|
473
|
+
default: deny
|
|
474
|
+
routing_prerequisites:
|
|
475
|
+
- field: agents.{agent_id}.bloodbank.gateway_scope
|
|
476
|
+
constraint: equals-fleet
|
|
477
|
+
- field: agents.{agent_id}.bloodbank.target_agent_id
|
|
478
|
+
constraint: equals-agent-id
|
|
479
|
+
- field: agents.{agent_id}.profile_name
|
|
480
|
+
constraint: nonblank
|
|
481
|
+
|
|
482
|
+
retired:
|
|
483
|
+
- id: per-agent-bloodbank-consumer
|
|
484
|
+
reason: A per-agent consumer races the shared gateway and duplicates work.
|
|
485
|
+
superseded_by: service_model.fleet_shared.bloodbank_gateway_unit
|
|
486
|
+
detect:
|
|
487
|
+
- '-consumer\.service'
|
|
488
|
+
- 'consumer_unit'
|
|
489
|
+
- id: per-agent-checkpoint-timer
|
|
490
|
+
reason: Checkpoint-only ticks proved liveness without proving health.
|
|
491
|
+
superseded_by: service_model.per_agent.heartbeat_timer
|
|
492
|
+
detect:
|
|
493
|
+
- '-checkpoint\.timer'
|
|
494
|
+
- 'checkpoint_timer'
|
|
495
|
+
- id: n8n-owned-truth
|
|
496
|
+
reason: Orchestration may consume fleet APIs but may not own fleet truth.
|
|
497
|
+
superseded_by: authorities.agent_operational_records
|
|
498
|
+
detect:
|
|
499
|
+
- 'n8n'
|
|
500
|
+
- id: activation-by-discovery
|
|
501
|
+
reason: A resolvable target is not permission to dispatch to it.
|
|
502
|
+
superseded_by: activation.execution_authority
|
|
503
|
+
detect:
|
|
504
|
+
- 'activation_by_discovery'
|
|
505
|
+
- 'auto_activate'
|
|
506
|
+
- 'activate_on_discovery'
|
|
507
|
+
- id: hard-coded-hermes-checkout-path
|
|
508
|
+
reason: Pinned releases are resolved from the registry, never from a path.
|
|
509
|
+
superseded_by: authorities.agent_operational_records
|
|
510
|
+
detect:
|
|
511
|
+
- '\$HOME/[^\s]*hermes'
|
|
512
|
+
- '~/[^\s]*hermes'
|
|
513
|
+
- '(?:^|/)code/hermes-agent'
|