feat: enforce R-FC-014 (recently-Done item without Cycle -> current cycle) hourly - #61
Merged
Merged
Conversation
…ycle) hourly Codifies the "recently completed items need a Cycle" sweep-playbook check into a numbered rule with mechanical enforcement, mirroring R-FC-012 but scoped to items moved to Done in the last day instead of active items updated in the last 3 days. DoneCycleRule subclasses CycleRule, reusing its apply_one and mutation-log guard, and only overrides select()'s query. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AkjQydxZny5DgxZi7BVmU2
There was a problem hiding this comment.
Pull request overview
This PR adds a new mechanical field-completeness rule (R-FC-014) to automatically assign the current Cycle to items that are in 🎉 Done, have no Cycle, and were updated within the last day, closing a previously manual “recently done” gap in Cycle hygiene.
Changes:
- Implement
DoneCycleRule(R-FC-014) by subclassingCycleRuleand overriding onlyselect()to target Done items with a 1-day recency window. - Register the new rule in the default rule set and update CLI tests to include it.
- Document R-FC-014 in the mechanical rules README and the board rule canon (
field-completeness.md), including the API call pattern table.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| foc-mechanical-rules/foc_mechanical_rules/rules/cycle.py | Adds DoneCycleRule to reuse Cycle assignment logic with a Done-scoped query. |
| foc-mechanical-rules/foc_mechanical_rules/registry.py | Registers R-FC-014 in the default rule set. |
| foc-mechanical-rules/tests/test_cycle_rule.py | Adds unit tests for R-FC-014 query shape and apply_one reuse. |
| foc-mechanical-rules/tests/test_cli.py | Updates the “run all rules” assertion to include R-FC-014. |
| foc-mechanical-rules/README.md | Documents the new rule and its API call pattern. |
| foc-board-rules/field-completeness.md | Adds the canonical prose definition for R-FC-014. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…lter attribute Match R-FC-014's lookback window to R-FC-012's (3 days instead of 1) so the two rules differ only in which side of Done they target. DoneCycleRule now overrides a single _STATUS_FILTER class attribute instead of duplicating select() entirely. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AkjQydxZny5DgxZi7BVmU2
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Suppressed comments (2)
foc-mechanical-rules/README.md:53
- This table note says
DoneCycleRule"overrid[es] only"_STATUS_FILTER, but the subclass also changes metadata (id/doc_url). Consider rewording to avoid a literally incorrect claim while keeping the point that behavior is reused.
| R-FC-014 (cycle) | 1 paginated board query (Done items only, same 3-day window as R-FC-012) | 1 GraphQL query (iterations, shared helper with R-FC-012) | none | Batched, same mechanism as R-FC-012 (`DoneCycleRule` subclasses `CycleRule`, overriding only the `_STATUS_FILTER` class attribute) |
foc-mechanical-rules/foc_mechanical_rules/rules/cycle.py:293
DoneCycleRule's docstring says it targets items that "just moved to Done", but the selection is based on current status +updated:...and doesn't actually observe the status transition. Consider rewording to avoid implying a capability the query doesn't have.
"""Same "no cycle -> assign current cycle" logic as R-FC-012, scoped to
items that just moved to Done instead of items that are still active.
Per Copilot review feedback: the rule doesn't detect a Done transition event, it filters on current status plus updated:>@today-3d, same as R-FC-012 does for its own status. "moved to Done" overclaimed what the query actually checks. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AkjQydxZny5DgxZi7BVmU2
_STATUS_FILTER isn't literally the only class attribute DoneCycleRule overrides (id/doc_url also differ) -- clarify these docstrings and the test comment refer to the selection-query behavior specifically. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AkjQydxZny5DgxZi7BVmU2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
foc-board-rules/sweep-playbook.md's "Recently Done" stage), not as a numbered, automated rule — R-FC-012 explicitly excludes Done items, so nothing mechanical covered this gap before.DoneCycleRulesubclassesCycleRule, reusing itsapply_one(including the "don't re-add a cycle a human cleared" mutation-log guard) andselect()'s query shape, overriding only the_STATUS_FILTERclass attribute (status:"🎉 Done"vs. R-FC-012's-status:"🎉 Done") — both share the sameupdated:>@today-3dwindow.registry.py; documented infoc-board-rules/field-completeness.mdandfoc-mechanical-rules/README.md(rules table + API-call-pattern table).Test plan
uv run pytest -qinfoc-mechanical-rules/(63 passed)DoneCycleRuletests: select() query shape, apply_one reuse,Rulesubclass checktest_cli.py's full-rule-set assertion to includeR-FC-014🤖 Generated with Claude Code
https://claude.ai/code/session_01AkjQydxZny5DgxZi7BVmU2