{"id":51167078,"url":"https://github.com/navapbc/lockpicks-xlator-plugin","last_synced_at":"2026-06-26T20:30:23.219Z","repository":{"id":351675080,"uuid":"1210866565","full_name":"navapbc/lockpicks-xlator-plugin","owner":"navapbc","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-04T19:15:07.000Z","size":1538,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-04T21:27:53.370Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/navapbc.png","metadata":{"files":{"readme":"README-dev.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-14T20:49:02.000Z","updated_at":"2026-06-04T19:15:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/navapbc/lockpicks-xlator-plugin","commit_stats":null,"previous_names":["navapbc/lockpicks-xlator-plugin"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/navapbc/lockpicks-xlator-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Flockpicks-xlator-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Flockpicks-xlator-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Flockpicks-xlator-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Flockpicks-xlator-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/navapbc","download_url":"https://codeload.github.com/navapbc/lockpicks-xlator-plugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Flockpicks-xlator-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34832916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-26T20:30:22.614Z","updated_at":"2026-06-26T20:30:23.218Z","avatar_url":"https://github.com/navapbc.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Developer Guide — xlator plugin\n\nRules-as-Code pipeline: policy documents → Catala source (`.catala_en`) → `clerk typecheck` + `clerk test` → demo apps.\n\n---\n\n### First-time setup\n\nOptional: install [`mise`](https://mise.jdx.dev/) for tool versions (Python 3.14, Rust, OCaml/opam).\n\n```bash\n./xlator_setup.sh        # Install uv, create .venv, install deps, install opam + catala/clerk\n```\n\nAfter setup, use `xlator` directly (this shim activates the venv and redirects to other scripts as needed).\n\n---\n\n## CLI — `xlator`\n\nAll commands follow the pattern `xlator \u003caction\u003e [domain] [module]`.\n\n```bash\nxlator list                              # Show all domain-module pairs\n```\n\n### Pipeline (Catala)\n\n```bash\nxlator catala-test            \u003cdomain\u003e \u003cmodule\u003e   # Run Catala tests via clerk\nxlator catala-pipeline        \u003cdomain\u003e \u003cmodule\u003e   # copy-source-to-output → clerk typecheck → clerk test\nxlator clerk-loop             \u003cdomain\u003e \u003cmodule\u003e   # Run the U2 clerk loop (typecheck + test + diagnostics)\n```\n\nTest fixtures (`.catala_en` peers under `specs/tests/`) are authored by the `/catala-emit-tests` AI sub-skill — invoked automatically from `/create-tests` and `/expand-tests`, or standalone after manual YAML edits. Emission is AI work; there is no equivalent `xlator` CLI subcommand.\n\n### Demos\n\n```bash\nxlator catala-demo  \u003cdomain\u003e \u003cmodule\u003e    # Start Catala-Python demo (foreground)\n```\n\n### Utilities\n\n```bash\nxlator graph              \u003cdomain\u003e \u003cmodule\u003e   # Generate computation graph + Mermaid diagram (catala_depgraph.py)\nxlator evaluate-catala    \u003cdomain\u003e \u003cmodule\u003e   # Deterministic evaluator (catala interpret --output-format=json wrapper)\n```\n\n**Quick start with the AK DOH domain:**\n\n```bash\nxlator catala-pipeline ak_doh eligibility     # typecheck + transpile YAML tests + clerk test\nxlator catala-demo ak_doh eligibility         # Launch interactive demo at localhost\n```\n\n---\n\n## Project Layout\n\n```\nxlator/\n├── xlator               # Shell wrapper — run this (handles venv activation)\n├── core/                # Shared references: Catala quickrefs, naming-guide\n├── domains/             # Folder containing multiple domains (default is 'domains')\n│   └── \u003cdomain\u003e/        # One folder per policy domain (source of truth)\n│       ├── input/       # Raw policy documents (PDFs, Markdown, HTML)\n│       ├── specs/       # Catala source (.catala_en) + naming-manifest + test YAML\n│       └── output/      # Generated build artifacts (Catala-source copy, *_meta.py, demos)\n├── tools/               # Python pipeline scripts\n├── docs/                # Brainstorms, plans, solutions\n│   ├── brainstorms/\n│   ├── plans/\n│   └── solutions/\n└── .claude/\n    └── skills/          # Claude Code skills (/extract-ruleset, etc.)\n```\n\n### Active Domains\n\nPro-tip: To provide a coding assistant with sample data, create a symlink for the `domains` folder to point to a checkout of https://github.com/navapbc/lockpick-xlator/tree/main/domains.\n\n| Domain | Program | Description |\n|--------|---------|-------------|\n| `snap` | `eligibility` | SNAP federal income eligibility (FY2026) |\n| `ak_doh` | `eligibility`, `exclusion_chain` | Alaska Department of Health programs (multi-module) |\n\n### Adding a domain\n\n```bash\n/new-domain \u003cdomain\u003e     # Creates domains/\u003cdomain\u003e/{input/policy_docs,specs,output}\n```\n\n---\n\n## `tools/` Scripts\n\n| Script | Action | Purpose |\n|--------|--------|---------|\n| `clerk_loop.py` | `clerk-loop` | Runs `clerk typecheck` + `clerk test`, parses GNU-format diagnostics, performs naming-manifest divergence check, returns structured outcome (`status: \"ok\" \\| \"unresolved\"`, `repair_history`). Library API used by authoring skills' post-emission step. |\n| `catala_eval.py` | `evaluate-catala` | Thin wrapper around `catala interpret --output-format=json`. Preserves the JSON contract consumed by `/expand-tests`, `/detect-stale-cases`, `/create-tests`. |\n| `xl-plugin/skills/catala-emit-tests/SKILL.md` | *(slash-command `/catala-emit-tests`)* | YAML test cases → Catala `#[test]` scopes. AI sub-skill (v14.0.0+); reads the Catala source for scope-input shape and the naming-manifest for leaf-field type metadata. |\n| `catala_depgraph.py` | `graph` | Computation-graph generator (Catala-native). Produces `.graph.yaml` and `.mmd`. |\n| `catala_to_python.sh` | *(via /create-demo)* | Catala → Python transpiler (invokes `clerk` build). |\n| `merge_naming_manifest.py` | `merge-naming-manifest` | Merges per-emission manifest deltas with the analyst-authoritative source. |\n| `load_extraction_context.py` | `load-extraction-context` | Pre-flight context loader for `/extract-ruleset` (manifest + guidance + facets). |\n| `detect_stale_cases.py` | `detect-stale-cases` | Detects test cases whose expected outcomes diverge from the live Catala source. |\n| `check_freshness.py` | `check-freshness` | Per-tier drift detection between `specs/*.catala_en` and `.catala-manifest.yaml`. |\n| `record_tier_manifest.py` | `manifest-update` | Refresh SHAs in the per-tier manifest files. |\n| `apa_html_to_md.py` | *(utility)* | Scrapes Alaska APA manual HTML → Markdown for input collection. |\n\nAll tools can be run directly:\n\n```bash\nuv run xl-plugin/tools/clerk_loop.py snap eligibility \\\n  --module-path domains/snap/specs/eligibility.catala_en\nuv run xl-plugin/tools/catala_eval.py snap eligibility --inputs case.json\n```\n\n---\n\n## `core/` Reference Files\n\n| File | Description |\n|------|-------------|\n| `catala-authoring-quickref.md` | AI-targeted Catala authoring reference: scopes, contextual definitions, exceptions, modules, comprehensions, denial_reasons idiom, fence visibility, common AI failure modes |\n| `catala-quickref.md` | General Catala 1.1.0 syntax patterns |\n| `catala-test-quickref.md` | Catala `#[test]` annotation patterns |\n| `naming_guide.md` | Static style rules for canonical identifier names (fallback under the authority chain) |\n| `ruleset-shared.md` | Shared procedures (`SP-LoadNamingManifest`, `SP-LoadInputIndex`, etc.) consumed by every authoring skill |\n| `output-fencing.md` | Semantic fence-block convention (`:::important`, `:::error`, etc.) for skill output |\n| `proposed_transpilation_fixes_snapshot.md` | Recovered AI-failure-mode catalogue (six categories) that drives `catala-authoring-quickref.md` |\n| `tests/fixtures/` | Persistent Catala fixtures used by `clerk_loop` test suite and U9 verification gates |\n| `guidance-examples/` | Reference examples of populated `guidance/` files — illustrative only; no skill copies from this directory |\n\n---\n\n## Claude Code Slash Commands\n\nUsed for AI-assisted domain work. Run from within Claude Code (VS Code extension or CLI).\n\n| Command | Purpose |\n|---------|---------|\n| `/new-domain` | Scaffold a new domain folder structure |\n| `/index-inputs` | Build a reading index from large policy documents |\n| `/refine-guidance` | Tune AI extraction guidance under `guidance/` |\n| `/extract-ruleset` | Emit `specs/\u003cmodule\u003e.catala_en` from policy docs; runs clerk-loop post-emission |\n| `/update-ruleset` | Update an existing Catala source with changed policy rules; Step 0 divergence check |\n| `/create-tests` | Generate YAML test cases for a Catala module |\n| `/expand-tests` | Add boundary, edge-case, and null-input tests via `catala_eval` |\n| `/review-ruleset` | Refresh graph artifacts; capture guidance learnings |\n| `/check-freshness` | Detect drift between input data and downstream artifacts |\n| `/create-demo` | Create a Catala-Python demo app |\n\n---\n\n## Typical Development Workflow\n\n### Edit an existing domain\n\n```bash\n# 1. Drive /update-ruleset to apply a policy-doc change\n/update-ruleset \u003cdomain\u003e \u003cmodule\u003e\n\n# 2. Run the pipeline (typecheck + test transpile + clerk test)\nxlator catala-pipeline \u003cdomain\u003e \u003cmodule\u003e\n\n# 3. (Optional) Regenerate computation graph\nxlator graph \u003cdomain\u003e \u003cmodule\u003e\n```\n\n### Adding a new domain from policy docs\n\n```bash\n# 1. Scaffold the folder\n/new-domain \u003cdomain\u003e\n\n# 2. Drop policy documents into:\n#    domains/\u003cdomain\u003e/input/policy_docs/\n\n# 3. Index inputs (for large docs)\n/index-inputs \u003cdomain\u003e\n\n# 4. Refine guidance (orchestrated or step-by-step)\n/refine-guidance \u003cdomain\u003e\n\n# 5. Extract ruleset (emits Catala via the clerk-loop)\n/extract-ruleset \u003cdomain\u003e\n\n# 6. Create test cases\n/create-tests \u003cdomain\u003e \u003cmodule\u003e\n\n# 7. Run the full pipeline\nxlator catala-pipeline \u003cdomain\u003e \u003cmodule\u003e\n```\n\n---\n\n## Architecture Notes\n\n- **Catala is the authored source format** as of v13.0.0. `domains/\u003cd\u003e/specs/\u003cmodule\u003e.catala_en` is the human-+-AI-authored truth; `domains/\u003cd\u003e/output/\u003cmodule\u003e.catala_en` is a copy of the source maintained by the build step for consumer compatibility (`catala_depgraph.py`, the FastAPI demo, and other build-artifact consumers continue reading from `output/`).\n- **Two-phase authoring discipline.** Deterministic Python tools handle pre-flight context loading and post-emission verification; the AI emits Catala content. The clerk-loop (`xl-plugin/tools/clerk_loop.py`) runs `clerk typecheck` + `clerk test` after each AI emission and self-repairs before SME handoff.\n- **Naming-manifest authority chain (two-tier).** `specs/naming-manifest.yaml` (analyst-authoritative, includes per-field types as of U7) → `core/naming_guide.md` (static style rules). The manifest carries identifier names AND leaf-field types so test-emission consumers (`/catala-emit-tests`, the CSV import/export tools) can render correct literals; the Catala source — not the manifest — is the authority for scope-input layout.\n- **`policy_facets/` folder (per-domain).** Each domain has a `policy_facets/` folder for derived views of its policy docs:\n  - **`policy_facets/compressed/`** — caveman-compressed mirror of `input/policy_docs/`, produced by `/index-inputs`. Downstream skills (`/extract-ruleset`, `/update-ruleset`) read these files for content.\n  - **`policy_facets/computations/`** — per-source-file YAML lists of `{heading, summary, tags, computations?}` section blocks. Catala authoring uses these section blocks to mirror Markdown `## Heading` structure inside the literate `.catala_en` source.\n\n  `input-index.yaml` (files block: SHAs, md_quality scores) also lives in `policy_facets/`.\n\n- **v14.0.0 — replaced the deterministic test-fixture transpiler with the `/catala-emit-tests` AI sub-skill.** `.catala_en` test fixtures relocated from `output/tests/` (build-time output) to `specs/tests/` (authored, checked into git). The post-cutover pipeline is `copy-source-to-output → clerk typecheck → clerk test` (the `catala-test-transpile` step is gone). Existing `output/tests/*.catala_en` files are discarded on next pipeline run — no migration shim per the \"Don't migrate old files\" rule. **Rollback recipe:** `git revert \u003cU8-squashed-commit\u003e` restores the deterministic transpiler script and its CLI subcommand; re-publish at `v13.0.3` (PATCH over v13.0.2). A `pre-test-transpile-retirement` git tag at the pre-cutover HEAD serves as the durable rollback anchor.\n\n---\n\n## Key Files at a Glance\n\n| File | Role |\n|------|------|\n| `xl-plugin/bin/xlator` | Entry point — always run this |\n| `xl-plugin/tools/clerk_loop.py` | clerk-loop library + CLI (authoring skills' post-emission verification) |\n| `xl-plugin/tools/catala_eval.py` | Deterministic Catala evaluator |\n| `xl-plugin/skills/catala-emit-tests/SKILL.md` | AI sub-skill that emits `.catala_en` test fixtures from YAML test cases (v14.0.0+) |\n| `xl-plugin/core/catala-authoring-quickref.md` | AI-targeted Catala authoring reference |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnavapbc%2Flockpicks-xlator-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnavapbc%2Flockpicks-xlator-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnavapbc%2Flockpicks-xlator-plugin/lists"}