Skip to content

Commit 9d30555

Browse files
Bordaclaude
andcommitted
refine(oss): skip deprecation for unreleased APIs
- review Step 3b: replace naive __init__.py removal check with release-gated loop — emits DEPRECATION_NEEDED / UNRELEASED_REMOVAL per export based on latest git tag - review Agent 6: add backward-compat caveat — exports added after latest tag must not be flagged as breaking or requiring deprecation - resolve intelligence: add deprecation false-positive filter — downgrade action item to [done] when removed symbol is absent from latest release tag - resolve + review: add PR description drift note — thread consensus is authoritative when PR body diverges from what reviewers agreed upon - sync.sh: pass --approve to /foundry:setup to prevent indefinite hang in non-interactive --print mode --- Co-authored-by: Claude Code <noreply@anthropic.com>
1 parent 0101df0 commit 9d30555

4 files changed

Lines changed: 27 additions & 5 deletions

File tree

‎plugins/oss/.claude-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
"license": "MIT",
1616
"name": "oss",
1717
"repository": "https://github.com/Borda/AI-Rig",
18-
"version": "0.11.1"
18+
"version": "0.11.2"
1919
}

‎plugins/oss/skills/resolve/SKILL.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ Key invariant: location tracks "does this comment have a resolvable PullRequestR
306306
Synthesize contribution motivation (2–3 sentences using PR body + linked issues):
307307
what problem contributor solving, why this approach, expected user-visible outcome.
308308
This becomes the priority lens for conflict resolution.
309+
**PR body = stated intent; thread = authoritative record**: PR descriptions often drift from actual implementation when reviewers request changes mid-review. When PR body conflicts with what thread discussion/reviewer requests agreed upon, thread wins. Use thread consensus to understand what was actually implemented, not original PR description.
309310
310311
Classify EVERY comment using these codes:
311312
[gh][req] change required before merge (reviewer with write access / maintainer)
@@ -319,6 +320,14 @@ Per location:inline comment: if its REST 'id' (= GraphQL databaseId) appears in
319320
list → mark [done] without reading content. All others: apply codes above.
320321
Per location:discussion comment: skip resolved-thread list entirely — PR discussion comments have no resolvable PullRequestReviewThread; apply classification codes directly.
321322
323+
**Deprecation false-positive filter**: Before finalising any action item whose `full_comment_text` requests adding a deprecation warning (keywords: "deprecate", "deprecation", "DeprecationWarning", "deprecated") for a removed argument, parameter, or function:
324+
1. Determine the removed symbol name from comment context or diff.
325+
2. Get latest release tag: `LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null)` # timeout: 6000
326+
3. Check if symbol existed in that release: `git show "$LATEST_TAG" -- <file_path> 2>/dev/null | grep -qF "<symbol>"` # timeout: 6000
327+
4. **Not found in latest tag** → symbol was never released; downgrade item to `[done]`; set Notes to "unreleased API — deprecation not required; clean removal OK".
328+
5. **Found in latest tag** → symbol was released; keep original classification ([gh][req] or [gh][suggest]) — deprecation is legitimately needed.
329+
6. **No tag found** → cannot determine; keep original classification but add Notes "no release tag — deprecation status unknown".
330+
322331
ACTION_ITEM fields: id (sequential int starting at 1), type, change, severity, author,
323332
summary (≤60 chars, truncated at word boundary with …), file, line, url (html_url from
324333
API, blank for report items), full_comment_text, location.

‎plugins/oss/skills/review/SKILL.md‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ Also check explicitly (GT-level findings, not afterthoughts):
372372

373373
**Security scan ownership**: Agent 2 (foundry:qa-specialist) owns all security/vulnerability scanning — runs on every PR unconditionally. Agent 1 (sw-engineer) adds supplementary security scrutiny only when diff explicitly touches auth, input parsing, or serialization logic: flag insecure implementation patterns (e.g. string-formatted SQL, raw `eval()`). No separate security agent spawn.
374374

375-
**Agent 6 — foundry:solution-architect**: Spawns for FEATURE, MIXED, and REFACTOR scope. Public-API PRs (diff touches `__init__.py` exports, Protocols/ABCs, new public classes): evaluate API design, coupling, backward compat. REFACTOR-scope PRs (internal restructure, no new public API): evaluate module boundaries, coupling/cohesion, and whether restructuring introduces new architectural debt — even without public API changes, structural decisions affect maintainability.
375+
**Agent 6 — foundry:solution-architect**: Spawns for FEATURE, MIXED, and REFACTOR scope. Public-API PRs (diff touches `__init__.py` exports, Protocols/ABCs, new public classes): evaluate API design, coupling, backward compat. **Backward-compat caveat for removals**: only flag a removed export as requiring a deprecation period if it was present in the latest published release (`git describe --tags --abbrev=0`). Exports added after the latest tag were never released — clean removal is acceptable and must NOT be flagged as a breaking change or deprecation gap. REFACTOR-scope PRs (internal restructure, no new public API): evaluate module boundaries, coupling/cohesion, and whether restructuring introduces new architectural debt — even without public API changes, structural decisions affect maintainability.
376376

377377
**Agent 7 — foundry:challenger (skip only if `CHALLENGE_ENABLED=false` — pass `--no-challenge` to opt out)**: Adversarial review of design decisions. Attacks assumptions, missing edge cases, security risks, architectural concerns, complexity creep with mandatory refutation step. File-handoff: per preamble above (output to `foundry--challenger.md`). Severity mapping: Blockers → critical/high; Concerns → medium; Nitpicks → low.
378378

@@ -497,8 +497,20 @@ gh pr diff $CLEAN_ARGS -- pyproject.toml 'requirements*.txt' 2>/dev/null # timeo
497497
# Check for secrets accidentally committed — scoped to .py files only (oss:review is Python-only)
498498
gh pr diff $CLEAN_ARGS -- '*.py' 2>/dev/null | grep -iE "(password|secret|api_key|token|private_key|auth_token)\s*[=:]\s*['\"]?[A-Za-z0-9+/._-]{8,}['\"]?" # timeout: 6000
499499

500-
# Check for API stability: are public APIs being removed without deprecation?
501-
gh pr diff $CLEAN_ARGS -- ':(glob)src/**/__init__.py' 2>/dev/null # timeout: 6000
500+
# Check for API stability: removals needing deprecation — only if the removed export was in a published release
501+
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null || echo "") # timeout: 6000
502+
REMOVED_EXPORTS=$(gh pr diff $CLEAN_ARGS -- ':(glob)src/**/__init__.py' 2>/dev/null | grep '^-[^-]' | grep -oP '\b[A-Za-z_]\w*\b' | sort -u) # timeout: 6000
503+
if [ -n "$LATEST_TAG" ] && [ -n "$REMOVED_EXPORTS" ]; then
504+
for export in $REMOVED_EXPORTS; do
505+
if git show "$LATEST_TAG" -- ':(glob)src/**/__init__.py' 2>/dev/null | grep -qF "$export"; then
506+
echo "DEPRECATION_NEEDED: $export (present in $LATEST_TAG — was released)"
507+
else
508+
echo "UNRELEASED_REMOVAL: $export (absent from $LATEST_TAG — clean removal OK, no deprecation needed)"
509+
fi
510+
done # timeout: 15000
511+
elif [ -z "$LATEST_TAG" ]; then
512+
echo "NO_RELEASE_TAG: cannot determine release history — skip deprecation check"
513+
fi
502514

503515
# Check CHANGELOG was updated
504516
gh pr diff $CLEAN_ARGS -- CHANGELOG.md CHANGES.md 2>/dev/null # timeout: 6000
@@ -535,6 +547,7 @@ Spawn **foundry:sw-engineer** consolidator agent with prompt:
535547
> - Codex deduplication: include `foundry--codex.md` unique findings under `### Codex Co-Review`; same file:line raised by both agent and Codex → keep agent version, mark 'also flagged by Codex'.
536548
>
537549
> **Issue alignment (when `issue-*.md` files exist in `$RUN_DIR`):** Include `### Issue Root Cause Alignment` section placed immediately after `### [blocking] Critical`. Per linked issue: state root cause hypothesis, whether PR addresses it (yes / partially / no), whether PR description diverges from issue's stated problem, whether reproduction scenario tested. Any `root cause misalignment` or `scope divergence` finding is at least HIGH severity.
550+
> **PR description drift**: PR descriptions routinely diverge from actual implementation — reviewers request changes mid-review that get implemented but not reflected in PR body. Before flagging `scope divergence`, cross-check PR thread and review comments to determine what was actually agreed upon; description diverges from *thread consensus* (not original description) is the signal worth flagging.
538551
>
539552
> **CI status:** If `CI_RED=true` (literal value expanded by orchestrator): set report header `CI:` field to `failing — [CI_FAILING_CHECKS literal list]`. Otherwise set to `passing` or `pending` per `gh pr checks` output.
540553
>

‎sync.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ for p in "${PLUGINS[@]}"; do
116116
done
117117

118118
echo "Initializing Foundry (sync settings + symlinks)..."
119-
claude --print "/foundry:setup"
119+
claude --print "/foundry:setup --approve"
120120

121121
fi # SYNC_CLAUDE
122122

0 commit comments

Comments
 (0)