From fe0fa0a4d9297ae43cc07e4b07c1981178952160 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 9 Jul 2026 06:15:13 +0200 Subject: [PATCH 1/6] Preserve unique content in the README default Trimming a module README must not delete unique information. Adds a content-preservation rule (keep/trim/relocate, never drop), makes the capabilities showcase mandatory for implemented modules, carves out an upstream attribution and licensing exception, fixes the copy/paste-hostile Get-Help example, and extends README validation. --- .../PowerShell/Modules/Repository-Defaults.md | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/docs/PowerShell/Modules/Repository-Defaults.md b/src/docs/PowerShell/Modules/Repository-Defaults.md index 7ce6b66..bb6ae5d 100644 --- a/src/docs/PowerShell/Modules/Repository-Defaults.md +++ b/src/docs/PowerShell/Modules/Repository-Defaults.md @@ -171,6 +171,8 @@ Dependabot PRs still go through normal review. Automated dependency updates are A module README is a start page, not the command reference or full manual. It brings a reader in, answers the first questions, and sends them to the right documentation surface. +Making the README shorter must not delete unique information. The README is often the only place that carries certain content: prerequisites, platform and dependency notes, authentication and setup guidance, operational behavior such as caching, state, or update and versioning semantics, and upstream attribution. None of that is generated from comment-based help, so trimming the README must preserve it — keep it on the landing page when it belongs there, or relocate it to `docs/`, `examples/`, or comment-based help. Only remove content that is genuinely duplicated by generated command documentation. + The README answers these questions, in this order: | Question | Module README responsibility | @@ -224,15 +226,25 @@ Use PowerShell help and command discovery for module details: ```powershell Get-Command -Module -Get-Help -Name 'CommandName' -Examples +Get-Help -Name -Examples ``` ```` -README pages should include a short capabilities or usage showcase before the documentation link when the module has working capabilities. Keep that section focused on discovery and marketing: show representative outcomes, not every command, parameter, or edge case. +In the documentation examples, replace `` with a real command exported by the module, for example `Get-Help -Name Get-GitHubRepository -Examples`, so the snippet runs as written. Do not ship placeholder tokens such as `'CommandName'` or `` as if they were runnable commands. + +Implemented modules must include the capabilities or usage showcase before the documentation link. Keep it focused on discovery: show one to three representative outcomes, not every command, parameter, or edge case. A landing page with only an installation snippet and a documentation link is not enough for a module that has working commands. + +Keep, trim, or relocate content — do not delete it: + +- **Keep on the landing page:** the overview, prerequisites and requirements (PowerShell version, supported platforms, module or native dependencies), installation, the capabilities showcase, and the short operational notes a reader needs before first use. +- **Trim:** exhaustive command inventories, parameter tables, and repetitive examples that differ only by a parameter. These come from comment-based help — point to `Get-Help` and the documentation site instead of restating them. +- **Relocate, never drop:** long-form guides and unique conceptual content that is too detailed for a landing page, such as authentication and setup walkthroughs, deep operational detail, and end-to-end scenarios. Move them to `docs/` or `examples/`, or into comment-based help, and link to them. If there is no other home for the content yet, keep a condensed version in the README rather than deleting it. + +Retain upstream attribution and licensing context. Credit, acknowledgements, donation notes, and third-party license notices for wrapped or bundled work must stay in the README, or move to a clearly linked place. The rule below about community and policy sections does not apply to attribution the project is expected to carry. README pages should not duplicate generated command documentation. Do not add full command inventories, parameter tables, or long reference sections when those details are already produced from comment-based help. -Do not add a community-file or policy link section by default. Readers can find standard repository files such as `LICENSE`, `CONTRIBUTING.md`, `SECURITY.md`, and `CODE_OF_CONDUCT.md` through GitHub conventions and the repository file tree. Link them only when the module has an unusual rule the user must know before using it. +Do not add a community-file or policy link section by default. Readers can find standard repository files such as `LICENSE`, `CONTRIBUTING.md`, `SECURITY.md`, and `CODE_OF_CONDUCT.md` through GitHub conventions and the repository file tree. Link them only when the module has an unusual rule the user must know before using it, or when it carries required upstream attribution. ## Placeholder and in-progress repositories @@ -267,12 +279,15 @@ Before opening a README-only PR, check that the README follows the default and d ```powershell Select-String -Path README.md -SimpleMatch -Pattern 'Greet-Entity', 'PSModuleTemplate', 'YourModuleName' Select-String -Path README.md -SimpleMatch -Pattern '{{ NAME }}', '{{ DESCRIPTION }}' +Select-String -Path README.md -SimpleMatch -Pattern "-Name 'CommandName'", '' Select-String -Path README.md -Pattern '^## Commands$' git diff --check -- README.md ``` `Template-PSModule` is the exception: it intentionally keeps `{{ NAME }}` and `{{ DESCRIPTION }}` tokens because those are template inputs. +For an implemented module, also confirm the README keeps a capabilities or usage showcase and that any unique content removed from the previous version — prerequisites, setup or authentication guidance, operational notes, or upstream attribution — was relocated to `docs/`, `examples/`, or comment-based help rather than deleted. + ## Documentation ownership Command details belong in comment-based help and generated documentation. The README can showcase capability, then points to those sources for reference detail. From 85fbc3c75d70c3b3cd791fc36b0545f7ec15e0c7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 9 Jul 2026 06:51:47 +0200 Subject: [PATCH 2/6] Clarify README is the published landing page The README publishes as the module landing page; a bare top-level docs/ is not published by the docs build. Correct the relocation guidance to only published homes (README, group overview pages under src/functions/public, comment-based help) and state that a longer README is acceptable rather than deleting narrative content to shorten it. --- src/docs/PowerShell/Modules/Repository-Defaults.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docs/PowerShell/Modules/Repository-Defaults.md b/src/docs/PowerShell/Modules/Repository-Defaults.md index bb6ae5d..0cefa8d 100644 --- a/src/docs/PowerShell/Modules/Repository-Defaults.md +++ b/src/docs/PowerShell/Modules/Repository-Defaults.md @@ -171,7 +171,7 @@ Dependabot PRs still go through normal review. Automated dependency updates are A module README is a start page, not the command reference or full manual. It brings a reader in, answers the first questions, and sends them to the right documentation surface. -Making the README shorter must not delete unique information. The README is often the only place that carries certain content: prerequisites, platform and dependency notes, authentication and setup guidance, operational behavior such as caching, state, or update and versioning semantics, and upstream attribution. None of that is generated from comment-based help, so trimming the README must preserve it — keep it on the landing page when it belongs there, or relocate it to `docs/`, `examples/`, or comment-based help. Only remove content that is genuinely duplicated by generated command documentation. +Making the README shorter must not delete unique information. The README is published as the module's landing page on the documentation site (for example `psmodule.io/`); the per-command reference is generated separately from comment-based help. So the README is often the only published home for prerequisites, platform and dependency notes, authentication and setup guidance, operational behavior such as caching, state, or update and versioning semantics, and upstream attribution. Trimming the README must preserve that content: keep it on the landing page, or move it only to another surface that also publishes (a command group's overview page under `src/functions/public//.md`, or comment-based help). Only remove content that is genuinely duplicated by the generated command reference. The README answers these questions, in this order: @@ -238,7 +238,7 @@ Keep, trim, or relocate content — do not delete it: - **Keep on the landing page:** the overview, prerequisites and requirements (PowerShell version, supported platforms, module or native dependencies), installation, the capabilities showcase, and the short operational notes a reader needs before first use. - **Trim:** exhaustive command inventories, parameter tables, and repetitive examples that differ only by a parameter. These come from comment-based help — point to `Get-Help` and the documentation site instead of restating them. -- **Relocate, never drop:** long-form guides and unique conceptual content that is too detailed for a landing page, such as authentication and setup walkthroughs, deep operational detail, and end-to-end scenarios. Move them to `docs/` or `examples/`, or into comment-based help, and link to them. If there is no other home for the content yet, keep a condensed version in the README rather than deleting it. +- **Relocate only to a published home — never drop:** long-form guides and unique conceptual content (authentication and setup walkthroughs, deep operational detail, end-to-end scenarios) may move out of the README only into a surface that is actually published: a command group's overview page under `src/functions/public//.md`, or comment-based help. A bare top-level `docs/` folder is not published by the current docs build, so moving content there drops it from the site. When there is no published home for it yet, keep the full content in the README. A longer landing page is acceptable and expected for feature-rich modules; do not shorten by deleting. Retain upstream attribution and licensing context. Credit, acknowledgements, donation notes, and third-party license notices for wrapped or bundled work must stay in the README, or move to a clearly linked place. The rule below about community and policy sections does not apply to attribution the project is expected to carry. @@ -299,7 +299,7 @@ Use these defaults: - Realistic end-to-end scenarios live in `examples/`. - Product docs beyond generated command help live under `docs/` and publish through GitHub Pages or the initiative's module documentation site. - README capability examples are short, representative, and user-facing. -- README pages stay short and stable. +- README pages stay focused and stable, and keep the narrative content that has no other published home. This keeps the repository landing page readable and prevents drift between README content, PowerShell help, and generated documentation. From cbf0b5d683b075f0490687203e68c451c0eed08c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 11 Jul 2026 19:45:32 +0200 Subject: [PATCH 3/6] Expand module standard: Usage section, agent files, module types, PS 7.6+ - Rename README showcase heading Capabilities -> Usage (Examples allowed); disallow Capabilities and add to README validation. - Each repo stands on its own: carries own governance files, no reliance on org .github fallback; README has no Contributing section (repo ships self-contained CONTRIBUTING.md). - Add agent onboarding files (AGENTS.md, CLAUDE.md, .github/copilot-instructions.md) to required files + Distributor mandatory sets, pointing to PSModule/docs and MSXOrg/docs. - Placeholder guard: a module exporting any real command is not a placeholder. - Modern PowerShell only: minimum 7.6, track current + LTS; drop 5.1 accommodation. - New Module-Types.md (integration/API + data modules) + Naming.md rules (REST->verb, ConvertTo/From + Format/Import/Export); Hashtable is the data-module reference; Context for user + module settings. --- src/docs/PowerShell/Modules/Module-Types.md | 95 +++++++++++++++++++ .../PowerShell/Modules/Repository-Defaults.md | 45 ++++++--- src/docs/PowerShell/Modules/index.md | 1 + src/docs/PowerShell/Standard/Naming.md | 43 +++++++++ src/docs/PowerShell/index.md | 2 +- src/zensical.toml | 1 + 6 files changed, 173 insertions(+), 14 deletions(-) create mode 100644 src/docs/PowerShell/Modules/Module-Types.md diff --git a/src/docs/PowerShell/Modules/Module-Types.md b/src/docs/PowerShell/Modules/Module-Types.md new file mode 100644 index 0000000..7f7d1e2 --- /dev/null +++ b/src/docs/PowerShell/Modules/Module-Types.md @@ -0,0 +1,95 @@ +# Module types + +Most PSModule modules fall into one of a few archetypes. The general rules in +[PowerShell module standard](Standards.md) and [Naming](../Standard/Naming.md) always apply; this +page adds the conventions that are specific to a module's type so that modules of the same kind feel +the same to use. + +Two archetypes have enough shared shape to standardize: + +- **Integration (API) modules** wrap an external service's REST or GraphQL API. +- **Data modules** convert or manage a data format or in-memory structure. + +A module can be both (for example, an integration module that also exposes conversion helpers). +Apply each relevant section. + +## Integration (API) modules + +Integration modules are the PowerShell face of an external service. `GitHub`, and the +service-client modules such as `Anthropic`, `OpenAI`, `Bluesky`, and `Domeneshop`, are integration +modules. + +### Command naming maps to the resource, not the HTTP method + +Name commands after the resource and the intent, using approved verbs. Never name a command after +the HTTP method or the endpoint path. Map REST methods to verbs: + +| REST method | PowerShell verb | Example | +| ----------- | --------------- | ------- | +| `GET` | `Get-` | `Get-GitHubRepository` | +| `POST` (create) | `New-` / `Add-` | `New-GitHubRepository` | +| `PUT` / `PATCH` (update) | `Set-` / `Update-` | `Set-GitHubRepository` | +| `DELETE` | `Remove-` | `Remove-GitHubRepository` | +| Non-CRUD action | Approved verb for the intent | `Invoke-`, `Start-`, `Stop-`, `Enable-`, … | + +Prefix the noun with the service's term of art (`GitHubRepository`, not `Repository`). See +[integration command naming](../Standard/Naming.md#integration-commands-and-rest-methods). + +### Transport stays private + +Public functions accept resolved inputs and typed objects; private helpers own the concrete +`Invoke-RestMethod` / GraphQL / HTTP calls. This is the Dependency Inversion rule from +[Standards](Standards.md#solid-applied) applied to the network boundary. + +### Use Context for user and module settings + +Integration modules persist state with the [`Context`](https://github.com/PSModule/Context) module +rather than inventing bespoke storage. Two kinds of state are both standard: + +- **User settings and secrets** — accounts, tokens, sessions, and per-user configuration. Store these + in a per-user context. `Context` encrypts secrets at rest (via `Sodium`), so a user can resume work + without reconfiguring or logging in again when the service supports session refresh. +- **Module settings** — module-wide defaults, endpoints, and feature flags that are not tied to a + single user. Store these in a module-scoped context. + +Persisting both through `Context` gives every integration module the same, discoverable settings +model, and keeps secrets out of source, logs, and plain files. + +## Data modules + +Data modules convert between representations or manage an in-memory structure. `Hashtable` is the +reference shape; `Base64`, `Json`, `Lua`, `Hcl`, `Sodium`, and `Uri` follow the same pattern. + +### The neutral object is the pivot + +Every conversion goes through the neutral PowerShell object model +(`[PSCustomObject]` / `[hashtable]` / `[PSObject]`). `ConvertFrom-` parses a +format-specific representation *into* an object; `ConvertTo-` renders an object *into* the +format. Converting through the object as a common pivot means any format interoperates with any +other, instead of writing a direct converter for every pair. + +Always ship **both** directions so data round-trips. + +### Verb vocabulary + +| Verb pattern | Purpose | +| ------------ | ------- | +| `ConvertFrom-` | Format-specific text/representation → `[PSCustomObject]` / `[hashtable]` | +| `ConvertTo-` | Object → format-specific text/representation | +| `Import-` | Read from a file or store into objects | +| `Export-` | Write objects to a file or store | +| `Format-` | Produce a normalized or pretty rendering | +| `Merge-` | Combine two structures | +| `Compare-` | Diff two structures | +| `Test-` | Validate a value or structure | +| `Remove-Entry` | Remove elements by criteria | + +The `Hashtable` module demonstrates the full set: `ConvertFrom-Hashtable`, `ConvertTo-Hashtable`, +`Import-Hashtable`, `Export-Hashtable`, `Format-Hashtable`, `Merge-Hashtable`, and +`Remove-HashtableEntry`. See [data conversion and I/O verbs](../Standard/Naming.md#data-conversion-and-io-verbs). + +## Where this connects + +- [Naming](../Standard/Naming.md) — the concrete verb rules for both types. +- [PowerShell module standard](Standards.md) — layout, private functions, and the mandatory context parameter. +- [Repository Defaults](Repository-Defaults.md) — repository files, README shape, and agent onboarding. diff --git a/src/docs/PowerShell/Modules/Repository-Defaults.md b/src/docs/PowerShell/Modules/Repository-Defaults.md index 0cefa8d..3097afc 100644 --- a/src/docs/PowerShell/Modules/Repository-Defaults.md +++ b/src/docs/PowerShell/Modules/Repository-Defaults.md @@ -2,7 +2,7 @@ This page defines the default repository contract for PowerShell module repositories in the PSModule organization. It describes what a newly created or maintained module repository should look like before module-specific code, tests, documentation, and managed repository files are considered. -The implementation standard still lives in [PowerShell module standard](Standards.md). This page covers repository defaults: files, metadata, README shape, release integration, placeholder handling, shared community files, and managed-file distribution. +The implementation standard still lives in [PowerShell module standard](Standards.md). Type-specific conventions for integration (API) and data modules live in [Module types](Module-Types.md). This page covers repository defaults: files, metadata, README shape, release integration, placeholder handling, shared community files, agent onboarding files, and managed-file distribution. ## Scope @@ -62,10 +62,13 @@ Module repositories use the PSModule framework layout: | ---- | --------------- | | `README.md` | Concise start page for the module. | | `LICENSE` | Repository license. PSModule module repositories default to MIT unless a different license is explicitly decided. | -| `CONTRIBUTING.md` | Contribution workflow or a repository-level pointer to the organization contribution guide. | +| `CONTRIBUTING.md` | Self-contained contribution workflow for this repository. Does not rely on an organization-level fallback. | | `SECURITY.md` | Security support policy and private vulnerability reporting instructions. | | `SUPPORT.md` | Support expectations and where users ask for help. | | `CODE_OF_CONDUCT.md` | Community conduct expectations. | +| `AGENTS.md` | Agent onboarding entry point. Points agents to the PSModule and MSX documentation for the why, how, and what. | +| `CLAUDE.md` | Claude Code entry point. Imports `AGENTS.md` so Claude reads the same instructions. | +| `.github/copilot-instructions.md` | VS Code and GitHub Copilot repository instructions. Points to the same documentation. | | `.github/PSModule.yml` | Module workflow configuration overrides. | | `.github/workflows/workflow.yml` | Reusable Process-PSModule workflow entry point. | | `.github/dependabot.yml` | Dependency and supply-chain update configuration. | @@ -102,10 +105,13 @@ Required baseline files for module repositories: | ---- | ------------------ | | `README.md` | Repository landing page and evergreen context for humans and agents. | | `LICENSE` | Clear legal terms for reuse, packaging, and redistribution. | -| `CONTRIBUTING.md` | Shared contribution workflow and expectations. | +| `CONTRIBUTING.md` | Self-contained contribution workflow and expectations for this repository. | | `SECURITY.md` | Private vulnerability reporting and latest-version support policy. | | `SUPPORT.md` | Support channel and issue-routing expectations. | | `CODE_OF_CONDUCT.md` | Community participation rules. | +| `AGENTS.md` | Cross-tool agent instructions pointing to the PSModule and MSX documentation. | +| `CLAUDE.md` | Claude Code entry point that imports `AGENTS.md`. | +| `.github/copilot-instructions.md` | VS Code and GitHub Copilot repository instructions pointing to the documentation. | | `.github/dependabot.yml` | Supply-chain maintenance for GitHub Actions and PowerShell dependencies. | | `.github/CODEOWNERS` | Review routing for source, docs, and GitHub workflow files. | | `.github/pull_request_template.md` | Consistent PR Manager-style PR descriptions and change classification. | @@ -118,6 +124,18 @@ Required baseline files for module repositories: Repositories can add local files, but they should not remove these baseline files unless the repository is explicitly outside the module standard. +Each repository must stand on its own. It carries its own copy of every file above and does not depend on the organization `.github` fallback: that fallback is only surfaced in GitHub's web UI, and agents, linters, and local tooling do not read it. + +## Agent onboarding files + +Every repository must be usable by an agent that has never seen it before, without special configuration. Each repository carries its own agent entry points that *point to* the authoritative documentation instead of restating it: + +- `AGENTS.md` — the cross-tool entry point, read by the GitHub Copilot coding agent, VS Code, and other AGENTS.md-aware tools. It names what the repository is in a line or two and points to the PSModule documentation (`https://psmodule.io`, source in [`PSModule/docs`](https://github.com/PSModule/docs)) for the module's why/how/what, and to the MSX documentation (`https://msxorg.github.io/docs`, source in [`MSXOrg/docs`](https://github.com/MSXOrg/docs)) for organization-level principles and ways of working. +- `CLAUDE.md` — a thin file that imports `AGENTS.md` with `@AGENTS.md` so Claude Code reads the same instructions. Claude-specific notes, if any, go below the import. +- `.github/copilot-instructions.md` — repository instructions for VS Code and GitHub Copilot that point to the same documentation. + +These files are the agent equivalent of the README: pointers, not copies. Keep them short so the linked documentation stays the single source of truth. Like the other governance files, they live in the repository itself so it can stand on its own. + ## Managed file distribution Shared files should be treated as managed files. The current distribution service is [`PSModule/Distributor`](https://github.com/PSModule/Distributor). It keeps source file sets under `Repos/{Type}/{Selection}/` and syncs those files into repositories through pull requests. @@ -133,7 +151,7 @@ The current Distributor model is subscription-based: Two follow-up Distributor capabilities define the desired direction: - **Global file sets** should allow common file sets such as `.gitattributes`, `.gitignore`, and `License` to be defined once and made available to all repository types while still requiring subscription. -- **Mandatory file sets** should allow organization-critical files such as `SECURITY.md`, `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, and supply-chain configuration to be pushed to applicable repositories without each repository having to subscribe manually. +- **Mandatory file sets** should allow organization-critical files such as `SECURITY.md`, `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, the agent onboarding files (`AGENTS.md`, `CLAUDE.md`, `.github/copilot-instructions.md`), and supply-chain configuration to be pushed to applicable repositories without each repository having to subscribe manually. Until mandatory file sets exist, repository owners are still responsible for ensuring the required common files exist. Distributor is the preferred implementation mechanism; this document is the standard that says what must exist and why. @@ -180,7 +198,7 @@ The README answers these questions, in this order: | What is it? | Name the module and define its scope in one short paragraph. | | Why should I care? | State the value or kind of task the module makes easier. | | How do I get it? | Show the PowerShell Gallery install and import commands. | -| How does it work? | Show one to three representative capabilities or usage examples. | +| How does it work? | Show one to three representative usage examples. | | How do I get more info? | Link to generated module documentation and PowerShell help. | Module installation examples must use PSResourceGet: @@ -207,11 +225,11 @@ Install-PSResource -Name Import-Module -Name ``` -## Capabilities +## Usage -Use this section as a short showcase and introduction to how the module works. Show the most important things the module makes possible with one to three realistic examples. +Use this section as a short showcase and introduction to how the module works. Show the most important things the module makes possible with one to three realistic examples; `### Example: ` subsections are fine when you have more than one. -The goal is discovery and marketing, not exhaustive command documentation. A reader should understand why the module exists and what kind of tasks it helps with. +The goal is discovery, not exhaustive command documentation. A reader should understand why the module exists and what kind of tasks it helps with. ```powershell # Replace this with a real example that demonstrates the module's value. @@ -232,11 +250,11 @@ Get-Help -Name -Examples In the documentation examples, replace `` with a real command exported by the module, for example `Get-Help -Name Get-GitHubRepository -Examples`, so the snippet runs as written. Do not ship placeholder tokens such as `'CommandName'` or `` as if they were runnable commands. -Implemented modules must include the capabilities or usage showcase before the documentation link. Keep it focused on discovery: show one to three representative outcomes, not every command, parameter, or edge case. A landing page with only an installation snippet and a documentation link is not enough for a module that has working commands. +Implemented modules must include the `## Usage` showcase before the documentation link. Keep it focused on discovery: show one to three representative outcomes, not every command, parameter, or edge case. A landing page with only an installation snippet and a documentation link is not enough for a module that has working commands. Do not title this section `## Capabilities`; use `## Usage` (or `## Examples`). Keep, trim, or relocate content — do not delete it: -- **Keep on the landing page:** the overview, prerequisites and requirements (PowerShell version, supported platforms, module or native dependencies), installation, the capabilities showcase, and the short operational notes a reader needs before first use. +- **Keep on the landing page:** the overview, prerequisites and requirements (PowerShell version, supported platforms, module or native dependencies), installation, the usage showcase, and the short operational notes a reader needs before first use. - **Trim:** exhaustive command inventories, parameter tables, and repetitive examples that differ only by a parameter. These come from comment-based help — point to `Get-Help` and the documentation site instead of restating them. - **Relocate only to a published home — never drop:** long-form guides and unique conceptual content (authentication and setup walkthroughs, deep operational detail, end-to-end scenarios) may move out of the README only into a surface that is actually published: a command group's overview page under `src/functions/public//.md`, or comment-based help. A bare top-level `docs/` folder is not published by the current docs build, so moving content there drops it from the site. When there is no published home for it yet, keep the full content in the README. A longer landing page is acceptable and expected for feature-rich modules; do not shorten by deleting. @@ -244,7 +262,7 @@ Retain upstream attribution and licensing context. Credit, acknowledgements, don README pages should not duplicate generated command documentation. Do not add full command inventories, parameter tables, or long reference sections when those details are already produced from comment-based help. -Do not add a community-file or policy link section by default. Readers can find standard repository files such as `LICENSE`, `CONTRIBUTING.md`, `SECURITY.md`, and `CODE_OF_CONDUCT.md` through GitHub conventions and the repository file tree. Link them only when the module has an unusual rule the user must know before using it, or when it carries required upstream attribution. +Do not add a community-file, policy, or Contributing link section to the README by default, and do not add a `## Contributing` section. Each repository carries its own `CONTRIBUTING.md`, `SECURITY.md`, `SUPPORT.md`, and `CODE_OF_CONDUCT.md`; readers and tools find them through the repository file tree and GitHub renders them in its UI. The README links or restates them only when the module has an unusual rule the user must know before using it, or when it carries required upstream attribution. ## Placeholder and in-progress repositories @@ -280,13 +298,14 @@ Before opening a README-only PR, check that the README follows the default and d Select-String -Path README.md -SimpleMatch -Pattern 'Greet-Entity', 'PSModuleTemplate', 'YourModuleName' Select-String -Path README.md -SimpleMatch -Pattern '{{ NAME }}', '{{ DESCRIPTION }}' Select-String -Path README.md -SimpleMatch -Pattern "-Name 'CommandName'", '' -Select-String -Path README.md -Pattern '^## Commands$' +Select-String -Path README.md -Pattern '^## (Commands|Capabilities)$' +Select-String -Path README.md -Pattern '^Install-Module\b' git diff --check -- README.md ``` `Template-PSModule` is the exception: it intentionally keeps `{{ NAME }}` and `{{ DESCRIPTION }}` tokens because those are template inputs. -For an implemented module, also confirm the README keeps a capabilities or usage showcase and that any unique content removed from the previous version — prerequisites, setup or authentication guidance, operational notes, or upstream attribution — was relocated to `docs/`, `examples/`, or comment-based help rather than deleted. +For an implemented module, also confirm the README keeps a `## Usage` showcase and that any unique content removed from the previous version — prerequisites, setup or authentication guidance, operational notes, or upstream attribution — was relocated to a published surface (`src/functions/public//.md`, `examples/`, or comment-based help) rather than deleted. ## Documentation ownership diff --git a/src/docs/PowerShell/Modules/index.md b/src/docs/PowerShell/Modules/index.md index f88e7ad..f2c739b 100644 --- a/src/docs/PowerShell/Modules/index.md +++ b/src/docs/PowerShell/Modules/index.md @@ -22,6 +22,7 @@ Version increments are driven by PR labels (`Major`, `Minor`, `Patch`, `Prerelea - **[Repository Defaults](Repository-Defaults.md)** — Required repository defaults for PSModule PowerShell module repos, including README shape, placeholder handling, metadata, and documentation ownership. - **[Standards](Standards.md)** — Repository layout, naming, style, parameter design, comment-based help, and SOLID applied to PowerShell modules. +- **[Module types](Module-Types.md)** — Type-specific conventions for integration (API) modules and data modules, including function-to-REST naming and using Context for user and module settings. - **[Test Specification](Test-Specification.md)** — How we write Pester tests: structure, hierarchy, and naming conventions. - **[Versioning](Versioning.md)** — How changes to the public interface determine the SemVer version bump. diff --git a/src/docs/PowerShell/Standard/Naming.md b/src/docs/PowerShell/Standard/Naming.md index 27cde7f..49baaf3 100644 --- a/src/docs/PowerShell/Standard/Naming.md +++ b/src/docs/PowerShell/Standard/Naming.md @@ -25,6 +25,49 @@ function Get-Users { } # Plural noun function Get-ContosoProjectByID { } # Named after lookup mechanism ``` +## Data conversion and I/O verbs + +**Practice:** In data modules, use a fixed verb vocabulary. `ConvertFrom-` turns a format-specific representation into a neutral `[PSCustomObject]`/`[hashtable]`; `ConvertTo-` does the reverse. Use `Import-`/`Export-` for file or store round-trips, `Format-` for a normalized rendering, and `Merge-`, `Compare-`, `Test-`, or `Remove-…Entry` to manipulate a structure. Always provide both `ConvertTo-` and `ConvertFrom-` so data round-trips. + +**Why:** `ConvertTo`/`ConvertFrom` around the neutral PowerShell object model let any format interoperate with any other through a common pivot — the object — instead of N×N direct converters. A predictable verb set makes a data module's surface obvious to humans and agents. + +**How:** + +```powershell +# Good — the Hashtable module is the reference shape +ConvertFrom-Hashtable # hashtable -> PSCustomObject +ConvertTo-Hashtable # object -> hashtable +Import-Hashtable # file -> hashtable +Export-Hashtable # hashtable -> file +Format-Hashtable # normalized rendering +Merge-Hashtable / Remove-HashtableEntry +``` + +See [Module types](../Modules/Module-Types.md#data-modules). + +## Integration commands and REST methods + +**Practice:** In API/integration modules, name commands after the resource and intent using approved verbs — never after the HTTP method or endpoint path. Map REST methods to verbs: `GET` → `Get-`, `POST` (create) → `New-`/`Add-`, `PUT`/`PATCH` → `Set-`/`Update-`, `DELETE` → `Remove-`, and non-CRUD actions → the approved verb that matches the intent (`Invoke-`, `Start-`, `Stop-`, …). + +**Why:** Users think in resources, not routes. `Get-GitHubRepository` is discoverable; a transport-shaped name like `Invoke-GitHubReposGet` is not. Approved verbs keep the surface consistent across every integration module. + +**How:** + +```powershell +# Good +Get-GitHubRepository -Owner PSModule -Name docs # GET .../repos/PSModule/docs +New-GitHubRepository -Name docs # POST .../repos +Remove-GitHubRepository -Owner PSModule -Name docs # DELETE .../repos/PSModule/docs +``` + +```powershell +# Bad +Invoke-GitHubReposGet # named after the route + HTTP verb +Get-GitHubReposByName # named after the lookup mechanism +``` + +See [Module types](../Modules/Module-Types.md#integration-api-modules). + ## Use full command names **Practice:** Always use the full `Verb-Noun` command name. Never use aliases in scripts or shared code. diff --git a/src/docs/PowerShell/index.md b/src/docs/PowerShell/index.md index 1268006..8ddb473 100644 --- a/src/docs/PowerShell/index.md +++ b/src/docs/PowerShell/index.md @@ -4,4 +4,4 @@ PowerShell is a command shell and scripting language originally developed by Mic We chose PowerShell as the foundation of the PSModule ecosystem because it fits the way we work. The object model is a first-class design decision, not a bolted-on feature — where Bash hands you a string and leaves you to parse it, PowerShell hands you a typed object you can work with directly. Tooling is exceptional: VS Code with the PowerShell extension gives you full IntelliSense backed by .NET types, and tab-completion works on parameter *values*, not just parameter names — something most shells never achieve. Cross-platform support is genuine: PowerShell 7 runs on Windows, macOS, and Linux, installable via `winget`, `brew`, `apt`, `dnf`, or an MSI. It is not pre-installed on Linux by default, but that is a far smaller obstacle than Bash and Zsh face on Windows, where they simply aren't available without WSL or a compatibility layer. And on GitHub-hosted runners it is available out of the box, which matters a great deal for the kind of automation we build. -We target the latest Long-Term Support (LTS) release of PowerShell 7. We do not actively pursue Windows PowerShell 5.1 compatibility — where support comes at low effort we accommodate it, but we will not constrain the framework to legacy capabilities. Developers who need to run these tools on systems that only have 5.1 can install PowerShell 7 alongside it. +We support modern PowerShell only. The minimum supported version is PowerShell 7.6, and from there we track the current and Long-Term Support (LTS) releases of PowerShell 7. We do not support Windows PowerShell 5.1 and will not constrain the framework to legacy capabilities. Developers on systems that only have 5.1 can install PowerShell 7 alongside it. diff --git a/src/zensical.toml b/src/zensical.toml index f7fb8f4..ee03590 100644 --- a/src/zensical.toml +++ b/src/zensical.toml @@ -35,6 +35,7 @@ nav = [ "PowerShell/Modules/index.md", {"Repository Defaults" = "PowerShell/Modules/Repository-Defaults.md"}, {"Standards" = "PowerShell/Modules/Standards.md"}, + {"Module types" = "PowerShell/Modules/Module-Types.md"}, {"Test Specification" = "PowerShell/Modules/Test-Specification.md"}, {"Versioning" = "PowerShell/Modules/Versioning.md"}, ]}, From 828fe3a5906990da73fdc3d6f11f9110ced98f37 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 12 Jul 2026 02:20:09 +0200 Subject: [PATCH 4/6] Resolve module-scope conflict; adopt agent onboarding files in docs repo Clarify Repository-Defaults scope so agent onboarding files and repository self-sufficiency apply to every PSModule repository, while the module file set and layout stay type-specific. This removes the contradiction with the 'every repository' / 'stand on its own' requirements that had excluded PSModule/docs. Dogfood the standard: add AGENTS.md, CLAUDE.md (@AGENTS.md import), and .github/copilot-instructions.md to PSModule/docs, which previously carried none of the required agent onboarding files. --- .github/copilot-instructions.md | 1 + AGENTS.md | 19 +++++++++++++++++++ CLAUDE.md | 1 + .../PowerShell/Modules/Repository-Defaults.md | 2 ++ 4 files changed, 23 insertions(+) create mode 100644 .github/copilot-instructions.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..3884664 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1 @@ +Follow the instructions in [AGENTS.md](../AGENTS.md). diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8402301 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,19 @@ +# Agents + +This repository holds the source for the [PSModule](https://psmodule.io) documentation, published at [psmodule.io/docs](https://psmodule.io/docs). Everything an agent needs to work here is documentation — read it the same way a new contributor would. + +## Start here + +1. Read this file, then the [README](README.md) for what this repository is and how it builds. +2. Read the [PSModule documentation](https://psmodule.io/docs) for the framework's why, how, and what — its standards, conventions, and style guides. The source for those pages lives under `src/docs/` in this repository. +3. Read the [MSX documentation](https://msxorg.github.io/docs) for the organization-level principles and ways of working that sit above any single repository. + +## Working in this repository + +- Documentation pages live under `src/docs/`; the published site navigation is defined in `src/zensical.toml`. Add a new page to both. +- The PowerShell standards and style guides under `src/docs/` are the source of truth for content changes — follow the page you are changing. +- Keep each page the single source of truth: link to the canonical page instead of restating its content elsewhere. + +## The rule + +This file points; it never defines. Standards and process live in the documentation and are referenced by their canonical location — never copied here. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/src/docs/PowerShell/Modules/Repository-Defaults.md b/src/docs/PowerShell/Modules/Repository-Defaults.md index 3097afc..aabab1a 100644 --- a/src/docs/PowerShell/Modules/Repository-Defaults.md +++ b/src/docs/PowerShell/Modules/Repository-Defaults.md @@ -15,6 +15,8 @@ They do not apply directly to: - Template repositories other than `Template-PSModule`. - Test, archive, service, or infrastructure repositories that are not published as module artifacts. +Two baseline expectations still apply to every PSModule repository, including the types listed above. Each repository stands on its own — it carries its own governance and community files instead of relying on the organization `.github` fallback — and each repository ships the [agent onboarding files](#agent-onboarding-files) so an agent can work in it without prior context. What differs by type is the concrete file set and layout: the required files, README shape, and framework wiring on the rest of this page are module defaults, and non-module repositories keep only the equivalent baseline appropriate to their own type. This repository, `PSModule/docs`, follows those two baseline expectations itself. + Each initiative should keep its own repository standards in its central documentation repository. For the PSModule organization, this repository is the source of truth. ## Repository creation From f78206941d80711cf1a5f339ed0b5d6c78221065 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 12 Jul 2026 02:29:33 +0200 Subject: [PATCH 5/6] Address Copilot review: examples/ not a published surface; complete round-trip grammar - Repository-Defaults README validation no longer calls examples/ a published surface; it now aligns with the 'relocate only to a published home' rule (group overview page or comment-based help) and states repository-only locations such as examples/ must still be linked from the README. - Naming.md and Module-Types.md: complete the 'so data round-trips' clause -> 'so data can round-trip between the format and the object model'. --- src/docs/PowerShell/Modules/Module-Types.md | 2 +- src/docs/PowerShell/Modules/Repository-Defaults.md | 2 +- src/docs/PowerShell/Standard/Naming.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docs/PowerShell/Modules/Module-Types.md b/src/docs/PowerShell/Modules/Module-Types.md index 7f7d1e2..c4842d2 100644 --- a/src/docs/PowerShell/Modules/Module-Types.md +++ b/src/docs/PowerShell/Modules/Module-Types.md @@ -68,7 +68,7 @@ format-specific representation *into* an object; `ConvertTo-` renders an format. Converting through the object as a common pivot means any format interoperates with any other, instead of writing a direct converter for every pair. -Always ship **both** directions so data round-trips. +Always ship **both** directions so data can round-trip between the format and the object model. ### Verb vocabulary diff --git a/src/docs/PowerShell/Modules/Repository-Defaults.md b/src/docs/PowerShell/Modules/Repository-Defaults.md index aabab1a..3ac99ed 100644 --- a/src/docs/PowerShell/Modules/Repository-Defaults.md +++ b/src/docs/PowerShell/Modules/Repository-Defaults.md @@ -307,7 +307,7 @@ git diff --check -- README.md `Template-PSModule` is the exception: it intentionally keeps `{{ NAME }}` and `{{ DESCRIPTION }}` tokens because those are template inputs. -For an implemented module, also confirm the README keeps a `## Usage` showcase and that any unique content removed from the previous version — prerequisites, setup or authentication guidance, operational notes, or upstream attribution — was relocated to a published surface (`src/functions/public//.md`, `examples/`, or comment-based help) rather than deleted. +For an implemented module, also confirm the README keeps a `## Usage` showcase and that any unique content removed from the previous version — prerequisites, setup or authentication guidance, operational notes, or upstream attribution — was kept on the landing page or relocated to a published home (`src/functions/public//.md` or comment-based help) rather than deleted. Repository-only locations such as `examples/` are not published on their own, so content moved there must still be linked from the README. ## Documentation ownership diff --git a/src/docs/PowerShell/Standard/Naming.md b/src/docs/PowerShell/Standard/Naming.md index 49baaf3..8b61d1c 100644 --- a/src/docs/PowerShell/Standard/Naming.md +++ b/src/docs/PowerShell/Standard/Naming.md @@ -27,7 +27,7 @@ function Get-ContosoProjectByID { } # Named after lookup mechanism ## Data conversion and I/O verbs -**Practice:** In data modules, use a fixed verb vocabulary. `ConvertFrom-` turns a format-specific representation into a neutral `[PSCustomObject]`/`[hashtable]`; `ConvertTo-` does the reverse. Use `Import-`/`Export-` for file or store round-trips, `Format-` for a normalized rendering, and `Merge-`, `Compare-`, `Test-`, or `Remove-…Entry` to manipulate a structure. Always provide both `ConvertTo-` and `ConvertFrom-` so data round-trips. +**Practice:** In data modules, use a fixed verb vocabulary. `ConvertFrom-` turns a format-specific representation into a neutral `[PSCustomObject]`/`[hashtable]`; `ConvertTo-` does the reverse. Use `Import-`/`Export-` for file or store round-trips, `Format-` for a normalized rendering, and `Merge-`, `Compare-`, `Test-`, or `Remove-…Entry` to manipulate a structure. Always provide both `ConvertTo-` and `ConvertFrom-` so data can round-trip between the format and the object model. **Why:** `ConvertTo`/`ConvertFrom` around the neutral PowerShell object model let any format interoperate with any other through a common pivot — the object — instead of N×N direct converters. A predictable verb set makes a data module's surface obvious to humans and agents. From 3f39186029ef245ee193e232f5b5fa3b8fac794a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 12 Jul 2026 02:33:53 +0200 Subject: [PATCH 6/6] Address Copilot review: use explicit Remove-Entry placeholder in Naming.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the ambiguous ellipsis in 'Remove-…Entry' with the explicit '' placeholder so it matches the verb vocabulary in Module-Types.md and is copy/paste-safe. --- src/docs/PowerShell/Standard/Naming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/PowerShell/Standard/Naming.md b/src/docs/PowerShell/Standard/Naming.md index 8b61d1c..6d3fc27 100644 --- a/src/docs/PowerShell/Standard/Naming.md +++ b/src/docs/PowerShell/Standard/Naming.md @@ -27,7 +27,7 @@ function Get-ContosoProjectByID { } # Named after lookup mechanism ## Data conversion and I/O verbs -**Practice:** In data modules, use a fixed verb vocabulary. `ConvertFrom-` turns a format-specific representation into a neutral `[PSCustomObject]`/`[hashtable]`; `ConvertTo-` does the reverse. Use `Import-`/`Export-` for file or store round-trips, `Format-` for a normalized rendering, and `Merge-`, `Compare-`, `Test-`, or `Remove-…Entry` to manipulate a structure. Always provide both `ConvertTo-` and `ConvertFrom-` so data can round-trip between the format and the object model. +**Practice:** In data modules, use a fixed verb vocabulary. `ConvertFrom-` turns a format-specific representation into a neutral `[PSCustomObject]`/`[hashtable]`; `ConvertTo-` does the reverse. Use `Import-`/`Export-` for file or store round-trips, `Format-` for a normalized rendering, and `Merge-`, `Compare-`, `Test-`, or `Remove-Entry` to manipulate a structure. Always provide both `ConvertTo-` and `ConvertFrom-` so data can round-trip between the format and the object model. **Why:** `ConvertTo`/`ConvertFrom` around the neutral PowerShell object model let any format interoperate with any other through a common pivot — the object — instead of N×N direct converters. A predictable verb set makes a data module's surface obvious to humans and agents.