
Highlights#
- Compiled the live catalog behind procedimentipa.gov.it into an agent-navigable knowledge graph: one markdown page per procedure and per legal article, stitched by wikilinks, so an LLM agent answers by walking procedure → article → law instead of re-running retrieval every time.
- Chose article-level atomicity — each law article is its own addressable page — so a procedure cites the exact article it depends on rather than a 300-article decree, keeping agent context small and citations exact.
- Built the compiler as an idempotent Python CLI over the catalog’s backoffice API:
syncre-pulls what’s already in the vault,--no-clobberprotects hand-edited files, and colon-bearing legal URNs map to filesystem-safe slugs reversibly.
How it works#
flowchart TD
subgraph src["Procedure catalog backoffice"]
P["Procedures
(each declares its legal sources)"]
L["Legislation
(Normattiva / EUR-Lex URNs)"]
end
CLI["procedure-wiki CLI
fetch · resolve · render"]
subgraph vault["Obsidian vault (markdown)"]
PF["procedures/*.md"]
AF["legislation/*/art_NN.md
one page per article"]
end
P --> CLI
L --> CLI
CLI --> PF
CLI --> AF
PF --> A["LLM agent / human
navigates by wikilinks"]
AF --> A
Portfolio Case Study#
Problem. Most LLM-over-documents setups are RAG: retrieve some chunks at query time and hope the right fragments come back, with the model rediscovering the same knowledge from scratch on every question. For a catalog of administrative procedures anchored to specific law articles, the connections are the knowledge — “which law backs this procedure, and what does that article actually say?” should be one link away, not a similarity search.
Approach. The tool instantiates Karpathy’s LLM Wiki idea, but auto-compiled: the graph already exists implicitly in the catalog, since every procedure declares the legislation it depends on. The CLI fetches procedures from the backoffice API, resolves their legal references hierarchically down to the article, and renders everything as markdown with typed links in both directions — procedure → article via frontmatter, article ↔ law via back-links. Shared hubs emerge for free: two unrelated procedures citing the same decree converge on the same law node, so the graph surfaces which laws are load-bearing across the catalog without anyone declaring it.
The defining design choice is atomicity at the article level. Legislation isn’t stored as one giant law document; each article is its own addressable page, so an agent loads one article instead of scanning a 300-article decree — cheaper tokens, sharper citations.
Atomicity as navigation: from a procedure page, one wikilink lands on exactly the cited article — never the surrounding 300-article decree, and never a similarity ranking over chunks.
What was hard. Legal URNs contain colons, which break filesystems and Obsidian links, so the tool maps : → ~ reversibly (~ never appears in Italian NIR URNs). Re-running also had to be safe: sync is idempotent, and --no-clobber keeps hand-edited pages intact across refreshes, so the vault can accumulate human annotations without being overwritten by the next compile.
Outcome. The compiled development vault holds 88 procedure pages and 115 legislation pages, navigable in Obsidian and trivially parseable by any agent — the graph renders on this page come from that vault. It complements the platform’s search engine rather than replacing it: search finds an entry point, the graph carries the agent from there.

Non-goals. No embeddings and no retrieval index by design — navigation is deterministic link-following. The wiki is regenerated from the source of truth on demand, not hand-curated, and it is a companion artifact to the catalog platform rather than a standalone product.
Stack#
Python, the catalog’s REST API, Obsidian-flavored markdown + YAML frontmatter, Normattiva / EUR-Lex URN resolution.
