@oddessentials/repo-standards 4.3.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "checklist": {
3
3
  "core": [
4
+ {
5
+ "ciHints": {
6
+ "azure-devops": {
7
+ "notes": "Run CRLF detection early in pipeline before other checks.",
8
+ "stage": "quality"
9
+ }
10
+ },
11
+ "description": "Enforce line endings at the Git layer using .gitattributes. Mark text files with appropriate EOL handling (eol=lf for shell scripts, eol=auto for most files) and binary files as binary to prevent corruption. This prevents 'works locally, fails in CI' issues caused by CRLF/LF mismatches.",
12
+ "id": "gitattributes-eol",
13
+ "label": "Git Attributes (Line Endings)",
14
+ "stack": {
15
+ "exampleConfigFiles": [
16
+ ".gitattributes",
17
+ ".editorconfig"
18
+ ],
19
+ "exampleTools": [
20
+ "git"
21
+ ],
22
+ "machineCheck": {
23
+ "command": "git ls-files --eol | grep -E 'w/crlf.*\\.sh$' && exit 1 || exit 0",
24
+ "description": "Verify no CRLF in shell scripts",
25
+ "expectExitCode": 0
26
+ },
27
+ "notes": "Use .gitattributes for EOL authority. Mark *.sh, *.ps1 scripts appropriately. .editorconfig drives editor behavior but .gitattributes is the source of truth for Git operations.",
28
+ "optionalFiles": [
29
+ ".editorconfig"
30
+ ],
31
+ "requiredFiles": [
32
+ ".gitattributes"
33
+ ],
34
+ "verification": "Run 'git ls-files --eol' to check EOL consistency."
35
+ }
36
+ },
37
+ {
38
+ "ciHints": {
39
+ "azure-devops": {
40
+ "notes": "Run CRLF detection as the first quality check before linting or testing.",
41
+ "stage": "quality"
42
+ }
43
+ },
44
+ "description": "Fail CI early for Linux-executed files containing CRLF line endings. Shell scripts, Python files, and other interpreted files fail silently or with cryptic errors when they contain \\r characters. Detect this before running deeper CI steps.",
45
+ "id": "crlf-detection",
46
+ "label": "CRLF Detection in CI",
47
+ "stack": {
48
+ "exampleConfigFiles": [],
49
+ "exampleTools": [
50
+ "file",
51
+ "grep"
52
+ ],
53
+ "machineCheck": {
54
+ "command": "git ls-files --eol | grep -E 'w/crlf.*\\.sh$' && exit 1 || exit 0",
55
+ "description": "Detect CRLF in shell scripts",
56
+ "expectExitCode": 0
57
+ },
58
+ "notes": "Detect CRLF in shell scripts and CI configuration files. C# source files can tolerate CRLF but shell scripts cannot.",
59
+ "verification": "Run CRLF detection on .sh files in CI."
60
+ }
61
+ },
4
62
  {
5
63
  "ciHints": {
6
64
  "azure-devops": {
@@ -178,6 +236,28 @@
178
236
  "verification": "Trigger the release pipeline and confirm all artifacts share the same version number and tag."
179
237
  }
180
238
  },
239
+ {
240
+ "ciHints": {
241
+ "azure-devops": {
242
+ "notes": "Set HUSKY=0 or equivalent in release pipeline to disable hooks.",
243
+ "stage": "release"
244
+ }
245
+ },
246
+ "description": "Release automation must bypass local developer hooks (HUSKY=0, --no-verify) and rely solely on CI gates for validation. This ensures idempotent, reproducible releases that don't fail due to hook environment differences.",
247
+ "id": "release-hook-bypass",
248
+ "label": "Release Hook Bypass",
249
+ "stack": {
250
+ "exampleConfigFiles": [
251
+ "azure-pipelines.yml",
252
+ ".github/workflows/release.yml"
253
+ ],
254
+ "exampleTools": [
255
+ "GitVersion"
256
+ ],
257
+ "notes": "Release pipelines should skip local hooks. If using Lefthook, set LEFTHOOK=0. Rely on CI gates for all validation.",
258
+ "verification": "Check release pipeline for hook bypass configuration."
259
+ }
260
+ },
181
261
  {
182
262
  "ciHints": {
183
263
  "azure-devops": {
@@ -292,21 +372,69 @@
292
372
  {
293
373
  "ciHints": {
294
374
  "azure-devops": {
375
+ "notes": "Hooks and CI must invoke identical verification commands. Use npm run verify or equivalent.",
295
376
  "stage": "quality"
296
377
  }
297
378
  },
298
- "description": "Use git hooks to run linting, formatting, tests, and commit linting before changes are committed.",
379
+ "description": "Use git hooks to run linting, formatting, and commit linting before changes are committed. Hooks should CHECK by default (not auto-fix), be fast, and scope to changed files only. Use a single entry hook mechanism (e.g., Husky as entry point calling pre-commit or lint-staged).",
299
380
  "id": "pre-commit-hooks",
300
381
  "label": "Pre-Commit Hooks",
301
382
  "stack": {
302
383
  "exampleConfigFiles": [
303
- "lefthook.yml"
384
+ "lefthook.yml",
385
+ ".husky/"
304
386
  ],
305
387
  "exampleTools": [
306
- "Lefthook"
388
+ "Lefthook",
389
+ "husky.net"
307
390
  ],
308
- "notes": "Configure Lefthook or similar to run formatting and basic checks on staged files before commits.",
309
- "verification": "Inspect the hook configuration (for example, Lefthook or similar) and confirm it runs at least formatting and basic checks on staged changes before commits or pushes."
391
+ "notes": "Configure Lefthook or husky.net to run formatting checks (not auto-fix) on staged files. Hooks should be deterministic and environment-pinned via global.json SDK version.",
392
+ "verification": "Inspect hook configuration and confirm checks run in verify mode, not auto-fix mode."
393
+ }
394
+ },
395
+ {
396
+ "ciHints": {
397
+ "azure-devops": {
398
+ "notes": "CI should call the same verify script that hooks use locally.",
399
+ "stage": "quality"
400
+ }
401
+ },
402
+ "description": "Local hooks and CI must invoke identical verification commands to prevent 'works locally, fails in CI' issues. Use a single canonical verify entrypoint (e.g., npm run verify) that both hooks and CI call.",
403
+ "id": "hook-ci-parity",
404
+ "label": "Hook/CI Parity",
405
+ "stack": {
406
+ "exampleConfigFiles": [
407
+ "Makefile",
408
+ "Directory.Build.props"
409
+ ],
410
+ "exampleTools": [
411
+ "dotnet CLI",
412
+ "make"
413
+ ],
414
+ "notes": "Define a verify target (make verify or dotnet cake verify) that both hooks and CI invoke. Keep verification logic in one place.",
415
+ "verification": "Compare hook commands with CI commands and confirm they invoke the same targets."
416
+ }
417
+ },
418
+ {
419
+ "ciHints": {
420
+ "azure-devops": {
421
+ "notes": "Also run secret scanning in CI as a safety net for commits that bypassed hooks.",
422
+ "stage": "quality"
423
+ }
424
+ },
425
+ "description": "Scan staged diffs for credentials, API keys, and secrets before they reach the remote repository. Catch secrets at commit time rather than after they're pushed.",
426
+ "id": "secret-scanning-precommit",
427
+ "label": "Pre-commit Secret Scanning",
428
+ "stack": {
429
+ "exampleConfigFiles": [
430
+ ".gitleaks.toml"
431
+ ],
432
+ "exampleTools": [
433
+ "gitleaks",
434
+ "detect-secrets"
435
+ ],
436
+ "notes": "Add gitleaks to pre-commit hooks via Lefthook. Scan staged changes before commits.",
437
+ "verification": "Run 'gitleaks protect --staged' and verify it catches test secrets."
310
438
  }
311
439
  },
312
440
  {
@@ -525,6 +653,73 @@
525
653
  ],
526
654
  "verification": "LICENSE file is present in the repository root; CODE_OF_CONDUCT.md and CONTRIBUTING.md are present for contribution guidance."
527
655
  }
656
+ },
657
+ {
658
+ "ciHints": {
659
+ "azure-devops": {
660
+ "notes": "CI should call the canonical verify command, not duplicate check logic.",
661
+ "stage": "quality"
662
+ }
663
+ },
664
+ "description": "Provide one canonical 'verify' command per repository/stack that all stages call with appropriate flags. This prevents duplication, drift, and ensures consistency between local development and CI.",
665
+ "id": "canonical-verify",
666
+ "label": "Canonical Verify Entrypoint",
667
+ "stack": {
668
+ "exampleConfigFiles": [
669
+ "Makefile",
670
+ "build.cake"
671
+ ],
672
+ "exampleTools": [
673
+ "dotnet CLI",
674
+ "make",
675
+ "cake"
676
+ ],
677
+ "notes": "Define 'make verify' or 'dotnet cake verify' that runs all checks. Both hooks and CI use this single entrypoint with stage-appropriate flags.",
678
+ "verification": "Makefile or build script contains a 'verify' target."
679
+ }
680
+ },
681
+ {
682
+ "ciHints": {
683
+ "azure-devops": {
684
+ "notes": "Ensure CI reads from authoritative configs, not duplicated settings.",
685
+ "stage": "quality"
686
+ }
687
+ },
688
+ "description": "Each configuration rule must live in exactly one authoritative config file. Avoid duplication across .editorconfig, linter configs, and CI definitions. Document which file is authoritative for each concern.",
689
+ "id": "config-authority",
690
+ "label": "Config File Authority Rules",
691
+ "stack": {
692
+ "exampleConfigFiles": [
693
+ ".gitattributes",
694
+ ".editorconfig",
695
+ "Directory.Build.props"
696
+ ],
697
+ "exampleTools": [],
698
+ "notes": "Authority mapping: .gitattributes for EOL, .editorconfig for formatting rules, Directory.Build.props for shared build settings. Roslyn analyzers read from .editorconfig.",
699
+ "verification": "Review configs and confirm no rule is duplicated across files."
700
+ }
701
+ },
702
+ {
703
+ "ciHints": {
704
+ "azure-devops": {
705
+ "notes": "CI should read skip paths from config files, not hardcode them in pipeline.",
706
+ "stage": "quality"
707
+ }
708
+ },
709
+ "description": "Encode path exclusions and skip rules deterministically in config files, not through ad-hoc human judgment. Make it clear which paths are excluded from checks and why.",
710
+ "id": "explicit-skip-paths",
711
+ "label": "Explicit Skip Paths",
712
+ "stack": {
713
+ "exampleConfigFiles": [
714
+ ".editorconfig"
715
+ ],
716
+ "exampleTools": [
717
+ "dotnet format",
718
+ "Roslyn"
719
+ ],
720
+ "notes": "Use .editorconfig file globs to exclude generated code from analysis. Document exclusions with comments.",
721
+ "verification": "Review .editorconfig and confirm exclusions are explicit and documented."
722
+ }
528
723
  }
529
724
  ],
530
725
  "optionalEnhancements": [
@@ -548,6 +743,48 @@
548
743
  "notes": "Configure structured logging for your .NET services and ensure exceptions and key events are logged with useful context.",
549
744
  "verification": "Confirm that a structured logging library (such as Serilog or NLog) is configured with an agreed sink and format, and that the application logs meaningful context for errors and key events."
550
745
  }
746
+ },
747
+ {
748
+ "ciHints": {
749
+ "azure-devops": {
750
+ "stage": "governance"
751
+ }
752
+ },
753
+ "description": "Define phase transition requirements in phase-gates.md for autonomous agent workflows with clear pre-conditions and approval gates.",
754
+ "id": "agent-phase-gates",
755
+ "label": "Agent Phase Gates",
756
+ "stack": {
757
+ "exampleConfigFiles": [
758
+ "phase-gates.md"
759
+ ],
760
+ "exampleTools": [],
761
+ "notes": "Define phase gates with .NET-specific verification (dotnet test, coverage reports, NuGet package publishing) and approval workflows.",
762
+ "optionalFiles": [
763
+ "phase-gates.md"
764
+ ],
765
+ "verification": "phase-gates.md exists defining transition requirements."
766
+ }
767
+ },
768
+ {
769
+ "ciHints": {
770
+ "azure-devops": {
771
+ "stage": "governance"
772
+ }
773
+ },
774
+ "description": "Document milestone completion criteria in victory-gates.md defining 'done' for releases and major deliverables with evidence requirements.",
775
+ "id": "agent-victory-gates",
776
+ "label": "Agent Victory Gates",
777
+ "stack": {
778
+ "exampleConfigFiles": [
779
+ "victory-gates.md"
780
+ ],
781
+ "exampleTools": [],
782
+ "notes": "Specify victory conditions for releases including .NET-specific requirements (NuGet publishing, deployment validation, documentation) and evidence collection.",
783
+ "optionalFiles": [
784
+ "victory-gates.md"
785
+ ],
786
+ "verification": "victory-gates.md exists with milestone criteria."
787
+ }
551
788
  }
552
789
  ],
553
790
  "recommended": [
@@ -687,6 +924,142 @@
687
924
  "notes": "Apply accessibility tooling to ASP.NET or Blazor front-ends and review issues alongside functional testing.",
688
925
  "verification": "For web-facing apps, run the configured accessibility checks or tools against your main UI endpoints and confirm that blocking accessibility issues are addressed."
689
926
  }
927
+ },
928
+ {
929
+ "ciHints": {
930
+ "azure-devops": {
931
+ "notes": "Run AI drift detection in a scheduled nightly pipeline separate from main CI.",
932
+ "stage": "nightly"
933
+ }
934
+ },
935
+ "description": "Run nightly or scheduled checks comparing AI-generated outputs against pinned baselines to detect model drift, prompt drift, or code changes affecting AI behavior. Attribute regressions to code changes vs model updates vs prompt changes.",
936
+ "id": "ai-drift-detection",
937
+ "label": "AI Drift Detection",
938
+ "stack": {
939
+ "exampleConfigFiles": [
940
+ "*.verified.txt",
941
+ "ai-baselines/"
942
+ ],
943
+ "exampleTools": [
944
+ "Verify",
945
+ "custom baseline tests"
946
+ ],
947
+ "notes": "Use Verify library or custom comparison tests to detect AI output drift. Run nightly to catch model-side changes that don't show up in code diffs.",
948
+ "verification": "Run AI baseline tests and confirm outputs match pinned baselines."
949
+ }
950
+ },
951
+ {
952
+ "ciHints": {
953
+ "azure-devops": {
954
+ "notes": "Run schema validation tests as part of quality gates.",
955
+ "stage": "quality"
956
+ }
957
+ },
958
+ "description": "Validate all AI-generated outputs against strict JSON schemas or type definitions at system boundaries. Reject invalid outputs early rather than letting malformed data propagate through the system.",
959
+ "id": "ai-schema-enforcement",
960
+ "label": "AI Output Schema Enforcement",
961
+ "stack": {
962
+ "exampleConfigFiles": [
963
+ "*.schema.json",
964
+ "Schemas/"
965
+ ],
966
+ "exampleTools": [
967
+ "System.Text.Json",
968
+ "FluentValidation",
969
+ "JsonSchema.Net"
970
+ ],
971
+ "notes": "Use strongly-typed DTOs with validation attributes or FluentValidation for AI outputs. Deserialize with strict settings that reject unknown properties.",
972
+ "verification": "Review AI integration code and confirm outputs are validated against schemas."
973
+ }
974
+ },
975
+ {
976
+ "ciHints": {
977
+ "azure-devops": {
978
+ "notes": "Run AI golden tests as part of the test stage.",
979
+ "stage": "test"
980
+ }
981
+ },
982
+ "description": "Validate AI tool-generated patches, configs, and code against exact expected formats. Test that AI outputs respect forbidden paths, file patterns, and format constraints through golden contract tests.",
983
+ "id": "ai-golden-tests",
984
+ "label": "AI Golden Contract Tests",
985
+ "stack": {
986
+ "exampleConfigFiles": [
987
+ "TestData/",
988
+ "*.verified.json"
989
+ ],
990
+ "exampleTools": [
991
+ "xUnit",
992
+ "Verify"
993
+ ],
994
+ "notes": "Use Verify for golden file testing of AI outputs. Ensure AI-generated code respects namespace conventions and doesn't modify protected files.",
995
+ "verification": "Run golden tests and confirm AI outputs match verified snapshots."
996
+ }
997
+ },
998
+ {
999
+ "ciHints": {
1000
+ "azure-devops": {
1001
+ "notes": "Run AI safety tests as part of security stage on main branch.",
1002
+ "stage": "security"
1003
+ }
1004
+ },
1005
+ "description": "Test AI integrations for prompt injection resistance, input sanitization, output filtering, and data exfiltration prevention. Include adversarial test cases that attempt to manipulate AI behavior.",
1006
+ "id": "ai-safety-checks",
1007
+ "label": "AI Adversarial & Safety Testing",
1008
+ "stack": {
1009
+ "exampleConfigFiles": [
1010
+ "Tests/AiSafety/"
1011
+ ],
1012
+ "exampleTools": [
1013
+ "xUnit",
1014
+ "custom security tests"
1015
+ ],
1016
+ "notes": "Test prompt injection resistance and output sanitization. Ensure AI outputs are escaped/validated before use in SQL queries, command execution, or HTML rendering.",
1017
+ "verification": "Run AI safety tests and confirm adversarial inputs are handled safely."
1018
+ }
1019
+ },
1020
+ {
1021
+ "ciHints": {
1022
+ "azure-devops": {
1023
+ "notes": "Verify AI provenance logging is implemented in quality checks.",
1024
+ "stage": "quality"
1025
+ }
1026
+ },
1027
+ "description": "Log AI provider, model version, prompt template version, parameters, and tool versions for all AI operations. Enable attribution of outputs to specific model+prompt combinations for debugging and compliance.",
1028
+ "id": "ai-provenance-tracking",
1029
+ "label": "AI Provenance & Audit Logging",
1030
+ "stack": {
1031
+ "exampleConfigFiles": [
1032
+ "AiProvenance.cs"
1033
+ ],
1034
+ "exampleTools": [
1035
+ "OpenTelemetry",
1036
+ "Serilog"
1037
+ ],
1038
+ "notes": "Use structured logging to capture AI call provenance. Include model version, prompt hash, and parameters in log context.",
1039
+ "verification": "Review AI integration and confirm provenance logging is implemented."
1040
+ }
1041
+ },
1042
+ {
1043
+ "ciHints": {
1044
+ "azure-devops": {
1045
+ "notes": "Run invariant verification commands in a dedicated quality stage.",
1046
+ "stage": "quality"
1047
+ }
1048
+ },
1049
+ "description": "Maintain INVARIANTS.md defining repository-wide rules that must always hold true, with machine-readable verification commands for autonomous agents.",
1050
+ "id": "agent-invariants",
1051
+ "label": "Autonomous Agent Invariants",
1052
+ "stack": {
1053
+ "exampleConfigFiles": [
1054
+ "INVARIANTS.md"
1055
+ ],
1056
+ "exampleTools": [],
1057
+ "notes": "Document invariants with verification commands like 'dotnet test', 'dotnet format --verify-no-changes', 'dotnet build' for autonomous validation.",
1058
+ "requiredFiles": [
1059
+ "INVARIANTS.md"
1060
+ ],
1061
+ "verification": "INVARIANTS.md exists with machine-readable verification commands."
1062
+ }
690
1063
  }
691
1064
  ]
692
1065
  },
@@ -742,27 +1115,41 @@
742
1115
  },
743
1116
  "migrationGuide": [
744
1117
  {
745
- "description": "Start by adding pre-commit hooks and core formatting/linting so developers get fast feedback without touching CI.",
1118
+ "description": "Configure .gitattributes for cross-platform line ending correctness and establish the canonical verify entrypoint before adding any checks. This prevents 'works locally, fails in CI' issues from day one.",
1119
+ "focusIds": [
1120
+ "gitattributes-eol",
1121
+ "canonical-verify",
1122
+ "hook-ci-parity",
1123
+ "config-authority"
1124
+ ],
1125
+ "notes": "Start here to avoid debugging cryptic CRLF failures later. Use .gitattributes as the authority for EOL (not .editorconfig). Run 'git add --renormalize .' after adding .gitattributes to fix existing files.",
1126
+ "step": 0,
1127
+ "title": "Foundation: Line Endings and Hook Entry Point"
1128
+ },
1129
+ {
1130
+ "description": "Add pre-commit hooks with secret scanning, formatting, and linting. Hooks should CHECK (not auto-fix) and scope to changed files only for speed.",
746
1131
  "focusIds": [
747
1132
  "pre-commit-hooks",
1133
+ "secret-scanning-precommit",
748
1134
  "linting",
749
1135
  "code-formatter"
750
1136
  ],
751
- "notes": "Keep hooks fast and focused on changed files to avoid slowing down day-to-day work.",
1137
+ "notes": "Keep hooks fast by scoping to staged files. Use Husky as entry point calling lint-staged or pre-commit. Hooks should check, not fix, to keep developers aware of issues.",
752
1138
  "step": 1,
753
1139
  "title": "Establish Local Safety Nets First"
754
1140
  },
755
1141
  {
756
- "description": "Introduce CI quality gates that mirror local checks, but treat existing violations as warnings wherever possible.",
1142
+ "description": "Introduce CI quality gates that mirror local hooks exactly. Add CRLF detection early in pipeline. Treat existing violations as warnings where possible.",
757
1143
  "focusIds": [
1144
+ "crlf-detection",
758
1145
  "ci-quality-gates",
759
1146
  "linting",
760
1147
  "code-formatter",
761
1148
  "commit-linting"
762
1149
  ],
763
- "notes": "Use diff-based tools or baselines so only new violations break builds; legacy issues remain visible but non-blocking.",
1150
+ "notes": "CI must call the same verify scripts that hooks use. Add CRLF detection before other checks to fail fast on line ending issues. Use diff-based tools so only new violations break builds.",
764
1151
  "step": 2,
765
- "title": "Mirror Local Checks in CI (Soft-Fail on Legacy)"
1152
+ "title": "Mirror Local Checks in CI with CRLF Detection"
766
1153
  },
767
1154
  {
768
1155
  "description": "Enable type-checking, coverage thresholds, and dependency/vulnerability scanning with gradual enforcement.",
@@ -787,9 +1174,22 @@
787
1174
  "complexity-analysis",
788
1175
  "accessibility-auditing"
789
1176
  ],
790
- "notes": "Tackle recommended items in order of business value; backend-only repos can skip web-focused checks like accessibility. For AI/ML-heavy Python teams, consider extending containerization with data versioning (DVC) and unit tests with data quality checks (e.g., Great Expectations) as part of this step.",
1177
+ "notes": "Tackle recommended items in order of business value; backend-only repos can skip web-focused checks like accessibility.",
791
1178
  "step": 4,
792
1179
  "title": "Layer in Docs, Governance, and Recommended Checks"
1180
+ },
1181
+ {
1182
+ "description": "For repos using or building with generative AI, add drift detection, schema enforcement, golden contract tests, safety testing, and provenance tracking.",
1183
+ "focusIds": [
1184
+ "ai-drift-detection",
1185
+ "ai-schema-enforcement",
1186
+ "ai-golden-tests",
1187
+ "ai-safety-checks",
1188
+ "ai-provenance-tracking"
1189
+ ],
1190
+ "notes": "Skip this step if your repo has no AI/ML components. For AI-heavy repos: add nightly drift detection to catch model changes, enforce strict schemas at AI output boundaries, and log provenance for debugging 'why did AI do X?'",
1191
+ "step": 5,
1192
+ "title": "AI/ML Governance (If Applicable)"
793
1193
  }
794
1194
  ],
795
1195
  "qualityGatePolicy": {