You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/Markdown.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,3 +54,12 @@ These rules are disabled or widened so they do not flag valid documentation —
54
54
-**Surround headings, lists, and fenced blocks with a blank line** for readability, even though the linter no longer enforces it.
55
55
-**Prefer relative links** within a repository; use the canonical published URL for cross-repository references.
56
56
-**Tag every code fence with a language** (` ```bash `, ` ```yaml `) so it is highlighted and converts cleanly when published.
57
+
58
+
## PowerShell code samples
59
+
60
+
Documentation is full of PowerShell, so present it the way the [PowerShell standard](PowerShell/index.md) writes it:
61
+
62
+
-**Label the fence `powershell`**, and put command output in a separate block labelled `Output`, so it is neither syntax-highlighted as a command nor mistaken for input.
63
+
-**Use full cmdlet and parameter names**, and avoid positional parameters, so a reader can copy the sample and run it.
64
+
-**Avoid backtick line-continuation.** Break a long call with splatting, or at PowerShell's natural points — after a pipe, an opening parenthesis, or a brace.
65
+
-**Leave out the prompt string** (`PS>`) unless the sample is specifically about interactive, prompt-changing behaviour.
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/PowerShell/Functions.md
+15-1Lines changed: 15 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -66,7 +66,21 @@ function Get-UserData {
66
66
## Errors and output
67
67
68
68
-**`throw` for terminating errors**; `Write-Error` only where the caller is expected to handle a non-terminating one.
69
-
-**Emit one object type**, matching `[OutputType()]`; never `Write-Host` data another command might consume.
69
+
-**Call cmdlets you mean to trap with `-ErrorAction Stop`** so they raise terminating, catchable errors. Native commands report failure through `$LASTEXITCODE`, not the error stream, so check it and `throw` yourself — or set `$PSNativeCommandUseErrorActionPreference = $true` on PowerShell 7.4+ so their non-zero exits honour `$ErrorActionPreference` too.
70
+
-**Put the whole transaction in the `try` block** rather than setting success flags to gate later code, and do not lean on `$?` — it reports only whether the last command considered itself successful, with no detail.
71
+
-**In a `catch`, copy `$_` into your own variable first**, before later commands overwrite it. The baseline rules — fail fast, never swallow — live in [Error Handling](../Error-Handling.md).
72
+
73
+
## Output streams
74
+
75
+
Send each kind of message to the stream built for it, so a caller can capture, redirect, or silence it:
76
+
77
+
-**Results** are objects on the output stream — emit them implicitly by naming the object on its own line; do **not** use `return $obj` to emit, and in a pipeline function emit from `process`, not `end`.
78
+
-**Emit one object type**, matching `[OutputType()]`.
79
+
-**`Write-Verbose`** for status a caller may want (`-Verbose`), **`Write-Debug`** for maintainer breadcrumbs (`-Debug`), and **`Write-Progress`** for progress that need not persist.
80
+
-**`Write-Warning`** and **`Write-Error`** for warnings and non-terminating errors.
81
+
-**`Write-Host`** only for `Show-` or `Format-` verbs or an interactive prompt — never for data another command might consume.
82
+
83
+
`[CmdletBinding()]` is what turns on the `-Verbose` and `-Debug` switches, so those streams reach the caller.
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/PowerShell/Scripts.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -48,3 +48,8 @@ $ErrorActionPreference = 'Stop'
48
48
-**Name scripts `Verb-Noun.ps1`** to match the function convention.
49
49
-**No side effects on load.** A script runs top to bottom when invoked; it should not do work merely by being dot-sourced.
50
50
-**Return objects**, so the script composes in a pipeline like any other command.
51
+
52
+
## Paths
53
+
54
+
-**Do not depend on the current directory.** Avoid relative paths and `~` — the meaning of `~` depends on the current PowerShell provider — and build paths from `$PSScriptRoot` with `Join-Path`.
55
+
-**Pass full paths to .NET and native calls.** .NET methods and external executables resolve relative paths against `[System.Environment]::CurrentDirectory`, which PowerShell does not keep reliably in step with `$PWD` — it can lag `Set-Location`, and diverges in non-FileSystem providers (`Registry`, `Cert:`). Resolve to a full path first.
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/PowerShell/index.md
+11-1Lines changed: 11 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,13 +19,23 @@ This standard builds on the [language-agnostic baseline](../index.md); where the
19
19
20
20
<!-- INDEX:END -->
21
21
22
+
## Tools and controllers
23
+
24
+
PowerShell falls into two kinds, and the difference decides how a command shapes its output:
25
+
26
+
- A **tool** is a reusable unit — an advanced function, usually exported from a module. It takes input only through parameters and emits **raw, least-manipulated objects**, so it stays usable in situations its author never imagined; a tool that measures a size returns bytes, not a rounded string.
27
+
- A **controller** is a script that automates one process by calling tools. It may reshape, round, or format data for how it will be read, and it is not meant to be reused.
28
+
29
+
Keep the shaping at the edge: tools stay general and emit raw objects, and a controller — or a format view (`.format.ps1xml`) — turns those into presentation. This is the [thin script](Scripts.md) rule seen from the other side, and it is why tools [emit objects, not text](#shared-conventions).
30
+
22
31
## Shared conventions
23
32
24
33
These hold for all PowerShell, whatever the construct:
25
34
26
35
-**`Verb-Noun` naming** with an approved verb (`Get-Verb`) and a singular noun: `Get-RepositorySecret`, not `Fetch-Secrets`.
27
36
-**`PascalCase`** for functions, parameters, public variables, and class members; `camelCase` for local variables.
28
37
-**Full cmdlet names, never aliases** (`Where-Object`, not `?`; `ForEach-Object`, not `%`).
38
+
-**Full parameter names, and standard ones.** Pass parameters by name and avoid positional arguments in shared code — `Get-Process -Name pwsh`, not `Get-Process pwsh` — so a call survives parameter-set changes and reads clearly. Name your own parameters after PowerShell's built-ins (`Path`, `Name`, `ComputerName`), not `$Param_Computer`.
29
39
-**Set `$ErrorActionPreference = 'Stop'`** at the top of every script and module so errors are terminating, not silently swallowed.
30
40
-**Emit objects, not formatted text.** Return rich objects and let the caller format; reserve `Write-Host` for genuine console UX, and use `Write-Verbose` / `Write-Information` for progress narration.
31
41
@@ -49,7 +59,7 @@ Beyond the basics, these language-specific habits keep PowerShell correct and fa
49
59
-**Put `$null` on the left of a comparison** — `$null -eq $x`, never `$x -eq $null`. Against a collection the right-hand form *filters* rather than tests. Use `-contains` / `-in` for membership, never `-eq`.
50
60
-**Suppress unwanted output with `$null = ...`** (or `[void]` for method calls), not `| Out-Null` — the pipeline form is markedly slower on hot paths.
51
61
-**Build collections with a typed list, not `+=` in a loop.**`$a += $x` reallocates the whole array every iteration; use `[System.Collections.Generic.List[T]]` with `.Add()`, and prefer a cmdlet's `-Filter` over piping to `Where-Object` on large sets.
52
-
-**Keep secrets out of source, and never `Invoke-Expression` untrusted input.**Take secrets as `[securestring]`or through `Get-Credential`, and guard state-changing commands with `ShouldProcess` (see [Functions](Functions.md)); the wider rules live in the [Security](../Security.md) baseline.
62
+
-**Keep secrets out of source, and never `Invoke-Expression` untrusted input.**Accept credentials as a `[PSCredential]`parameter with the `[Credential()]` attribute rather than calling `Get-Credential` inside a reusable function, so a caller can pass one they already hold, and take other sensitive values as `[securestring]`. Guard state-changing commands with `ShouldProcess` (see [Functions](Functions.md)); the wider rules live in the [Security](../Security.md) baseline.
Copy file name to clipboardExpand all lines: src/docs/Ways-of-Working/Principles/Software-Design.md
+23-1Lines changed: 23 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
title: Software design
3
-
description: SOLID, extensibility, DRY with judgment, and making change easy before making the change.
3
+
description: SOLID, extensibility, smart defaults with local overrides, DRY with judgment, and making change easy before making the change.
4
4
---
5
5
6
6
# Software design
@@ -19,6 +19,28 @@ Extend by adding, not by modifying what already works — the Open/Closed princi
19
19
20
20
The system stays pluggable: the docs do not change when a new agent runtime is added — only a new integration layer is written. See the [Agentic Development](../Agentic-Development.md) specification for how this plays out in practice.
21
21
22
+
## Smart defaults, local overrides
23
+
24
+
The default is the smart, secure choice — what you would pick most of the time, and the safe option when unsure. A system with no configuration is already correct, safe, and useful out of the box. Configuration exists to *deviate* from a good default, never to reach a usable one.
25
+
26
+
Set the default at the broadest scope, and let each narrower scope override it. The setting closest to the thing it controls wins:
27
+
28
+
```text
29
+
org / ecosystem the widest default — set once, inherited everywhere
30
+
└── repository may narrow the default for one codebase
31
+
└── directory may narrow it further for one area
32
+
└── item the last word — closest to what it configures
33
+
```
34
+
35
+
This shape is chosen for manageability over the life of a system, and it earns two properties at once:
36
+
37
+
-**Manageable across the wide.** Change the default in one place and everything that has not opted out follows. You set the norm once instead of finding and editing many copies of it.
38
+
-**Flexible in the narrow.** Deviating is a small, local edit beside the item that needs it — not a fight with the system, and not a change that ripples outward. The exception lives with the thing it applies to.
39
+
40
+
Make the wide default easy to set and the local override easy to make. When the two disagree, the more specific one wins — predictably, by its position in the hierarchy, never by special-casing.
41
+
42
+
This is [Easy and Safe](../../index.md) expressed as design: doing the right thing takes no effort because it is the default, and deviating is deliberate and contained because it is a local override. [Least-privilege](Purpose-and-Direction.md#least-privilege) and [secure by default](../../Coding-Standards/Security.md#secure-by-default) are this principle applied to permissions and security; the way [the vision cascades](../../Vision/index.md#how-the-vision-cascades) is its shape applied to knowledge.
43
+
22
44
## DRY — with judgment
23
45
24
46
Don't Repeat Yourself, but **don't extract too early**. Wait until the same non-trivial logic appears in three or more places, or until the duplication is clearly load-bearing. Premature abstraction is more expensive than duplication.
Copy file name to clipboardExpand all lines: src/docs/Ways-of-Working/Principles/index.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,7 @@ Principles are grouped by theme; each theme is its own page so an agent can load
15
15
| --- | --- |
16
16
|[Purpose and direction](Purpose-and-Direction.md)| Why we build, who we build for, and the least-privilege stance under every decision. |
17
17
|[AI-first development](AI-First-Development.md)| Agents as first-class participants, determinism before intelligence, and how humans and agents share the work. |
18
-
|[Software design](Software-Design.md)| SOLID, extensibility, DRY with judgment, and making change easy before making the change. |
18
+
|[Software design](Software-Design.md)| SOLID, extensibility, smart defaults with local overrides, DRY with judgment, and making change easy before making the change. |
19
19
|[Engineering practices](Engineering-Practices.md)| Write it down, everything as code, evergreen docs, test-driven development, and shift-left quality. |
20
20
|[Planning and delivery](Planning-and-Delivery.md)| Roadmapping, lean delivery, and the loops that keep iteration fast. |
21
21
|[References](References.md)| The literature behind these principles. |
0 commit comments