Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 30 additions & 29 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
# Root config
root = true

# Defaults - CRLF is the default; only the LF exceptions below are declared. Most LF pins are shared with
# `.gitattributes` (git-enforced): `*.sh`, the husky pre-commit shebang, `spec/validate.py`, `uv.lock`, and Dockerfiles.
# The workflow-YAML pins (`.github/workflows/*` and the catalog snippet workflows) are `.editorconfig`-only -
# git stays passive on them (`* -text`) and CI (editorconfig-checker) enforces LF. Keep the `[*]`
# `end_of_line = crlf` default - it is required for the Windows-GUI/WSL-engine
# workflow (Windows tooling misbehaves on LF) and every uncovered file type relies on it.
# Defaults: CRLF is the default, and only the LF exceptions below are declared.
# Most LF pins are shared with `.gitattributes`, which git enforces: `*.sh`, the husky pre-commit shebang, `spec/validate.py`, `uv.lock`, and Dockerfiles.
# The workflow-YAML pins (`.github/workflows/*` and the catalog snippet workflows) are `.editorconfig`-only.
# For those, git stays passive (`* -text`) and CI (editorconfig-checker) enforces LF.
# Keep the `[*]` `end_of_line = crlf` default, which the Windows-GUI and WSL-engine workflow requires because Windows tooling misbehaves on LF.
# Every uncovered file type relies on that default too.
[*]
charset = utf-8
end_of_line = crlf
Expand All @@ -39,60 +39,61 @@ indent_size = 2
[*.{yml,yaml}]
indent_size = 2

# Workflow YAML is LF: Dependabot and Actions rewrite it with LF, so declaring LF keeps it consistent instead of
# mixed. git still leaves endings alone (`* -text`); this and CI (editorconfig-checker) enforce it. Other YAML is CRLF.
# Workflow YAML is LF, because Dependabot and Actions rewrite it with LF, so declaring LF keeps it consistent instead of mixed.
# Endings are still left alone by git (`* -text`), and this file plus CI (editorconfig-checker) enforce it.
# Other YAML stays CRLF.
[.github/workflows/*.{yml,yaml}]
end_of_line = lf

# Catalog snippet workflows mirror real workflow files (LF above); keep the snippets LF so a copied snippet
# lands compliant instead of needing conversion.
# Catalog snippet workflows mirror the real workflow files pinned LF above.
# Keep the snippets LF, so a copied snippet lands compliant instead of needing conversion.
[catalog/snippets/workflows/*.{yml,yaml}]
end_of_line = lf

# The husky pre-commit snippet is a shebang script; keep it LF so a copied snippet runs (a CRLF shebang breaks).
# The husky pre-commit snippet is a shebang script, so keep it LF.
# A copied snippet then runs, where a CRLF shebang would break it.
[catalog/snippets/husky/pre-commit]
end_of_line = lf

# Linux scripts
[*.sh]
end_of_line = lf

# Python is CRLF by the `[*]` default (universal newlines; commonly edited on Windows). Pin LF
# only for a `.py` executed directly via its shebang, by path - here the CI validation entry point
# and the fleet-audit runner.
# Python is CRLF by the `[*]` default, since universal newlines accept it and it is commonly edited on Windows.
# Pin LF only for a `.py` executed directly via its shebang, by path.
# Here that is the CI validation entry point and the fleet-audit runner.
[spec/{validate,audit,fidelity_honesty}.py]
end_of_line = lf

# The agent-safety kit's Python is shebang-executable tooling run by path (the PreToolUse hook and its
# installer), so pin LF for the same reason as the entry points above - a CRLF shebang breaks direct
# execution on a Unix host.
# The agent-safety kit's Python is shebang-executable tooling run by path, namely the PreToolUse hook and its installer.
# Pin LF for the same reason as the entry points above, because a CRLF shebang breaks direct execution on a Unix host.
[host-setup/agent-safety/*.py]
end_of_line = lf

# The repo lint/review scripts are shebang-executable tooling run by path, so a CRLF shebang would
# break direct execution on a Unix host. Pinned in .gitattributes to match.
# The repo lint and review scripts are shebang-executable tooling run by path, so a CRLF shebang would break direct execution on a Unix host.
# They are pinned in .gitattributes to match.
[scripts/*.py]
end_of_line = lf

# uv regenerates uv.lock with LF on every platform, so pin it or an EOL check (editorconfig-checker/CI)
# reds on every `uv lock`/`uv sync` until the file is manually reconverted - same rationale as the
# shebang/Dockerfile pins (a tool owns the ending). A Python repo on the CRLF default carries this; a repo
# with no lockfile is unaffected.
# The uv tool regenerates uv.lock with LF on every platform, so pin it here.
# Without the pin an EOL check (editorconfig-checker or CI) fails on every `uv lock` or `uv sync` until the file is manually reconverted.
# The rationale matches the shebang and Dockerfile pins, where a tool owns the ending.
# A Python repo on the CRLF default carries this, and a repo with no lockfile is unaffected.
[uv.lock]
end_of_line = lf

# Dockerfiles - CRLF breaks RUN heredocs and line continuations
# Dockerfiles are LF, because CRLF breaks RUN heredocs and line continuations.
[{Dockerfile,*.Dockerfile}]
end_of_line = lf

# --- .NET-only below: C# and ReSharper style. Everything above is the line-ending
# governance every derived repo carries; a non-.NET repo may drop from here down. ---
# .NET-only below, covering C# and ReSharper style.
# Everything above is the line-ending governance every derived repo carries, and a non-.NET repo may drop from here down.

# C# files
[*.cs]
# Suppressions follow CODESTYLE.md "Analyzer Diagnostics and Suppressions": prefer a
# [SuppressMessage] attribute or the owning project's .editorconfig; relax a rule
# repo-wide here only when it applies to every project (never a brownfield batch).
# Suppressions follow CODESTYLE.md "Analyzer Diagnostics and Suppressions".
# Prefer a [SuppressMessage] attribute, or the owning project's .editorconfig.
# Relax a rule repo-wide here only when it applies to every project, never for a brownfield batch.
dotnet_diagnostic.IDE0055.severity = none
csharp_indent_block_contents = true
csharp_indent_braces = false
Expand Down
35 changes: 18 additions & 17 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# Default: do not normalize line endings (`* -text`); .editorconfig end_of_line rules guide what the editor writes.
# The exception pins below are git's own enforcement - they force LF for execution-sensitive classes regardless of editor.
# git config --global core.autocrlf false
# git add --renormalize .
# git ls-files --eol
# Default: git does not normalize line endings (`* -text`), and .editorconfig end_of_line rules guide what the editor writes.
# The exception pins below are git's own enforcement, forcing LF for execution-sensitive classes regardless of editor.
# Configure with: git config --global core.autocrlf false
# Renormalize with: git add --renormalize .
# Inspect with: git ls-files --eol
* -text

# Exception: scripts must stay LF regardless of the `* -text` default - a CRLF shebang breaks execution. `.editorconfig`
# covers `*.sh`, but extensionless executables match no extension rule, so pin them here so git enforces LF on checkout
# and `--renormalize`. Any repo whose tooling ships extensionless scripts adds the matching path pin, e.g. s6-overlay
# init `Docker/s6-overlay/** text eol=lf` or husky/git hooks `.husky/pre-commit text eol=lf`.
# Exception: scripts must stay LF regardless of the `* -text` default, because a CRLF shebang breaks execution.
# `.editorconfig` covers `*.sh`, but an extensionless executable matches no extension rule.
# Pin those here, so git enforces LF on checkout and on `--renormalize`.
# Any repo whose tooling ships extensionless scripts adds the matching path pin.
# The s6-overlay init is `Docker/s6-overlay/** text eol=lf`, and a husky or git hook is `.husky/pre-commit text eol=lf`.
*.sh text eol=lf
# The husky pre-commit snippet is an extensionless shebang script (like a copied .husky/pre-commit).
catalog/snippets/husky/pre-commit text eol=lf

# Vanilla `.py` follows the CRLF default - Python's universal newlines accept CRLF, and it is
# commonly edited on Windows. Pin LF only for a `.py` executed directly via its shebang, by path -
# here the CI validation entry point, the fleet-audit runner, the agent-safety hook and its
# installer, and the repo lint/review scripts with their tests. Do not re-add a blanket
# `*.py text eol=lf`.
# Vanilla `.py` follows the CRLF default, since Python's universal newlines accept CRLF and it is commonly edited on Windows.
# Pin LF only for a `.py` executed directly via its shebang, by path.
# Those are the CI validation entry point, the fleet-audit runner, the agent-safety hook and its installer, and the repo lint and review scripts with their tests.
# Do not re-add a blanket `*.py text eol=lf`.
spec/validate.py text eol=lf
spec/audit.py text eol=lf
spec/fidelity_honesty.py text eol=lf
Expand All @@ -30,10 +30,11 @@ scripts/test_prose_lint.py text eol=lf
scripts/test_repo_gate.py text eol=lf
scripts/test_pr_review.py text eol=lf

# uv regenerates uv.lock with LF on every platform; pin it so git enforces LF on checkout/renormalize and a
# CRLF-default repo does not fight the tool on every `uv lock`/`uv sync`. A repo with no lockfile is unaffected.
# The uv tool regenerates uv.lock with LF on every platform, so pin it here.
# That makes git enforce LF on checkout and renormalize, so a CRLF-default repo does not fight the tool on every `uv lock` or `uv sync`.
# A repo with no lockfile is unaffected.
uv.lock text eol=lf

# Dockerfiles must be LF - a CRLF breaks RUN heredocs and line continuations.
# Dockerfiles must be LF, because a CRLF breaks RUN heredocs and line continuations.
Dockerfile text eol=lf
*.Dockerfile text eol=lf
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Summarized for VS Code's generators. The full rules, rationale, and examples are

## Reviewing Carried Fleet Content

Several of this repository's governance files are carried from a shared template and kept in sync across a fleet of sibling repositories, among them `AGENTS.md`, `CODESTYLE.md`, `WORKFLOW.md`, this file, and the `repo-config/` rulesets. Most of `AGENTS.md` is universal fleet law: every section that states a rule, as opposed to the two that describe this repository's own directory tree and devcontainer, is byte-locked and verified by an automated byte-for-byte match against the template canonical, not by line-by-line review.
Several of this repository's governance files are carried from a shared template and kept in sync across a fleet of sibling repositories, among them `AGENTS.md`, `CODESTYLE.md`, `WORKFLOW.md`, this file, and the `repo-config/` rulesets. Most of `GOVERNANCE.md` is universal fleet law: every section that states a rule, as opposed to the two that describe this repository's own directory tree and devcontainer, is byte-locked and verified by an automated byte-for-byte match against the template canonical, not by line-by-line review. `AGENTS.md` is the thin router and carries two byte-locked sections of its own, with no repository-specific ones.

Two constraints follow when reviewing that content.

Expand Down
4 changes: 4 additions & 0 deletions AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ A repo is **operational** only if every applicable check passes. A single applic

Write `reports/<repo>/audit.md` from [`reports/_template.md`][template]: a dimension x {letter, intent, verdict, evidence} table with `file:line` citations (WORKFLOW.md 5A style), a drift section, and a list of proposed registry/spec updates (e.g. a resolved `classificationPending`). Rank findings most severe first.

**The hub authors the report, and a downstream repo does not open a pull request against the hub to write its own.** `reports/` is the hub's evidence that it audited a repo, so a report written by the repo being audited is a claim rather than evidence, and the hub cannot adopt one without checking it. Checking the judgment dimensions **is** the audit, since confirming a verdict like "analyzers enforced" means reading the same files the audit reads, so a submitted report saves only the writing up and not the work. A submitted report is also stale by construction, because it is a snapshot of one hub revision arriving at a later one, and its claims then have to be reconciled against findings that did not exist when it was written.

What a downstream repo does instead is unchanged and is where its context is worth most: it **files findings about the hub as issues**, which is the opposite of self-certification and is how several hub defects have been found, and it **applies fixes to its own repo** per section 10. Any pull request it does open against the hub follows the same branching model as every other, targeting `develop` and never `main`.

**Findings are a point-in-time snapshot. Stamp them and re-verify before acting.** [`spec/audit.py`][audit-runner] prints a run stamp (`audit run <UTC> | hub <sha>`) and, per repo, the exact commit it read (`@ <branch>@<sha>`). Anything derived from a run (a report, and especially an **onboarding or conformance issue**) quotes that stamp, so a reader can tell whether it still applies. A convergence issue is generated from the audit, never composed by hand: `spec/audit.py --issue <repo>` emits a ready-to-file title and body from that repo's live findings (grouped into must-fix, converge, and could-not-verify), so the issue content cannot drift from what the audit actually found and regenerates as the repo changes.

**Verify a convergence before it is promoted with `--branch`.** `spec/audit.py --branch <ref> <repo>` reads that ref instead of the repo's registry `groundTruthBranch`, so a repo can audit its own `develop` while the work is still in flight rather than discovering the gaps after `main` has moved. The registry is not edited, the run is still read-only, and the run stamp names the override so a finding cannot be mistaken for one against ground truth. A ref that does not resolve is a single error naming it, never a baseline's worth of file-absent letters.
Expand Down
3 changes: 2 additions & 1 deletion CODESTYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ Each language defines a **clean-compile** verification: the combination of build

These apply repo-wide, in every directory:

1. **Markdown linting**: All `.md` files must be lint-clean (error and warning free) via the VS Code `markdownlint` extension. [`.markdownlint-cli2.jsonc`][markdownlint-cli2] at the repo root is the single source of truth, and the davidanson `markdownlint` extension and a command-line `markdownlint-cli2` run both read it, so the IDE and CLI stay in lock-step. Rules it deliberately disables (e.g. `MD013` line-length) are **intentional**, so do not "fix" them. `MD033` inline HTML stays **enabled**: HTML comments are permitted (markdownlint does not flag them), HTML elements are flagged, and anything with a native markdown equivalent uses the markdown. Fix violations at the source rather than disabling rules.
1. **Markdown linting**: All `.md` files must be lint-clean (error and warning free) via the VS Code `markdownlint` extension. [`.markdownlint-cli2.jsonc`][markdownlint-cli2] at the repo root is the single source of truth, and the davidanson `markdownlint` extension and a command-line `markdownlint-cli2` run both read it, so the IDE and CLI stay in lock-step. Rules it deliberately disables (e.g. `MD013` line-length) are **intentional**, so do not "fix" them. `MD033` inline HTML stays **enabled**: HTML comments are permitted (markdownlint does not flag them), `details` and `summary` are allowed because a GitHub collapsible has no markdown equivalent, every other element is flagged, and anything with a native markdown equivalent uses the markdown. Fix violations at the source rather than disabling rules.
2. **Spelling**: All spelling must be clean via the CSpell VS Code integration, and words must be correctly spelled in **US English** (the repo-wide convention, per [GOVERNANCE.md][governance]). The shared `cspell.json` sets `"language": "en-US"` so British spellings are flagged, where a bare `"en"` accepts both US and British and silently passes the wrong spelling. Project-specific terms go in the shared `cspell.json` `words` list, the single source of truth the extension, CLI, and CI all read. The `.code-workspace` must **not** carry its own `cspell.words`/`cSpell.words` block, and when externalizing words into `cspell.json`, delete any word list left in the workspace (a leftover one duplicates the list and silently drifts).
3. **Spelling CI scope**: The enforced CI spell-check gate covers **`README.md` and `HISTORY.md` only**, because these are the files every repo visitor sees, so they must be clean. It is deliberately **not** all `**/*.md`: repos carry many markdown files full of technical terms, and gating every one of them would mean endlessly padding `cspell.json` just to keep CI green. Broad, live spell-checking across any file (source, markdown, text) is the **cspell editor extension's** job, so typos still surface to whoever is editing. A repo owner **may** widen their own CI file list, but README + HISTORY are the default; keep the CI workflow, the `Lint: Spelling` VS Code task, and the GOVERNANCE.md cspell one-liner on the same file list. The list is explicit (not a glob), so a repo that ships no `HISTORY.md` (e.g. one with no changelog) must drop it from all three surfaces and gate on `README.md` alone, since cspell errors on a listed file that does not exist. Markdown *linting* (item 1) stays repo-wide `**/*.md`, which does not choke on technical terms.
4. **`HISTORY.md` mirrors the README opening**: `HISTORY.md` is the maintainer-curated changelog and opens as the README's twin, carrying the same `# <Title>` (without the README's ToC-omit comment) and the same intro paragraph copied verbatim, then a `## Release History` section. The mirrored opening keeps the project identity consistent for a reader who lands on the changelog directly. The audit checks that the title and intro match the README, with HTML comments stripped.

## .NET

Expand Down
Loading
Loading