Skip to content

fix(catalog): discover CLI Reference from both inventories (#285) - #286

Merged
mobileskyfi merged 2 commits into
mainfrom
agent/285-cliref-union-discovery
Aug 12, 2026
Merged

fix(catalog): discover CLI Reference from both inventories (#285)#286
mobileskyfi merged 2 commits into
mainfrom
agent/285-cliref-union-discovery

Conversation

@mobileskyfi

@mobileskyfi mobileskyfi commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

MikroTik reshaped the CLI Reference from module pages into per-command leaf pages whose slug is the CLI path. Fixed upstream in tikoci/rosetta#138 (tikoci/rosetta#137 + tikoci/rosetta#136); this is the centrs half. The catalog audit abort after #279 was correct, and was not an isolated deletion.

1. Discovery is the union of both inventories, not the sitemap

The sitemap serves a branching menu as a trailing-slash category URL with no .md of its own. That menu's own Directory entry is published — at <dir>/<basename>.md (app/app/app.md) — and listed only in llms.txt. Grounded live before touching code:

sitemap pages 814  ∪  derived <dir>/<basename> 256  =  1,070
1,070 + index (glossary prose, no **Type:** entry)  =  1,071 = llms.txt filtered

discoverSlugs now unions both, and a blocking gate asserts every sitemap category dir still contributes its leaf — the same assertion rosetta ships as V-cliref-discovery, so the next reshape fails loudly instead of quietly shrinking the table. A page only one inventory lists is reported, not refused: the union already carries it, so nothing is dropped, and --check fails on the new row anyway.

index is excluded explicitly — it is the argument-type glossary prose and publishes no **Type:** entry, so the loud-fail parser would (correctly) reject it.

Corpus now reconciles with rosetta exactly: 1,070 pages / 1,077 entries.

2. The alias allowlist is empty, and that is the correct state

Re-audited every entry against the corrected inventory: zero of the twenty sources survive; twenty of twenty targets are published outright. The caps-man definition modules, easymesh, serial-interface, ddns, ifaces, queues — all gone from the publication, each now published under its real CLI path.

The machinery stays and stays asserted, because an allowlist that expects zero hits is exactly what should refuse the next one:

The R1 test moved to a synthetic allowlist, since the rule must be provable without a live entry. The product-side anchors stay green for a different reason than before, which is why they stay: /caps-man/acl/access-list is absent and /caps-man/access-list present whichever mechanism is responsible.

The reshape also silently fixed nine doc-spelled paths that were never in the allowlist — /interface/pwr-link/pwr-line/* is now /interface/pwr-line/*.

3. A path published twice as two container kinds is not a contradiction

Seven paths are published twice on one page under different hardware gates. Two of those pairs split Directory against Settings Directory:

## system/health   **Conditions:** !i386                    **Type:** Settings Directory
## system/health   **Conditions:** !i386  **Syscap:** health **Type:** Directory

Both halves say the path is navigation; they differ on whether this hardware's menu holds a single record. The row records what the occurrences agree on, exactly as a disagreed gate is dropped rather than picked — and nothing downstream distinguishes the two (isKnownMenu accepts either). Only a navigation-vs-command split still aborts.

Anchored end-to-end on a new frozen fixture of the real page. "One entry per page" is explicitly not an invariant.

Catalog movement

before after
paths 1,119 1,124
menu / command / settings 563 / 439 / 117 558 / 450 / 116
published-only ungated, ancestry-aware 7 1 (/interface/xfrm)
exactly-matching paths (both) 906 968

42 added, 37 removed, 3 kind refinements, 272 gate changes (the recovered menu leaves carry gates their children inherit).

Corpus differential — 948 scripts, old table vs new

Harness verified by reproducing the #249 figures exactly on the old table before trusting it on the new one.

#249 this PR
stmts 18,648 18,648
argCandidates 14,329 14,336
argReadable 7,385 7,392
abstentions 6,944 6,944 (48.4375%)
ambiguous-statement 91 85
unresolved-statement 3,911 3,910
context-lost 69 83

Six scripts move, and every statement in them is a correction. Seven that read as ambiguous/unknown now resolve and their arguments read (/interface/monitor-traffic, /system/package/apply-changes, /system/package/update/{check-for-updates,download,install}) — the whole of the argCandidates/argReadable gain, with abstentions flat. Five more read the same but with the right verb: /ip hotspot user reset-counters [find …] took hotspot as the verb and now takes reset-counters, which also reclassifies it as a write. No document changes containsWrite verdict. CRUD-verb read rate is bit-identical.

context-lost rising is the resolver withdrawing a certainty claim, not losing ground — it is info severity and marks a statement that resolved correctly while the context was already unknown. All 14 are in one script, a bare list of command paths with no navigation anywhere. Previously /interface/monitor-traffic was unreadable and so might have been an absolute navigation, which R4 has REPLACE the context; certainty was restored on that maybe. Knowing it is a command, the resolver knows it never navigated.

Verification

  • bun run lint, bun test (2,635 pass / 0 fail), bun run build, bun run lint:ci — all green
  • bun run explain:catalog:check against live — committed table matches its two sources
  • Cold live --check is 1m34s (was ~30s), inside the QA job's 10-minute budget — no workflow change needed

Refs: tikoci/rosetta#137, tikoci/rosetta#136, tikoci/rosetta#138, #228, #237, #279.

Closes #285

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Expanded CLI Reference discovery using combined sitemap and llms.txt inventories.
    • Added support for category and command-page validation, duplicate entries, and refreshed command coverage.
    • Added glossary terminology and health-command reference documentation.
  • Bug Fixes

    • Improved recovery of missing command aliases and handling of published command paths.
    • Corrected command classification, catalog gates, and write-detection behavior.
  • Tests

    • Added coverage for inventory reconciliation, category validation, duplicate entries, updated command paths, and write detection.

MikroTik reshaped the CLI Reference from module pages into per-command leaf
pages whose slug is the CLI path. Fixed upstream in tikoci/rosetta#138; this is
the centrs half.

Discovery was the sitemap alone, which serves a branching menu as a
trailing-slash category URL with no .md of its own. That menu's own entry IS
published, at <dir>/<basename>.md, and listed only in llms.txt. Grounded live
before touching code:

  sitemap 814 U derived <dir>/<basename> 256 = 1,070 = llms.txt (1,071 - index)

Discovery is now the union, with a BLOCKING gate that every sitemap category dir
contributes its leaf — the same assertion rosetta ships as V-cliref-discovery,
so the next reshape fails loudly instead of quietly shrinking the table. A page
only one inventory lists is reported rather than refused: the union already
carries it, and --check fails on the new row anyway. Corpus now reconciles with
rosetta exactly at 1,070 pages / 1,077 entries.

The alias allowlist is empty, and that is the correct state. All 20 source
spellings are gone from the publication and all 20 targets are published
directly. R0/R1/R2 stay asserted so the next entry is refused rather than
absorbed; the R1 test moved to a synthetic allowlist since no live entry exists.

Two paths publish twice as containers under different hardware gates
(/system/health as !i386 and health, /interface/ethernet/switch as musicswitch
and rbswitch). Both halves say the path is navigation, so the row records what
they agree on, exactly as a disagreed gate is dropped rather than picked. Only a
navigation-vs-command split still aborts. Anchored on a new frozen fixture of
the real page; "one entry per page" is explicitly not an invariant.

Catalog: 1,119 -> 1,124 paths, 439 -> 450 commands, and the ancestry-aware
unexplained residue 7 -> 1 (/interface/xfrm).

Corpus differential over the 948-script corpus, old table vs new, harness
verified by reproducing the #249 figures exactly on the old table:

  stmts          18,648 -> 18,648
  argCandidates  14,329 -> 14,336
  argReadable     7,385 ->  7,392
  abstentions     6,944 ->  6,944  (48.4612% -> 48.4375%)
  context-lost       69 ->     83

Six scripts move and every statement in them is a correction. Seven newly
resolve and read; five read the same with the right verb (/ip hotspot user
reset-counters took `hotspot` as the verb, now takes `reset-counters`, which
also reclassifies it as a write). No document changes containsWrite verdict.
context-lost rising is the resolver withdrawing a certainty claim it should
never have had: an unreadable statement might have been an absolute navigation
and so restored context; a known command never navigated.

Live --check is 1m34s cold, inside the QA job's 10-minute budget.

Closes #285

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 12, 2026 15:16
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c431bbc6-2f76-4fa9-a318-09ab08118c83

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR migrates CLI Reference discovery to combined sitemap and llms.txt inventories. It updates duplicate-entry reconciliation, regenerates the RouterOS path catalog, refreshes fixtures, and adjusts explain and write-detection tests.

Changes

CLI Reference catalog migration

Layer / File(s) Summary
Combined inventory discovery
scripts/explain-catalog-data.ts, scripts/gen-explain-catalog.ts, test/unit/explain-catalog.test.ts, test/fixtures/explain/cliref/*, commands/explain/README.md
Discovery combines sitemap, category-leaf, and filtered llms.txt entries. Tests cover unioning, missing leaves, sitemap-only pages, and the empty alias allowlist.
Duplicate publication reconciliation
scripts/explain-catalog-data.ts, test/unit/explain-catalog.test.ts
Compatible navigation kinds collapse to menu. Duplicate entries retain shared gates. Navigation-versus-command contradictions remain failures.
Generated CLI path catalog
src/explain/catalog.ts, GLOSSARY.txt
The catalog refresh adds and removes published paths, updates provenance, and revises package, capability, and ancestry-aware gate metadata.
Fixtures and explain validation
test/fixtures/explain/cliref/*, test/unit/explain-write.test.ts, commands/explain/README.md
Fixtures and tests reflect the refreshed command inventory. Documentation records updated corpus and comment-placement measurements.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • Issue 285 — Directly related to the CLI Reference migration, combined inventory discovery, empty aliases, and duplicate published entries.
  • Issue 137 in the related repository — Covers the same per-command inventory migration, leaf derivation, llms.txt discovery, and catalog refresh.

Possibly related PRs

  • tikoci/centrs#231: Established the CLI path catalog ETL and generated catalog extended by this inventory migration.
  • tikoci/centrs#232: Added the generated command catalog consumed by the explain analyzers.
  • tikoci/centrs#284: Extracted and tested catalog drift reporting while this PR changes discovery inputs.

Sequence Diagram(s)

sequenceDiagram
  participant CatalogGenerator
  participant MikroTikSitemap
  participant MikroTikLlmsTxt
  participant discoverSlugs
  participant CatalogFolder
  participant GeneratedCatalog
  CatalogGenerator->>MikroTikSitemap: fetch sitemap
  CatalogGenerator->>MikroTikLlmsTxt: fetch llms.txt
  MikroTikSitemap-->>discoverSlugs: sitemap XML
  MikroTikLlmsTxt-->>discoverSlugs: inventory text
  discoverSlugs-->>CatalogGenerator: unioned page slugs
  CatalogGenerator->>CatalogFolder: parse and reconcile pages
  CatalogFolder-->>GeneratedCatalog: catalog rows and gate metadata
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: discovering the CLI Reference from both inventories.
Description check ✅ Passed The description thoroughly explains the changes, links related work, documents assumptions, and records validation results, although it does not follow every template heading exactly.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/285-cliref-union-discovery

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the explain CLI-Reference catalog generation to handle MikroTik’s reshaped CLI-Reference publication by discovering pages from the union of sitemap.xml and llms.txt, removing now-stale alias rewrites, and refreshing the generated catalog/table and its tests/fixtures accordingly.

Changes:

  • Switch CLI-Reference discovery to discoverSlugs(sitemap ∪ llms.txt) with a hard abort if any sitemap category directory would silently drop its <dir>/<basename> leaf.
  • Remove/lock down the alias allowlist as empty (with updated assertions and tests) and update catalog semantics around duplicated published paths and gate folding.
  • Refresh unit tests, frozen fixtures, glossary, and commands/explain documentation to match the new inventory shape and updated counts.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
scripts/explain-catalog-data.ts Adds union inventory discovery (sitemap.xml + llms.txt), category-leaf recovery, and updated published-entry folding rules.
scripts/gen-explain-catalog.ts Fetches both inventories and uses the new union-based discovery during catalog generation/checking.
src/explain/catalog.ts Updates the generated catalog table and its header documentation to reflect the new source inventory and semantics.
test/unit/explain-catalog.test.ts Adds coverage for new discovery behavior and duplicated published-path handling.
test/unit/explain-write.test.ts Updates write-detection anchors that changed due to the corrected catalog inventory.
test/fixtures/explain/cliref/system__health__health.md Adds a new frozen fixture representing the new per-leaf page shape and duplicate path publication case.
test/fixtures/explain/cliref/README.md Documents fixture purpose and the CLI-Reference reshape, including why older fixtures are intentionally retained.
commands/explain/README.md Updates the explain command documentation to match the corrected inventory, discovery approach, and new measurements.
GLOSSARY.txt Adds CLI-Reference reshape vocabulary (llms, musicswitch, rbswitch, etc.).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/explain-catalog-data.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/explain-catalog-data.ts`:
- Around line 224-233: Update llmsSlugs so relative llms.txt links are not
silently discarded by cliRefPath: resolve supported root-relative and
path-relative targets against the correct llms.txt/CLI-reference base before
deriving pageSlug, or explicitly reject non-absolute targets with a visible
failure. Preserve slug collection and sorting for valid links.

In `@test/unit/explain-write.test.ts`:
- Around line 249-254: Split the combined test around containsWrite into two
tests: keep the existing bare-word “reset” assertions in “a bare-word head
abstains rather than clearing the document,” and move the
“/interface\nreset-counters” verdict assertion into a separate
catalog-resolution test. Preserve both expected verdicts and blockers.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 49616e39-767d-41a4-86f0-541111106d8b

📥 Commits

Reviewing files that changed from the base of the PR and between a6ce2b3 and 1edb5e9.

📒 Files selected for processing (9)
  • GLOSSARY.txt
  • commands/explain/README.md
  • scripts/explain-catalog-data.ts
  • scripts/gen-explain-catalog.ts
  • src/explain/catalog.ts
  • test/fixtures/explain/cliref/README.md
  • test/fixtures/explain/cliref/system__health__health.md
  • test/unit/explain-catalog.test.ts
  • test/unit/explain-write.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: CHR smoke (stable)
  • GitHub Check: copilot-pull-request-reviewer
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (6)
{docs/**,.github/instructions/**,.github/**/*.yml,.github/**/*.yaml,**/*.{md,txt,dict}}

📄 CodeRabbit inference engine (AGENTS.md)

Run bun run lint:ci when changing documentation, instructions, security configuration, spelling dictionaries, or workflow files.

Files:

  • GLOSSARY.txt
  • test/fixtures/explain/cliref/README.md
  • test/fixtures/explain/cliref/system__health__health.md
  • commands/explain/README.md
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Transport or RouterOS-touching code is not done until bun run test:integration passes.
Do not silently fall back to another protocol when the caller pinned --via.
Do not make generated output the hand-edited source of truth.
Do not disable validation to make a test pass; validation is part of the product.

Files:

  • scripts/gen-explain-catalog.ts
  • test/unit/explain-write.test.ts
  • scripts/explain-catalog-data.ts
  • test/unit/explain-catalog.test.ts
  • src/explain/catalog.ts
test/fixtures/**/*

📄 CodeRabbit inference engine (test/AGENTS.md)

Keep fixtures under test/fixtures/ with clear source/provenance notes.

Files:

  • test/fixtures/explain/cliref/README.md
  • test/fixtures/explain/cliref/system__health__health.md
commands/*/README.md

📄 CodeRabbit inference engine (commands/AGENTS.md)

commands/*/README.md: Each commands/<name>/README.md is the executable specification's designed tier: document intent, flags, and behavior; include a Designed, not implemented table for spec-only flags; do not duplicate implemented-flag tables generated in docs/CLI.md; link to docs/CONSTITUTION.md rather than restating constitution-wide rules; document only command-specific behavior; and keep the Status line consistent with docs/MATRIX.md.
Implemented flags must be generated from CliCommandMetadata into docs/CLI.md via bun run docs:cli; command READMEs must not maintain duplicate tables of implemented flags.

Files:

  • commands/explain/README.md
commands/*/{README.md,examples.md}

📄 CodeRabbit inference engine (AGENTS.md)

Read the target command's README.md and examples.md as the executable specification before writing code or tests.

Files:

  • commands/explain/README.md
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/AGENTS.md)

src/**/*.{ts,tsx}: Use Bun-native TypeScript and Web APIs where possible
Errors must be actionable for humans and agents, with next-step guidance when a dependency, protocol, credential, or validation source is missing

Files:

  • src/explain/catalog.ts
🧠 Learnings (21)
📚 Learning: 2026-08-05T03:19:54.280Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 209
File: test/unit/explain-menus.test.ts:146-152
Timestamp: 2026-08-05T03:19:54.280Z
Learning: In `test/unit/explain-write.test.ts`, keep separate test anchors for `isDanglingBarePath` and menu-table rejection. Known menu paths such as `/ip/firewall/filter` and `/log` reach `isDanglingBarePath` at document end, while `/system/reboot` is rejected earlier by `isConfirmedNav` because `isMenuPath` returns false. Do not combine these inputs in one test when asserting coverage of either mechanism.

Applied to files:

  • test/unit/explain-write.test.ts
  • test/fixtures/explain/cliref/README.md
  • commands/explain/README.md
  • scripts/explain-catalog-data.ts
  • test/unit/explain-catalog.test.ts
  • src/explain/catalog.ts
📚 Learning: 2026-08-06T14:17:50.227Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 224
File: commands/explain/examples.md:11-16
Timestamp: 2026-08-06T14:17:50.227Z
Learning: For the phase-1 offline explain API, offline behavior is tested through unit and fixture tests rather than CHR-backed integration tests. In `test/unit/explain-envelope.test.ts`, the CLI-spelling gate-versus-analysis behavior described by `commands/explain/examples.md` example `1b` and the resolved-menu behavior described by example `18b` have focused unit coverage. The CLI `explain` command surface is deferred and is not implemented as `src/cli/explain.ts` in this PR.

Applied to files:

  • test/unit/explain-write.test.ts
  • test/fixtures/explain/cliref/README.md
  • commands/explain/README.md
  • scripts/explain-catalog-data.ts
  • test/unit/explain-catalog.test.ts
📚 Learning: 2026-08-01T23:46:54.392Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 197
File: src/explain/verbsplit.ts:383-387
Timestamp: 2026-08-01T23:46:54.392Z
Learning: In `src/explain/verbsplit.ts`, `VerbSplit` is the ratified Q6 boundary shape. Do not add document-scale context-certainty metadata to it independently; add that signal with the planned `ambiguous`/`unknown` verdict-vocabulary and phase-1 envelope work tracked in GitHub issue `#192`. Until then, `resolveVerbs` may correctly return root-based resolved paths for context-independent statements after context loss, but callers cannot observe that certainty was lost.

Applied to files:

  • test/unit/explain-write.test.ts
  • commands/explain/README.md
📚 Learning: 2026-08-06T05:38:01.223Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 222
File: src/explain/defects.ts:1-70
Timestamp: 2026-08-06T05:38:01.223Z
Learning: In the TypeScript `src/explain` modules, references to phase-0 lab questions and issue numbers are an established documentation idiom when they explain the technical basis for a current contract. Keep these rationale references when they support implementation behavior. Remove dated decisions, delivery status, and future roadmap text from implementation and test comments.

Applied to files:

  • test/unit/explain-write.test.ts
  • test/fixtures/explain/cliref/README.md
  • scripts/explain-catalog-data.ts
  • test/unit/explain-catalog.test.ts
📚 Learning: 2026-08-05T20:06:21.299Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 217
File: src/explain/symbols.ts:0-0
Timestamp: 2026-08-05T20:06:21.299Z
Learning: In `src/explain/symbols.ts`, comparative corpus measurements that explain a semantic modeling trade-off are rule provenance and follow the established F1/F2 documentation convention. Treat run-specific bookkeeping, fuzz counts, scratch-script paths, method pointers, and per-version missed-tail details as status data that should not remain in source comments.

Applied to files:

  • test/unit/explain-write.test.ts
  • commands/explain/README.md
  • scripts/explain-catalog-data.ts
📚 Learning: 2026-08-02T01:55:57.600Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 197
File: src/explain/pathresolve.ts:0-0
Timestamp: 2026-08-02T01:55:57.600Z
Learning: In `src/explain/pathresolve.ts`, `isUnreadablePath` identifies unreadable menu paths in both relative and absolute spelling. However, document-context poisoning applies only to unreadable `/`-led statements (`isUnreadableAbsolute`); relative unreadable paths do not poison document context by declared design.

Applied to files:

  • test/unit/explain-write.test.ts
  • scripts/explain-catalog-data.ts
  • test/unit/explain-catalog.test.ts
📚 Learning: 2026-08-11T17:46:27.539Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 273
File: test/fixtures/explain/corpus-partition.json:4-4
Timestamp: 2026-08-11T17:46:27.539Z
Learning: For durable fixtures in this repository, do not cite in-flight `.scratch/` files as provenance. In `test/fixtures/explain/corpus-partition.json`, the committed groups are the durable artifact, and the `frozen` no-regeneration statement replaces the former `.scratch/explain-lab-partition.ts` generator citation.

Applied to files:

  • test/fixtures/explain/cliref/README.md
📚 Learning: 2026-08-06T14:17:38.964Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 224
File: commands/explain/README.md:0-0
Timestamp: 2026-08-06T14:17:38.964Z
Learning: For the `explain` command documentation, `commands/explain/examples.md` specifies the finished target contract, not the current implementation phase. `commands/explain/README.md` contains the phase inventory and must map omitted phase fields to the issues and examples that will make them green. Future phase gaps must add fields without changing the finished example contract.

Applied to files:

  • test/fixtures/explain/cliref/README.md
  • commands/explain/README.md
📚 Learning: 2026-08-06T23:42:39.898Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 227
File: src/explain/args.ts:151-158
Timestamp: 2026-08-06T23:42:39.898Z
Learning: For the RouterOS explain argument lexer corpus checks, a green frozen corpus measures coverage and risk but does not validate lexical rules absent from the corpus. The frozen corpus contains no lone-`\r` continuation case, so edge-case probes and targeted regression tests remain required for continuation behavior.

Applied to files:

  • test/fixtures/explain/cliref/README.md
  • commands/explain/README.md
📚 Learning: 2026-07-23T00:15:08.643Z
Learnt from: CR
Repo: tikoci/centrs PR: 0
File: commands/AGENTS.md:0-0
Timestamp: 2026-07-23T00:15:08.643Z
Learning: Applies to commands/*/README.md : Each `commands/<name>/README.md` is the executable specification's designed tier: document intent, flags, and behavior; include a `Designed, not implemented` table for spec-only flags; do not duplicate implemented-flag tables generated in `docs/CLI.md`; link to `docs/CONSTITUTION.md` rather than restating constitution-wide rules; document only command-specific behavior; and keep the `Status` line consistent with `docs/MATRIX.md`.

Applied to files:

  • test/fixtures/explain/cliref/system__health__health.md
📚 Learning: 2026-06-08T22:26:06.293Z
Learnt from: CR
Repo: tikoci/centrs PR: 0
File: src/protocols/AGENTS.md:0-0
Timestamp: 2026-06-08T22:26:06.293Z
Learning: Applies to src/protocols/**/*router*{protocol,implementation,api,cli}*.{js,ts,md} : Ground protocol facts before implementation: RouterOS service/API/CLI path, auth model, default port, local tooling, validation source, security warnings, failure modes, and CHR test shape

Applied to files:

  • commands/explain/README.md
  • scripts/explain-catalog-data.ts
  • test/unit/explain-catalog.test.ts
  • src/explain/catalog.ts
📚 Learning: 2026-08-06T22:07:13.134Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 226
File: commands/explain/README.md:0-0
Timestamp: 2026-08-06T22:07:13.134Z
Learning: For `centrs explain` documentation, an instructed remedy must be executable in the current phase. The live `centrs explain <router> --file -` form is parsed but returns `usage/not-implemented` until phase 2, so documentation must present the offline `--file -` form as the actionable stdin remedy.

Applied to files:

  • commands/explain/README.md
📚 Learning: 2026-06-08T22:25:53.303Z
Learnt from: CR
Repo: tikoci/centrs PR: 0
File: src/AGENTS.md:0-0
Timestamp: 2026-06-08T22:25:53.303Z
Learning: Preserve RouterOS syntax and semantics. Do not add high-level RouterOS configuration helpers; that boundary is fixed in `docs/CONSTITUTION.md`

Applied to files:

  • commands/explain/README.md
📚 Learning: 2026-08-10T23:41:13.189Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 256
File: src/explain/args.ts:936-945
Timestamp: 2026-08-10T23:41:13.189Z
Learning: In `src/explain/args.ts`, `pushArrayMembers` must withdraw the enclosing array shape with `DEPTH_BOUND_REACHED` when `depth >= MAX_MEMBER_DEPTH`; returning `null` incorrectly reports the unverified literal as a valid array. CHR 7.23.3 accepts valid array nesting to at least depth 64, while invalid `(1,)` members remain syntax errors at all tested depths. The 948-script corpus has a maximum observed array-member depth of 6, so the depth-8 analysis bound does not drop observed valid corpus literals.

Applied to files:

  • commands/explain/README.md
📚 Learning: 2026-08-06T05:38:13.259Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 222
File: test/fixtures/explain/defects.json:3-73
Timestamp: 2026-08-06T05:38:13.259Z
Learning: In `src/explain/pathresolve.ts`, `Loc.base = -1` widening applies to defects raised during nested walker traversal, such as `over-depth`, when their local offsets cannot be mapped safely from UTF-16 string indexes to analyzed UTF-8 byte offsets. Defects emitted by the top-level segmenter are already in analyzed-document byte space and therefore retain precise offsets even when their enclosing statement contains non-ASCII text. The behavior is covered by `test/fixtures/explain/defects.json` and `test/unit/explain-defects.test.ts`.

Applied to files:

  • commands/explain/README.md
  • test/unit/explain-catalog.test.ts
📚 Learning: 2026-06-08T22:26:06.293Z
Learnt from: CR
Repo: tikoci/centrs PR: 0
File: src/protocols/AGENTS.md:0-0
Timestamp: 2026-06-08T22:26:06.293Z
Learning: Applies to src/protocols/commands/**/*.{js,ts} : Surface missing local tools with platform-aware install or remediation advice

Applied to files:

  • scripts/explain-catalog-data.ts
📚 Learning: 2026-08-06T23:42:39.897Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 227
File: src/explain/args.ts:151-158
Timestamp: 2026-08-06T23:42:39.897Z
Learning: In the RouterOS explain lexer, `src/explain/args.ts` and `src/explain/verbsplit.ts` must use the shared `continuationLength(text, at)` helper for backslash-newline handling. Only `\n` and `\r\n` are continuations. A lone `\r` after `\` must not be skipped; `args.ts` must refuse it as an invalid escape to preserve source-accurate token names and spans.

Applied to files:

  • scripts/explain-catalog-data.ts
📚 Learning: 2026-06-16T10:51:07.659Z
Learnt from: CR
Repo: tikoci/centrs PR: 0
File: test/AGENTS.md:0-0
Timestamp: 2026-06-16T10:51:07.659Z
Learning: Applies to test/integration/**/*.test.{ts,js} : Put long-running, RouterOS-backed, or platform-specific tests (including process-level tests that spawn the real `src/cli.ts` through `cli-process.ts` and network-free CLI smoke tests in `cli-smoke.test.ts`) under `test/integration/` and wire them through QA or lab workflows.

Applied to files:

  • test/unit/explain-catalog.test.ts
📚 Learning: 2026-07-23T00:15:08.643Z
Learnt from: CR
Repo: tikoci/centrs PR: 0
File: commands/AGENTS.md:0-0
Timestamp: 2026-07-23T00:15:08.643Z
Learning: Use centered command verbs (`retrieve`, `execute`, `api`, `devices`, `discover`, `check`, `explain`, `terminal`, and `settings`) rather than one tool per RouterOS command; fold open-ended follow into `api --stream` rather than creating a separate `stream` verb.

Applied to files:

  • src/explain/catalog.ts
📚 Learning: 2026-08-07T16:47:13.907Z
Learnt from: CR
Repo: tikoci/centrs PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-07T16:47:13.907Z
Learning: Prefer `rosetta` MCP tools for RouterOS facts before using web search.

Applied to files:

  • src/explain/catalog.ts
📚 Learning: 2026-08-06T05:37:57.693Z
Learnt from: mobileskyfi
Repo: tikoci/centrs PR: 222
File: src/explain/defects.ts:1-70
Timestamp: 2026-08-06T05:37:57.693Z
Learning: In TypeScript modules under src/explain, retain references to phase-0 lab questions and issue numbers when they document the technical rationale for current implementation behavior or contracts. Remove comments containing dated decisions, delivery status, or future roadmap information when it does not explain current behavior, including in tests.

Applied to files:

  • src/explain/catalog.ts
🔇 Additional comments (12)
scripts/explain-catalog-data.ts (2)

26-52: LGTM!

Also applies to: 94-138, 528-534, 660-674, 815-817, 831-835, 848-850, 1000-1004


195-222: LGTM!

Also applies to: 235-289

scripts/gen-explain-catalog.ts (1)

20-32: LGTM!

Also applies to: 114-121

test/unit/explain-catalog.test.ts (1)

32-40: LGTM!

Also applies to: 151-159, 188-206, 285-296, 315-332, 380-411, 526-602, 666-691, 769-776

commands/explain/README.md (1)

176-200: LGTM!

Also applies to: 913-920, 943-973

test/fixtures/explain/cliref/README.md (1)

3-27: LGTM!

src/explain/catalog.ts (3)

12-14: LGTM!

Also applies to: 27-35, 48-50, 90-101, 1323-1327


93-101: LGTM!

Also applies to: 130-130, 155-155, 167-183, 227-238, 282-348, 366-366, 378-419, 429-472, 534-534, 558-559, 603-628, 659-698, 746-749, 760-811, 845-858, 877-878, 954-954, 987-988, 999-1007, 1025-1047, 1076-1089, 1106-1120, 1130-1132, 1172-1172, 1208-1211


283-286: 🗄️ Data Integrity & Integration

Keep the i386 conditions. The published CLI Reference lists Conditions: i386 for both /interface/ethernet and /interface/ethernet/monitor.

			> Likely an incorrect or invalid review comment.
GLOSSARY.txt (1)

687-694: LGTM!

test/fixtures/explain/cliref/system__health__health.md (1)

1-90: LGTM!

test/unit/explain-write.test.ts (1)

408-415: LGTM!

Comment thread scripts/explain-catalog-data.ts
Comment thread test/unit/explain-write.test.ts Outdated
Three review findings, all fixed.

Copilot — `discoverSlugs` reported the sitemap-only direction but never the
inverse, while the docstring claimed both. The two directions are NOT symmetric,
and that asymmetry is the shape: every sitemap page is also in llms.txt, but
llms.txt legitimately carries 256 pages the sitemap lacks — those ARE the
category leaves, so reporting them would bury the signal. The residue is what
matters, and is now reported: an llms.txt page that is neither in the sitemap nor
a category leaf has appeared from nowhere.

CodeRabbit — `cliRefPath` used `new URL(link)`, which throws on a root-relative
or document-relative link and so returned null, indistinguishable from "not a
CLI page". Both inventories publish absolute URLs today (verified live), so this
was latent rather than live, but a silent inventory shrink is exactly the #285
defect class. Links now resolve against the document they were read from.

CodeRabbit — split the combined bare-word-head test. The abstention anchor
(`/interface reset`) and the catalog-resolution anchor (`/interface
reset-counters`) are separate mechanisms and now separate tests, so a catalog
change is legible as one.

Both new guards mutation-tested: reverting either fix turns its test red.
`explain:catalog:check` still matches live — the catalog itself is unmoved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mobileskyfi
mobileskyfi merged commit 2f3df39 into main Aug 12, 2026
11 checks passed
@mobileskyfi
mobileskyfi deleted the agent/285-cliref-union-discovery branch August 12, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI-Reference catalog: MikroTik reshaped the source — re-audit the alias allowlist against 1,070 pages, not 814

2 participants