Repository navigation
ci(security): add CodeQL, OpenSSF Scorecard, a security policy and README badges - #29
Merged
Merged
Conversation
…ADME badges CodeQL runs in manual build mode: autobuild picks the wrong entry point in a solution whose generator targets netstandard2.0 alongside the net10.0 libraries. Scorecard publishes its results so the README badge can read them. SECURITY.md points at private vulnerability reporting and says what a finding in this repository usually looks like, since these packages carry no boundary of their own -- the interesting reports are about generated parsing, a bypassable rule, or an integration that lets a value cross without its rules. The codecov badge stays dark until the coverage upload lands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
CONTRIBUTING.md stays short and defers the long-form layout and debugging guidance to website/docs/contributing.md rather than becoming a second copy of it. What it does carry is the thing a first contributor cannot guess: a change to the consumer-facing surface is rarely a one-file change, because the README, the site and skills/value-objects/ are all held to it by tests. Issue templates are YAML forms rather than markdown: a generator bug is diagnosable from the declaration, the call path that reached it and the emitted source, and a form is what actually gets those three filled in. The discussion template is scaffolded ready for Discussions being enabled. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
… benchmark run Auto-merge covers minor and patch bumps only; a major bump gets a comment saying it was deliberately left for a human, rather than sitting silently in the PR list. Both depend on repository settings this file cannot set -- "Allow auto-merge" and CI as a required check -- which is the difference between the job succeeding and anything actually merging. Benchmarks stay on workflow_dispatch. A shared runner is contended enough that absolute timings are not comparable between runs, so a gate on every push would report noise; the filter is a choice list of the four suites that exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
ARCHITECTURE.md is the "where do I start reading" map and deliberately does not re-explain the reasoning -- the site already does that well. It does carry the typed-path/boxed-path split, because that is where defects hide and it is not obvious from the layout. The ADRs record what the site does not: what was rejected, and what would have to change to revisit it. 0002 is retroactive and covers the representation choice; 0003 records the release model, and is written before the commit that implements it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
dotnet format --verify-no-changes did not pass on this tree. Two separate causes, only one of which was drift: LiteralFactory's escape switch kept its statements on the case labels, which reads well as a table but contradicts csharp_preserve_single_line_statements = false in this repository's own .editorconfig. Reformatted to match the declared style. Flipping that setting to true instead would be the other honest fix. ASP0020 on the sample's minimal API endpoint is a false positive: dotnet format builds a workspace without running source generators, so it cannot see the IParsable<Iban> the generator emits, and reports the endpoint as unbindable. The real build sees it and is clean. CI therefore runs whitespace and style and deliberately skips analyzers, which EnforceCodeStyleInBuild already covers where the generator actually runs. Coverage now comes from all three suites. The unit suite alone exercises the typed path, which is precisely how a descriptor defect stayed invisible once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
…merge Merging to main now publishes a preview and nothing else; a stable release is a workflow_dispatch on release.yml. The version and CHANGELOG.md come from the Conventional Commits this repository already enforces, so they cannot drift from the history, while the step that cannot be undone -- pushing to nuget.org, which allows delisting but never unpublishing -- still waits for a person. MinVer is kept rather than replaced. It already produces preview versions with no decision from anyone, and MINVERVERSIONOVERRIDE is its documented hook for an external tool that has already chosen the version, so semantic-release hands it the stable number and MinVer steps aside. Both read the same v* tags. Verified by packing: all twelve packages stamp the overridden version. The tag trigger and the publish job leave ci.yml, or the tag semantic-release creates would publish the release a second time. The preview job refuses outright to push a non-preview version rather than relying on --skip-duplicate, since publishing a stable nobody cut is the failure this split exists to avoid. Package validation now has a real baseline, which EnablePackageValidation has been missing: semantic-release knows the last released version. The baseline is skipped where a break is intended -- a major, or a minor while still pre-1.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
DocFX extracts the public surface of every package except the generator into markdown under website/docs/api/, which sidebars.ts picks up as an autogenerated category. The output is not committed -- deploy-docs.yml regenerates it, and `npm run docs:api` does the same locally. Three things this needed beyond running the tool, each found by building the site rather than assuming: - markdown.format is now 'detect', so .md is CommonMark. The generated pages are full of bare generic signatures like ValueObjectContract<TValueObject, TValue> which MDX parses as JSX and rejects outright. No hand-written page uses MDX. - docfx-postprocess.py rewrites DocFX's raw <a id> heading anchors into Docusaurus heading ids, preserving the id so cross-references still resolve. Docusaurus otherwise nests its own anchor inside DocFX's, which is invalid HTML and produced 323 minifier diagnostics. - DocumentationSnippetTests now excludes docs/api/. It compiles every published csharp block through the real generator, and generated member signatures are not declarations anyone wrote. CLAUDE.md's per-suite test commands were also wrong: given a bare directory dotnet test prints a hint and exits 0 without running anything, which reads exactly like a pass. They now pass --project. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
A dry run against main showed semantic-release computing 1.0.0, not 0.1.0: it ignores prerelease tags when the branch is not a prerelease channel, so v0.1.0-preview.1 and .2 are invisible to it and it reads the repository as never released. Three dry runs are tabulated in ADR-0003; a v0.0.0 tag at the initial commit yields 0.1.0, continuing the preview line instead of skipping the whole 0.x range. The tag could not be pushed from this session -- git-receive-pack returns 403 for refs/tags while branch pushes succeed -- so it is documented as a command to run rather than silently left undone. docs/maintaining.md collects the rest of the settings that live outside this repository and that let a workflow succeed while doing nothing: auto-merge, required checks, Pages source, Discussions, CODECOV_TOKEN, and the NuGet trusted publisher, which has to name both ci.yml and release.yml now that previews and stable releases are published by different workflows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
The script skips a bare '<a id="x"></a>' with no heading text on purpose --
rewriting it would emit '## {#id}', an empty heading. The verification that
follows then counted that same heading as unconverted and returned 1, so the
one case the rewrite deliberately declines to touch was also the one case that
failed the docs build.
Not reachable with DocFX's current output, which always emits a title, so this
never fired here; found by running the script against a fixture while extracting
it as a reusable template. Verified against the real output: 323 anchors
rewritten, exit 0, and idempotent on a second run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
The workflow failed on every run with "CodeQL analyses from advanced configurations cannot be processed when the default setup is enabled". The analysis itself was fine -- the build succeeded and every query ran -- but GitHub refuses the SARIF upload, so the job could never go green. Default setup was already enabled on this repository and already passing, which an audit that reads the file tree cannot see: it is a repository setting, not a file. Adding codeql.yml duplicated coverage that existed rather than adding any. Deleting the workflow rather than disabling default setup: the advanced configuration's only advantage here was a manual build step for the mixed netstandard2.0/net10.0 solution, and default setup builds it without help. The README badge pointed at the deleted workflow, so it goes too; default setup has no workflow to badge. docs/maintaining.md records the decision and what would justify revisiting it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CodeQL runs in manual build mode: autobuild picks the wrong entry point in a
solution whose generator targets netstandard2.0 alongside the net10.0
libraries. Scorecard publishes its results so the README badge can read them.
SECURITY.md points at private vulnerability reporting and says what a finding
in this repository usually looks like, since these packages carry no boundary
of their own -- the interesting reports are about generated parsing, a
bypassable rule, or an integration that lets a value cross without its rules.
The codecov badge stays dark until the coverage upload lands.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01CmFH2YU1sNDRtgWStye15J