بنقرة واحدة
pre-review
Prepare a PR for review by a team member. Use when the user asks you to perform a pre-review.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Prepare a PR for review by a team member. Use when the user asks you to perform a pre-review.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | pre-review |
| description | Prepare a PR for review by a team member. Use when the user asks you to perform a pre-review. |
A PR (corresponding to the current checked-out branch, or one the user has told you) is ready for review. That review is going to be performed by another team member, but that member has limited time. You are tasked with performing a "pre-review" to make this PR as easy to review as possible.
For example, this could mean:
Focus specifically on making the reviewer's job easier, not on making the PR perfect. Issues involving readability might be particularly important, especially if the changes are hard to understand or the reason for them is not immediately clear.
Begin by taking a look at the PR, as well as its description and title, and considering areas for improvement. Communicate with the user about whether:
When leaving comments on a PR, always start your comment with "Pre-review agent: ".
Before reporting the PR ready, walk the diff and explicitly perform each of these passes. Report findings even if none — silence on a pass means it wasn't done. Address findings inline where small; surface them as comments or to the user where they need a decision.
For every new branch, default, fallback, optional field, union member, or aggregation introduced by this PR, name what happens when its input is missing, empty, None, 0.0, a default-valued weight, or a key not present in the prior schema. If the answer is "the code takes the default branch quietly," flag it. Specifically check:
The user's reviewers catch this class of issue more reliably than the author's AI agent does. Treat it as the highest-priority pass.
For every function, method, or code path that was modified (not newly added) by this PR, decide whether the change alters what existing callers observe. AI-generated edits regularly drift the semantics of code they "clean up" — particularly:
BatchData-like objects, dicts, dataclasses) that downstream code relied on.For each behavior change found: if intended, it should be stated in the PR description (and a docstring updated if the public contract shifted); if unintended, revert it. If unclear, seek clarification from the author. Do not let "incidental cleanup" through.
Keep an eye out also for unintended effects of intended behavior changes, especially if the change is in a widely-used utility function or a core code path.
For every test added or modified to cover new behavior, confirm the assertion would actually fail if the new code path were no-oped out. Flag any test whose inputs make masked/unmasked, weighted/unweighted, filtered/unfiltered, or seeded/unseeded outputs numerically identical (e.g., all-ones inputs for a masking test, identical values across channels for a per-channel test, single-element collections for a multi-element behavior). Strengthen inputs in place where the fix is small.
When the PR adds an option, field, or behavior to one builder, config, or registry entry, list the siblings in the same registry or module and decide explicitly for each whether it applies. Common sibling sets in this repo: SFNO variants (SFNO, NoiseConditionedSFNO, etc.), the ace/coupled mirror modules, builder registries, aggregator-config types. If a sibling is intentionally skipped, that decision belongs in the PR description.
The only hard back-compat guarantee in this repo is that prior trained checkpoints must still load for inference. Resuming an in-progress training job across code or config changes is explicitly not guaranteed (see AGENTS.md). Check:
Recommend splitting the PR if more than one of these is true: it touches >20 files; it introduces a new typed config and changes behavior and adds a back-compat shim; it bundles a refactor with a new feature. Past PRs that hit two of these took 5–8 days to merge and often attracted reviewer-authored companion PRs; splitting the scaffolding from the migration usually cuts that to 1–2 days per piece.
Note: an fme/ace change and its fme/coupled mirror are not a reason to split — they should travel together (or, if separated, the second PR's description should cite the first's review) so reviewers don't re-derive the same questions twice.
@abstractmethod or @final. Exception: __init__ on nn.Module subclasses.@abstractmethod).Quick scan for patterns that AI-generated code drops in and human reviewers consistently flag:
Any return types where a concrete type is available.isinstance + type: ignore pairs (prefer refactoring the type).cb → callback).We generally follow a "builder pattern" for configuration in this repo: dataclasses we load using dacite (a Config), usually paired with an implementation class that the config's build() constructs.
The rules to check are:
_. Reading config.some_field from anywhere else (an implementation class, a free function, or another config) is a violation; expose what callers need as a @property or method.Config class is paired with an implementation class, the builder should construct sub-objects from any sub-configuration fields and pass those to the implementation class, rather than the implementation class building those sub-objects. The implementation class receives built collaborators, never a sub-config to build itself.Exceptions:
build() constructs, and that impl may read the config's fields. If the config is a leaf, i.e. none of its fields are themselves dataclasses, your work is done on this point. list[Config], dict[str, Config], and Config | None all make a config non-leaf. If the config is non-leaf, consider whether the code is improved by packing the scalars the impl needs into a separate, non-dacite-loaded leaf dataclass passed as an argument. Would this better separate concerns and make the impl easier to test? If so, recommend doing so, perhaps strongly if it's a significant improvement, but it's not a rule-violation. Is the configuration clearly an extension of the class itself, and adding the params doesn't make the code clearer and just adds boilerplate? Then it's fine to pass it to the impl.A config reading another config's fields — even one it directly contains — is still a violation.
Fix it with a public @property on the child for a derived value (e.g. loss.requires_ensemble rather than loss.type == "EnsembleLoss"), or a validate(...) method on the child for an invariant (e.g. metric.validate(required_target="denorm")). The parent then goes through that sanctioned API.
These rules still apply for top-level entrypoints.
A run-config consumed by a free function (e.g. run_*_from_config) that reads the config as a parameter bag is a violation, unless that config is a leaf (it almost certainly isn't) since the free function isn't built by the config.
Instead of the config having a .build() method, it should likely have a .run() method that performs all building and side-effects, then calls a free function that takes the built objects and explicit values as arguments.
The free function should not read the config class itself.
The config's build() should assemble the runtime object(s); a thin entrypoint then performs the process side-effects (IO, logging, distributed setup) and invokes the built object.
Pure assembly (which reads the config) belongs in build(); the side-effecting shell operates on built objects and explicit values, not the config.
Pre-existing violations of these builder pattern rules are allowed, but new violations should be flagged, including refactors to existing classes that introduce new violations.
When audit passes are complete, give a concise summary of the audit pass results. Start each audit pass with a ✅ if clear, or a ⚠️ or ❌ (depending on severity) if issues are found.
Then, under a separate heading, revisit the overall purpose of the pre-review. Give the user a clear summary of the state of the PR and what you recommend for next steps. When giving this summary, do not re-cap on each successful check that has no actions required, but you could give a summary of the overall state.