mit einem Klick
index-inputs
Index Input Policy Documents
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Menü
Index Input Policy Documents
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Basierend auf der SOC-Berufsklassifikation
Emit Catala
Create Sample Tests
Draft or Update Test Cases
Expand Test Coverage
Extract Test Cases from Policy Documents
Generate a Demo App (Catala-Python Backend)
| name | index-inputs |
| description | Index Input Policy Documents |
Scan a domain's input/policy_docs/ directory and produce:
policy_facets/input-index.yaml — metadata only: the files: block (SHAs, md_quality scores). Always small. Fully rewritten on every run.policy_facets/compressed/<rel>.md (one file per source doc) — caveman-compressed (token-reduced) mirrors of input/policy_docs/<rel>.md. Generated by /compress-input per file as part of the unified per-file batch and consumed by downstream skills (/extract-ruleset, /update-ruleset).policy_facets/computations/<rel>.md.yaml (one file per source doc) — per-file YAML map {sections} of {heading, summary, tags, stage?, stage_source?, computations} blocks. Each computations[] entry carries description:, optional preconditions:, and an optional expr_hint: of the form output_name = <expression>. Generated by /extract-computations per file as part of the unified per-file batch.Per-file work is dispatched as a bounded fan-out of subagent workers — each worker reads one source file and runs all applicable per-file actions for that file (compress + extract) in the same context. Action outcomes are recorded as per-file marker files under policy_facets/.compress-plan.d/ and policy_facets/.extract-plan.d/; the matching xlator <tool> --finalize collates markers and updates the manifests. Concurrency is bounded by the XLATOR_AI_CONCURRENCY environment variable (default 3); the analyst can raise it once their Anthropic-tier rate-limit headroom is confirmed.
On first run (CREATE), all files are dispatched and every per-file output is generated. On subsequent runs (UPDATE), only changed or new files are re-processed using git SHA comparison; unchanged files are left alone via the per-action manifests.
/index-inputs <domain>
If <domain> is not provided, list all $DOMAINS_DIR/*/input/policy_docs/ directories as a numbered menu, prompt the user to choose, await their response, and use it as <domain> before continuing.
Read ../../core/output-fencing.md now.
Run these checks before doing anything else:
Domain argument provided?
$DOMAINS_DIR/*/input/policy_docs/ as a numbered menu and prompt:
:::user_input
Available domains:
<domain>. Then continue.Domain folder exists?
Input docs present?
$DOMAINS_DIR/<domain>/input/policy_docs/ missing or contains no .md files →
:::error
No input documents found. Add .md files to $DOMAINS_DIR//input/policy_docs/ and re-run.
:::
Then stop.Input files committed to git?
Check for uncommitted changes (modified, staged, untracked) under $DOMAINS_DIR/<domain>/input/:
git -C "$DOMAINS_DIR/<domain>" status --porcelain -- input/
git status --porcelain>
Commit them now? [y/n]
:::
y: stage and commit only those paths with message chore(<domain>): commit input files for indexing, e.g.:
git -C "$DOMAINS_DIR/<domain>" add -- input/
git -C "$DOMAINS_DIR/<domain>" commit -m "chore(<domain>): commit input files for indexing"
Then continue.n: continue without committing. SHA detection via git hash-object still picks up working-tree edits, but the source state is not preserved in history.policy_facets/CLAUDE.md noticeEnsure policy_facets/ exists and overwrite its CLAUDE.md from the static template so the folder identifies itself as derived (not original) for any agent that walks into it:
mkdir -p "$DOMAINS_DIR/<domain>/policy_facets/"
cp "$CLAUDE_PLUGIN_ROOT/core/policy_facets_claude.md" "$DOMAINS_DIR/<domain>/policy_facets/CLAUDE.md"
The template is overwritten on every run so edits to xl-plugin/core/policy_facets_claude.md propagate without an extra command.
Run BOTH per-action plans up-front:
xlator compress-inputs <domain> --plan
xlator extract-computations <domain> --plan
Each emits its own work plan as JSON. The shapes are:
// xlator compress-inputs --plan
{
"to_compress": [ {"src": "...", "dst": "...", "source_sha": "..."}, ... ],
"to_delete": [ "policy_facets/compressed/<rel>.md", ... ],
"noop": [ {"src": "...", "reason": "unchanged"}, ... ],
"skipped": [ {"src": "...", "reason": "not_allowed"}, ... ]
}
// xlator extract-computations --plan
{
"to_extract": [ {"src": "...", "dst": "...", "source_sha": "..."}, ... ],
"to_delete": [ "policy_facets/computations/<rel>.md.yaml", ... ],
"noop": [ {"src": "...", "reason": "unchanged"}, ... ],
"skipped": [ {"src": "...", "reason": "not_allowed"}, ... ]
}
Capture both JSON outputs. Build the unified per-file action map: for each source rel that appears in compress.to_compress ∪ extract.to_extract, record the action set as the subset that applies — ["compress"], ["extract"], or ["compress", "extract"]. Files appearing in neither plan's to_* list (i.e., both manifests classify them as noop) are not dispatched in Step 5 — they are already in sync.
Each --plan invocation also creates an empty .compress-plan.d/ and .extract-plan.d/ directory under policy_facets/ (clearing any stale markers from a prior crashed run). Workers in Step 5 write their per-file outcome markers there.
/index-inputs itself continues to scan input/policy_docs/ for SHA and md_quality scoring — its index reflects the source files, not the compressed copies and not the computations files.
ls $DOMAINS_DIR/<domain>/policy_facets/input-index.yaml 2>/dev/null
| Result | Mode |
|---|---|
| File absent | CREATE — index all files from scratch |
| File present | UPDATE — re-index changed/new files only |
The minimum acceptable quality score is 40 (out of 100). Files scoring below this threshold are REJECTED: they are moved to $DOMAINS_DIR/<domain>/input/rejected/ (preserving subdirectory structure) and no per-file output is generated for them. The md_quality: field in the files: block explains the rejection.
Read XLATOR_AI_CONCURRENCY from the environment; default to 3 if unset. This is the number of subagent workers that run in parallel per batch in Step 5.
K="${XLATOR_AI_CONCURRENCY:-3}"
A value of 3 is conservative across Anthropic tiers and stays well within typical analyst rate-limit headroom. The analyst can raise it (e.g., XLATOR_AI_CONCURRENCY=8) once their tier confirms more capacity. There is no explicit 429 retry/backoff in v1 — if rate-limit errors surface, lower the value or set it to 1.
Glob all .md files recursively under $DOMAINS_DIR/<domain>/input/policy_docs/. Sort alphabetically by path.
:::progress Found document(s). Indexing all... :::
For each file, run:
git hash-object $DOMAINS_DIR/<domain>/<domain-relative-path>
git hash-object returns the blob SHA of the file's current content (working-tree state), so the SHA changes whenever the file's bytes change — independent of whether the file is tracked or committed. This is the comparison key the per-action manifests use to decide SKIP vs REINDEX.
If git hash-object itself fails (e.g., git unavailable), use "untracked" and the file will be re-indexed on every run.
After obtaining each file's SHA, score it:
xlator rate-md-quality "$DOMAINS_DIR/<domain>/<domain-relative-path>"
Store the JSON result {"score": N} or {"score": N, "flags": [...]} alongside the SHA.
input-index.yamlEnsure $DOMAINS_DIR/<domain>/policy_facets/ exists (Pre-step B's --plan calls already created policy_facets/computations/ and policy_facets/compressed/). Write the following to $DOMAINS_DIR/<domain>/policy_facets/input-index.yaml (this creates or overwrites the file):
# Auto-generated by /index-inputs — do not edit manually
files:
input/policy_docs/<file1>.md:
sha: "<sha>"
md_quality:
score: <N>
flags: [<flag1>, <flag2>]
input/policy_docs/<file2>.md:
sha: "<sha>"
md_quality:
score: <N>
"input/policy_docs/<file with spaces>.md":
sha: "<sha>"
md_quality:
score: <N>
YAML conventions for the files: block:
"input/policy_docs/441-1 EARNED INCOME.md":)sha: values as quoted stringsmd_quality: sub-block with score: as an unquoted integerflags: as an inline bracket list (e.g., flags: [no_headings, repeated_page_headers]) — omit the flags: line entirely when there are no flags (do not emit flags: [])Important: Write each file's entry to the files: block one at a time (not all files in a single output block) to avoid hitting the 32k output token limit.
Run the rejection script, passing the domain directory and the quality threshold:
xlator reject-low-quality-inputs "$DOMAINS_DIR/<domain>" 40
The script reads the files: block just written, moves every file whose md_quality.score is below 40 from input/policy_docs/ to input/rejected/ (preserving subdirectory structure), and returns a JSON result:
{"moved": <R>, "files": ["input/policy_docs/<file>.md", ...]}
Capture <R> (the moved count) for the completion message.
Filter the unified action map (built in Pre-step B) to remove REJECTED sources — they have been moved to input/rejected/ by Step 4 and are no longer at their input/policy_docs/ paths. For each REJECTED file, emit:
:::progress Skipped (low quality, score=): input/policy_docs/.md :::
For the remaining sources, sort by source path for deterministic batch composition. Dispatch in batches of K (the concurrency cap). Each batch is a single assistant turn with K parallel Agent-tool calls using subagent_type: index-inputs-worker (defined at xl-plugin/agents/index-inputs-worker.agent.md); wait for the batch to return before issuing the next.
Each Agent call's prompt is the per-invocation context block the worker expects:
source_path: <abs path under input/policy_docs/<rel>.md>
domain_dir: <abs path under $DOMAINS_DIR/<domain>>
source_sha: "<sha>" or "untracked"
actions: <subset of [
{name: "compress", skill: "/compress-input", marker_path: "<domain_dir>/policy_facets/.compress-plan.d/<rel>.md.outcome.json", dst: "<domain_dir>/policy_facets/compressed/<rel>.md"},
{name: "extract", skill: "/extract-computations", marker_path: "<domain_dir>/policy_facets/.extract-plan.d/<rel>.md.outcome.json", dst: "<domain_dir>/policy_facets/computations/<rel>.md.yaml"}
]>
The agent body owns the per-action loop (write in_progress marker → invoke child skill skipping pre-flight → atomically update marker to succeeded/failed → return one succeeded: or failed: line per action) and the path-discipline guarantee — see xl-plugin/agents/index-inputs-worker.agent.md for the full worker contract.
After each batch returns:
Verify markers on disk for each (src, action) the batch dispatched. If a worker reported succeeded: but the marker is missing or still in_progress, emit:
:::progress
⚠ Worker reported success for but no completed marker — treating as aborted.
:::
The action will surface as aborted in the corresponding --finalize summary.
Emit a :::progress line per per-action outcome (parsed from the worker's return text), e.g.:
:::progress
Compressed: input/policy_docs/.md
Extracted: input/policy_docs/.md
:::
Continue to the next batch.
On any per-action failure, do NOT abort the run — failures are surfaced in Step 6's --finalize summaries.
Run BOTH --finalize commands. They are independent of each other; either order works, but emit each summary as it completes so the analyst sees per-action outcomes incrementally:
xlator compress-inputs <domain> --finalize
Relay its summary inside :::important:
:::important ✓ Compress: compressed, failed, aborted, deleted, unchanged. :::
(Use the actual numbers from the tool's stdout. If <M> or <A> is non-zero, list each failed/aborted source path on subsequent lines.)
xlator extract-computations <domain> --finalize
Relay its summary inside a separate :::important:
:::important ✓ Extract: extracted, failed, aborted, deleted, unchanged. :::
Each --finalize:
.compress-plan.d/ / .extract-plan.d/ directory,in_progress markers for to_* entries as aborted (cleans up the dst since action state is indeterminate),tmp + os.replace),.compress-plan.tmp / .extract-plan.tmp and its .d/ marker dir.If either finalize reports any failed or aborted count > 0, exit non-zero so any caller can decide whether to proceed.
After Step 6 completes, print:
:::important ✓ policy_facets/input-index.yaml written (files block). policy_facets/compressed/ written ( file(s) compressed). policy_facets/computations/ written ( file(s) extracted). file(s) rejected (low quality) and moved to input/rejected/ — re-run after reformatting. :::
Omit the "rejected" line if R = 0.
:::next_step
Next step: /refine-guidance <domain> to set extraction goals and ruleset guidance
:::
Read $DOMAINS_DIR/<domain>/policy_facets/input-index.yaml. Extract the current files: SHA map (including any existing md_quality: values).
Glob all .md files recursively under $DOMAINS_DIR/<domain>/input/policy_docs/. Sort alphabetically by path.
For each current file, run:
git hash-object $DOMAINS_DIR/<domain>/<domain-relative-path>
git hash-object returns the blob SHA of the file's current bytes — modified-but-uncommitted edits produce a new SHA, so changes are detected without requiring a commit. Use "untracked" only if git hash-object itself fails.
For files that will be classified as REINDEX (see Step 4), also score them now:
xlator rate-md-quality "$DOMAINS_DIR/<domain>/<domain-relative-path>"
Store the JSON result alongside the SHA.
For files that will be classified as SKIP (SHA unchanged), use the md_quality: value already stored in the prior index. If the prior index has no md_quality: for a SKIP file (e.g., it was indexed before this feature was added), score it now using the same command.
Compare current files + SHAs against the stored files: block:
| Condition | Classification |
|---|---|
| File in index, SHA unchanged | SKIP — preserve existing per-file outputs and md_quality |
| File in index, SHA changed | REINDEX — re-run any per-file action whose manifest is stale |
| File not in index (new) | REINDEX — run all applicable per-file actions |
| REINDEX file with score < 40 | REJECTED — move to input/rejected/; no per-file outputs |
| File in index but not on disk (deleted) | REMOVE — drop from files:; the per-action manifests' to_delete entries already handled the mirror-deletes via Pre-step B |
:::progress Found document(s): changed/new, unchanged, deleted. Re-indexing file(s)... :::
Same shape as CREATE Step 5. Filter the unified action map (built in Pre-step B) to remove REJECTED sources, sort by source path, dispatch K parallel subagent workers per batch, verify markers post-batch, emit per-action :::progress lines.
REJECTED files (score < 40) are skipped — they produce no per-file outputs. SKIP files are not dispatched — Pre-step B's per-action manifests already classified them as noop for both compress and extract, and their existing per-file outputs remain untouched.
For each REJECTED file, emit:
:::progress Skipped (low quality, score=): input/policy_docs/.md :::
input-index.yaml (files block only)Write the following to $DOMAINS_DIR/<domain>/policy_facets/input-index.yaml (overwrites the existing file):
# Auto-generated by /index-inputs — do not edit manually
# Domain: <domain>
files:
<all current files with their current SHAs and md_quality>
Apply the same YAML conventions as CREATE mode Step 3:
sha: as quoted strings; md_quality: sub-block with unquoted score:; flags: omitted when emptyRun the same rejection script used in CREATE mode:
xlator reject-low-quality-inputs "$DOMAINS_DIR/<domain>" 40
Capture <R> from the JSON result for the completion message.
Same shape as CREATE Step 6: run BOTH xlator compress-inputs <domain> --finalize and xlator extract-computations <domain> --finalize, emit each summary in its own :::important block as it completes, list any failed/aborted source paths. Exit non-zero if either finalize reports any failure or aborted entry.
After Step 8 completes, print:
:::important ✓ policy_facets/input-index.yaml updated (files block). policy_facets/compressed/ updated ( file(s) re-compressed). policy_facets/computations/ updated ( file(s) re-extracted, skipped, removed). file(s) rejected (low quality) and moved to input/rejected/ — re-run after reformatting. :::
Omit the "rejected" line if R = 0.
:::next_step
Next step: /refine-guidance <domain> to set extraction goals and ruleset guidance
:::
policy_facets/computations/<rel>.md.yaml or policy_facets/compressed/<rel>.md — they are derived. Edit the source under input/policy_docs/ and re-run /index-inputs.xlator <tool> --finalize — without it, the per-action manifest is not updated and the next run re-runs every per-file action.files: keys must start with input/policy_docs/, not /Users/... or $DOMAINS_DIR/<domain>/.reject-low-quality-inputs reads policy_facets/input-index.yaml for scores; run it only after CREATE Step 3 / UPDATE Step 6 is complete.noop; touching their per-file outputs burns AI tokens for no gain.files: keys that contain spaces — YAML keys with spaces must be quoted strings.flags: [] for files with no quality flags — omit the flags: line entirely; score: alone is sufficient.files: block must have an md_quality: entry.input/rejected/ before Step 5; no per-file outputs are generated for them.--finalize summaries and exit non-zero so the analyst can address them.XLATOR_AI_CONCURRENCY env var — it's the only rate-limit defense in v1. If 429 errors surface, lower it (or set to 1) and re-run.succeeded: is the worker-LLM-obedience failure mode, surfaced as an aborted action by --finalize.