@knowledge-bus/opencode 0.5.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sterling Freeman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { fileURLToPath } from "node:url";
2
+
3
+ // Register bundled skills in memory. Never copy files or edit the user's config.
4
+ export default async function knowledgeBus() {
5
+ const skillsPath = fileURLToPath(new URL("./skills", import.meta.url));
6
+ return {
7
+ async config(config) {
8
+ config.skills ??= {};
9
+ config.skills.paths = [...new Set([...(config.skills.paths ?? []), skillsPath])];
10
+ },
11
+ };
12
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@knowledge-bus/opencode",
3
+ "version": "0.5.0",
4
+ "private": false,
5
+ "description": "Knowledge Bus workflows for OpenCode",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./index.js",
9
+ "exports": {
10
+ ".": "./index.js",
11
+ "./server": "./index.js"
12
+ },
13
+ "files": [
14
+ "index.js",
15
+ "skills/",
16
+ "references/",
17
+ "runtime/",
18
+ "LICENSE"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public",
22
+ "registry": "https://registry.npmjs.org/"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/SterlingJF/knowledge-bus.git",
27
+ "directory": "plugins/opencode/knowledge-bus"
28
+ },
29
+ "homepage": "https://github.com/SterlingJF/knowledge-bus#readme"
30
+ }
@@ -0,0 +1,35 @@
1
+ # Checker for Agent Workflows
2
+
3
+ Read this when a workflow needs validation or code minting.
4
+
5
+ ## Locate the Runtime
6
+
7
+ Resolve paths from the loaded skill's directory, not from the shell's working directory.
8
+
9
+ - An individually installed skill has its own `runtime/kbp.py`.
10
+ - In a full plugin, the shared `runtime/kbp.py` is two directories above the skill directory.
11
+
12
+ Use the first location that exists. If neither exists, report an incomplete installation rather than running a different checker.
13
+
14
+ ## Run the Checker
15
+
16
+ Requires [uv](https://docs.astral.sh/uv/) and Python matching `requires_python` in the runtime's `requirements.json`. The launcher reports the requirement if the invoking interpreter is too old. Use the resolved absolute launcher path:
17
+
18
+ ```sh
19
+ python3 /absolute/runtime/kbp.py --validate /absolute/target/.knowledge-bus/
20
+ python3 /absolute/runtime/kbp.py --mint element 1 /absolute/target/.knowledge-bus/
21
+ ```
22
+
23
+ The bundled wheel supplies the checker and protocol. Its pinned dependency can be downloaded on first use. The launcher keeps its cache outside the installation and preserves the caller's working directory and failure exit code. If a prerequisite is missing, report it; do not install tools without permission.
24
+
25
+ Supply an absolute target when the shell is not in the user's folder. Checking never initializes a folder. `KNOWLEDGE_BUS_CACHE_DIR` optionally selects another external cache location.
26
+
27
+ ## References
28
+
29
+ The references directory containing this guide includes `knowledge-bus-protocol.yaml`. Read it when authoring or interpreting definitions. The ingestion skill also provides `product-development/` for adopting or adapting the starter. These are reference files, not the user's definitions; do not copy them automatically.
30
+
31
+ ## Interpreting Results
32
+
33
+ The checker first checks that its protocol is sound. It checks definitions and guidance for required fields, code collisions, references, version compatibility, and permitted structures. Include the universe when checking its guidance.
34
+
35
+ Each failure names the offending declaration or reference. Explain the change it calls for. A passing result does not establish that a question is useful or that an answer is true. Answers and ingestion logs still require human review.
@@ -0,0 +1,53 @@
1
+ # Knowledge Bus Directory
2
+
3
+ The `.knowledge-bus/` directory holds the definitions and supporting files for the folder that contains it. That containing folder can be a notes vault, document collection, project, or any other folder. This convention specifies where Knowledge Bus files live, not how to organize the surrounding files.
4
+
5
+ ## Directory Contents
6
+
7
+ ```text
8
+ my-folder/
9
+ ├── ... source files ...
10
+ └── .knowledge-bus/
11
+ ├── universe.kbp.yaml
12
+ ├── type-guidance.kbp.yaml # optional
13
+ ├── answers.yaml # when recording answers
14
+ └── ingest-log.md # when ingesting existing material
15
+ ```
16
+
17
+ Any folder can contain a `.knowledge-bus/` directory. Git is not required. Define the structure before creating documents, or derive it from existing material through ingestion. Answers and an ingest log are not prerequisites for authoring a universe.
18
+
19
+ ## Directory Selection
20
+
21
+ Explicit targets take precedence. Pass the folder, its `.knowledge-bus/` directory, or individual definition files:
22
+
23
+ ```sh
24
+ kbp --validate path/to/my-folder
25
+ kbp --validate path/to/my-folder/.knowledge-bus/
26
+ kbp --validate path/to/universe.kbp.yaml path/to/type-guidance.kbp.yaml
27
+ ```
28
+
29
+ Without an explicit target, the checker searches the current folder and then its parents for `.knowledge-bus/`. It uses the first one found and does not combine definitions from different directories. Calls from inside `.knowledge-bus/` use that directory. An empty or incomplete nearer directory does not fall back to a parent's `.knowledge-bus/`.
30
+
31
+ The selected Knowledge Bus directory supplies its directly contained `*.kbp.yaml` files together, so guidance can resolve its universe. Answers and logs are not checker inputs. Explicit file targets select exactly those files; include the universe when checking guidance.
32
+
33
+ A generic directory target without its own `.knowledge-bus/` still scans for `*.kbp.yaml` files, for example a reference collection or test corpus. It skips metadata directories and nested folders that contain their own `.knowledge-bus/`. Directory scans do not follow nested directory symlinks.
34
+
35
+ Missing definitions are an error when checking. Checking never creates a `.knowledge-bus/` directory.
36
+
37
+ ## Creating and Updating Definitions
38
+
39
+ Create `.knowledge-bus/` when the user asks to set up definitions for a folder. There is no separate `kbp init` command. Keep writes inside the selected metadata directory and leave existing source files untouched.
40
+
41
+ Inspect existing definitions, guidance, answers, and logs before writing. Reuse them or propose deliberate changes; do not reset or blindly overwrite them. Preserve decisions and history. Ask how to proceed if existing content is incompatible or ambiguous.
42
+
43
+ During ingestion, exclude every `.knowledge-bus/` directory from source material. Skip and report nested folders that contain their own `.knowledge-bus/`; ingest them separately only when explicitly targeted.
44
+
45
+ ## Protocol and Examples
46
+
47
+ The installed checker carries its protocol. Knowledge Bus directory discovery does not search for a `protocol/` directory. An explicit protocol file can still override the bundled protocol.
48
+
49
+ In the implementation checkout, `protocol/` remains the protocol source and `universes/` remains the bundled example collection. A bare `uv run kbp` there validates the examples when no `.knowledge-bus/` directory is found. Those reference files do not move into `.knowledge-bus/`.
50
+
51
+ ## Previous Locations
52
+
53
+ The sibling `<folder>-spec/` convention is no longer supported for discovery or output. There is no fallback or migration. Existing folders are not moved or deleted. An explicitly supplied file remains a valid checker target regardless of its location.
@@ -0,0 +1,432 @@
1
+ protocol:
2
+ id: kbp
3
+ name: Knowledge Bus Protocol
4
+ version: 0.5
5
+ status: draft
6
+ purpose: >
7
+ The structured exchange of contextual knowledge rather than data. Defines what a
8
+ universe is, how knowledge decomposes within one, and what occurs when a composed
9
+ artifact crosses into a universe that need not match the sender's.
10
+
11
+ concepts:
12
+
13
+ universe:
14
+ definition: >
15
+ An enumerated set of elements and artifacts for one domain, with the frames that
16
+ index them, the factors it declares without indexing by, and the relations
17
+ between them.
18
+ closed: [elements, artifacts, frames, factors, relation-kinds, statuses]
19
+ open: [instances]
20
+
21
+ element:
22
+ definition: A unit of conclusion, identified by the question its content answers.
23
+ standalone: false
24
+
25
+ artifact:
26
+ definition: >
27
+ A composition over elements, identified by the decision or action it enables for
28
+ a named actor.
29
+ standalone: true
30
+
31
+ frame:
32
+ definition: A dimension a universe is indexed by.
33
+ powers: [select, promote-to-core, gate-element, disable-artifact, return-empty]
34
+ declared_by: universe
35
+
36
+ factor:
37
+ definition: >
38
+ A dimension a universe declares and wires into nothing. It states that the
39
+ dimension exists and what its values are; whatever consumes the universe reads
40
+ it, sets it, and factors it in however it sees fit.
41
+ powers: []
42
+ declared_by: universe
43
+ valued_by: consumer
44
+ rules:
45
+ - >
46
+ A factor is referenced by nothing the universe declares. No element gate, no
47
+ artifact disabling, no composition entry, no empty composition, no relation
48
+ edge and no strength may name one.
49
+ - >
50
+ A guidance entry MAY condition on a factor the guided universe declares.
51
+ Selecting advice is not structure.
52
+
53
+ relation:
54
+ definition: A typed edge over element and artifact identities.
55
+ topology: [ordered, non-linear, cyclical, iterative, recursive]
56
+ kinds_declared_by: universe
57
+
58
+ instance:
59
+ definition: One asserted answer to an element's question, by a party, at a status, at a time.
60
+
61
+ guidance:
62
+ definition: >
63
+ Advisory content attached to an element, an artifact type or a factor — how to
64
+ answer its question well, and on whose authority.
65
+ advisory: true
66
+ standalone: false
67
+ attaches_to: [element, artifact, factor]
68
+ kinds_declared_by: guidance-document
69
+ rules:
70
+ - >
71
+ Guidance MUST NOT carry structure. Where a claim is load-bearing — where it
72
+ gates, orders, relates, or determines composition — it belongs in the universe
73
+ as a field or an edge, and guidance may only carry the reason for it.
74
+ - >
75
+ A value belongs in the universe because something reads it. Everything else
76
+ belongs in guidance. This is the whole of the split, and it is the rule to
77
+ apply where a declaration carries no structure for the first rule to bite on.
78
+ - >
79
+ A factor conditioning a guidance entry is not structure. It selects which
80
+ advice applies; it never selects what an artifact is made of.
81
+ - A universe MUST remain valid with no guidance document present.
82
+ - Divergence from a guidance claim is not non-conformance.
83
+
84
+ declarations:
85
+
86
+ document_types:
87
+ dispatch: >
88
+ A document declares its type by its top-level header key. Both types below carry
89
+ a header block named for the type, and a reader selects the shape by that key.
90
+ kinds: [universe, guidance]
91
+
92
+ frame_predicate:
93
+ form: "{ <frame-id | factor-id>: [<value>, ...] }"
94
+ nested: "{ <frame-id | factor-id>: { <facet>: [<value>, ...] } }"
95
+ scope: >
96
+ A predicate in a universe names frames only. A factor id is legal in a guidance
97
+ entry's `when` and nowhere else.
98
+
99
+ universe:
100
+ document:
101
+ universe:
102
+ id: "<universe-id>"
103
+ label: "<human label>"
104
+ version: "<version>"
105
+ conforms_to: "<protocol-id>/<version>"
106
+ ordering_frame: "<frame-id>"
107
+ overview: { covers: "<prose>", for: "<prose>", excludes: "<prose>" }
108
+ statuses: ["<status>"]
109
+ frames: ["<frame>"]
110
+ factors: ["<factor>"]
111
+ empty_composition: { when: "<frame-predicate>" }
112
+ relation_kinds: ["<relation-kind>"]
113
+ elements: ["<element>"]
114
+ artifacts: ["<artifact>"]
115
+ relations: ["<edge>"]
116
+ instances: ["<instance-record>"]
117
+ required: [universe, statuses, frames, empty_composition, relation_kinds, elements, artifacts, relations]
118
+ header_required: [id, version, conforms_to, ordering_frame]
119
+
120
+ code:
121
+ form: "<kind-letter><four characters from the alphabet below>"
122
+ kinds: { element: e, artifact: a, frame: f, factor: k }
123
+ alphabet: "0123456789abcdefghjkmnpqrstvwxyz"
124
+ minted_by: "kbp-conform.py --mint <kind> [count]"
125
+ rules:
126
+ - >
127
+ A code is stable. Once published it never changes, whatever happens to the
128
+ slug id or the wording of the question, and it is never reused by a second
129
+ declaration after the first is retired.
130
+ - >
131
+ A code carries no order and no meaning. It is not derived from the id, the
132
+ question, or a position in any list. Order is the ordering frame's job.
133
+ - >
134
+ The kind letter is the set, so a code identifies its declaration across the
135
+ whole universe, and a code minted in one universe means nothing in another.
136
+ - >
137
+ Two readerships, two keys. A person or an agent keys on the id and the
138
+ question — that is what makes a universe readable. A tool or a backend keys
139
+ on the code, because it must survive editorial change without a migration. A
140
+ code is never rendered in copy a person reads.
141
+ - >
142
+ The alphabet omits i, l, o and u. That is what keeps a minted code out of
143
+ reach of a parser's implicit types: no code can spell a boolean, null, or
144
+ anything numeric.
145
+
146
+ element:
147
+ id: "<element-id>"
148
+ code: "<code>"
149
+ question: "<conclusion-test question>"
150
+ "<ordering-frame-id>": "<ordering-value>"
151
+ cardinality: singleton | "per-<dimension>"
152
+ closable: true | false
153
+ gate: "<frame-predicate>"
154
+ required: [id, code, question, "<ordering-frame-id>", cardinality]
155
+
156
+ artifact:
157
+ id: "<artifact-id>"
158
+ code: "<code>"
159
+ enablement:
160
+ action: "<what the actor can now do>"
161
+ actor: "<who does it>"
162
+ timing: "<when they do it>"
163
+ alias:
164
+ kind: descriptive | normative | none
165
+ form: "<external form>"
166
+ reason: "<required when kind is none>"
167
+ disabled_when: "<frame-predicate>"
168
+ composition:
169
+ core: ["<composition-entry>"] # the enabled action cannot be taken without these
170
+ situational: ["<composition-entry>"] # included when the frames call for them
171
+ required: [id, code, enablement, composition]
172
+
173
+ frame:
174
+ id: "<frame-id>"
175
+ code: "<code>"
176
+ role: ordering | applicability | gating | selection
177
+ set_by: universe | scope | instance
178
+ question: "<what the frame asks>"
179
+ values: '["<value>"] or [{ id: "<value>", question: "<conclusion-test question>" }]'
180
+ facets: { "<facet-id>": ["<value>"] }
181
+ attaches_to: "<what this frame indexes>"
182
+ source: "<external registry, where values are not declared inline>"
183
+ required: [id, code, role, set_by]
184
+ one_of: [values, facets, source]
185
+
186
+ factor:
187
+ id: "<factor-id>"
188
+ code: "<code>"
189
+ set_by: universe | scope | instance
190
+ question: "<what the factor asks>"
191
+ values: '["<value>"] or [{ id: "<value>", question: "<conclusion-test question>" }]'
192
+ facets: { "<facet-id>": ["<value>"] }
193
+ source: "<external registry, where values are not declared inline>"
194
+ required: [id, code, question, set_by]
195
+ one_of: [values, facets, source]
196
+ # The frame shape without `role` or `attaches_to`, because a factor has no job in
197
+ # the index and indexes nothing. `question` is required here and optional on a
198
+ # frame: a consumer that has to determine a value needs to know what is being asked.
199
+
200
+ relation_kind:
201
+ id: "<kind-id>"
202
+ ordered: true | false
203
+ required: [id, ordered]
204
+
205
+ guidance:
206
+ document:
207
+ guidance: { id: "<guidance-id>", label: "<human label>", version: "<version>", conforms_to: "<protocol-id>/<version>", guides: "<universe-id>" }
208
+ guidance_kinds: ["<guidance-kind>"]
209
+ sources: "{ <source-id>: <source> }"
210
+ elements: "{ <element-id>: [<guidance-entry>, ...] }"
211
+ artifacts: "{ <artifact-id>: [<guidance-entry>, ...] }"
212
+ factors: "{ <factor-id>: [<guidance-entry>, ...] }"
213
+ required: [guidance, guidance_kinds]
214
+ header_required: [id, version, conforms_to, guides]
215
+
216
+ guidance_kind:
217
+ id: "<kind-id>"
218
+ sourced: true | false
219
+ required: [id, sourced]
220
+
221
+ guidance_entry:
222
+ kind: "<guidance-kind>"
223
+ claim: "<one claim, in one sentence or two>"
224
+ source: "<source-id | asserted>"
225
+ when: "<frame-predicate>"
226
+ required: [kind, claim, source]
227
+
228
+ source:
229
+ cite: "<bibliographic reference>"
230
+ url: "<url>"
231
+ checked: "<date the source was last verified>"
232
+ required: [cite]
233
+
234
+ identity:
235
+
236
+ element:
237
+ test: conclusion
238
+ question: "What question does this content answer?"
239
+ key: [question]
240
+ rules:
241
+ - Two candidates answering the same question are the same element, universe-wide.
242
+ - Local naming within an artifact does not affect identity.
243
+ - >
244
+ The code is a handle, not the key. It addresses an element without depending on
245
+ its wording; correspondence between universes remains by question.
246
+
247
+ instance:
248
+ key: [element, status, asserted_by]
249
+ rules:
250
+ - >
251
+ A universe MUST admit several concurrent instances of one element differing
252
+ only by status or asserting party. Collapsing them to a single current value
253
+ is non-conforming.
254
+
255
+ artifact:
256
+ test: enablement
257
+ question: "What decision or action does this enable, and for whom?"
258
+ key: [action, actor]
259
+ rules:
260
+ - Two compositions enabling the same action for the same actor are one artifact.
261
+ - An artifact MUST declare an enablement before it declares a composition.
262
+ - >
263
+ The code is a handle, not the key. Renaming an artifact type or restating its
264
+ enablement leaves the code untouched.
265
+
266
+ strength:
267
+ rule: >
268
+ An element is core to an artifact if and only if the enabled action cannot be
269
+ taken without it. All other composed elements are situational.
270
+ derived: true
271
+
272
+ composition:
273
+
274
+ entry:
275
+ element: "<element-id>"
276
+ strength: core | situational
277
+ mode: owns | links
278
+ when: "<frame-predicate>"
279
+ shorthand:
280
+ form: "<element-id>"
281
+ expands_to: { element: "<element-id>", mode: owns }
282
+ note: strength comes from the core or situational list the entry appears in
283
+ required: [element]
284
+
285
+ rules:
286
+ - An element appears at most once per artifact.
287
+ - Exactly one artifact owns a given element instance; others link to the owner.
288
+ - Strength MAY be conditional on a frame predicate.
289
+ - A universe MAY disable an artifact type entirely under a frame predicate.
290
+ - >
291
+ A universe MUST be able to return the empty composition. Where no frame value
292
+ warrants structure, the conforming answer is no artifact.
293
+
294
+ ordering:
295
+ declared_by: universe
296
+ attaches_to: element
297
+ rule: >
298
+ A universe declares exactly one ordering frame, whose values are assigned to
299
+ elements. An artifact's position in the order, where required, is derived from
300
+ the elements it composes.
301
+
302
+ relations:
303
+
304
+ edge:
305
+ from: "<element-id | artifact-id>"
306
+ to: "<element-id | artifact-id>"
307
+ kind: "<relation-kind>"
308
+ legality: permitted | permitted-if-logged | forbidden
309
+ gate: { authority: "<frame-value>", latency: "<duration>" }
310
+ freeze: open | baselined | superseded
311
+ required: [from, to, kind]
312
+
313
+ rules:
314
+ - Every edge declares a kind.
315
+ - Every edge on a cycle declares legality.
316
+ - >
317
+ permitted-if-logged requires the traversal to be recorded as an instance before
318
+ the resulting value is admitted.
319
+ - An edge into a baselined target is an event, not an edit; it MUST NOT mutate in place.
320
+
321
+ instances:
322
+
323
+ record:
324
+ element: "<element-id>"
325
+ value: "<content>"
326
+ asserted_by: "<party>"
327
+ binding_on: ["<party>"]
328
+ status: "<status>"
329
+ observed_at: "<timestamp>"
330
+ supersedes: "<instance-id | null>"
331
+ exhaustive: unknown | true | false
332
+
333
+ rules:
334
+ - asserted_by and binding_on are independent.
335
+ - Every instance carries the time its value was established.
336
+ - An instance is never edited in place; a new instance supersedes it.
337
+ - A superseded instance remains retrievable and citable.
338
+ - >
339
+ exhaustive answers whether THIS set of instances is complete, and applies only
340
+ where cardinality is per-dimension. Default unknown.
341
+ - >
342
+ exhaustive MUST NOT be asserted true where the element declares closable false.
343
+ Whether a complete set can exist at all is the element's closable; whether one
344
+ has been assembled yet is this field.
345
+
346
+ exchange:
347
+
348
+ premise: >
349
+ Within a boundary the body is shared whole and requires no protocol. The protocol
350
+ governs the crossing, where sender and receiver need not share a universe, a frame
351
+ set, or an authority.
352
+
353
+ sequence:
354
+ - step: compose
355
+ by: sender
356
+ input: [body, enablement, audience]
357
+ output: artifact
358
+ - step: transmit
359
+ carries: [artifact, composition, instance-records, universe-reference]
360
+ rule: Instance records travel with the artifact; asserted_by, status and observed_at MUST NOT be stripped.
361
+ - step: decode
362
+ by: receiver
363
+ output: [elements, decisions, assumptions]
364
+ rule: The receiver re-instantiates into their own universe and decides within their own frames.
365
+ - step: reconcile
366
+ by: receiver
367
+ rule: >
368
+ Where a decoded instance meets a local instance of the same element, the
369
+ receiver records disagreement. Silent overwrite is non-conforming.
370
+
371
+ correspondence:
372
+ rule: >
373
+ Two elements in different universes correspond when their questions are the same.
374
+ Names, local labels and host artifacts are irrelevant to the match.
375
+ receiver_obligations:
376
+ - MUST accept an artifact containing elements its own universe gates off.
377
+ - MUST hold uncorresponded elements as inert rather than rejecting the artifact.
378
+ - MUST NOT treat a decoded instance as a local decision.
379
+
380
+ aliases:
381
+ kinds:
382
+ descriptive: >
383
+ An external form the composition aligns with. The universe could derive it
384
+ independently; divergence is a variation.
385
+ normative: >
386
+ An external authority owns shape and content. It versions independently of the
387
+ universe, and local divergence renders the local artifact invalid.
388
+ none:
389
+ reason: no-aligned-form | non-decomposable
390
+ rules:
391
+ - An alias MAY map to a set of elements.
392
+ - Several aliases MAY map to one artifact.
393
+ - >
394
+ reason non-decomposable records an external form whose units confer effect
395
+ rather than answer questions. Such a form MUST NOT be aliased.
396
+
397
+ conformance:
398
+
399
+ guidance_valid_if:
400
+ - >
401
+ Every element, artifact and factor key resolves to a declared id in the guided
402
+ universe.
403
+ - Every entry declares a kind drawn from the document's own guidance_kinds.
404
+ - >
405
+ Every entry declares a source that is either a key in sources or the literal
406
+ asserted. A kind declared sourced MUST NOT be satisfied by asserted.
407
+ - Every when predicate names a frame or a factor the guided universe declares.
408
+ - guides resolves to a universe declaring the same conforms_to.
409
+ - >
410
+ Guidance is advisory. No universe may depend on a guidance document to be valid,
411
+ and no guidance claim may be required for conformance.
412
+
413
+ universe_valid_if:
414
+ - Every element declares a question, and no two elements share one.
415
+ - Every artifact declares an enablement with both an action and an actor.
416
+ - Every core element is derivable from its artifact's enablement.
417
+ - Every relation edge declares a kind; every cyclical edge declares legality.
418
+ - Every instance declares asserted_by, status and observed_at.
419
+ - >
420
+ The element, artifact, frame, factor, relation-kind and status sets are
421
+ enumerated.
422
+ - >
423
+ Every element, artifact, frame and factor declares a code carrying its kind's
424
+ letter, and no two declarations in a universe share one.
425
+ - >
426
+ No predicate a universe declares names a factor. Factors are declared and wired
427
+ into nothing.
428
+ - Exactly one ordering frame is declared, and it attaches to elements.
429
+ - The empty composition is reachable.
430
+ - >
431
+ Every field a universe declares appears in the corresponding declarations shape.
432
+ A universe carrying fields the protocol does not sanction is non-conforming.