The .issues flat-file DSL
Inside the core package there is a line-oriented text format that parses into graph nodes. Eleven source files, roughly fifty-five tests across seven test files, three live example files in the project's own graph, and a wired-in repository API. Until this page it had zero prose documentation anywhere — not in a README, not in a brief, not in an architecture document.
Read this page differently from the rest of the site. Everywhere else, this site corrects documentation against code. Here there is no documentation to correct: the parser tests and the three live files are the only specification that exists. What follows describes the shape of the feature and what it is wired into — verified against the source tree — and stops short of specifying a grammar that has never been written down. Where the exact syntax matters, read issues_fs/issues/issues_file/Parser__Issues_File__Line.py and the tests beside it.
What it is
A third way to get nodes into a graph. The other two are the CLI — one command per node — and the Python API. The DSL lets you write a batch of related nodes as plain text in one file, and have them parsed, checked, normalised and turned into nodes.
That matters most for the case the CLI handles worst: sitting down with a page of work in your head and wanting it in the graph. A dozen issues-fs create invocations is a poor way to express one thought. A file is a good one — and, being a file, it diffs, reviews and merges like everything else here.
The eleven source files
issues_fs/issues/issues_file/
| Component | Job |
|---|---|
Parser__Issues_File | The file-level parser — takes the text, produces the structure |
Parser__Issues_File__Line | The line-level parser. This is where the grammar actually lives |
Issues_File__Loader__Service | Finds and loads .issues files from a repository |
Issues_File__Check__Service | Validates a parsed file before anything is created from it |
Issues_File__Normalise__Service | Canonicalises the parsed form — the step that makes the format forgiving to write and strict to consume |
Issues_File__Schema__Service | Maps the parsed form onto the node schema |
Factory__Issues_File__Nodes | Builds actual Schema__Node objects from the parsed and checked form |
The shape of that list is itself informative. Parse, check, normalise, map to schema, construct — five distinct stages with a service each, which is not how anybody builds a throwaway. This is a considered feature that nobody announced.
Where it is wired in
The DSL is not a side tool. It is on Graph__Repository, the same object that loads and saves nodes:
Graph__Repository.issues_files_discover() # find .issues files in the repo
Graph__Repository.issues_files_load() # parse and load them
Graph__Repository.issues_files_get_cached_nodes() # the nodes they produced
Graph__Repository.issues_files_find_node_by_label()
Graph__Repository.issues_files_invalidate_cache()
Two things follow from that surface. There is a cache, with explicit invalidation — so parsed files are held rather than re-read per query. And there is find_node_by_label, which means nodes originating in a .issues file are addressable by the same label scheme as everything else.
The three live files
Issues-FS's own .issues/ directory contains three of them:
| File | What it appears to hold |
|---|---|
bugs-parser.issues | Bugs against the parser — the format being used to track work on itself |
workstream-integration.issues | An integration workstream |
workstream-issues-file-parser.issues | The workstream that built this feature |
The first and third are worth pausing on: the format is being used to track the development of the format. That is the same self-referential move the role ecosystem makes — the tracker tracks its own development — arriving independently in a corner of the codebase nobody documented.
Why it went unnoticed
Four reasons, and together they are a good case study in how a built feature becomes invisible.
- It has no CLI surface. None of the fourteen commands mentions it. A user exploring the tool through
--helpwill never encounter it. - It lives inside the core library, which is the package a user is least likely to read —
issues-fsis a dependency of the CLI, not the thing people install directly. - It is newest. It postdates every architecture document in the corpus, and no document has been revised since.
- Its examples are in a dot-directory. The three live files sit in
.issues/, which is hidden by default in every file listing anybody runs.
Issues-FS has three agent-operable surfaces — lite markdown, the.issuesDSL, and--for-agentJSON. Only the third is discoverable, and only the third has ever been written about.
Using it today
Honestly: read the source first. Specifically:
issues_fs/issues/issues_file/Parser__Issues_File__Line.py # the grammar
issues_fs/issues/issues_file/Issues_File__Check__Service.py # what is rejected, and why
tests/…/issues_file/ # ~55 tests across 7 files
Issues-FS/.issues/*.issues # three files that work
Then load through the repository API rather than calling the parser directly, so the check and normalise stages run:
repo = Graph__Repository__Factory.create_local_disk(root_path=".issues")
repo.issues_files_discover()
repo.issues_files_load()
node = repo.issues_files_find_node_by_label("Bug-3")
The one caveat worth stating. A format whose specification is its test suite can change without anything looking like a breaking change, because there is no document for a change to contradict. Treat the syntax as unstable until somebody writes the grammar down — and pin the issues-fs version if you build on it.
What this section needs next
| # | What | Who |
|---|---|---|
| 1 | The grammar, written down — read out of Parser__Issues_File__Line and the tests, published here as a specification with examples | site agent, next release |
| 2 | The three live files, published verbatim as worked examples, with the nodes each one produces alongside | needs the files — task T7 |
| 3 | A decision on whether the DSL is a supported surface or an internal convenience. It is currently in the middle: too built to be an experiment, too undocumented to depend on | project lead — request N8 |
For an agent
There is a third way to author nodes: .issues files, parsed by issues_fs/issues/issues_file/ and loaded through Graph__Repository.issues_files_discover() / issues_files_load(), then addressable via issues_files_find_node_by_label(). There is no written grammar — the specification is Parser__Issues_File__Line.py plus roughly 55 tests, and three working files in Issues-FS/.issues/*.issues. Read those before writing one. Load through the repository API, not the parser directly, so the check and normalise stages run. Treat the syntax as unstable and pin the issues-fs version. There is no CLI command for any of this.