6.0 KiB
SKILL: Org-Mode & AST Manipulation (Universal Literate Note)
Overview
This skill defines the Grammar of the Memex. It establishes the rules for treating plain text as a structured, hierarchical database. Org-mode is our *Homoiconic Memory*—documentation for humans and AST for the agent.
Phase A: Demand (PRD)
1. Purpose
Define the structural rules and manipulation interfaces for the Org-mode AST.
2. User Needs
- Everything is a Node: Mandatory headlines, properties, and unique IDs.
- Literate Programming: Code must be wrapped in narrative-rich blocks.
- Naming & Paths: Strict kebab-case and flat directory structure.
- Binary Integrity: Management of attachments via the Attachment Protocol.
3. Success Criteria
TODO ID Uniqueness Enforcement
TODO Literate Block Parsing
TODO Attachment Link Validation
Phase B: Blueprint (PROTOCOL)
Phase B: Blueprint (PROTOCOL)
1. Architectural Intent
The Org-mode AST will be the central data structure for the Memex. We aim for a simple, consistent, and easily navigable representation of hierarchical data. All operations should be performable through Lisp functions that respect the immutability of the underlying data where possible, returning new modified versions. The architecture must accommodate both human readability/editability and machine manipulation. We're focusing on a 'functional core, imperative shell' approach, with side-effecting operations clearly delineated and minimized. We'll leverage standard Emacs Lisp data structures (lists, alists, strings, numbers) so to not needlessly reinvent the wheel, but wrap them in functions offering strongly typed and named abstractions.
2. Semantic Interfaces
Core Data Structures
-
`org-node`: Represents a headline and its children. A Lisp alist with the following keys:
- `:id`: A unique string identifier (required).
- `:headline`: A string representing the headline text.
- `:level`: An integer indicating the heading level (1, 2, 3, etc.).
- `:properties`: An alist of property key-value pairs (string keys, string values).
- `:content`: A string representing the content within the headline, but before any sub-headings. This will generally contain a sequence of literate blocks.
- `:children`: A list of `org-node`s representing the sub-headings.
-
`literate-block`: Represents a code or narrative block. An alist with keys:
- `:type`: A symbol indicating the block type (e.g., `:code`, `:narrative`).
- `:language`: A symbol indicating the programming language for code blocks (e.g., `:lisp`, `:python`). `nil` or `:text` for narrative blocks.
- `:content`: A string representing the content of the block.
- `:metadata`: An alist of metadata key-value pairs for the block (string keys, string values).
CRUD Operations (Node Focused)
- `(org-node-create headline content properties children)`: Creates a new `org-node`. All parameters are required. Returns a new `org-node`. `headline`: String `content`: String `properties`: Alist `children`: List of `org-node` `returns`: `org-node`
- `(org-node-read node-id)`: Retrieves an `org-node` by its ID. Returns the `org-node` or `nil` if not found. `node-id`: String `returns`: `org-node` | `nil`
- `(org-node-update node attr value)`: Updates an attribute of an existing `org-node`. Returns a new `org-node` with the updated attribute. Purely functional; does not mutate the original. `node`: `org-node` `attr`: Symbol (e.g., `:headline`, `:content`, `:properties`) `value`: depends on attribute; e.g., String for headline, new alist for properties `returns`: `org-node`
- `(org-node-delete node-id)`: Deletes an `org-node` from the Memex. This operation has side effects. Returns `t` if successful, `nil` otherwise. (More thought will be required regarding how this interacts with the file system and possible dangling references.) `node-id`: String `returns`: `t` | `nil`
Traversal & Query Functions
- `(org-node-children node)`: Returns the list of child `org-node`s of a given `org-node`. `node`: `org-node` `returns`: List of `org-node`
- `(org-node-parent node)`: Returns the parent `org-node` of a given `org-node`, or `nil` if it's the root. Requires maintaining a separate index for efficient parent lookups. `node`: `org-node` `returns`: `org-node` | `nil`
- `(org-node-query query-fn)`: Searches the entire Memex for `org-node`s matching a given criteria. `query-fn` is a function that takes an `org-node` as input and returns `t` if the node matches the query, `nil` otherwise. Returns a list of matching `org-node`s. `query-fn`: Function taking `org-node` and returning boolean `returns`: List of `org-node`
Literate Block Operations
- `(org-node-extract-blocks node)`: Extracts all `literate-block`s from the `content` section of the `org-node`. This will require parsing the string `content` by detecting the block delimiters. Returns a list of `literate-block`s. `node`: `org-node` `returns`: List of `literate-block`
- `(literate-block-evaluate block)`: Evaluates a code block. The behavior depends on the `language` of the block. This operation has side effects. Returns the result of the evaluation. `block`: `literate-block` `returns`: depends on language.