C5. `bundlemap.build_map` lists a bundle in its own words: one line per source document -- its name, then the titles of its concepts in document order -- and documents whose names differ only in their numbers (a changelog per release, a note per week) as ONE line: the name with every number as `#`, the count, the first and last by natural order, and the titles across the series that are words. `SERIES_MIN` = 5, at most `TITLES_PER_LINE` = 24 titles a line, the lines capped at `MAP_MAX_BYTES` = 48 000 together with `lines_truncated` counting the rest. Derived on every call, never stored. The card (`okf card`, `okf_describe`) carries it as `map` and no longer carries `source_files`: that list named every document a second time with no series collapsed, a quarter of the reply on a large bundle, for names the map already carries. Chose removal over keeping both because the describe reply has to fit a client's tool-reply limit and the map says more. The working method now reads: take the map first (`okf card`, or `okf_describe`), write two to four sub-questions in its words, and send them in ONE call (`--question` repeated, or `okf_ask` `questions`). Changed in the skill template, the generated `skills/okf-consume`, and the server instructions (held under the 2 KB a client keeps). The regeneration recipe for `skills/okf-consume` gains `--for-bundle`: since v1.1 the generator writes the generic skill by default, so the recipe as published produced the other file. A test holds a four-sub-question `okf_ask` over concepts far over the passage size under 50 000 bytes of reply text (25 000 tokens at a pessimistic two bytes a token). The real-collection measurements are kept in local state. Suite on a clean tree after `git add`: 2429 passed, 2 skipped, 4 xfailed. ruff, ruff format, mypy --strict clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| example-payload.json | ||
| README.md | ||
References
example-payload.json is a real payload, not an illustration, and
../SKILL.md is the skill generated for the same bundle. Both come from the
three-concept golden bundle that ships in this repository,
examples/ingest-golden-segmented-okf-v0-2/expected-bundle, so anyone reading
this file can regenerate them byte for byte and compare. Neither carries content
from any corpus.
Regenerate them from the repository root rather than editing either file, with
okf being this checkout's own install (for example .venv/bin/okf):
okf skill examples/ingest-golden-segmented-okf-v0-2/expected-bundle \
--out skills/okf-consume --force --for-bundle \
--example-question "Hva sier veiledningen om krav?"
python3 -c 'import os, pathlib; p = pathlib.Path("skills/okf-consume/SKILL.md"); p.write_text(p.read_text(encoding="utf-8").replace(os.path.realpath(".") + "/", ""), encoding="utf-8")'
okf check --skill skills/okf-consume/SKILL.md \
--payload skills/okf-consume/references/example-payload.json
Why each part is there:
--for-bundle: since v1.1 the generator writes the GENERIC skill by default; this copy is the instantiated one, for this bundle.--force: the generator refuses to replace an existingSKILL.md(refused (target_occupied)), because a silent overwrite would destroy a hand-edited copy.--example-question: without it the question is derived from the bundle's own titles and the payload is a different one.tests/test_okf_consume.pyasserts this payload byte for byte against the pre-pass for exactlyHva sier veiledningen om krav?, so the question is part of what the file is.- The
python3line:okf skillwrites the bundle root and the skill's own path absolute when--outis not under.claude/skills/, and this directory is not. Shipped as generated, the two commands inSKILL.mdwould name one checkout on one machine. The line strips that checkout's prefix and nothing else, and a test holds the shippedSKILL.mdto the generator's output with exactly that prefix removed. okf checkshould reportconformant: 17 rules over 3 excerpts and 0 withheld entries, 0 findingsand exit 0.
The generated name is b-golden-segmented-okf-v0-2-consume while this
directory stays skills/okf-consume/. Claude Code takes a project or personal
skill's command from its directory name and uses name as a display label, so
a copy placed at .claude/skills/okf-consume/ is still /okf-consume.
The payload is here so that its shape can be read without running anything, and
so that a reader can see what the members the contract does not name look like in
practice: text and text_sha256 on every excerpt (§ 8 permits additional
members; § 1 defines an excerpt as delivered content, and without a body the
budget gate would measure a skeleton), rank, bundle_id_inherited, and the
raw_bytes/encoding_delta pair that gives the known-positive a second,
independent check.