Ctrl K
ComunidadGuías…

docs/semantic-blocks.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<!-- authority:non-specification -->

# Semantic blocks

Semantic blocks are optional Markdown sections that make Exomem notes easier to
parse without making them harder to read. They are normal headings plus optional
metadata bullets. The body remains ordinary Markdown.

This is not a separate DSL. The goal is governed cognition: claims, evidence,
decisions, assumptions, risks, records, cases, and actions can be named,
related, validated, and reused by Exomem tooling. Compact observations, rich
units, category/kind governance, retrieval, and exact unit reads are documented
in [first-class semantic language](semantic-language.md).

## Block shape

Use a heading whose text is a supported block type:

```markdown
## Claim
- id: retrieval-owned-files
- relations: evidenced_by: [[Knowledge Base/Sources/Sessions/2026-07-07-session]]

Retrieval works best when durable conclusions live in owned Markdown files.
```

Metadata is optional. Leading bullets of the form `- key: value` are parsed as
metadata and removed from the block body. Any other body content stays Markdown:
paragraphs, bullets, wikilinks, tables, and code blocks.

The first-class rich metadata fields are `category`, `tags`, and `context`.
`tags` is a comma-separated list of plain tokens (no `#` prefix); tokens are
trimmed, Unicode-normalized, case-folded, and de-duplicated in first-authored
order. `context` is trimmed, non-empty, single-line Unicode. Invalid values stay
visible in generic parsed metadata for diagnosis but do not partially populate
the first-class field.

When `category` is omitted, the heading supplies the authored category identity:
the exact heading is `category_raw` and its normalized key is `category_key`.
Reviewed category aliases may resolve that key; otherwise the public category
falls back to the governed heading kind. An explicit `- category:` overrides the
heading-derived category identity. Category, governed kind, tags, context, and
typed relations are separate dimensions.

Headings inside fenced code blocks are ignored by the parser.

## Block types

The shipped kinds are the entries of `src/exomem/vocabulary/packs/core/kinds.yaml`.
Each entry has its labels, its heading aliases and the traits that state what code
does with it. A vault adds kinds, and labels in any language, in
`_Schema/semantic-language-registry.yaml`. To list every kind in a vault, run
`inspect_memory(operation="schema.infer", arguments={'subject': 'categories'})` and
read `kinds`: each entry gives its `key`, its `labels` and whether it is `shipped`. The
list also holds the compact kind `observation`, which no heading names.

A heading names a kind by its key, one of its heading aliases or one of its labels.
When a vault gives `claim` the label `Väite` in Finnish, `## Väite` is a `claim`
unit, whatever the case of the heading.

Heading labels normalize spaces and hyphens to underscores, so these are
equivalent:

```markdown
## Open Question
## open-question
## open_question
```

Unknown headings remain normal Markdown and are not validation errors.

## Note relations

Use a canonical `## Relations` section for directional note-to-note edges. Each
bullet has one governed lower-snake-case relation type and one wikilink:

```markdown
## Relations
- refines [[Knowledge Base/Notes/Insights/Earlier Conclusion]]
- depends_on [[Knowledge Base/Entities/Decisions/Architecture Decision]]
- relates_to [[Knowledge Base/Notes/Research/Project/Adjacent Finding]]
```

These links remain visible and editable in Obsidian. Exomem indexes the declared
edge type instead of a redundant generic edge. Inline references elsewhere in
the note remain generic `links_to` connections.

Typed bullets written outside `## Relations` remain index-compatible for older
notes, but new notes should use the canonical section so validation and review
can distinguish governed relations from incidental list prose.

## Block relations

When a relation belongs to a specific claim, finding, decision, or piece of
evidence rather than the whole note, put it in that semantic block's
`relations` metadata bullet. Use comma-separated `relation: target` entries:

```markdown
## Risk
- id: schema-dsl-risk
- relations: mitigates: [[Decision#Use headings]], blocks: [[Requirement#Plain Markdown]]

A custom grammar would make notes harder to read and harder to edit by hand.
```

Supported relations:

- `supports`
- `contradicts`
- `refines`
- `duplicates`
- `supersedes`
- `derived_from`
- `evidenced_by`
- `depends_on`
- `implements`
- `mitigates`
- `causes`
- `caused_by`
- `blocks`
- `resolves`
- `answers`
- `raises_question`
- `used_for`
- `observed_in`
- `mentions`
- `about_entity`
- `relates_to`
- `links_to`
- `cites`
- `tests`
- `owns`
- `located_at`
- `operates`
- `supplies`
- `produces`
- `member_of`
- `precedes`
- `follows`
- `assesses`

Unsupported relation names and malformed relation entries are validation
errors. Duplicate block IDs are warnings because the file remains readable, but
references become ambiguous.

## Examples

```markdown
## Evidence
- id: receipt-photo
- category: purchase records
- tags: warranty, hardware/receipts
- context: replacement request
- relations: supports: [[Case#Laptop warranty]]

Photo of the purchase receipt preserved for the warranty claim.

## Decision
- id: use-markdown-headings
- relations: resolves: [[Open Question#Block syntax]], mitigates: [[Risk#DSL sprawl]]

Use ordinary headings plus optional metadata bullets for v1 semantic blocks.

## Action
- id: add-tests
- relations: implements: [[Requirement#Validation Result Shape]], owns: [[Fixture Actor]]

Add parser, validation, claim extraction, and context-pack tests.
```

## Integration

Rich blocks are governed semantic units and may carry typed relations. Compact
`- [category] ... ^anchor` observations remain ordinary one-line Markdown and
cannot imply typed graph edges; use rich form or a canonical note-level
relation when direction matters.

`claims.extract_claim_text` prefers the first semantic `claim` block when one is
present, then falls back to the legacy section-based extraction.

`context_pack.assemble_pack` includes a `semantic_blocks` map keyed by packed
page path when pages contain supported blocks. This is additive: existing pack
fields and find ordering are unchanged.