@logicsrc/schemas 0.1.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/README.md +34 -0
- package/fixtures/agent.yaml +20 -0
- package/fixtures/agentad-ad.yaml +33 -0
- package/fixtures/agentad-placement.yaml +21 -0
- package/fixtures/opencontext/conformance.json +279 -0
- package/fixtures/opencontext/invalid/audit-event-missing-actor.json +5 -0
- package/fixtures/opencontext/invalid/audit-event-unknown-event.json +9 -0
- package/fixtures/opencontext/invalid/bundle-bad-digest.json +11 -0
- package/fixtures/opencontext/invalid/bundle-bad-id.json +11 -0
- package/fixtures/opencontext/invalid/bundle-missing-digest.json +10 -0
- package/fixtures/opencontext/invalid/bundle-unknown-exclusion-reason.json +17 -0
- package/fixtures/opencontext/invalid/decision-bad-status.json +7 -0
- package/fixtures/opencontext/invalid/decision-missing-decision.json +5 -0
- package/fixtures/opencontext/invalid/decision-wrong-type.json +6 -0
- package/fixtures/opencontext/invalid/diagnostic-missing-ok.json +4 -0
- package/fixtures/opencontext/invalid/diagnostic-unknown-code.json +11 -0
- package/fixtures/opencontext/invalid/manifest-bad-authority.json +10 -0
- package/fixtures/opencontext/invalid/manifest-bad-extension.json +9 -0
- package/fixtures/opencontext/invalid/manifest-bad-id.json +4 -0
- package/fixtures/opencontext/invalid/manifest-bad-ttl.json +7 -0
- package/fixtures/opencontext/invalid/manifest-missing-version.json +3 -0
- package/fixtures/opencontext/invalid/manifest-role-bad-pattern.json +11 -0
- package/fixtures/opencontext/invalid/manifest-unknown-key.json +5 -0
- package/fixtures/opencontext/invalid/object-bad-digest.json +10 -0
- package/fixtures/opencontext/invalid/object-bad-id.json +4 -0
- package/fixtures/opencontext/invalid/object-bad-layer.json +5 -0
- package/fixtures/opencontext/invalid/object-bad-redaction-mode.json +10 -0
- package/fixtures/opencontext/invalid/object-bad-supersedes.json +7 -0
- package/fixtures/opencontext/invalid/object-confidence-out-of-range.json +5 -0
- package/fixtures/opencontext/invalid/object-extra-property.json +5 -0
- package/fixtures/opencontext/invalid/object-missing-id.json +3 -0
- package/fixtures/opencontext/invalid/object-missing-type.json +3 -0
- package/fixtures/opencontext/invalid/object-source-without-uri.json +9 -0
- package/fixtures/opencontext/invalid/object-unknown-authority.json +5 -0
- package/fixtures/opencontext/invalid/object-unknown-classification.json +5 -0
- package/fixtures/opencontext/invalid/object-unknown-trust.json +5 -0
- package/fixtures/opencontext/invalid/provenance-canonical-false.json +4 -0
- package/fixtures/opencontext/invalid/provenance-no-source.json +3 -0
- package/fixtures/opencontext/invalid/role-bad-classification.json +4 -0
- package/fixtures/opencontext/invalid/role-bad-include.json +6 -0
- package/fixtures/opencontext/invalid-manifest.json +177 -0
- package/fixtures/opencontext/resolution/authority-conflict/context/policies/refunds-observed.md +10 -0
- package/fixtures/opencontext/resolution/authority-conflict/context/policies/refunds.md +12 -0
- package/fixtures/opencontext/resolution/authority-conflict/expected.json +21 -0
- package/fixtures/opencontext/resolution/authority-conflict/opencontext.yaml +11 -0
- package/fixtures/opencontext/resolution/classification-ceiling/context/docs/handbook.md +11 -0
- package/fixtures/opencontext/resolution/classification-ceiling/context/docs/litigation.md +11 -0
- package/fixtures/opencontext/resolution/classification-ceiling/expected.json +32 -0
- package/fixtures/opencontext/resolution/classification-ceiling/opencontext.yaml +16 -0
- package/fixtures/opencontext/resolution/deny-overrides-allow/context/mission.md +10 -0
- package/fixtures/opencontext/resolution/deny-overrides-allow/context/policies/internal/margins.md +10 -0
- package/fixtures/opencontext/resolution/deny-overrides-allow/context/policies/refunds.md +10 -0
- package/fixtures/opencontext/resolution/deny-overrides-allow/expected.json +19 -0
- package/fixtures/opencontext/resolution/deny-overrides-allow/opencontext.yaml +17 -0
- package/fixtures/opencontext/resolution/duplicate-canonical/context/policies/refunds-rewrite.md +12 -0
- package/fixtures/opencontext/resolution/duplicate-canonical/context/policies/refunds.md +12 -0
- package/fixtures/opencontext/resolution/duplicate-canonical/expected.json +10 -0
- package/fixtures/opencontext/resolution/duplicate-canonical/opencontext.yaml +11 -0
- package/fixtures/opencontext/resolution/lifecycle/context/notes/current.md +11 -0
- package/fixtures/opencontext/resolution/lifecycle/context/notes/expired.md +12 -0
- package/fixtures/opencontext/resolution/lifecycle/context/notes/future.md +12 -0
- package/fixtures/opencontext/resolution/lifecycle/context/notes/stale.md +11 -0
- package/fixtures/opencontext/resolution/lifecycle/expected.json +30 -0
- package/fixtures/opencontext/resolution/lifecycle/opencontext.yaml +14 -0
- package/fixtures/opencontext/resolution/object-permissions/context/policies/payroll.md +12 -0
- package/fixtures/opencontext/resolution/object-permissions/context/policies/refunds.md +10 -0
- package/fixtures/opencontext/resolution/object-permissions/expected.json +32 -0
- package/fixtures/opencontext/resolution/object-permissions/opencontext.yaml +14 -0
- package/fixtures/opencontext/resolution/redaction/context/customers/acme.json +21 -0
- package/fixtures/opencontext/resolution/redaction/expected.json +28 -0
- package/fixtures/opencontext/resolution/redaction/opencontext.yaml +19 -0
- package/fixtures/opencontext/resolution/supersession/context/pricing/enterprise.v1.md +12 -0
- package/fixtures/opencontext/resolution/supersession/context/pricing/enterprise.v2.md +14 -0
- package/fixtures/opencontext/resolution/supersession/expected.json +33 -0
- package/fixtures/opencontext/resolution/supersession/opencontext.yaml +11 -0
- package/fixtures/opencontext/valid/audit-event.json +26 -0
- package/fixtures/opencontext/valid/bundle.json +67 -0
- package/fixtures/opencontext/valid/decision.json +51 -0
- package/fixtures/opencontext/valid/diagnostic.json +37 -0
- package/fixtures/opencontext/valid/manifest-minimal.json +4 -0
- package/fixtures/opencontext/valid/manifest.json +134 -0
- package/fixtures/opencontext/valid/object-minimal.json +4 -0
- package/fixtures/opencontext/valid/object-policy.json +75 -0
- package/fixtures/opencontext/valid/object-structured.json +34 -0
- package/fixtures/opencontext/valid/object-untrusted.json +19 -0
- package/fixtures/opencontext/valid/provenance-canonical.json +4 -0
- package/fixtures/opencontext/valid/provenance.json +14 -0
- package/fixtures/opencontext/valid/role.json +38 -0
- package/fixtures/openontology/conformance.json +158 -0
- package/fixtures/openontology/invalid/action-no-permissions.json +13 -0
- package/fixtures/openontology/invalid/changeset-empty-operations.json +10 -0
- package/fixtures/openontology/invalid/changeset-unknown-op.json +15 -0
- package/fixtures/openontology/invalid/claim-both-objects.json +14 -0
- package/fixtures/openontology/invalid/claim-confidence-out-of-range.json +14 -0
- package/fixtures/openontology/invalid/claim-extra-property.json +14 -0
- package/fixtures/openontology/invalid/claim-unknown-status.json +13 -0
- package/fixtures/openontology/invalid/entity-missing-canonical-name.json +8 -0
- package/fixtures/openontology/invalid/evidence-unknown-selector.json +10 -0
- package/fixtures/openontology/invalid/manifest-bad-id.json +15 -0
- package/fixtures/openontology/invalid/manifest-bad-version.json +15 -0
- package/fixtures/openontology/invalid/manifest-no-maintainer.json +11 -0
- package/fixtures/openontology/invalid/relationship-no-range.json +11 -0
- package/fixtures/openontology/valid/action.json +29 -0
- package/fixtures/openontology/valid/approval.json +12 -0
- package/fixtures/openontology/valid/changeset.json +34 -0
- package/fixtures/openontology/valid/claim-relationship.json +23 -0
- package/fixtures/openontology/valid/claim-value.json +15 -0
- package/fixtures/openontology/valid/constraint.json +12 -0
- package/fixtures/openontology/valid/entity-type.json +16 -0
- package/fixtures/openontology/valid/entity.json +16 -0
- package/fixtures/openontology/valid/event.json +17 -0
- package/fixtures/openontology/valid/evidence.json +12 -0
- package/fixtures/openontology/valid/manifest.json +21 -0
- package/fixtures/openontology/valid/namespace.json +7 -0
- package/fixtures/openontology/valid/property.json +8 -0
- package/fixtures/openontology/valid/query-adhoc.json +16 -0
- package/fixtures/openontology/valid/query.json +24 -0
- package/fixtures/openontology/valid/relationship-type.json +16 -0
- package/fixtures/openontology/valid/review.json +17 -0
- package/fixtures/openontology/valid/source.json +13 -0
- package/fixtures/openprd/conformance.json +104 -0
- package/fixtures/openprd/invalid/bad-filename.md +41 -0
- package/fixtures/openprd/invalid/bad-id-format.md +41 -0
- package/fixtures/openprd/invalid/bad-status.md +41 -0
- package/fixtures/openprd/invalid/dates-backwards.md +43 -0
- package/fixtures/openprd/invalid/duplicate-requirement.md +42 -0
- package/fixtures/openprd/invalid/id-mismatch.md +41 -0
- package/fixtures/openprd/invalid/missing-section.md +37 -0
- package/fixtures/openprd/invalid/missing-title.md +40 -0
- package/fixtures/openprd/invalid/no-front-matter.md +33 -0
- package/fixtures/openprd/invalid/out-of-order.md +41 -0
- package/fixtures/openprd/invalid/superseded-without-replacement.md +41 -0
- package/fixtures/openprd/invalid/unknown-key.md +42 -0
- package/fixtures/openprd/valid/bold-requirements.md +41 -0
- package/fixtures/openprd/valid/full.md +48 -0
- package/fixtures/openprd/valid/minimal.md +41 -0
- package/fixtures/openprd/valid/none-sections.md +41 -0
- package/fixtures/openprd/valid/subsections.md +47 -0
- package/fixtures/openprd/valid/superseded.md +42 -0
- package/fixtures/openprd-prd.yaml +12 -0
- package/fixtures/pull-request.yaml +24 -0
- package/fixtures/repo.yaml +27 -0
- package/fixtures/task.yaml +26 -0
- package/package.json +91 -0
- package/schemas/agentad-ad-request.schema.json +32 -0
- package/schemas/agentad-ad-response.schema.json +31 -0
- package/schemas/agentad-ad.schema.json +79 -0
- package/schemas/agentad-campaign.schema.json +40 -0
- package/schemas/agentad-click.schema.json +23 -0
- package/schemas/agentad-impression.schema.json +18 -0
- package/schemas/agentad-placement.schema.json +46 -0
- package/schemas/logicsrc-account-audit-event.schema.json +31 -0
- package/schemas/logicsrc-account-grant.schema.json +48 -0
- package/schemas/logicsrc-account-provider.schema.json +31 -0
- package/schemas/logicsrc-agent.schema.json +51 -0
- package/schemas/logicsrc-connected-account.schema.json +39 -0
- package/schemas/logicsrc-credential-audit-event.schema.json +32 -0
- package/schemas/logicsrc-credential-provider.schema.json +28 -0
- package/schemas/logicsrc-credential-sync-plan.schema.json +56 -0
- package/schemas/logicsrc-credential-sync-run.schema.json +35 -0
- package/schemas/logicsrc-email-message.schema.json +22 -0
- package/schemas/logicsrc-event.schema.json +25 -0
- package/schemas/logicsrc-opencontext-audit-event.schema.json +69 -0
- package/schemas/logicsrc-opencontext-bundle.schema.json +210 -0
- package/schemas/logicsrc-opencontext-decision.schema.json +229 -0
- package/schemas/logicsrc-opencontext-diagnostic.schema.json +123 -0
- package/schemas/logicsrc-opencontext-manifest.schema.json +337 -0
- package/schemas/logicsrc-opencontext-object.schema.json +311 -0
- package/schemas/logicsrc-opencontext-provenance.schema.json +76 -0
- package/schemas/logicsrc-opencontext-role.schema.json +93 -0
- package/schemas/logicsrc-openontology-action.schema.json +90 -0
- package/schemas/logicsrc-openontology-approval.schema.json +39 -0
- package/schemas/logicsrc-openontology-changeset.schema.json +168 -0
- package/schemas/logicsrc-openontology-claim.schema.json +148 -0
- package/schemas/logicsrc-openontology-constraint.schema.json +104 -0
- package/schemas/logicsrc-openontology-entity-type.schema.json +107 -0
- package/schemas/logicsrc-openontology-entity.schema.json +59 -0
- package/schemas/logicsrc-openontology-event.schema.json +60 -0
- package/schemas/logicsrc-openontology-evidence.schema.json +121 -0
- package/schemas/logicsrc-openontology-manifest.schema.json +148 -0
- package/schemas/logicsrc-openontology-namespace.schema.json +21 -0
- package/schemas/logicsrc-openontology-package.schema.json +73 -0
- package/schemas/logicsrc-openontology-property.schema.json +83 -0
- package/schemas/logicsrc-openontology-query.schema.json +207 -0
- package/schemas/logicsrc-openontology-relationship-type.schema.json +57 -0
- package/schemas/logicsrc-openontology-review.schema.json +37 -0
- package/schemas/logicsrc-openontology-source.schema.json +43 -0
- package/schemas/logicsrc-plugin.schema.json +35 -0
- package/schemas/logicsrc-pull-request.schema.json +73 -0
- package/schemas/logicsrc-repo.schema.json +73 -0
- package/schemas/logicsrc-run.schema.json +69 -0
- package/schemas/logicsrc-social-post.schema.json +26 -0
- package/schemas/logicsrc-task.schema.json +114 -0
- package/schemas/openprd-prd.schema.json +79 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://logicsrc.com/schemas/opencontext/manifest.schema.json",
|
|
4
|
+
"title": "OpenContext Manifest",
|
|
5
|
+
"description": "The root manifest of an OpenContext repository, canonically named opencontext.yaml (opencontext.json is also permitted). It declares which context exists, where it is loaded from, who may read it, how authority is ranked, how freshness is judged, and which audit events are recorded. The manifest is a control plane: it points at systems that remain the sources of truth, and is not itself the database.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["opencontext", "id"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"opencontext": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^\\d+\\.\\d+(\\.\\d+)?$",
|
|
13
|
+
"description": "OpenContext specification version this manifest conforms to, e.g. '1.0'. Implementations MUST refuse a major version they do not support rather than guess."
|
|
14
|
+
},
|
|
15
|
+
"id": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
18
|
+
"description": "Stable identifier for this context namespace, e.g. 'acme'. Object ids are unique within it."
|
|
19
|
+
},
|
|
20
|
+
"name": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"minLength": 1,
|
|
23
|
+
"description": "Human-readable name of the organization or project this context belongs to."
|
|
24
|
+
},
|
|
25
|
+
"description": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "One-paragraph summary of what this context repository covers."
|
|
28
|
+
},
|
|
29
|
+
"context": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"description": "Named single-document context entries. Each key becomes a resolvable object id; each value is a path or URI. Example: mission: ./context/mission.md",
|
|
32
|
+
"additionalProperties": { "type": "string", "minLength": 1 },
|
|
33
|
+
"propertyNames": { "$ref": "#/$defs/segment" }
|
|
34
|
+
},
|
|
35
|
+
"collections": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"description": "Named globs or URIs that expand to many context objects. The key namespaces the ids of everything the collection loads, so ./context/policies/refunds.md under the 'policies' collection becomes policies.refunds unless the document declares its own id.",
|
|
38
|
+
"additionalProperties": {
|
|
39
|
+
"anyOf": [
|
|
40
|
+
{ "type": "string", "minLength": 1 },
|
|
41
|
+
{ "$ref": "#/$defs/collectionSpec" }
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"propertyNames": { "$ref": "#/$defs/segment" }
|
|
45
|
+
},
|
|
46
|
+
"roles": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"description": "Named scopes. A role declares which context its holders may read, which context is denied, and which capabilities they hold. Deny always overrides allow.",
|
|
49
|
+
"additionalProperties": { "$ref": "#/$defs/role" },
|
|
50
|
+
"propertyNames": { "$ref": "#/$defs/segment" }
|
|
51
|
+
},
|
|
52
|
+
"agents": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"description": "Named consumers mapped to the roles they hold. An agent's scope is the union of its roles' includes minus the union of their excludes; an agent holds no context rights of its own.",
|
|
55
|
+
"additionalProperties": { "$ref": "#/$defs/agentBinding" },
|
|
56
|
+
"propertyNames": { "$ref": "#/$defs/segment" }
|
|
57
|
+
},
|
|
58
|
+
"authority": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": false,
|
|
61
|
+
"description": "How competing objects are ranked. Precedence MAY be overridden but MUST remain a permutation of the standard authority levels — a repository cannot invent a level that outranks canonical.",
|
|
62
|
+
"properties": {
|
|
63
|
+
"precedence": {
|
|
64
|
+
"type": "array",
|
|
65
|
+
"minItems": 1,
|
|
66
|
+
"uniqueItems": true,
|
|
67
|
+
"items": { "$ref": "#/$defs/authority" },
|
|
68
|
+
"description": "Highest authority first. Default: canonical, approved, reference, observed, inferred, historical."
|
|
69
|
+
},
|
|
70
|
+
"tie_breakers": {
|
|
71
|
+
"type": "array",
|
|
72
|
+
"uniqueItems": true,
|
|
73
|
+
"items": { "type": "string", "enum": ["version", "updated", "created", "confidence", "id"] },
|
|
74
|
+
"description": "Applied in order when two candidates remain tied after authority and supersession. Default: version, updated, confidence, id. Resolution appends id as a final total tie breaker so the outcome is always deterministic."
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"freshness": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"additionalProperties": false,
|
|
81
|
+
"description": "Defaults for lifecycle evaluation. Per-object metadata always wins over these defaults.",
|
|
82
|
+
"properties": {
|
|
83
|
+
"default_ttl": {
|
|
84
|
+
"$ref": "#/$defs/duration",
|
|
85
|
+
"description": "How long an object stays 'current' after its updated timestamp before it is reported 'stale', e.g. '30d'. Staleness is a warning: stale context is still resolved, and still flagged."
|
|
86
|
+
},
|
|
87
|
+
"stale_is_error": {
|
|
88
|
+
"type": "boolean",
|
|
89
|
+
"default": false,
|
|
90
|
+
"description": "When true, --strict treats stale context as a failure rather than a warning."
|
|
91
|
+
},
|
|
92
|
+
"exclude_expired": {
|
|
93
|
+
"type": "boolean",
|
|
94
|
+
"default": true,
|
|
95
|
+
"description": "When true (default), expired objects are excluded from resolution unless historical context is explicitly requested."
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"provenance": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"additionalProperties": false,
|
|
102
|
+
"description": "Provenance policy. When required, every resolved object MUST carry a source or declare itself canonical source material.",
|
|
103
|
+
"properties": {
|
|
104
|
+
"required": { "type": "boolean", "default": false, "description": "Require every resolved object to be attributable." },
|
|
105
|
+
"digest": { "type": "string", "enum": ["sha256"], "default": "sha256", "description": "Digest algorithm for source integrity and bundle digests." },
|
|
106
|
+
"require_digest": { "type": "boolean", "default": false, "description": "Require every declared remote source to carry an integrity digest." }
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"audit": {
|
|
110
|
+
"type": "object",
|
|
111
|
+
"additionalProperties": false,
|
|
112
|
+
"description": "Which events implementations should record. The specification defines the event shape; it does not mandate a storage backend.",
|
|
113
|
+
"properties": {
|
|
114
|
+
"context_reads": { "type": "boolean", "default": false },
|
|
115
|
+
"context_writes": { "type": "boolean", "default": false },
|
|
116
|
+
"decisions": { "type": "boolean", "default": false },
|
|
117
|
+
"conflicts": { "type": "boolean", "default": false },
|
|
118
|
+
"sink": { "type": "string", "description": "Optional URI the reference implementation appends audit events to, e.g. file://./context/.audit/events.ndjson" }
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"redact": {
|
|
122
|
+
"type": "array",
|
|
123
|
+
"description": "Repository-wide redaction rules, applied after authorization and before compilation.",
|
|
124
|
+
"items": { "$ref": "#/$defs/redaction" }
|
|
125
|
+
},
|
|
126
|
+
"review": {
|
|
127
|
+
"$ref": "#/$defs/review",
|
|
128
|
+
"description": "Default review cadence for objects that do not declare their own."
|
|
129
|
+
},
|
|
130
|
+
"adapters": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"description": "URI schemes this repository expects to resolve, mapped to adapter configuration. A scheme no installed adapter claims MUST fail clearly rather than silently resolve to nothing.",
|
|
133
|
+
"additionalProperties": { "$ref": "#/$defs/adapterConfig" },
|
|
134
|
+
"propertyNames": { "type": "string", "pattern": "^[a-z][a-z0-9+.-]*$" }
|
|
135
|
+
},
|
|
136
|
+
"defaults": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"additionalProperties": false,
|
|
139
|
+
"description": "Field defaults applied to objects that omit them. Defaults describe house style; they never launder authority, and an implementation MUST NOT default observed or inferred content to canonical.",
|
|
140
|
+
"properties": {
|
|
141
|
+
"layer": { "$ref": "#/$defs/layer" },
|
|
142
|
+
"authority": { "$ref": "#/$defs/authority" },
|
|
143
|
+
"classification": { "$ref": "#/$defs/classification" },
|
|
144
|
+
"durability": { "$ref": "#/$defs/durability" },
|
|
145
|
+
"trust": { "$ref": "#/$defs/trust" },
|
|
146
|
+
"owner": { "type": "string", "minLength": 1 },
|
|
147
|
+
"ttl": { "$ref": "#/$defs/duration" }
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"health": {
|
|
151
|
+
"type": "object",
|
|
152
|
+
"additionalProperties": false,
|
|
153
|
+
"description": "Configuration for `opencontext doctor`. The score formula is documented and configurable so a CI threshold means the same thing across repositories.",
|
|
154
|
+
"properties": {
|
|
155
|
+
"minimum_score": { "type": "number", "minimum": 0, "maximum": 100, "description": "Doctor exits non-zero below this score when --strict is set." },
|
|
156
|
+
"weights": {
|
|
157
|
+
"type": "object",
|
|
158
|
+
"description": "Per-diagnostic-code weight overriding the documented default. Deductions are weight x affected objects, normalised by object count.",
|
|
159
|
+
"additionalProperties": { "type": "number", "minimum": 0 },
|
|
160
|
+
"propertyNames": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" }
|
|
161
|
+
},
|
|
162
|
+
"fail_on": { "$ref": "#/$defs/severity", "description": "Lowest severity that fails a strict run. Default: error." },
|
|
163
|
+
"require_owner": { "type": "boolean", "default": false, "description": "Treat objects with no owner as an error rather than a warning." }
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"related": {
|
|
167
|
+
"type": "object",
|
|
168
|
+
"additionalProperties": false,
|
|
169
|
+
"description": "Optional links to sibling LogicSRC specifications. These integrations MUST remain optional: OpenContext is independently usable without either of them.",
|
|
170
|
+
"properties": {
|
|
171
|
+
"prd": { "type": "string", "description": "Path or URI of an OpenPRD document or collection." },
|
|
172
|
+
"topology": { "type": "string", "description": "Path or URI of an OpenTopology manifest." },
|
|
173
|
+
"ontology": { "type": "string", "description": "Path or URI of an OpenOntology package." }
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"extensions": { "$ref": "#/$defs/extensions" }
|
|
177
|
+
},
|
|
178
|
+
"$defs": {
|
|
179
|
+
"segment": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"pattern": "^[a-z0-9][a-z0-9_-]*$",
|
|
182
|
+
"description": "A single dotted-id segment: lowercase alphanumerics, dashes, underscores."
|
|
183
|
+
},
|
|
184
|
+
"duration": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"pattern": "^\\d+(ms|s|m|h|d|w|y)$",
|
|
187
|
+
"description": "A duration such as '30d', '12h', or '180d'. Units are fixed lengths: y = 365d, w = 7d, d = 24h."
|
|
188
|
+
},
|
|
189
|
+
"layer": {
|
|
190
|
+
"type": "string",
|
|
191
|
+
"enum": ["L0", "L1", "L2", "L3", "L4", "L5"],
|
|
192
|
+
"description": "L0 mission, L1 identity, L2 knowledge, L3 policy, L4 procedure, L5 operational."
|
|
193
|
+
},
|
|
194
|
+
"authority": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"enum": ["canonical", "approved", "reference", "observed", "inferred", "historical"],
|
|
197
|
+
"description": "Declared truth level, highest to lowest by default."
|
|
198
|
+
},
|
|
199
|
+
"trust": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"enum": ["trusted", "verified", "untrusted"],
|
|
202
|
+
"description": "Whether the content originated inside the trust boundary."
|
|
203
|
+
},
|
|
204
|
+
"durability": {
|
|
205
|
+
"type": "string",
|
|
206
|
+
"enum": ["ephemeral", "session", "operational", "long-lived", "permanent"]
|
|
207
|
+
},
|
|
208
|
+
"classification": {
|
|
209
|
+
"type": "string",
|
|
210
|
+
"enum": ["public", "internal", "confidential", "restricted"]
|
|
211
|
+
},
|
|
212
|
+
"severity": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"enum": ["info", "warning", "error"]
|
|
215
|
+
},
|
|
216
|
+
"collectionSpec": {
|
|
217
|
+
"type": "object",
|
|
218
|
+
"required": ["source"],
|
|
219
|
+
"additionalProperties": false,
|
|
220
|
+
"description": "A collection declared with options rather than as a bare glob string.",
|
|
221
|
+
"properties": {
|
|
222
|
+
"source": { "type": "string", "minLength": 1, "description": "Glob or URI the collection loads from." },
|
|
223
|
+
"type": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$", "description": "Default object type for members that omit one." },
|
|
224
|
+
"layer": { "$ref": "#/$defs/layer" },
|
|
225
|
+
"authority": { "$ref": "#/$defs/authority" },
|
|
226
|
+
"classification": { "$ref": "#/$defs/classification" },
|
|
227
|
+
"durability": { "$ref": "#/$defs/durability" },
|
|
228
|
+
"trust": { "$ref": "#/$defs/trust" },
|
|
229
|
+
"owner": { "type": "string", "minLength": 1 },
|
|
230
|
+
"ttl": { "$ref": "#/$defs/duration" }
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"role": {
|
|
234
|
+
"type": "object",
|
|
235
|
+
"additionalProperties": false,
|
|
236
|
+
"description": "A named scope. Relevance and authorization are different questions: include says what is in scope, and nothing in scope is returned if a deny, an exclusion, or a classification ceiling says otherwise.",
|
|
237
|
+
"properties": {
|
|
238
|
+
"description": { "type": "string" },
|
|
239
|
+
"include": {
|
|
240
|
+
"type": "array",
|
|
241
|
+
"uniqueItems": true,
|
|
242
|
+
"items": { "$ref": "#/$defs/pattern" },
|
|
243
|
+
"description": "Id patterns in scope, e.g. mission, products.*, policies.support.*. A role with no include sees nothing."
|
|
244
|
+
},
|
|
245
|
+
"exclude": {
|
|
246
|
+
"type": "array",
|
|
247
|
+
"uniqueItems": true,
|
|
248
|
+
"items": { "$ref": "#/$defs/pattern" },
|
|
249
|
+
"description": "Id patterns denied. Applied before relevance ranking and unconditionally overriding include."
|
|
250
|
+
},
|
|
251
|
+
"permissions": {
|
|
252
|
+
"type": "array",
|
|
253
|
+
"uniqueItems": true,
|
|
254
|
+
"items": { "type": "string", "minLength": 1 },
|
|
255
|
+
"description": "Capability strings such as customer.read or ticket.write. OpenContext carries these; it does not enforce your application's actions."
|
|
256
|
+
},
|
|
257
|
+
"max_classification": {
|
|
258
|
+
"$ref": "#/$defs/classification",
|
|
259
|
+
"description": "Highest classification this role may read. Objects above it are denied even when included. Defaults to internal."
|
|
260
|
+
},
|
|
261
|
+
"redact": {
|
|
262
|
+
"type": "array",
|
|
263
|
+
"description": "Redaction rules applied to everything this role reads.",
|
|
264
|
+
"items": { "$ref": "#/$defs/redaction" }
|
|
265
|
+
},
|
|
266
|
+
"inherits": {
|
|
267
|
+
"type": "array",
|
|
268
|
+
"uniqueItems": true,
|
|
269
|
+
"items": { "$ref": "#/$defs/segment" },
|
|
270
|
+
"description": "Roles whose scope is merged into this one. Includes union; excludes and redactions also union, so inheriting can only ever narrow what is readable."
|
|
271
|
+
},
|
|
272
|
+
"extensions": { "$ref": "#/$defs/extensions" }
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
"pattern": {
|
|
276
|
+
"type": "string",
|
|
277
|
+
"minLength": 1,
|
|
278
|
+
"pattern": "^([a-z0-9][a-z0-9_-]*|\\*)(\\.([a-z0-9][a-z0-9_-]*|\\*))*$",
|
|
279
|
+
"description": "An exact object id, a trailing wildcard such as policies.support.* covering that subtree, an interior wildcard such as customers.*.churn-risk matching exactly one segment, or * for everything. Wildcards match whole segments only."
|
|
280
|
+
},
|
|
281
|
+
"agentBinding": {
|
|
282
|
+
"type": "object",
|
|
283
|
+
"required": ["roles"],
|
|
284
|
+
"additionalProperties": false,
|
|
285
|
+
"properties": {
|
|
286
|
+
"roles": {
|
|
287
|
+
"type": "array",
|
|
288
|
+
"minItems": 1,
|
|
289
|
+
"uniqueItems": true,
|
|
290
|
+
"items": { "$ref": "#/$defs/segment" },
|
|
291
|
+
"description": "Roles this agent holds. A role named here that the manifest does not define is a validation error."
|
|
292
|
+
},
|
|
293
|
+
"description": { "type": "string" },
|
|
294
|
+
"extensions": { "$ref": "#/$defs/extensions" }
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
"adapterConfig": {
|
|
298
|
+
"type": "object",
|
|
299
|
+
"additionalProperties": true,
|
|
300
|
+
"description": "Adapter options. Unknown keys are passed through to the adapter, which validates them.",
|
|
301
|
+
"properties": {
|
|
302
|
+
"enabled": { "type": "boolean", "default": true },
|
|
303
|
+
"package": { "type": "string", "description": "Module implementing the adapter contract for this scheme." },
|
|
304
|
+
"offline": { "type": "boolean", "description": "When true this adapter is skipped in --offline runs instead of failing them." },
|
|
305
|
+
"trust": { "$ref": "#/$defs/trust", "description": "Trust applied to content this adapter returns when the object does not declare its own. Remote adapters SHOULD default to untrusted." },
|
|
306
|
+
"timeout_ms": { "type": "integer", "minimum": 1 }
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"redaction": {
|
|
310
|
+
"type": "object",
|
|
311
|
+
"required": ["path"],
|
|
312
|
+
"additionalProperties": false,
|
|
313
|
+
"properties": {
|
|
314
|
+
"path": { "type": "string", "minLength": 1, "description": "Dotted path into structured content, with [] or [*] for every element of an array." },
|
|
315
|
+
"mode": { "type": "string", "enum": ["remove", "mask", "hash"], "default": "remove" },
|
|
316
|
+
"replacement": { "type": "string", "default": "[REDACTED]" },
|
|
317
|
+
"reason": { "type": "string" }
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
"review": {
|
|
321
|
+
"type": "object",
|
|
322
|
+
"additionalProperties": false,
|
|
323
|
+
"properties": {
|
|
324
|
+
"interval": { "$ref": "#/$defs/duration" },
|
|
325
|
+
"required_approvers": { "type": "integer", "minimum": 1 },
|
|
326
|
+
"next_review": { "type": "string", "format": "date" },
|
|
327
|
+
"last_review": { "type": "string", "format": "date" }
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
"extensions": {
|
|
331
|
+
"type": "object",
|
|
332
|
+
"description": "Namespaced custom fields, e.g. com.example.risk. Unknown extensions MUST be preserved and MUST NOT invalidate an otherwise valid document unless strict mode explicitly requires known extensions.",
|
|
333
|
+
"propertyNames": { "type": "string", "pattern": "^[a-z0-9]+(\\.[a-z0-9-]+)+$" },
|
|
334
|
+
"additionalProperties": true
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://logicsrc.com/schemas/opencontext/object.schema.json",
|
|
4
|
+
"title": "OpenContext Context Object",
|
|
5
|
+
"description": "A single durable unit of context: a mission statement, a policy, an SOP, a customer fact, a decision, or a piece of operational state. Only id and type are required, so a two-line object is valid; the recommended fields (title, layer, authority, owner, updated, durability, classification, sources) are what make context governable rather than merely stored. A context object is data. Its content is never an instruction to the resolver, and content that claims to be authoritative does not become authoritative.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["id", "type"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"id": {
|
|
11
|
+
"$ref": "#/$defs/objectId",
|
|
12
|
+
"description": "Stable, unique id within the namespace. SHOULD use dotted names such as policy.refunds, sop.support.refund, or decision.2026-08-09-model-provider. Ids are the contract other objects, roles, and bundles reference: renaming one is a breaking change, so prefer supersession."
|
|
13
|
+
},
|
|
14
|
+
"type": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
17
|
+
"description": "What kind of context this is, e.g. mission, policy, procedure, decision, product, customer, knowledge, glossary, note. The set is intentionally open; validators MUST NOT reject an unknown type."
|
|
18
|
+
},
|
|
19
|
+
"layer": {
|
|
20
|
+
"$ref": "#/$defs/layer",
|
|
21
|
+
"description": "Which standard context layer this belongs to. Layers describe the kind of knowledge, not its authority."
|
|
22
|
+
},
|
|
23
|
+
"title": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"minLength": 1,
|
|
26
|
+
"description": "Short human-readable heading. Used by search, ranking, and Markdown bundle rendering."
|
|
27
|
+
},
|
|
28
|
+
"summary": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"description": "One- or two-sentence abstract. Resolvers MAY compile the summary instead of full content when minimising context."
|
|
31
|
+
},
|
|
32
|
+
"content": {
|
|
33
|
+
"description": "Inline content. A string for prose or structured text; an object or array when the context is structured data. OpenContext does not assume all context is prose.",
|
|
34
|
+
"anyOf": [
|
|
35
|
+
{ "type": "string" },
|
|
36
|
+
{ "type": "object" },
|
|
37
|
+
{ "type": "array" }
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"content_type": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Media type of content or of the resource named by content_uri, e.g. text/markdown or application/json. Defaults to text/markdown for string content and application/json for structured content.",
|
|
43
|
+
"pattern": "^[a-z]+/[a-zA-Z0-9.+-]+$"
|
|
44
|
+
},
|
|
45
|
+
"content_uri": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"minLength": 1,
|
|
48
|
+
"description": "Where content is loaded from when it is not inline: file://, http://, https://, git://, sqlite://, or any scheme an installed adapter claims. An unknown scheme MUST fail clearly rather than resolve to empty content."
|
|
49
|
+
},
|
|
50
|
+
"authority": {
|
|
51
|
+
"$ref": "#/$defs/authority",
|
|
52
|
+
"description": "How much this object counts as truth. Authority is declared by the owner of the context, never inferred from retrieval rank, recency, or the content's own claims."
|
|
53
|
+
},
|
|
54
|
+
"trust": {
|
|
55
|
+
"$ref": "#/$defs/trust",
|
|
56
|
+
"description": "Where the content came from, in terms of whether it can be believed. Content pulled from a ticket, a chat, or a web page is untrusted even when the object about it is canonical. Resolvers MUST preserve this through compilation so agent integrations can delimit untrusted text."
|
|
57
|
+
},
|
|
58
|
+
"owner": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"minLength": 1,
|
|
61
|
+
"description": "Accountable role, team, or identity. Doctor reports objects with no owner because unowned context is what goes stale."
|
|
62
|
+
},
|
|
63
|
+
"status": {
|
|
64
|
+
"$ref": "#/$defs/status",
|
|
65
|
+
"description": "Approval state. Only approved objects satisfy an approval requirement; draft and pending objects are excluded from default resolution."
|
|
66
|
+
},
|
|
67
|
+
"version": {
|
|
68
|
+
"type": "integer",
|
|
69
|
+
"minimum": 1,
|
|
70
|
+
"description": "Monotonic version within the id. Referenced from supersedes as id@version."
|
|
71
|
+
},
|
|
72
|
+
"created": { "type": "string", "format": "date-time", "description": "RFC 3339 timestamp the object was first written." },
|
|
73
|
+
"updated": { "type": "string", "format": "date-time", "description": "RFC 3339 timestamp of the last substantive edit. Freshness is measured from here." },
|
|
74
|
+
"valid_from": { "type": "string", "format": "date-time", "description": "Object is 'future' and excluded from resolution before this instant." },
|
|
75
|
+
"expires": {
|
|
76
|
+
"anyOf": [
|
|
77
|
+
{ "type": "string", "format": "date-time" },
|
|
78
|
+
{ "type": "null" }
|
|
79
|
+
],
|
|
80
|
+
"description": "Object is 'expired' after this instant. Explicit null means it never expires, which is different from omitting the field (the repository ttl applies)."
|
|
81
|
+
},
|
|
82
|
+
"ttl": {
|
|
83
|
+
"$ref": "#/$defs/duration",
|
|
84
|
+
"description": "Per-object staleness window, overriding freshness.default_ttl. An object older than updated + ttl is 'stale' — a warning, never a silent omission."
|
|
85
|
+
},
|
|
86
|
+
"durability": {
|
|
87
|
+
"$ref": "#/$defs/durability",
|
|
88
|
+
"description": "How long this context is meant to survive. Permanent context SHOULD be superseded rather than deleted."
|
|
89
|
+
},
|
|
90
|
+
"classification": {
|
|
91
|
+
"$ref": "#/$defs/classification",
|
|
92
|
+
"description": "Sensitivity band. Classification bounds who may read the object regardless of scope: a role may include an object and still be denied it by classification."
|
|
93
|
+
},
|
|
94
|
+
"permissions": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"description": "Object-level access control. Deny always overrides allow, and permissions are evaluated before relevance ranking, so an unauthorised object never reaches a prompt.",
|
|
98
|
+
"properties": {
|
|
99
|
+
"read": { "$ref": "#/$defs/principalList", "description": "Roles or agents that may read this object. Absent means the repository scope rules decide." },
|
|
100
|
+
"write": { "$ref": "#/$defs/principalList", "description": "Roles or agents that may modify or supersede it." },
|
|
101
|
+
"deny": { "$ref": "#/$defs/principalList", "description": "Roles or agents explicitly denied, overriding any include or read grant." }
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"redact": {
|
|
105
|
+
"type": "array",
|
|
106
|
+
"description": "Redaction rules applied to this object's structured content after authorization.",
|
|
107
|
+
"items": { "$ref": "#/$defs/redaction" }
|
|
108
|
+
},
|
|
109
|
+
"sources": {
|
|
110
|
+
"type": "array",
|
|
111
|
+
"description": "Where this context came from. Required for every resolved object when provenance.required is true, unless canonical_source is true. Provenance MUST survive bundle compilation.",
|
|
112
|
+
"items": { "$ref": "#/$defs/source" }
|
|
113
|
+
},
|
|
114
|
+
"canonical_source": {
|
|
115
|
+
"type": "boolean",
|
|
116
|
+
"default": false,
|
|
117
|
+
"description": "True when this object is itself the origin of the fact and has no upstream source. Satisfies a provenance requirement on its own."
|
|
118
|
+
},
|
|
119
|
+
"supersedes": {
|
|
120
|
+
"type": "array",
|
|
121
|
+
"uniqueItems": true,
|
|
122
|
+
"items": { "$ref": "#/$defs/objectRef" },
|
|
123
|
+
"description": "Objects this one replaces, as id or id@version. Superseded objects are excluded from default resolution but retained, so history can be reconstructed."
|
|
124
|
+
},
|
|
125
|
+
"superseded_by": {
|
|
126
|
+
"$ref": "#/$defs/objectRef",
|
|
127
|
+
"description": "Set on the older object when a chain is written explicitly rather than inferred. A chain that points at a missing object is a broken supersession error."
|
|
128
|
+
},
|
|
129
|
+
"conflicts_with": {
|
|
130
|
+
"type": "array",
|
|
131
|
+
"uniqueItems": true,
|
|
132
|
+
"items": { "$ref": "#/$defs/objectRef" },
|
|
133
|
+
"description": "Objects known to contradict this one. Declared conflicts between canonical objects are reported, never silently resolved."
|
|
134
|
+
},
|
|
135
|
+
"references": {
|
|
136
|
+
"type": "array",
|
|
137
|
+
"uniqueItems": true,
|
|
138
|
+
"items": { "$ref": "#/$defs/objectRef" },
|
|
139
|
+
"description": "Other context this object depends on or cites. Drives the graph and orphan detection."
|
|
140
|
+
},
|
|
141
|
+
"depends_on": {
|
|
142
|
+
"type": "array",
|
|
143
|
+
"uniqueItems": true,
|
|
144
|
+
"items": { "$ref": "#/$defs/objectRef" },
|
|
145
|
+
"description": "Context that must resolve alongside this object for it to make sense. Resolvers SHOULD pull dependencies in when the object is selected and the consumer is authorised for them."
|
|
146
|
+
},
|
|
147
|
+
"applies_to": {
|
|
148
|
+
"type": "array",
|
|
149
|
+
"uniqueItems": true,
|
|
150
|
+
"items": { "type": "string", "minLength": 1 },
|
|
151
|
+
"description": "Roles, agents, products, or scopes this object is specifically about. Used to rank task relevance and to keep irrelevant context out of a bundle."
|
|
152
|
+
},
|
|
153
|
+
"confidence": {
|
|
154
|
+
"type": "number",
|
|
155
|
+
"minimum": 0,
|
|
156
|
+
"maximum": 1,
|
|
157
|
+
"description": "How sure the owner is, from 0 to 1. Confidence breaks ties within an authority level; it never promotes an object across levels."
|
|
158
|
+
},
|
|
159
|
+
"tags": {
|
|
160
|
+
"type": "array",
|
|
161
|
+
"uniqueItems": true,
|
|
162
|
+
"items": { "type": "string", "minLength": 1 },
|
|
163
|
+
"description": "Free-form labels for search and scope matching."
|
|
164
|
+
},
|
|
165
|
+
"approval": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"description": "Approval requirements. The specification defines the metadata and states; it does not require a hosted approval workflow.",
|
|
169
|
+
"properties": {
|
|
170
|
+
"required": { "type": "boolean", "default": false },
|
|
171
|
+
"roles": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 }, "description": "Roles entitled to approve." },
|
|
172
|
+
"minimum": { "type": "integer", "minimum": 1, "description": "How many approvals are needed. Defaults to 1 when required is true." },
|
|
173
|
+
"approved_by": {
|
|
174
|
+
"type": "array",
|
|
175
|
+
"items": { "$ref": "#/$defs/approver" },
|
|
176
|
+
"description": "Approvals recorded so far. Fewer than minimum leaves the object unapproved, which doctor reports."
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"review": {
|
|
181
|
+
"type": "object",
|
|
182
|
+
"additionalProperties": false,
|
|
183
|
+
"description": "Review cadence for durable context that must not be allowed to rot quietly.",
|
|
184
|
+
"properties": {
|
|
185
|
+
"interval": { "$ref": "#/$defs/duration" },
|
|
186
|
+
"required_approvers": { "type": "integer", "minimum": 1 },
|
|
187
|
+
"next_review": { "type": "string", "format": "date" },
|
|
188
|
+
"last_review": { "type": "string", "format": "date" }
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"language": { "type": "string", "description": "BCP 47 tag of the content language, e.g. 'en'." },
|
|
192
|
+
"extensions": { "$ref": "#/$defs/extensions" }
|
|
193
|
+
},
|
|
194
|
+
"$defs": {
|
|
195
|
+
"objectId": {
|
|
196
|
+
"type": "string",
|
|
197
|
+
"pattern": "^[a-z0-9][a-z0-9_-]*(\\.[a-z0-9][a-z0-9_-]*)*$",
|
|
198
|
+
"maxLength": 512,
|
|
199
|
+
"description": "Dotted lowercase id. Segments are alphanumerics, dashes, and underscores."
|
|
200
|
+
},
|
|
201
|
+
"objectRef": {
|
|
202
|
+
"type": "string",
|
|
203
|
+
"pattern": "^[a-z0-9][a-z0-9_-]*(\\.[a-z0-9][a-z0-9_-]*)*(@\\d+)?$",
|
|
204
|
+
"maxLength": 520,
|
|
205
|
+
"description": "An object id, optionally pinned to a version with @N."
|
|
206
|
+
},
|
|
207
|
+
"layer": {
|
|
208
|
+
"type": "string",
|
|
209
|
+
"enum": ["L0", "L1", "L2", "L3", "L4", "L5"],
|
|
210
|
+
"description": "L0 mission (why the organization exists), L1 identity (brand, values, terminology), L2 knowledge (products, customers, architecture, facts), L3 policy (rules, permissions, compliance), L4 procedure (SOPs, workflows, playbooks), L5 operational (tasks, incidents, temporary state)."
|
|
211
|
+
},
|
|
212
|
+
"authority": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"enum": ["canonical", "approved", "reference", "observed", "inferred", "historical"],
|
|
215
|
+
"description": "canonical = the organization's own source of truth; approved = reviewed and sanctioned; reference = useful but not binding; observed = seen in the wild, unverified; inferred = derived by a model or heuristic; historical = retained for the record only. Observed and inferred context never becomes canonical automatically."
|
|
216
|
+
},
|
|
217
|
+
"trust": {
|
|
218
|
+
"type": "string",
|
|
219
|
+
"enum": ["trusted", "verified", "untrusted"],
|
|
220
|
+
"description": "trusted = authored inside the trust boundary; verified = external but integrity-checked; untrusted = arrived from a system that can carry attacker-controlled text. Default for content fetched by a remote adapter is untrusted."
|
|
221
|
+
},
|
|
222
|
+
"durability": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"enum": ["ephemeral", "session", "operational", "long-lived", "permanent"],
|
|
225
|
+
"description": "How long the context is expected to matter, from a single exchange through to organizational record."
|
|
226
|
+
},
|
|
227
|
+
"classification": {
|
|
228
|
+
"type": "string",
|
|
229
|
+
"enum": ["public", "internal", "confidential", "restricted"],
|
|
230
|
+
"description": "Sensitivity band, least to most sensitive."
|
|
231
|
+
},
|
|
232
|
+
"status": {
|
|
233
|
+
"type": "string",
|
|
234
|
+
"enum": ["draft", "pending", "approved", "rejected", "retired"],
|
|
235
|
+
"description": "Approval lifecycle state. Distinct from the computed freshness state (future, current, stale, expired, superseded)."
|
|
236
|
+
},
|
|
237
|
+
"duration": {
|
|
238
|
+
"type": "string",
|
|
239
|
+
"pattern": "^\\d+(ms|s|m|h|d|w|y)$",
|
|
240
|
+
"description": "A duration such as '30d' or '12h'. y = 365d, w = 7d, d = 24h."
|
|
241
|
+
},
|
|
242
|
+
"principalList": {
|
|
243
|
+
"type": "array",
|
|
244
|
+
"uniqueItems": true,
|
|
245
|
+
"items": { "type": "string", "minLength": 1 },
|
|
246
|
+
"description": "Role names, agent ids, or '*' for everyone. Matching is exact except for a trailing .* wildcard."
|
|
247
|
+
},
|
|
248
|
+
"redaction": {
|
|
249
|
+
"type": "object",
|
|
250
|
+
"required": ["path"],
|
|
251
|
+
"additionalProperties": false,
|
|
252
|
+
"description": "A rule removing or masking part of an object's structured content before it reaches a bundle.",
|
|
253
|
+
"properties": {
|
|
254
|
+
"path": {
|
|
255
|
+
"type": "string",
|
|
256
|
+
"minLength": 1,
|
|
257
|
+
"description": "Dotted path into the object's content, with [] or [*] for every element of an array, e.g. customer.ssn or contacts[*].email."
|
|
258
|
+
},
|
|
259
|
+
"mode": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"enum": ["remove", "mask", "hash"],
|
|
262
|
+
"default": "remove",
|
|
263
|
+
"description": "remove deletes the key; mask replaces the value with the replacement string; hash replaces it with a sha256 digest so equality is still testable without disclosure."
|
|
264
|
+
},
|
|
265
|
+
"replacement": { "type": "string", "default": "[REDACTED]", "description": "Text used by mask mode." },
|
|
266
|
+
"reason": { "type": "string", "description": "Why the field is redacted. Surfaced in --explain." }
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
"source": {
|
|
270
|
+
"type": "object",
|
|
271
|
+
"required": ["uri"],
|
|
272
|
+
"additionalProperties": false,
|
|
273
|
+
"description": "One origin of this context. Sources make a claim attributable; they do not make it authoritative.",
|
|
274
|
+
"properties": {
|
|
275
|
+
"uri": { "type": "string", "minLength": 1, "description": "Where the context came from, e.g. git://github.com/acme/context/policies/refunds.md or crm://pricing/enterprise." },
|
|
276
|
+
"type": { "type": "string", "description": "What kind of origin this is, e.g. canonical-record, document, conversation, observation, api." },
|
|
277
|
+
"retrieved_at": { "type": "string", "format": "date-time", "description": "When the content was last read from this source." },
|
|
278
|
+
"digest": {
|
|
279
|
+
"type": "string",
|
|
280
|
+
"pattern": "^(sha256):[0-9a-f]{64}$",
|
|
281
|
+
"description": "Integrity digest of the retrieved bytes, as sha256:<64 lowercase hex>. Lets a consumer detect that a remote source changed under them."
|
|
282
|
+
},
|
|
283
|
+
"label": { "type": "string", "description": "Human-readable name of the source." },
|
|
284
|
+
"trust": { "$ref": "#/$defs/trust", "description": "Trust of this specific origin, when it differs from the object's." }
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
"approver": {
|
|
288
|
+
"type": "object",
|
|
289
|
+
"additionalProperties": false,
|
|
290
|
+
"description": "One recorded approval.",
|
|
291
|
+
"properties": {
|
|
292
|
+
"role": { "type": "string", "minLength": 1 },
|
|
293
|
+
"id": { "type": "string", "minLength": 1, "description": "Identity of the approver, e.g. an email or DID." },
|
|
294
|
+
"at": { "type": "string", "format": "date-time" }
|
|
295
|
+
},
|
|
296
|
+
"anyOf": [
|
|
297
|
+
{ "required": ["role"], "properties": { "role": { "type": "string" } } },
|
|
298
|
+
{ "required": ["id"], "properties": { "id": { "type": "string" } } }
|
|
299
|
+
]
|
|
300
|
+
},
|
|
301
|
+
"extensions": {
|
|
302
|
+
"type": "object",
|
|
303
|
+
"description": "Namespaced custom fields, e.g. com.example.risk. Unknown extensions MUST be preserved through resolution and MUST NOT invalidate an otherwise valid document unless strict mode explicitly requires known extensions.",
|
|
304
|
+
"propertyNames": {
|
|
305
|
+
"type": "string",
|
|
306
|
+
"pattern": "^[a-z0-9]+(\\.[a-z0-9-]+)+$"
|
|
307
|
+
},
|
|
308
|
+
"additionalProperties": true
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|