structured-context 0.9.2 → 0.10.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 +8 -4
- package/dist/api.d.ts +15 -0
- package/dist/api.js +9 -0
- package/dist/commands/dump.js +1 -1
- package/dist/commands/validate-file.d.ts +5 -24
- package/dist/commands/validate-file.js +10 -104
- package/dist/commands/validate.d.ts +1 -12
- package/dist/commands/validate.js +6 -157
- package/dist/config.js +1 -1
- package/dist/index.js +2 -2
- package/dist/plugins/markdown/index.d.ts +42 -32
- package/dist/plugins/markdown/index.js +9 -8
- package/dist/plugins/markdown/parse-embedded.d.ts +1 -1
- package/dist/plugins/markdown/read-space.js +3 -3
- package/dist/plugins/markdown/template-sync.d.ts +1 -1
- package/dist/plugins/markdown/template-sync.js +2 -2
- package/dist/schema/schema.js +45 -8
- package/dist/schemas/_knowledge_wiki.json +246 -0
- package/dist/schemas/_strategy_general.json +262 -0
- package/dist/schemas/knowledge_wiki.json +7 -237
- package/dist/schemas/strategy_general.json +12 -254
- package/dist/types.d.ts +20 -2
- package/dist/validate.d.ts +50 -0
- package/dist/validate.js +291 -0
- package/docs/schemas.md +6 -3
- package/package.json +11 -5
- package/schemas/_knowledge_wiki.json +246 -0
- package/schemas/_strategy_general.json +262 -0
- package/schemas/knowledge_wiki.json +7 -237
- package/schemas/strategy_general.json +12 -254
- package/dist/plugin-api.d.ts +0 -12
- package/dist/plugin-api.js +0 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { basename, join, resolve } from 'node:path';
|
|
3
|
-
import
|
|
3
|
+
import fg from 'fast-glob';
|
|
4
4
|
import matter from 'gray-matter';
|
|
5
5
|
import { extractSchemaTypeNames } from '../../schema/schema';
|
|
6
6
|
import { extractEmbeddedNodes, ON_A_PAGE_TYPES } from './parse-embedded';
|
|
@@ -42,7 +42,7 @@ export async function readSpaceDirectory(context, options) {
|
|
|
42
42
|
const absoluteTemplateDir = templateDir ? resolve(templateDir) : undefined;
|
|
43
43
|
const typeInferenceCfg = mdCfg.typeInference;
|
|
44
44
|
const knownTypes = typeInferenceCfg?.mode !== 'off' ? extractSchemaTypeNames(context.schema, context.schemaRefRegistry) : undefined;
|
|
45
|
-
const files = await
|
|
45
|
+
const files = await fg('**/*.md', { cwd: directory, followSymbolicLinks: true });
|
|
46
46
|
const nodes = [];
|
|
47
47
|
const parseIssues = [];
|
|
48
48
|
for (const file of files) {
|
|
@@ -70,7 +70,7 @@ export async function readSpaceDirectory(context, options) {
|
|
|
70
70
|
continue;
|
|
71
71
|
}
|
|
72
72
|
if (!parsed.data || Object.keys(parsed.data).length === 0) {
|
|
73
|
-
parseIssues.push({ file, severity: 'warning', type: '
|
|
73
|
+
parseIssues.push({ file, severity: 'warning', type: 'no-type', message: 'No front-matter or type specified' });
|
|
74
74
|
continue;
|
|
75
75
|
}
|
|
76
76
|
const data = coerceDates(applyFieldMap(parsed.data, fieldMap));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnySchemaObject } from 'ajv';
|
|
2
|
-
import type { HierarchyLevel, Relationship, SchemaWithMetadata } from '../../
|
|
2
|
+
import type { HierarchyLevel, Relationship, SchemaWithMetadata } from '../../api';
|
|
3
3
|
import type { PluginContext, TemplateSyncOptions } from '../util';
|
|
4
4
|
export interface TypeVariant {
|
|
5
5
|
required: string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import
|
|
3
|
+
import fg from 'fast-glob';
|
|
4
4
|
import matter from 'gray-matter';
|
|
5
5
|
import yaml from 'js-yaml';
|
|
6
6
|
import { mergeVariantProperties, resolveRef } from '../../schema/schema-refs';
|
|
@@ -190,7 +190,7 @@ export async function templateSync(context, options) {
|
|
|
190
190
|
const { schema, schemaRefRegistry } = context;
|
|
191
191
|
const typeVariants = getTypeVariants(schema, schemaRefRegistry);
|
|
192
192
|
const matchedTypes = new Set();
|
|
193
|
-
const files = await
|
|
193
|
+
const files = await fg('*.md', { cwd: templateDir, absolute: true });
|
|
194
194
|
const dryRun = options.dryRun ?? false;
|
|
195
195
|
let filesModified = 0;
|
|
196
196
|
let filesCreated = 0;
|
package/dist/schema/schema.js
CHANGED
|
@@ -3,7 +3,7 @@ import { basename, dirname, join, resolve } from 'node:path';
|
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { isDeepStrictEqual } from 'node:util';
|
|
5
5
|
import Ajv, {} from 'ajv';
|
|
6
|
-
import
|
|
6
|
+
import JSON5 from 'json5';
|
|
7
7
|
import { DIALECT_META_SCHEMA, METADATA_SCHEMA, SCHEMA_META_ID, } from './metadata-contract';
|
|
8
8
|
import { isObject, mergeVariantProperties, resolveJsonPointer } from './schema-refs';
|
|
9
9
|
const packageDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -255,17 +255,14 @@ function areRulesEquivalent(left, right) {
|
|
|
255
255
|
}
|
|
256
256
|
function extractMetadata(schema, schemaRefRegistry) {
|
|
257
257
|
const metadataProviders = collectMetadataProviders(schema, schemaRefRegistry);
|
|
258
|
-
let hierarchyProvider;
|
|
259
258
|
let mergedHierarchy;
|
|
260
259
|
const mergedAliases = {};
|
|
261
260
|
const mergedRules = new Map();
|
|
262
261
|
const mergedRelationships = [];
|
|
263
262
|
for (const provider of metadataProviders) {
|
|
264
263
|
if (provider.metadata.hierarchy) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
hierarchyProvider = provider.schemaId;
|
|
264
|
+
// Later providers (including root schema) override earlier ones (e.g. partials).
|
|
265
|
+
// This allows partials to define a default hierarchy that composing schemas can override.
|
|
269
266
|
mergedHierarchy = provider.metadata.hierarchy;
|
|
270
267
|
}
|
|
271
268
|
if (provider.metadata.aliases) {
|
|
@@ -294,6 +291,14 @@ function extractMetadata(schema, schemaRefRegistry) {
|
|
|
294
291
|
}
|
|
295
292
|
}
|
|
296
293
|
}
|
|
294
|
+
// Collect valid type names from the schema's oneOf list for validation
|
|
295
|
+
const validTypeNames = extractSchemaTypeNames(schema, schemaRefRegistry);
|
|
296
|
+
// Validate and filter metadata references against valid type names
|
|
297
|
+
validateMetadataReferences({ mergedHierarchy, mergedAliases, mergedRules, mergedRelationships }, validTypeNames);
|
|
298
|
+
// Filter relationships to only include those where both parent and child types are valid
|
|
299
|
+
const filteredRelationships = mergedRelationships.filter((rel) => {
|
|
300
|
+
return validTypeNames.has(rel.parent) && validTypeNames.has(rel.type);
|
|
301
|
+
});
|
|
297
302
|
const levels = mergedHierarchy?.levels.map((entry) => {
|
|
298
303
|
if (typeof entry === 'string') {
|
|
299
304
|
return { type: entry, field: 'parent', fieldOn: 'child', multiple: false, selfRef: false };
|
|
@@ -321,8 +326,8 @@ function extractMetadata(schema, schemaRefRegistry) {
|
|
|
321
326
|
: undefined,
|
|
322
327
|
typeAliases: Object.keys(mergedAliases).length > 0 ? mergedAliases : undefined,
|
|
323
328
|
rules: mergedRules.size > 0 ? [...mergedRules.values()].map(({ rule }) => normalizeRule(rule)) : undefined,
|
|
324
|
-
relationships:
|
|
325
|
-
?
|
|
329
|
+
relationships: filteredRelationships.length > 0
|
|
330
|
+
? filteredRelationships.map((rel) => ({
|
|
326
331
|
...rel,
|
|
327
332
|
field: rel.field ?? 'parent',
|
|
328
333
|
fieldOn: rel.fieldOn === 'parent' ? 'parent' : 'child',
|
|
@@ -331,6 +336,38 @@ function extractMetadata(schema, schemaRefRegistry) {
|
|
|
331
336
|
: undefined,
|
|
332
337
|
};
|
|
333
338
|
}
|
|
339
|
+
function validateMetadataReferences(metadata, validTypes) {
|
|
340
|
+
// Skip validation if no types are defined (e.g., schemas without oneOf or placeholder schemas)
|
|
341
|
+
if (validTypes.size === 0) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const errors = [];
|
|
345
|
+
// Validate hierarchy level types
|
|
346
|
+
if (metadata.mergedHierarchy?.levels) {
|
|
347
|
+
for (const level of metadata.mergedHierarchy.levels) {
|
|
348
|
+
const typeName = typeof level === 'string' ? level : level.type;
|
|
349
|
+
if (!validTypes.has(typeName)) {
|
|
350
|
+
errors.push(`Hierarchy level "${typeName}" is not a valid type in the schema's oneOf list`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Validate alias targets (the values)
|
|
355
|
+
for (const [alias, target] of Object.entries(metadata.mergedAliases)) {
|
|
356
|
+
if (!validTypes.has(target)) {
|
|
357
|
+
errors.push(`Alias "${alias}" → "${target}" references type "${target}" which is not in the schema's oneOf list`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Note: relationships are filtered (not validated) - see extractMetadata
|
|
361
|
+
// Validate rule types
|
|
362
|
+
for (const { rule } of metadata.mergedRules.values()) {
|
|
363
|
+
if (rule.type && !validTypes.has(rule.type)) {
|
|
364
|
+
errors.push(`Rule "${rule.id}" has type "${rule.type}" which is not in the schema's oneOf list`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (errors.length > 0) {
|
|
368
|
+
throw new Error(`Schema metadata validation failed:\n - ${errors.join('\n - ')}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
334
371
|
export function extractEntityInfo(schema, schemaRefRegistry) {
|
|
335
372
|
if (!Array.isArray(schema.oneOf))
|
|
336
373
|
return [];
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/mindsocket/structured-context/main/schemas/generated/_structured_context_schema_meta.json",
|
|
3
|
+
"$id": "sctx://_knowledge_wiki",
|
|
4
|
+
// Shared entity definitions for knowledge wiki schemas.
|
|
5
|
+
// Provides aliases, relationships, rules, and entity type $defs.
|
|
6
|
+
// This partial has no hierarchy — wiki entities are flat with no required parent links.
|
|
7
|
+
"$metadata": {
|
|
8
|
+
"aliases": {
|
|
9
|
+
"source_summary": "source",
|
|
10
|
+
"study": "source",
|
|
11
|
+
"article": "source",
|
|
12
|
+
"paper": "source",
|
|
13
|
+
"research": "source",
|
|
14
|
+
"comparison": "synthesis",
|
|
15
|
+
"query": "synthesis"
|
|
16
|
+
},
|
|
17
|
+
"relationships": [
|
|
18
|
+
{
|
|
19
|
+
"parent": "source",
|
|
20
|
+
"type": "source",
|
|
21
|
+
"field": "sources",
|
|
22
|
+
"fieldOn": "child",
|
|
23
|
+
"multiple": true
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"parent": "source",
|
|
27
|
+
"type": "synthesis",
|
|
28
|
+
"field": "sources",
|
|
29
|
+
"fieldOn": "child",
|
|
30
|
+
"multiple": true
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"parent": "source",
|
|
34
|
+
"type": "entity",
|
|
35
|
+
"field": "sources",
|
|
36
|
+
"fieldOn": "child",
|
|
37
|
+
"multiple": true
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"parent": "concept",
|
|
41
|
+
"type": "synthesis",
|
|
42
|
+
"field": "concepts",
|
|
43
|
+
"fieldOn": "child",
|
|
44
|
+
"multiple": true
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"rules": [
|
|
48
|
+
{
|
|
49
|
+
"id": "synthesis-references-sources",
|
|
50
|
+
"category": "coherence",
|
|
51
|
+
"description": "Syntheses should reference at least one contributing source in their sources array",
|
|
52
|
+
"type": "synthesis",
|
|
53
|
+
"check": "$exists(current.sources) and $count(current.sources) >= 1"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "concept-has-summary",
|
|
57
|
+
"category": "best-practice",
|
|
58
|
+
"description": "Concept pages should have a short summary for index discoverability",
|
|
59
|
+
"type": "concept",
|
|
60
|
+
"check": "$exists(current.summary) and $length(current.summary) > 0"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"$defs": {
|
|
65
|
+
"source": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"description": "A processed summary of a raw source (article, paper, book, video, thread, podcast, etc.). Captures key information from the source in structured form with provenance.",
|
|
68
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
69
|
+
"properties": {
|
|
70
|
+
"type": { "const": "source" },
|
|
71
|
+
"summary": {
|
|
72
|
+
"$ref": "sctx://_sctx_base#/$defs/summary"
|
|
73
|
+
},
|
|
74
|
+
"url": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"description": "URL of the original source"
|
|
77
|
+
},
|
|
78
|
+
"local_copy": {
|
|
79
|
+
"$ref": "sctx://_sctx_base#/$defs/wikilink",
|
|
80
|
+
"description": "Wikilink to a local copy of the source (e.g. a saved PDF or clipped note)"
|
|
81
|
+
},
|
|
82
|
+
"author": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"description": "Author or creator of the source"
|
|
85
|
+
},
|
|
86
|
+
"book": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"description": "Book title and author if the source is a book"
|
|
89
|
+
},
|
|
90
|
+
"published_date": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"format": "date",
|
|
93
|
+
"description": "Original publication date"
|
|
94
|
+
},
|
|
95
|
+
"source_type": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"description": "Kind of source material. Free-form — common values include article, paper, book, video, podcast, thread, substack, tweet, website. Not enum-constrained to allow evolving vocabulary."
|
|
98
|
+
},
|
|
99
|
+
"sources": {
|
|
100
|
+
"type": "array",
|
|
101
|
+
"items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
|
|
102
|
+
"description": "Wikilinks to other source pages that this one references or extends"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"required": ["type", "url"],
|
|
106
|
+
"additionalProperties": true,
|
|
107
|
+
"examples": [
|
|
108
|
+
{
|
|
109
|
+
"type": "source",
|
|
110
|
+
"author": "Joe Bloggs",
|
|
111
|
+
"url": "https://example.com/design-of-yesterday-things",
|
|
112
|
+
"source_type": "book",
|
|
113
|
+
"tags": ["design", "ux", "psychology"]
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
"concept": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"description": "A concept page — defines and frames a specific idea, mechanism, or domain term. May draw from multiple sources. The building blocks of the wiki's knowledge graph.",
|
|
120
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
121
|
+
"properties": {
|
|
122
|
+
"type": { "const": "concept" },
|
|
123
|
+
"summary": {
|
|
124
|
+
"$ref": "sctx://_sctx_base#/$defs/summary"
|
|
125
|
+
},
|
|
126
|
+
"sources": {
|
|
127
|
+
"type": "array",
|
|
128
|
+
"items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
|
|
129
|
+
"description": "Wikilinks to source pages that contributed to this concept"
|
|
130
|
+
},
|
|
131
|
+
"related": {
|
|
132
|
+
"type": "array",
|
|
133
|
+
"items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
|
|
134
|
+
"description": "Wikilinks to related concept or synthesis pages"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"required": ["type"],
|
|
138
|
+
"additionalProperties": true,
|
|
139
|
+
"examples": [
|
|
140
|
+
{
|
|
141
|
+
"type": "concept",
|
|
142
|
+
"summary": "A property of an object that signals how it can be used, first described by Gibson and popularised in design by Norman",
|
|
143
|
+
"tags": ["design", "ux"]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
"entity": {
|
|
148
|
+
"type": "object",
|
|
149
|
+
"description": "A concrete entity — a person, organisation, product, model, or other named thing. The building blocks of the wiki's knowledge graph alongside concepts. Entities are distinct from concepts: a concept frames an idea or mechanism; an entity is a specific, identifiable thing in the world.",
|
|
150
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
151
|
+
"properties": {
|
|
152
|
+
"type": { "const": "entity" },
|
|
153
|
+
"summary": {
|
|
154
|
+
"$ref": "sctx://_sctx_base#/$defs/summary"
|
|
155
|
+
},
|
|
156
|
+
"sources": {
|
|
157
|
+
"type": "array",
|
|
158
|
+
"items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
|
|
159
|
+
"description": "Wikilinks to source pages that contributed to this entity page"
|
|
160
|
+
},
|
|
161
|
+
"related": {
|
|
162
|
+
"type": "array",
|
|
163
|
+
"items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
|
|
164
|
+
"description": "Wikilinks to related entity, concept, or synthesis pages"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"required": ["type"],
|
|
168
|
+
"additionalProperties": true,
|
|
169
|
+
"examples": [
|
|
170
|
+
{
|
|
171
|
+
"type": "entity",
|
|
172
|
+
"summary": "AI safety research lab founded by Dario Amodei and Daniela Amodei",
|
|
173
|
+
"tags": ["company", "ai", "safety"]
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
"synthesis": {
|
|
178
|
+
"type": "object",
|
|
179
|
+
"description": "A synthesis page — connects multiple concepts and sources into a coherent model, framework, or thesis. The highest-value pages in a knowledge wiki. Must reference contributing sources.",
|
|
180
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
181
|
+
"properties": {
|
|
182
|
+
"type": { "const": "synthesis" },
|
|
183
|
+
"summary": {
|
|
184
|
+
"$ref": "sctx://_sctx_base#/$defs/summary"
|
|
185
|
+
},
|
|
186
|
+
"sources": {
|
|
187
|
+
"type": "array",
|
|
188
|
+
"items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
|
|
189
|
+
"description": "Wikilinks to source pages this synthesis draws from"
|
|
190
|
+
},
|
|
191
|
+
"concepts": {
|
|
192
|
+
"type": "array",
|
|
193
|
+
"items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
|
|
194
|
+
"description": "Wikilinks to concept pages this synthesis connects"
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
"required": ["type"],
|
|
198
|
+
"additionalProperties": true,
|
|
199
|
+
"examples": [
|
|
200
|
+
{
|
|
201
|
+
"type": "synthesis",
|
|
202
|
+
"summary": "How Norman's affordance model and feedback principles combine to explain intuitive vs confusing interfaces",
|
|
203
|
+
"sources": ["[[The Design of Everyday Things - Don Norman]]"],
|
|
204
|
+
"concepts": ["[[Affordance]]", "[[Feedback loop]]"]
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
"note": {
|
|
209
|
+
"type": "object",
|
|
210
|
+
"description": "Personal notes, journal entries, appointments, experiential records. Your own data about your journey — not sourced from external material.",
|
|
211
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
212
|
+
"properties": {
|
|
213
|
+
"type": { "const": "note" },
|
|
214
|
+
"date": {
|
|
215
|
+
"type": "string",
|
|
216
|
+
"format": "date",
|
|
217
|
+
"description": "Date this entry was created or relates to"
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"required": ["type"],
|
|
221
|
+
"additionalProperties": true,
|
|
222
|
+
"examples": [
|
|
223
|
+
{
|
|
224
|
+
"type": "note",
|
|
225
|
+
"date": "2024-03-15",
|
|
226
|
+
"tags": ["reading-log"]
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
},
|
|
230
|
+
"index": {
|
|
231
|
+
"type": "object",
|
|
232
|
+
"description": "The wiki index — a catalog of all pages with links, summaries, and metadata. Updated by the agent on ingest. Used as the primary navigation entry point.",
|
|
233
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
234
|
+
"properties": {
|
|
235
|
+
"type": { "const": "index" }
|
|
236
|
+
},
|
|
237
|
+
"required": ["type"],
|
|
238
|
+
"additionalProperties": true,
|
|
239
|
+
"examples": [
|
|
240
|
+
{
|
|
241
|
+
"type": "index"
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/mindsocket/structured-context/main/schemas/generated/_structured_context_schema_meta.json",
|
|
3
|
+
"$id": "sctx://_strategy_general",
|
|
4
|
+
// Shared entity definitions for strategy-general schemas.
|
|
5
|
+
// Provides a default hierarchy, aliases, relationships, and entity type $defs.
|
|
6
|
+
// Composing schemas can override the hierarchy by defining their own.
|
|
7
|
+
"$metadata": {
|
|
8
|
+
"hierarchy": {
|
|
9
|
+
"levels": [
|
|
10
|
+
"vision",
|
|
11
|
+
"mission",
|
|
12
|
+
{ "type": "goal", "selfRef": true, "matchers": ["Goals"] },
|
|
13
|
+
{ "type": "opportunity", "selfRef": true, "matchers": ["Opportunities"] },
|
|
14
|
+
{
|
|
15
|
+
"type": "solution",
|
|
16
|
+
"selfRef": true,
|
|
17
|
+
"matchers": ["Solutions", "Potential solutions", "Solutions considered", "Possible solutions"]
|
|
18
|
+
},
|
|
19
|
+
"experiment"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"aliases": {
|
|
23
|
+
"outcome": "goal",
|
|
24
|
+
"assumption_test": "experiment",
|
|
25
|
+
"test": "experiment"
|
|
26
|
+
},
|
|
27
|
+
"relationships": [
|
|
28
|
+
{
|
|
29
|
+
"parent": "opportunity",
|
|
30
|
+
"type": "problem_statement",
|
|
31
|
+
"templateFormat": "heading",
|
|
32
|
+
"matchers": ["Problem statement", "What problem are we solving?"],
|
|
33
|
+
"multiple": false
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"parent": "opportunity",
|
|
37
|
+
"type": "assumption",
|
|
38
|
+
"templateFormat": "table",
|
|
39
|
+
"matchers": ["Assumptions", "^Assumptions?$"],
|
|
40
|
+
"embeddedTemplateFields": ["assumption", "status", "confidence"],
|
|
41
|
+
"multiple": true
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"$defs": {
|
|
46
|
+
"dashboard": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
49
|
+
"properties": {
|
|
50
|
+
"type": { "const": "dashboard" }
|
|
51
|
+
},
|
|
52
|
+
"required": ["type"],
|
|
53
|
+
"additionalProperties": true
|
|
54
|
+
},
|
|
55
|
+
"ost_on_a_page": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
|
|
58
|
+
"properties": {
|
|
59
|
+
"type": { "enum": ["ost_on_a_page", "space_on_a_page"] }
|
|
60
|
+
},
|
|
61
|
+
"required": ["type"],
|
|
62
|
+
"additionalProperties": true
|
|
63
|
+
},
|
|
64
|
+
"vision": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"allOf": [
|
|
67
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
68
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
69
|
+
],
|
|
70
|
+
"properties": {
|
|
71
|
+
"type": { "const": "vision" }
|
|
72
|
+
},
|
|
73
|
+
"required": ["type"],
|
|
74
|
+
"not": { "required": ["parent"] },
|
|
75
|
+
"additionalProperties": true,
|
|
76
|
+
"examples": [
|
|
77
|
+
{
|
|
78
|
+
"type": "vision",
|
|
79
|
+
"status": "active"
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
"mission": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"allOf": [
|
|
86
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
87
|
+
{ "$ref": "sctx://_sctx_base#/$defs/parentNodeProps" },
|
|
88
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
89
|
+
],
|
|
90
|
+
"properties": {
|
|
91
|
+
"type": { "const": "mission" }
|
|
92
|
+
},
|
|
93
|
+
"required": ["type"],
|
|
94
|
+
"additionalProperties": true,
|
|
95
|
+
"examples": [
|
|
96
|
+
{
|
|
97
|
+
"type": "mission",
|
|
98
|
+
"status": "active",
|
|
99
|
+
"parent": "[[Personal Vision]]"
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"goal": {
|
|
104
|
+
"type": "object",
|
|
105
|
+
"allOf": [
|
|
106
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
107
|
+
{ "$ref": "sctx://_sctx_base#/$defs/parentNodeProps" },
|
|
108
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
109
|
+
],
|
|
110
|
+
"properties": {
|
|
111
|
+
"type": { "enum": ["goal", "outcome"] },
|
|
112
|
+
"priority": { "$ref": "sctx://_sctx_base#/$defs/priority" }
|
|
113
|
+
},
|
|
114
|
+
"required": ["type"],
|
|
115
|
+
"additionalProperties": true,
|
|
116
|
+
"examples": [
|
|
117
|
+
{
|
|
118
|
+
"type": "goal",
|
|
119
|
+
"status": "active",
|
|
120
|
+
"parent": "[[My Mission (2026)]]",
|
|
121
|
+
"priority": "p2"
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"opportunity": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"allOf": [
|
|
128
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
129
|
+
{ "$ref": "sctx://_sctx_base#/$defs/parentNodeProps" },
|
|
130
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
131
|
+
],
|
|
132
|
+
"properties": {
|
|
133
|
+
"type": { "const": "opportunity" },
|
|
134
|
+
"priority": { "$ref": "sctx://_sctx_base#/$defs/priority" },
|
|
135
|
+
"impact": { "$ref": "sctx://_sctx_base#/$defs/assessment" },
|
|
136
|
+
"feasibility": { "$ref": "sctx://_sctx_base#/$defs/assessment" },
|
|
137
|
+
"resources": { "$ref": "sctx://_sctx_base#/$defs/assessment" },
|
|
138
|
+
"timeline": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"description": "Timeline estimate (e.g., S-M, M-L)"
|
|
141
|
+
},
|
|
142
|
+
"next_steps": {
|
|
143
|
+
"type": "string",
|
|
144
|
+
"description": "Next steps for this opportunity"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"required": ["type"],
|
|
148
|
+
"additionalProperties": true,
|
|
149
|
+
"examples": [
|
|
150
|
+
{
|
|
151
|
+
"type": "opportunity",
|
|
152
|
+
"status": "identified",
|
|
153
|
+
"parent": "[[Career Growth]]",
|
|
154
|
+
"priority": "p2"
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
},
|
|
158
|
+
"solution": {
|
|
159
|
+
"type": "object",
|
|
160
|
+
"allOf": [
|
|
161
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
162
|
+
{ "$ref": "sctx://_sctx_base#/$defs/parentNodeProps" },
|
|
163
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
164
|
+
],
|
|
165
|
+
"properties": {
|
|
166
|
+
"type": { "const": "solution" },
|
|
167
|
+
"priority": { "$ref": "sctx://_sctx_base#/$defs/priority" },
|
|
168
|
+
"impact": { "$ref": "sctx://_sctx_base#/$defs/assessment" },
|
|
169
|
+
"feasibility": { "$ref": "sctx://_sctx_base#/$defs/assessment" },
|
|
170
|
+
"resources": { "$ref": "sctx://_sctx_base#/$defs/assessment" },
|
|
171
|
+
"timeline": {
|
|
172
|
+
"type": "string",
|
|
173
|
+
"description": "Timeline estimate (e.g., S-M, M-L)"
|
|
174
|
+
},
|
|
175
|
+
"next_steps": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"description": "Next steps for this solution"
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"required": ["type"],
|
|
181
|
+
"additionalProperties": true,
|
|
182
|
+
"examples": [
|
|
183
|
+
{
|
|
184
|
+
"type": "solution",
|
|
185
|
+
"status": "identified",
|
|
186
|
+
"parent": "[[Some Opportunity]]",
|
|
187
|
+
"priority": "p3"
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"experiment": {
|
|
192
|
+
"type": "object",
|
|
193
|
+
"allOf": [
|
|
194
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
195
|
+
{ "$ref": "sctx://_sctx_base#/$defs/parentNodeProps" },
|
|
196
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
197
|
+
],
|
|
198
|
+
"properties": {
|
|
199
|
+
"type": { "enum": ["experiment", "assumption_test", "test"] }
|
|
200
|
+
},
|
|
201
|
+
"required": ["type"],
|
|
202
|
+
"additionalProperties": true,
|
|
203
|
+
"examples": [
|
|
204
|
+
{
|
|
205
|
+
"type": "experiment",
|
|
206
|
+
"status": "exploring",
|
|
207
|
+
"parent": "[[Build a Side Project]]"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"type": "test",
|
|
211
|
+
"status": "active",
|
|
212
|
+
"parent": "[[Mobile App Solution]]"
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
"assumption": {
|
|
217
|
+
"type": "object",
|
|
218
|
+
"allOf": [
|
|
219
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
220
|
+
{ "$ref": "sctx://_sctx_base#/$defs/parentNodeProps" },
|
|
221
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
222
|
+
],
|
|
223
|
+
"properties": {
|
|
224
|
+
"type": { "const": "assumption" },
|
|
225
|
+
"confidence": {
|
|
226
|
+
"type": "string",
|
|
227
|
+
"enum": ["low", "medium", "high"],
|
|
228
|
+
"description": "Confidence level in this assumption"
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"required": ["type"],
|
|
232
|
+
"additionalProperties": true,
|
|
233
|
+
"examples": [
|
|
234
|
+
{
|
|
235
|
+
"type": "assumption",
|
|
236
|
+
"status": "identified",
|
|
237
|
+
"parent": "[[Some Opportunity]]",
|
|
238
|
+
"confidence": "medium"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
"problem_statement": {
|
|
243
|
+
"type": "object",
|
|
244
|
+
"allOf": [
|
|
245
|
+
{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" },
|
|
246
|
+
{ "$ref": "sctx://_sctx_base#/$defs/parentNodeProps" },
|
|
247
|
+
{ "$ref": "sctx://_sctx_base#/$defs/ostEntityProps" }
|
|
248
|
+
],
|
|
249
|
+
"properties": {
|
|
250
|
+
"type": { "const": "problem_statement" }
|
|
251
|
+
},
|
|
252
|
+
"required": ["type"],
|
|
253
|
+
"additionalProperties": true,
|
|
254
|
+
"examples": [
|
|
255
|
+
{
|
|
256
|
+
"type": "problem_statement",
|
|
257
|
+
"status": "identified"
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|