@sprig-and-prose/sprig-universe 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/PHILOSOPHY.md +201 -0
- package/README.md +168 -0
- package/REFERENCE.md +355 -0
- package/biome.json +24 -0
- package/package.json +30 -0
- package/repositories/sprig-repository-github/index.js +29 -0
- package/src/ast.js +257 -0
- package/src/cli.js +1510 -0
- package/src/graph.js +950 -0
- package/src/index.js +46 -0
- package/src/ir.js +121 -0
- package/src/parser.js +1656 -0
- package/src/scanner.js +255 -0
- package/src/scene-manifest.js +856 -0
- package/src/util/span.js +46 -0
- package/src/util/text.js +126 -0
- package/src/validator.js +862 -0
- package/src/validators/mysql/connection.js +154 -0
- package/src/validators/mysql/schema.js +209 -0
- package/src/validators/mysql/type-compat.js +219 -0
- package/src/validators/mysql/validator.js +332 -0
- package/test/fixtures/amaranthine-mini.prose +53 -0
- package/test/fixtures/conflicting-universes-a.prose +8 -0
- package/test/fixtures/conflicting-universes-b.prose +8 -0
- package/test/fixtures/duplicate-names.prose +20 -0
- package/test/fixtures/first-line-aware.prose +32 -0
- package/test/fixtures/indented-describe.prose +18 -0
- package/test/fixtures/multi-file-universe-a.prose +15 -0
- package/test/fixtures/multi-file-universe-b.prose +15 -0
- package/test/fixtures/multi-file-universe-conflict-desc.prose +12 -0
- package/test/fixtures/multi-file-universe-conflict-title.prose +4 -0
- package/test/fixtures/multi-file-universe-with-title.prose +10 -0
- package/test/fixtures/named-document.prose +17 -0
- package/test/fixtures/named-duplicate.prose +22 -0
- package/test/fixtures/named-reference.prose +17 -0
- package/test/fixtures/relates-errors.prose +38 -0
- package/test/fixtures/relates-tier1.prose +14 -0
- package/test/fixtures/relates-tier2.prose +16 -0
- package/test/fixtures/relates-tier3.prose +21 -0
- package/test/fixtures/sprig-meta-mini.prose +62 -0
- package/test/fixtures/unresolved-relates.prose +15 -0
- package/test/fixtures/using-in-references.prose +35 -0
- package/test/fixtures/using-unknown.prose +8 -0
- package/test/universe-basic.test.js +804 -0
- package/tsconfig.json +15 -0
package/PHILOSOPHY.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# 🌱 Why sprig exists
|
|
2
|
+
|
|
3
|
+
Modern systems are hard to understand — not because they’re poorly built, but because they’re *alive*.
|
|
4
|
+
|
|
5
|
+
They grow over time.
|
|
6
|
+
They accumulate history.
|
|
7
|
+
They reflect decisions made by different people, under different constraints, at different moments.
|
|
8
|
+
|
|
9
|
+
Most tooling assumes the opposite.
|
|
10
|
+
|
|
11
|
+
Most tooling assumes:
|
|
12
|
+
|
|
13
|
+
* there is a single source of truth
|
|
14
|
+
* that truth is owned
|
|
15
|
+
* and the primary goal is to *enforce* it
|
|
16
|
+
|
|
17
|
+
sprig starts from a different premise.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## sprig exists to help people **understand systems as they are**
|
|
22
|
+
|
|
23
|
+
sprig is not an ORM.
|
|
24
|
+
It is not a schema language.
|
|
25
|
+
It is not a framework that asks to be “in charge.”
|
|
26
|
+
|
|
27
|
+
Instead, sprig is an ecosystem for **describing**, **grounding**, and **gently interacting with** real systems over time.
|
|
28
|
+
|
|
29
|
+
It is designed to be useful:
|
|
30
|
+
|
|
31
|
+
* before execution
|
|
32
|
+
* before adoption is complete
|
|
33
|
+
* before certainty exists
|
|
34
|
+
|
|
35
|
+
Sometimes even *before intent exists*.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Nouns before verbs
|
|
40
|
+
|
|
41
|
+
sprig favors **nouns over verbs**.
|
|
42
|
+
|
|
43
|
+
You describe:
|
|
44
|
+
|
|
45
|
+
* what exists
|
|
46
|
+
* how things relate
|
|
47
|
+
* what shape reality seems to have
|
|
48
|
+
* what identifiers appear to matter
|
|
49
|
+
|
|
50
|
+
You do not start by declaring:
|
|
51
|
+
|
|
52
|
+
* how things must change
|
|
53
|
+
* who owns enforcement
|
|
54
|
+
* or what actions are allowed
|
|
55
|
+
|
|
56
|
+
Verbs — migrations, transformations, ownership — are optional, explicit, and unlockable later.
|
|
57
|
+
|
|
58
|
+
This keeps sprig readable, calm, and safe to approach.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Fuzzy first, precise later
|
|
63
|
+
|
|
64
|
+
Real systems are rarely known all at once.
|
|
65
|
+
|
|
66
|
+
sprig is designed for:
|
|
67
|
+
|
|
68
|
+
* partial knowledge
|
|
69
|
+
* evolving understanding
|
|
70
|
+
* incremental refinement
|
|
71
|
+
|
|
72
|
+
You can begin with:
|
|
73
|
+
|
|
74
|
+
* rough shapes
|
|
75
|
+
* optional fields
|
|
76
|
+
* multiple perspectives
|
|
77
|
+
* incomplete grounding
|
|
78
|
+
|
|
79
|
+
And move toward:
|
|
80
|
+
|
|
81
|
+
* tighter validation
|
|
82
|
+
* clearer identities
|
|
83
|
+
* stronger guarantees
|
|
84
|
+
|
|
85
|
+
Without losing information along the way.
|
|
86
|
+
|
|
87
|
+
sprig is **lossless by design**.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Description is valuable on its own
|
|
92
|
+
|
|
93
|
+
A core belief of sprig is that **description has intrinsic value**.
|
|
94
|
+
|
|
95
|
+
Even without validation.
|
|
96
|
+
Even without execution.
|
|
97
|
+
Even without enforcement.
|
|
98
|
+
|
|
99
|
+
The Universe layer exists to support this:
|
|
100
|
+
|
|
101
|
+
* human-first modeling
|
|
102
|
+
* narrative structure
|
|
103
|
+
* exploration and orientation
|
|
104
|
+
* shared language across experience levels
|
|
105
|
+
|
|
106
|
+
New engineers learn faster.
|
|
107
|
+
Experienced engineers continue learning safely.
|
|
108
|
+
|
|
109
|
+
sprig helps systems be *read*.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Grounding, not control
|
|
114
|
+
|
|
115
|
+
When sprig touches reality, it does so gently.
|
|
116
|
+
|
|
117
|
+
Scenes describe how abstract concepts appear in the real world:
|
|
118
|
+
|
|
119
|
+
* files
|
|
120
|
+
* databases
|
|
121
|
+
* tables
|
|
122
|
+
* shapes
|
|
123
|
+
* identifiers
|
|
124
|
+
|
|
125
|
+
Validation observes reality and reports back — calmly.
|
|
126
|
+
|
|
127
|
+
It does not punish.
|
|
128
|
+
It does not assume ownership.
|
|
129
|
+
It does not demand compliance.
|
|
130
|
+
|
|
131
|
+
Errors are grouped, contextualized, and human.
|
|
132
|
+
|
|
133
|
+
sprig doesn’t say *“this is wrong.”*
|
|
134
|
+
It says *“this is what I see.”*
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Sensing before changing
|
|
139
|
+
|
|
140
|
+
sprig’s natural evolution is:
|
|
141
|
+
|
|
142
|
+
**description → grounding → sensing → care**
|
|
143
|
+
|
|
144
|
+
Before systems change, they should be *felt*:
|
|
145
|
+
|
|
146
|
+
* row counts
|
|
147
|
+
* file counts
|
|
148
|
+
* freshness
|
|
149
|
+
* drift
|
|
150
|
+
* validation status
|
|
151
|
+
|
|
152
|
+
Observability is not a bolt-on feature — it is a continuation of grounding.
|
|
153
|
+
|
|
154
|
+
Only after sensing does it make sense to talk about:
|
|
155
|
+
|
|
156
|
+
* evolution helpers
|
|
157
|
+
* migrations
|
|
158
|
+
* safety analysis
|
|
159
|
+
* slowly unlocked verbs
|
|
160
|
+
|
|
161
|
+
Even then, everything remains optional.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## sprig is local-first and non-invasive
|
|
166
|
+
|
|
167
|
+
sprig runs where your systems live.
|
|
168
|
+
|
|
169
|
+
It reads files.
|
|
170
|
+
It connects locally.
|
|
171
|
+
It links to repositories without owning them.
|
|
172
|
+
|
|
173
|
+
You can adopt sprig:
|
|
174
|
+
|
|
175
|
+
* per directory
|
|
176
|
+
* per entity
|
|
177
|
+
* per scene
|
|
178
|
+
* per moment in time
|
|
179
|
+
|
|
180
|
+
There is no cliff.
|
|
181
|
+
There is no rewrite.
|
|
182
|
+
There is no lock-in.
|
|
183
|
+
|
|
184
|
+
sprig should *touch* systems — not dominate them.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## The goal
|
|
189
|
+
|
|
190
|
+
sprig exists to make systems:
|
|
191
|
+
|
|
192
|
+
* more legible
|
|
193
|
+
* more humane
|
|
194
|
+
* easier to learn
|
|
195
|
+
* safer to evolve
|
|
196
|
+
|
|
197
|
+
It is a companion, not a commander.
|
|
198
|
+
|
|
199
|
+
A field guide, not a rulebook.
|
|
200
|
+
|
|
201
|
+
🌱
|
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# sprig-universe
|
|
2
|
+
|
|
3
|
+
A minimal parser for the universe layer of Sprig, a declarative language for describing systems.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
`sprig-universe` parses Sprig `.prose` files and extracts the universe structure, producing a JSON representation (`UniverseGraph`) that includes:
|
|
8
|
+
|
|
9
|
+
**v0 Simplification:**
|
|
10
|
+
- Automatic discovery: finds `universe.prose` marker and loads all prose files
|
|
11
|
+
- Dead simple defaults: no configuration required
|
|
12
|
+
- Single universe rule: exactly one universe declaration required across all files
|
|
13
|
+
|
|
14
|
+
- **Nodes**: Universe, series, book, and chapter declarations with their relationships
|
|
15
|
+
- **Edges**: `relates` declarations connecting concepts
|
|
16
|
+
- **Describe blocks**: Freeform text preserved exactly as authored
|
|
17
|
+
- **Unknown blocks**: Blocks like `references` and `documentation` are preserved with their raw content
|
|
18
|
+
- **Source spans**: File, line, column, and offset information for all nodes and blocks
|
|
19
|
+
- **Diagnostics**: Warnings for duplicate names and unresolved references
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### CLI
|
|
30
|
+
|
|
31
|
+
#### Compile (v0 - Recommended)
|
|
32
|
+
|
|
33
|
+
The `compile` command uses automatic discovery to find and compile all prose files:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
sprig-universe compile
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Discovery behavior:**
|
|
40
|
+
- Walks upward from the current directory to find `universe.prose` marker file
|
|
41
|
+
- Loads all `**/*.prose` files under the discovered root
|
|
42
|
+
- Automatically excludes: `.sprig/**`, `dist/**`, `node_modules/**`, `.git/**`
|
|
43
|
+
- Requires exactly one `universe` declaration across all files
|
|
44
|
+
|
|
45
|
+
**Options:**
|
|
46
|
+
- `--root <path>` - Override discovery start path (default: current directory)
|
|
47
|
+
- `--quiet` - Suppress observable header output
|
|
48
|
+
- `--config <path>` - Path to `sprig.config.json` (optional, uses defaults if not found)
|
|
49
|
+
|
|
50
|
+
**Observable header** (shown unless `--quiet`):
|
|
51
|
+
```
|
|
52
|
+
Universe: <Name> (root: /path/to/root)
|
|
53
|
+
Loaded: <N> prose files
|
|
54
|
+
Ignored: .sprig/**, dist/**, node_modules/**, .git/**
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Other commands:**
|
|
58
|
+
- `sprig-universe watch` - Watch files and recompile on change
|
|
59
|
+
- `sprig-universe check:references` - Validate repository references
|
|
60
|
+
- `sprig-universe validate` - Validate scene sources
|
|
61
|
+
|
|
62
|
+
#### Parse (Legacy)
|
|
63
|
+
|
|
64
|
+
Parse a single file:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
sprig-universe parse path/to/file.prose
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Parse a directory (recursively finds all `*.prose` files):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
sprig-universe parse path/to/directory
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Output to a file:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
sprig-universe parse path/to/file.prose --out output.json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The CLI exits with a non-zero code if there are any error-level diagnostics.
|
|
83
|
+
|
|
84
|
+
### Programmatic API
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
import { parseFiles, parseText } from './src/index.js';
|
|
88
|
+
|
|
89
|
+
// Parse a single text string
|
|
90
|
+
const ast = parseText(sourceText, 'filename.prose');
|
|
91
|
+
|
|
92
|
+
// Parse multiple files into a single graph
|
|
93
|
+
const graph = parseFiles([
|
|
94
|
+
{ file: 'file1.prose', text: sourceText1 },
|
|
95
|
+
{ file: 'file2.prose', text: sourceText2 },
|
|
96
|
+
]);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Supported Syntax
|
|
100
|
+
|
|
101
|
+
The parser supports the universe layer of Sprig:
|
|
102
|
+
|
|
103
|
+
- `universe <Name> { ... }` - Top-level universe declaration
|
|
104
|
+
- `series <Name> { ... }` - Series within a universe
|
|
105
|
+
- `book <Name> in <ParentName> { ... }` - Book within a series or book
|
|
106
|
+
- `chapter <Name> in <ParentName> { ... }` - Chapter within a book
|
|
107
|
+
- `relates <A> and <B> { ... }` - Relationship between concepts
|
|
108
|
+
- `describe { ... }` - Freeform text block (preserves raw content including braces)
|
|
109
|
+
- Unknown blocks (e.g., `references { ... }`, `documentation { ... }`) - Preserved as-is
|
|
110
|
+
|
|
111
|
+
Comments start with `--` and continue to the end of the line.
|
|
112
|
+
|
|
113
|
+
## Output Format
|
|
114
|
+
|
|
115
|
+
The parser produces a `UniverseGraph` JSON structure:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"version": 1,
|
|
120
|
+
"universes": {
|
|
121
|
+
"UniverseName": {
|
|
122
|
+
"name": "UniverseName",
|
|
123
|
+
"root": "UniverseName:universe:UniverseName"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"nodes": {
|
|
127
|
+
"UniverseName:series:SeriesName": {
|
|
128
|
+
"id": "UniverseName:series:SeriesName",
|
|
129
|
+
"kind": "series",
|
|
130
|
+
"name": "SeriesName",
|
|
131
|
+
"parent": "UniverseName:universe:UniverseName",
|
|
132
|
+
"children": [],
|
|
133
|
+
"describe": { "raw": "...", "source": {...} },
|
|
134
|
+
"source": {...}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"edges": {
|
|
138
|
+
"UniverseName:relates:A--B:0": {
|
|
139
|
+
"id": "UniverseName:relates:A--B:0",
|
|
140
|
+
"kind": "relates",
|
|
141
|
+
"a": { "text": "A", "target": "..." },
|
|
142
|
+
"b": { "text": "B", "target": "..." },
|
|
143
|
+
"source": {...}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"diagnostics": []
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Development
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Format code
|
|
154
|
+
npm run format
|
|
155
|
+
|
|
156
|
+
# Lint code
|
|
157
|
+
npm run lint
|
|
158
|
+
|
|
159
|
+
# Type check (JSDoc types)
|
|
160
|
+
npm run typecheck
|
|
161
|
+
|
|
162
|
+
# Run tests
|
|
163
|
+
npm test
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
ISC
|
package/REFERENCE.md
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# 🌱 sprig Universe Prose — Quick Reference
|
|
2
|
+
|
|
3
|
+
*A compact guide to the universe layer of prose.*
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What the Universe layer is for
|
|
8
|
+
|
|
9
|
+
Use the Universe layer to:
|
|
10
|
+
|
|
11
|
+
* describe **what exists**
|
|
12
|
+
* name **concepts and domains**
|
|
13
|
+
* express **relationships and perspectives**
|
|
14
|
+
* provide **human-first orientation**
|
|
15
|
+
* link concepts to real artifacts (repos, paths, docs)
|
|
16
|
+
|
|
17
|
+
The Universe layer is:
|
|
18
|
+
|
|
19
|
+
* read-first
|
|
20
|
+
* plural by convention
|
|
21
|
+
* non-executable
|
|
22
|
+
* safe to explore without intent to change anything
|
|
23
|
+
|
|
24
|
+
### String literals
|
|
25
|
+
|
|
26
|
+
All string literals in prose use **single quotes (`'`)**, not double quotes.
|
|
27
|
+
|
|
28
|
+
Single quotes are intentionally chosen to read as static, descriptive values,
|
|
29
|
+
not dynamic or interpolated strings.
|
|
30
|
+
|
|
31
|
+
In practice, this is not a usability burden:
|
|
32
|
+
most writing in prose happens inside `describe`, `note`, and `documentation`
|
|
33
|
+
blocks, which do not require quoting at all.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Core blocks
|
|
38
|
+
|
|
39
|
+
### `universe`
|
|
40
|
+
|
|
41
|
+
Top-level container for a body of knowledge.
|
|
42
|
+
|
|
43
|
+
```sprig
|
|
44
|
+
universe GameWorld {
|
|
45
|
+
describe {
|
|
46
|
+
A high-level model of the game’s systems and domains.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
* Usually singular and conceptual
|
|
52
|
+
* Holds series, books, or entities directly
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### `series`
|
|
57
|
+
|
|
58
|
+
Groups related books or topics.
|
|
59
|
+
|
|
60
|
+
```sprig
|
|
61
|
+
series Items {
|
|
62
|
+
describe {
|
|
63
|
+
Everything related to items and inventories.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
* Optional
|
|
69
|
+
* Useful for large domains
|
|
70
|
+
* Named in the plural
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### `book`
|
|
75
|
+
|
|
76
|
+
A readable unit of knowledge about a domain.
|
|
77
|
+
|
|
78
|
+
```sprig
|
|
79
|
+
book Items {
|
|
80
|
+
describe {
|
|
81
|
+
Items represent objects that can exist in the world.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
* Plural by convention
|
|
87
|
+
* Think “a book about X”
|
|
88
|
+
* Can contain chapters and relationships
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### `chapter`
|
|
93
|
+
|
|
94
|
+
A subsection within a book.
|
|
95
|
+
|
|
96
|
+
```sprig
|
|
97
|
+
chapter Quality {
|
|
98
|
+
describe {
|
|
99
|
+
Item quality affects rarity and behavior.
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
* Optional
|
|
105
|
+
* Use for structure and scannability
|
|
106
|
+
* Reads like documentation, not schema
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Relationships
|
|
111
|
+
|
|
112
|
+
### `relates A and B`
|
|
113
|
+
|
|
114
|
+
Declares a relationship between two universe entities.
|
|
115
|
+
|
|
116
|
+
```sprig
|
|
117
|
+
relates Items and Skills {
|
|
118
|
+
from Items {
|
|
119
|
+
relationships { 'can grant' }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
from Skills {
|
|
123
|
+
relationships { 'can be granted by' }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
describe {
|
|
127
|
+
Certain items grant skills when equipped or consumed.
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Key points:
|
|
133
|
+
|
|
134
|
+
* Relationships are **plural**
|
|
135
|
+
* Perspectives are symmetric but labeled differently
|
|
136
|
+
* `describe` provides narrative context
|
|
137
|
+
* No directionality is enforced — this is about understanding
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Documentation blocks
|
|
142
|
+
|
|
143
|
+
### `describe`
|
|
144
|
+
|
|
145
|
+
Human explanation. The most important block.
|
|
146
|
+
|
|
147
|
+
```sprig
|
|
148
|
+
describe {
|
|
149
|
+
Items can be stored, consumed, equipped, or traded.
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
* Freeform text
|
|
154
|
+
* Encouraged everywhere
|
|
155
|
+
* No required format
|
|
156
|
+
* Calm, explanatory tone preferred
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### `title`
|
|
161
|
+
|
|
162
|
+
Entities are automatically converted into title-case, but sometimes that's not enough.
|
|
163
|
+
|
|
164
|
+
```sprig
|
|
165
|
+
chapter TimeBasedEffects {
|
|
166
|
+
title { Time-Based Effects }
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
* Follows the same rules as `describe`
|
|
171
|
+
|
|
172
|
+
### `note`
|
|
173
|
+
|
|
174
|
+
Notes are developer artifacts. They shouldn't be rendered, but they should be parsed and preserved for posterity. They are not intended for end-user documentation.
|
|
175
|
+
|
|
176
|
+
```sprig
|
|
177
|
+
chapter CodeMonsters {
|
|
178
|
+
note {
|
|
179
|
+
Remember to write about that one time I accidentally hard-deleted 400,000 documents.
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
* Follows the same rules as `describe`
|
|
185
|
+
|
|
186
|
+
### `documentation`
|
|
187
|
+
|
|
188
|
+
Longer-form or structured explanation.
|
|
189
|
+
|
|
190
|
+
```sprig
|
|
191
|
+
documentation {
|
|
192
|
+
document DocumentName {
|
|
193
|
+
kind { 'internal' }
|
|
194
|
+
path { '/docs/items/document-name.md' }
|
|
195
|
+
describe {
|
|
196
|
+
This document contains additional details about documents.
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
document {
|
|
201
|
+
...
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
* Optional
|
|
207
|
+
* Use when `describe` isn’t enough
|
|
208
|
+
* May render differently in UI later
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
### `references`
|
|
213
|
+
|
|
214
|
+
Links to real-world artifacts.
|
|
215
|
+
|
|
216
|
+
```sprig
|
|
217
|
+
references {
|
|
218
|
+
reference {
|
|
219
|
+
describe {
|
|
220
|
+
These files contain information about references.
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
repository { 'repo-name' }
|
|
224
|
+
paths {
|
|
225
|
+
'/data/references.yaml',
|
|
226
|
+
'/data/references.json',
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
reference {
|
|
231
|
+
repository { 'repo-name' }
|
|
232
|
+
paths { '/src/routers/references.js' }
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
You can also reuse named references defined at the universe scope:
|
|
238
|
+
|
|
239
|
+
```sprig
|
|
240
|
+
references {
|
|
241
|
+
reference {
|
|
242
|
+
repository { 'repo-name' }
|
|
243
|
+
paths { '/src/helpers.ts' }
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
using { ItemRouter, PlayerRouter }
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
* Non-owning
|
|
251
|
+
* Informational only
|
|
252
|
+
* Used for navigation and grounding
|
|
253
|
+
* `paths` may contain one or more file paths
|
|
254
|
+
* Mix inline `reference { ... }` entries with `using { Name }` to reuse named references
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Named artifacts
|
|
259
|
+
|
|
260
|
+
### Named references
|
|
261
|
+
|
|
262
|
+
Define reusable references at the universe scope:
|
|
263
|
+
|
|
264
|
+
```sprig
|
|
265
|
+
universe GameWorld {
|
|
266
|
+
reference ItemRouter {
|
|
267
|
+
repository { 'amaranthine-backend' }
|
|
268
|
+
paths { '/src/routers/items.ts' }
|
|
269
|
+
describe { Routes that implement item endpoints. }
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
reference PlayerRouter {
|
|
273
|
+
repository { 'amaranthine-backend' }
|
|
274
|
+
paths { '/src/routers/players.ts' }
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
series Items {
|
|
278
|
+
references {
|
|
279
|
+
using { ItemRouter }
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
* Named references are defined at universe scope
|
|
286
|
+
* Can be reused via `using { Name }` inside `references` blocks
|
|
287
|
+
* Useful for common references shared across multiple entities
|
|
288
|
+
* Each name must be unique within a universe
|
|
289
|
+
|
|
290
|
+
### Named documents
|
|
291
|
+
|
|
292
|
+
Define reusable documents at the universe scope:
|
|
293
|
+
|
|
294
|
+
```sprig
|
|
295
|
+
universe GameWorld {
|
|
296
|
+
document ItemsDesignDoc {
|
|
297
|
+
kind { 'internal' }
|
|
298
|
+
path { '/docs/items/overview.md' }
|
|
299
|
+
describe { High-level items design notes. }
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
series Items {
|
|
303
|
+
documentation {
|
|
304
|
+
document {
|
|
305
|
+
kind { 'internal' }
|
|
306
|
+
path { '/docs/items/details.md' }
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
* Named documents are defined at universe scope
|
|
314
|
+
* Can be referenced later (future: via `using { Name }` in `documentation` blocks)
|
|
315
|
+
* Useful for shared documentation artifacts
|
|
316
|
+
* Each name must be unique within a universe
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Naming conventions (recommended)
|
|
321
|
+
|
|
322
|
+
| Context | Convention | Rationale |
|
|
323
|
+
| ----------------- | ------------------ | ------------------------------ |
|
|
324
|
+
| Universe entities | **Plural** | You are reading about a domain |
|
|
325
|
+
| Books / series | **Plural** | Bodies of knowledge |
|
|
326
|
+
| Chapters | Singular or plural | Natural language |
|
|
327
|
+
| Relationships | Plural | Express populations |
|
|
328
|
+
| Scenes / actors | **Singular** | Describe one participant |
|
|
329
|
+
|
|
330
|
+
These are conventions, not enforcement.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## What Universe prose does *not* do
|
|
335
|
+
|
|
336
|
+
* No validation
|
|
337
|
+
* No execution
|
|
338
|
+
* No ownership
|
|
339
|
+
* No enforcement
|
|
340
|
+
* No “correctness” guarantees
|
|
341
|
+
|
|
342
|
+
Universe prose exists to be:
|
|
343
|
+
|
|
344
|
+
* read
|
|
345
|
+
* explored
|
|
346
|
+
* understood
|
|
347
|
+
* evolved over time
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Mental model
|
|
352
|
+
|
|
353
|
+
> Universe prose is closer to a field guide than a schema.
|
|
354
|
+
> It tells you what kinds of things exist and how they relate —
|
|
355
|
+
> not what you must do with them.
|