Skip to content

feat: Add --repos flag to scope weekly report - #32

Merged
rubambiza merged 5 commits into
rossoctl:mainfrom
rubambiza:feat/report-core-repos-scope
Aug 20, 2026
Merged

feat: Add --repos flag to scope weekly report#32
rubambiza merged 5 commits into
rossoctl:mainfrom
rubambiza:feat/report-core-repos-scope

Conversation

@rubambiza

@rubambiza rubambiza commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a --repos flag to the github-weekly-report generator so callers can
scope a report to an explicit set of repos instead of discovering every repo
in the org. This is the generator half of scoping the weekly report to the
curated core repos; the automation wrapper that supplies the allowlist lives
in rossoctl/automation.

Backward compatible: when --repos is omitted, the report discovers all repos
in the org exactly as before.

Changes

  • scripts/report.py — add --repos OWNER/REPO ...; when present, skip
    org-wide discovery and report on exactly those repos. Thread the same repo
    set into the epic tracker so epics are scoped consistently.
  • scripts/epic-tracker.py — add --repos; when present, scan only those
    repos instead of enumerating the org.
  • scripts/report.py — add a breadcrumb to the report header linking back to
    the github-weekly-report skill, so a reader of a generated issue can find and
    improve the generator (matches the pattern requested in
    Feat: Add a link back to the skill when opening a link issue (breadcrumb) automation#41).
  • SKILL.md — document --repos and note that automation deployments pass
    the core-repo allowlist via the weekly-report.sh wrapper.

Testing

Ran the generator scoped to explicit repos (correct section count, no org
discovery) and with --repos omitted (identical org-wide output). Header
renders the breadcrumb link.

Fixes #29

Assisted-By: Claude Code

Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com>

Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com>

Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com>

Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
Link the report header back to the github-weekly-report skill so a
reader can find and improve the generator, matching the breadcrumb
pattern requested in rossoctl/automation#41.

Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com>

Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
@rubambiza rubambiza added the ready-for-ai-review Request automated AI code review from clawgenti label Aug 18, 2026

@clawgenti clawgenti 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.

Adds --repos OWNER/REPO ... to report.py and epic-tracker.py so callers can scope the weekly report to an explicit repo set instead of org-wide discovery, and threads the same set into the epic tracker for consistency — plus SKILL.md docs and a report-header breadcrumb linking back to the skill.

All checks pass. Ready for human review.


Reviewed by clawgenti using the github-pr-review skill

@rubambiza rubambiza self-assigned this Aug 18, 2026
@rubambiza rubambiza added ready-for-human-review AI review passed, ready for human reviewer and removed ready-for-ai-review Request automated AI code review from clawgenti labels Aug 18, 2026

@esnible esnible left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Scoping works for the intended single-org case and the backward-compatible default (--repos omitted → org-wide discovery) is preserved cleanly. Commits are all signed off with conventional prefixes, and CI is green.

One blocking issue: --repos advertises OWNER/REPO but discards the owner, so passing a repo from a different org silently reports on the wrong repo. Details inline.

Areas reviewed: Python, Docs
Agent/IDE config (.claude/.vscode): none
Commits: 4, all signed-off: yes
CI status: passing (DCO, PR title, project automation)

item = item.strip()
if not item:
continue
_, _, name = item.rpartition('/')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

must-fix: the owner half of OWNER/REPO is parsed and then thrown away, so a repo outside --org is silently reported against the wrong owner.

rpartition keeps only the tail, and every downstream fetch rebuilds the slug from --org: report.py at get_merged_prs/get_open_prs/get_new_issues/get_open_issue_count/get_ci_runs (all -R f'{org}/{repo}'), and epic-tracker.py:47 in get_epics. Nothing validates that the parsed owner matches --org.

Reproduced with the function as written, --org rossoctl:

--repos value          bare name    actual query target      reattributed?
rossoctl/operator      operator     rossoctl/operator        no
otherorg/operator      operator     rossoctl/operator        YES  <-- bug
a/b/c                  c            rossoctl/c               YES  <-- bug

The failure mode is the bad kind: no error, just a report whose header says one thing while the data came from another org's repo of the same name. a/b/c is also accepted rather than rejected.

Two ways out, depending on the intended contract:

  1. Validate and reject (smaller fix, matches the flag's current single-org usage) — if the value contains a / and the owner differs from --org, exit with an error, or at minimum warn on stderr:

    owner, sep, name = item.rpartition('/')
    if sep and owner != org:
        sys.exit(f"--repos entry '{item}' is not in --org '{org}'")

    This needs org threaded into normalize_repo_args.

  2. Honor the owner end-to-end — keep the full slug and pass -R <owner>/<name> through both scripts, so cross-org sets genuinely work as the OWNER/REPO metavar implies.

If cross-org is out of scope for now, option 1 plus a metavar change to REPO (or documenting that entries must be within --org) would make the contract honest.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in f4ae90e (option 1 — validate and reject within --org).

normalize_repo_args now takes org and accepts only a bare name or an owner-qualified name whose owner matches --org; a differing owner or a malformed entry (a/b/c) exits with a clear error instead of silently reattributing. Verified against your repro table:

operator            -> {name: operator}
rossoctl/operator   -> {name: operator}
otherorg/operator   -> REJECTED: not in --org rossoctl
a/b/c               -> REJECTED: malformed

Also changed the metavar OWNER/REPO -> REPO and documented the within-org contract, per your suggestion. Kept cross-org out of scope for this flag — broadening to arbitrary owners is a separate design question I am taking to a discussion.

@esnible esnible left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Claude considers the org vs org/name confusion a "must-fix", but I will lower my response to "Comment".

@esnible
esnible dismissed their stale review August 18, 2026 18:17

Owner-stripping is unreachable via the weekly-report.sh wrapper; downgrading to non-blocking.

@rubambiza

Copy link
Copy Markdown
Contributor Author

@esnible Thanks for the review and downgrade to comment. I did consider this design decision, and I opted for a simple repo so that the report headers for per-repo deep dives would come out less cluttered with the org/repo format (more of a cosmetic preference). However, this is a good callout, and a good design contract is more important than pretty printing. I will address in an upcoming commit.

@rubambiza

Copy link
Copy Markdown
Contributor Author

Cross-linking the companion wrapper PR: rossoctl/automation#59 (weekly-report.sh) is the caller of the --repos contract added here.

Ordering: automation#59 should merge after this PR — its REPORT_PY default resolves to the deployed github-weekly-report generator, so the host needs the merged, owner-attribution-corrected report.py from #32 in place first. Flagged on #59 as well.

Note for the owner-attribution must-fix on report.py:43: the automation wrapper feeds --repos values via get_core_repos, which emits $ORG/name where the owner is always $ORG by construction — so the caller stays within-org and is compatible with the validate-and-reject-within-org contract.

Assisted-By: Claude Code

normalize_repo_args parsed OWNER/REPO and discarded the owner, while
every downstream fetch rebuilds the slug as f'{org}/{name}'. An entry
like 'otherorg/operator' was therefore queried as '{--org}/operator'
and silently reported against the wrong owner; a malformed 'a/b/c' was
also accepted.

Scope the flag to a single owner: accept a bare name or an
owner-qualified name whose owner matches --org, and exit with a clear
error otherwise (or on a malformed entry). Update the metavar to REPO
and document the within-org contract.

The automation wrapper (rossoctl/automation#59) emits '$ORG/name'
(owner always == $ORG), so it stays compatible with this contract.
Cross-owner repo sets are out of scope for this flag; broadening to
arbitrary owners is a separate design discussion.

Addresses esnible's must-fix review on rossoctl#32.

Assisted-By: Claude Code (Anthropic AI) <noreply@anthropic.com>

Signed-off-by: Gloire Rubambiza <gloire@ibm.com>
@rubambiza
rubambiza merged commit 85449be into rossoctl:main Aug 20, 2026
2 checks passed
@rubambiza
rubambiza deleted the feat/report-core-repos-scope branch August 20, 2026 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human-review AI review passed, ready for human reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature: Update weekly report skill to focus on core repos

3 participants