Skip to content

Commit 00a5532

Browse files
Merge pull request #32 from Entrolution/fix/spec-review-remediation
Fix 25 spec review issues across core and extensions
2 parents de46677 + 61cda28 commit 00a5532

16 files changed

Lines changed: 305 additions & 30 deletions

File tree

schemas/academic.schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@
9292
},
9393
"resetTrigger": {
9494
"type": "string",
95-
"description": "When to reset counters",
96-
"enum": ["chapter", "section", "none"]
95+
"description": "When to reset counters. Uses heading level identifiers corresponding to the core heading block's level attribute.",
96+
"enum": ["heading1", "heading2", "heading3", "heading4", "heading5", "heading6", "none"]
9797
},
9898
"theoremBlock": {
9999
"type": "object",

spec/core/00-introduction.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ document.cdx
129129
└── dublin-core.json # Dublin Core metadata (required)
130130
```
131131

132-
### 1.5a Annotation Layers
132+
### 1.6 Annotation Layers
133133

134134
Codex provides three annotation storage locations, each serving different purposes:
135135

@@ -151,7 +151,7 @@ All annotation layers are **outside the content hash boundary** — adding annot
151151

152152
**Implementation note**: Core annotations live in `security/annotations.json` because they share the security directory's "outside content hash" semantics. When migrating from core annotations to the collaboration extension, implementations SHOULD convert existing annotations to the collaboration format and remove the core annotations file. The two formats SHOULD NOT coexist in the same document to avoid confusion.
153153

154-
### 1.6 Specification Organization
154+
### 1.7 Specification Organization
155155

156156
This specification is organized into the following sections:
157157

@@ -173,8 +173,9 @@ Extension specifications (optional modules) are defined separately:
173173
- Phantom Extension
174174
- Forms Extension
175175
- Semantic Extension
176+
- Legal Extension
176177

177-
### 1.7 Versioning
178+
### 1.8 Versioning
178179

179180
This specification uses semantic versioning (MAJOR.MINOR.PATCH):
180181

spec/core/03-content-blocks.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,15 @@ Example:
10031003
}
10041004
```
10051005

1006+
### 5.1 Extension Mark Types
1007+
1008+
Extensions MAY define additional mark types for use within text nodes. Unlike block types, extension marks are NOT required to use a namespace prefix — marks operate within the text node's `marks` array where the collision risk is lower. However, extensions MAY use a namespace prefix (e.g., `legal:cite`) when the unqualified name could cause confusion with marks from other extensions.
1009+
1010+
Extension marks:
1011+
- SHOULD be documented in the extension specification
1012+
- MUST define their field table (type, required fields, optional fields)
1013+
- SHOULD avoid names that collide with core marks or marks from commonly-paired extensions
1014+
10061015
## 6. Internationalization
10071016

10081017
### 6.1 Text Direction and Writing Mode

spec/core/03a-anchors-and-references.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ Extensions extend the base Person type with additional fields via schema composi
295295

296296
All Person objects MUST include at minimum the `name` field. Extensions SHOULD include the base fields alongside their extension-specific fields. The naming distinction between "author" and "signer" is intentional to reflect the semantic difference in their contexts.
297297

298+
Extensions MAY add domain-specific identity fields to the Person object. The core `identifier` field remains available for persistent scholarly or decentralized identifiers. Extension-specific identity fields are additive — they do not replace `identifier`. For example, the collaboration extension adds `userId` for session-level identity, and the security extension adds `keyId` for cryptographic key association. A Person object MAY include both `identifier` and extension-specific fields simultaneously.
299+
298300
## 10. Relationship to Extensions
299301

300302
The anchor system is defined in the core specification but is primarily consumed by extensions:
@@ -307,3 +309,16 @@ The anchor system is defined in the core specification but is primarily consumed
307309
| Semantic (`codex.semantic`) | Internal `semantic:ref` `target` fields use Content Anchor URI syntax |
308310

309311
See the respective extension specifications for details.
312+
313+
## 11. Cross-Reference Mechanism Selection
314+
315+
Multiple mechanisms exist for cross-referencing within Codex documents. Use the following guidance:
316+
317+
| Mechanism | Extension | Use When |
318+
|-----------|-----------|----------|
319+
| `link` mark (with `#anchor` href) | Core | General-purpose internal links; hyperlink-style references |
320+
| `semantic:ref` | Semantic | Scholarly cross-references (e.g., 'see Section 3', 'as shown in Figure 2') with automatic label generation |
321+
| `presentation:reference` | Presentation | Layout-aware references that need presentation-specific formatting or page numbers |
322+
| `academic:theoremRef` / `academic:equationRef` | Academic | References to theorems, equations, or other numbered academic elements |
323+
324+
For simple internal links, use the core `link` mark. For documents requiring automatic numbering and label generation (e.g., 'Figure 3', 'Theorem 2.1'), use extension-specific reference marks. When multiple reference types apply, prefer the most semantically specific mechanism.

spec/core/05-asset-embedding.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,24 @@ Embedded files are attachments that accompany the document but are not directly
288288

289289
### 6.3 Referencing Embedded Files
290290

291-
Embedded files can be referenced from content:
291+
Embedded files can be referenced from content using a `paragraph` block with a `link` mark pointing to the embedded file:
292292

293293
```json
294294
{
295-
"type": "attachment",
296-
"ref": "assets/embeds/quarterly-data.xlsx",
297-
"title": "Download source data",
298-
"icon": "spreadsheet"
295+
"type": "paragraph",
296+
"children": [
297+
{
298+
"type": "text",
299+
"value": "Download source data",
300+
"marks": [
301+
{
302+
"type": "link",
303+
"href": "assets/embeds/quarterly-data.xlsx",
304+
"title": "Download source data"
305+
}
306+
]
307+
}
308+
]
299309
}
300310
```
301311

spec/core/06-document-hashing.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,12 @@ The following table summarizes what is included in and excluded from the documen
122122
| Security | No | Signatures reference the hash — not part of it |
123123
| Timestamps | No | Administrative metadata (`created`, `modified`) |
124124
| Provenance | No | Lineage tracking and derivation history |
125+
| CRDT metadata | No | Transient synchronization state from collaboration extension |
125126

126127
This boundary ensures that the document's identity represents its **semantic content** — what the document says — rather than how it appears or administrative metadata about it.
127128

129+
> **Note:** CRDT metadata added by the collaboration extension (`crdt` fields on content blocks) is excluded from the content hash. CRDT data represents transient synchronization state and MUST be stripped before computing the document hash.
130+
128131
### 4.2 Canonical Content Structure
129132

130133
```json

spec/core/08-metadata.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Location: `metadata/extended.json` (or custom paths)
3737

3838
### 3.1 File Format
3939

40+
The `version` field in Dublin Core metadata refers to the Dublin Core Metadata Element Set standard version (currently 1.1), not the Codex specification version. The Codex specification version is declared in the manifest's `specVersion` field.
41+
4042
```json
4143
{
4244
"version": "1.1",

spec/extensions/README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,22 @@ This directory contains specifications for Codex extensions. Each extension adds
1313
| [Security](security/README.md) | `codex.security` | 0.1 | Draft | Digital signatures, encryption, access control |
1414
| [Phantoms](phantoms/README.md) | `codex.phantoms` | 0.1 | Draft | Off-page annotation clusters |
1515
| [Presentation](presentation/README.md) | `codex.presentation` | 0.1 | Draft | Layout templates and rendering hints |
16+
| [Legal](legal/README.md) | `codex.legal` | 0.1 | Draft | Legal citations, clause references, jurisdiction metadata |
1617

1718
## Extension Compatibility
1819

1920
Extensions are designed to work together. The following matrix shows compatibility between extensions:
2021

21-
| Extension | semantic | academic | forms | collaboration | security | phantoms | presentation |
22-
|-----------|----------|----------|-------|---------------|----------|----------|--------------|
23-
| semantic | - |||||||
24-
| academic || - |* |||||
25-
| forms ||* | - |||||
26-
| collaboration |||| - ||||
27-
| security ||||| - |||
28-
| phantoms |||||| - ||
29-
| presentation ||||||| - |
22+
| Extension | semantic | academic | forms | collaboration | security | phantoms | presentation | legal |
23+
|-----------|----------|----------|-------|---------------|----------|----------|--------------|-------|
24+
| semantic | - ||||||||
25+
| academic || - |* ||||||
26+
| forms ||* | - ||||||
27+
| collaboration |||| - |||||
28+
| security ||||| - ||||
29+
| phantoms |||||| - |||
30+
| presentation ||||||| - ||
31+
| legal |||||||| - |
3032

3133
**Legend:**
3234
- ✓ = Fully compatible
@@ -69,6 +71,7 @@ Most extensions store data in dedicated directories:
6971
| collaboration | `collaboration/` | `comments.json`, `changes.json` |
7072
| security | `security/` | `signatures.json`, `encryption.json` |
7173
| phantoms | `phantoms/` | `clusters.json` |
74+
| legal | `legal/` | `citations.json` |
7275

7376
### Shared Definitions
7477

spec/extensions/academic/README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ Location: `academic/numbering.json`
632632
"version": "0.1",
633633
"equations": {
634634
"style": "chapter.number",
635-
"resetOn": "chapter"
635+
"resetOn": "heading1"
636636
},
637637
"theorems": {
638638
"style": "chapter.section.number",
@@ -644,11 +644,11 @@ Location: `academic/numbering.json`
644644
},
645645
"algorithms": {
646646
"style": "number",
647-
"resetOn": "chapter"
647+
"resetOn": "heading1"
648648
},
649649
"exercises": {
650650
"style": "chapter.number",
651-
"resetOn": "chapter"
651+
"resetOn": "heading1"
652652
},
653653
"customVariants": {
654654
"axiom": {
@@ -690,10 +690,16 @@ This produces: Theorem 1, Lemma 2, Proposition 3, Theorem 4, etc.
690690

691691
### 10.3 Reset Triggers
692692

693+
The `resetOn` field accepts heading level identifiers: `heading1` through `heading6`, corresponding to the core `heading` block's `level` attribute. For example, `"heading1"` resets numbering at each level-1 heading.
694+
693695
| Reset On | Description |
694696
|----------|-------------|
695-
| `chapter` | Reset at each chapter |
696-
| `section` | Reset at each section |
697+
| `heading1` | Reset at each level-1 heading |
698+
| `heading2` | Reset at each level-2 heading |
699+
| `heading3` | Reset at each level-3 heading |
700+
| `heading4` | Reset at each level-4 heading |
701+
| `heading5` | Reset at each level-5 heading |
702+
| `heading6` | Reset at each level-6 heading |
697703
| `none` | Never reset (document-wide numbering) |
698704

699705
## 11. Examples

spec/extensions/collaboration/README.md

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ Each content block can carry CRDT metadata:
6464
}
6565
```
6666

67+
**Hashing:** CRDT metadata (`crdt` fields on content blocks) MUST be stripped before computing the document content hash (see Core Specification, Section 6 — Document Hashing). CRDT metadata represents transient synchronization state, not document content. Implementations MUST materialize CRDT operations to plain content before hashing.
68+
6769
### 3.4 Text CRDTs
6870

6971
For rich text editing within blocks, integrate with text CRDTs:
@@ -231,7 +233,27 @@ Location: `collaboration/comments.json`
231233
| `resolved` | boolean | No | Whether comment is resolved |
232234
| `replies` | array | No | Reply comments |
233235

234-
### 4.3a Author Object
236+
### 4.3a Reply Object
237+
238+
The `replies` array contains reply objects. Replies are flat — they do not nest (a reply cannot contain further replies). Replies do not have their own anchors; they inherit the anchor context of the parent comment.
239+
240+
```json
241+
{
242+
"id": "c1-r1",
243+
"author": { "name": "Author", "email": "author@example.com" },
244+
"created": "2025-01-15T10:30:00Z",
245+
"content": "Good point, I'll expand this section."
246+
}
247+
```
248+
249+
| Field | Type | Required | Description |
250+
|-------|------|----------|-------------|
251+
| `id` | string | Yes | Unique reply identifier |
252+
| `author` | object | Yes | Reply author (see Author Object below) |
253+
| `created` | string | Yes | ISO 8601 creation timestamp |
254+
| `content` | string | Yes | Reply text content |
255+
256+
### 4.3b Author Object
235257

236258
The `author` field uses a consistent structure throughout the collaboration extension:
237259

@@ -359,7 +381,21 @@ Location: `collaboration/changes.json`
359381
}
360382
```
361383

362-
### 5.3 Change Types
384+
### 5.3 Change Record Fields
385+
386+
| Field | Type | Required | Description |
387+
|-------|------|----------|-------------|
388+
| `id` | string | Yes | Unique change identifier |
389+
| `type` | string | Yes | Change type (see Change Types below) |
390+
| `anchor` | ContentAnchor | Yes | Anchor to the affected content (see Anchors and References spec) |
391+
| `position` | object | No | Position for insert/move operations (e.g., `{ "after": "block-id" }`) |
392+
| `before` | object | No | Content state before the change (for `modify` and `delete` types) |
393+
| `after` | object | No | Content state after the change (for `modify` and `insert` types) |
394+
| `author` | object | Yes | Change author (see Author Object in section 4.3a) |
395+
| `timestamp` | string | Yes | ISO 8601 change timestamp |
396+
| `status` | string | No | Change status: `"pending"`, `"accepted"`, or `"rejected"` (default: `"pending"`) |
397+
398+
### 5.4 Change Types
363399

364400
| Type | Description |
365401
|------|-------------|
@@ -369,7 +405,7 @@ Location: `collaboration/changes.json`
369405
| `move` | Block moved to new position |
370406
| `format` | Formatting changed |
371407

372-
### 5.4 Accepting/Rejecting Changes
408+
### 5.5 Accepting/Rejecting Changes
373409

374410
Changes can be:
375411
- `pending` - Not yet reviewed

0 commit comments

Comments
 (0)