|
| 1 | +--- |
| 2 | +description: Reproduce, diagnose, fix, and test a GitHub issue on a reviewable local branch |
| 3 | +argument-hint: <issue-number | issue-URL> [extra context] |
| 4 | +allowed-tools: Bash(gh issue view:*), Bash(git checkout:*), Bash(git switch:*), Bash(git branch:*), Bash(git status:*), Bash(git diff:*), Bash(git add:*), Bash(python -m pytest:*), Bash(python:*), Bash(export:*), Read, Grep, Glob, Edit, Write, Agent, Task, TodoWrite |
| 5 | +--- |
| 6 | + |
| 7 | +# Fix a SageMaker Python SDK issue |
| 8 | + |
| 9 | +Drive an issue from `aws/sagemaker-python-sdk` to a **reviewable local branch**: reproduce it, |
| 10 | +find the root cause, write a v3-correct fix, and back it with tests. **Stop before pushing or |
| 11 | +opening a PR** — leave the branch and a written summary for the human to review. |
| 12 | + |
| 13 | +## Input |
| 14 | + |
| 15 | +`$ARGUMENTS` is the GitHub issue number or URL, optionally followed by extra context/hints. |
| 16 | +If it's empty, ask for an issue number or URL and stop. |
| 17 | + |
| 18 | +## Repo facts (this monorepo) |
| 19 | + |
| 20 | +- Four namespace packages: `sagemaker-core`, `sagemaker-train`, `sagemaker-serve`, |
| 21 | + `sagemaker-mlops`, each with `src/` and `tests/unit/`. |
| 22 | +- **v3 is the golden rule.** Follow `AGENTS.md` — never introduce banned v2 patterns |
| 23 | + (`Estimator`, framework estimators, `estimator.fit`, `sagemaker.model.Model`, |
| 24 | + `sagemaker.workflow.*`, etc.) into fix code, tests, or examples. |
| 25 | +- **Running unit tests** (v2 install shadows the v3 namespace, so PYTHONPATH is required). |
| 26 | + From the package dir, e.g. for `sagemaker-train`: |
| 27 | + ```bash |
| 28 | + cd sagemaker-train |
| 29 | + export PYTHONPATH="$PWD/../sagemaker-core/src:$PWD/src:$PWD/../sagemaker-serve/src:$PWD/../sagemaker-mlops/src" |
| 30 | + python -m pytest tests/unit/<path> -q |
| 31 | + ``` |
| 32 | + Adjust the first `$PWD/src` to whichever package you're testing. Pydantic v1 |
| 33 | + `@validator`/`@root_validator` deprecation warnings are expected noise. |
| 34 | + |
| 35 | +## Steps |
| 36 | + |
| 37 | +Track progress with TodoWrite. Do the steps in order; do not skip reproduction. |
| 38 | + |
| 39 | +### 1. Fetch the issue — including the full comment thread |
| 40 | +Run `gh issue view <n> --repo aws/sagemaker-python-sdk --comments` to pull the title, body, |
| 41 | +labels, **and the entire discussion**. Extract: the failing API/module, the reported behavior |
| 42 | +vs. expected, any repro snippet, versions, and stack traces. State which of the four packages |
| 43 | +it most likely lives in. |
| 44 | + |
| 45 | +**Read the comments before writing any code** and check the maintainer stance. STOP and report |
| 46 | +back (do not fix) if the thread shows any of: |
| 47 | +- a maintainer **reclassified** it (e.g. bug → feature request) or **declined / won't-fix** it; |
| 48 | +- it targets an **unsupported configuration** (e.g. Windows — the SDK supports Unix/Linux/Mac |
| 49 | + only) where maintainers have said they won't support it; |
| 50 | +- it's a **duplicate**, already fixed, or there's an **existing open PR** for it; |
| 51 | +- it's a pure question or docs request. |
| 52 | + |
| 53 | +In those cases, summarize the maintainer position and ask how to proceed rather than assuming |
| 54 | +the triage label (e.g. a spreadsheet "bug" tag) is authoritative — the issue thread wins over |
| 55 | +external triage. |
| 56 | + |
| 57 | +### 1b. Scope gate — is this a large feature request? |
| 58 | +Before starting work, classify the issue as **in-scope** (a bug fix, a type/annotation or docs |
| 59 | +correction, or a small self-contained enhancement — the kind of change that lands in roughly one |
| 60 | +focused PR touching a bounded set of files) vs. a **large feature request**. |
| 61 | + |
| 62 | +Treat it as a **large feature request** — and STOP — when any of these hold: |
| 63 | +- it asks for a **new public API, class, or capability** rather than fixing existing behavior |
| 64 | + (e.g. "add support for X", "make the SDK able to Y"); |
| 65 | +- delivering it would need **design decisions, a new module, cross-package changes, or new |
| 66 | + external dependencies**, or would plausibly span multiple PRs; |
| 67 | +- it's labeled `type: feature` / `feature request` (or was reclassified as one) and is not a |
| 68 | + trivial addition; |
| 69 | +- the effort is clearly beyond "quick win" (e.g. the triage doc marks it larger than S), or you |
| 70 | + can't scope it to a concrete, bounded change after reading the code. |
| 71 | + |
| 72 | +When it's a large feature request, **do NOT fix it. Backlog it**: report a one-paragraph summary |
| 73 | +(what it asks for, rough scope, why it's out of scope for this quick-fix flow) and stop. Do not |
| 74 | +create a branch. If a tracking sink is in use (e.g. the Pippin backlog doc), note it there as |
| 75 | +"backlogged — large feature request" rather than as a completed fix. When unsure whether |
| 76 | +something is a small enhancement or a large feature, ask rather than starting to build it. |
| 77 | + |
| 78 | +### 1c. v2-vs-v3 relevance check (older issues) |
| 79 | +Many older issues were filed against **v2** (they cite a v2 version like `1.x`/`2.x`, or use v2 |
| 80 | +imports such as `sagemaker.estimator`, `sagemaker.tuner`, `sagemaker.pytorch`, `sagemaker.model`, |
| 81 | +`sagemaker.workflow.*`). This repo is **v3**. Before fixing such an issue, confirm the bug is |
| 82 | +still relevant here: |
| 83 | +- **Locate the equivalent v3 code** for the reported behavior (map the v2 symbol to its v3 home |
| 84 | + via `AGENTS.md` / `migration.md`; grep the four `src/` trees). The reporter's v2 snippet is a |
| 85 | + description of intent — translate it to the v3 API, don't run it verbatim. |
| 86 | +- **STOP and report (do not fix)** if: |
| 87 | + - the feature was **removed in v3 with no replacement** (e.g. MXNet, Chainer, RLEstimator, |
| 88 | + Training Compiler) — nothing to fix here; |
| 89 | + - the v3 code path **does not have the bug** — the defect was already fixed or the v3 redesign |
| 90 | + doesn't exhibit it. Show the v3 code that proves it's fine. |
| 91 | +- **Only proceed** once you've confirmed the defect actually reproduces (or is clearly present by |
| 92 | + inspection) in the **v3** code — not merely that it existed in v2. Reproduce against v3 in |
| 93 | + step 3, and write the fix and tests against the v3 module. |
| 94 | + |
| 95 | +### 2. Create a working branch |
| 96 | +From a clean tree, `git switch -c fix/issue-<n>-<slug>`. If the tree is dirty, stop and report |
| 97 | +it rather than mixing unrelated changes. Never work on `master`. |
| 98 | + |
| 99 | +### 3. Reproduce (fork subagent) |
| 100 | +Dispatch a **fork** subagent to reproduce the bug. It should write a minimal repro (a script or |
| 101 | +a temporary failing test), run it with the PYTHONPATH setup above, and report the exact |
| 102 | +observed failure (traceback, wrong value) — or report that it could NOT reproduce, with what it |
| 103 | +tried. Do not proceed to a fix until repro is confirmed **or** you've explicitly decided the |
| 104 | +issue is valid-by-inspection (e.g. an obvious logic error) and said why. |
| 105 | + |
| 106 | +### 4. Explore the code (Explore subagent) |
| 107 | +Dispatch an `Explore` (or fork) subagent to map the code around the failure: the entry point, |
| 108 | +call chain to the fault, related tests in `tests/unit/`, and any nearby patterns/conventions the |
| 109 | +fix must match. Ask it for `file:line` anchors and the conclusion, not file dumps. |
| 110 | + |
| 111 | +### 5. Write the fix |
| 112 | +Edit the source to address the **root cause**, not the symptom. Keep the change focused and |
| 113 | +match surrounding style. No hardcoded account IDs, ARNs, regions, or bucket names. Keep it v3. |
| 114 | + |
| 115 | +### 6. Add / update tests |
| 116 | +Add or update unit tests under the owning package's `tests/unit/` that **fail without the fix |
| 117 | +and pass with it**. Run the relevant subset with the PYTHONPATH setup and paste the real result. |
| 118 | +Only consider an integ test (`tests/integ/`) when the bug genuinely needs AWS to exercise; if |
| 119 | +so, write it but note it's CI-only and don't require it to pass locally. |
| 120 | + |
| 121 | +### 6b. Validate at the strongest feasible level (before AND after) |
| 122 | +A passing mocked unit test is the floor, not proof. Validate the fix as close to the real failure |
| 123 | +as you can, and demonstrate the defect **before** the fix and its absence **after**: |
| 124 | +- **Reproduce the actual reported error, deterministically and offline, when possible.** If the |
| 125 | + bug is about an external contract, exercise that contract directly rather than asserting on |
| 126 | + mocks: e.g. validate params against the real boto **service model** with |
| 127 | + `botocore.validate.ParamValidator` (offline, no network/credentials); reproduce a type-checker |
| 128 | + error by running the real tool (`mypy`) against a translated repro; run the real function for |
| 129 | + in-memory logic. State which level you reached and what you could NOT cover. |
| 130 | +- **Prove "fails without the fix" against a real baseline.** `git stash push <file>` only stashes |
| 131 | + **uncommitted** changes — once the fix is committed on the branch it stashes nothing and you'll |
| 132 | + falsely "confirm" a fail. Use `git checkout master -- <file>` as the negative control, then |
| 133 | + restore. BUT: if you haven't committed the fix yet, the branch `HEAD` still equals `master`, so |
| 134 | + `git checkout HEAD -- <file>` will restore the **unfixed** file and silently wipe your edit. |
| 135 | + Safe recipe: **commit the fix first**, then `git checkout master -- <file>` (run the test → it |
| 136 | + fails), then `git checkout HEAD -- <file>` (now HEAD has the fix → it passes). After any such |
| 137 | + dance, re-grep the file to confirm your fix is actually present before continuing. |
| 138 | +- **Never let `|| echo`, `|| true`, or a grep-with-no-match masquerade as success.** Check the |
| 139 | + tool's real exit code and read its actual output; a command that errored out is not a pass. |
| 140 | +- **Live AWS calls** only when no offline reproduction exists. Prefer ReadOnly/least-privilege, |
| 141 | + create only resources you clean up, confirm the account is non-production, and never run |
| 142 | + destructive operations. Most SDK bugs (serialization, typing, arg wiring, in-memory logic) are |
| 143 | + fully provable offline — reach for a live call last, not first. |
| 144 | +- Some things genuinely can't be validated here (e.g. Windows-only behavior with no Windows host, |
| 145 | + a real distributed training run). Say so plainly rather than implying coverage you don't have. |
| 146 | + |
| 147 | +### 7. Verify |
| 148 | +Run the affected package's relevant unit subset once more and confirm green. |
| 149 | + |
| 150 | +### 8. Independent review (fix-reviewer subagent) |
| 151 | +Dispatch the **`fix-reviewer`** subagent (fresh agent, not a fork — it must judge |
| 152 | +independently). Give it the issue number/URL and the branch name. It re-derives correctness |
| 153 | +from the issue and diff, hunts backwards-incompatibilities (callers/readers, serialized |
| 154 | +formats, semantics for existing inputs), and independently reproduces + runs adversarial |
| 155 | +checks. Relay its verdict. If it returns `REQUEST CHANGES` with a BLOCKER/MAJOR finding, |
| 156 | +address it and re-run the reviewer before summarizing. |
| 157 | + |
| 158 | +### 9. Summarize |
| 159 | +Report: |
| 160 | +- **Root cause** — what was actually wrong, with `file:line`. |
| 161 | +- **Fix** — what changed and why it's correct. |
| 162 | +- **Tests** — what you added and the pass/fail output (verbatim if anything failed). |
| 163 | +- **Review** — the `fix-reviewer` verdict and any findings you actioned. |
| 164 | +- **Branch** — the branch name and `git diff --stat`. |
| 165 | +- **Next step** — that it's ready for human review; do NOT push or open a PR. |
| 166 | + |
| 167 | +## Constraints |
| 168 | +- You MUST stop at the local branch. Do NOT `git push`, `gh pr create`, or otherwise publish. |
| 169 | +- You MUST report test failures faithfully, with output — never claim green without running. |
| 170 | +- You MUST NOT introduce v2 patterns; self-check the diff against `AGENTS.md` before summarizing. |
| 171 | +- If reproduction fails, say so plainly and ask how to proceed instead of guessing a fix. |
0 commit comments