Skip to content

docs(backlog): register 23 historical architectural decisions#336

Merged
piotrzajac merged 4 commits intomasterfrom
docs/register-historical-backlog-decisions
Apr 22, 2026
Merged

docs(backlog): register 23 historical architectural decisions#336
piotrzajac merged 4 commits intomasterfrom
docs/register-historical-backlog-decisions

Conversation

@piotrzajac
Copy link
Copy Markdown
Collaborator

@piotrzajac piotrzajac commented Apr 22, 2026

Summary

  • Mines the full git history to reconstruct 22 architectural decisions made between 2017 and 2026, each dated from its originating commit
  • Renumbers the pre-existing performance benchmark decision to decision-23 (last in the timeline)
  • Adds task-19 (Add performance benchmarks) referencing decision-23

Test plan

  • Verify .backlog/decisions/ contains exactly 23 files (decision-1 through decision-23)
  • Verify each file has a date field in yyyy-mm-dd format matching its historical origin
  • Verify decision-23 is the performance benchmark decision
  • Verify task-19 references decision-23

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Documentation

    • Added architectural decision records covering module structure, CI/CD platform migration (GitHub Actions), security tooling integration (CodeQL, Semgrep, Snyk), code quality scanning (Qodana), license compliance (FOSSA), dependency management strategy, versioning approach, and symbol publishing with SourceLink.
    • Added decision documents for new parameter-level customization attributes and benchmark approach using BenchmarkDotNet.
    • Added performance benchmarking task specifications.
  • Chores

    • Corrected spelling in task documentation.
    • Added "performance" label to configuration.

Mines the full git history to reconstruct 22 architectural decisions
made from 2017 to 2026 and assigns each an accurate date from the
originating commit. Moves the pre-existing performance benchmark
decision to decision-23. Also adds task-19 (Add performance benchmarks).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Warning

Rate limit exceeded

@piotrzajac has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 10 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 24 minutes and 10 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 26b15cee-8ebd-4265-8127-fb38e4d625ed

📥 Commits

Reviewing files that changed from the base of the PR and between a2c1540 and 312a6f2.

📒 Files selected for processing (26)
  • .backlog/completed/task-15 - Add-backlog-CLI-reference-to-AGENTS.md.md
  • .backlog/completed/task-16 - Fix-CodeQL-warnings.md
  • .backlog/completed/task-17 - Consolidate-duplicate-Facts-into-Theories.md
  • .backlog/decisions/decision-1 - Share-fixture-across-member-data-rows-by-default.md
  • .backlog/decisions/decision-10 - Adopt-GitHub-Actions-as-CI-CD-platform.md
  • .backlog/decisions/decision-11 - Integrate-FOSSA-for-license-compliance-scanning.md
  • .backlog/decisions/decision-12 - Use-GitVersion-in-ContinuousDelivery-mode.md
  • .backlog/decisions/decision-13 - Exclude-Moq-from-Dependabot-group-remaining-NuGet-updates.md
  • .backlog/decisions/decision-14 - Enable-CodeQL-for-C-static-security-analysis.md
  • .backlog/decisions/decision-15 - Integrate-Stryker-mutation-testing-into-CI.md
  • .backlog/decisions/decision-16 - Publish-symbols-and-enable-SourceLink.md
  • .backlog/decisions/decision-17 - Add-data-narrowing-parameter-attributes.md
  • .backlog/decisions/decision-18 - Integrate-Semgrep-for-SAST-scanning.md
  • .backlog/decisions/decision-19 - Adopt-Qodana-for-code-quality-scanning.md
  • .backlog/decisions/decision-2 - Decouple-xUnit-from-AutoFixture-via-provider-pattern.md
  • .backlog/decisions/decision-20 - Integrate-Snyk-for-dependency-vulnerability-scanning.md
  • .backlog/decisions/decision-21 - Enforce-Conventional-Commits.md
  • .backlog/decisions/decision-22 - Adopt-CodeRabbit-for-AI-powered-PR-review.md
  • .backlog/decisions/decision-3 - Extract-shared-logic-into-a-Core-assembly.md
  • .backlog/decisions/decision-4 - Support-multiple-mocking-frameworks-as-separate-modules.md
  • .backlog/decisions/decision-5 - Target-netstandard2.0-2.1-and-net472-net48.md
  • .backlog/decisions/decision-6 - Delay-sign-assemblies-full-signing-in-CI-only.md
  • .backlog/decisions/decision-7 - Publish-Core-bundled-into-module-packages-not-standalone.md
  • .backlog/decisions/decision-8 - Suppress-virtual-member-population-via-customization.md
  • .backlog/decisions/decision-9 - Add-CustomizeWith-parameter-attributes.md
  • .backlog/tasks/task-19 - Add-performance-benchmarks.md
📝 Walkthrough

Walkthrough

This pull request adds 23 new architectural decision records and 1 backlog task document to formalize design choices for an AutoFixture XUnit2 mocking library project. It also updates the backlog configuration with a "performance" label and applies a minor spelling correction to a completed task documentation file.

Changes

Cohort / File(s) Summary
Backlog Configuration
.backlog/config.yml, .backlog/completed/task-12
Added "performance" label to configuration; corrected American English spelling in completed task documentation.
Architectural Decisions
.backlog/decisions/decision-[1-7]
Established core module structure, xUnit/AutoFixture integration approach, multi-module support for different mocking frameworks, publishing strategy, and virtual member suppression behavior.
Versioning & CI/CD Platform
.backlog/decisions/decision-[9-11]
Documented GitVersion in ContinuousDelivery mode, GitHub Actions migration from Travis CI, and Dependabot grouping rules for NuGet updates.
Security & Scanning Tooling
.backlog/decisions/decision-[12,13,16,17,20,21]
Integrated Stryker mutation testing, CodeQL static analysis, FOSSA license compliance, Semgrep SAST scanning, Qodana code quality, and Snyk dependency vulnerability detection.
Release & Developer Experience
.backlog/decisions/decision-[14,15,22]
Adopted CodeRabbit for AI-powered PR review, enabled SourceLink with symbol package publishing, and enforced Conventional Commits format via Husky and CommitLint.
Test Data Attributes
.backlog/decisions/decision-[18,19]
Specified four data-narrowing parameter attributes and two CustomizeWith parameter-level customization attributes implemented via IParameterCustomizationSource.
Fixture Configuration
.backlog/decisions/decision-8
Defined ShareFixture default behavior for MemberAutoDataBaseAttribute.
Performance Benchmarking
.backlog/decisions/decision-23, .backlog/tasks/task-19
Established BenchmarkDotNet-based benchmarking strategy and corresponding implementation task with per-module benchmark project structure.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

enhancement

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning PR description lacks issue reference, missing most checklist items, and provides only basic summary without addressing context or rationale. Add 'Closes #' issue reference, provide context explaining why these decisions needed reconstruction, and complete the verification checklist items applicable to documentation changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: registering 23 historical architectural decisions in the backlog documentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/register-historical-backlog-decisions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@piotrzajac piotrzajac self-assigned this Apr 22, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
.backlog/decisions/decision-11 - Exclude-Moq-from-Dependabot-group-remaining-NuGet-updates.md (1)

22-24: Add an explicit Moq re-evaluation cadence.

“Frozen until explicitly upgraded” is clear, but it would be safer to add a periodic review trigger (for example, quarterly/manual security review) to avoid long-term drift.

Suggested wording
 ## Consequences
 
 - Moq version is frozen until explicitly and consciously upgraded.
+- Moq freeze is re-evaluated on a regular cadence (e.g., quarterly) and on any security advisory.
 - Grouped updates reduce weekly PR noise from many individual bumps to a handful of grouped PRs.
 - Any future Moq upgrade must be reviewed for licensing, telemetry, and breaking changes before merging.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.backlog/decisions/decision-11 -
Exclude-Moq-from-Dependabot-group-remaining-NuGet-updates.md around lines 22 -
24, Add a periodic re-evaluation cadence for Moq by updating the decision text
that currently says "Moq version is frozen until explicitly and consciously
upgraded." — append a sentence such as "Moq will be re-evaluated on a quarterly
basis (or upon major security advisories) for licensing, telemetry, security,
and breaking changes" immediately after that bullet so future reviewers have a
clear scheduled trigger for review; ensure the new sentence references the same
review criteria already listed (licensing, telemetry, breaking changes) and
matches the tone/format of the existing bullets.
.backlog/decisions/decision-23 - Performance-benchmark-tooling-and-approach.md (1)

69-71: Clarify benchmark design vs. IDE behavior.

The statement "Each benchmark iteration therefore calls GetData() twice to reflect this reality" conflates IDE discovery behavior with benchmark design. It's unclear whether:

  1. The benchmarks are intentionally designed to call GetData() twice per iteration to simulate IDE behavior, or
  2. This is merely describing IDE behavior without prescribing benchmark design

Benchmarks should measure the library's performance in isolation, not replicate IDE-specific quirks. If the intent is to simulate real-world IDE usage, state this explicitly and justify why IDE behavior should influence benchmark design.

📋 Suggested clarification
-The double-call concern is real at the **IDE layer**: Visual Studio Test Explorer and Rider
-each trigger an independent discovery pass on project load and again on "Run". Each benchmark
-iteration therefore calls `GetData()` **twice** to reflect this reality.
+The double-call concern is real at the **IDE layer**: Visual Studio Test Explorer and Rider
+each trigger an independent discovery pass on project load and again on "Run". Benchmarks
+may optionally call `GetData()` twice per iteration to simulate this IDE behavior, though
+single-call benchmarks remain valid for measuring core library performance.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.backlog/decisions/decision-23 -
Performance-benchmark-tooling-and-approach.md around lines 69 - 71, Clarify
whether the double-call to GetData() is part of the benchmark design or merely
an observation of IDE behavior: in the paragraph mentioning "Each benchmark
iteration therefore calls `GetData()` **twice**" explicitly state intent (e.g.,
"Benchmarks intentionally call `GetData()` twice per iteration to simulate IDE
discovery behavior") and add a sentence justifying that choice (or remove the
sentence if benchmarks should measure the library in isolation); separate the
IDE layer description (Visual Studio Test Explorer and Rider discovery behavior)
from the benchmark methodology and reference the `GetData()` call to make the
distinction unambiguous.
.backlog/decisions/decision-4 - Publish-Core-bundled-into-module-packages-not-standalone.md (1)

23-23: Clarify the distinction between packaging strategy and API visibility.

The statement "its public API is effectively internal" is misleading. Core's public types remain public in the .NET type system and are accessible to consumers of the module packages. The bundling strategy controls distribution, not visibility. Consider rephrasing to: "Core is an implementation detail of the distribution strategy; consumers interact with it through the module packages."

📝 Suggested rephrasing
-- Core is an implementation detail; its public API is effectively internal to the three published packages.
+- Core is an implementation detail of the distribution strategy; consumers interact with it indirectly through the three published module packages, though its public types remain accessible.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.backlog/decisions/decision-4 -
Publish-Core-bundled-into-module-packages-not-standalone.md at line 23, Replace
the misleading sentence "Core is an implementation detail; its public API is
effectively internal to the three published packages." with a clearer
distinction between packaging and type visibility: rephrase to something like
"Core is an implementation detail of the distribution strategy; consumers
interact with it through the module packages." Ensure the wording clarifies that
Core's public types remain public in the .NET type system and that bundling
affects distribution, not API visibility.
.backlog/decisions/decision-22 - Enforce-Conventional-Commits.md (1)

11-16: Consider documenting merge commit exclusion for completeness.

Based on learnings, merge commit messages are intentionally excluded from Conventional Commits linting (via --no-merges flag in git rev-list). Adding this detail to the decision would provide a more complete picture of the enforcement strategy and prevent future confusion.

📋 Suggested addition for merge commit handling
 Enforce Conventional Commits format (`<type>(<scope>): <description>`) on every commit,
+where scope is optional. Merge commits are intentionally excluded from linting.
 Enforcement uses a Husky.NET `commit-msg` hook for local validation and CommitLint.Net
 in CI to block merges that contain non-conforming commit messages.

Based on learnings: merge commits are intentionally excluded from linting in both PR and push-to-master scenarios.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.backlog/decisions/decision-22 - Enforce-Conventional-Commits.md around
lines 11 - 16, Update the decision to explicitly state that merge commits are
excluded from Conventional Commits linting: add a sentence under "Decision"
noting that linting uses git rev-list --no-merges (or equivalent) so merge
commits are skipped, and clarify this applies to both the Husky.NET commit-msg
local validation and the CommitLint.Net CI enforcement to avoid future
confusion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.backlog/decisions/decision-19 - Add-CustomizeWith-parameter-attributes.md:
- Line 27: The document decision-19 currently references "the other
data-narrowing parameter attributes in the same parameter list" which
forward-references features introduced in decision-18 (dated later); to fix,
either update decision-19's date to be after decision-18 or remove the forward
reference phrase from the sentence on line 27 (the fragment "and the other
data-narrowing parameter attributes in the same parameter list"); locate the
sentence in decision-19 and edit it to either adjust the date metadata or remove
that clause so the decision does not reference future features.

In @.backlog/decisions/decision-22 - Enforce-Conventional-Commits.md:
- Line 13: Update the commit format line to use placeholder angle-bracket
notation (e.g., <type>(<scope>): <description>) instead of square brackets, and
add a brief note that scope is optional in this project (include a sentence like
"scope is optional; this project sets conventional-commit.scopes.enabled to
false"). Reference the decision title "decision-22 -
Enforce-Conventional-Commits" and the configuration key
conventional-commit.scopes.enabled to ensure the reader understands the
intentional optionality.
- Line 4: Update the decision entry's date field to match its originating commit
by changing the value of the date: property in the "decision-22 -
Enforce-Conventional-Commits.md" file from '2026-04-22' to '2026-04-10'; locate
the line containing the date: token and replace the timestamp string accordingly
so the file reflects the commit date.

In @.backlog/decisions/decision-3 -
Support-multiple-mocking-frameworks-as-separate-modules.md:
- Around line 17-18: The sentence claiming the attributes (`[AutoMockData]`,
`[InlineAutoMockData]`, `[MemberAutoMockData]`) are "prefixed with the framework
name" is incorrect; update the wording to state that each module (e.g., the
AutoMoq, AutoNSubstitute, and AutoFakeItEasy modules) exposes attributes with
the same public names/shape (e.g., AutoMockDataAttribute,
InlineAutoMockDataAttribute, MemberAutoMockDataAttribute) but differing
implementations via their Customize(IFixture) override, to avoid implying
different API names per framework.

In @.backlog/tasks/task-19 - Add-performance-benchmarks.md:
- Line 19: The link label and target disagree: the visible text shows
"DECISION-1" while the URL points to "decision-23 — Performance benchmark
tooling and approach"; update the markdown so the visible label and the link
target match (either change the label to "DECISION-23 — Performance benchmark
tooling and approach" or change the URL to point to the correct decision
referenced by "DECISION-1"), ensuring the link text and href are consistent in
the line containing "recorded in [DECISION-1 — Performance benchmark tooling and
approach](../decisions/decision-23%20-%20Performance-benchmark-tooling-and-approach.md)".

---

Nitpick comments:
In @.backlog/decisions/decision-11 -
Exclude-Moq-from-Dependabot-group-remaining-NuGet-updates.md:
- Around line 22-24: Add a periodic re-evaluation cadence for Moq by updating
the decision text that currently says "Moq version is frozen until explicitly
and consciously upgraded." — append a sentence such as "Moq will be re-evaluated
on a quarterly basis (or upon major security advisories) for licensing,
telemetry, security, and breaking changes" immediately after that bullet so
future reviewers have a clear scheduled trigger for review; ensure the new
sentence references the same review criteria already listed (licensing,
telemetry, breaking changes) and matches the tone/format of the existing
bullets.

In @.backlog/decisions/decision-22 - Enforce-Conventional-Commits.md:
- Around line 11-16: Update the decision to explicitly state that merge commits
are excluded from Conventional Commits linting: add a sentence under "Decision"
noting that linting uses git rev-list --no-merges (or equivalent) so merge
commits are skipped, and clarify this applies to both the Husky.NET commit-msg
local validation and the CommitLint.Net CI enforcement to avoid future
confusion.

In @.backlog/decisions/decision-23 -
Performance-benchmark-tooling-and-approach.md:
- Around line 69-71: Clarify whether the double-call to GetData() is part of the
benchmark design or merely an observation of IDE behavior: in the paragraph
mentioning "Each benchmark iteration therefore calls `GetData()` **twice**"
explicitly state intent (e.g., "Benchmarks intentionally call `GetData()` twice
per iteration to simulate IDE discovery behavior") and add a sentence justifying
that choice (or remove the sentence if benchmarks should measure the library in
isolation); separate the IDE layer description (Visual Studio Test Explorer and
Rider discovery behavior) from the benchmark methodology and reference the
`GetData()` call to make the distinction unambiguous.

In @.backlog/decisions/decision-4 -
Publish-Core-bundled-into-module-packages-not-standalone.md:
- Line 23: Replace the misleading sentence "Core is an implementation detail;
its public API is effectively internal to the three published packages." with a
clearer distinction between packaging and type visibility: rephrase to something
like "Core is an implementation detail of the distribution strategy; consumers
interact with it through the module packages." Ensure the wording clarifies that
Core's public types remain public in the .NET type system and that bundling
affects distribution, not API visibility.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4a28db82-aacb-49a7-a50a-2530073d2114

📥 Commits

Reviewing files that changed from the base of the PR and between 8d0fe72 and a2c1540.

📒 Files selected for processing (26)
  • .backlog/completed/task-12 - Eliminate-intermediate-array-allocations.md
  • .backlog/config.yml
  • .backlog/decisions/decision-1 - Decouple-xUnit-from-AutoFixture-via-provider-pattern.md
  • .backlog/decisions/decision-10 - Adopt-GitHub-Actions-as-CI-CD-platform.md
  • .backlog/decisions/decision-11 - Exclude-Moq-from-Dependabot-group-remaining-NuGet-updates.md
  • .backlog/decisions/decision-12 - Integrate-Stryker-mutation-testing-into-CI.md
  • .backlog/decisions/decision-13 - Enable-CodeQL-for-C-static-security-analysis.md
  • .backlog/decisions/decision-14 - Adopt-CodeRabbit-for-AI-powered-PR-review.md
  • .backlog/decisions/decision-15 - Publish-symbols-and-enable-SourceLink.md
  • .backlog/decisions/decision-16 - Integrate-FOSSA-for-license-compliance-scanning.md
  • .backlog/decisions/decision-17 - Integrate-Semgrep-for-SAST-scanning.md
  • .backlog/decisions/decision-18 - Add-data-narrowing-parameter-attributes.md
  • .backlog/decisions/decision-19 - Add-CustomizeWith-parameter-attributes.md
  • .backlog/decisions/decision-2 - Extract-shared-logic-into-a-Core-assembly.md
  • .backlog/decisions/decision-20 - Adopt-Qodana-for-code-quality-scanning.md
  • .backlog/decisions/decision-21 - Integrate-Snyk-for-dependency-vulnerability-scanning.md
  • .backlog/decisions/decision-22 - Enforce-Conventional-Commits.md
  • .backlog/decisions/decision-23 - Performance-benchmark-tooling-and-approach.md
  • .backlog/decisions/decision-3 - Support-multiple-mocking-frameworks-as-separate-modules.md
  • .backlog/decisions/decision-4 - Publish-Core-bundled-into-module-packages-not-standalone.md
  • .backlog/decisions/decision-5 - Target-netstandard2.0-2.1-and-net472-net48.md
  • .backlog/decisions/decision-6 - Delay-sign-assemblies-full-signing-in-CI-only.md
  • .backlog/decisions/decision-7 - Suppress-virtual-member-population-via-customization.md
  • .backlog/decisions/decision-8 - Share-fixture-across-member-data-rows-by-default.md
  • .backlog/decisions/decision-9 - Use-GitVersion-in-ContinuousDelivery-mode.md
  • .backlog/tasks/task-19 - Add-performance-benchmarks.md

Comment thread .backlog/decisions/decision-19 - Add-CustomizeWith-parameter-attributes.md Outdated
Comment thread .backlog/decisions/decision-22 - Enforce-Conventional-Commits.md Outdated
Comment thread .backlog/decisions/decision-22 - Enforce-Conventional-Commits.md Outdated
Comment thread .backlog/tasks/task-19 - Add-performance-benchmarks.md Outdated
piotrzajac and others added 2 commits April 22, 2026 23:53
Renumbers all 23 decisions so their IDs match the chronological
order implied by the date field. Decision-23 (Performance benchmark)
remains unchanged as the most recent entry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@piotrzajac piotrzajac merged commit 465541f into master Apr 22, 2026
3 checks passed
@piotrzajac piotrzajac deleted the docs/register-historical-backlog-decisions branch April 22, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant