Skip to content

Bootstrap repository scaffolding and microservices documentation - #1

Merged
xavierjohn merged 2 commits into
mainfrom
feat/bootstrap-and-docs
Jun 6, 2026
Merged

Bootstrap repository scaffolding and microservices documentation#1
xavierjohn merged 2 commits into
mainfrom
feat/bootstrap-and-docs

Conversation

@xavierjohn

Copy link
Copy Markdown
Owner

What

PR A of the carve-out — repository scaffolding plus the four LLM-discoverability docs that establish this repo's shape before any .cs lands.

Zero .cs in this PR. Source for the three packages lands in follow-ups:

  • PR BTrellis.Microservices.Abstractions (promotes TrellisInternalJwtClaimNames to public).
  • PR CTrellis.Yarp move from main + Trellis.Microservices.AspNetCore carve-out (namespace rename).

File inventory (24 files)

Standard scaffolding (verbatim from xavierjohn/Trellis where possible)

File Source
.editorconfig, .gitattributes, .gitignore (replaces stub), nuget.config, global.json, icon.png verbatim copy
build/test.props, build/Trellis.ApiReference.targets verbatim copy
.github/dependabot.yml verbatim copy
LICENSE unchanged (auto-init MIT)

Adapted (not verbatim)

File Adaptation
Directory.Build.props RepositoryUrl + PackageProjectUrl point to xavierjohn/Trellis.Microservices; Copyright year 2026
Directory.Build.targets TrellisShipsCookbook now packs trellis-api-microservices-cookbook.md (not main's trellis-api-cookbook.md)
Directory.Packages.props Pruned to packages this repo will consume (Yarp, IdentityModel, AspNetCore auth + test infra) + added upstream Trellis.Asp / Trellis.Authorization / Trellis.Core / Trellis.ServiceDefaults deps as NuGet refs
version.json Initial version 0.1-alpha.{height} — placeholder; tracked as outstanding decision in session-state/files/carveout-plan.md
Trellis.Microservices.slnx Solution-items only (no projects yet)
README.md, CHANGELOG.md Written from scratch for this repo

Documentation

File Status
.github/copilot-instructions.md NEW — agent instructions with "P4 invariants — never regress" 14-row checklist for any change touching minter / validator / provider code
docs/docfx_project/api_reference/trellis-api-microservices-cookbook.md NEW — LLM entry-point cookbook (Recipes 1+2 are intentional stubs; carry-over from main Recipes 33+34 lands in PR C)
docs/docfx_project/api_reference/trellis-api-yarp.md MOVED from main repo with cross-doc rewrites (Recipes 33/34 → 1/2; trellis-api-asp.mdtrellis-api-internal-jwt.md)
docs/docfx_project/api_reference/trellis-api-internal-jwt.md NEW — carved from main trellis-api-asp.md TrellisInternalJwt* sections (namespace renamed Trellis.Asp.AuthorizationTrellis.Microservices.AspNetCore)
docs/docfx_project/api_reference/trellis-api-microservices-abstractions.md NEW — abstractions package reference
docs/lint-api-reference.ps1, docs/lint-api-reference.md Doc-lint infrastructure verbatim from main

Verification

  • pwsh docs/lint-api-reference.ps1 — passes (4 markdown files scanned, exit 0).
  • ✅ BOM check — all .md / .xml / .props / .targets / .slnx files have UTF-8 BOM per .editorconfig. JSON files (global.json, version.json, nuget.config) match upstream convention.
  • ⏸️ dotnet build / dotnet test — N/A (no .csproj yet). First signal lands in PR B.
  • ⏸️ audit-stale-docs.ps1 — not copied (it scans .cs for deprecated vocabulary; nothing to audit yet). Add in PR B with the first source file.

Lint regressions fixed during validation

The api-reference lint script (copied from main) caught 15 issues across the 4 drafted docs:

Rule Count Fix applied
TRLDOC001 — bare cross-doc trellis-api link missing anchor 11 Added #use-this-file-when anchors
TRLDOC003 — anchor doesn't resolve in (self) 4 Added <!-- trellis-doc-lint: allow-broken-anchor --> markers; anchors resolve once Recipe 1+2 bodies are inlined in PR C

Outstanding decisions (deferred to PR B or beyond)

  1. Initial version — currently 0.1-alpha.{height} placeholder. Final choice (0.1.0-preview.0 vs 1.0.0-preview.0) needs to land before PR B publishes the first preview NuGet.
  2. Trellis.Yarp version reset behavior on move — continue main's Nerdbank.GitVersioning numbering vs reset.
  3. TrellisServiceBuilder.UseTrellisInternalJwtActor slot location — keep on upstream Trellis.ServiceDefaults (current) vs move to this repo.
  4. Recipe 7 update in main — full forward-pointer vs slim summary (PR D against main repo).

Reviewer focus

  • Doc cross-references — every link in the 4 reference docs should either be a valid in-doc anchor, point at another in-repo doc with a #use-this-file-when anchor, or be a full URL to upstream xavierjohn/Trellis.
  • P4 invariants — never regress table in .github/copilot-instructions.md — verify the 14 invariants match shipped behavior in xavierjohn/Trellis PR #582/#583/#584.
  • Migration note in trellis-api-internal-jwt.md (bottom) — verify services.AddTrellis(b => ...) syntax matches the actual Trellis.ServiceDefaults extension method (TrellisServiceCollectionExtensions.cs).
  • Trellis.Microservices.slnx — no projects yet; this PR is solution-items only. PR B adds the first project.

🤖 Generated with GitHub Copilot CLI

Initial PR for the new xavierjohn/Trellis.Microservices repository.
Establishes file conventions, central package management, and the four
LLM-discoverability docs (cookbook + 3 package references) plus the
.github/copilot-instructions.md agent guardrails. No .cs yet — source
for the three packages lands in follow-up PRs B and C.

Layout mirrors xavierjohn/Trellis conventions: TreatWarningsAsErrors,
central package management, BOM-enforced .editorconfig, Nerdbank.GitVersioning,
TrellisApiRefName auto-pack mechanism, doc lint script.

Doc-lint validation: api-reference lint script passes against all 4 new
reference docs after fixing 11 bare-cross-doc-link warnings (added
#use-this-file-when anchors) and 4 broken-anchor warnings (added
allow-broken-anchor markers for anchors that resolve once Recipe 1/2
bodies are inlined in PR C).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Pull request overview

Bootstraps the new Trellis.Microservices repository with baseline build/scaffolding assets and the initial set of LLM-discoverability / API-reference docs that define the repo’s intended microservices/JWT trust-boundary surface before any C# source lands.

Changes:

  • Adds repo-wide .NET build configuration (Directory.Build.* + central package versions) and versioning config (Nerdbank.GitVersioning).
  • Introduces DocFX-style API reference markdown + a PowerShell lint gate for cross-doc link/anchor hygiene.
  • Adds contribution/agent guidance (.github/copilot-instructions.md) and standard repo scaffolding (editorconfig/gitattributes/gitignore, solution items, dependabot, etc.).

Reviewed changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
version.json Initializes Nerdbank.GitVersioning configuration for prerelease versioning.
Trellis.Microservices.slnx Adds a solution-items-only .slnx referencing scaffolding + docs.
README.md Replaces stub readme with repo purpose, package inventory, and doc entry points.
nuget.config Sets NuGet source configuration (nuget.org only).
global.json Pins SDK and test runner settings for the repo.
docs/lint-api-reference.ps1 Adds API-reference markdown lint script (anchors/cross-doc link rules).
docs/lint-api-reference.md Documents the lint rules and intended usage.
docs/docfx_project/api_reference/trellis-api-yarp.md Adds/migrates gateway-side YARP/internal-JWT contract reference.
docs/docfx_project/api_reference/trellis-api-microservices-cookbook.md Adds the cookbook entry point + recipe placeholders and routing tables.
docs/docfx_project/api_reference/trellis-api-microservices-abstractions.md Adds the abstractions/claim-constants contract reference.
docs/docfx_project/api_reference/trellis-api-internal-jwt.md Adds consumer-side internal-JWT actor provider/options reference + migration note.
Directory.Packages.props Introduces central package version pinning for runtime + test dependencies.
Directory.Build.targets Adds packing conventions for API refs + optional lint target hook.
Directory.Build.props Establishes repo-wide build properties, packaging metadata, analyzers, etc.
CHANGELOG.md Adds initial changelog describing repo bootstrap contents.
build/Trellis.ApiReference.targets Adds MSBuild target to sync packaged API refs into .github/ for Copilot.
build/test.props Adds shared test project props (MTP runner, package refs, analyzers off).
.gitignore Replaces stub/updates ignore rules and adds Trellis-specific generated paths.
.github/dependabot.yml Enables weekly Dependabot updates for Actions + NuGet.
.github/copilot-instructions.md Adds agent/contribution guidance + “P4 invariants — never regress” checklist.
.gitattributes Configures text/binary handling and encoding declarations.
.editorconfig Adds repo-wide formatting/style rules and UTF-8 BOM enforcement.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

| `using Trellis.Asp.Authorization;` (for `TrellisInternalJwt*`) | `using Trellis.Microservices.AspNetCore;` |
| `Trellis.Asp` NuGet package | `Trellis.Microservices.AspNetCore` NuGet package (add reference) + still keep `Trellis.Asp` (for everything else) |
| `services.AddTrellisInternalJwtActorProvider(...)` | unchanged (extension method is `IServiceCollection`-scoped, namespace move only) |
| `builder.AddTrellis(b => b.UseTrellisInternalJwtActor(...))` | `services.AddTrellis(b => b.UseTrellisInternalJwtActor(...))` — `AddTrellis` is an `IServiceCollection` extension. The composition-root slot (`TrellisServiceBuilder.UseTrellisInternalJwtActor`) remains on `Trellis.ServiceDefaults.TrellisServiceBuilder` in the upstream `xavierjohn/Trellis` repo; this package supplies the underlying `TrellisInternalJwtActorProvider`. Slot signature unchanged. |

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in b822902. The Old column now correctly shows the actual pre-carveout form (services.AddTrellis(b => b.UseTrellisInternalJwtActor(...))) and notes the call site is unchanged — the only migration step is adding the Trellis.Microservices.AspNetCore NuGet reference so the upstream TrellisServiceBuilder.UseTrellisInternalJwtActor slot can resolve the moved provider.

Comment thread docs/lint-api-reference.md Outdated
pwsh docs/lint-api-reference.ps1
```

The solution build runs the same script through `docs\Trellis.DocsLint.csproj`, so failures are emitted as MSBuild errors.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in b822902. Now describes the actual integration: the LintApiReference target in Directory.Build.targets, opt-in per project via <TrellisEnableApiReferenceLint>true</TrellisEnableApiReferenceLint>. The Trellis.DocsLint.csproj reference was stale from when this doc was copied verbatim from main.

…ild integration reference

Round-1 Copilot reviewer findings:

1. trellis-api-internal-jwt.md migration table: the `Old` column listed
   `builder.AddTrellis(...)` which was never a valid Trellis registration
   surface. AddTrellis is and always was an IServiceCollection extension,
   so the call site is identical pre- and post-carveout. Rewrite the row
   to reflect actual migration shape: call site unchanged; the only
   change is adding the Trellis.Microservices.AspNetCore NuGet reference,
   which lets the upstream TrellisServiceBuilder.UseTrellisInternalJwtActor
   slot resolve the provider that moved to this package.

2. lint-api-reference.md: line 11 referenced
   `docs\Trellis.DocsLint.csproj` which does not exist in this repo
   (that csproj lives only in xavierjohn/Trellis). The actual MSBuild
   integration is the LintApiReference target in Directory.Build.targets,
   opt-in per project via <TrellisEnableApiReferenceLint>true. Rewrite
   the line to describe the actual mechanism.

Doc lint passes (4 markdown files scanned, exit 0).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@xavierjohn
xavierjohn merged commit 430b134 into main Jun 6, 2026
xavierjohn added a commit that referenced this pull request Jun 6, 2026
…CHANGELOG

Round-1 Copilot reviewer findings (all 11 applied):

1+5. ReleaseGateScenarios.cs:16 - class XmlDoc listed a "KeyRotation"
    gateway-to-downstream scenario that doesn't exist. Updated the
    docstring to list the actual 8 scenarios by category.

2. HarnessFixtures.cs:94 - fixture claimed to use "strict cookbook
    Recipe 1 profile" but missed RequireExpirationTime=true. Added.

3. HarnessFixtures.cs:62 - remarks said "mediator pipeline 401s" but
    this harness has no mediator. The /probe endpoint handler itself
    returns 401 on Maybe.None. Comment updated.

4. E2EHarness.Tests.csproj:37 - removed unused
    Microsoft.Extensions.TimeProvider.Testing PackageReference
    (nothing in the project uses FakeTimeProvider).

6+7+8. POST -> GET across ReleaseGateScenarios.cs:27, HarnessFixtures.cs:30,
    README.md:27. The harness actually uses GET /probe with
    Authorization: Bearer header (per HarnessFixtures.ProbeAsync); the
    "POST" wording in the docs was inaccurate.

9. README.md:69 - P4-invariant mapping row for MapInboundClaims=false /
    TryAllIssuerSigningKeys=false was still over-claiming. Narrowed
    further: the row now says the fixture configures both consistent
    with Recipe 1 but does NOT prove either's protective effect (the
    actor provider has explicit sub short-long fallback that lets the
    contract work even with MapInboundClaims=true; the wrong-kid
    fallback path is not exercised with the single-key fixture).

10. GatewayHarness.cs:89 - the TestServerForwarderHttpClientFactory
    captures an HttpMessageHandler but never disposes it (handler leak
    across larger/looped runs). Made the factory IDisposable so DI
    disposes the handler when the host disposes.

11. CHANGELOG.md:11 - section heading "0.1-alpha.d - Cookbook Recipes
    1+2 inlined" had bullets describing the Abstractions package. Root
    cause: a prior edit during PR #7 ate the 0.1-alpha.b heading and
    mis-attributed 0.1-alpha.b's bullets to 0.1-alpha.c, then PR #8
    compounded the damage by renaming 0.1-alpha.c -> 0.1-alpha.d.

    Reconstructed the full CHANGELOG from git history. Structure now:
      ## Unreleased       - E2E harness (this PR)
      ## 0.1-alpha.d      - Recipes inlining + slot-ref cleanup (PR #7)
      ## 0.1-alpha.c      - Yarp move + AspNetCore carve-out (PR #3)
      ## 0.1-alpha.b      - Abstractions package (PR #2)
      ## 0.1-alpha.a      - Initial bootstrap (PR #1)

    The 0.1-alpha.d body was recovered from origin/main's Unreleased
    section (post-PR-#7-merge); the 0.1-alpha.c body was recovered from
    PR #3's merge-commit CHANGELOG state via git show.

Build + test + lint: 0 warnings, 0 errors; 231/231 pass; doc-lint clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
xavierjohn added a commit that referenced this pull request Jun 7, 2026
…m the RBAC rework

The Aspire+RBAC sample had 4 places where the prose/snippets hadn't been
updated when the RBAC layer changed the Orders endpoint shapes. Found by a
local code-review pass (gpt-5.5).

1. ARCHITECTURE.md §3 happy-path sequenceDiagram showed the response as
   `{ "service":"orders", "actor":{...} }` — that was the SHAPE before RBAC.
   The current `GET /api/orders` endpoint returns an array of OrderResponse
   DTOs (`orders.Select(OrderResponse.From).ToArray()` in Orders/Program.cs).
   Updated the diagram's last step to show the actual array shape.

2. README.md "Drive it with curl" section had the same stale "service+actor"
   response example for /api/orders. Replaced with:
   - Orders → array of seeded OrderResponse DTOs (the actual response)
   - Billing → unchanged Actor-echo shape (Billing IS still actor-echo; only
     Orders gained the domain layer)
   Also updated the `Invoke-RestMethod` comments to make the contrast
   explicit (Orders has domain; Billing stays trust-boundary-only).

3. README.md "Load-once invariant" bullet over-stated the claim:
   "Orders handlers inject IAuthorizedResource<,> instead of IOrderRepository"
   — but ListOrdersHandler CORRECTLY injects IOrderRepository (list is a
   static-permission-only path; not a single-resource auth path). The
   broad claim would mislead a careful reader auditing whether the
   load-once invariant holds for list too. Narrowed to: "the single-resource
   Orders handlers (GetOrderHandler / UpdateOrderHandler) inject
   IAuthorizedResource<TCommand, Order>", with an explicit note that
   ListOrdersHandler uses IOrderRepository.ListAllAsync intentionally.

4. Sample.http "Load-once proof" comment had the same over-broad claim.
   Same narrowing applied.

5. Sample.http request #1 description said the response is "service:orders
   + round-tripped Actor" — same stale shape. Updated to "an array of
   seeded OrderResponse DTOs (order-1 + order-2)".

6. CHANGELOG entry said "bumped all 7 upstream Trellis.* pins from
   alpha.342 to alpha.360". Only 5 pins existed at alpha.342 — bumped those
   5; Trellis.Mediator + Trellis.Primitives are NEW pins added at alpha.360
   (the sample didn't consume them before RBAC). Rewrote the line to be
   accurate about which pins are bumped vs newly-added.

7. OrderResourceLoader.cs:7-10 source comment had the bridge direction
   REVERSED — it said "Bridges from Result<Order> (auth) to Maybe<Order>
   (repo)" but the code does the opposite (repo returns Maybe<Order>; the
   loader translates to Result<Order> via Error.NotFound). Swapped the
   from/to in the comment to match the code.

No runtime behavior change. Pure documentation/comment alignment.

Verified
--------

- dotnet build Trellis.Microservices.slnx -c Release → 0 warnings, 0 errors
- All 11 Mermaid diagrams in ARCHITECTURE.md still parse via mermaid-cli
- Diff is doc-only: CHANGELOG + ARCHITECTURE + README + Sample.http + 1
  source comment (OrderResourceLoader.cs). No .cs runtime code touched.

Diff: 5 files changed, 31 insertions(+), 17 deletions(-)
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.

2 participants