Skip to content
2 changes: 1 addition & 1 deletion src/docs/Modules/Process-PSModule/repository-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A module repository in PSModule follows a predictable structure so the framework
- `tests/`: Pester tests and test helpers
- `examples/`: usage examples for consumers
- `icon/`: module icon assets
- `.github/workflows/`: workflow entrypoint using Process-PSModule
- `.github/workflows/Process-PSModule.yml`: caller workflow that invokes the reusable `PSModule/Process-PSModule/.github/workflows/workflow.yml`
- `.github/PSModule.yml`: repository-level framework settings

## Source layout overview
Expand Down
91 changes: 72 additions & 19 deletions src/docs/Modules/Repository-Defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,27 @@ After creating the repository:
Each module repository should have:

- A concise GitHub repository description that starts with or clearly says `A PowerShell module ...`.
- `RepoType: Module` as the repository custom property.
- `Type: Module` as the repository custom property.
- Topics that help users find the module, when relevant.
- Branch protection and workflow requirements inherited from organization defaults.
- `main` as the default branch unless there is a documented legacy reason.

The repository description is used as a short landing-page summary in documentation and automation. Keep it user-facing and avoid implementation details.

### Organization custom properties

Custom properties are defined once for the whole organization and set per repository. The organization schema is the source of truth; read it with `gh api /orgs/PSModule/properties/schema` before automating against a property, and update this page when the schema changes.

| Property | Value type | Required | Module repository expectation |
| --- | --- | --- | --- |
| `Type` | Single select: `Action`, `Archive`, `Docs`, `Framework`, `FunctionApp`, `Memory`, `Module`, `Other`, `Template`, `Workflow` | Yes, organization default `Other` | `Module`. Set it explicitly after repository creation; a new repository otherwise inherits `Other`. `Template-PSModule` itself is `Template`. |
| `SubscribeTo` | Multi select: `Custom Instructions`, `Prompts`, `Hooks`, `CODEOWNERS`, `dependabot.yml`, `PSModule Settings`, `Linter Settings`, `gitattributes`, `gitignore`, `License` | No | Opt-in for [managed file distribution](#managed-file-distribution). Select the file types the distribution runtime should own in this repository; leave a type unselected to keep a repository-local version. |
| `Description` | String | No | Optional machine-readable description for automation that needs it independently of the GitHub repository description. |
| `Archive` | True/false | No | Set to `true` only when the repository is no longer maintained. |
| `Upstream` | URL | No | Set when the module wraps, mirrors, or is generated from an upstream project. |

Automation and repository search select module repositories with the `props.Type:Module` qualifier, for example `gh search repos --owner PSModule 'props.Type:Module'`.

## Default branch and worktrees

Use `main` for active module repositories. Legacy repositories that still use `master` should not be used as examples for new work.
Expand All @@ -70,9 +84,10 @@ Module repositories use the PSModule framework layout:
| `CODE_OF_CONDUCT.md` | Community conduct expectations. |
| `AGENTS.md` | Agent onboarding entry point. Points agents to the canonical guidance in `PSModule/docs`. |
| `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/workflows/Process-PSModule.yml` | Caller workflow that runs the module's CI/CD by calling the shared Process-PSModule workflow. |
| `.github/release.yml` | Release-note and changelog categorization for GitHub releases. |
| `.github/linters/` | Linter configuration used by the framework's linting stage, including `.markdown-lint.yml` and `.powershell-psscriptanalyzer.psd1`. |
| `.github/dependabot.yml` | Dependency and supply-chain update configuration. |
| `.github/CODEOWNERS` | Ownership routing for reviews and protected areas. |
| `.github/pull_request_template.md` | PR Manager-compatible pull request template. |
Expand All @@ -91,6 +106,27 @@ Module repositories use the PSModule framework layout:

Detailed source layout rules live in [PowerShell module standard](Standards.md#repository-layout).

### Caller workflow and reusable workflow

The module repository owns a caller workflow; the framework owns the reusable workflow it calls. These are two separate files in two separate repositories:

| Role | Repository | File |
| --- | --- | --- |
| Caller workflow | The module repository | `.github/workflows/Process-PSModule.yml` |
| Reusable workflow | [`PSModule/Process-PSModule`](https://github.com/PSModule/Process-PSModule) | `.github/workflows/workflow.yml` |

The caller workflow declares the triggers, concurrency, and permissions for the module repository, and delegates the work:

```yaml
jobs:
Process-PSModule:
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@<commit-sha> # <version tag>
secrets:
APIKey: ${{ secrets.APIKEY }}
```

Name the caller file `Process-PSModule.yml`, matching [`PSModule/Template-PSModule`](https://github.com/PSModule/Template-PSModule) and every existing module repository. `workflow.yml` is the reusable workflow's own filename inside `PSModule/Process-PSModule` and belongs only in the `uses:` reference. Pin the reference to a commit SHA with the version tag in a trailing comment so Dependabot can update it.

## Required common files

Every module repository must carry the same baseline community, governance, and automation files. GitHub's organization-level `.github` community-file fallback is useful for display defaults, but it is not enough as the long-term PSModule standard because:
Expand All @@ -113,8 +149,7 @@ Required baseline files for module repositories:
| `CODE_OF_CONDUCT.md` | Community participation rules. |
| `AGENTS.md` | Cross-tool agent instructions pointing to the canonical guidance in `PSModule/docs`. |
| `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/dependabot.yml` | Supply-chain maintenance for GitHub Actions and any other Dependabot ecosystem the repository actually uses. |
| `.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. |
| `.github/release.yml` | Release-note and changelog categorization where the repository creates GitHub releases. |
Expand All @@ -137,6 +172,10 @@ Every repository must be usable by an agent that has never seen it before, witho

See [PSModule/Template-PSModule](https://github.com/PSModule/Template-PSModule) for a concrete implementation example of `AGENTS.md` and `CLAUDE.md`.

`AGENTS.md` and `CLAUDE.md` are the required set. `AGENTS.md` is the entry point that AGENTS.md-aware runtimes read directly, so a repository is usable by an agent without a per-runtime copy of the same pointer.

Runtime-specific adapter files such as `.github/copilot-instructions.md` and `.github/instructions/*.instructions.md` are optional. MSX treats them as client adapters that *may* add runtime-specific loading or path rules, described in [Agentic Development](https://msxorg.github.io/docs/Ways-of-Working/Agentic-Development/) and its [capability specification](https://msxorg.github.io/docs/Capabilities/agentic-development/spec/). Add one when a runtime needs loading or path rules that `AGENTS.md` cannot express, and keep it pointing at `AGENTS.md` rather than restating it. `Template-PSModule` ships without one.

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
Expand All @@ -159,32 +198,46 @@ This page defines the required target state (the file requirements). Runtime mig

Every module repository must include `.github/dependabot.yml`. Dependabot is part of the repository supply-chain control, not an optional convenience.

Module repositories should configure at least:
Configure the `github-actions` ecosystem. It keeps the pinned actions current, including the pinned `PSModule/Process-PSModule` reference in the [caller workflow](#caller-workflow-and-reusable-workflow). This is what [`PSModule/Template-PSModule`](https://github.com/PSModule/Template-PSModule) ships, and it is the default for new repositories:

```yaml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: github-actions
directory: /
labels:
- "dependencies"
- "github-actions"

- package-ecosystem: "powershell"
directory: "/"
- dependencies
- github-actions
schedule:
interval: "weekly"
interval: daily
cooldown:
default-days: 7
```

Add `nuget` when the module ships or builds against .NET dependencies, as [`PSModule/Sodium`](https://github.com/PSModule/Sodium) does:

```yaml
- package-ecosystem: nuget
directory: /
labels:
- "dependencies"
- "powershell"
- dependencies
- .NET
schedule:
interval: weekly
```

The GitHub Actions ecosystem keeps pinned actions current. The PowerShell ecosystem keeps PowerShell dependency declarations current where Dependabot supports them. Repositories with additional package ecosystems should add them explicitly rather than replacing these defaults.
Repositories with other package ecosystems add them explicitly rather than replacing the `github-actions` entry. Older repositories still use a weekly interval without a cooldown; align them with the template default when the file is touched anyway.

Dependabot PRs still go through normal review. Automated dependency updates are not a substitute for reviewing release notes, changed permissions, pinned SHAs, or generated lockfiles.

### PowerShell dependencies

Dependabot's valid `package-ecosystem` values are enumerated in its configuration parser ([`common/lib/dependabot/config/file.rb`](https://github.com/dependabot/dependabot-core/blob/main/common/lib/dependabot/config/file.rb)) and listed in the [Dependabot options reference](https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference#package-ecosystem). Configure only values from that list: `powershell` is not among them, and an unsupported value makes `.github/dependabot.yml` invalid, which puts the repository's whole Dependabot configuration at risk, including the `github-actions` entry that does work.

PowerShell module dependencies are therefore declared with `#Requires -Modules` in the function files that use them, as described in [PowerShell module standard](Standards.md), and the build collects them into the compiled manifest. Keeping those declarations current is a review responsibility.

A PowerShell ecosystem is proposed in [dependabot/dependabot-core#15501](https://github.com/dependabot/dependabot-core/issues/15501) and implemented in [dependabot/dependabot-core#15666](https://github.com/dependabot/dependabot-core/pull/15666), covering PowerShell's native declarations β€” `#Requires -Modules` in `.ps1` and `.psm1` files, and `RequiredModules` in a `.psd1` manifest β€” resolved against the PowerShell Gallery. Adopt it once it ships and `powershell` appears in the options reference, updating this section and the `dependabot.yml` that `Template-PSModule` distributes together.

## README default

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.
Expand Down