agentleFS
pnppnp/powershell/.agents/skills/code-review/SKILL.md

code-review

Skill906 starsChanged 2 months agoMITView on GitHub

Review changes to PnP PowerShell for the failure modes this repository actually ships - silently ignored input, unpaged Graph collections, the wrong base class, permission attributes that do not match the API called, culture and cross-platform bugs, and missing documentation or changelog updates. Use when reviewing a diff, a PR, or uncommitted changes.

We split this skill into the rules it gives an agent

5 rules. 0 are common, 3 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 185 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Verify before reporting. A claim about behaviour that nobody ran is a guess.

    line 14
  2. Very specific:

    Check the base class actually matches what the cmdlet does — a tenant-admin operation on PnPWebCmdlet, or a Graph call from a SharePoint …

    line 70
  3. Distinctive:

    No Windows-only path assumptions, no backslash string surgery

    line 116
  4. Distinctive:

    Ask one question: does any correct usage behave differently?

    line 144
  5. Very specific:

    If only previously-broken usage changes — a configuration that was never honoured, an invocation that already threw — it is a fix, and it …

    line 146

“Common” is measured: kept by at least 6 in 10 of the 185 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Playbook: code-review

Review changes to PnP PowerShell for the failure modes this repository actually ships.

Cmdlets here run unattended, against production tenants, often with tenant-wide permissions. A cmdlet that quietly does the wrong thing is worse than one that fails, because nobody finds out until the tenant is already changed. Weight findings accordingly.

Verify before reporting. A claim about behaviour that nobody ran is a guess; say so when it is one.

Language and API rules live in dotnet-standards. This playbook is about what goes wrong here specifically.

Report to the user, in the session. Never post a review, a comment, or an approval to GitHub, and never open an issue for a finding — see Human in the loop.

Layout

  • src/Commands/ — cmdlet implementations, one folder per feature area
  • src/Commands/Base/ — base classes, PipeBinds/ for parameter binding types
  • src/Commands/Attributes/ — permission and behaviour attributes
  • src/ALC/ — assembly load context that isolates private dependencies
  • documentation/<Verb-PnPNoun>.md — the reference page for every cmdlet, one file each
  • pages/articles/ — conceptual articles, listed in pages/articles/toc.yml
  • pages/_site/ — generated site output, never edited by hand
  • build/ — build and generator scripts
  • CHANGELOG.md — release notes

Much of the provisioning behaviour lives in PnP Framework, a separate repository. When a root cause sits there, say so rather than accepting a workaround layered on top here, and do not let a PR claim to fix an issue whose cause it never touched.

What to look for first

Silence

The defect this repository has shipped most often is input accepted and then ignored.

  • catch { } or catch { return null; } — swallowing turns a user's mistake into wrong output
  • A parameter parsed into "no value given", after which the cmdlet proceeds with its default behaviour. Ignoring a -Configuration that could not be read once meant extracting an entire site instead of the one list asked for
  • System.Text.Json ignores unknown members by default, so a misspelled property silently has no effect. Custom enum converters here drop values they cannot parse, case sensitively
  • An unrecognised resource prefix in a permission attribute is silently classified as SharePoint, so a typo'd "garph/…" declares a bogus SharePoint scope while the real Graph requirement goes undeclared — see permissions-auditor
  • A dropped value that widens what the cmdlet does deserves an error, not a warning. An empty handler list means "all handlers", so one unrecognised handler name would otherwise turn a scoped operation into a full one

Unpaged collections

GraphRequestHelper.GetResultCollection follows @odata.nextLink. GraphRequestHelper.Get does not — pointed at a collection endpoint it returns the first page only, with no error. The same applies to RequestHelper. This presents to users as "the cmdlet misses items in large tenants", which is invisible in any tenant small enough to develop against. Check every new collection fetch.

The CSOM equivalent: a query returning more than the list view threshold, or a loop that pages manually and drops the last page.

Base class

Check the base class actually matches what the cmdlet does — a tenant-admin operation on PnPWebCmdlet, or a Graph call from a SharePoint cmdlet, gets the wrong context and the wrong permission flavour. It compiles, and it fails in someone's tenant. The table in new-cmdlet is the reference.

How errors reach the user

PnPConnectedCmdlet.ProcessRecord rethrows PipelineStoppedException untouched (src/Commands/Base/PnPConnectedCmdlet.cs:57-60) and catches everything else. Two paths, and the difference is the finding:

  • WriteError / ThrowTerminatingError — under -ErrorAction Stop these surface as a pipeline stop, rethrown unchanged. The ErrorRecord, its ErrorCategory and its target object all reach the user intact.
  • A raw throw — hits the generic catch. Default error action: rethrown as PSInvalidOperationException with the original as inner. Under -ErrorAction Stop or SilentlyContinue: LogError → LoggingUtility.Error → WriteError(new ErrorRecord(new Exception(message), source, ErrorCategory.NotSpecified, null)). Type, inner exception, category and target object are all discarded, so everything the user needs must be in the message text. Under -ErrorAction Ignore the LogError call is skipped altogether (PnPConnectedCmdlet.cs:112-119), so the failure is swallowed with no record at all — worth remembering when a user reports a cmdlet that "does nothing and says nothing".

So a raw throw carrying a custom exception type the caller is meant to inspect is a finding — the type is not observable on that path. So is a fatal condition signalled with WriteWarning and then continuing, and a throw where ThrowTerminatingError with a real ErrorCategory and target object would have told the user which object failed.

Cmdlet conventions

  • Verb-PnPNoun, approved verbs, correct base class
  • ParameterSpecified(nameof(X)) distinguishes "not supplied" from "supplied as default"
  • Reference-typed parameters that are dereferenced in ExecuteCmdlet need [ValidateNotNull], otherwise -Param $null is a NullReferenceException
  • Permission attributes must match the APIs the cmdlet actually calls, in both directions — over-declaring forces users to grant access the cmdlet never uses
  • Destructive or overwriting behaviour needs ShouldProcess, with -Force bypassing only a secondary ShouldContinue. Force || ShouldProcess(...) is a defect: -Force short-circuits the ||, ShouldProcess is never called, and -Force -WhatIf performs the operation instead of simulating it. Force || ShouldContinue(...) is the correct, repo-standard form
  • A renamed cmdlet keeps its old name as [Alias]

Cross-platform

.NET 8 and PowerShell 7.4+ on Windows, Linux and macOS.

  • No Windows-only path assumptions, no backslash string surgery
  • Environment.NewLine (what StringBuilder.AppendLine writes) mixed with hardcoded \r\n makes generated files churn purely from changing OS
  • Format dates and numbers with CultureInfo.InvariantCulture. A custom format string like "yyyy-MM-ddTHH:mm:ssZ" takes its separators from the current culture and produces 13.53.41 under some locales, which is not a valid xsd:dateTime
  • New package references have ALC consequences: the module assembly and CSOM live in Core, every other dependency is private and goes to Common

Documentation and changelog

A parameter added, renamed, or changed in behaviour requires its documentation/<Cmdlet>.md updated in the same PR. A new cmdlet requires a new page; a removed cmdlet requires its page deleted.

  • ## PARAMETERS sections carry only the platyPS ```yaml metadata blocks. Other fenced blocks there risk the help build; put examples under ## EXAMPLES with ```powershell fences
  • Parameter subsections are listed alphabetically
  • Conceptual content belongs in pages/articles/ with front matter, registered in toc.yml, not in documentation/, which is cmdlet reference only

CHANGELOG.md entries go under [Current nightly] in Added, Changed, Fixed or Removed, each naming the affected cmdlets in backticks and linking its PR. A change in behaviour belongs under Changed even when it fixes a bug, so it appears in the release notes people read before upgrading. A PR with no changelog entry is an incomplete PR — but the file header says it is owner maintained and maintainers do add entries, so raise it as a gap, not a blocker.

Breaking changes

Ask one question: does any correct usage behave differently?

If only previously-broken usage changes — a configuration that was never honoured, an invocation that already threw — it is a fix, and it belongs in a minor release with a Changed entry. Reserve a major release for changes that break usage which was working as documented. Say which of the two a PR is, and name the invocation that changes, rather than labelling it breaking on the strength of a diff. api-surface-diff has the full classification.

Reporting

Lead with the finding, not the file tour. For each one give the location, one sentence on the defect, and a concrete failure scenario: the input, and what the user gets instead of what they expected. Rank by consequence. If a check could not be run, say what would settle it.

Download now (ZIP)

  • Other versions195 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 195

    1. mattpocock/skills★ 309ksame name
    2. TheAlgorithms/Python★ 226ksame name
    3. microsoft/vscode★ 194ksame name
    4. github/spec-kit★ 145ksame name
    5. ggml-org/llama.cpp★ 133ksame name
    6. shareAI-lab/learn-claude-code★ 80ksame name
    7. shareAI-lab/analysis_claude_code★ 78ksame name
    8. vectorize-io/hindsight★ 57ksame name
    9. dbeaver/dbeaver★ 52ksame name
    10. roboflow/supervision★ 51ksame name

    185 more not listed

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • Used alongsideProjects with it also use add-new-model, azsdk-common-sdk-breaking-change and 9 more.

    Other files people use alongside this one.

    Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
    • PydanticSkill

      add-new-model

      Add support for a newly-released language or image generation model in pydantic-ai (e.g. openai:gpt-5.6, anthropic:claude-sonnet-5, openai:gpt-image-2). Use when a provider ships a new model id and you need to wire literals, profile flags, adapters, and tests to recognize it. Handles SDK-lag, gateway list conventions, capability probing, and direct image-model geometry.

      Also in 9 projects that use this

    • Microsoft AzureSkill

      azsdk-common-sdk-breaking-change

      Detect and mitigate SDK Breaking changes for an SDK package which is generated from TypeSpec. WHEN: "Detect SDK breaking changes for a service", "Detect SDK breaking changes for an SDK package", "Detect and mitigate SDK breaking changes for a service", "Detect and mitigate SDK breaking changes for an SDK package". INVOKES: skill: azsdk-common-generate-sdk-locally; MCP tools: azure-sdk-mcp:azsdk_customized_code_update, azure-sdk-mcp:azsdk_package_detect_breaking_change.

      Also in 4 projects that use this

    • ww-w-aiSkill

      bkend-auth

      bkend.ai authentication guide. Signup, login, JWT tokens, sessions, role-based access control, and password management with bkend.ai BaaS. Triggers: bkend auth, bkend login, bkend signup, JWT, session, RBAC, password, bkend 인증, 로그인, 회원가입, bkend認証, ログイン, 新規登録, bkend认证, 登录, 注册, autenticacion bkend, authentification bkend, bkend-Auth Do NOT use for: data operations (use $bkend-data), file storage (use $bkend-storage).

      Also in 4 projects that use this

    • ww-w-aiSkill

      bkend-cookbook

      bkend.ai cookbook with step-by-step tutorials and example projects. Build a todo app, blog, e-commerce store, and more with bkend.ai BaaS. Triggers: bkend cookbook, bkend tutorial, bkend example, todo app, blog app, bkend 쿡북, bkend 튜토리얼, 예제 프로젝트, bkendクックブック, チュートリアル, bkend教程, 示例项目, tutorial bkend, tutoriel bkend, bkend-Tutorial, ricettario Do NOT use for: initial setup (use $bkend-quickstart), specific features (use $bkend-data/auth/storage).

      Also in 4 projects that use this

    • dzhngSkill

      close-spec

      When a spec under specs/<feature>/ is done shipping (a write-spec build, or any planned task that produced a spec), archive it to specs/done/ and rewrite it from a build-plan into a durable rationale — the why, the principles, the invariants — pointing back to the real code for the how. Use when implementation has landed and the plan no longer matches what shipped, or the user says a feature/spec is finished. Pairs with [write-spec](../write-spec/SKILL.md) (the plan this closes) and [review](../review/SKILL.md) (run before closing).

      Also in 4 projects that use this

    • dzhngSkill

      design-with-images

      Explore UI and visual design with image generation, then iterate the real implementation against the user-selected concept. Use when brainstorming visual directions, offering mockup variants, or implementing an approved generated design; do not stop at the mockups or the first code approximation.

      Also in 4 projects that use this

    • +5 more from ww-w-ai
  • In this repository13 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.