Skip to content

docs(cli): classify the agent-directory command in the manual - #4613

Merged
huangruiteng merged 4 commits into
mainfrom
codex/manpage-agent-directory-20260917
Sep 17, 2026
Merged

huangruiteng merged 4 commits into
mainfrom
codex/manpage-agent-directory-20260917

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

What changed

examples/cli-help-manpage-smoke.py requires every top-level loopx command to be either represented in the manual or explicitly kept on its command-specific help surface. loopx agent-directory, added by #4544 (commit 818db7522) and dispatched at loopx/cli.py:773, was never classified, so every main head since then fails that check:

AssertionError: {'unclassified': ['agent-directory'], 'stale_manual': [], 'stale_help_only': []}
  examples/cli-help-manpage-smoke.py:97

On main today this is what takes the full public smoke sweep down (run 35164002565: shards (0,2,3,4) fail, shard 0 stops here), so the failure is unrelated to the PRs it looks like it is blocking.

This PR makes the visibility decision instead of relaxing the assertion: agent-directory joins the manual's maintainer-facing agent commands, next to register-agent, because the command's job is to produce the local, goal-scoped peer agent directory this host can hand work to. man/loopx.1 is regenerated from render_manpage(); the smoke asserts the checked-in manual equals the renderer output, so both move together.

Validation

uv run --extra test python examples/cli-help-manpage-smoke.py
# cli-help-manpage-smoke ok

uv run --extra test python -m pytest tests/control_plane/test_cli_output_budget.py -q
# 22 passed

tests/control_plane/test_cli_output_budget.py budgets the agent-facing rows ("Start here", "Daily operator commands", loopx heartbeat-prompt); a maintainer-group row is not part of that budget, and the suite passes unchanged.

Before the fix, the same smoke fails on this tree with the unclassified assertion above; the only source change is the four-line entry plus the regenerated manual.

Boundary

Public help surface only: one catalog entry and its generated manual text. No runtime, control-plane, permission, scoring, or agent-facing output change, and no assertion is relaxed or skipped. loopx commands and loopx --help line counts are unchanged in the assertion that bounds them.

`loopx agent-directory` shipped in #4544 without a manual-visibility
decision, so `examples/cli-help-manpage-smoke.py` fails on every `main` head
with `{'unclassified': ['agent-directory']}` and takes the full public smoke
sweep down with it.

The command produces the local, goal-scoped peer agent directory this host
can hand work to, so it belongs with the other maintainer-facing agent
commands instead of the help-only surface. `man/loopx.1` is regenerated from
`render_manpage()`, because the smoke asserts the checked-in manual equals the
renderer output.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

动机

examples/cli-help-manpage-smoke.py 要求每个顶层 loopx 命令要么进入手册目录,要么显式声明只存在于命令自身的 help 面。PR #4544(commit 818db75,分发点在 loopx/cli.py:773)新增了 loopx agent-directory 却没有做这个可见性决定,于是此后每个 main head 都在这条断言上失败:{'unclassified': ['agent-directory']}。这正是 run 35164002565 中 full public smokes 分片 0/2/3/4 全红的原因,与被它看起来挡住的那些 PR 无关。

改动思路

不放宽断言,而是补上这个决定:agent-directory 的职责是产出本机可派活的、goal 作用域的 peer agent 目录,因此它和 register-agent 同属“Maintainer and adapter commands”,而不是 help-only 面。手册文本由渲染器生成,而 smoke 断言签入的 man/loopx.1 必须等于渲染结果,所以两者一起更新。

具体改动

loopx/help_surface.py 增加一条目录项(命令 + 用途);man/loopx.1 按渲染器重新生成,只多出对应的三行(.TP、粗体命令、用途)。除此之外没有其它改动。

对主干的风险

只动公开 help 面,单用途、可回滚。tests/control_plane/test_cli_output_budget.py 的预算只覆盖 agent 面行(Start here、Daily operator commands、loopx heartbeat-prompt),维护者分组新增行不进入该预算,22 项测试通过;默认 help 行数上限、命令引用面断言均不变。改动前可在本分支复现同一条 unclassified 失败,改动后 cli-help-manpage-smoke ok。

我的整体评价

修的是 main 上真实存在的公开 smoke 红灯,改动面最小且没有绕过任何断言;分类位置与命令用途一致,证据是先复现后修复。建议在该 head 的必过检查转绿后合并,并据此把 Todo#todo_28e0823d6392 的 public smoke 修复范围收敛为已修复状态。

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Head: f02b3fa

English verdict: APPROVE

…irectory-20260917

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

动机

examples/cli-help-manpage-smoke.py 要求每个 top-level loopx 命令要么在 manual 里有代表,要么被显式留在 command-specific help 面上。agent-directory(#4544 引入,loopx/cli.py:773 分派)从来没有被归类,于是从那次合并开始,每一个 main head 都挂在这条断言上:

AssertionError: {'unclassified': ['agent-directory'], 'stale_manual': [], 'stale_help_only': []}

今天 main 的整轮 public smoke(shards 0/2/3/4)就停在这里,看起来像在拦一堆与它无关的 PR,实际原因只有这一个未分类命令。

改动思路

做可见性决定,而不是放松断言:把 agent-directory 归到 manual 的 maintainer-facing agent 命令组,挨着 register-agent——理由是这个命令的职责正是产出这台 host 可以派活的、本地 goal-scoped 的 peer agent 目录。man/loopx.1 由 render_manpage() 重新生成;smoke 断言签入的 manual 等于渲染输出,所以两者必须一起动,而本 PR 是一起动的。

具体改动

  • loopx/help_surface.py:新增 agent-directory 的 manual 条目(四行),归入 agent 命令组。
  • man/loopx.1:从渲染函数重新生成。
  • 没有别的源改动,也没有把任何命令加进跳过列表。

对主干的风险

把命令放进 manual 会让人在帮助页里看到它,这正是本 PR 的目的;需要留意的是 agent-facing 行预算,因为 manual 变长有时会顺带撑大那些行。本次复审在更新后的 head 上实测(该 head 只是把 origin/main 合进来,两个被评审文件在旧 head 与新 head 之间逐字节一致,已用内容哈希核对):

  • uv run --extra test python examples/cli-help-manpage-smoke.py → cli-help-manpage-smoke ok
  • 该改动落在 maintainer 分组,不在 tests/control_plane/test_cli_output_budget.py 预算的 agent-facing 行里(PR 记录该套件 22 passed 不变)

另需如实记一笔:这条分支上一次跑 CI 时 stage2c (mutants 0) 出现过一个存活 mutant(fence_unshared_state_lock),当时在 main 的两次同 job 运行里没有复现;本次复审以新 head 的必过检查结果为准。

我的整体评价

用一个明确的可见性决定消掉“自 #4544 起 main 每个 head 都红”的这个原因,并且是改事实而不是改断言,方向正确。

合并边界这条要说清楚:本 PR 改的是 loopx/help_surface.py,属于控制面/CLI 契约面,按仓库当前规则不由作者自合并——本 head 的审查记录只用于把决定交给维护者,实际合并由维护者执行。

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Head: d10d7f6

English verdict: APPROVE

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Reviewed exact head: c13df19dae7f5e4e51224ebc08dba4391db74992 (re-review after merging origin/main; previous review covered the pre-merge content).

loopx pr-review --check-result on the matching packet returned ok: true with no approval_blockers; all 19 evidence rows for this control-plane plan are verified.

动机

loopx agent-directory 是真实的顶层命令(实测它存在于 130 个顶层命令中,loopx agent-directory --help 正常),但既不在手册命令组里,也不在显式 help-only 集合里。examples/cli-help-manpage-smoke.py::assert_top_level_commands_are_explicitly_classified 要求 parser 命令集合 == 手册命令集合 ∪ help-only 集合,于是 main 上这条必过 shard 0 报:

AssertionError: {'unclassified': ['agent-directory'], 'stale_manual': [], 'stale_help_only': []}

这是 main 必过套件里最后一条红项,不修则所有开放 PR 都拿不到必过检查全绿。

这个 PR 的价值:它补的是真实存在的帮助面缺口(命令有实现、手册无分类),而且没有用「少写文档」的方式换取绿灯。

改动思路

关键在于选择哪一类归属。smoke 的一致性等式只允许两种落点:进手册的 COMMAND_GROUPS,或进显式的 MANPAGE_COMMAND_HELP_ONLY。把命令丢进后者虽然同样能让集合等式成立,却会让它从手册正文消失——等于用削文档换绿灯,所以选择按既有条目形状补进手册组;man/loopx.1 是被 scripts/render-manpage.py 从同一张表渲染出来的产物,因此必须同步更新。

具体改动

  • loopx/help_surface.py:262:在「运行与编排」组追加一条 {'command': 'loopx agent-directory', 'purpose': 'Produce the local, goal-scoped peer agent directory this host can hand work to.'},与相邻条目(register-agent、lark-kanban、presentation)形状完全同构。
  • man/loopx.1:追加对应的 .TP 段落(转义与生成器一致)。

两个文件之外零改动:不改命令实现、不改 smoke 断言、不新增 help-only 例外。

关键代码讲解

def manpage_top_level_commands() -> frozenset[str]:
    commands = {"commands"}
    for group in COMMAND_GROUPS:
        for entry in group.get("commands", []):
            command = str(entry.get("command") or "")
            commands.update(re.findall(r"(?:^| / )loopx ([a-z0-9][a-z0-9-]*)", command))

分类不是靠子串匹配判定的,而是靠集合相等:正则只负责从既有条目文本里提取命令 id,归属由「在哪张表里」决定。因此唯一真实的书写风险是形态(例如写成下划线就解析不出来),这一点由 smoke 实测覆盖。

def assert_checked_in_manpage_surface() -> None:
    assert (REPO_ROOT / "man" / "loopx.1").read_text(encoding="utf-8") == render_manpage()

man page 必须与渲染结果逐字节相等,所以「只改表不改 man page」会立刻失败——这也是我这次单独复核的地方:实测 checked == render_manpage() 为 True。

对主干的风险

纯帮助面数据改动,风险面只有一个:分类表与 man page 可能不同步。该风险由 assert_checked_in_manpage_surface 的逐字节比对强制,本次已实测通过。命令行为、权限、registry、quota、todo 均未触碰;loopx agent-directory 的成员校验语义(未注册调用方得到 scope gap)只被描述、未被修改。

本次在更新后的 head 上实测(该 head 把 origin/main —— 含已合并的 #4593 —— 合入;本分支自身 diff 仍为 2 文件 +7/-0):

  • env -u PYTHONPATH uv run --extra test python examples/cli-help-manpage-smoke.py → ok(exit 0)
  • man/loopx.1 == render_manpage() → True
  • 干净 main worktree(/tmp/main-green.CEZZNu)上同一 smoke → 失败(unclassified: ['agent-directory']),确认基线确为红
  • env -u PYTHONPATH uv run --extra test loopx canary premerge --from-git-diff → 0 failures / 0 advisories(diff hygiene、changed-python compile、3/3 catalog canary)

未验证 / 环境说明(如实标注,不当通过):semantic-vocabulary-drift-smoke 在本机需要仓库的 TypeScript npm 依赖,缺依赖时会以 TypeScript production parser failed; run npm ci --ignore-scripts 退出。该失败与本次改动无关——在同一台机器的干净 main worktree 上以完全相同的方式失败——补齐本地未跟踪的根 node_modules 后该 smoke 与 premerge 均通过。未手工在安装后的 man1 环境翻阅页面(该路径由 smoke 的安装断言覆盖)。

边界声明:本 PR 改动 loopx/** 下的帮助面数据,按仓库规则属控制面改动,只提 PR、由维护者合并,作者不做自合并。

我的整体评价

按既有分类把帮助面补完整、并同步生成产物,是解除这条 main 红项的最小且不削弱契约的改动。无阻断性发现,残余风险只有「分类表与 man page 必须同时更新」这一既有约定。

与 #4620(main 上另外三条红 smoke,属控制面运行时改动)合并后,main 的 Full Public Smokes 应恢复全绿,随后重跑 canary promotion-readiness 预检以替换陈旧证据。

English verdict: APPROVE - re-verified on exact head c13df19: loopx agent-directory is a real top-level command that was missing from both the manual command groups and the explicit help-only set, so the full-public-smoke assertion failed on main. This adds it to the existing group with the existing entry shape and syncs the rendered man page, instead of hiding it in the help-only set. cli-help-manpage-smoke passes, man/loopx.1 == render_manpage() is True, the same smoke still fails on a clean main worktree, and premerge canary reports 0 failures. No blocking finding.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

动机

examples/cli-help-manpage-smoke.py 要求每个 top-level loopx 命令要么在 manual 里有代表,要么被显式留在 command-specific help 面上。agent-directory(#4544 引入,loopx/cli.py:773 分派)从来没有被归类,于是从那次合并开始,每一个 main head 都挂在这条断言上:

AssertionError: {'unclassified': ['agent-directory'], 'stale_manual': [], 'stale_help_only': []}

今天 main 的整轮 public smoke(shards 0/2/3/4)就停在这里,看起来像在拦一堆与它无关的 PR,实际原因只有这一个未分类命令。

改动思路

做可见性决定,而不是放松断言:把 agent-directory 归到 manual 的 maintainer-facing agent 命令组,挨着 register-agent——理由是这个命令的职责正是产出这台 host 可以派活的、本地 goal-scoped 的 peer agent 目录。man/loopx.1 由 render_manpage() 重新生成;smoke 断言签入的 manual 等于渲染输出,所以两者必须一起动,而本 PR 是一起动的。

具体改动

  • loopx/help_surface.py:新增 agent-directory 的 manual 条目(四行),归入 agent 命令组。
  • man/loopx.1:从渲染函数重新生成。
  • 没有别的源改动,也没有把任何命令加进跳过列表。

对主干的风险

把命令放进 manual 会让人在帮助页里看到它,这正是本 PR 的目的;需要留意的是 agent-facing 行预算,因为 manual 变长有时会顺带撑大那些行。本次复审在更新后的 head 上实测(该 head 只是把 origin/main 合进来,两个被评审文件在旧 head 与新 head 之间逐字节一致(loopx/help_surface.py 与 man/loopx.1 均用内容哈希核对)):

  • uv run --extra test python examples/cli-help-manpage-smoke.py → cli-help-manpage-smoke ok
  • 该改动落在 maintainer 分组,不在 tests/control_plane/test_cli_output_budget.py 预算的 agent-facing 行里(PR 记录该套件 22 passed 不变)

另需如实记一笔:这条分支上一次跑 CI 时 stage2c (mutants 0) 出现过一个存活 mutant(fence_unshared_state_lock),当时在 main 的两次同 job 运行里没有复现;本次复审以新 head 的必过检查结果为准。

我的整体评价

用一个明确的可见性决定消掉“自 #4544 起 main 每个 head 都红”的这个原因,并且是改事实而不是改断言,方向正确。

合并边界这条要说清楚:本 PR 改的是 loopx/help_surface.py,属于控制面/CLI 契约面,按仓库当前规则不由作者自合并——本 head 的审查记录只用于把决定交给维护者,实际合并由维护者执行。

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Head: c13df19

English verdict: APPROVE

…irectory-20260917

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/manpage-agent-directory-20260917 branch from c13df19 to fe27f18 Compare September 17, 2026 07:03

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

动机

examples/cli-help-manpage-smoke.py 要求每个 top-level loopx 命令要么在 manual 里有代表,要么被显式留在 command-specific help 面上。agent-directory(#4544 引入,loopx/cli.py:773 分派)从来没有被归类,于是从那次合并开始,每一个 main head 都挂在这条断言上:

AssertionError: {'unclassified': ['agent-directory'], 'stale_manual': [], 'stale_help_only': []}

今天 main 的整轮 public smoke(shards 0/2/3/4)就停在这里,看起来像在拦一堆与它无关的 PR,实际原因只有这一个未分类命令。

改动思路

做可见性决定,而不是放松断言:把 agent-directory 归到 manual 的 maintainer-facing agent 命令组,挨着 register-agent——理由是这个命令的职责正是产出这台 host 可以派活的、本地 goal-scoped 的 peer agent 目录。man/loopx.1 由 render_manpage() 重新生成;smoke 断言签入的 manual 等于渲染输出,所以两者必须一起动,而本 PR 是一起动的。

具体改动

  • loopx/help_surface.py:新增 agent-directory 的 manual 条目(四行),归入 agent 命令组。
  • man/loopx.1:从渲染函数重新生成。
  • 没有别的源改动,也没有把任何命令加进跳过列表。

对主干的风险

把命令放进 manual 会让人在帮助页里看到它,这正是本 PR 的目的;需要留意的是 agent-facing 行预算,因为 manual 变长有时会顺带撑大那些行。本次复审在更新后的 head 上实测(该 head 只是把 origin/main 合进来,两个被评审文件在旧 head 与新 head 之间逐字节一致(loopx/help_surface.py 与 man/loopx.1 均用内容哈希核对)):

  • uv run --extra test python examples/cli-help-manpage-smoke.py → cli-help-manpage-smoke ok
  • 该改动落在 maintainer 分组,不在 tests/control_plane/test_cli_output_budget.py 预算的 agent-facing 行里(PR 记录该套件 22 passed 不变)

另需如实记一笔:这条分支上一次跑 CI 时 stage2c (mutants 0) 出现过一个存活 mutant(fence_unshared_state_lock),当时在 main 的两次同 job 运行里没有复现;本次复审以新 head 的必过检查结果为准。

我的整体评价

用一个明确的可见性决定消掉“自 #4544 起 main 每个 head 都红”的这个原因,并且是改事实而不是改断言,方向正确。

合并边界这条要说清楚:本 PR 改的是 loopx/help_surface.py,属于控制面/CLI 契约面,按仓库当前规则不由作者自合并——本 head 的审查记录只用于把决定交给维护者,实际合并由维护者执行。

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Head: fe27f18

English verdict: APPROVE

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Reviewed exact head: 90fd1806ea86f1f102181fc10d5608bbae48476f (re-review after merging origin/main through e160b1bbc / #4633; the two changed files are byte-identical to the earlier reviewed heads, and the main advance has no intersection with them).

loopx pr-review --check-result on the matching packet returned ok: true with no approval_blockers; all 19 evidence rows for this control-plane plan are verified.

动机

loopx agent-directory 是真实的顶层命令(实测它存在于 130 个顶层命令中,loopx agent-directory --help 正常),但既不在手册命令组里,也不在显式 help-only 集合里。examples/cli-help-manpage-smoke.py::assert_top_level_commands_are_explicitly_classified 要求 parser 命令集合 == 手册命令集合 ∪ help-only 集合,于是 main 上这条必过 shard 0 报:

AssertionError: {'unclassified': ['agent-directory'], 'stale_manual': [], 'stale_help_only': []}

这是 main 必过套件里最后一条红项,不修则所有开放 PR 都拿不到必过检查全绿。

这个 PR 的价值:它补的是真实存在的帮助面缺口(命令有实现、手册无分类),而且没有用「少写文档」的方式换取绿灯。

改动思路

关键在于选择哪一类归属。smoke 的一致性等式只允许两种落点:进手册的 COMMAND_GROUPS,或进显式的 MANPAGE_COMMAND_HELP_ONLY。把命令丢进后者虽然同样能让集合等式成立,却会让它从手册正文消失——等于用削文档换绿灯,所以选择按既有条目形状补进手册组;man/loopx.1 是被 scripts/render-manpage.py 从同一张表渲染出来的产物,因此必须同步更新。

具体改动

  • loopx/help_surface.py:262:在「运行与编排」组追加一条 {'command': 'loopx agent-directory', 'purpose': 'Produce the local, goal-scoped peer agent directory this host can hand work to.'},与相邻条目(register-agent、lark-kanban、presentation)形状完全同构。
  • man/loopx.1:追加对应的 .TP 段落(转义与生成器一致)。

两个文件之外零改动:不改命令实现、不改 smoke 断言、不新增 help-only 例外。

关键代码讲解

def manpage_top_level_commands() -> frozenset[str]:
    commands = {"commands"}
    for group in COMMAND_GROUPS:
        for entry in group.get("commands", []):
            command = str(entry.get("command") or "")
            commands.update(re.findall(r"(?:^| / )loopx ([a-z0-9][a-z0-9-]*)", command))

分类不是靠子串匹配判定的,而是靠集合相等:正则只负责从既有条目文本里提取命令 id,归属由「在哪张表里」决定。因此唯一真实的书写风险是形态(例如写成下划线就解析不出来),这一点由 smoke 实测覆盖。

def assert_checked_in_manpage_surface() -> None:
    assert (REPO_ROOT / "man" / "loopx.1").read_text(encoding="utf-8") == render_manpage()

man page 必须与渲染结果逐字节相等,所以「只改表不改 man page」会立刻失败——这也是我这次单独复核的地方:实测 checked == render_manpage() 为 True。

对主干的风险

纯帮助面数据改动,风险面只有一个:分类表与 man page 可能不同步。该风险由 assert_checked_in_manpage_surface 的逐字节比对强制,本次已实测通过。命令行为、权限、registry、quota、todo 均未触碰;loopx agent-directory 的成员校验语义(未注册调用方得到 scope gap)只被描述、未被修改。

本次在更新后的 head 上实测(该 head 把 origin/main —— 含已合并的 #4593 —— 合入;本分支自身 diff 仍为 2 文件 +7/-0):

  • env -u PYTHONPATH uv run --extra test python examples/cli-help-manpage-smoke.py → ok(exit 0)
  • man/loopx.1 == render_manpage() → True
  • 干净 main worktree(/tmp/main-green.CEZZNu)上同一 smoke → 失败(unclassified: ['agent-directory']),确认基线确为红
  • env -u PYTHONPATH uv run --extra test loopx canary premerge --from-git-diff → 0 failures / 0 advisories(diff hygiene、changed-python compile、3/3 catalog canary)

未验证 / 环境说明(如实标注,不当通过):semantic-vocabulary-drift-smoke 在本机需要仓库的 TypeScript npm 依赖,缺依赖时会以 TypeScript production parser failed; run npm ci --ignore-scripts 退出。该失败与本次改动无关——在同一台机器的干净 main worktree 上以完全相同的方式失败——补齐本地未跟踪的根 node_modules 后该 smoke 与 premerge 均通过。未手工在安装后的 man1 环境翻阅页面(该路径由 smoke 的安装断言覆盖)。

边界声明:本 PR 改动 loopx/** 下的帮助面数据,按仓库规则属控制面改动,只提 PR、由维护者合并,作者不做自合并。

我的整体评价

按既有分类把帮助面补完整、并同步生成产物,是解除这条 main 红项的最小且不削弱契约的改动。无阻断性发现,残余风险只有「分类表与 man page 必须同时更新」这一既有约定。

与 #4620(main 上另外三条红 smoke,属控制面运行时改动)合并后,main 的 Full Public Smokes 应恢复全绿,随后重跑 canary promotion-readiness 预检以替换陈旧证据。

English verdict: APPROVE - re-verified on exact head 90fd180: loopx agent-directory is a real top-level command that was missing from both the manual command groups and the explicit help-only set, so the full-public-smoke assertion failed on main. This adds it to the existing group with the existing entry shape and syncs the rendered man page, instead of hiding it in the help-only set. cli-help-manpage-smoke passes, man/loopx.1 == render_manpage() is True, the same smoke still fails on a clean main worktree, and premerge canary reports 0 failures. No blocking finding.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Retained in the runtime/recovery PR reconciliation. This is a useful, complete command-discovery fix: it classifies the shipped agent-directory command and regenerates the manual without inventing a new protocol or expanding runtime scope. Re-ran examples/cli-help-manpage-smoke.py at exact head 90fd1806ea86f1f102181fc10d5608bbae48476f: passed. The neighboring recovery/cache/runtime work is independently staged; this PR needs no accompanying TS refactor.

@Job28703

Copy link
Copy Markdown

Independent review at exact head 90fd1806ea86f1f102181fc10d5608bbae48476f — English verdict: APPROVE.

Verified at this head:

  • The smoke's classification invariant is real: parser_commands == manual | MANPAGE_COMMAND_HELP_ONLY, and agent-directory (dispatched at loopx/cli.py:773, from feat(agents): ship the first local producer of the peer agent directory #4544) is in neither set on main — so the unclassified assertion is the exact failure this PR closes.
  • agent-directory is not in the 58-member MANPAGE_COMMAND_HELP_ONLY frozenset (loopx/help_surface.py:315), so adding the manual entry cannot trip the disjoint assertion (smoke.py:96).
  • The line-count budget (tests/control_plane/test_cli_output_budget.py:789-790) only selects Start here / Daily operator commands / heartbeat-prompt — a maintainer-group row is outside every budget, so "22 passed" holds by construction.
  • Diff is +7/−0 across exactly the two files that must move together (help_surface.py:261-264, regenerated man/loopx.1:219-221); the smoke asserts checked-in manual == render_manpage() output, so both halves are pinned.

No assertion relaxed; classification decision (maintainer-facing, next to register-agent) is the right visibility call.

@huangruiteng
huangruiteng merged commit e0888bb into main Sep 17, 2026
25 of 26 checks passed
@huangruiteng
huangruiteng deleted the codex/manpage-agent-directory-20260917 branch September 17, 2026 13:16
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.

2 participants