Repository navigation
feat: Add /repoman entrypoint skill - #49
Conversation
The RepoMan epic (rossoctl/automation#72) built composable primitives -- setup writer, capability gate, enrolled-set resolver, requirements parser, per-program scanners -- but nothing wired them into the user-facing invocation flow. This adds the entrypoint: a single intent-dispatching /repoman skill that infers setup-vs-activate from ~/.repoman/ state and asks only on genuine ambiguity, always with enumerated options. Implements rossoctl/automation#107; delivers the setup-conversation half of rossoctl/automation#73. Spec: docs/specs/2026-10-12-repoman-entrypoint-skill-design.md (automation). skills/repoman/SKILL.md: - HARD INVARIANT front and center: the driver never writes ~/.repoman/ directly; every mutation goes through a repoman-setup.sh subcommand. - State-inference decision tree (SETUP x INTENT), with the cold-start conflict as the one forced, enumerated question. - Welcome orientation for no-intent branches (new + returning users), a first-class new-user acquisition flow inferred from live state. - Five-question setup conversation mapped to setup subcommands, including Q3 requirement wiring via repoman_parse_requirements -> set-requirements and Q2 Option B org enrollment. - Org-vs-repo detection rule (enrolled-name-wins -> gh probe -> ask), the single place a bare token is classified as an org; both Q2 Option B and reconciliation rule 6 route through it. - Six reconciliation rules keyed to repoman_match_name output count, and the handoff boundary to the (out-of-scope) run path. - Requirements block verified to parse via repoman_parse_requirements: pat_scopes [repo], empty labels, programs [entrypoint]. skills/repoman/scripts/org.sh: - Bundled copy of the automation source org.sh (adds repoman_match_name, the one new primitive this phase introduces). shellcheck-clean at warning severity; byte-identical to the automation source of truth. skills/automation-health-dashboard/scripts/org.sh: - Required parity resync. Adding repoman_match_name to the automation source org.sh moved the shared library; the dashboard's bundled copy is resynced in the same PR cycle to honor the 7-file byte-identical parity contract. No behavior change to the dashboard -- repoman_match_name is additive and unused by it. Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
clawgenti
left a comment
There was a problem hiding this comment.
The /repoman entrypoint skill: SKILL.md is clear and consistent with the automation-side spec, the program→skill-dir map is accurate (all five directories exist), and the bundled org.sh is byte-identical to the automation source as claimed. Two suggestions:
- suggestion (org.sh:226): the bundled copies include
repoman_match_name, which only lands on automationmainvia companion PR rossoctl/automation#110 — merging this first would temporarily break the byte-identical parity contract. - suggestion (SKILL.md:160): the Q1 default
~/repoman/reposfailsvalidate_repos_dir's existence check on a fresh system unless the driver creates it first.
Reviewed by clawgenti using the github-pr-review skill
Address clawgenti review on rossoctl#49: on a fresh system ~/repoman/repos does not exist and repoman-setup.sh init-config never creates --repos-dir, so the skill driver must mkdir -p the chosen repos dir before init-config. It is outside ~/.repoman/, so this does not violate the hard invariant. Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
clawgenti
left a comment
There was a problem hiding this comment.
The Q1 mkdir -p note now matches the companion spec edit in rossoctl/automation#110, and the merge-ordering requirement is documented; the bundled org.sh copies remain byte-identical to the automation#110 source (verified). All checks pass. Ready for human review.
Reviewed by clawgenti using the github-pr-review skill
mrsabath
left a comment
There was a problem hiding this comment.
Well-constructed, documentation-heavy PR. The HARD INVARIANT framing (never write ~/.repoman/ directly; all mutations through repoman-setup.sh) is the right architectural boundary and is stated unambiguously. Every factual claim I could check against the automation source held up.
Verification performed
| Claim | Result |
|---|---|
Both bundled org.sh copies byte-identical to automation#110 source |
pass — all three blobs are 0c411a9ab9c6546b542c63df6c4e682623e6fdfe |
| Program→skill-dir map (5 entries) | pass — all five directories exist on main |
KNOWN_PROGRAMS allowlist matches SKILL.md |
pass — link-health dep-bump pr-review automation-health repo-sync |
| All 5 named subcommands exist | pass — cmd_init_config, cmd_add_repo, cmd_enable_program, cmd_set_output, cmd_set_requirements |
add-repo array-on-stdin form |
pass — documented and implemented |
repoman_parse_requirements output keys |
pass — exact match on all four keys |
Q1 mkdir -p necessity |
pass — cmd_init_config calls validate_repos_dir but never creates the dir |
programs: [entrypoint] not in allowlist |
non-issue — free-form role tag, same as siblings' review/scanner |
| Frontmatter convention | pass — matches siblings |
| DCO sign-off, title lengths | pass — both commits signed, 35 and 44 chars |
Notes on repoman_match_name (no action needed)
The two subtle bash hazards are both correctly handled and well-commented: capture-then-iterate preserves repoman_get_repos' fail-loud exit (a bare pipe would mask it as "zero matches"), and the if guard keeps the loop body's final status 0 so a trailing non-match doesn't return 1 under set -e. Whole-name match via ${line##*/} is substring-safe as claimed. bash 3.2-safe — no mapfile, no associative arrays.
Summary
The two points raised in the earlier review have since been addressed — the Q1 mkdir -p clarification landed in b267833, and merge ordering is now documented in the PR body.
Areas reviewed: Docs/Markdown, Shell (bash), cross-repo parity, commit conventions
Commits: 2, all signed-off: yes
CI status: passing (DCO, pr-title-check)
No must-fix issues — two suggestions/nits inline, neither blocking.
Blocking dependency: rossoctl/automation#110 must merge first (currently OPEN, MERGEABLE, BLOCKED on REVIEW_REQUIRED). This is a sequencing requirement, not a defect in this PR — but it is real: please do not merge this before automation#110.
| missing/empty/malformed `repos.json`. Whole-name match (substring-safe: `cort` | ||
| never matches `cortex`). bash 3.2-safe. The authoritative source and its unit | ||
| test (`tests/test-repoman-match-name.sh`) live in the automation repo; this is a | ||
| bundled copy. |
There was a problem hiding this comment.
suggestion — The "7-file parity contract" is asserted but unenforced anywhere. Neither repo's CI has a parity job: agent-skills runs only pr-verifier/project/self-assign, and automation's tests.yml checks its own function surface (test-lib-inventory.sh asserts the 28-function inventory of program-lib.sh), never the bundled agent-skills copies.
The PR body says "agent-skills CI cannot detect the drift" until #110 lands — but it can't detect drift after #110 lands either, in either direction. Worth tracking a real byte-comparison check; the merge-ordering requirement is currently enforced by human discipline alone.
There was a problem hiding this comment.
Agreed, and you're right that it's unenforced in both directions even after automation#110 lands — the merge-ordering line in the PR body only covers the pre-#110 window. A real byte-comparison parity check is already tracked in #47 ("Add committed dashboard-copy parity test (automation vs agent-skills)"); I confirmed in a sweep today that it's still NOT DONE. I'll leave the contract documentation as-is here and let #47 carry the enforcement so this PR stays scoped to the skill. The ordering remains human-discipline-enforced until #47 lands.
| whole set). The **run path** (capability-check → refresh clones → exec scanner → | ||
| write reports + `_index.json`) is a named follow-on and is **not implemented in | ||
| this skill**. Until it lands, complete reconciliation and **report the resolved | ||
| `owner/name` set you *would* run** — do not attempt to exec a scanner yourself. |
There was a problem hiding this comment.
nit — "The run path … is not implemented in this skill" — consider linking the follow-on issue number here so a reader lands on the tracking item rather than inferring it from epic #72.
There was a problem hiding this comment.
Done in 6f7a53a. The run path is the "program invocation wiring" half of #107 (epic #72) rather than a separate tracker, so I linked both there instead of inventing a new issue number.
Address review nit on rossoctl#49: the run path is the 'program invocation wiring' half of #107 (epic #72), not a separate tracker. Link it so a reader lands on the tracking item instead of inferring from the epic. Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
Adds the
/repomanintent-dispatch skill (#107, epic #72), theuser-facing half of the entrypoint design. Delivers #73's setup-
conversation deliverable.
Merge the companion rossoctl/automation#110 first. It carries
repoman_match_nameinto the automationscripts/org.shsource. Thebundled
org.shcopies in this PR are byte-identical to that source(the 7-file parity contract); if this PR merges first, parity is broken
until #110 lands and agent-skills CI cannot detect the drift.
Changes
skills/repoman/SKILL.md— the intent-dispatching skill: inferssetup-vs-activate from ~/.repoman/ state, 5-question setup flow,
bare-name reconciliation (6 rules), org-vs-repo detection. Asks only
on genuine ambiguity with enumerated options.
skills/repoman/scripts/org.sh— bundled copy (byte-identical toautomation source), carries repoman_match_name.
skills/automation-health-dashboard/scripts/org.sh— parity resync(7-file byte-identical contract).
HARD INVARIANT: the skill never writes ~/.repoman/ files directly —
every mutation goes through a repoman-setup.sh subcommand.
Assisted-By: Claude Code