Skip to content

feat(sleep): report per-skill-group gate decisions - #187

Open
Bogdan (Dan) Baciu (bogdanbaciu21) wants to merge 2 commits into
microsoft:mainfrom
bogdanbaciu21:skoc-006-per-group-gate-report
Open

feat(sleep): report per-skill-group gate decisions#187
Bogdan (Dan) Baciu (bogdanbaciu21) wants to merge 2 commits into
microsoft:mainfrom
bogdanbaciu21:skoc-006-per-group-gate-report

Conversation

@bogdanbaciu21

Copy link
Copy Markdown
Contributor

Summary

Sixth review-sized slice of #120: make a multi-skill night's gate decisions
legible per skill, without breaking readers that only know single-skill reports.

  • new types.SkillGroupReport: one row per skill with its own status,
    accepted, gate_action, baseline_score, candidate_score, n_tasks,
    applied/rejected edit counts, and reason;
  • SleepReport.skill_groups: List[SkillGroupReport], default empty — a
    single-managed-skill night serializes exactly as before plus "skill_groups": [],
    and the existing flat summary fields stay authoritative for older consumers;
  • multi_skill.skill_group_reports(outcomes) builds those rows from each group's
    own evidence, in first-seen order;
  • GroupConsolidation now records n_tasks, so a skipped or failed group can
    report how much input it had without a side table.

A skipped or failed group reports its reason with zeroed scores rather than
inheriting a neighbour's numbers, and an accepted group's row is unaffected by a
weak group's rejection — no group can block or borrow another's evidence.

Stacked on #186 (skoc-005-consolidate-skill-groups), which adds
multi_skill.py. Reviewed in order this diff is just the reporting commit.

Tests

  • python -m pytest -q tests/test_sleep_skill_group_report.py → 8 passed
  • python -m pytest -q → 574 passed, 7 skipped (base main at 8304e6c:
    556 passed, 7 skipped)
  • python -m ruff check skillopt_sleep/types.py skillopt_sleep/multi_skill.py tests/test_sleep_skill_group_report.py
    → All checks passed

Covered: row defaults, strong-vs-weak groups keeping their own scores, first-seen
row order, skipped/failed rows carrying reasons and no borrowed scores, rows from
a real mixed MockBackend night, empty skill_groups on a single-skill report,
legacy keyword construction, and serialization alongside the flat summary.

Refs #120

Copilot AI lite review requested due to automatic review settings July 28, 2026 16:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds per-skill-group gate reporting for multi-skill Sleep nights, while preserving the existing single-skill summary fields for backward compatibility with older report readers.

Changes:

  • Introduces types.SkillGroupReport and adds SleepReport.skill_groups (default empty) so multi-skill nights can report one gate-evidence row per skill.
  • Adds multi_skill.skill_group_reports(outcomes) to build per-group report rows from each group’s own consolidation/gate evidence.
  • Adds/extends deterministic stdlib-only tests covering row defaults, ordering, isolation of evidence, and legacy/single-skill compatibility.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
skillopt_sleep/types.py Adds SkillGroupReport and extends SleepReport with skill_groups for backward-compatible serialization.
skillopt_sleep/multi_skill.py Implements group consolidation outcomes and converts outcomes into per-skill report rows.
tests/test_sleep_multi_skill.py Tests independent per-skill-group consolidation behavior and failure/skip isolation.
tests/test_sleep_skill_group_report.py Tests per-skill-group gate row reporting and SleepReport compatibility/serialization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread skillopt_sleep/multi_skill.py Outdated
Comment on lines +59 to +62
Returns one entry per input group, keyed by skill name and ordered
first-seen. A group is ``skipped`` when it is unusable (blank name, no
tasks, repeated name) and ``failed`` when its own consolidation raised; both
leave every other group's decision untouched.
Comment on lines +69 to +72
name = (group.skill_name or "").strip()
if not name:
out.setdefault("", GroupConsolidation("", SKIPPED, reason="group has no skill name"))
continue
@bogdanbaciu21

Copy link
Copy Markdown
Contributor Author

Thanks for the welcome on #120. To keep review load bounded and follow the incremental shape Yif-Yang suggested, I'm closing this PR for now and will reopen it once #182 (the harvesting slice) lands or the maintainer asks for the next slice. The branch stays on my fork so this can be re-opened as-is. Happy to restructure if a different cadence is preferred.

devin-ai-integration Bot and others added 2 commits August 6, 2026 06:50
Add SkillGroupReport plus SleepReport.skill_groups (default empty) and build the
rows from each group's own baseline, candidate score, decision, and reason, so a
weak group can neither block nor borrow a strong group's evidence and older
single-group report consumers keep working.

Refs microsoft#120
… count

Two defects in the per-group report, both found by testing the docstring
against the code rather than reading it:

- skill_group_reports said "one report row per group". It builds one row per
  entry in `outcomes`, which is keyed by skill name — so groups that collapsed
  onto a shared key upstream are already one entry and cannot each get a row.
  Measured: four groups in, two rows out. This is the same claim that was
  corrected on consolidate_groups in microsoft#186; it had been copied down here.

- A group skipped for a blank name reported n_tasks=0 even when it carried
  tasks. The row is meant to be that group's own evidence, so a zero count
  misstates why it was dropped — it reads as "empty group" when the real
  reason was the missing name. The count is now carried onto the skipped row.

Both are pinned by tests: one asserting rows track outcomes and stay fewer
than the input groups, one asserting a blank-named group still reports its
real task count.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Ready to approve

The changes appear backward-compatible (default-empty skill_groups) and are well-covered by targeted tests validating ordering, skipped/failed behavior, and serialization.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

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