Skip to content

docs(decisions): Phase 02a packet 1 — foundation decisions (ADR 0023/0024/0028) - #5

Merged
cemililik merged 2 commits into
mainfrom
feat/phase-02a-packet-1-foundation-decisions
May 21, 2026
Merged

docs(decisions): Phase 02a packet 1 — foundation decisions (ADR 0023/0024/0028)#5
cemililik merged 2 commits into
mainfrom
feat/phase-02a-packet-1-foundation-decisions

Conversation

@cemililik

@cemililik cemililik commented May 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Phase 02a Packet 1 ships the three Phase-02a-blocking ADRs as Accepted, unblocking every code-bearing packet that follows.

  • ADR-0023 — Strongly-Typed ID Source Generator → Vogen. Broader value-object coverage (Email / Slug / LocaleCode use the same [ValueObject<Guid>] annotation as IDs), pre-baked EF + JSON + ASP.NET binder + OpenAPI emitters, active maintenance. UUIDv7 minting split: DB-side gen_uuid_v7() for high-volume tables (per ADR-0031), app-side Guid.CreateVersion7() for aggregates needing the ID before flush.
  • ADR-0024 — API Versioning Policy → URL-based /v{N}/, 6-month deprecation window, RFC 8594 Sunset + Deprecation + Link rel=successor-version headers, OpenAPI deprecated: true + x-sunset / x-successor / x-migration-guide extensions for SDK codegen, 410 Gone with RFC 7807 Problem Details at sunset. /healthz exempted. Hub /api/internal/* out of scope (ADR-0019 governs).
  • ADR-0028audit_log Partition Management → Hangfire recurring job (learnstack:audit:partition-management). pg_partman rejected for SelfHostedAirGapped story + single-source-of-truth posture (retention rules already live in Standards 18). Daily 02:15 UTC; create-ahead 2 months; drop only at platform-max (10y) horizon; row-level retention purge separate.

Docs-only. No code. Compile-time Vogen wiring + Entity<TId> base + remaining SharedKernel primitives ship in Packet 2.

Cross-link updates

Test plan

  • Broken-link sweep over all 11 changed Markdown files (incl. cross-references in 3 new ADRs): 0 broken.
  • docs/analysis/ residual scan on changed files: 0 hits.
  • CLAUDE.md hard-rules walk:
    • ✅ ADR numbers sequential (0023 / 0024 / 0028 — already reserved; never reused).
    • ✅ Each ADR cites prior Accepted ADRs it builds on (-0014 / -0016 / -0019 / -0020 / -0031 / -0032).
    • ✅ No 5th cross-module mechanism, no 5th Hub endpoint, no domain-specific names in ADR scope, no IConnectionMultiplexer / KafkaProducer / VaultClient direct injection mentioned.
    • ✅ No edits to other Accepted ADRs' Decision sections — only stale cross-reference links (typo-fix grade) in ADR-0002 / ADR-0016 / ADR-0031.
  • ADR template conformance: every ADR has Decision Drivers (≥ 4 bullets), Considered Options (chosen + ≥ 1 rejected with reasoning), Decision (present tense), Context (deeper why-not + what-would-change-our-minds + what-we-punted-on), Consequences (positive / negative / neutral), Implementation Notes (with architecture-test names), References.
  • Architecture-test identifiers introduced match the catalogue's naming convention (Subject_Constraint): Aggregate_Roots_Use_StronglyTypedId, Every_Deprecated_Endpoint_Has_Sunset_And_Successor, Every_Endpoint_Is_Under_Versioned_Route, Partition_Manager_Job_Is_Registered_At_Startup. Each carries a "lands in Packet N" note; catalogue entries follow when the tests do (per Packet 10's plan).
  • dotnet build — N/A (docs-only).

Notes for the reviewer

  • ADR-0023's Vogen choice is the load-bearing decision for Packet 2. If you push back on Vogen, every subsequent ID-touching packet shifts. The strongest counter-argument is "custom in-house generator"; the ADR's Context section spells out why we declined.
  • ADR-0024's 6-month window is calibrated to the Twilio / Auth0 cluster (multi-tenant SaaS + SDK consumers) rather than the Stripe billing cluster (12-month). The 3-month alternative is explicitly rejected because it doesn't fit tenant-side quarterly SDK regeneration cadences.
  • ADR-0028's row-level retention purge is separate from the partition-drop schedule. The two-job split exists because the platform-max retention (10y) doesn't match per-class retention (2y / 7y); without the split, 2-year-old rows would sit in partitions pinned by 7-year-old security-event rows.
  • The three drafts at the top of the Open ADR Drafts table (ADR-0025 DSL engine, ADR-0026 release-tag scheme, ADR-0027 frontend i18n library) are intentionally not addressed here — they target Phases 05 / 11 / 04 respectively.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Three ADRs finalized and added: Strongly‑Typed ID source generator (Vogen), API Versioning Policy, and Audit‑Log Partition Management.
    • Backend coding and API design standards updated to reflect these ADRs (ID generator, URL-based versioning, deprecation metadata, retention/partitioning approach).
    • Roadmap and README updated: Phase 02a marked “underway,” Packet 0/1 noted as shipped/accepted and Packet 2 listed next.

Review Change Stack

…0024/0028)

Moves the three Phase-02a-blocking drafts from Open ADR Drafts to Accepted:

- ADR-0023 — Strongly-Typed ID Source Generator → Vogen. Chosen for
  broader value-object support (Email / Slug / LocaleCode use the same
  [ValueObject<Guid>] annotation as IDs), pre-baked EF + JSON + ASP.NET
  binder + OpenAPI schema-filter emitters, and active maintenance
  velocity. PrivateAssets="all" reference in SharedKernel; no runtime
  bleed into module assemblies. UUIDv7 minting split DB-side
  (gen_uuid_v7 per ADR-0031) for high-volume tables, app-side
  (Guid.CreateVersion7) for aggregates needing the id before flush.

- ADR-0024 — API Versioning Policy. Codifies what Standards 04 already
  half-said: URL-based /v{N}/, no minor versions in the URL, 6-month
  deprecation window (vs Stripe's 12, Twilio's 6 — we sit with Twilio).
  Every deprecated endpoint carries RFC 8594 Sunset + Deprecation +
  Link rel=successor-version headers plus OpenAPI deprecated + x-sunset
  + x-successor + x-migration-guide extensions for SDK codegen.
  410 Gone with RFC 7807 Problem Details at sunset. /healthz exempted.
  Hub /api/internal/* surface explicitly out of scope (governed by
  ADR-0019).

- ADR-0028 — audit_log Partition Management → Hangfire recurring job
  (learnstack:audit:partition-management). pg_partman rejected for
  air-gapped-deployment story (no PG extension to ship) + single-
  source-of-truth posture (retention rules already in Standards 18, not
  duplicated in partman config). Daily 02:15 UTC; create-ahead 2
  months; drop only at platform-max (10y) horizon; row-level retention
  purge separate (separate Hangfire job operating inside still-attached
  partitions).

Cross-link updates:
- docs/standards/02-backend-coding.md § Strongly-Typed Identifiers cites
  ADR-0023 with the Vogen [ValueObject<Guid>(...)] declaration shape.
- docs/standards/04-api-design.md § Versioning cites ADR-0024 with the
  6-month + RFC 8594 + OpenAPI extension set.
- docs/decisions/0002-initial-architecture.md, 0016-audit-log-subsystem.md,
  0031-postgresql-major-version.md: stale "ADR-XXXX draft" references
  updated to point at the now-Accepted files.
- docs/decisions/README.md: 3 rows added to Active ADRs, removed from
  Open ADR Drafts.
- docs/roadmap/phase-02a-kernel-tenancy.md: Packet 1 marked ✅; the ADR
  commitments table at the bottom updated to "Accepted" state.
- README.md: Status line names the three new ADRs and points at Packet 2
  (Shared Kernel core) as next.

No code in this packet; ADR-0023's compile-time Vogen wiring + the
Entity<TId> base + Result<T> already-in-SharedKernel work belongs in
Packet 2. Packet 0 was the kickoff; Packet 1 unblocks Packets 2+.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @cemililik, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b656b1c7-999d-4b77-8775-cc8ef7ab8e4e

📥 Commits

Reviewing files that changed from the base of the PR and between da1d37e and 9df097d.

📒 Files selected for processing (6)
  • docs/decisions/0016-audit-log-subsystem.md
  • docs/decisions/0023-strongly-typed-id-source-generator.md
  • docs/decisions/0024-api-versioning-policy.md
  • docs/decisions/0028-audit-log-partition-management.md
  • docs/standards/02-backend-coding.md
  • docs/standards/04-api-design.md
✅ Files skipped from review due to trivial changes (4)
  • docs/decisions/0016-audit-log-subsystem.md
  • docs/standards/02-backend-coding.md
  • docs/decisions/0023-strongly-typed-id-source-generator.md
  • docs/decisions/0028-audit-log-partition-management.md

📝 Walkthrough

Walkthrough

Phase 02a Packet 1 (Foundation decisions) ships with three newly documented architecture decisions: Vogen for strongly-typed IDs, URL-based API versioning with 6-month deprecation windows, and Hangfire-managed audit log partitioning. Cross-references in existing ADRs, standards documentation, and roadmap tracking are updated to reflect these acceptances.

Changes

Phase 02a Packet 1 Architecture Decisions

Layer / File(s) Summary
ADR-0023: Strongly-typed ID source generator (Vogen)
docs/decisions/0023-strongly-typed-id-source-generator.md
Vogen is selected as the compile-time source generator for strongly-typed IDs and value objects, with [ValueObject<Guid>(...)] annotation pattern, support for EF Core/JSON/OpenAPI/minimal API binding, and UUIDv7 minting split between DB-side gen_uuid_v7() for high-volume tables and app-side Guid.CreateVersion7().
ADR-0024: API versioning policy
docs/decisions/0024-api-versioning-policy.md
URL-based major versioning under /api/v{N}/ with a 6-month deprecation window, RFC 8594 Deprecation/Sunset headers, OpenAPI deprecation extensions, and implementation notes for routing, OpenAPI emission, middleware headers, and SDK generation.
ADR-0028: Audit log partition management (Hangfire)
docs/decisions/0028-audit-log-partition-management.md
Hangfire recurring job learnstack:audit:partition-management manages monthly audit_log partitions (create-ahead/idempotency, drop-by-retention), with retention enforced via a separate row-level purge job and failure observability via IErrorTrackingProvider and integration events.
ADR acceptance and cross-references
docs/decisions/0002-initial-architecture.md, docs/decisions/0016-audit-log-subsystem.md, docs/decisions/0031-postgresql-major-version.md, docs/decisions/README.md
Existing ADRs updated to reference finalized ADR-0023/0024/0028 files; decisions README adds ADR-0023/0024/0028 to Active ADRs and moves reserved drafts to 0025–0027.
Standards and roadmap alignment
docs/standards/02-backend-coding.md, docs/standards/04-api-design.md, docs/roadmap/phase-02a-kernel-tenancy.md, README.md
Backend coding standards now reference Vogen and the canonical ValueObject<Guid> pattern; API design standards align with ADR-0024 and update examples to /api/v1/...; roadmap marks Packet 1 decisions as Accepted; README reflects per-packet shipping progress.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • cemililik/LearnStack#4: Both PRs update Phase 02a delivery tracking and roadmap documents; PR #4 established the per-packet structure that this PR populates with accepted ADR decisions.

Poem

🐰 I penned three choices bright and small,
Vogen, versions, partitions — one and all.
Docs updated, packets now proceed,
Phase 02a grows from seed to seed. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically identifies the main change: acceptance of three Phase 02a foundation decision ADRs (0023, 0024, 0028) with focus on decisions rather than implementation details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 feat/phase-02a-packet-1-foundation-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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request formalizes several architectural decisions for Phase 02a, including the adoption of Vogen for strongly-typed IDs and value objects (ADR-0023), the establishment of a URL-based API versioning policy with a six-month deprecation window (ADR-0024), and the selection of Hangfire recurring jobs for audit log partition management (ADR-0028). Corresponding updates have been made to the project roadmap, coding standards, and existing ADRs to reflect these decisions. Feedback was provided regarding the format of the Deprecation header to ensure alignment with IETF drafts and to correct a typo in the RFC reference for the Sunset header.

Comment on lines +100 to +101
- `Deprecation: @<unix-timestamp>` HTTP response header on every call
(per `draft-ietf-httpapi-deprecation-header-06`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The Deprecation header format @<unix-timestamp> does not align with the cited draft-ietf-httpapi-deprecation-header-06. That draft specifies a boolean value (Deprecation: true), while later drafts specify an HTTP-date. Using a Unix timestamp appears to be a custom implementation that deviates from the standard you're aiming to follow.

To better adhere to web standards, consider aligning with one of the draft versions. For example:

  • Use a boolean value and a separate Link header with rel="deprecation" as per older drafts.
  • Use an HTTP-date as per the latest draft.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Applied in 9df097d. Verified against the upstream spec: RFC 9745 (March 2025) superseded the draft and uses sf-date per RFC 9651 § 3.3.7, format @<unix-timestamp>. The ADR now cites RFC 9745 + RFC 9651 directly in the Lifecycle section and the References block.

Comment on lines +102 to +103
- `Sunset: <RFC 9651 HTTP-date>` HTTP response header pointing 6 months
into the future (per RFC 8594).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

There seems to be a typo in the RFC number. RFC 9651 does not exist. The Sunset header is defined in RFC 8594, and its value should be an HTTP-date as defined in RFC 7231. It would be clearer to use <HTTP-date> as a placeholder.

Suggested change
- `Sunset: <RFC 9651 HTTP-date>` HTTP response header pointing 6 months
into the future (per RFC 8594).
- `Sunset: <HTTP-date>` HTTP response header pointing 6 months
into the future (per RFC 8594).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Applied in 9df097d. RFC 9651 IS a real RFC (Structured Field Values for HTTP, used by the Deprecation header) but was the wrong citation for Sunset. Replaced with HTTP-date per RFC 9110 § 5.6.7, which is what RFC 8594 § 3 actually requires (example: Sun, 15 Jan 2027 00:00:00 GMT).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/decisions/0016-audit-log-subsystem.md`:
- Around line 295-296: The paragraph in 0016-audit-log-subsystem.md conflicts
with ADR-0028 by implying tenant retention purges drop partitions; update the
text to explicitly follow ADR-0028: state that partition management (including
monthly partition drops via the Hangfire recurring job) is handled at the
platform horizon per ADR-0028, while tenant-specific retention is enforced via
row-level purge and does not drop partitions, and remove or reword any sentence
that says retention purge drops partitions by tenant windows to avoid the
contradiction.

In `@docs/decisions/0023-strongly-typed-id-source-generator.md`:
- Around line 190-192: The inline code span for the PackageVersion XML element
is malformed (extra backtick) in the sentence mentioning
Directory.Packages.props; fix the markdown so the full element is a single
inline code span (e.g. `<PackageVersion Include="Vogen" Version="..." />`) and
ensure the following `<PackageReference Include="Vogen" PrivateAssets="all" />`
remains properly formatted; update the text around Directory.Packages.props and
LearnStack.SharedKernel.csproj to use that single correct inline code span.

In `@docs/standards/02-backend-coding.md`:
- Around line 52-63: Update the standards file header to include ADR-0023 in the
"Derives from:" metadata so the backend coding standard traces its source to
ADR-0023 (which defines the shared Vogen-based value object convention); locate
the "Derives from" header in docs/standards/02-backend-coding.md and add
"ADR-0023" alongside the existing ADR-0002/0006 entries.

In `@docs/standards/04-api-design.md`:
- Around line 34-56: The file's metadata header is missing ADR-0024 as a
provenance source; update the document header that lists "Derives from" (the
top-of-file metadata block) to include "ADR-0024" (or the full ADR identifier
"ADR-0024: API versioning policy") so the Versioning standard explicitly cites
ADR-0024 as its source; ensure the header format matches other standards files
(the existing "Derives from" field) and add the ADR identifier only to that
header without changing the body text.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 57cca3fa-6606-4575-8b1d-0a073327819b

📥 Commits

Reviewing files that changed from the base of the PR and between 29adb7b and da1d37e.

📒 Files selected for processing (11)
  • README.md
  • docs/decisions/0002-initial-architecture.md
  • docs/decisions/0016-audit-log-subsystem.md
  • docs/decisions/0023-strongly-typed-id-source-generator.md
  • docs/decisions/0024-api-versioning-policy.md
  • docs/decisions/0028-audit-log-partition-management.md
  • docs/decisions/0031-postgresql-major-version.md
  • docs/decisions/README.md
  • docs/roadmap/phase-02a-kernel-tenancy.md
  • docs/standards/02-backend-coding.md
  • docs/standards/04-api-design.md

Comment thread docs/decisions/0016-audit-log-subsystem.md
Comment thread docs/decisions/0023-strongly-typed-id-source-generator.md Outdated
Comment thread docs/standards/02-backend-coding.md
Comment thread docs/standards/04-api-design.md Outdated
…ix + partition shape

Addresses two review-agent passes on PR #5. Each finding was verified against
current code / upstream docs / corpus before fixing; the trivial-prose Minors
(steel-man overlap, in-place edits to Accepted ADRs' Drivers vs dated
Amendments) were left alone with explicit reasoning.

Blockers / Majors fixed:

- ADR-0023 Vogen API claims. Verified against
  https://github.com/SteveDunn/Vogen/blob/main/src/Vogen.SharedTypes/Conversions.cs:
  `Conversions.AspNetCoreRouteParameter` and `Conversions.SwaggerSchemaFilter`
  are fabricated names. Real members used: `EfCoreValueConverter`,
  `SystemTextJson`, `TypeConverter` (TypeConverter is what carries ASP.NET
  Core route binding). OpenAPI schema mapping is wired separately via either
  assembly-level `[VogenDefaults(openApiSchemaCustomizations: ...)]` or a
  custom `IOpenApiSchemaTransformer` in `LearnStack.Api` (Packet 4 picks
  one). EF registration is explicit, not convention-scanned —
  `LearnStack.SharedKernel.Infrastructure.ModelConfigurationBuilder.RegisterVogenIds(Assembly[])`
  helper reflects Domain assemblies and calls `.HaveConversion<...>()`.
  Acknowledged `Vogen.SharedTypes.dll` runtime dependency (~10KB, MIT).
  PrivateAssets="all" must be per-project: SharedKernel for cross-cutting VOs
  + each `LearnStack.Modules.<X>.Domain` for aggregate IDs; centralised via
  `Directory.Build.props` under `backend/src/Modules/`.

- ADR-0024 route prefix `/v1/*` → `/api/v{N}/*` end-to-end. Verified against
  `infra/apisix/apisix.yaml` (routes `/api/v*/**`) and
  `docs/architecture/30-api-gateway.md` (uses `/api/v*/**`). Fixed Decision,
  Lifecycle, Per-deployment-mode, OpenAPI examples, Punted-on, Drivers (the
  "first endpoint already ships" claim was factually wrong — the scaffold
  exposes `/healthz` unversioned, not `/v1/healthz`).

- ADR-0024 Deprecation header citation. Verified RFC 9745 (March 2025,
  "The Deprecation HTTP Response Header Field") supersedes
  `draft-ietf-httpapi-deprecation-header`. Replaced all three citation sites
  (Drivers, Lifecycle, References). Format `@<unix-timestamp>` is correct
  per RFC 9745 § 2 (sf-date per RFC 9651 § 3.3.7).

- ADR-0024 Sunset HTTP-date citation. RFC 9651 is Structured Field Values
  (sf-date, used by Deprecation), NOT HTTP-date. Sunset uses HTTP-date per
  RFC 9110 § 5.6.7 (was RFC 7231 § 7.1.1.1). Fixed example placeholder +
  References block.

- ADR-0024 Problem Details example host. Was `learnstack.dev/problems/...`;
  Standards 04 § Errors uses `errors.learnstack.dev/...`. Aligned to the
  Standards 04 convention.

- ADR-0024 closed-set enum rule. Was only in prose below the matrix;
  promoted to a matrix row (Breaking: "Adding a value to a closed-set enum
  (default)"). Open-set rule stays on the non-breaking side with the
  `x-extensible-enum: true` hint.

- ADR-0028 partition shape. Verified ADR-0016 + architecture/31 use
  `PARTITION BY RANGE (timestamp)`. My LIST claim was inconsistent; fixed
  to RANGE(timestamp) and noted this ADR owns *lifecycle*, not table layout
  (which stays under ADR-0016). Column-name occurrences `occurred_at` →
  `timestamp` to match the authoritative ADR. (Standards 18 still uses
  `occurred_at` — a pre-existing corpus inconsistency, out of this PR's
  scope.)

- ADR-0028 anchor "§ Background Jobs". Verified architecture/31 has no
  such heading; the cited content lives under "§ 8 Retention" (lines
  432-438). Fixed both occurrences (Drivers + References).

- ADR-0028 architecture-test name `Partition_Manager_Job_Is_Registered_At_Startup`
  → `Partition_Manager_Job_Is_Registered_AtStartup` to match the catalogue's
  existing `IExceptionHandler_Registered_AtStartup` single-token convention.

- ADR-0016 retention-purge text contradicted ADR-0028 ("dropping partitions
  older than the tenant's configured retention window"). Reworded to follow
  ADR-0028's split: partition lifecycle = platform-max horizon via
  `learnstack:audit:partition-management`; per-tenant retention = row-level
  delete via `learnstack:audit:retention-purge` inside still-attached
  partitions.

Cross-link / standards-hygiene fixes:

- Standards 02 `**Derives from:**` adds ADR-0023 alongside ADR-0002 / ADR-0006.
- Standards 04 `**Derives from:**` adds ADR-0024 alongside ADR-0002 / ADR-0003.
- Standards 04 § Versioning shrunk from a duplicate of ADR-0024 to a
  one-paragraph summary + "for the full policy, see ADR-0024" pointer
  (single-source-of-truth per Standards 13).
- Standards 04 URL examples (7 occurrences) updated from `/v1/...` to
  `/api/v1/...` to match the canonical APISIX route shape. The
  `/openapi/v1.json` spec download URL is intentionally left as-is (that's
  a spec download surface, not an API endpoint).

Skipped with reasoning:

- "Why Hangfire over pg_partman + steel-man overlap" (ADR-0028 § Context) —
  reviewer marked as defensible-as-is; the steel-man section earns its
  keep for a 2027 reader who might wonder if we should have chosen
  pg_partman.
- "In-place edits to Accepted ADRs 0002 / 0016 / 0031 push slightly past
  typo grade" — reviewer marked as "Acceptable for this PR"; switching to
  dated Amendments retroactively would itself be an Accepted-ADR edit.
  The previous packet's commit body already noted the pattern.
- ADR-0023 inline code span (malformed extra backtick) — already
  collateral-fixed in the Implementation Notes § Package reference rewrite
  in this same commit; the malformed `<PackageVersion Include="Vogen" Version="..."` />
  span is now a single clean inline span.

Validation:
- Broken-link sweep over 6 changed files: 0 broken.
- docs/analysis/ residual scan: 0 hits.
- Conversions enum members in ADR-0023 verified against upstream source.
- Standards 04 has no remaining bare `/v1/` API-surface examples.
- ADR-0028 has no remaining LIST / At_Startup / Background Jobs references.
- ADR-0024 cites RFC 9745 + RFC 8594 + RFC 9651 + RFC 9110 + RFC 7807 with
  correct role per header.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cemililik

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cemililik
cemililik merged commit aabaa2f into main May 21, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant