Platform Reference
Lookup material: naming taxonomy, prefix ownership, coding conventions, and the agent catalogue. Nothing here explains why. It records the exact form that names, code, and agent invocations must take.
1. Naming taxonomy
1.1 Product name forms
Apply the form that matches the context. These are the only permitted renderings of the product name.
| Form | Value | Used for |
|---|---|---|
| kebab-case | event-route-optimiser | Package names, Wrangler names, repository URLs, directory paths |
| lowercase alias | ero | Short identifiers, CLI commands, prefixes such as ero-edge |
| PascalCase | EventRouteOptimiser | Azure DevOps project name, TypeScript interfaces, database names |
| UPPERCASE | ERO | User interface text, README titles, documentation headings |
Environment variable prefixes are split by purpose:
SKNX_ERO_for core application variables.SKNXR_for integration and synchronisation variables.- Variables supplied by external systems keep their external contract, normally upper snake case, for example
CLOUDFLARE_API_TOKEN.
1.2 Prefix ownership
Three prefixes divide ownership across the estate.
| Prefix | Scope | Examples |
|---|---|---|
sknx- | Organisation and governance assets, cross-platform operating policy, delivery controls | Agent names such as sknx-release-promotion; governance artefacts and operating directives |
sknxr- | SynkronyXr platform and framework architecture, shared engine rules, platform identity boundaries | Core architecture and standards documents; sync and identity principles used by every product |
ero- | Product-specific implementation for Event Route Optimiser | API contracts, worker implementation, product runbooks and delivery artefacts |
Documents owned by sknx- and sknxr- publish to the core site when they represent shared architecture, governance, or repository policy. Documents owned by ero- publish to the product site unless a cross-platform policy requires otherwise.
Prefix ownership changes must be recorded here before navigation profiles are modified, and profile entries in platform/automation/node/docs/docs-profiles.mjs must change in the same pull request.
1.3 Infrastructure naming
Full names are the default for environments, subscriptions, parameter files, and resource groups. Short tokens apply only where a provider imposes a length limit. The canonical mapping and the landing zone hierarchy are in Platform Architecture.
2. PowerShell coding conventions
These conventions are mandatory for PowerShell in SynkronyXr automation and platform modules.
2.1 Language naming model
Follow the convention native to each language. Do not carry casing rules across language boundaries.
| Language | Types and members | Example |
|---|---|---|
| PowerShell | PascalCase for functions, parameters, variables, hashtable keys, and module names | Get-DeploymentStatus, $ResourceGroupName |
| C# | PascalCase for types, properties, and public members | FinanceAccount { get; set; } |
| Java | PascalCase types and camelCase methods | BankAccount.getTotal() |
| Python | lower snake case for functions, variables, and modules | calculate_total() |
2.2 Naming rules
- Functions use an approved Verb-Noun name, both words PascalCase:
Get-DeploymentStatus,Invoke-DocumentationBuild. - Function names, parameters, local and script variables, and hashtable keys use PascalCase:
$SubscriptionId,@{ ResourceGroupName = $ResourceGroupName }. - Booleans begin with
Is,Has,Can, orShould:$IsProduction,$HasChanges. - Collections use a plural noun:
$ResourceGroups,$PendingChanges. - Switch parameters describe the requested state or action:
-Force,-WhatIf,-SkipValidation. - File names use lowercase kebab case:
deploy-landing-zone.ps1. - Module folders and module files share the same PascalCase module name:
SynkronyXr.Core/SynkronyXr.Core.psm1. - Abbreviations are permitted only for established platform terms such as
ERO,CIAM,URL,URI,ID, andAPI.
2.3 Code rules
- Every script and module begins with
Set-StrictMode -Version Latest. - Every reusable function uses
[CmdletBinding()]and aparamblock with typed parameters. - Mandatory parameters declare
[Parameter(Mandatory)]. UseValidateSet,ValidateNotNullOrEmpty,ValidatePattern, andValidateRangewhen the input contract is known. - Indent with four spaces. Opening braces sit on the same line as the control statement or declaration.
- Use full cmdlet names. Aliases such as
?,%,cat,cd,ls, andrmare prohibited in committed automation. - Use
Join-PathandResolve-Pathfor filesystem paths. Do not assemble paths with string separators. - Use
-LiteralPathwhen a path may contain wildcard characters. - Commands that can fail use
-ErrorAction Stopinsidetryblocks. Catch only when the code adds recovery or clear diagnostic context; otherwise let the terminating error surface. - Throw actionable errors:
throw "The deployment parameter file was not found: $ParameterFile". - Use
Write-Verbose,Write-Debug,Write-Warning,Write-Information, andWrite-Errorfor diagnostics.Write-Hostis permitted only in established presentation wrappers. - Never store secrets in scripts, modules, parameters, logs, or source-controlled files. Resolve them from
settings/or the configured secret provider. - Public module functions are explicitly exported with
Export-ModuleMember.
2.4 Required function shape
Set-StrictMode -Version Latest
function Invoke-DeploymentValidation { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$ParameterFile,
[switch]$SkipValidation )
$IsParameterFilePresent = Test-Path -LiteralPath $ParameterFile -PathType Leaf if (-not $IsParameterFilePresent) { throw "The deployment parameter file was not found: $ParameterFile" }
if (-not $SkipValidation) { Write-Verbose "Validating deployment parameters from $ParameterFile" }}2.5 Review checklist
- Functions use approved Verb-Noun PascalCase names.
- Parameters and variables use descriptive PascalCase names.
- Boolean and collection names follow their required prefixes and plurality.
- Inputs are typed and validated.
- Failure paths are terminating and carry actionable context.
- Filesystem operations use path cmdlets, and literal paths where required.
- No aliases, embedded secrets, or unstructured diagnostic output.
3. TypeScript and JavaScript module conventions
Every package in this repository is an ES module. CommonJS must not appear in authored source. The stack leaves no room for a choice: Cloudflare Workers accept only the ES module worker format, and Astro, Vite, and Starlight are ESM only.
3.1 Package rules
- Every
package.jsonoutsidenode_modulesmust declare"type": "module". - A package must not declare
mainunless it is published for consumption by another package. A Worker entry point is declared bymaininwrangler.jsonc, never bypackage.json. - The
.cjsand.ctsextensions must not enter source control.
3.2 Source rules
- Use
importandexport. Do not userequire,module.exports, orexports.. - Derive directory context from
import.meta.url:
import path from "node:path";import { fileURLToPath } from "node:url";
const currentDirectory = path.dirname(fileURLToPath(import.meta.url));- Top-level
awaitis available and is preferred over an immediately invoked async function.
3.3 Compiler options
| Setting | Value | Applies to |
|---|---|---|
module | ESNext | Code a bundler consumes: Astro shells, React components, Cloudflare Workers |
moduleResolution | Bundler | The same bundler-consumed code |
module and moduleResolution | NodeNext | Node code that is compiled rather than run directly as .mjs |
target | ES2022 or later | All TypeScript |
3.4 Permitted exceptions
require is permitted in exactly two places, both outside the repository module graph:
- Inline
actions/github-scriptblocks in.github/workflows/, which GitHub evaluates inside a CommonJS wrapper. node -eandnode -pone-liners inside workflow shell steps, which Node evaluates as CommonJS.
Neither form may be moved into a repository source file.
3.5 Review checklist
- Every package manifest declares
"type": "module". - No source file uses
require,module.exports, or a bare__dirname. - Worker entry points resolve through
wrangler.jsonc. - Compiler options match the table in section 3.3.
4. Agent catalogue
Repository-local specialist agents use the format sknx-<capability>-<focus>: lowercase, hyphen separated, short, action-oriented, one stable name per capability area.
| Agent | Use it for | When |
|---|---|---|
sknx-github-mcp-readonly | Read-only diagnostics for repository drift, pull request analysis, issue analysis, and repository search | Before merge decisions needing risk evidence, and during governance checks where mutation is not allowed |
sknx-implementation-delivery | Converting implementation requests into Feature, User Story, and Task structures with a quality audit | New feature intake, backlog decomposition, implementation readiness checks |
sknx-release-promotion | Landing work on the trunk and cutting a release tag | Pull request status reporting, and releasing a validated commit |
sknx-solution-architecture-review | Architecture and code governance review against CAF, WAF, and platform rules | Pull request architecture readiness, platform risk assessment before promotion |
Invocation uses the exact prefixed name, for example:
- “Run
sknx-github-mcp-readonlyfor drift on this branch.” - “Run
sknx-release-promotionfrom this feature branch torelease/v-next.” - “Run
sknx-solution-architecture-reviewfor PR #.”
4.1 Operating policy
- Agent names in prompts, documentation, and automation must use the exact
sknx-prefixed form. - A new repository-local agent must be added to this catalogue in the same change set that creates the agent file.
- Deprecated agent names must be removed from prompts and documentation in the same sprint.
The architecture review agent has an associated backlog reconciliation flow, documented in Platform Implementation.