issues-fs.sgit.ai / dsl

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/

ComponentJob
Parser__Issues_FileThe file-level parser — takes the text, produces the structure
Parser__Issues_File__LineThe line-level parser. This is where the grammar actually lives
Issues_File__Loader__ServiceFinds and loads .issues files from a repository
Issues_File__Check__ServiceValidates a parsed file before anything is created from it
Issues_File__Normalise__ServiceCanonicalises the parsed form — the step that makes the format forgiving to write and strict to consume
Issues_File__Schema__ServiceMaps the parsed form onto the node schema
Factory__Issues_File__NodesBuilds 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:

FileWhat it appears to hold
bugs-parser.issuesBugs against the parser — the format being used to track work on itself
workstream-integration.issuesAn integration workstream
workstream-issues-file-parser.issuesThe 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.

  1. It has no CLI surface. None of the fourteen commands mentions it. A user exploring the tool through --help will never encounter it.
  2. It lives inside the core library, which is the package a user is least likely to read — issues-fs is a dependency of the CLI, not the thing people install directly.
  3. It is newest. It postdates every architecture document in the corpus, and no document has been revised since.
  4. 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 .issues DSL, and --for-agent JSON. 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

#WhatWho
1The grammar, written down — read out of Parser__Issues_File__Line and the tests, published here as a specification with examplessite agent, next release
2The three live files, published verbatim as worked examples, with the nodes each one produces alongsideneeds the files — task T7
3A 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 onproject 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.