Skip to main content

chunk-text-extraction

Deterministically slice a mainframe or IBM i (AS400) source file (COBOL, CBLLE, SQLCBLLE, CL, CLP, CLLE, JCL, PROC, copybook, BMS) into one raw-text file per chunk. USE FOR: extract CL or COBOL chunks as txt and prepare source text for section-doc-writer. DO NOT USE FOR: chunking, facts extraction, facts slicing, copybook expansion, or markdown generation.

Source facts

Repository
microsoft/cobol-docs-pipeline-sample
Last source activity
July 16, 2026 at 08:28
Detected SKILL.md language
English
Stars
1
Forks
3

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
4 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
chunk-text-extraction
description
Deterministically slice a mainframe or IBM i (AS400) source file (COBOL, CBLLE, SQLCBLLE, CL, CLP, CLLE, JCL, PROC, copybook, BMS) into one raw-text file per chunk. USE FOR: extract CL or COBOL chunks as txt and prepare source text for section-doc-writer. DO NOT USE FOR: chunking, facts extraction, facts slicing, copybook expansion, or markdown generation.
argument-hint
Path to a source file (e.g. repos/sample1/COBOL/DEMO100.CBL). Optional --chunk-id <id> for one chunk, --output-dir to override, --manifest to override, --prune to drop stale .txt files, --source-root override.
# Chunk Text Extraction Deterministic phase-B sibling. Reads a source file + its `chunk-manifest.json` and emits one raw-text file per chunk under `docs/_shared/<basename-with-ext>/chunks/<chunk_id_sanitized>.txt`. No LLM calls — pure byte/line slicing, sha-gated against stale manifests. The `.txt` files are the **only** raw-source view a downstream per-section subagent (section-doc-writer, qa-reviewer) needs. They sit beside `facts-slices/` so a phase-C agent for chunk `X` reads exactly two files: its slice JSON and its `.txt`. ## When to Use - The user asks to "extract chunks as txt", "save each chunk to a file", "dump chunk source", or "give me the source for chunk_id X". - Phase A has just (re-)written a `chunk-manifest.json` and the matching `chunks/` directory is missing or stale (different source `sha256`). - A single chunk needs to be re-extracted on demand (`--chunk-id <id>`). - Preparing per-section inputs before launching phase-C subagents. Do **not** use this skill for chunking ([`cobol-chunking`](../cobol-chunking/SKILL.md)), facts extraction ([`cobol-facts-extraction`](../cobol-facts-extraction/SKILL.md)), per-chunk facts slicing ([`facts-slicing`](../facts-slicing/SKILL.md)), markdown writing (phase C), or copybook *expansion*. ## Output Contract One UTF-8 text file per chunk at `docs/_shared/<basename-with-ext>/chunks/<chunk_id_sanitized>.txt`. - `<chunk_id_sanitized>` = `chunk_id.replace("/", "__")` — the default transformation. Same rule as `facts-slicing`. - **Duplicate-chunk-id disambiguation.** Phase A *should* guarantee unique chunk ids; some real-world manifests violate that (e.g. two `data-division/FILLER` records at different line ranges). On collision, the second+ occurrence is suffixed with `__L<start_line>` (and `_<n>` if even that collides) and a `DUPLICATE_CHUNK_ID` entry is recorded in `errors[]`. The authoritative chunk-id → filename map is always `index.json::chunks[].file` — downstream agents MUST read that, not re-derive the filename from the chunk id. - Body = the raw source bytes for the inclusive 1-based line range `[chunk.start_line .. chunk.end_line]` from the manifest, decoded with the manifest's `encoding_detected` (default `utf-8`). - Line endings are normalized to `\n` to keep re-runs byte-identical across OSes; the original column content (including significant trailing spaces inside columns 8–72) is preserved verbatim. - No header, no chunk-id banner, no line-number gutter. The companion slice JSON already carries `chunk.start_line` / `chunk.end_line`. - Empty chunks (`start_line == end_line + 1` due to upstream parsing edge cases) produce a zero-byte file and a single `errors[]` entry on stdout, but still write the file. Alongside the per-chunk files, a single index is emitted at `docs/_shared/<basename-with-ext>/chunks/index.json`: ```jsonc { "index_version": "1.0", "source_path": "repos/sample1/COBOL/DEMO100.CBL", "source_sha256": "<64-hex>", // copied from manifest "manifest_sha256": "<64-hex of the chunk-manifest.json bytes>", "encoding": "utf-8", "chunks": [ { "id": "DEMO100/procedure-division/MAIN-PROCESSING/A000-MAIN", "file": "DEMO100__procedure-division__MAIN-PROCESSING__A000-MAIN.txt", "start_line": 22, "end_line": 26, "line_count": 5, "byte_count": 187, "sha256": "<64-hex of the emitted .txt bytes>" } /* one per chunk, sorted by start_line */ ], "errors": [] } ``` `chunks[].sha256` is the integrity gate downstream consumers use to detect a stale `.txt` without re-reading every file. ## Procedure 1. **Resolve inputs.** Locate the source file (same rules as upstream skills: relative to repo root first, then to `source_root` from `config/sources.yaml`). Default manifest is at `docs/_shared/<basename-with-ext>/chunk-manifest.json`. Reject if either is missing. 2. **Stale-input check.** Hash the source bytes on disk and compare with `chunk-manifest.json::sha256`. On mismatch: exit code `4`, error on stderr, **no `.txt` written**. Re-run `cobol-chunking` first. 3. **Run the extractor.** Invoke [scripts/extract-chunks.py](./scripts/extract-chunks.py): ```powershell python .github/skills/chunk-text-extraction/scripts/extract-chunks.py ` --source repos/sample1/COBOL/DEMO100.CBL ``` Flags: - `--chunk-id <id>` — extract ONLY that chunk (must exist in the manifest); default is all chunks. - `--output-dir <path>` — override `docs/_shared/<basename-with-ext>/chunks`. - `--source-root <root>` — override `sources.yaml::source_root`. - `--manifest <path>` — override the default chunk-manifest location. - `--prune` — delete any pre-existing `.txt` in the output directory whose chunk id is NOT in the current manifest (default: keep stale files and warn). - `--no-index` — skip writing `index.json` (useful when extracting a single chunk on demand). 4. **Report.** The script prints `OK: wrote N chunks to <dir>` plus total `.txt` written / skipped / pruned, the source/manifest sha256 prefixes, and any entries from `errors[]`. Do not echo the chunk bodies. ## Batch / Parallel Extraction When the user asks to extract chunks for **more than one file**, do **not** loop the python script inline. Use [scripts/extract_chunks_batch.ps1](./scripts/extract_chunks_batch.ps1): ```powershell pwsh -File .github/skills/chunk-text-extraction/scripts/extract_chunks_batch.ps1 ` -Paths repos/sample1/COBOL/*.CBL ``` Parameters (mirrors `cobol-facts-extraction` / `facts-slicing`): - `-Files`, `-Paths`, `-Manifest <json|csv>` — input selection. - `-SourceRoot`, `-OutputDir` — per-run overrides. - `-Prune` — pass `--prune` to every child invocation. - `-Throttle <int>` — defaults to `[Environment]::ProcessorCount`. - `-ResultsXml <path>` — defaults to `chunk_text_results.xml`. - `-ExcludeExtensions <string[]>` — case-insensitive extensions skipped when expanding `-Paths`. Default: `.cob, .inp, .itt` (copybooks and JCL inline-data are consumed by reference upstream, not chunked standalone). The runner is deterministic (sorted inputs/results, no timestamps), captures per-file stdout/stderr/exit, persists results via `Export-Clixml`, and exits `1` if any child failed. **Ad-hoc helpers go in `temp/`.** Same convention as the other phase-B skills. Report only the summary line (`DONE total=… ok=… failed=…`) plus any failures, matching the single-file reporting contract in step 4. ## Determinism Rules - No LLM calls. - Re-running on an unchanged source + manifest pair MUST yield byte-identical `.txt` files AND a byte-identical `index.json` (sorted `chunks[]`, stable key order, no timestamps). - Line endings always normalized to `\n` in the output — the input may be CRLF, LF, or mixed; the emitted bytes are LF-only. - Filename sanitization is `chunk_id.replace("/", "__")` by default. The only non-deterministic-looking case is duplicate chunk ids (a phase-A bug), where the second+ occurrence gets a `__L<start_line>` suffix — still deterministic given the same manifest. Chunk ids that exceed the OS path limit fail loudly with `code=CHUNK_ID_TOO_LONG`. - Stale `source sha256` (manifest vs. on-disk source) is a hard error, not a warning. Extracting against a manifest whose line numbers no longer match the source would silently mis-bind every chunk. - `--prune` is opt-in. Default behavior is additive (write/overwrite per-chunk files; never delete) so a partial run does not destroy a known-good directory. ## Resources - [scripts/extract-chunks.py](./scripts/extract-chunks.py) — the extractor (entry point). - [scripts/extract_chunks_batch.ps1](./scripts/extract_chunks_batch.ps1) — parallel batch runner. ## Pipeline Wiring `config/pipeline-dag.yaml` phase B lists `skills/chunk-text-extraction/scripts/extract-chunks.py` as a sibling of `cobol-facts-extraction`'s `extract-facts.py`. Both run per source after phase A, both consume the same `chunk-manifest.json`, and neither depends on the other — they can be parallelized freely. Outputs land at `docs/_shared/<file>/chunks/<chunk_id>.txt` (with `/` → `__` filename sanitization). ## Common Pitfalls - **Stale manifest.** If the source was edited after `cobol-chunking` ran, the line numbers in the manifest no longer point at the right ranges. Step 2 catches this. Always re-run phase A first. - **Encoding mismatch.** If the manifest claims `utf-8` but the source is actually EBCDIC or CP1252, the extractor will still write bytes — they just may not be human-readable. Trust the manifest's `encoding_detected` and fix it in phase A if wrong. - **CRLF on Windows checkouts.** The extractor reads via universal-newline mode and writes LF, so the output is stable regardless of git's `core.autocrlf` setting. Do not introduce a `--preserve-eol` flag unless a downstream agent explicitly needs it. - **Filename collisions.** Phase A is *supposed* to guarantee unique chunk ids, but some legacy manifests have duplicates. This skill disambiguates by suffixing `__L<start_line>` and emits a `DUPLICATE_CHUNK_ID` error entry. Always look up filenames via `index.json::chunks[].file`, never by re-sanitizing the chunk id, or you will mis-bind to the wrong .txt for duplicated ids. - **`--chunk-id` without `--no-index`.** Extracting one chunk without `--no-index` will overwrite `index.json` with a single-entry file. Pass `--no-index` for surgical single-chunk re-extraction.
View on GitHub