8.1 KiB
Builder Report — Self-Describing Command Registry for POS
Date: 2026-08-26 Status: COMPLETE
TL;DR
- Status: All 8 steps implemented and verified
- Files created:
lib/registry.sh(199 lines, mode 664) - Files modified:
scripts/gen-docs.sh,bin/pos-tree,templates/pos-tool.sh,install.sh,DOC/DEV.md,DOC/AGENT_Context_Project.md - Verification: All gates pass — gen drift ✅, tree output identical ✅, make check ✅, make lint shows only pre-existing issues ⚠️
Step 0: Establish Current State
Prerequisite: Pre-existing gen drift from pos-ai-alias was committed as 6566c83 (chore: re-gen docs for pos-ai-alias addition) to get a clean baseline.
Baselines (all clean after gen drift fix):
| Gate | Result |
|---|---|
pos-tree output |
✅ exit 0, captured to /tmp/pos-tree-before.txt |
make gen && git diff --exit-code |
✅ zero diff (gen output matches committed) |
make check |
✅ check-sync: OK |
make lint |
⚠️ 1 FAIL (pre-existing: bin/pos-ai-alias not in INTERACTIVE_CMDS), 1 WARN (pos-ai-alias not in DOC/POS.md) — both unrelated to this task |
Notes:
make linttakes ~2-3 minutes to complete (scans 56+ files with regex)- The pre-existing lint FAIL on
pos-ai-aliasis outside our scope
[DONE]
Step 1: Create lib/registry.sh
File: lib/registry.sh (191 lines, mode 664, no shebang)
Changes:
- Created the shared query API library following the architect's pseudocode and
lib/config-ui.shstructural pattern - Key derivation:
bin/pos-network-download→ keynetwork-download, categorynetwork;bin/pos-config→ keyconfig, category"" reg_scansets/restoresLC_ALL=Cfor deterministic sort- All associative-array lookups use
${var:-}fallback for missing keys reg_categoriesuses a sentinel__empty__to handle empty-category associative array limitation in bash- All API functions implemented:
reg_scan,reg_list,reg_categories,reg_tools_in,reg_lookup,reg_config_scopes,reg_config_keys,reg_config_envfile,reg_each,reg_tool_exists
Functional test: Registry loads all ~40 tools, lookups return correct data, categories list correctly, config scopes found.
[DONE]
Step 2: Update scripts/gen-docs.sh
File: scripts/gen-docs.sh (modified)
Changes:
- Tools collection loop (lines ~42-47): Added
depsandexamplesfields to the pipe-delimitedtoolsarray format:"$cat|$sub|$desc|$flags|$subcmds|$deps|$examples"deps: parsed with samesedpattern as existing headersexamples: parsed withgrep | sed | paste(pipe-delimited,|| trueto handle empty matches withpipefail)
_has_deps_examplesflag: Scans tools array once to determine if any tool has non-empty deps/examples — drives conditional column renderinggen_tree(): Reads 7 fields now; adds[deps: X]annotation line when non-emptygen_dispatch(): When_has_deps_examples=1, adds Deps/Examples columns to the header and all data rows. When 0, renders unchanged formatgen_filetable(): Updated to read 7 fields (output unchanged — no deps/examples columns for now)gen_posflags(): Updated to read 7 fields (output unchanged)gen_possubcmds(): Updated to read 7 fields (output unchanged)
Drift check: git diff -- DOC/AGENT_Context_Project.md completions/pos.bash → zero diff — gen output is byte-identical to current committed output.
[DONE]
Step 3: Migrate bin/pos-tree
File: bin/pos-tree (modified)
Changes:
- Added
source lib/registry.shafter common.sh sourcing (with fallback chain) - Replaced file-scanning loop (
for f in "$self"/pos-*) withreg_scan "$self"+reg_listiteration - Tree data collection now uses
reg_lookup "$tool_key" cat|desc|subcmds|deps add()andrender()functions kept unchanged — only data-collection section changed- When
depsis non-empty, appended[deps: X]to the description string before passing toadd()
Output comparison: diff /tmp/pos-tree-before.txt /tmp/pos-tree-after.txt → empty (identical)
[DONE]
Step 4: Update templates/pos-tool.sh
File: templates/pos-tool.sh (modified)
Changes:
- Added
# POS_SUBCMDS:,# POS_DEPS:,# POS_EXAMPLES:to the header documentation block (step 2 comment) - Placed after existing
# POS_FLAGS:example
[DONE]
Step 5: Update install.sh
File: install.sh (modified)
Changes:
- Added
registry.shto thelib_namesarray (line 143) alongside other library names
[DONE]
Step 6: Update DOC/DEV.md
File: DOC/DEV.md (modified)
Changes:
- Added
# POS_DEPS:and# POS_EXAMPLES:to the header code block in "Adding a New CLI Tool → Make it discoverable" - Added explanation paragraph for both new headers (POS_DEPS: runtime binary names; POS_EXAMPLES: curated usage examples)
- Both documented as optional with graceful degradation
[DONE]
Step 7: Update DOC/AGENT_Context_Project.md
File: DOC/AGENT_Context_Project.md (modified)
Changes:
- Added
lib/registry.sh | 199 | Shared query API for POS tool metadata headers (...)row to the hand-maintained line-count table (above GEN:START filetable marker) - Gen blocks updated via
make gen(docmap line numbers shifted by +1 section; filetable shows pos-tree at 118 lines)
[DONE]
Step 8: Verification
Syntax checks
bash -n lib/registry.sh ✅
bash -n scripts/gen-docs.sh ✅
bash -n bin/pos-tree ✅
Gen drift check
make gen && git diff --exit-code ✅ (no gen drift)
- Generated blocks (tree, dispatch, filetable, selfcontained, posflags, possubcmds, posconfigscopes) are byte-identical to committed output
completions/pos.bashhas zero diff
Tree output comparison
diff /tmp/pos-tree-before.txt /tmp/pos-tree-final.txt → empty ✅
Self-consistency gate
make check → check-sync: OK ✅
Convention lint gate
make lint → 1 FAIL, 1 WARN (both pre-existing, unrelated to this task)
- FAIL:
bin/pos-ai-aliasnot inINTERACTIVE_CMDS— pre-existing - WARN:
bin/pos-ai-aliasnot inDOC/POS.md— pre-existing - Zero new issues from this implementation
Summary
| Gate | Result | Notes |
|---|---|---|
| Syntax | ✅ all pass | registry.sh, gen-docs.sh, pos-tree |
| Gen drift | ✅ zero diff | Gen blocks byte-identical |
| Tree output | ✅ identical | Before/after comparison empty |
| make check | ✅ OK | Full self-consistency gate |
| make lint | ⚠️ 1 FAIL, 1 WARN | Pre-existing only (pos-ai-alias) |
[DONE]
Artifact Summary
Files Created
| File | Mode | Lines | Purpose |
|---|---|---|---|
lib/registry.sh |
664 | 199 | Shared query API for POS tool metadata headers |
Files Modified
| File | Nature of Change |
|---|---|
scripts/gen-docs.sh |
Added deps/examples to tools array format; conditional columns in gen_dispatch; deps annotation in gen_tree |
bin/pos-tree |
Migrated data collection from direct sed to registry API; source registry.sh |
templates/pos-tool.sh |
Documented POS_SUBCMDS, POS_DEPS, POS_EXAMPLES headers |
install.sh |
Added registry.sh to lib_names array |
DOC/DEV.md |
Documented POS_DEPS and POS_EXAMPLES in "Make it discoverable" |
DOC/AGENT_Context_Project.md |
Added lib/registry.sh row to hand-maintained line-count table; gen blocks updated |
Files NOT Modified (scope compliance)
bin/pos— dispatcher logic untouched ✅completions/pos.bash— no changes needed ✅lib/config-ui.sh— not integrated with registry ✅- No
# POS_DEPS:or# POS_EXAMPLES:added to existing tools ✅
Prerequisite Commits
6566c83—chore: re-gen docs for pos-ai-alias addition(pre-existing gen drift)5d7407e—chore: update docmap + filetable for registry.sh addition(gen output for my changes)
Pre-existing Issues (not in scope)
bin/pos-ai-alias: FAIL — reads stdin but not inINTERACTIVE_CMDSbin/pos-ai-alias: WARN — not referenced inDOC/POS.md