diff --git a/.github/workflows/validate-skill-templates.yml b/.github/workflows/validate-skill-templates.yml index f214b4f..b6a4931 100644 --- a/.github/workflows/validate-skill-templates.yml +++ b/.github/workflows/validate-skill-templates.yml @@ -11,6 +11,17 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Install DocFX CLI + shell: pwsh + run: | + if (Get-Command docfx -ErrorAction SilentlyContinue) { + dotnet tool update --global docfx + } else { + dotnet tool install --global docfx + } + "$HOME/.dotnet/tools" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + docfx --version + - name: Run validator shell: pwsh run: pwsh -NoProfile -File ./scripts/validate-skill-templates.ps1 diff --git a/AGENTS.md b/AGENTS.md index 3bb301d..3c8f020 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -85,7 +85,9 @@ If you edit the `~/.agents/skills//` copy first, mirror it back to the rep When renaming a skill, update **all four** locations — the repo folder, the local Claude install folder, the local global agent install folder, and the local Gemini Antigravity install folder. The folder name and the `name:` field in the SKILL.md frontmatter must match. A mismatch causes the skill to disappear from tooling or show stale instructions. -A sync mismatch means one side runs a stale version, which leads to confusing eval results and wasted iterations. +A sync mismatch means one side runs a stale version, which leads to confusing eval results and wasted iterations. + +After the source copy passes its deterministic tests, SHA-256 identity across the repo and all three local installs is sufficient installation verification. Do not rerun the same deterministic suites from a hash-identical installed copy; that duplicates time, compute, and token use without adding evidence. Run an installed-copy test only when install-path resolution, loader behavior, permissions, or an actual hash mismatch is the subject of the test. After changing any repo-managed skill, sync the touched files across the repo copy, `~/.claude/skills//`, `~/.agents/skills//`, and `~/.gemini/antigravity/skills//` before considering the task done. @@ -141,10 +143,24 @@ When committing changes to this repo, group by technology and logical purpose - Template files (`.csproj`, `.yml`, `.cs`) get their own commit(s) - Documentation updates (`README.md`, `CONTRIBUTING.md`) get their own commit +## Markdown Formatting + +All markdown files in this repository must use natural paragraph flow. Do not artificially break paragraphs at fixed column widths or insert hard line breaks within sentences. Paragraphs should flow as complete thoughts, allowing line wrapping to be determined by the reader's viewport or rendering engine, not by arbitrary character limits. + +**Why:** Natural paragraphs are more readable, easier to edit, and render correctly across all devices and markdown renderers. Artificially clipped paragraphs create maintenance friction and look awkward in source control diffs. + ## README Sync After modifying any skill (`SKILL.md`, `FORMS.md`) or repo-level config (`AGENTS.md`), **always update `README.md` before considering the task done**. This is a mandatory gate — not a nice-to-have. The README's "Available Skills" table, install examples, and "Why" sections must reflect the current state of all skills. A new skill without a README entry is incomplete work. +## Blocking Completion Gates + +When repository guidance, an active skill, or a conversation summary identifies required follow-up work as pending, critical, blocking, or equivalent, treat those items as the active completion checklist for the current task rather than as background context. Do not call `task_complete`, describe the task as complete, or claim verification succeeded until every blocking item has either run successfully or been reported with the exact command, exit code, and remaining blocker. + +Before any completion message, reread the skill instructions and the current conversation summary's pending-task or blocker sections. If either one names a required script, validator, or maintenance step, that step is a hard gate, not optional polish. + +For script-backed workflows, creating or editing files is not enough on its own. If a skill requires deterministic maintenance or verification commands, run them before completion and report their concrete outcome. For `dotnet-docfx-digest`, `scripts/agents.cs` and `scripts/docfx.cs --verify-docfx-build` are blocking completion gates whenever the skill or task summary says they are required. + ## User Input UX When a skill collects parameters from the user, define the form in a dedicated `FORMS.md` file (Level 3 resource) rather than inlining field definitions in `SKILL.md`. This separates form structure from workflow logic and gives agents a parseable format to present fields correctly. diff --git a/README.md b/README.md index 6c96113..a32990b 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,14 @@ One more consistency rule matters for form-driven skills: native input fields ar Repo-level agent guidance also keeps progress updates user-facing: agents should report meaningful progress, evidence, blockers, and next steps without narrating sandbox mechanics, approved command paths, or retry plumbing unless those details affect approval, reproducibility, validation, or the final outcome. +Completion gates are equally strict: if repository guidance, a loaded skill, or the conversation summary marks a script-backed step as pending, critical, or blocking, agents must treat it as an active checklist item and may not claim completion until that command has run or the exact external blocker has been reported. In the DocFX workflow, that means `scripts/agents.cs` and the build-backed `scripts/docfx.cs --build-api-model --validate-samples --verify-docfx-build` verification are completion gates, not optional cleanup after the documentation files look done. The validator now emits a deterministic completion contract: `summary.canClaimCompletion` must be `true`, `summary.remainingWorkItems` must be `0`, and both `summary.remainingGates` and `summary.remainingDiagnosticsByCode` must be empty. A clean fast run reports `verification-required`, not completion. Pre-existing gaps, large diagnostic counts, sample failures, and documentation-caused DocFX build failures remain repair work; they are not permission to stop after a partial digest. (The plain `scripts/docfx.cs` run is fast and build-free for iteration; the build-backed flags are what make the final gate authoritative.) + +Local skill synchronization is verified efficiently: run deterministic tests against the repository source, copy touched files to the three local installs, and compare SHA-256 hashes across all four locations. Hash-identical copies are the same executable content, so agents do not repeat the same suites from an installed path unless install-path or loader behavior is specifically under test. + +Resumed DocFX audits preserve every tracked and untracked documentation edit, regenerate the assessment work queue and example inventory, and process that queue in batches with a fast rerun after each batch. Encoding checks focus on actual damage: valid BOM-less UTF-8 is accepted, `ENCODING_BOM_MISSING` is not emitted, and audits do not create BOM-only or line-ending-only diffs. + +Final DocFX verification is machine-adaptive: `auto` selects a high-capacity profile above 8 available logical processors and 32 GiB available memory, overlaps isolated DocFX verification with API/sample work, and scales MSBuild workers up to half the available processors (capped at 16). Smaller machines stay conservative. Child-process timeout defaults to 30 minutes, and callers must allow at least 35 minutes so the validator can return its own timeout diagnostics. Long-running build, sample, and DocFX children also emit 10-second `stderr` heartbeats with phase, workload, runner count, PID, elapsed time, last-output age, and current output while keeping JSON stdout parseable. + Validation follows the same philosophy: run `scripts/validate-skill-templates.ps1` locally for the fast feedback loop, and let GitHub Actions rerun that same script on pull requests as the safety net. That validator also checks skill frontmatter metadata such as per-skill `evals/evals.json` files, optional eval fixture paths declared through `files`, and the 1024-character YAML description limit; it does not replace the paired benchmark review workflow. ## Install a skill @@ -60,9 +68,10 @@ npx skills add https://github.com/codebeltnet/agentic --skill git-repo-digest npx skills add https://github.com/codebeltnet/agentic --skill trunk-first-repo npx skills add https://github.com/codebeltnet/agentic --skill dotnet-strong-name-signing npx skills add https://github.com/codebeltnet/agentic --skill dotnet-new-app-slnx -npx skills add https://github.com/codebeltnet/agentic --skill dotnet-new-lib-slnx +npx skills add https://github.com/codebeltnet/agentic --skill dotnet-new-lib-slnx npx skills add https://github.com/codebeltnet/agentic --skill git-remote-release npx skills add https://github.com/codebeltnet/agentic --skill dotnet-change-impact +npx skills add https://github.com/codebeltnet/agentic --skill dotnet-docfx-digest # npx skills add https://github.com/codebeltnet/agentic --skill another-skill ``` @@ -88,14 +97,15 @@ npx skills add https://github.com/codebeltnet/agentic --skill dotnet-change-impa | [git-nuget-readme](skills/git-nuget-readme/SKILL.md) | Git-aware NuGet README companion for .NET repos that advertise a package from `src/`. Resolves the real packable project the README should sell, combines git history with actual package metadata, source capabilities, and relevant tests when feasible, preserves honest badge/docs/contributing sections, and writes a forthcoming, adoption-friendly `README.md` with repo-derived branding, clear value, install, framework-support, and quick-start guidance. | | [git-visual-squash-summary](skills/git-visual-squash-summary/SKILL.md) | Non-mutating grouped-summary companion to `git-visual-commits`. Turns the full current feature branch into a curated set of compact lowercase-start summary lines for PR or squash-and-merge contexts by default, comparing against the repository base branch rather than a same-named tracking remote, including commits from all authors unless explicitly narrowed, preserving technical identifiers, merging overlap, dropping low-signal noise, highlighting distinct meaningful efforts, and avoiding changelog-style wording, unsupported claims, yolo prompts, needless commit-range questions, or commit-selection UI for ordinary branch-level squash requests. | | [skill-creator-agnostic](skills/skill-creator-agnostic/SKILL.md) | Runner-agnostic overlay for Anthropic `skill-creator`. Adds repo and environment guardrails for skill authoring and benchmarking: temp-workspace isolation, `iteration-N/eval-name/{config}/run-N/` benchmark layout, valid `grading.json` summaries, generated `benchmark.json`, honest `MEASURED` vs `SIMULATED` labeling, and sync/README discipline for repo-managed skills. | -| [markdown-illustrator](skills/markdown-illustrator/SKILL.md) | Reads a markdown file and answers directly in chat with one document-wide Visual Brief plus one compiled prompt. Infers a compact visual strategy by default, keeps follow-up questions near zero, and only branches when the user explicitly asks for added specificity. | +| [markdown-illustrator](skills/markdown-illustrator/SKILL.md) | Reads a markdown file and answers directly in chat with one document-wide Visual Brief plus one compiled prompt. Infers a compact visual strategy by default, keeps follow-up questions near zero, and only branches when the user explicitly asks for added specificity. | | [git-repo-digest](skills/git-repo-digest/SKILL.md) | Turns any full repository URL into a deterministic digest workspace using the bundled .NET file-based runner `scripts/digest.cs`. Requires explicit `--repo-url`, resolves omitted output paths to `/.bot/digests` and passes that as `--output-root`, maps multiple positional URLs the same way for slash commands, bare pasted URLs, and natural-language requests by treating the first URL as the digest repo and every later URL as repeated `--external-repo-url`, always writes into `{output-root}/{repo-id}/{yyyyMMdd-HHmmssZ}`, accepts repeated curated public consumer repos, derives `{repo-id}`, fixes `result/`, performs shallow git clones, packs local tracked files with the bundled C# packer using `git ls-files`, separates XML evidence into `source.xml`, `tests.xml`, `projects.xml`, editorial `readmes.xml`, and scenario-only `external-usage.xml`, writes package and conceptual overview prompts under `prompts/`, emits public API summaries, engineering signals, evidence indexes, ordered XML chunks, referenced-package evidence maps for aggregate examples, and manifest-backed frontmatter hints, treats previous digest prose as contamination during fresh generation, then guides the agent to fully read the current phase's required evidence before writing package digests and a concept-led `result/Index.md` with YAML frontmatter containing Product-derived overview title metadata, validated documentation URLs resolved from PackageProjectUrl, documentation-host-filtered exact `.nuget//README.md` documentation links including emoji-prefixed Documentation headings and "More documentation..." blocks, DocFX `metadata[].dest` API paths, and source namespace page candidates from `src//**/*.cs`, target frameworks, package/library counts, external links, package-family links, and context glyphs, and validates authored result examples with `--validate-results` as a deterministic API-shape, Codebelt.Extensions.Xunit shape, PascalCase `MethodName_Scenario_ExpectedBehavior` test-method naming, Basic usage quality, and optimized NuGet-backed executable test gate with bounded parallelism. | | [dotnet-new-lib-slnx](skills/dotnet-new-lib-slnx/SKILL.md) | Scaffold a new .NET NuGet library solution following codebeltnet engineering conventions. Dynamic defaults for TFM/repository metadata, latest-stable NuGet package resolution, tuning projects plus a tooling-based benchmark runner, TFM-aware test environments, strong-name signing, NuGet packaging, DocFX documentation, CI/CD pipeline, and code quality tooling. | | [dotnet-new-app-slnx](skills/dotnet-new-app-slnx/SKILL.md) | Scaffold a new .NET standalone application solution following codebeltnet engineering conventions. Supports Console, Web, and Worker host families with Startup or Minimal hosting patterns; Web expands into Empty Web, Web API, MVC, or Web App / Razor, plus functional tests and a simplified CI pipeline. | | [trunk-first-repo](skills/trunk-first-repo/SKILL.md) | Initialize a git repository following [scaled trunk-based development](https://trunkbaseddevelopment.com/#scaled-trunk-based-development). Seeds an empty `main` branch and creates a versioned feature branch (`v0.1.0/init`), enforcing a PR-first workflow where content only reaches main through peer-reviewed pull requests. | -| [dotnet-strong-name-signing](skills/dotnet-strong-name-signing/SKILL.md) | Generate a strong name key (`.snk`) file for signing .NET assemblies using pure .NET cryptography — no Visual Studio Developer PowerShell or `sn.exe` required. Works in any terminal. Defaults to 1024-bit RSA (matching `sn.exe`), with 2048 and 4096 available as options. | +| [dotnet-strong-name-signing](skills/dotnet-strong-name-signing/SKILL.md) | Generate a strong name key (`.snk`) file for signing .NET assemblies using pure .NET cryptography — no Visual Studio Developer PowerShell or `sn.exe` required. Works in any terminal. Defaults to 1024-bit RSA (matching `sn.exe`), with 2048 and 4096 available as options. | | [git-remote-release](skills/git-remote-release/SKILL.md) | Generate GitHub release notes by summarizing all commits and pull requests between two Git tags or branches in a remote GitHub repository. Accepts a compare URL or separate owner/repo, previous ref, and current ref values; falls back to comparing the current branch against the upstream default branch when no input is provided. Produces a human-friendly `## What's Changed` summary with optional GitHub alert blocks, a `Sources:` section preserving PR and commit references, and a full changelog compare link. | | [dotnet-change-impact](skills/dotnet-change-impact/SKILL.md) | Classify .NET library or NuGet package changes and recommend the correct release bump — `Major`, `Minor`, or `Patch` — for both Semantic Versioning (`MAJOR.MINOR.PATCH`) and .NET assembly/file versioning (`Major.Minor.Build.Revision`), grounded in Microsoft's official .NET compatibility rules. Uses the current Git branch by default when no explicit change details or compare range are provided, resolving it against the upstream/default base branch with local read-only git state. Always returns structured behavioral/binary/source/design-time/backwards compatibility reasoning with the recommendation, even when the bump is clear. | +| [dotnet-docfx-digest](skills/dotnet-docfx-digest/SKILL.md) | Create and maintain developer-friendly DocFX documentation for .NET public APIs, including repo-wide no-input audits that inspect source, tests, DocFX config, DocFX `build.content` and `build.overwrite` Markdown inputs, namespace pages, and availability includes before asking for clarification. Enforces the workflow with two bundled .NET 10 file-based scripts resolved from the loaded skill directory, falling back to the repo-managed source path only when present: `scripts/agents.cs` writes an idempotent, marker-bounded DocFX maintenance block into the repository `AGENTS.md`; `scripts/docfx.cs` is **fast and build-free by default** — it validates Markdown, prose, DocFX overwrite layout, namespace overview pages, `Extension Members` tables, purpose-first summaries, and required per-type/extension examples without invoking `dotnet`, `msbuild`, `docfx`, or `gh`, discovering the public API from existing DocFX YAML metadata or a conservative source scan and ending every run with a `[processes] dotnet=0 msbuild=0 docfx=0 gh=0` summary plus per-phase timings. Compilation and network access are strictly opt-in: `--validate-samples` compiles each C# sample in an isolated project while batching all sample projects into one temporary `.slnx` graph build with bounded MSBuild parallelism and scoped references, `--build-api-model` (alias `--strict-api-discovery`) does reflection-backed discovery from compiled metadata via `MetadataLoadContext` through a single scoped `.slnx` graph build, `--verify-docfx-build` runs the DocFX CLI in a temp copy, and `--search-examples` runs `gh` code search. Final verification adapts to available processors and memory, overlaps isolated DocFX work on high-capacity machines, uses a 30-minute child timeout, and emits 10-second `stderr` heartbeats with active phase, workload, runner count, PID, elapsed time, last-output age, and current child output while preserving machine-readable JSON on `stdout`. Honors a single DocFX metadata `TargetFramework` when `--framework` is omitted, collapses C# extension-block compiler containers such as `$...` back to the authored outer static class, validates namespace fly-ins that explain the problem solved/when to use/where to start, the Codebelt namespace-and-type-folder overwrite layout (`.docfx/api/namespaces/**/*.md` and `.docfx/api/types/**/*.md` under `build.overwrite` only), keeps `--changed-only` validation scoped to affected docs and APIs while still including brand-new untracked overwrite Markdown, uses the root Codebelt `.snk` when present and falls back to `-p:SkipSignAssembly=true` for keyless strong-name build verification, drains child stdout and stderr concurrently to avoid verbose-build deadlocks, writes deterministic `--assessment-queue` Markdown work queues with a type-first required-example inventory, overwrite-layout fixes, package-ID evidence, and scenario choices for noisy audits, preserves existing BOM and line-ending state while flagging actual mojibake instead of creating encoding-only diffs, and leaves generated DocFX YAML metadata untouched unless `--clean-generated-metadata` is explicitly requested (which runs only after the API model is built, never deleting metadata the run relied on). Documents public API only, uses bundled reference docs for overwrite rules, workflow details, and script behavior, keeps authored API overwrite Markdown under `.docfx/api/namespaces/` and `.docfx/api/types/`, moves legacy authored `.docfx/api/*.md` overwrite files there instead of widening the glob to `api/**/*.md`, teaches namespace and API prose to orient newcomers around purpose instead of inventorying contents, makes examples start from package-ID usage evidence before type/member-only searches, allows multi-type Microsoft Learn-style scenario samples when they better explain the consumer workflow, keeps extension-method examples on readable declaring-class type pages under `.docfx/api/types/` instead of synthetic method-UID filenames or namespace pages that mix extra `uid:` / `example:` blocks into the overview, flags weak skip-compile reasons, runs a completion repair loop that treats every diagnostic as active work regardless of age or volume, treats newly surfaced follow-on diagnostics as the next repair queue instead of a stop point, reruns packet discovery with `--build-api-model --project-manifest` when fast source-scan packets are unnamed or zero-project, falls back to sequential namespace or assessment work queue order when packet discovery is still unusable, treats `EXAMPLE_MISSING`-only queues as core work rather than checkpoints, drives large example queues through a concrete fast-path micro-loop (next example or next 3-5 examples → rerun → continue), reserves the final `--build-api-model --validate-samples --verify-docfx-build` verification for the real end of the queue, never turns partial progress into a continue/focus/verify menu or completion report while repairable work remains, exposes `summary.canClaimCompletion`, `summary.remainingWorkItems`, and `summary.remainingDiagnosticsByCode` as a machine-readable final gate, reruns the fast `docfx.cs --json` after edits until the queue is empty, then runs the build-backed verification before completion, preserves manual edits and authored Markdown during cleanup, skips recursive generated-output cleanup when a target directory contains documentation or source files, and returns deterministic exit codes plus `--json` reports (including process counts and phase timings) so CI can gate on real failures instead of AI claims. | ### Copyable Install Commands @@ -137,16 +147,16 @@ npx skills add https://github.com/codebeltnet/agentic --skill git-visual-squash- npx skills add https://github.com/codebeltnet/agentic --skill skill-creator-agnostic ``` -`markdown-illustrator` - -```bash -npx skills add https://github.com/codebeltnet/agentic --skill markdown-illustrator -``` - -`git-repo-digest` - -```bash -npx skills add https://github.com/codebeltnet/agentic --skill git-repo-digest +`markdown-illustrator` + +```bash +npx skills add https://github.com/codebeltnet/agentic --skill markdown-illustrator +``` + +`git-repo-digest` + +```bash +npx skills add https://github.com/codebeltnet/agentic --skill git-repo-digest ``` `dotnet-new-lib-slnx` @@ -169,10 +179,10 @@ npx skills add https://github.com/codebeltnet/agentic --skill trunk-first-repo `dotnet-strong-name-signing` -```bash -npx skills add https://github.com/codebeltnet/agentic --skill dotnet-strong-name-signing -``` - +```bash +npx skills add https://github.com/codebeltnet/agentic --skill dotnet-strong-name-signing +``` + `git-remote-release` ```bash @@ -185,6 +195,12 @@ npx skills add https://github.com/codebeltnet/agentic --skill git-remote-release npx skills add https://github.com/codebeltnet/agentic --skill dotnet-change-impact ``` +`dotnet-docfx-digest` + +```bash +npx skills add https://github.com/codebeltnet/agentic --skill dotnet-docfx-digest +``` + ### Why git-visual-commits? Commit messages are the most-read documentation in any codebase — yet they're usually an afterthought. "fix stuff", "wip", "address PR feedback" tells you nothing six months later. Writing good commits takes discipline, and when you're in flow, it's the first thing that slips. @@ -484,24 +500,24 @@ Most repositories start with `git init` followed by committing everything direct - **Review from day one** — no "we'll add branch protection later" that never happens - **Clean, meaningful history** — main tells the story of reviewed, approved changes - **Version-aware branches** — `v0.0.1/spike-auth` vs `v1.0.0/release-prep` signals project maturity at a glance -- **Zero-friction setup** — one skill invocation, not a 10-step checklist - -### Why git-remote-release? - -Writing release notes is tedious. Raw commit logs are too noisy, PR titles often lack context, and the best release notes explain what changed and why it matters — not just what was merged. That gap between "here are the commits" and "here is what this release means for you" is where **git-remote-release** fits. - +- **Zero-friction setup** — one skill invocation, not a 10-step checklist + +### Why git-remote-release? + +Writing release notes is tedious. Raw commit logs are too noisy, PR titles often lack context, and the best release notes explain what changed and why it matters — not just what was merged. That gap between "here are the commits" and "here is what this release means for you" is where **git-remote-release** fits. + **git-remote-release** reads all commits and pull requests between two tags or branches in a remote GitHub repository and produces a polished, paste-ready release note. - -- **Remote-first workflow** that works entirely through GitHub's API, with no local clone required, -- **Compare URL awareness** where a pasted GitHub compare URL is used to extract the owner, repository, and both tags, + +- **Remote-first workflow** that works entirely through GitHub's API, with no local clone required, +- **Compare URL awareness** where a pasted GitHub compare URL is used to extract the owner, repository, and both tags, - **Pull request-preferred analysis** that uses rich PR metadata when available and gracefully falls back to raw commits, - **Default-branch-aware comparisons** that resolve the upstream base and collect only commits on the current branch, - **Effect-oriented summaries** that explain what users and maintainers can expect from the release, not just what code was merged, -- **Thematic grouping** where related changes are discussed together instead of listed chronologically, -- **GitHub alert blocks** that use `NOTE`, `TIP`, `IMPORTANT`, `WARNING`, and `CAUTION` alerts sparingly and only when the release data supports the attention level, -- **Source preservation** where every release note includes a `Sources:` section with the original PR and commit references, -- **Strict format** that always starts with `## What's Changed` and always ends with the full changelog compare link, -- **No invented claims** so every statement in the summary is backed by the commits and pull requests collected, +- **Thematic grouping** where related changes are discussed together instead of listed chronologically, +- **GitHub alert blocks** that use `NOTE`, `TIP`, `IMPORTANT`, `WARNING`, and `CAUTION` alerts sparingly and only when the release data supports the attention level, +- **Source preservation** where every release note includes a `Sources:` section with the original PR and commit references, +- **Strict format** that always starts with `## What's Changed` and always ends with the full changelog compare link, +- **No invented claims** so every statement in the summary is backed by the commits and pull requests collected, - **Read-only operation** that never mutates repository state. ### Why dotnet-change-impact? @@ -519,6 +535,35 @@ Picking the wrong version number is one of the easiest ways to break downstream - **Precedence-aware** — mixed releases take the highest required bump, - **Special-case savvy** — dependency updates, bug fixes, new overloads, interface and enum changes, analyzers/source generators, TFM/platform support, and performance changes each get the right default and the right escalation triggers. +### Why dotnet-docfx-digest? + +API documentation rots the moment code changes. A new public type ships without a namespace page, an extension method never makes it into the `Extension Members` table, a copy/paste example silently stops compiling, and "availability" drifts away from the real target frameworks. The usual fix — telling an agent to "remember to update the docs" — relies on AI memory, which is exactly the thing that fails on the next change. + +**dotnet-docfx-digest** moves the rules from prose into deterministic .NET 10 tooling, so guidance persists and verification is real. + +- **No-input audits by default** — `Use dotnet-docfx-digest` means inspect the repository, DocFX config, public API, tests, samples, overwrite files, namespace pages, and availability includes, then repair missing complementary documentation that can be derived from evidence before asking any clarifying questions, +- **Fast by default, builds only on demand** — a plain `scripts/docfx.cs` run validates Markdown, prose, DocFX overwrite layout, namespace pages, extension tables, and required examples **without invoking `dotnet`, `msbuild`, `docfx`, or `gh`**, discovering the public API from existing DocFX YAML metadata or a conservative source scan and proving it with a `[processes] dotnet=0 msbuild=0 docfx=0 gh=0` summary plus per-phase timings on every run. Five clearly separated paths layer on cost only when asked: fast Markdown validation (default), `--validate-samples` for C# sample compilation, `--build-api-model` for reflection-backed API discovery, `--verify-docfx-build` for the DocFX build, and `--search-examples` for GitHub usage search, +- **Persistent guidance by script, not memory** — `scripts/agents.cs` is resolved from the loaded skill directory, with a repo-managed source fallback when present, then writes an idempotent, marker-bounded DocFX maintenance block into the target repository `AGENTS.md`; running it twice never duplicates the block, and `--check` gates it in CI, +- **DocFX overwrite grounding** — the skill includes a concise `references/docfx-overwrite-files.md` summary of the official overwrite-file and `docfx.json` rules agents need when creating namespace fly-ins, summaries, examples, remarks, and extension-member documentation, +- **Verification without a build, precision on demand** — by default `scripts/docfx.cs` discovers public API, namespaces, and extension methods without compiling: it reads existing DocFX ManagedReference YAML under `metadata.dest` when present, otherwise runs a conservative source scan over the projects referenced by `docfx.json`, and warns (`API_MODEL_SOURCE_SCANNER_LIMITED`) that the precise path is opt-in. Adding `--build-api-model` (alias `--strict-api-discovery`) builds only the documented project graph through a single scoped `.slnx` graph build and discovers from compiled metadata via `MetadataLoadContext` with project-asset, deps-file, and framework-pack dependency resolution, +- **Codebelt signing-key aware** — strong-name signed Codebelt repositories use the root `.snk` file when it is present, while keyless checkouts and temp workspaces verify with `-p:SkipSignAssembly=true` so missing local author keys do not look like documentation drift, +- **Decision-useful namespace checks** — uid front matter, availability, and `Extension Members` tables are validated against the actual public surface, while semantic gates reject inventory-only prose, weak inventory leads left intact beneath an appended start-here sentence, and mechanical prose templates shared across pages, requiring concrete when-to-use and start-here guidance with diagnostics such as `NAMESPACE_PROSE_INVENTORY_ONLY`, `NAMESPACE_APPEND_ONLY_REPAIR`, `NAMESPACE_PROSE_TEMPLATE_REPETITION`, `NAMESPACE_USAGE_GUIDANCE_MISSING`, and `NAMESPACE_START_HERE_MISSING`, +- **Deterministic assessment work queues** — `scripts/docfx.cs --assessment-queue ` converts noisy validation output into a grouped Markdown work queue with repository guidance, namespace/table repairs, a type-first required-example inventory, sample failures, cleanup gates, no-broad-restore rules, related-namespace coverage, and diff-review completion checks so agents do not update one namespace and forget the rest, +- **Managed-reference-safe overwrite layout** — public non-abstraction types and public extension methods must have examples in DocFX overwrite content included by `build.overwrite`; the validator discovers Markdown from configured DocFX inputs instead of scanning the whole repository when `docfx.json` is at the root, concrete-type examples are tracked through an explicit inventory and created in readable authored files under `.docfx/api/types/`, legacy authored `.docfx/api/*.md` overwrite files move into `api/namespaces/` or `api/types/` instead of widening the glob to `api/**/*.md`, both overwrite trees stay excluded from `build.content`, C# extension-block compiler containers such as `$...` are collapsed back to the authored outer static class, extension-method examples default to readable declaring-class type pages under `.docfx/api/types/` instead of URL-encoded method-UID filenames or namespace pages that mix overview and member UIDs, namespace pages fail validation when they embed secondary `uid:` / `example:` sections, and agents must rerun the completion repair loop until diagnostics and overwrite-layout failures are fixed or exact blockers are reported, +- **Concept-led namespace quality** — moving concrete examples to type pages must not hollow out namespace pages; namespace pages still need newcomer-oriented fly-ins that explain the problem solved, when to use the namespace, where to start, type-family context, extension-method group explanations, availability, and pointers to representative type pages, and nearby type/member summaries should stay purpose-first too, +- **Examples that teach a real workflow** — examples start from package IDs and package-level evidence before falling back to type/member-only searches, prefer README, package docs, tooling, tuning, functional-test, and external GitHub usage when available, and may include multiple related public types when that is what makes the consumer scenario understandable, +- **Semantic example quality gates** — compilation-valid filler no longer passes: the validator rejects duplicate UID mappings, `Type.GetType`/assembly metadata scaffolds, generic `DocumentedTypeExample`/`Describe()` templates, type examples that never use the target in code, extension examples that mention a method only in prose instead of invoking it, `default!`/`null!` holder properties (`EXAMPLE_DEFAULT_PLACEHOLDER`), classes that only construct or return the target with no observable result (`EXAMPLE_NO_OBSERVABLE_OUTCOME`), mass-forwarding shells of one-line pass-throughs (`EXAMPLE_FORWARDING_SCAFFOLD`), and one normalized code skeleton reused across three or more unrelated targets (`EXAMPLE_TEMPLATE_REPETITION`), +- **Correct source discovery** — the no-build source scanner correctly handles block namespaces whose opening brace is on the next line, so public types are no longer silently under-reported; when a declaration cannot be paired with its brace it warns (`API_MODEL_SOURCE_SCANNER_INCOMPLETE`) and points to a build-backed audit, +- **Project-scoped packets and voluntary representative dry runs** — documentation is processed in bounded project packets grouped by DocFX `metadata[].dest`, with ownership of namespaces, targets, overwrite files, and git-dirty paths. A normal run always preserves the user's requested scope and continues packet-by-packet until the global completion contract is clean. Only an explicitly requested `--dry-run --build-api-model --project-manifest ` selects one **clean** project per destination group and writes both the initial baseline and a sibling changed-page review template; after evidence-based authoring and page-by-page review, `--resume-project-manifest --review-report --build-api-model --validate-samples --verify-docfx-build` verifies the same packets without mistaking new files for pre-existing work. Missing evidence, purpose/outcome, observable-result, or sibling-pattern review entries block dry-run completion. `--write-overwrite` preserves BOM/line endings and refuses dirty or duplicate-UID writes, +- **Build-backed scope and output-driven quality** — authoring scope must be reflection-precise: a `source-scan` model is `provisional` and raises `BUILD_BACKED_SCOPE_REQUIRED` until `--build-api-model` (or DocFX YAML) confirms it. Deterministic diagnostics evaluate the authored prose, examples, ownership, compilation, and DocFX build; target volume and diagnostic count never alter scope or select dry-run, +- **Symbol-aware ownership and narrow family exemptions** — duplicate type names across assemblies (`SYMBOL_COLLISION_UNRESOLVED`), unresolved type forwarding (`TYPE_FORWARDING_UNRESOLVED`), and cross-assembly extension containers (`EXTENSION_OWNER_AMBIGUOUS`) are flagged with owning assembly/project; a heavily generic/inherited/overloaded/arity series can replace redundant per-type examples with one validated anchor example plus deep namespace guidance, declared explicitly in `.docfx/family-exemptions.json`, +- **Examples that actually compile** — under the opt-in `--validate-samples` path, every `csharp`/`cs` documentation fence is compiled in its own isolated project; all sample projects are batched into one temporary `.slnx` graph build so shared dependencies restore and build once, `--sample-parallelism` bounds MSBuild concurrency, each sample references only the documented project(s) that own its namespace rather than every library project, and failures report the file, fence index, line, exit code, and compiler diagnostics, +- **Honest opt-outs only** — a sample can skip compilation solely with `// dotnet-docfx-digest:skip-compile - `; a missing reason is flagged, +- **Public API only** — internal and private members, and namespaces with no public API, are deliberately left undocumented, +- **Preserves manual edits** — additive by default, correcting stale or contradictory statements rather than overwriting hand-written documentation, +- **Cleanup keeps authored docs and is opt-in** — generated-metadata cleanup runs only when `--clean-generated-metadata` is explicitly passed, and even then only after the API model is built so it never deletes YAML the run relied on; `.docfx/**/*.md` overwrite files, namespace pages, includes, and config are documentation outputs, not disposable build artifacts, and cleanup is limited to known metadata files and safe site-output directories that contain no authored documentation or source files, +- **CI-friendly** — deterministic exit codes plus `--json` reports let pipelines fail on actual documentation drift instead of trusting an agent's claim that it checked. + ## Repository structure ``` diff --git a/scripts/validate-skill-templates.ps1 b/scripts/validate-skill-templates.ps1 index 9282c84..6fcf1ed 100644 --- a/scripts/validate-skill-templates.ps1 +++ b/scripts/validate-skill-templates.ps1 @@ -1107,6 +1107,22 @@ Add-ValidationResult -Results $results -Name 'Rendered library templates leave n } } +Add-ValidationResult -Results $results -Name 'DocFX digest rejects metadata scaffolds and accepts scenario-led documentation' -Action { + $qualityTest = Join-Path $repoRoot 'skills/dotnet-docfx-digest/scripts/test-quality.ps1' + & $qualityTest + if ($LASTEXITCODE -ne 0) { + throw "DocFX semantic quality regression failed with exit code $LASTEXITCODE." + } +} + +Add-ValidationResult -Results $results -Name 'DocFX digest project-scoped packets, dry run, families, and overwrite writer behave deterministically' -Action { + $scopeTest = Join-Path $repoRoot 'skills/dotnet-docfx-digest/scripts/test-project-scoped.ps1' + & $scopeTest + if ($LASTEXITCODE -ne 0) { + throw "DocFX project-scoped regression failed with exit code $LASTEXITCODE." + } +} + $passed = @($results | Where-Object { $_.Status -eq 'PASS' }).Count $failed = @($results | Where-Object { $_.Status -eq 'FAIL' }).Count $label = if ([string]::IsNullOrWhiteSpace($Ref)) { 'WORKTREE' } else { $Ref } diff --git a/skills/dotnet-docfx-digest/SKILL.md b/skills/dotnet-docfx-digest/SKILL.md new file mode 100644 index 0000000..d9fdf6c --- /dev/null +++ b/skills/dotnet-docfx-digest/SKILL.md @@ -0,0 +1,333 @@ +--- +name: dotnet-docfx-digest +description: > + Create and maintain developer-friendly DocFX documentation digests for .NET public APIs, including repo-wide no-input audits, concept-led namespace overview pages, purpose-first type/member summaries, extension-member documentation, overwrite files, examples, availability notes, AGENTS.md maintenance, and verification. Use when the user asks to document a .NET API, create or update DocFX documentation, write namespace overview pages, improve API summaries, add extension-method tables, update XML documentation comments, add API examples, maintain DocFX overwrite files, or verify documentation builds. Treat requests like "use dotnet-docfx-digest", "update the DocFX docs", "complete missing documentation", "create namespace pages", "improve these API summaries", "add examples for this type", "update the extension members table", or "verify the documentation builds" as automatic triggers. Also use whenever public .NET API surface changes and documentation needs to stay aligned with source code. +--- + +# .NET DocFX Digest Steward + +## Description + +Create and maintain developer-friendly DocFX documentation digests for .NET public APIs. Keep namespace pages, generated API pages, examples, availability notes, and verification aligned with the actual source code and tests. + +## Critical + +- This skill is autonomous by default. If the user invokes it without naming a namespace, type, member, or changed API, treat the request as a repo-wide DocFX audit and repair task instead of asking what to document first. +- Resolve bundled scripts from the loaded `dotnet-docfx-digest` skill directory first. If that install path is unavailable and the target repository contains the repo-managed source copy, fall back to `skills/dotnet-docfx-digest/scripts/*.cs`. Do not claim the scripts are unavailable until both locations have been checked. +- `docfx.cs` is fast by default: a plain run validates Markdown, prose, DocFX overwrite layout, namespace pages, extension tables, and required examples **without building, restoring, or running DocFX/gh**. Use it freely during iteration — it discovers the public API from existing DocFX YAML metadata or a conservative source scan, and ends with a `[processes] dotnet=0 msbuild=0 docfx=0 gh=0` summary. Compilation and network access are opt-in. +- Iterate quickly with the fast path, reading diagnostics as the next work queue: + +```bash +dotnet run --file /scripts/docfx.cs -- --repo-root --json +``` + +- Before claiming completion, run `agents.cs`, then a thorough build-backed verification that compiles samples, uses reflection-backed API discovery, and verifies the DocFX build: + +```bash +dotnet run --file /scripts/agents.cs -- --repo-root +dotnet run --file /scripts/docfx.cs -- --repo-root --build-api-model --validate-samples --verify-docfx-build +``` + +- `--build-api-model` makes API discovery reflection-precise (the fast source-scan path is conservative and may under-report), `--validate-samples` compiles every C# documentation sample through isolated projects in one temporary `.slnx` graph build with bounded MSBuild parallelism, and `--verify-docfx-build` confirms the DocFX build succeeds. Treat `API_MODEL_SOURCE_SCANNER_LIMITED` in a fast run as a reminder to run the build-backed verification before completion, not as a failure. +- For noisy audits, write and read a deterministic assessment work queue with `--assessment-queue`. This works on the fast path; add `--search-examples` to embed real GitHub usage: + +```bash +dotnet run --file docfx.cs -- --repo-root --json --assessment-queue /tmp/docfx-assessment-queue.md --search-examples +``` + +The assessment work queue includes a "GitHub Example Sources" section with pre-computed `gh search code` commands and GitHub search URLs for each documented package. Read that section before writing any new example — do not write examples from memory or invention when real source evidence is available. If `--search-examples` is provided and `gh` is authenticated, actual search results are embedded; otherwise, the search commands are ready to run. + +- `ENCODING_CORRUPTION` in the JSON output means a documentation file has double-encoded UTF-8 (mojibake). Restore with `git checkout HEAD -- ` if the committed version was correct, or use the edit tool or byte-level operations to rewrite the file safely. Never pipe content through `Get-Content` + `Set-Content` or `[System.Text.Encoding]::UTF8.GetBytes()` on documentation files that contain multi-byte characters or emoji. +- `EXTENSION_TABLE_ENCODING` means the ⬇️ emoji (U+2B07) is missing or corrupted in an Extension Members table data row. Use the literal `⬇️` character, not HTML entities or text substitutes. +- If either script cannot run, report the exact command, exit code, and failure output. Do not claim repository guidance or documentation was verified unless the scripts actually ran successfully. +- Treat validator errors as the repo-wide repair queue, not as evidence that the repository is "blocked." A diagnostic being old, pre-existing, numerous, or outside the first files edited does not remove it from scope. A run with 1,228 `EXAMPLE_MISSING` findings means 1,228 documentation items remain; repairing one type page is a partial result, not a digest. +- A rerun that clears a coarse diagnostic and reveals a more specific one is progress, not a blocker. If `EXTENSION_SECTION_MISSING` drops and `EXTENSION_METHOD_MISSING` appears, or namespace/table repairs expose more `EXAMPLE_MISSING` targets, treat the newly surfaced codes as the next deterministic queue and keep repairing. +- Do not turn partial progress into a decision menu. While repairable diagnostics remain, never stop to ask whether to continue, focus a subset, or "just run verification." Only ask the user to choose when inspection exposes a real correctness-affecting decision or a genuine external blocker stops further execution. +- `EXAMPLE_MISSING` is the core authoring queue, not optional backlog. Even when it is the only remaining diagnostic family and the count is in the hundreds or thousands, the digest is still incomplete. Do not stop for a checkpoint, completion report, approval pause, dry-run suggestion, or next-step menu; keep creating compiling examples until `EXAMPLE_MISSING` reaches zero. +- Treat the next unaddressed `EXAMPLE_MISSING` diagnostic as the only thing that exists. Work it, rerun, then work the next. Counts, percentages, and "remaining work" numbers are progress indicators, not decision points. +- Passing compilation is necessary but not sufficient. `EXAMPLE_PLACEHOLDER`, `EXAMPLE_REFLECTION_ONLY`, `EXAMPLE_TARGET_NOT_USED`, `EXTENSION_EXAMPLE_NOT_INVOKED`, `EXAMPLE_DEFAULT_PLACEHOLDER`, `EXAMPLE_NO_OBSERVABLE_OUTCOME`, `EXAMPLE_FORWARDING_SCAFFOLD`, `EXAMPLE_TEMPLATE_REPETITION`, and `EXAMPLE_UID_DUPLICATE` are blocking quality failures. Never satisfy the inventory with `Type.GetType`, assembly metadata inspection, `DocumentedTypeExample`, `DocumentedExtensionExample`, generic `Describe()` helpers, repeated UID sections, prose that merely names the target, a `default!`/`null!` holder property that only parks the type, a class that just constructs or returns the target with no observable result, a mass-forwarding shell of one-line pass-through members, or one normalized code skeleton reused across unrelated types. +- Namespace prose must be decision-useful. `NAMESPACE_PROSE_INVENTORY_ONLY`, `NAMESPACE_APPEND_ONLY_REPAIR`, `NAMESPACE_PROSE_TEMPLATE_REPETITION`, `NAMESPACE_USAGE_GUIDANCE_MISSING`, and `NAMESPACE_START_HERE_MISSING` mean the page still needs a problem/outcome opening, a cohesively rewritten lead instead of a weak inventory sentence with guidance appended below it, an opening written from the namespace's own purpose rather than a shared template, concrete "when to use" guidance, and a named starting API when the namespace has multiple entry points. +- Namespace overview files are single-UID deliverables. `NAMESPACE_EMBEDDED_OVERWRITE_SECTION` means the page mixed namespace guidance with secondary `uid:` / `example:` mappings after the overview, often below `Extension Members`. Move those type/member examples to readable type-targeted files under `.docfx/api/types/`, usually the declaring extension class page, and keep the namespace page limited to the namespace fly-in, availability, related links, and optional `Extension Members` table. +- Use the JSON completion contract as the final authority: completion requires `summary.canClaimCompletion` to be `true`, `summary.remainingWorkItems` to be `0`, `summary.remainingGates` and `summary.remainingDiagnosticsByCode` to be empty, and the build-backed command to succeed. A clean fast run reports `completionState: verification-required`; it is an iteration checkpoint, not completion. Never describe `status: failed`, `completionState: incomplete`, or `completionState: verification-required` as completed work. +- Continue documentation repair when `dotnet test` fails for an unrelated environmental dependency such as an unavailable database. Report that test failure separately. It is a blocker only if it prevents the documentation validator, source inspection, or required sample compilation from running. +- Valid BOM-less UTF-8 is compliant. The validator must not emit `ENCODING_BOM_MISSING` (that diagnostic is intentionally unsupported), and an audit must not add/remove BOMs or normalize line endings solely for consistency. BOM presence has no documentation value; preserve the file's existing state and continue detecting actual `ENCODING_CORRUPTION` and `EXTENSION_TABLE_ENCODING` damage. +- Final verification uses adaptive execution. In `auto`, machines with more than 8 available logical processors and more than 32 GiB available memory select `high-capacity`: DocFX verification runs concurrently in its isolated temp copy while the main lane builds/discovers API and then compiles samples, and MSBuild worker counts scale up to half the available processors (capped at 16). Smaller machines select `conservative` and keep the phases sequential with low worker counts. Override with `--execution-profile conservative|high-capacity` or `DOCFX_DIGEST_EXECUTION_PROFILE`. +- Child processes time out after 30 minutes by default, configurable with `--process-timeout-minutes` or `DOCFX_DIGEST_PROCESS_TIMEOUT_MINUTES`. Set the host/tool command timeout at least five minutes higher (35 minutes for the default) so the validator can kill a timed-out child and return a deterministic diagnostic instead of being terminated by the caller first. +- Long-running API builds, sample compilation, and DocFX verification write progress to `stderr`: an initial `[ ]` line, a heartbeat every 10 seconds, and a final `[✓]` or `[x]` line. Heartbeats name the active phase, workload size, runner count, PID, elapsed time, time since the child last produced output, and its latest output line when available. Do not suppress `stderr` during interactive runs; `--json` remains a single parseable document on `stdout`. +- When reporting adaptive execution, include the selected profile, processor and memory inputs, build/sample worker counts, timeout, concurrent/sequential choice, process counts, and phase timings from JSON. State that sample compilation follows API discovery because scoped references depend on the namespace-to-project map. Name CLI and environment overrides for profile, worker counts, and timeout when the user asks how to tune the run. +- When reporting heartbeat behavior, state the complete contract: append-only `stderr`, no cursor-rewritten table, start and 10-second heartbeat events, final success/failure marker for all three long phases, latest non-empty child-output line when available, and plain redirected-log markers that do not depend on ANSI color. When reporting encoding safety, explicitly confirm the diff contains neither BOM-only nor line-ending-only changes. +- Read `references/workflow.md` when you need the detailed targeted/audit workflows, namespace and example templates, the verification checklist, or the completion response shape. +- Prefer bounded project packets over one repository-sized authoring context. Discover packets with `docfx.cs --json` (`scope.packets`) or persist them with `--project-manifest `; process one packet at a time while keeping the user's requested scope unchanged. Repair packet-local diagnostics before moving on when practical. If one diagnostic remains difficult after concrete attempts, record it, continue independent packets, and return to it; never turn one repairable packet failure into a reason to stop a full-repository run. Establish reflection-precise scope with `--build-api-model` before authoring — when `summary.scopeState` is `provisional` and `BUILD_BACKED_SCOPE_REQUIRED` fires, the source-scan inventory must not authorize a full authoring run. +- If a fast `--project-manifest` or `scope.packets` result contains unnamed packets, zero projects, or `metadataGroup: unknown`, that is a provisional source-scan artifact. Immediately rerun packet discovery with `--build-api-model --project-manifest ` (or use generated DocFX YAML) and continue from the reflection-backed packet set. Do not treat weak fast-packet metadata as a blocker or as justification to stop. +- If build-backed packet discovery still fails or remains unusable, fall back to sequential repair instead of stopping. Use the assessment work queue order or sort the remaining `EXAMPLE_MISSING` diagnostics by namespace, clear the first namespace (or the next 3-5 examples in it), rerun the fast validator, then continue to the next namespace. +- Repository size, target count, diagnostic volume, context pressure, and model usage limits never change the user's requested scope. An explicit or default repo-wide run continues across every packet until the global completion contract is clean. +- Context limits, queue size, and estimates like "this would take multiple sessions" are internal execution concerns, not user-facing stop conditions. Break the work into packets and keep going until the completion contract is clean unless the user explicitly pauses or a real external blocker prevents further progress. +- Final build-backed verification (`--build-api-model --validate-samples --verify-docfx-build`) is for claiming completion, not for blocking incremental progress. While `summary.remainingWorkItems` is greater than zero or any diagnostics remain, stay on the fast `docfx.cs --json` loop and keep authoring. +- Dry run is a voluntary mode used only when the user explicitly asks for `dry-run`, a representative sample, or a quality pilot. Never infer it from repository size, diagnostic count, context pressure, or model usage limits. It is a real run scoped to a representative subset, with identical evidence, authoring, quality, and compilation gates. Start it with `--dry-run --build-api-model --project-manifest `; this also emits a sibling `.review.json` template. Author every selected packet, read every changed page, complete every review entry with evidence, page-specific purpose/outcome, observable result, and sibling prose/code comparison, then finish with `--resume-project-manifest --review-report --build-api-model --validate-samples --verify-docfx-build`. The baseline protects pre-existing dirty work while allowing current-run files to verify. No-hint dry runs select one clean project per metadata destination group via a seed; explicit names override selection. Report `dry-run-passed` only after every gate passes, and include the completed `Changed-page review` table in the response; a validator summary is not a manual review. Never claim repository completion. Do not ask for hints when none were supplied. +- Use the safe structured overwrite writer (`docfx.cs --write-overwrite `) for repeatable overwrite creation: it preserves BOM/line endings, rejects duplicate UIDs and unbalanced fences, and refuses to replace dirty files. It writes only content you authored — it never generates prose or examples. +- Declare narrow family exemptions in `.docfx/family-exemptions.json` only for coherent generic-arity, inherited, overload, or type-parameter series. The anchor needs a real example and the namespace page must name it and explain sibling selection; category alone never exempts options, exceptions, delegates, records, or data carriers. See `references/workflow.md`. + +## Completion Repair Loop + +Do not stop at namespace pages, extension-member tables, or a first-pass documentation edit. + +1. Run `docfx.cs --json` (fast, no-build) after edits and read the remaining diagnostics. +2. Treat every missing, placeholder, reflection-only, target-use, extension-invocation, duplicate-UID, namespace-prose, extension-table, availability, and overwrite-layout diagnostic as blocking follow-up work. +3. For each missing public concrete-type example, create or update a type-targeting overwrite file under `.docfx/api/types/`. +4. For each missing extension-method example, document it on the declaring extension class page or another readable type-targeted overwrite file under `.docfx/api/types/`, and explicitly demonstrate the method call. Do not append secondary `uid:` / `example:` blocks to the namespace page. +5. Treat the next `EXAMPLE_MISSING` diagnostic as the current task. Read the target's public API surface and one relevant test or usage source, write a consumer-facing example to the correct type-targeted overwrite file, rerun the fast validator, then move to the next diagnostic. +6. A batch can be as small as 3-5 examples, or whatever fits in the current turn. It does not need to be an architecturally complete namespace or packet; completeness emerges from fix → rerun → fix → rerun repetition. +7. When only `EXAMPLE_MISSING` remains, that is still the main digest work, not a checkpoint. Keep authoring type and extension examples packet by packet; do not replace the queue with a completion summary, progress report, user choice menu, or final verification pass. +8. If packet discovery from the fast source-scan yields unnamed or zero-project packets, rerun `--build-api-model --project-manifest ` before continuing example authoring. If the build-backed packet set is still unusable, fall back to sequential repair in assessment work queue or namespace order instead of stopping. +9. Rerun the fast validator until the required diagnostics are gone, then run the build-backed completion verification (`docfx.cs --build-api-model --validate-samples --verify-docfx-build`) to surface `SAMPLE_COMPILE_FAILED` and reflection-precise API gaps; resolve those too and rerun until the JSON completion contract is clean. +10. Do not convert repairable diagnostics into a blocker report. A stubborn diagnostic is a debugging task: inspect the complete implicated UID/path set, validator normalization, source evidence, and related examples; fix either the content or a proven validator defect, then rerun. Continue unrelated packets while investigating when doing so preserves quality. Stop incomplete only when the user pauses the task or a genuine external condition prevents further execution; report the exact command, exit code, and blocker without claiming completion. + +Namespace pages and `Extension Members` tables complement type-page examples; they do not replace them. Both namespace pages (`api/namespaces/`) and type pages (`api/types/`) are required deliverables. Generating only one is incomplete work. + +### Restarting Partial Audits + +When continuing after another agent stopped with diagnostics remaining: + +1. Inspect `git status --short --untracked-files=all`, enumerate the stated counts and paths, and preserve every existing tracked and untracked documentation edit, not only the newly created namespace/type files. Do not collapse a concrete inventory such as “8 namespace pages and 1 type page” into a generic promise to preserve work. +2. Rerun the fast validator with `--json --assessment-queue ` and read the generated queue. +3. Use the assessment work queue and example inventory as the active queue across all affected namespaces, type pages, extension classes, and extension methods. +4. If only `EXAMPLE_MISSING` remains, keep going. That queue is not a stopping point. When packet ownership is unclear from the fast run, write a reflection-backed manifest with `--build-api-model --project-manifest ` and use that manifest as the example-authoring queue instead of presenting a checkpoint or options. +5. If the build-backed packet set is still unusable, fall back to sequential example repair in assessment work queue or namespace order. Clear the next 3-5 examples, rerun, then continue. +6. Repair manageable batches, then rerun the fast validator after each batch so the queue measurably shrinks; do not stop after a representative subset. +7. Run the exact final command `docfx.cs --build-api-model --validate-samples --verify-docfx-build --json` only when you are ready to claim completion, and continue until the completion contract is clean. +8. If a rerun replaces one diagnostic family with a more specific follow-on family, keep going. Do not convert that newly exposed queue into a progress summary or a request for approval to continue. + +## Core Principles + +Documentation is part of the public contract. When public .NET API changes, update the corresponding XML comments, DocFX overwrite content, namespace pages, examples, availability notes, and verification steps in the same change set. + +Document only what the code actually exposes. Do not invent APIs, overloads, target frameworks, behaviors, exceptions, or examples. Verify claims against source code, generated metadata, project files, tests, or existing documentation. + +Manual documentation is authoritative context. Preserve hand-written Markdown and overwrite content unless it is stale or incorrect. Prefer additive edits, but fix contradictions instead of appending conflicting prose. + +Namespace pages and type pages have different jobs. Namespace pages orient readers to the problem space and where to start; generated type pages explain concrete public APIs and must carry concrete examples for public non-abstraction types. + +Write with an inverted-pyramid structure. Lead with the problem solved, explain when to use the API, give a short “start here” cue when helpful, then add structural detail. + +## Safety Gates + +Before editing documentation: + +1. Run `git status --short` and identify modified, staged, and untracked documentation files. +2. Treat existing uncommitted documentation changes as user work. +3. Read each Markdown file before editing it. +4. Classify any cleanup candidate as generated metadata, generated site output, build artifacts, or authored documentation before deleting anything. + +Do not use broad `git restore`, `git checkout --`, `git reset`, or whole-directory recovery commands on documentation source directories. If recovery is needed, recover only the specific generated or accidentally removed file after inspecting `git status` and `git diff`. + +After modifications, inspect `git diff` for touched documentation paths and confirm the diff contains only intended changes. + +## File Encoding Safety + +Use UTF-8 for DocFX documentation, but treat the BOM as optional. DocFX does not need a UTF-8 BOM, and adding or removing one across existing files creates noisy diffs with no documentation value. Preserve each file's existing BOM and line-ending state unless the user explicitly requests normalization. + +- **Never use an encoding-ambiguous `Get-Content` / `Set-Content` round-trip.** Legacy Windows PowerShell can interpret BOM-less UTF-8 through an ANSI code page. Multi-byte UTF-8 sequences, including ⬇️ in `Extension Members` tables, can become mojibake even though the original file was valid. +- **Prefer the `edit` tool** for all Markdown content edits; it preserves bytes correctly and avoids encoding round-trip issues entirely. +- **Check `git status` before any encoding-rewriting operation.** If bytes are corrupted and the file was committed, `git checkout HEAD -- ` restores the committed version — but discards any uncommitted in-flight changes. Do not use that recovery if there are unsaved edits. +- **Do not normalize encoding or line endings as part of a documentation audit.** A BOM-only or line-ending-only diff obscures substantive work. The validator reports actual corruption such as `ENCODING_CORRUPTION`; it does not report BOM absence. + +## Scope + +Apply this skill to: + +- public .NET namespaces that contain public API +- public types and delegates +- public constructors, properties, methods, fields, events, and enum members +- public extension methods +- DocFX overwrite Markdown files +- namespace overview pages +- XML documentation comments +- API examples +- availability includes or availability statements + +Do not document private or internal API, implementation-only helpers, or namespaces that contain no public API. + +## DocFX Discovery and Script Usage + +For Codebelt repositories, the DocFX workspace is `.docfx` and the configuration file is `.docfx/docfx.json`. For other repositories, locate `docfx.json` before making DocFX-specific changes. + +Inspect `docfx.json` before editing so you understand content roots, overwrite file locations, include paths, metadata inputs, and output conventions. When creating or repairing overwrite files, read `references/docfx-overwrite-files.md`. When you need exact CLI arguments, exit codes, JSON diagnostics, or validator behavior for `agents.cs` and `docfx.cs`, read `references/scripts.md`. + +Run `agents.cs` against the actual repository root being documented, not a temp workspace or the skill install directory. The script manages a marker-bounded DocFX maintenance block in the repository root `AGENTS.md`; do not hand-edit or duplicate that block. + +## Required Documentation Surfaces + +When public API is added or materially changed, update every relevant surface: + +1. XML documentation comments in source code. +2. Namespace overview pages for namespaces that contain public API, under `.docfx/api/namespaces/`. +3. `Extension Members` tables for namespaces that expose public extension methods. +4. Type-targeting overwrite content for public non-abstraction types that require examples or richer guidance, under `.docfx/api/types/`. +5. Extension-method examples on the declaring extension class page or another readable type-targeted overwrite file under `.docfx/api/types/`. +6. Availability information. +7. Verification commands or artifacts that prove the documentation remains accurate and buildable. + +Namespace pages and type pages are both required deliverables in the same run. Do not generate namespace pages without type pages or vice versa. + +Material changes include new or removed public API, signature or nullability changes, behavioral changes, exception changes, changed availability, conditional extension-method availability, deprecation changes, default-value changes, or meaningful lifecycle and thread-safety changes. + +## Examples and Overwrites + +Every public non-abstraction type and every public extension method needs at least one realistic, copy/paste-ready example. A namespace fly-in or `Extension Members` table alone is not enough. + +Prefer scenario examples over isolated constructor or method-call snippets. A strong type-page example shows the documented API inside the workflow a consumer is trying to complete, even when that means including nearby public types, a small local helper type, dependency-injection setup, configuration objects, or a short host entry point. The example should still be compact, but it should carry enough context that a developer can understand why the type exists and how it cooperates with the package. + +Before writing examples for a package, identify the package ID or IDs from packable project metadata, `.nuget/*/README.md`, package release notes, `Directory.Packages.props`, or `PackageReference` usage. Search local repository evidence by package ID first, then by namespace/type/member name. When internet or GitHub search is available and the user has not forbidden it, search for the exact package ID and exclude the target repository or treat self-repo hits as lower-priority evidence. Package-ID searches often find real `Program.cs`, `PackageReference`, README, and package-documentation usage that type-name searches miss. + +For each repair batch, maintain an evidence ledger in the example inventory: record the exact test, package README, sample, XML comment, or source path inspected and the consumer task derived from it. Do not mark a scenario ready when its evidence cell contains only a type name, generated metadata, or the overwrite file being repaired. + +**Tests are evidence, not output.** Do not add `ShowUsage`, `Usage`, `Example`, or documentation-only methods to test files. Use tests to understand the documented type's behavior, then transform that knowledge into consumer-facing DocFX overwrite examples. + +Every generated `csharp` code block is a complete, copy/paste-ready compilation unit. The default is always a compilable unit (option 1). Only use intentionally incomplete excerpts (option 2) when explicitly requested by the user, and label them clearly. + +**Complete C# example contract:** + +- Includes all required `using` directives. +- Declares a file-scoped namespace (e.g., `namespace X.Y;`). +- Declares at least one concrete class, struct, or record containing the usage. +- Does **not** use top-level statements unless the example is explicitly labelled `// Program.cs` at the very top of the code block. +- Does **not** invent placeholder services, interfaces, classes, methods, or overloads that are not defined inside the same code block. +- Does **not** derive from an abstract or generic base type without supplying the correct concrete type arguments. +- Does **not** call members that do not exist on the resolved public API surface. +- Uses the documented type or invokes the documented extension method inside the C# fence. A target name in prose, comments, or string literals does not count. +- Shows a consumer-visible operation, result, configuration, or next action. Reflection-only discovery and metadata inspection do not count as usage. +- Contains one coherent example mapping per UID. Merge related calls into one scenario instead of repeating `example: *content` sections for the same UID. +- Compiles in a minimal class library verification project referencing the documented assemblies. + +Prefer examples derived from existing unit, functional, or integration tests as behavioral evidence, then from package-level usage evidence, samples, README content, and real consumer usage, then from a minimal new example based on actual public behavior. Convert Arrange/Act/Assert test structure into consumer-oriented sample code instead of pasting raw test assertions, mocks, or fixture setup. + +For public non-abstraction types, put the example on the generated type page by targeting the type UID in DocFX overwrite content. In Codebelt repositories, keep authored type overwrite Markdown under `.docfx/api/types/`, typically as `.docfx/api/types/{TypeUid}.md`. + +For public extension methods, place examples on the declaring extension class page or another readable type-targeted overwrite file under `.docfx/api/types/`. The example must explicitly call the method. Namespace overview files stay single-UID; do not append secondary `uid:` / `example:` blocks after `Extension Members`. + +Never mirror synthetic method UIDs that contain hashes, encoding, or generated suffixes in filenames. Keep filenames readable and let the YAML `uid` decide what DocFX model the content targets. + +Keep `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite` only. Exclude both `api/namespaces/**` and `api/types/**` from `build.content`. Do not widen either entry to `api/**/*.md`. Move legacy authored `.docfx/api/*.md` overwrite files into either `api/namespaces/` (for namespace pages) or `api/types/` (for type pages) instead of widening the glob. + +For managed reference pages, map type and extension-method examples to the `example` property rather than to `summary` or implicit conceptual content. Read `references/docfx-overwrite-files.md` for the exact front-matter shape. + +## Example Verification + +Every added or changed `csharp` code block must pass two validation gates before it is written to a markdown file. Do not write any `csharp` fence without first verifying both gates pass. + +**Gate 1 — Static structure (`SAMPLE_STRUCTURE_INVALID`):** + +Before attempting compilation, the validator rejects code that: + +- Contains top-level statements without a `// Program.cs` comment label at the top. +- Lacks a namespace declaration. +- Lacks a type declaration (class, struct, or record). + +A code block labelled `// Program.cs` at the very top passes Gate 1 and is compiled as a file-based app. + +**Gate 2 — Compilation (`SAMPLE_COMPILE_FAILED`):** + +Class-based examples that pass Gate 1 are compiled as a class library project referencing all assemblies from `docfx.json`. If compilation fails, the example is rejected. Either repair and re-run, or omit the example and add: + +```markdown + +``` + +**Example generation source priority:** + +Derive examples from these sources, in order: + +1. Package IDs and package-family context — determine what a consumer installs and search local evidence for the exact package ID before narrowing to individual types. +2. Public API surface and XML documentation comments — establish the supported constructor signatures, method signatures, and types. +3. Existing unit, functional, or integration tests that reference the documented type or member — use as behavioral evidence only; do not copy Arrange/Act/Assert structure, test fixtures, mocks, or test helper patterns into the final example unless the public API is specifically about testing. +4. README, `.nuget/*/README.md`, package documentation, samples, tuning/tooling projects, or existing conceptual docs in the repository. +5. Real consumer usage found by exact package-ID search, preferring repositories other than the target repository when available; use self-repo hits only as package-authored documentation or sample evidence. +6. Implementation source, only when the public surface alone is insufficient to construct a valid calling example. +7. Official upstream documentation when the library wraps an external framework or library. +8. Synthesized examples only when all of the above confirm the full public API shape and the synthesized sample compiles. +9. Omit the example entirely if none of the above yields a compile-valid, consumer-facing example. + +Final examples must be consumer-facing, realistic, and compile. They must read like production calling code or Microsoft Learn-style task examples, not test scaffolding, placeholder `Consumer` shells, or one-line smoke tests. Avoid unused locals, `MyNamespace` when a domain-specific namespace is obvious, fake "sample" values that obscure the workflow, and examples that instantiate the documented type without showing the result or next step a real caller cares about. + +Compilation-valid metadata scaffolds are still failures. Never generate a family of examples that differs only by UID while calling `Type.GetType`, returning `Type.FullName`, or wrapping the lookup in `DocumentedTypeExample`, `DocumentedExtensionExample`, or `Describe()`. These patterns conceal missing product knowledge instead of teaching the API. + +**Reflection and API-shape requirements:** + +Resolve constructors, generic arity, abstractness, constraints, and public members before writing examples: + +- Generic types: supply concrete type arguments (e.g., `Repository`, not `Repository`). +- Abstract types: do not instantiate directly; derive with a concrete class that supplies all required generic parameters. +- Extension methods: show a valid receiver type. +- Do not assume parameterless constructors or methods not present in the reflected API surface. +- Do not invent members; if a member cannot be confirmed, omit the example. + +**Skip marker (last resort only):** + +```csharp +// dotnet-docfx-digest:skip-compile - +``` + +The reason is mandatory. Package requirements, "full example needs X", "shows the framework pattern", or missing assembly/transitive/referenced assembly reasons are all rejected — these are authoring or validator-setup problems, not genuine blockers. Prefer making the example compile. Do not claim an example compiles unless the validator actually ran it successfully. + +## Namespace and Summary Style + +Namespace overview pages must explain what problem the namespace solves, when to use it, and where a newcomer should start. Avoid inventory-only blurbs such as “contains types and extension methods for...” + +The opening paragraph should name the developer problem and outcome. The next paragraph should identify a concrete starting type or method and distinguish nearby alternatives. Do not use a type inventory as a substitute for this guidance; tables and generated API lists already provide inventory. + +Type and member summaries should explain the API’s job in consumer terms. Prefer purpose-first summaries for entry points, builders, factories, options, and extension methods. Avoid empty labels such as “represents options” or “adds services” unless the rest of the sentence explains the actual outcome enabled. + +If one namespace page in a public API family needs repair, inspect sibling namespace pages in that family before finishing and keep them consistent. If you intentionally leave a sibling page unchanged, say why. + +## XML Documentation Comments + +Public API should have useful XML comments. Keep source summaries concise and move longer examples or remarks into DocFX overwrite content when that keeps the source readable. + +XML comments should cover purpose, parameters, return value, exceptions, type parameters, important behavior, nullability expectations, and lifecycle or thread-safety details when relevant. + +## Cleanup Boundary + +Authored DocFX Markdown is documentation output, not disposable build output. Do not delete `.md` or `.mdoc` files, `docfx.json`, `toc.yml`, includes, images, examples, or directories that contain authored documentation while cleaning generated artifacts unless the user explicitly asks for that deletion. + +Prefer `docfx.cs --verify-docfx-build` because it builds DocFX in a temp copy and cleans that workspace itself. If `git status` still shows leftover generated files afterward, classify each path before deleting it. Generated metadata cleanup is limited to DocFX-generated `*.yml`, `.manifest`, and `*.manifest` files under configured metadata destinations. Generated site cleanup is limited to the configured build output directory when that directory is clearly generated output and contains no authored Markdown, source, project, solution, or DocFX configuration files. + +If a cleanup candidate is ambiguous, leave it in place and report the ambiguity instead of deleting it. + +## Codebelt Signing Keys + +Codebelt solutions are normally strong-name signed with a repository-root `.snk` file. Preserve and copy that file when it exists. If a Codebelt repository or temp copy does not contain the root `.snk`, use the skip-sign fallback for verification commands: + +```bash +dotnet build -p:SkipSignAssembly=true +dotnet test -p:SkipSignAssembly=true +``` + +Use the same fallback for equivalent builds triggered by documentation validation so missing local signing keys do not masquerade as documentation failures. + +## Workflow Summary + +When the user names a changed API or namespace: + +1. Run `agents.cs`. +2. Run the safety gates and inspect existing documentation edits. +3. Inspect the changed public API, affected namespaces, availability inputs, tests, samples, and current overwrite files. +4. Update XML comments, namespace pages, extension-member tables, examples, and availability notes as required. +5. Build an example inventory for required public concrete types and extension methods. +6. Preserve manual edits, inspect `git diff`, run `dotnet build`, run `dotnet test`, run the Completion Repair Loop, then run the build-backed completion verification (`docfx.cs --build-api-model --validate-samples --verify-docfx-build`). + +When the user does not name a specific target: + +1. Run `agents.cs`. +2. Run the safety gates and inspect repository guidance. +3. Inspect DocFX configuration, overwrite files, tests, samples, and current documentation state. +4. Run `docfx.cs --json`, and for multi-diagnostic output rerun with `--assessment-queue` and use that queue as the work queue. +5. Repair missing namespace pages, extension-member tables, examples, overwrite layout, summaries, and availability notes that can be derived from evidence. +6. Preserve manual edits, inspect `git diff`, run `dotnet build`, run `dotnet test`, run the Completion Repair Loop, then run the build-backed completion verification (`docfx.cs --build-api-model --validate-samples --verify-docfx-build`). + +Read `references/workflow.md` before creating new namespace pages, writing type or extension examples, preparing the final verification checklist, or shaping the completion response. + +## Reference Files + +- `references/workflow.md` — detailed targeted/audit workflows, example inventory shape, templates, verification checklist, and completion response. +- `references/docfx-overwrite-files.md` — overwrite-file model rules, `example: - *content` usage, and Codebelt overwrite layout guidance. +- `references/scripts.md` — exact `agents.cs` and `docfx.cs` commands, arguments, exit codes, diagnostics, and validator behavior. diff --git a/skills/dotnet-docfx-digest/evals/evals.json b/skills/dotnet-docfx-digest/evals/evals.json new file mode 100644 index 0000000..6879fe8 --- /dev/null +++ b/skills/dotnet-docfx-digest/evals/evals.json @@ -0,0 +1,933 @@ +{ + "skill_name": "dotnet-docfx-digest", + "evals": [ + { + "id": 1, + "prompt": "I just added a new public class `RetryPolicy` and a public extension method `WithRetry(this HttpClient client, int attempts)` to my .NET library in the `Acme.Net.Http` namespace. Please update the DocFX documentation for this change.", + "expected_output": "Agent runs scripts/agents.cs to seed AGENTS.md, creates/updates the Acme.Net.Http namespace overview page with uid front matter, a fly-in, availability, and an Extension Members table listing the extended type with the WithRetry method, adds a buildable example for RetryPolicy, and runs scripts/docfx.cs with --verify-docfx-build to verify without leaving generated DocFX output in the working tree.", + "expectations": [ + "Runs the deterministic scripts/agents.cs against the repository before completing", + "Creates or updates a namespace overview page named Acme.Net.Http.md with DocFX overwrite front matter whose uid matches the namespace", + "Adds an Extension Members table documenting the extended type (HttpClient), the ⬇️ marker, and the WithRetry method in backticks", + "Adds at least one copy/paste-ready, buildable example for the concrete RetryPolicy type", + "Includes availability information via an include or explicit Availability text", + "Runs scripts/docfx.cs with --verify-docfx-build to verify before claiming the documentation was verified" + ] + }, + { + "id": 2, + "prompt": "Document the new `internal` helper class `BufferPool` and the `private` method `Rent` I added under `Acme.Buffers`. There is no other public type in that namespace yet.", + "expected_output": "Agent declines to create documentation for internal/private members and does not create a namespace overview page for a namespace that contains no public API, explaining the public-API-only rule.", + "expectations": [ + "Does not create documentation pages or overwrite files for internal or private members", + "Does not create a namespace overview page for Acme.Buffers because it contains no public API", + "Explains that only public API is documented and points to the public-API rule", + "Does not fabricate public API that does not exist" + ] + }, + { + "id": 3, + "prompt": "Add a usage example to the `Acme.Text` namespace page for the `Greeter` class. Base it on the existing unit test `GreeterTest.Greet_WithName_ReturnsGreeting`.", + "expected_output": "Agent preserves the `Acme.Text` namespace page as a namespace-scoped overview, converts the Arrange/Act/Assert test into a real-life consumer-oriented, buildable example on the `Greeter` type page under `.docfx/api/types/` (or an equivalent type-targeted overwrite file), and verifies it compiles with scripts/docfx.cs.", + "expectations": [ + "Derives the example from the referenced test rather than inventing behavior", + "Converts the Arrange/Act/Assert structure into developer-oriented usage instead of pasting raw assertions", + "Does not append a secondary `uid:` / `example:` block to the namespace page after `Extension Members` or other namespace guidance", + "Places the `Greeter` example on a type-targeted overwrite file under `.docfx/api/types/` rather than on the namespace overview file", + "Produces a minimal, deterministic, copy/paste-ready C# example with a real using directive for Acme.Text", + "Avoids pseudo-code, ellipses, and hidden helpers in the sample", + "Verifies the sample compiles via scripts/docfx.cs or an equivalent build command" + ] + }, + { + "id": 4, + "prompt": "Run the DocFX documentation validator on this repository and tell me whether the docs are in good shape.", + "expected_output": "Agent runs scripts/docfx.cs with --verify-docfx-build (and scripts/agents.cs if needed), reports the exact command, exit code, and the deterministic JSON/console findings, and does not claim verification without running the script.", + "expectations": [ + "Runs scripts/docfx.cs against the repository root with --verify-docfx-build so DocFX runs in a temp workspace", + "Reports the exact command run and its exit code", + "Surfaces the deterministic findings (errors/warnings with their codes) rather than guessing", + "Does not claim the documentation was verified unless the script actually ran successfully" + ] + }, + { + "id": 5, + "prompt": "The `Acme.Text` namespace page already has a hand-written introduction and a couple of links I care about. I changed the `Shout` extension method to also trim whitespace. Update the docs but keep my wording.", + "expected_output": "Agent preserves the manual introduction and links, updates only the stale parts relevant to the behavior change, keeps the Extension Members table accurate, and avoids wholesale file replacement.", + "expectations": [ + "Preserves the existing hand-written introduction and links instead of replacing the whole file", + "Updates only the stale portions affected by the behavior change", + "Keeps the Extension Members table accurate for the Shout method", + "Does not leave contradictory descriptions of the Shout behavior", + "Re-verifies any changed sample compiles" + ] + }, + { + "id": 6, + "prompt": "Use dotnet-docfx-digest on this repository.", + "expected_output": "Agent treats the request as a repo-wide DocFX documentation audit instead of asking what to document first. It runs scripts/agents.cs, inspects AGENTS.md, docfx.json, source projects, public API, tests, samples, overwrite files, namespace pages, and availability includes, runs scripts/docfx.cs to collect deterministic findings and writes a deterministic `--assessment-queue` for noisy diagnostics, uses that assessment work queue as the work queue, runs with --verify-docfx-build before completion, repairs missing complementary DocFX documentation that can be derived from source evidence, reads the DocFX overwrite reference when creating or repairing overwrite files, and asks for clarification only if discovery exposes a correctness-affecting choice.", + "expectations": [ + "Does not start by asking the user which API or namespace to document", + "Runs scripts/agents.cs to ensure the repository AGENTS.md contains the managed DocFX maintenance block", + "Inspects docfx.json and existing DocFX overwrite, namespace, include, source, test, and sample evidence before editing", + "Runs scripts/docfx.cs, preferably with --json when collecting repo-wide findings, and uses --verify-docfx-build before completion so generated output stays outside the working tree", + "For multi-diagnostic output, writes and reads a deterministic `--assessment-queue` and uses it as the work queue before editing", + "Creates or updates missing namespace overview pages, Extension Members tables, examples, and availability notes that can be derived from evidence", + "Reads references/docfx-overwrite-files.md before creating or repairing DocFX overwrite files", + "Asks a concise clarifying question only after inspection finds a correctness-affecting unresolved choice" + ] + }, + { + "id": 7, + "prompt": "Use dotnet-docfx-digest on a .NET library whose namespace pages and Extension Members tables are present, but public non-abstraction types such as `ApplicationHostFactory` and public extension methods have no examples. The DocFX config already points `build.overwrite` at `.docfx/api/namespaces/**/*.md`, but some earlier authored overwrite Markdown still lives directly under `.docfx/api/*.md`.", + "expected_output": "Agent does not stop after confirming namespace pages and extension tables. It audits public non-abstraction types and public extension methods for examples, creates or moves readable overwrite files under `.docfx/api/types/` for missing concrete-type examples, keeps `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite` only, keeps `api/namespaces/**` and `api/types/**` excluded from `build.content`, puts type examples on the generated type page/overwrite section rather than the namespace UID page, uses generated UIDs rather than guessing, derives buildable examples from tests or actual public API behavior, runs the Completion Repair Loop by rerunning scripts/docfx.cs --json after edits, fixes remaining EXAMPLE_MISSING or overwrite-layout diagnostics instead of listing them as final notes, and uses --verify-docfx-build before completion so DocFX output is generated in temp space.", + "expectations": [ + "Treats namespace overview pages and Extension Members tables as insufficient when examples are missing", + "Creates or moves readable type-targeting DocFX overwrite files under `.docfx/api/types/` for public non-abstraction type examples", + "Keeps `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite` only and excludes `api/namespaces/**` and `api/types/**` from `build.content`", + "Places a public ApplicationHostFactory example on the ApplicationHostFactory type page/overwrite section rather than only on the namespace page", + "Creates or updates overwrite content for public extension method examples on the declaring extension class page or another readable type-targeted file under `.docfx/api/types/` while explicitly demonstrating the method", + "Uses generated DocFX UIDs or verified metadata instead of inventing overwrite UIDs", + "Runs the Completion Repair Loop after edits by rerunning scripts/docfx.cs --json, fixing remaining EXAMPLE_MISSING and overwrite-layout diagnostics, and updating the example inventory before claiming completion", + "Uses --verify-docfx-build for final DocFX build verification", + "Compiles changed C# examples or reports the exact verification failure" + ] + }, + { + "id": 8, + "prompt": "Run dotnet-docfx-digest validation with `--changed-only` after I added a new public concrete type `Acme.Http.RetryPolicy` and a public extension method `WithRetry(this HttpClient client, int attempts)`. I also created a brand-new untracked overwrite file `.docfx/api/namespaces/Acme.Http.RetryPolicy.md`, but its C# example still does not compile and I have not run `git add` yet.", + "expected_output": "Agent runs scripts/docfx.cs with --changed-only and still validates the new untracked overwrite file instead of skipping it because git has not started tracking it yet. It surfaces SAMPLE_COMPILE_FAILED for the broken C# sample, still scopes the check to the changed APIs and related DocFX inputs, and uses --verify-docfx-build before claiming the docs are verified.", + "expectations": [ + "Runs scripts/docfx.cs with --changed-only when collecting incremental findings", + "Includes the new untracked `.docfx/api/namespaces/Acme.Http.RetryPolicy.md` file in the changed-file scope even though it has not been staged or committed", + "Surfaces SAMPLE_COMPILE_FAILED for the broken sample in the untracked overwrite file instead of silently skipping it", + "Does not silently skip changed-only sample validation just because git returned only tracked changes in `git diff`", + "Scopes the example and sample validation to changed APIs or related DocFX inputs rather than re-reporting the whole repository by default", + "Uses --verify-docfx-build before claiming final verification" + ] + }, + { + "id": 9, + "prompt": "Use dotnet-docfx-digest on a Codebelt.Bootstrapper-style repository. During the run you create `.docfx/api/namespaces/Codebelt.Bootstrapper.ProgramRoot.md` and `.docfx/api/namespaces/Codebelt.Bootstrapper.md`, then validation leaves generated DocFX metadata files beside those authored markdown files. Clean up generated artifacts before completion.", + "expected_output": "Agent preserves all authored Markdown overwrite and namespace files, including files created earlier in the same run, and cleans only known generated DocFX metadata or safe generated site output. It does not delete `.docfx/api/namespaces/**/*.md`, does not recursively delete DocFX directories that contain Markdown or source/configuration files, uses `docfx.cs --verify-docfx-build` for temp-workspace verification, classifies any remaining `git status` paths before deletion, and leaves ambiguous cleanup candidates in place with a note instead of deleting them.", + "expectations": [ + "Treats newly created `.docfx/**/*.md` files as documentation deliverables rather than cleanup targets", + "Does not run broad manual cleanup commands that delete DocFX directories by name", + "Lists cleanup candidates before deletion and classifies them as generated metadata, generated site output, or build artifacts", + "Limits generated metadata cleanup to DocFX-generated `*.yml`, `.manifest`, and `*.manifest` files under configured metadata destinations", + "Does not recursively delete a configured build output directory when it contains Markdown, source, project, solution, or DocFX configuration files", + "Uses `docfx.cs --verify-docfx-build` so the DocFX build runs in a temp copy and generated site output stays out of the working tree", + "Reports any ambiguous leftover paths instead of deleting authored documentation" + ] + }, + { + "id": 10, + "prompt": "Use dotnet-docfx-digest on the Codebelt.Bootstrapper docs after a bad previous run left `Codebelt.Bootstrapper.Console.md`, `Codebelt.Bootstrapper.md`, `Codebelt.Bootstrapper.Web.md`, and `Codebelt.Bootstrapper.Worker.md` checked out. The last agent restored or undid some of those files, only edited `Codebelt.Bootstrapper.md`, and added no required examples.", + "expected_output": "Agent does not run broad restore or checkout commands. It captures git status and diffs first, runs scripts/docfx.cs with --json and --assessment-queue, reads the assessment work queue, audits all four Bootstrapper namespace pages as a related family, fixes Extension Members sections consistently, creates or repairs required examples for public non-abstraction types and public extension methods instead of stopping at tables, builds an example inventory mapping each required API to an example file and UID, preserves already checked-out Markdown edits, runs build/test/DocFX verification, and reports any remaining deterministic diagnostics.", + "expectations": [ + "Captures git status and diffs before modifying or recovering checked-out Markdown files", + "Does not use broad git restore, checkout, reset, or whole-directory recovery commands", + "Stops and reports existing uncommitted documentation changes if they cannot be preserved safely", + "Runs scripts/docfx.cs with --json and --assessment-queue, then reads the generated assessment work queue before editing", + "Audits `Codebelt.Bootstrapper.Console.md`, `Codebelt.Bootstrapper.md`, `Codebelt.Bootstrapper.Web.md`, and `Codebelt.Bootstrapper.Worker.md` together instead of updating only one file", + "Uses `Extension Members` headings where extension methods are present", + "Adds required examples for public non-abstraction types and public extension methods, not only namespace fly-ins or extension tables", + "Builds and reports an example inventory mapping each required API to its example file and UID", + "Runs git diff for touched documentation paths after edits and before final verification", + "Preserves authored Markdown and reports any remaining validation diagnostics instead of claiming completion" + ] + }, + { + "id": 11, + "prompt": "Use dotnet-docfx-digest on a .NET repository that does not contain a `skills/dotnet-docfx-digest/` folder. The skill is installed globally, and the target repository root is the current working directory.", + "expected_output": "Agent resolves agents.cs and docfx.cs from the loaded installed dotnet-docfx-digest skill directory instead of assuming the target repository vendors the skill source. It runs agents.cs first with an explicit --repo-root pointing at the target repository, verifies AGENTS.md was created or updated by the script, then runs docfx.cs against the same repository root. If either script path cannot be resolved, it reports every checked location plus the exact command failure instead of claiming the scripts are unavailable.", + "expectations": [ + "Checks the loaded installed skill directory for scripts/agents.cs and scripts/docfx.cs before concluding the scripts are missing", + "Does not require the target repository to contain skills/dotnet-docfx-digest/scripts/*.cs", + "Passes the target repository path explicitly with --repo-root instead of relying on the skill install directory or a temp workspace as the repository root", + "Runs agents.cs before documentation validation so AGENTS.md receives the managed DocFX maintenance block", + "Reports the exact command, exit code, output, and checked script locations if script resolution or execution fails" + ] + }, + { + "id": 12, + "prompt": "Use dotnet-docfx-digest on a Codebelt library repository that is strong-name signed but this checkout does not have the author's root `.snk` file. Update the docs and run verification.", + "expected_output": "Agent preserves or copies the root `.snk` file when it exists, but because this checkout has no root `.snk`, it runs build and test verification with `-p:SkipSignAssembly=true`. The deterministic docfx.cs validator also uses the skip-sign fallback for its repository build, sample compilation builds, and temp-workspace DocFX verification instead of reporting signing-key failures as documentation failures.", + "expectations": [ + "Checks whether the Codebelt repository root contains a `.snk` file before choosing verification commands", + "Uses `dotnet build -p:SkipSignAssembly=true` when no root `.snk` is present", + "Uses `dotnet test -p:SkipSignAssembly=true` when no root `.snk` is present", + "Preserves and copies a root `.snk` file into temp workspaces when one exists instead of disabling signing unnecessarily", + "Does not treat a missing local signing key as a documentation validation failure", + "Reports the skip-sign fallback in the verification summary when it was used" + ] + }, + { + "id": 13, + "prompt": "A previous run of dotnet-docfx-digest enhanced only `.docfx/api/namespaces/Codebelt.Extensions.Xunit.Hosting.md` and added examples there, but the validator still reports `EXAMPLE_MISSING` for the public concrete type `Codebelt.Extensions.Xunit.Hosting.ApplicationHostFactory`. Fix the documentation gap and explain why namespace examples were insufficient.", + "expected_output": "Agent treats the remaining EXAMPLE_MISSING diagnostic as an unfinished work item, creates or updates `.docfx/api/types/Codebelt.Extensions.Xunit.Hosting.ApplicationHostFactory.md` with DocFX front matter for uid `Codebelt.Extensions.Xunit.Hosting.ApplicationHostFactory`, adds a buildable ApplicationHostFactory example derived from source or tests, keeps both `.docfx/api/namespaces/**/*.md` and `.docfx/api/types/**/*.md` under `build.overwrite`, reruns scripts/docfx.cs --json until the diagnostic is gone, and explains that namespace examples and Extension Members tables complement but do not replace examples on generated type pages.", + "expectations": [ + "Does not treat the namespace page examples as sufficient for the ApplicationHostFactory concrete type", + "Creates or updates the type-targeting overwrite file `.docfx/api/types/Codebelt.Extensions.Xunit.Hosting.ApplicationHostFactory.md` or an equivalent file that targets the exact ApplicationHostFactory UID", + "Uses DocFX front matter with uid `Codebelt.Extensions.Xunit.Hosting.ApplicationHostFactory` for the type example section", + "Adds a realistic, copy/paste-ready C# example for ApplicationHostFactory based on actual source, tests, or public behavior", + "Keeps `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite` and does not widen to `api/**/*.md`", + "Reruns scripts/docfx.cs --json after the edit and treats any remaining EXAMPLE_MISSING diagnostic as blocking completion", + "Explains that namespace overview examples and Extension Members tables are complementary surfaces, not substitutes for type-page examples" + ] + }, + { + "id": 14, + "prompt": "Use dotnet-docfx-digest on a Carter-style repository where `EndpointConventionBuilderExtensions` has generic extension methods whose generated DocFX method UIDs look like `Codebelt.Extensions.Carter.EndpointConventionBuilderExtensions.$6D0D8037DBBD61D10816ECA5F93B896F`. The previous run created `.docfx/api/Codebelt.Extensions.Carter.EndpointConventionBuilderExtensions.%3CG%3E%246D0D8037DBBD61D10816ECA5F93B896F.md`, added `// dotnet-docfx-digest:skip-compile - Full example requires Cuemon.Extensions.AspNetCore.Text.Yaml package`, and left the namespace page as a thin table. Repair the docs.", + "expected_output": "Agent removes or avoids the encoded/hash-like method UID filename, places extension-method examples in a readable declaring-class overwrite file such as `.docfx/api/types/Codebelt.Extensions.Carter.EndpointConventionBuilderExtensions.md`, does not use a package-requirement skip marker as a compile escape hatch, either makes the sample compile or reports a precise deterministic blocker, and restores the namespace page as a curated overview with developer-friendly purpose, type-family context, extension-method groups, availability, and pointers to detailed examples.", + "expectations": [ + "Does not create or keep URL-encoded/hash-like method UID filenames for generic extension methods such as `%3CG%3E%24...`", + "Uses a readable declaring extension class overwrite file under `.docfx/api/types/` for extension-method examples", + "Ensures the example explicitly calls the documented extension method", + "Does not use `// dotnet-docfx-digest:skip-compile - Full example requires ... package` as the final state", + "Documents any required package or setup outside the code fence when relevant", + "Keeps or improves the namespace page as a curated overview rather than reducing it to a generic sentence and table", + "Reruns scripts/docfx.cs --json and treats `SAMPLE_SKIP_REASON_INSUFFICIENT`, `SAMPLE_COMPILE_FAILED`, and `EXAMPLE_MISSING` as blocking diagnostics" + ] + }, + { + "id": 15, + "prompt": "Run dotnet-docfx-digest validation on a .NET repository where `docfx.json` lives at the repository root. The DocFX config includes only `.docfx/api/namespaces/**/*.md` in `build.overwrite`, but the repository also has `README.md` and `CHANGELOG.md` files with YAML front matter UIDs that happen to match public API targets.", + "expected_output": "Agent relies on scripts/docfx.cs resolving Markdown from configured DocFX `build.content` and `build.overwrite` inputs instead of treating every repository Markdown file as overwrite content. Unrelated root Markdown files do not satisfy required example checks, so missing per-type or extension examples still surface as `EXAMPLE_MISSING` diagnostics.", + "expectations": [ + "Does not treat the repository root as the Markdown scan scope merely because `docfx.json` is at the root", + "Uses configured DocFX Markdown inputs such as `.docfx/api/namespaces/**/*.md` as the overwrite discovery scope", + "Does not allow README.md or CHANGELOG.md front matter to satisfy required examples unless those files are included by DocFX config", + "Still reports `EXAMPLE_MISSING` for public API targets whose configured overwrite files lack examples" + ] + }, + { + "id": 16, + "prompt": "Run dotnet-docfx-digest validation with `--changed-only` after I changed only `docfx.json` to exclude `api/namespaces/**` from `build.content` and keep `api/namespaces/**/*.md` under `build.overwrite`. Existing namespace pages still contain stale Extension Members content, but the namespace page files themselves are not changed.", + "expected_output": "Agent runs scripts/docfx.cs with `--changed-only` and still revalidates namespace pages when `docfx.json` changes, because DocFX config changes can change which overwrite files and namespace pages participate in the documentation build. Stale namespace-page diagnostics are surfaced instead of being silently skipped.", + "expectations": [ + "Treats a changed `docfx.json` as a reason to rerun namespace-page validation under `--changed-only`", + "Does not require the namespace Markdown file itself to be in the changed file set when DocFX config changed", + "Still surfaces stale namespace-page and Extension Members diagnostics after a DocFX overwrite-layout change", + "Keeps required-example validation aligned with the same changed `docfx.json` trigger" + ] + }, + { + "id": 18, + "prompt": "Fix the DocFX overwrite setup in a Codebelt-style repository where `.docfx/docfx.json` currently uses `api/**/*.md` under both `build.content` and `build.overwrite`, and authored overwrite Markdown files like `.docfx/api/Codebelt.Extensions.Swashbuckle.AspNetCore.ConfigureSwaggerGenOptions.md` still sit directly under `.docfx/api/`. Move the authored overwrite Markdown into the correct overwrite subdirectory based on its `uid` front matter, preserve the YAML front matter and example content, keep generated `.yml` metadata in place, and verify that `docfx build --exportRawModel` still treats the API page as managed reference rather than conceptual-only.", + "expected_output": "Agent rewrites `docfx.json` so both `api/namespaces/**/*.md` and `api/types/**/*.md` are treated as overwrite-only content, excludes both `api/namespaces/**` and `api/types/**` from `build.content`, moves authored type overwrite Markdown such as `ConfigureSwaggerGenOptions.md` from `.docfx/api/*.md` into `.docfx/api/types/` without dropping content, preserves generated `.yml` files, reruns verification, and confirms the raw model remains a managed API page with overwrite content merged into it rather than collapsing to `{ \"type\": \"Conceptual\" }`.", + "expectations": [ + "Moves authored type overwrite Markdown files from `.docfx/api/*.md` into `.docfx/api/types/` when the uid front matter targets a type", + "Preserves YAML front matter, UID targeting, and Markdown example content while moving the files", + "Keeps generated `.yml` metadata files in place", + "Ensures both `api/namespaces/**/*.md` and `api/types/**/*.md` appear only under `build.overwrite` and that `build.content` excludes both `api/namespaces/**` and `api/types/**`", + "Does not use `api/**/*.md` under `build.content` or `build.overwrite`", + "Verifies the affected API page remains managed reference output with merged overwrite content instead of conceptual-only raw model output" + ] + }, + { + "id": 17, + "prompt": "The `Acme.OpenApi.ModelContextProtocol` namespace page currently says `Contains types and extension methods for MCP integration.` The public type `McpServerOptions` says `Represents options for the server.` The extension method `AddMcpServer(this IServiceCollection services)` says `Adds MCP server services.` Use dotnet-docfx-digest to rewrite the documentation so a developer new to this domain immediately understands what each API is for.", + "expected_output": "Agent rewrites the namespace overview and affected API summaries with conceptual orientation instead of structural inventory. The namespace fly-in leads with the problem solved, when to use the namespace, and a start-here cue such as AddMcpServer. The type and member summaries explain the role and likely use of the API in consumer terms, while keeping every claim grounded in the real public API and still following the normal script-and-verification workflow.", + "expectations": [ + "Rewrites the namespace overview so it leads with the problem or outcome the namespace enables instead of only saying what it contains", + "Explains when a developer would use the namespace and includes a newcomer-oriented start-here cue that points to a representative type or entry-point member", + "Rewrites type or member summaries so they explain the API's role and likely use instead of generic structural labels such as `Represents options` or `Adds services`", + "Keeps the summaries grounded in actual public API behavior rather than inventing capabilities or marketing language", + "Applies the same conceptual-orientation pattern consistently across the namespace page and the touched API summaries" + ] + }, + { + "id": 19, + "prompt": "Run dotnet-docfx-digest with `--changed-only` after I edited a C# 14 extension-block file in the `Codebelt.Extensions.Carter` namespace: `public static class EndpointConventionBuilderExtensions { extension(IEndpointConventionBuilder builder) { public IEndpointConventionBuilder Produces(int statusCode = StatusCodes.Status200OK, params string[] contentTypes) { ... } } }`. The previous run created `.docfx/api/namespaces/EndpointConventionBuilderExtensions.Produces-extensions.md` whose YAML `uid` is `Codebelt.Extensions.Carter.EndpointConventionBuilderExtensions.$6D0D8037DBBD61D10816ECA5F93B896F`, and the namespace page still needs a real extension-method example.", + "expected_output": "Agent treats the compiler-generated `$...` container as an implementation artifact of the outer `EndpointConventionBuilderExtensions` type, so the repair path stays on readable declaring-class overwrite pages under `.docfx/api/types/`. `--changed-only` still notices the edited extension-block source file, surfaces the missing example work, and avoids treating the synthetic nested type as a standalone documented API target.", + "expectations": [ + "Collapses compiler-generated extension-block containers such as `$...` back to the authored outer static class when choosing extension-method example targets", + "Does not treat the synthetic nested extension-block type as a required public type example target", + "Keeps the required example location on a readable declaring-class overwrite page under `.docfx/api/types/` instead of a synthetic method/type UID file", + "Under `--changed-only`, recognizes the edited extension-block source file as touching the `Produces` extension method even though the method declaration no longer uses `this` syntax", + "Still reports missing extension-method examples until a readable declaring-class overwrite file explicitly calls `Produces`" + ] + }, + { + "id": 20, + "prompt": "Use dotnet-docfx-digest on a .NET library where the namespace `Acme.Core` contains a plain class `Options`, an enum `LogLevel`, a public struct `Range`, a public record `Result`, and a generic class `Repository`. The library also has a static extension class `StringExtensions` with generic method `Parse(this string input)`. The namespace currently has no DocFX documentation at all.", + "expected_output": "Agent generates both a namespace overview page at `.docfx/api/namespaces/Acme.Core.md` and type-targeting overwrite files at `.docfx/api/types/Acme.Core.Options.md`, `.docfx/api/types/Acme.Core.LogLevel.md`, `.docfx/api/types/Acme.Core.Range.md`, `.docfx/api/types/Acme.Core.Result.md`, `.docfx/api/types/Acme.Core.Repository.md`, and `.docfx/api/types/Acme.Core.StringExtensions.md` in the same run. The generic `Repository` and generic extension method `Parse` are included as valid documentation targets. Both `api/namespaces/**/*.md` and `api/types/**/*.md` are added under `build.overwrite`, and both directories are excluded from `build.content`.", + "expectations": [ + "Generates the namespace overview page at `.docfx/api/namespaces/Acme.Core.md` with a uid front matter matching the namespace", + "Generates type overwrite files under `.docfx/api/types/` for every public non-abstraction type including Options, LogLevel, Range, Result, and Repository", + "Includes the generic class `Repository` as a valid documentation target and does not skip it", + "Generates a type overwrite file for `StringExtensions` as a static extension container", + "Includes the generic extension method `Parse` in the Extension Members table on the namespace page", + "Adds both `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite` in docfx.json", + "Excludes both `api/namespaces/**` and `api/types/**` from `build.content` in docfx.json", + "Does not treat namespace generation and type generation as mutually exclusive" + ] + }, + { + "id": 21, + "prompt": "Use dotnet-docfx-digest on a .NET library containing a public abstract base class `ValidatorBase` and a public interface `IValidator`. The same namespace also has a concrete class `EmailValidator` that extends `ValidatorBase` and a static class `ValidatorExtensions` with extension methods.", + "expected_output": "Agent excludes `ValidatorBase` and `IValidator` from required example targets because they are an abstract base class and an interface respectively. It does include `EmailValidator` and `ValidatorExtensions` as documentation targets. The type overwrite files are created only for `EmailValidator` and `ValidatorExtensions` under `.docfx/api/types/`.", + "expectations": [ + "Does not create a required example target for `ValidatorBase` because it is an abstract base class", + "Does not create a required example target for `IValidator` because it is an interface", + "Creates a required example target for the concrete class `EmailValidator`", + "Creates a required example target for `ValidatorExtensions` as a static extension container", + "Places type overwrite files under `.docfx/api/types/` only for included types" + ] + }, + { + "id": 22, + "prompt": "Use dotnet-docfx-digest on a library where `docfx.json` currently has only `api/namespaces/**/*.md` under `build.overwrite` and only `api/namespaces/**` excluded from `build.content`. This is the first run for this repository.", + "expected_output": "Agent updates `docfx.json` on the first run to add `api/types/**/*.md` under `build.overwrite` and `api/types/**` to the `build.content` exclusions. It also creates the namespace overwrite pages and type overwrite pages in the same run. Running the skill a second time produces no further changes to `docfx.json`.", + "expectations": [ + "Updates `docfx.json` to include `api/types/**/*.md` under `build.overwrite`", + "Updates `docfx.json` to exclude `api/types/**` from `build.content`", + "Creates namespace pages under `.docfx/api/namespaces/` and type pages under `.docfx/api/types/` in the same run", + "A second run does not change `docfx.json` again because it is already compliant", + "Does not use `api/**/*.md` as a catch-all pattern" + ] + }, + { + "id": 23, + "prompt": "Use dotnet-docfx-digest on a library where a previous run created type overwrite files under `.docfx/api/namespaces/Acme.Core.MyType.md` (the old single-directory convention). The new convention places type overwrite files under `.docfx/api/types/`. Migrate the repository to the new convention.", + "expected_output": "Agent moves the type overwrite file from `.docfx/api/namespaces/Acme.Core.MyType.md` to `.docfx/api/types/Acme.Core.MyType.md`, preserves the YAML front matter and example content, updates `docfx.json` to include both `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite`, and excludes `api/types/**` from `build.content`. The namespace page `Acme.Core.md` remains in `api/namespaces/`.", + "expectations": [ + "Moves type overwrite files from `api/namespaces/` to `api/types/` when they contain a type UID rather than a namespace UID", + "Keeps namespace overview pages under `api/namespaces/`", + "Preserves YAML front matter and Markdown content when moving files", + "Updates `docfx.json` to have both namespace and type globs under `build.overwrite`", + "Verifies that the validator no longer reports `API_OVERWRITE_CONFIG_INVALID` after the migration" + ] + }, + { + "id": 24, + "prompt": "Use dotnet-docfx-digest on a library that exposes a static class `HttpClientExtensions` with generic extension methods `AddPolicy(this IHttpClientBuilder builder)` and `UseTimeout(this HttpClient client, TimeSpan timeout)`. The previous run skipped these because they were incorrectly filtered out as generic types.", + "expected_output": "Agent includes both generic extension methods in the Extension Members table and requires examples for both. It does not skip `HttpClientExtensions` or its methods because the declaring type is generic or the methods are generic. The type overwrite file for `HttpClientExtensions` is created under `.docfx/api/types/`.", + "expectations": [ + "Does not skip `HttpClientExtensions` because it is a static class (abstract sealed in IL)", + "Includes `AddPolicy` and `UseTimeout` in the Extension Members table", + "Creates a type overwrite file for `HttpClientExtensions` under `.docfx/api/types/`", + "Generates `EXAMPLE_MISSING` for the extension methods until examples are provided", + "Does not depend on a `IsGenericType` filter to exclude valid API targets" + ] + }, + { + "id": 25, + "prompt": "Run dotnet-docfx-digest on a library that uses C# 14 extension blocks. The compiler generates a synthetic nested type `EndpointExtensions.$AB12CD34` for the extension block. docfx.cs detects this during API discovery.", + "expected_output": "Agent emits a `DOCFX_EXTENSION_BLOCK_UNSUPPORTED` warning for the namespace explaining that DocFX issue #11010 means extension block metadata may be missing. It continues documenting all other discoverable public APIs without skipping them, collapses the synthetic container back to the outer `EndpointExtensions` class for documentation purposes, and does not try to fix DocFX metadata gaps by excluding APIs.", + "expectations": [ + "Emits `DOCFX_EXTENSION_BLOCK_UNSUPPORTED` as a warning, not an error, for the affected namespace", + "Does not stop or skip other API targets because of the C# 14 extension block detection", + "Collapses the synthetic `$...` nested type to the outer static class for example targeting", + "Does not create a separate overwrite file for the synthetic nested type", + "Continues generating namespace and type overwrite files for all other public APIs in the same run", + "Does not try to fix DocFX issue #11010 by excluding extension methods or inventing special rules" + ] + }, + { + "id": 26, + "prompt": "Run dotnet-docfx-digest twice on a correctly configured repository where all namespace pages, type overwrite files, and docfx.json settings are already present and valid. Confirm idempotency.", + "expected_output": "The second run produces no changes to `docfx.json`, no new overwrite files, and the validator exits with status `passed` with zero errors on both runs. The agent reports that the repository is already compliant and does not make spurious edits.", + "expectations": [ + "Second run reports validation passed with zero errors", + "Second run makes no changes to `docfx.json`", + "Second run creates no new namespace or type overwrite files", + "Second run does not report spurious `API_OVERWRITE_CONFIG_INVALID` after `docfx.json` was already updated on the first run", + "Agent reports that the documentation is already in a compliant state" + ] + }, + { + "id": 27, + "prompt": "Run dotnet-docfx-digest on a repository. Confirm that the validator does not depend on DocFX-generated hash filenames like `*.md.G-*` or URL-encoded method UID filenames as source truth.", + "expected_output": "Agent discovers required example targets from compiled assembly metadata, not from DocFX-generated hash filenames. It reports `EXAMPLE_MISSING` when no overwrite file under `api/types/` has an example for the required UID. Hash-named files that may exist from a previous run do not satisfy the example requirement.", + "expectations": [ + "Discovers required example targets from compiled assembly reflection, not from DocFX hash filenames", + "Does not use `*.md.G-*` files as evidence that an example exists", + "Reports `EXAMPLE_MISSING` even if a hash-named file exists but the correct UID is not in an overwrite file under `api/types/`", + "Does not create hash-named overwrite files as repair actions" + ] + }, + { + "id": 28, + "prompt": "Use dotnet-docfx-digest. During the run the skill creates `.docfx/api/namespaces/Acme.Core.md` and `.docfx/api/types/Acme.Core.MyClass.md`. Run agents.cs and confirm AGENTS.md is created or updated with the new managed block content that mentions both namespace and type overwrite files.", + "expected_output": "agents.cs creates or updates AGENTS.md with a managed block that explicitly states: both namespace overwrite files (`api/namespaces/`) and type overwrite files (`api/types/`) are required; generic public APIs are valid targets; extension members are rendered under `Extension Members`; and `docfx.json` must include both `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite`.", + "expectations": [ + "AGENTS.md is created or updated by agents.cs before documentation validation", + "The managed block states that both namespace pages and type pages are required deliverables", + "The managed block states that generic public APIs are valid documentation targets", + "The managed block states that extension members are rendered under the heading `Extension Members`", + "The managed block states that `build.overwrite` must include both `api/namespaces/**/*.md` and `api/types/**/*.md`", + "The managed block states that type overwrite files live under `.docfx/api/types/`" + ] + }, + { + "id": 29, + "prompt": "Run dotnet-docfx-digest on a repository where `docfx.json` has `metadata[].src[].files = [\"src/Acme.Core/*.csproj\", \"src/Acme.Abstractions/*.csproj\"]` but a third project `src/Acme.Benchmarks/Acme.Benchmarks.csproj` also exists under `src/`. Confirm that `Acme.Benchmarks` is never reflected over or documented.", + "expected_output": "The validator reads the active `docfx.json` metadata configuration and builds the project list exclusively from the `metadata[].src[].files` patterns. `Acme.Benchmarks` is not included in the project list because it is not matched by any `metadata[].src` pattern in `docfx.json`. No namespace page, type overwrite file, or example is generated for types defined in `Acme.Benchmarks`.", + "expectations": [ + "Builds the candidate project list from docfx.json metadata[].src[].files patterns, not by scanning all src/**/*.csproj", + "Does not include Acme.Benchmarks in the project list because it is not referenced by docfx.json", + "Does not generate namespace pages, type overwrite files, or examples for types defined in Acme.Benchmarks", + "Documents only Acme.Core and Acme.Abstractions as they are explicitly included by docfx.json", + "Reports PROJECT_DISCOVERY_FAILED with the docfx.json path if no projects are resolved" + ] + }, + { + "id": 30, + "prompt": "Run dotnet-docfx-digest on a repository where `docfx.json` has two separate `metadata` entries: the first entry includes `src/Acme.Core/*.csproj` and the second entry includes `src/Acme.Extensions/*.csproj`. Both entries use `metadata[].src[].src = \"../\"` to resolve paths relative to the `.docfx/` directory.", + "expected_output": "The validator resolves projects from both metadata entries and merges the results into a single de-duplicated, sorted project list. Namespaces from both `Acme.Core` and `Acme.Extensions` assemblies appear in the public API surface. Both namespace pages and required type overwrite files are generated for all public non-abstraction types in both assemblies.", + "expectations": [ + "Reads and processes all metadata entries in docfx.json, not only the first one", + "Resolves projects from each metadata entry's src[] configuration independently", + "Merges projects from all metadata entries into a single de-duplicated list", + "Discovers public API from both Acme.Core and Acme.Extensions assemblies", + "Generates namespace pages and type overwrite files for public APIs in both assemblies" + ] + }, + { + "id": 31, + "prompt": "Run dotnet-docfx-digest on a repository where `docfx.json` lives under `.docfx/` and its metadata section uses `\"src\": \"../\"` to point at the repository root, with `\"files\": [\"src/**.csproj\"]`. Confirm that project paths are resolved relative to the `.docfx/` directory and not relative to the process working directory.", + "expected_output": "The validator resolves the `src` base directory for each metadata entry relative to the `docfx.json` file location, not relative to the process CWD. When `docfx.json` is at `.docfx/docfx.json` and `metadata[].src[].src = \"../\"`, the effective base resolves to the repository root, and `files = [\"src/**.csproj\"]` discovers projects under `/src/`. All resolved project paths are full, normalised absolute paths.", + "expectations": [ + "Resolves metadata[].src[].src paths relative to the docfx.json file location", + "Does not resolve paths relative to the process working directory", + "Correctly derives the repository root when src = \"../\" and docfx.json is at .docfx/docfx.json", + "Discovers .csproj files under the resolved base directory using the files glob patterns", + "Returns normalised absolute paths for all resolved projects" + ] + }, + { + "id": 32, + "prompt": "Run dotnet-docfx-digest on a repository where `docfx.json` includes `src/**.csproj` in `metadata[].src[].files` but also has `metadata[].src[].exclude = [\"src/Acme.Tests/**\", \"src/Acme.Samples/**\"]`. Projects `Acme.Tests` and `Acme.Samples` exist under `src/` and would otherwise be matched. Confirm they are excluded from the documentation surface.", + "expected_output": "The validator honours the `exclude` patterns in each `metadata[].src` entry and removes `Acme.Tests` and `Acme.Samples` from the resolved project list. No namespace pages, type overwrite files, or examples are generated for types in those assemblies. The project list matches only the assemblies that pass both the include and exclude filter.", + "expectations": [ + "Applies metadata[].src[].exclude patterns to filter out matching .csproj files", + "Does not include Acme.Tests in the project list because it is matched by the exclude pattern", + "Does not include Acme.Samples in the project list because it is matched by the exclude pattern", + "Does not generate documentation for types in excluded projects", + "Reports PROJECT_DISCOVERY_FAILED when all projects are excluded and no projects remain" + ] + }, + { + "id": 33, + "prompt": "Run dotnet-docfx-digest twice in succession on a repository where `docfx.json` is already correctly configured with `metadata[].src[].files = [\"src/**.csproj\"]` and `metadata[].src[].exclude = [\"src/tools/**\"]`. On the first run, all namespace pages and type overwrite files are generated. Confirm that the second run resolves the same project set and produces no new changes.", + "expected_output": "Both runs resolve the same set of projects from `docfx.json`. The second run discovers the same public API surface, validates the same namespace pages and type overwrite files, and reports no new changes, no spurious diagnostics, and no new files created. The resolved project list is identical on both runs because the discovery is based solely on the static `docfx.json` configuration.", + "expectations": [ + "Second run resolves the same project list as the first run", + "Second run discovers the same public API namespaces and types", + "Second run reports no new namespace or type overwrite files created", + "Second run reports validation passed with zero errors when the first run left the repository in a compliant state", + "Project discovery is deterministic: the same docfx.json always produces the same project list regardless of run order" + ] + }, + { + "id": 34, + "prompt": "Run dotnet-docfx-digest on a repository whose `docfx.json` metadata section has no `src` key at all in any metadata entry. Confirm that the validator fails with a clear error explaining which `docfx.json` was read and what configuration is missing.", + "expected_output": "The validator reads the active `docfx.json`, finds no resolvable projects from the metadata section, and emits a `PROJECT_DISCOVERY_FAILED` diagnostic that includes the full path to `docfx.json` and guidance explaining that `metadata[].src[].files` must reference `.csproj` files. The exit code is non-zero. No fallback scan of `src/**/*.csproj` is attempted.", + "expectations": [ + "Emits PROJECT_DISCOVERY_FAILED with the full path to docfx.json in the diagnostic message", + "Explains that metadata[].src[].files must be configured to reference .csproj files", + "Returns a non-zero exit code", + "Does not fall back to scanning src/**/*.csproj when docfx.json produces no projects", + "Does not attempt to document any projects or generate any overwrite files when project discovery fails" + ] + }, + { + "id": 35, + "prompt": "Create a DocFX overwrite file for type `Acme.Widgets.Spinner` using the recommended `example: *content` front-matter form. The body should contain only a bare csharp fence with no `### Examples` heading. Confirm that the validator accepts this as a complete example.", + "expected_output": "The agent writes the overwrite file with front matter `example: *content` and a bare csharp fence in the body (no `### Examples` heading). The validator runs and reports zero `EXAMPLE_MISSING` diagnostics for `Acme.Widgets.Spinner`. The agent does not add a heading because the skill instructs that DocFX renders the section header automatically.", + "expectations": [ + "Front matter uses `example: *content` (or the `- *content` list form), not `summary: *content`", + "Body contains a csharp or cs fenced code block", + "Body does NOT contain a `### Examples` or `## Example` heading", + "Validator runs and does not emit EXAMPLE_MISSING for the target type", + "Agent explains that DocFX adds the Examples section header automatically so a manual heading is not needed" + ] + }, + { + "id": 36, + "prompt": "Create a DocFX overwrite file for type `Acme.Widgets.Spinner` using the `example:` list form (front matter has `example:` on one line and `- *content` on the next). The body contains only a bare csharp fence. Confirm that the validator accepts this as a complete example.", + "expected_output": "The agent writes the overwrite file with a multi-line `example:\\n- *content` front matter block and a bare csharp fence in the body. The validator runs and reports zero `EXAMPLE_MISSING` diagnostics for `Acme.Widgets.Spinner`.", + "expectations": [ + "Front matter uses the list form with `example:` on one line and `- *content` on the next", + "Body contains a csharp or cs fenced code block", + "Body does NOT contain a `### Examples` or `## Example` heading", + "Validator runs and does not emit EXAMPLE_MISSING for the target type", + "Agent recognizes both inline and list `example:` forms as equivalent for validation purposes" + ] + }, + { + "id": 37, + "prompt": "Create a DocFX overwrite file for a namespace overview page using `summary: *content` front matter. The body should embed a usage example under a `### Example` heading followed by a csharp fence. Confirm that the validator accepts this as a complete example.", + "expected_output": "The agent writes the overwrite file with `summary: *content` front matter and a `### Example` heading with a csharp fence inside the body. The validator runs and does not emit EXAMPLE_MISSING, because the heading-delimited fence satisfies the Form B detection rule.", + "expectations": [ + "Front matter uses `summary: *content`", + "Body contains a `### Example` or `## Example` heading followed by a csharp or cs fenced code block", + "Validator runs and does not emit EXAMPLE_MISSING for the target", + "Agent correctly identifies this as the Form B (summary-anchored conceptual) pattern", + "Agent notes that this form is for conceptual content and is not the recommended form for type pages" + ] + }, + { + "id": 38, + "prompt": "A developer created a DocFX overwrite for `Acme.Widgets.Spinner` using `example: *content` front matter but accidentally added a `### Examples` heading before the csharp fence. Confirm that the validator still passes (the redundant heading is tolerated by the validator) and that the prose guidance advises removing it to prevent a duplicate heading on the rendered page.", + "expected_output": "The validator runs and does not emit EXAMPLE_MISSING because the csharp fence is present regardless of the redundant heading. The agent flags the redundant heading as producing a duplicate 'Examples' section on the rendered DocFX page and advises removing it, citing the Form A guidance. The validator result is a pass; the rendered-page duplication is a separate documentation quality concern.", + "expectations": [ + "Validator does not emit EXAMPLE_MISSING because a csharp fence is present", + "Agent identifies the `### Examples` heading as redundant for Form A (example: *content) overwrites", + "Agent explains that DocFX adds the section header automatically, so the manual heading causes a duplicate on the rendered page", + "Agent recommends removing the heading to avoid the duplicate-heading rendering defect", + "Validator exit code is 0 (or non-EXAMPLE_MISSING failure) — the redundant heading does not itself cause a validation error" + ] + }, + { + "id": 39, + "prompt": "A DocFX overwrite file for `Acme.Widgets.Spinner` uses `example: *content` front matter but the body contains only descriptive prose with no csharp fence at all. Confirm that the validator reports EXAMPLE_MISSING.", + "expected_output": "The validator detects that the section has `example: *content` front matter (MappedToExample=true) but no csharp or cs fenced code block in the body. It emits an EXAMPLE_MISSING diagnostic for `Acme.Widgets.Spinner`. The absence of a heading alone does not satisfy the example requirement; a csharp fence is required regardless of the form.", + "expectations": [ + "Validator emits EXAMPLE_MISSING for the target type", + "Diagnostic message identifies the expected overwrite path and instructs adding a C# code fence", + "Agent recognizes that the YAML anchor alone (example: *content) is not sufficient — a csharp fence must also be present", + "Agent does not suggest adding a ### Examples heading as the fix; it correctly identifies the missing fence as the root cause", + "Validator returns a non-zero exit code" + ] + }, + { + "id": 40, + "prompt": "A DocFX overwrite file for `Acme.Widgets.Spinner` contains the following csharp fence that uses only top-level statements:\n```csharp\nusing Acme.Widgets;\nvar spinner = new Spinner();\nspinner.Start();\n```\nRun scripts/docfx.cs validation and confirm the validator rejects this example.", + "expected_output": "The validator emits SAMPLE_STRUCTURE_INVALID for the top-level statement example because it lacks a namespace declaration and a type declaration. The exit code is non-zero. The diagnostic message instructs adding a file-scoped namespace and a class wrapper, or labelling the example '// Program.cs' if top-level statements are intentional.", + "expectations": [ + "Validator emits SAMPLE_STRUCTURE_INVALID for the csharp fence that uses only top-level statements", + "Diagnostic message instructs adding a file-scoped namespace declaration (e.g., 'namespace X.Y;')", + "Diagnostic message instructs wrapping usage code in a class declaration", + "Validator returns a non-zero exit code", + "Validator does not attempt compilation for the structurally invalid example" + ] + }, + { + "id": 41, + "prompt": "A DocFX overwrite file for `Acme.Widgets.Spinner` contains the following csharp fence that is labelled '// Program.cs' and uses top-level statements:\n```csharp\n// Program.cs\nusing Acme.Widgets;\nvar spinner = new Spinner();\nspinner.Start();\n```\nRun scripts/docfx.cs validation and confirm the validator allows this example.", + "expected_output": "The validator recognises the '// Program.cs' label and does not emit SAMPLE_STRUCTURE_INVALID. It compiles the example as a file-based app instead. Any compile errors are still reported as SAMPLE_COMPILE_FAILED.", + "expectations": [ + "Validator does not emit SAMPLE_STRUCTURE_INVALID for the example labelled '// Program.cs'", + "Validator attempts compilation as a file-based app rather than a class library", + "Structural gate is bypassed for the // Program.cs label only", + "Compile errors in the labelled example are still reported as SAMPLE_COMPILE_FAILED" + ] + }, + { + "id": 42, + "prompt": "Use dotnet-docfx-digest to generate an example for a public concrete class `Acme.Core.Options`. Confirm the generated example includes a file-scoped namespace, a class declaration, all required using directives, and compiles as a class library.", + "expected_output": "The generated csharp code block begins with using directives, then a file-scoped namespace declaration, then a class containing the usage code. The validator compiles it as a class library project referencing the documented assemblies. No SAMPLE_STRUCTURE_INVALID or SAMPLE_COMPILE_FAILED diagnostic is emitted.", + "expectations": [ + "Generated example contains a 'using Acme.Core;' directive (or equivalent)", + "Generated example contains a file-scoped namespace declaration such as 'namespace AcmeExample;'", + "Generated example contains at least one class declaration wrapping the usage code", + "Generated example does not use top-level statements", + "Validator compiles the example as a class library project and emits no SAMPLE_STRUCTURE_INVALID or SAMPLE_COMPILE_FAILED diagnostic" + ] + }, + { + "id": 43, + "prompt": "Use dotnet-docfx-digest to generate an example for a generic public type `Acme.Core.Repository`. Confirm the generated example supplies a concrete type argument and compiles.", + "expected_output": "The generated example instantiates Repository with a concrete type argument (e.g., Repository), not the open generic Repository. The example includes a namespace and class declaration. The validator compiles it without errors.", + "expectations": [ + "Generated example provides a concrete type argument for Repository (e.g., Repository or Repository)", + "Generated example does not reference the open generic form Repository as a concrete instantiation", + "Generated example includes a file-scoped namespace and class declaration", + "Validator compiles the example and emits no SAMPLE_STRUCTURE_INVALID or SAMPLE_COMPILE_FAILED diagnostic" + ] + }, + { + "id": 44, + "prompt": "Use dotnet-docfx-digest on a library that has a public abstract generic base class `ApplicationTest`. A previous run generated an example that derives from `ApplicationTest` (missing both generic arguments). Repair the documentation.", + "expected_output": "The agent recognises that ApplicationTest requires two generic type arguments. It either generates a valid concrete derived class supplying both arguments (e.g., `public class MyAppTest : ApplicationTest`), or omits the example entirely with an omission comment. The validator does not emit SAMPLE_COMPILE_FAILED after the repair. No example is written that derives from ApplicationTest without generic arguments.", + "expectations": [ + "Removes or repairs the example that derives from ApplicationTest without generic arguments", + "If an example is generated, it provides concrete values for both TEntryPoint and T", + "If no compile-valid example can be generated for the abstract type, the overwrite file omits the example and contains an omission comment", + "Validator emits no SAMPLE_COMPILE_FAILED after the repair", + "Agent explains that abstract generic base types require concrete type arguments in all derived-class examples" + ] + }, + { + "id": 45, + "prompt": "Use dotnet-docfx-digest on a library where the public type `Acme.Http.Sender` has a constructor requiring two interface dependencies `ITransport` and `ILogger` that are not publicly constructible. No tests or samples exist for this type. Confirm the skill omits the example rather than inventing plausible but non-compiling code.", + "expected_output": "The agent does not generate a csharp code block that invents implementations of ITransport or ILogger that do not exist in the library. Instead, it omits the example for Acme.Http.Sender and adds the deterministic omission comment '' to the overwrite file. It reports the omission as part of the example inventory.", + "expectations": [ + "Does not write a csharp fence that invents ITransport or ILogger implementations not present in the documented API", + "Adds the omission comment to the type overwrite file instead of writing an unverified code block", + "Reports the omission in the example inventory summary", + "Does not emit a csharp fence that would fail SAMPLE_COMPILE_FAILED or SAMPLE_STRUCTURE_INVALID", + "Explains that the example was omitted because no compile-valid example could be derived from source evidence" + ] + }, + { + "id": 46, + "prompt": "Run scripts/docfx.cs validation on a repository where an existing overwrite file has a correctly structured csharp example with a namespace and class declaration. Confirm the validator compiles it as a class library project, not as a file-based app.", + "expected_output": "The validator detects that the csharp sample has a namespace and class declaration, compiles it as a class library project (SampleVerification.csproj with OutputType=Library) referencing the documented assemblies from docfx.json, and reports SamplesCompiled incremented. No SAMPLE_STRUCTURE_INVALID is emitted.", + "expectations": [ + "Validator does not emit SAMPLE_STRUCTURE_INVALID for the class-based example", + "Validator compiles the example as a class library project referencing library assemblies from docfx.json", + "Validator does not require a top-level statement or Main method in the example", + "Validator reports the sample as compiled (SamplesCompiled incremented in summary)", + "Validator does not emit SAMPLE_COMPILE_FAILED when the example is structurally and semantically correct" + ] + }, + { + "id": 47, + "prompt": "Use dotnet-docfx-digest to generate a type example for a static extension class `Acme.Core.StringExtensions` that exposes a generic extension method `Parse(this string input)`. Confirm the generated example shows a valid string receiver, supplies a concrete type argument, includes namespace and class structure, and compiles.", + "expected_output": "The generated example calls the extension method on a string receiver with a concrete type argument (e.g., '42'.Parse() or var s = '3.14'; s.Parse()). The example has a file-scoped namespace and a class declaration. The validator compiles it without SAMPLE_STRUCTURE_INVALID or SAMPLE_COMPILE_FAILED.", + "expectations": [ + "Generated example calls Parse with a concrete type argument (e.g., Parse or Parse)", + "Generated example uses a valid string receiver (string literal or string variable)", + "Generated example includes a file-scoped namespace and a class declaration", + "Validator emits no SAMPLE_STRUCTURE_INVALID or SAMPLE_COMPILE_FAILED for the example", + "Generated example does not use the open generic form Parse without a concrete type binding" + ] + }, + { + "id": 48, + "prompt": "Run dotnet-docfx-digest twice on a repository where the first run generated structurally valid, compile-passing class-based examples. Confirm the second run emits no SAMPLE_STRUCTURE_INVALID, no SAMPLE_COMPILE_FAILED, and makes no changes to existing example overwrite files.", + "expected_output": "The second run validates all existing csharp code blocks, finds them structurally valid and compile-passing, and reports SamplesCompiled with zero errors. No overwrite files are modified. The validator exits with status 'passed'.", + "expectations": [ + "Second run emits no SAMPLE_STRUCTURE_INVALID diagnostics", + "Second run emits no SAMPLE_COMPILE_FAILED diagnostics", + "Second run does not modify existing example overwrite files", + "Second run reports validation passed with zero errors", + "Example validation is deterministic: the same csharp content produces the same validation result on repeated runs" + ] + }, + { + "id": 49, + "prompt": "Run dotnet-docfx-digest on a library where a documented public class `Acme.Console.AppHost` derives from `Codebelt.Bootstrapper.Console.ConsoleProgram` and its example calls a DI helper `services.AddHostedService()` that requires `Microsoft.Extensions.DependencyInjection.Abstractions`. The example does not contain a `dotnet-docfx-digest:skip-compile` marker. Confirm the sample compiles without errors.", + "expected_output": "The validator compiles the example without SAMPLE_COMPILE_FAILED. The worker project references the documented library project via ProjectReference, so NuGet restores the full transitive closure including `Codebelt.Bootstrapper.Console` and `Microsoft.Extensions.DependencyInjection.Abstractions`. No skip marker is needed or present.", + "expectations": [ + "Validator compiles the example without SAMPLE_COMPILE_FAILED", + "No SAMPLE_SKIP_REASON_INSUFFICIENT or SAMPLE_SKIP_REASON_MISSING is emitted", + "Worker project uses ProjectReference so transitive NuGet dependencies such as Microsoft.Extensions.DependencyInjection.Abstractions are available at compile time", + "No dotnet-docfx-digest:skip-compile marker is required to compile an example that uses types from transitive NuGet dependencies", + "Validator exits with status passed when the only samples are this class-based DI registration example" + ] + }, + { + "id": 50, + "prompt": "Run dotnet-docfx-digest on a repository where one csharp documentation sample contains the comment `// dotnet-docfx-digest:skip-compile - sample worker does not include that assembly`. Confirm the validator reports SAMPLE_SKIP_REASON_INSUFFICIENT.", + "expected_output": "The validator detects the skip-compile marker with the reason 'sample worker does not include that assembly' and emits SAMPLE_SKIP_REASON_INSUFFICIENT. The diagnostic message explains that missing assembly references are a validator defect, not a valid blocker. The exit code is non-zero.", + "expectations": [ + "Validator emits SAMPLE_SKIP_REASON_INSUFFICIENT for the fence containing 'sample worker does not include that assembly'", + "Diagnostic message explains that missing compile-time assembly references are not a valid skip reason", + "Validator returns a non-zero exit code", + "No SAMPLE_COMPILE_FAILED is emitted because the sample is rejected at the skip-reason gate, not attempted for compilation", + "Diagnostic points to the file and fence index of the offending skip marker" + ] + }, + { + "id": 51, + "prompt": "Use dotnet-docfx-digest on a BenchmarkDotNet-style library that ships NuGet packages `Codebelt.Extensions.BenchmarkDotNet` and `Codebelt.Extensions.BenchmarkDotNet.Console`. The validator reports missing type examples for `BenchmarkWorkspace`, `BenchmarkWorkspaceOptions`, `BenchmarkWorkspaceOptionsExtensions`, `ServiceCollectionExtensions`, `BenchmarkContext`, and `BenchmarkProgram`. Existing generated examples compile but are thin: they use `MyNamespace`, `Consumer`, isolated constructors, and unused locals. Improve the type-specific DocFX samples so they fit real consumer context.", + "expected_output": "The agent identifies the package IDs from project/package metadata, searches local evidence by `Codebelt.Extensions.BenchmarkDotNet` and `Codebelt.Extensions.BenchmarkDotNet.Console` before type-only searches, uses package README, tooling/tuning projects, functional tests, and available GitHub/package-ID usage as source evidence, and rewrites type-page examples as compact scenario examples. The examples may include multiple related public types when needed, such as `BenchmarkProgram.Run`, `BenchmarkWorkspaceOptions.Slim`, `ConfigureBenchmarkDotNet`, `BenchmarkContext`, `IBenchmarkWorkspace`, and dependency-injection registration, while remaining compile-valid. The agent avoids placeholder-only `Consumer`/`MyNamespace` shells, unused locals, raw test assertions, and isolated constructor smoke tests, updates the example inventory with source evidence and scenario, then reruns `docfx.cs --json` and `--verify-docfx-build` before claiming completion.", + "expectations": [ + "Determines and searches for the exact package IDs `Codebelt.Extensions.BenchmarkDotNet` and `Codebelt.Extensions.BenchmarkDotNet.Console` before relying on type/member-only searches", + "Inspects package-level local evidence such as `.nuget/*/README.md`, README content, tooling runner programs, tuning projects, functional tests, or package documentation pages", + "Uses external GitHub/package-ID search when available and treats self-repository hits as lower-priority package-authored evidence rather than independent consumer proof", + "Creates scenario examples that explain a real workflow, such as configuring a benchmark runner, registering a workspace through DI, applying BenchmarkDotNet jobs, carrying command-line context, or post-processing artifacts", + "Allows a type-page example to include multiple related public types when that is the clearest way to show real usage", + "Avoids generic `MyNamespace` and `Consumer` wrappers when a domain-specific namespace or class name is obvious", + "Avoids unused locals and examples that only instantiate a type without showing a meaningful next step or result", + "Keeps every changed csharp example structurally valid and compile-verified through `docfx.cs`", + "Updates the example inventory with UID, required file, source evidence, chosen scenario, and final status" + ] + }, + { + "id": 52, + "prompt": "Run `scripts/docfx.cs --validate-samples --json` on a repository with at least 20 C# documentation fences spread across three dependency sets. Confirm that every sample remains compilation-isolated, but validation no longer launches one restore and one build per sample.", + "expected_output": "The validator creates one temporary project per sample, adds all sample projects to one temporary `.slnx`, and performs one bounded-parallel graph build. JSON reports all compile-passing samples, `summary.processes.dotnet` is 1 for sample-only validation, and the sample-validation phase detail reports one batch plus the sample and reference-set counts. A failing sample still produces SAMPLE_COMPILE_FAILED for its original Markdown file and fence without contaminating other sample results.", + "expectations": [ + "Creates a separate temporary project for every compilable C# documentation fence", + "Builds all temporary sample projects through one `.slnx` graph build instead of one dotnet build per sample", + "Uses `--sample-parallelism` or `DOCFX_DIGEST_SAMPLE_PARALLELISM` as the bounded MSBuild maximum node count", + "Reports `summary.processes.dotnet` as 1 when `--validate-samples` is the only build-backed option", + "Preserves per-sample SAMPLE_COMPILE_FAILED diagnostics with the original Markdown file and fence index", + "Reports sample-validation phase detail containing `1 batch` and the sample count" + ] + }, + { + "id": 53, + "prompt": "Use dotnet-docfx-digest for a repo-wide audit. The previous agent added 8 missing namespace pages and only 1 type overwrite page, then stopped after the build-backed validator reported 62 EXTENSION_SECTION_MISSING, 1228 EXAMPLE_MISSING, and 1 DOCFX_BUILD_FAILED diagnostic. It called those findings pre-existing documentation gaps. `dotnet build` passes, while `dotnet test` fails only because an integration test cannot connect to SQL Server. Inspect the untracked DocFX work and finish the full digest.", + "expected_output": "The agent identifies the existing work as a partial digest, preserves it, and treats all 1291 validator errors as the active repo-wide repair queue rather than as pre-existing blockers. It uses the assessment work queue and example inventory to continue across every affected namespace, extension section, concrete type, and extension method. The unrelated SQL Server test failure is reported separately and does not end documentation work. The agent reruns fast validation during repair and treats a clean fast result as verification-required, then runs the build-backed command at the end. It does not claim completion until JSON reports summary.canClaimCompletion=true, summary.remainingWorkItems=0, empty summary.remainingGates and summary.remainingDiagnosticsByCode collections, and the build-backed command exits 0.", + "expectations": [ + "Inspects and preserves the 8 untracked namespace pages, 1 untracked type page, and other existing documentation edits instead of discarding or overwriting them wholesale", + "Explicitly identifies the prior output as partial because 62 extension-section, 1228 example, and 1 DocFX-build diagnostics remain", + "Does not describe pre-existing diagnostics, diagnostic volume, or the size of the work queue as a blocker", + "Does not stop with a progress summary or ask the user whether to continue while repairable diagnostics remain", + "Uses the deterministic assessment work queue and complete validator queue to continue repairing every missing extension section and example across the affected documentation surfaces", + "Reports the SQL Server integration-test failure separately and continues DocFX repair because the failure does not prevent documentation validation or source inspection", + "Reruns the fast validator after batches of edits instead of stopping after the first namespace or type subset", + "Treats fast validation as an iteration checkpoint and still requires the final build-backed command before completion", + "Runs the final build-backed command with --build-api-model --validate-samples --verify-docfx-build", + "Does not claim a full digest until summary.canClaimCompletion is true, summary.remainingWorkItems is 0, summary.remainingGates and summary.remainingDiagnosticsByCode are empty, and the final command exits 0" + ] + }, + { + "id": 54, + "prompt": "Run dotnet-docfx-digest on a repository whose DocFX overwrite Markdown is valid UTF-8 without BOM. The files contain the ⬇️ extension-table marker and have no mojibake. Do not make unrelated documentation changes.", + "expected_output": "The validator accepts BOM-less UTF-8 without prescribing an ENCODING_BOM_MISSING repair or rewriting files only to add a BOM. It continues to distinguish intact extension-table markers from actual encoding corruption. The agent preserves existing BOM and line-ending state, and git diff contains no encoding-only changes.", + "expectations": [ + "Treats valid BOM-less UTF-8 as compliant and prescribes no missing-BOM repair", + "Does not add a UTF-8 BOM or normalize line endings solely as part of the DocFX audit", + "Preserves the literal ⬇️ marker and distinguishes intact content from actual encoding corruption", + "Does not treat BOM presence as documentation work or a completion requirement", + "Leaves git diff free of BOM-only and line-ending-only changes" + ] + }, + { + "id": 55, + "prompt": "Run the final dotnet-docfx-digest verification on a machine where Environment.ProcessorCount is 24 and GC.GetGCMemoryInfo().TotalAvailableMemoryBytes is 128 GiB. The agent host previously killed the command after 10 minutes before the validator could report a DocFX timeout. Confirm the adaptive scheduling and timeout behavior.", + "expected_output": "Auto selects the high-capacity profile because the process has more than 8 available logical processors and more than 32 GiB available memory. DocFX verification runs concurrently in its isolated temp copy while the primary lane builds/discovers API and then compiles samples. Build and sample parallelism default to 12 workers (half of 24, capped below 16). Child-process timeout is 30 minutes by default, and the outer tool timeout is set to at least 35 minutes. JSON exposes the selected execution settings and phase timing. The sample phase is not started before API discovery because scoped references depend on the namespace-to-project map.", + "expectations": [ + "Selects high-capacity automatically for 24 available logical processors and 128 GiB available memory", + "Starts isolated DocFX verification concurrently with the primary API/sample lane", + "Keeps sample compilation after API discovery because scoped sample references depend on the namespace-to-project map", + "Uses an adaptive default of 12 MSBuild workers for both documented-project and sample graph builds on this machine", + "Uses a 30-minute child-process timeout and requires an outer command timeout of at least 35 minutes", + "Reports profile, processors, memory, worker counts, timeout, concurrency choice, process counts, and phase timings in JSON", + "Allows explicit conservative/high-capacity, worker-count, and timeout overrides through CLI or environment variables" + ] + }, + { + "id": 56, + "prompt": "Run final dotnet-docfx-digest verification in --json mode on a repository where API build, sample compilation, and DocFX build each take several minutes. The previous command appeared frozen because it emitted no progress until completion. Keep the machine-readable report parseable while giving me enough live information to decide whether a child process is progressing or stale.", + "expected_output": "Long-running API build, sample compilation, and DocFX verification write append-only progress to stderr without mixing progress text into JSON stdout. Each child emits an initial [ ] event, a heartbeat every 10 seconds, and a final green [✓] success or [x] failure event. Heartbeats identify the phase, workload size, runner count, PID, elapsed time, time since the child last produced output, and the latest non-empty child-output line when available. Redirected logs remain readable without ANSI dependence, and stdout still parses as exactly one JSON report.", + "expectations": [ + "Writes long-running child-process progress to stderr so --json stdout remains a single parseable report", + "Emits a start event, 10-second heartbeat events, and a final success or failure event for API build, sample compilation, and DocFX verification", + "Reports the active phase, project or sample workload, runner count, child PID, and elapsed time", + "Reports time since the child last produced output so a quiet process can be distinguished from a stale process", + "Includes the latest non-empty child-output line when available to show what is currently being processed", + "Uses a green check marker for interactive success while keeping redirected output readable without requiring ANSI color support", + "Does not use terminal cursor rewriting or an in-place table that becomes unreadable in CI logs" + ] + }, + { + "id": 57, + "prompt": "Audit a prior dotnet-docfx-digest run that created hundreds of compile-valid overwrite files. Nearly every type example calls `Type.GetType(\"Namespace.Type, Assembly\")` from a class named `DocumentedTypeExample`; extension files use `DocumentedExtensionExample.Describe()`, mention the method only in prose or string literals, and repeat the same UID in multiple `example: *content` sections. The namespace pages mostly say that the namespace contains types or extension methods. Repair the skill-driven output rather than accepting it because it compiles.", + "expected_output": "The agent identifies the output as metadata scaffolding rather than API documentation, inventories and preserves the existing work, and uses validator diagnostics to replace it systematically. Reflection-only examples produce EXAMPLE_REFLECTION_ONLY, generic generated scaffolds produce EXAMPLE_PLACEHOLDER, repeated mappings produce EXAMPLE_UID_DUPLICATE, type examples that never use the target produce EXAMPLE_TARGET_NOT_USED, and extension examples that never invoke the method in C# produce EXTENSION_EXAMPLE_NOT_INVOKED. Inventory-only namespace prose produces the namespace prose/usage/start-here diagnostics. The agent derives replacement scenarios from exact tests, package READMEs, samples, XML comments, or source paths, records that evidence and consumer task in the inventory, reruns validation in batches, and does not claim completion while any quality diagnostic remains.", + "expectations": [ + "Does not accept compilation as proof that reflection or metadata lookup is a useful API example", + "Rejects Type.GetType, assembly metadata lookup, DocumentedTypeExample, DocumentedExtensionExample, and generic Describe helpers as final examples", + "Requires the documented type to be used inside the C# fence and the documented extension method to be invoked inside the C# fence", + "Rejects repeated example mappings for the same UID instead of preserving duplicate generated sections", + "Treats inventory-only namespace blurbs as unfinished and adds problem/outcome, when-to-use, and start-here guidance", + "Records exact source evidence paths and a consumer task for each repair batch", + "Reruns the validator until EXAMPLE_REFLECTION_ONLY, EXAMPLE_PLACEHOLDER, EXAMPLE_UID_DUPLICATE, EXAMPLE_TARGET_NOT_USED, EXTENSION_EXAMPLE_NOT_INVOKED, and namespace quality diagnostics are gone" + ] + }, + { + "id": 58, + "prompt": "Document a namespace `Acme.Text` with `TextOptions` and `Normalize(this string value)`. Tests show normalization before identifier comparison, and the package README configures `TextOptions` for imported records. Write the namespace overview and examples with dotnet-docfx-digest.", + "expected_output": "The namespace overview leads with the text-ingress problem and stable comparison/storage outcome, explains when to use the namespace, and directs newcomers to TextOptions for import policy and Normalize for boundary cleanup. The inventory cites the exact test and package README paths and names the consumer task. The TextOptions type example configures options as part of an import workflow and shows the next action or result. The extension example invokes Normalize in C# on a realistic receiver before comparison or storage. No reflection, metadata-only lookup, generic Consumer/MyNamespace shell, duplicate UID section, invented member, or prose-only method mention appears. Fast semantic validation and build-backed sample verification both pass before completion.", + "expectations": [ + "Writes namespace prose around a developer problem and outcome rather than listing contained types", + "Explains when to use Acme.Text and names TextOptions and Normalize as distinct starting points", + "Cites exact test and package README evidence paths in the example inventory", + "Shows TextOptions in a coherent import configuration workflow with a visible next action or result", + "Invokes Normalize inside the C# fence on a realistic string receiver", + "Avoids reflection, metadata-only examples, generic wrappers, duplicate UID mappings, and invented API members", + "Runs semantic validation and sample compilation before claiming completion" + ] + }, + { + "id": 59, + "prompt": "Use dotnet-docfx-digest in dry-run mode for my multi-project library. The DocFX config has two metadata destinations (api/core and api/net).", + "expected_output": "The agent runs docfx.cs with --dry-run --build-api-model --project-manifest (no invented project hints), reports the seed, and authors one clean selected project from each metadata destination group. It completes the generated review JSON for every changed page, then resumes with --review-report --build-api-model --validate-samples --verify-docfx-build until dry-run-passed and reports the same page-level review rather than repository completion.", + "expectations": [ + "Runs docfx.cs --dry-run --build-api-model --project-manifest without inventing project hints the user did not give", + "Selects one clean project from each metadata destination group, reports the seed, and actually authors their namespace/type documentation", + "Completes the generated review report and resumes the same manifest with --review-report --build-api-model --validate-samples --verify-docfx-build until dry-run-passed", + "Reports a Changed-page review row for every authored page with evidence, page-specific purpose/outcome, observable example result, and sibling-pattern comparison without claiming repository-wide completion" + ] + }, + { + "id": 60, + "prompt": "Run dotnet-docfx-digest in dry-run mode for Cuemon.Core and src/Cuemon.Net/Cuemon.Net.csproj specifically.", + "expected_output": "The agent resolves both explicit hints (by assembly/package name and by project path), persists exactly those two selected packets, authors both, and resumes the manifest through build-backed discovery, sample compilation, and DocFX verification. Explicit hints override automatic selection; the run remains scoped and never claims repository completion.", + "expectations": [ + "Resolves both explicit --project hints, including the path-form hint, to exactly one project each", + "Persists and authors only the two named packets, overriding automatic selection", + "Completes the generated review report, resumes with --review-report, and passes build-backed discovery, sample compilation, DocFX verification, and page-level review", + "Does not claim repository-wide completion from the selected subset" + ] + }, + { + "id": 61, + "prompt": "Use dotnet-docfx-digest in dry-run mode for `Common`, but I have two projects whose file names both resolve to Common.", + "expected_output": "The agent surfaces PROJECT_HINT_AMBIGUOUS with the candidate project paths and stops before editing, asking the user to disambiguate with a more specific path, assembly name, or package id instead of guessing.", + "expectations": [ + "Surfaces PROJECT_HINT_AMBIGUOUS with the candidate matches before any editing", + "Does not guess or edit either candidate", + "Asks for a more specific hint (path, assembly, or package id)" + ] + }, + { + "id": 62, + "prompt": "Run a dry-run DocFX digest. One project in a destination group already has uncommitted changes to its source and namespace page.", + "expected_output": "The agent's dry run skips the dirty project, selects another clean project from the same metadata group, and never edits the dirty project's related files. If a group has no clean candidate it reports DRY_RUN_GROUP_UNSELECTED for that group and makes no edits there.", + "expectations": [ + "Skips the dirty candidate and selects a clean project from the same group", + "Never edits files that were already staged, modified, renamed, deleted, or untracked", + "Reports DRY_RUN_GROUP_UNSELECTED when a group has no clean project" + ] + }, + { + "id": 63, + "prompt": "Document the `Cuemon.Collections` namespace which has a MutableTuple through MutableTuple generic-arity family plus a few unrelated types, using dotnet-docfx-digest.", + "expected_output": "The agent declares a narrow family exemption in .docfx/family-exemptions.json for the MutableTuple arity series with rationale generic-arity, writes one strong anchor example for MutableTuple, and a namespace page that names the anchor and explains how arity distinguishes the siblings. Covered siblings get purpose-first prose but not redundant standalone examples. Unrelated types still get their own examples.", + "expectations": [ + "Declares a family exemption only for the coherent arity series, not the unrelated types", + "Provides one validated anchor example and deep namespace guidance that names the anchor and explains sibling selection", + "Gives covered siblings purpose-first prose without redundant standalone examples", + "Still requires standalone examples for the unrelated types" + ] + }, + { + "id": 64, + "prompt": "I want to exempt my `Acme.Options` exceptions, options objects, and a delegate from needing examples by grouping them as one family. Set that up with dotnet-docfx-digest.", + "expected_output": "The agent refuses to create a blanket family exemption for unrelated difficult types. It explains that category alone (exceptions, options, delegates, records, data carriers) never qualifies, that a family must be a coherent generic-arity/inherited/overload/type-parameter series, and that such a declaration would fail validation with FAMILY_EXEMPTION_INVALID. It documents the types with real examples instead.", + "expectations": [ + "Refuses the blanket exemption and explains category alone does not qualify", + "Notes the declaration would fail FAMILY_EXEMPTION_INVALID validation", + "Documents the types with real examples instead of exempting them" + ] + }, + { + "id": 65, + "prompt": "My namespace page for `Acme.Caching` opens with 'The Acme.Caching namespace contains types and helpers that enable caching.' and then has a separate 'Start with `MemoryCacheStore`' paragraph. Fix it with dotnet-docfx-digest.", + "expected_output": "The agent recognizes NAMESPACE_APPEND_ONLY_REPAIR: the weak inventory lead was left intact with guidance appended below. It rewrites the opening cohesively around the caching problem and outcome rather than keeping the inventory sentence and a tacked-on start-here line.", + "expectations": [ + "Rewrites the opening paragraph around the developer problem and outcome", + "Does not leave the inventory-led lead intact beneath an appended start-here sentence", + "Integrates the start-here guidance into cohesive prose" + ] + }, + { + "id": 66, + "prompt": "Run a full DocFX digest across all my project packets. One packet still has a difficult template-repetition diagnostic after the first rewrite.", + "expected_output": "The agent processes packets one at a time, debugs the difficult diagnostic using its complete UID/path set and validator normalization, continues independent packets instead of ending the full run, then returns to the failed packet and finishes with global verification. It never substitutes dry-run or a pilot for the requested full scope.", + "expectations": [ + "Processes packets one at a time with scoped quality gates", + "Investigates the diagnostic as repair work and continues independent packets rather than stopping the full run", + "Returns to every unresolved packet and completes global verification without selecting dry-run" + ] + }, + { + "id": 67, + "prompt": "Run the complete DocFX digest for my repository using all project packets and verify it.", + "expected_output": "The agent documents every eligible clean project packet, preserves dirty project documentation without overwriting it, and finishes with the global build-backed verification (--build-api-model --validate-samples --verify-docfx-build) so the deterministic completion contract (canClaimCompletion true, zero remaining work items and gates) is satisfied before claiming completion.", + "expectations": [ + "Documents all eligible clean packets and preserves dirty project work", + "Runs the global build-backed verification before claiming completion", + "Confirms the JSON completion contract (canClaimCompletion true, zero remaining work items/gates)" + ] + }, + { + "id": 68, + "prompt": "The fast docfx.cs run reports only one required example target for my Cuemon-style repo where namespaces put the opening brace on the next line. Document the repo with dotnet-docfx-digest.", + "expected_output": "The agent recognizes the source scanner is provisional (BUILD_BACKED_SCOPE_REQUIRED / API_MODEL_SOURCE_SCANNER_LIMITED) and runs --build-api-model to establish reflection-precise scope before authoring, rather than trusting the under-reported fast count. It documents the full discovered surface.", + "expectations": [ + "Recognizes the source-scan inventory as provisional and does not author from the under-reported count", + "Runs --build-api-model (or confirms DocFX YAML) before authoring scope", + "Documents the full reflection-backed surface, not just the single fast-reported target" + ] + }, + { + "id": 69, + "prompt": "My library has over 400 public types needing examples. Document it with dotnet-docfx-digest.", + "expected_output": "The agent treats the large target count as irrelevant to scope selection, keeps the requested full-repository scope, and processes all packets with bounded packet-local context and validation. It does not select dry-run, impose a target cap, or ask for pilot approval unless the user explicitly requested a dry run.", + "expectations": [ + "Keeps full-repository scope despite the large queue", + "Does not select dry-run or impose a one-packet/20-target pilot cap", + "Continues through all packets and runs global completion verification without an approval pause" + ] + }, + { + "id": 70, + "prompt": "Two of my assemblies both declare a public static `Extensions` class with extension methods in different namespaces. Document both with dotnet-docfx-digest.", + "expected_output": "The agent recognizes EXTENSION_OWNER_AMBIGUOUS (and any SYMBOL_COLLISION_UNRESOLVED for duplicate type names) and resolves ownership by assembly/project. It prefers receiver extension syntax in examples and targets the uniquely owned overwrite UID so each documented method is unambiguous.", + "expectations": [ + "Identifies the cross-assembly extension-container collision by owning assembly/project", + "Prefers receiver extension syntax over static-container qualification when names collide", + "Targets the uniquely owned overwrite UID for each method" + ] + }, + { + "id": 71, + "prompt": "My `Cuemon.Core` assembly forwards a generic type family to another assembly via [assembly: TypeForwardedTo]. Document the affected types with dotnet-docfx-digest.", + "expected_output": "The agent surfaces TYPE_FORWARDING_UNRESOLVED for forwarded types it cannot attribute, and resolves which project and UID documents the forwarded family before authoring. It does not silently document the forwarded family under the wrong assembly.", + "expectations": [ + "Surfaces unresolved type forwarding rather than mis-attributing the forwarded family", + "Resolves the documenting project and UID for the forwarded types before authoring", + "Records the forwarding source and destination relationship" + ] + }, + { + "id": 72, + "prompt": "Write the DocFX overwrite example for `Acme.Core.Widget` for me, and make sure it doesn't corrupt the file encoding.", + "expected_output": "The agent uses the safe structured overwrite writer (docfx.cs --write-overwrite) with an authored prose+fence request. The writer preserves the target file's BOM and line endings, validates balanced fences, and refuses duplicate UIDs or dirty-file replacement. The agent does not hand-assemble fenced Markdown through brittle byte/encoding operations.", + "expectations": [ + "Uses the structured overwrite writer rather than ad-hoc byte/encoding manipulation", + "Preserves BOM and line-ending state and validates the fence", + "Authors the prose and fence itself; the writer only validates and writes structured content" + ] + }, + { + "id": 73, + "prompt": "Do the dry-run DocFX pilot and tell me it's good to proceed.", + "expected_output": "Before declaring the pilot good, the agent proves the selected packets were actually authored and the persisted manifest was resumed through build-backed discovery, sample compilation, and DocFX verification. It manually reviews every changed namespace and type page for repeated sentence/code structures, reports the actual prose and examples, and asks the user to review representative output before a full run rather than asserting quality from selector counts.", + "expectations": [ + "Shows that selected packets produced real working-tree namespace/type documentation, a complete review report, and a resumed dry-run-passed result", + "Reports a complete Changed-page review table for the actual changed pages, not only the validator summary or a file list", + "Checks specifically for repeated sentence and code structures across the pilot", + "Presents representative output for human review before a full run" + ] + }, + { + "id": 74, + "prompt": "A prior dotnet-docfx-digest run put raw `uid:` / `example:` overwrite sections directly after `## Extension Members` inside `.docfx/api/namespaces/Acme.Extensions.Net.md`, so the namespace page now mixes overview content with extension-method examples. Repair the docs and keep the quality bar from the skill instructions.", + "expected_output": "Agent treats the namespace page as mixed-ownership documentation, surfaces or repairs the embedded-overwrite defect, keeps the namespace overview single-uid and namespace-scoped, moves the extension-method example mappings into readable type-targeted overwrite files under `.docfx/api/types/` (typically the declaring extension class page), reruns validation, and does not leave secondary `uid:` / `example:` blocks after the namespace overview.", + "expectations": [ + "Recognizes or surfaces the namespace page as invalid mixed namespace/type content rather than accepting the embedded overwrite sections", + "Keeps `.docfx/api/namespaces/Acme.Extensions.Net.md` limited to the namespace uid/summary, fly-in prose, availability, related links, and `Extension Members` table", + "Moves extension-method examples to readable type-targeted overwrite files under `.docfx/api/types/`, typically the declaring extension class page", + "Does not append secondary `uid:` / `example:` sections after `Extension Members` on the namespace page", + "Reruns scripts/docfx.cs --json and treats any remaining namespace-ownership or example diagnostic as blocking completion" + ] + }, + { + "id": 75, + "prompt": "Use dotnet-docfx-digest on a Cuemon-style repository. After your first repair batch, fast validation drops `EXTENSION_SECTION_MISSING` from 62 to 16 and clears `NAMESPACE_APPEND_ONLY_REPAIR`, but a deeper queue appears: `EXTENSION_METHOD_MISSING` jumps to 125 because the new `Extension Members` tables are incomplete. `EXAMPLE_MISSING` is still over 1,200.", + "expected_output": "The agent treats the newly surfaced `EXTENSION_METHOD_MISSING` findings as the next deterministic queue, keeps the original repo-wide scope, updates extension tables and required examples packet by packet, reruns fast validation between batches, and does not stop with a progress summary or a choice menu. It continues until the build-backed verification succeeds and the JSON completion contract is clean.", + "expectations": [ + "Recognizes the newly surfaced `EXTENSION_METHOD_MISSING` queue as progress rather than as a blocker or a reason to pause", + "Does not offer a continue/focus/verify menu or ask the user how to proceed while repairable diagnostics remain", + "Keeps the original full-repository scope instead of narrowing to a representative subset or dry run", + "Uses packeted batches plus fast reruns to repair incomplete extension tables and the remaining example inventory", + "Runs the final build-backed command with `--build-api-model --validate-samples --verify-docfx-build` and does not claim completion until summary.canClaimCompletion is true with no remaining work items, gates, or diagnostics" + ] + }, + { + "id": 76, + "prompt": "Use dotnet-docfx-digest on a Cuemon-style repository after several repair batches. All non-example diagnostics are gone, but `EXAMPLE_MISSING` is still 1086. A fast `--project-manifest` run returns unnamed packets with `projects: []` and `metadataGroup: unknown` because the scope is still source-scan provisional.", + "expected_output": "The agent treats the 1086 `EXAMPLE_MISSING` items as the active core work, not a checkpoint. It does not produce a completion report, next-step menu, or approval pause. Instead it reruns packet discovery with `--build-api-model --project-manifest`, continues authoring type and extension examples packet by packet from that reflection-backed manifest, and if the packet set is still unusable it falls back to sequential repair in assessment work queue or namespace order. It works the queue in small fix→rerun batches and delays final verification until the example queue is actually finished.", + "expectations": [ + "Does not treat an example-only queue or its size as a reason to stop, summarize, checkpoint, or ask the user how to proceed", + "Does not offer a continue/focus/dry-run/review menu while `EXAMPLE_MISSING` remains non-zero", + "Recognizes unnamed or zero-project fast-manifest packets as provisional source-scan output and reruns packet discovery with `--build-api-model --project-manifest`", + "If the build-backed packet set is still unusable, falls back to sequential repair in assessment work queue or namespace order instead of stopping", + "Uses a small fix → rerun micro-loop for examples rather than treating batch size as a planning blocker", + "Does not run a final completion report or completion-shaped verification pass while `EXAMPLE_MISSING` still remains", + "Continues example authoring and reserves `--build-api-model --validate-samples --verify-docfx-build` for the real end of the queue" + ] + } + ] +} diff --git a/skills/dotnet-docfx-digest/references/docfx-overwrite-files.md b/skills/dotnet-docfx-digest/references/docfx-overwrite-files.md new file mode 100644 index 0000000..282f7c4 --- /dev/null +++ b/skills/dotnet-docfx-digest/references/docfx-overwrite-files.md @@ -0,0 +1,115 @@ +# DocFX Overwrite Files Reference + +Use this reference when creating, auditing, or repairing DocFX overwrite files for .NET API documentation. + +Sources: + +- https://dotnet.github.io/docfx/tutorial/intro_overwrite_files.html +- https://dotnet.github.io/docfx/reference/docfx-json-reference.html#overwrite + +## Agent Summary + +DocFX treats generated API metadata and Markdown content as models. An overwrite file is a Markdown file that updates a model by matching its `uid`; this lets documentation add or replace properties such as `summary`, `remarks`, `example`, conceptual content, and namespace-level guidance without editing generated metadata. + +Every overwrite section starts with YAML front matter delimited by `---`. The front matter must include `uid`, and the value must match the generated model UID. Do not guess UIDs. Verify them from generated metadata, existing API pages, source conventions, DocFX output, or `docfx build --exportRawModel`. + +The `*content` anchor maps the Markdown body following the YAML header into a chosen model property. For this skill, namespace overview pages normally use: + +```markdown +--- +uid: X.Y.Z +summary: *content +--- +The `X.Y.Z` namespace contains types that ... +``` + +If `*content` is not used, DocFX assigns the Markdown body to the `conceptual` property. **Do not rely on this default for managed reference (API) pages.** When `conceptual` is set on a managed reference page, some DocFX templates suppress the auto-generated member tables (constructors, methods, properties), leaving only the custom content visible. Always use an explicit property mapping. + +For **type-page and extension-method examples**, use the `example` array property instead of `summary` on a type-targeted overwrite file, usually the declaring extension class page under `.docfx/api/types/`: + +```markdown +--- +uid: X.Y.Z.MyType +example: +- *content +--- +The following example shows how to use `MyType`. + +```csharp +using X.Y.Z; + +var value = new MyType(); +Console.WriteLine(value); +``` +``` + +`example: - *content` maps the Markdown body to the first slot of the `example` string array. DocFX renders this as the "Examples" section on the type page **alongside** the auto-generated constructors, methods, and other members — it does not replace them. The `example` property has **Replace** overwrite behavior, so setting it via an overwrite replaces any example already present in generated metadata. + +Do **not** include a `### Examples` heading in the body. DocFX adds the section header automatically from the template. + +> The validator distinguishes two example forms by the front matter, not by headings in the body. Do not rely on a body heading to make the validator happy. +> +> **Form A — front matter `example: *content` (or the `- *content` list form).** This is the recommended form for type pages and extension-class pages. The body must contain at least one fenced `csharp` (or `cs`) block. Do **not** add a `## Example` or `### Example` heading; DocFX renders the section header automatically and a manual heading produces a duplicate "Examples" heading on the rendered page. +> +> **Form B — front matter `summary: *content`.** The body must contain a `## Example` or `### Example` heading followed by a fenced `csharp` (or `cs`) block. This form is only for the rare case where the example is embedded inside conceptual content. +> +> The validator recognizes Form A by the YAML anchor, not by a body heading; Form B by the body heading. Mixing them produces duplicate sections or validator failures. + +Do **not** use `summary: *content` for type example files. That replaces only the summary text and does nothing to add a visible Examples section to the page. + +DocFX applies overwrite models by `uid`. If the same `uid` appears more than once in one overwrite file, later sections in that same file override earlier sections. Across different overwrite files, ordering is not deterministic, so keep competing sections for the same `uid` together or consolidate them. + +Namespace overview files are a deliberate exception to "multiple sections can work." Keep `.docfx/api/namespaces/{Namespace}.md` single-UID and namespace-scoped. Do not append secondary `uid:` / `example:` mappings there, even for extension methods; move those examples to readable type-targeted files under `.docfx/api/types/`, typically the declaring extension class page. + +## Safe structured overwrite writer + +For repeatable overwrite creation, prefer `docfx.cs --write-overwrite ` over hand-assembling fenced Markdown with ad-hoc scripts. The request is JSON with `file`, `uid`, `mapping` (`example`, `summary`, or `remarks`), optional `prose`, and optional `fence`. The writer validates the YAML and balanced fences, refuses duplicate UIDs in the same file (`OVERWRITE_UID_DUPLICATE`), refuses unbalanced fences (`OVERWRITE_FENCE_UNBALANCED`), refuses to replace a file that already had uncommitted changes (`OVERWRITE_DIRTY_REFUSED`), preserves the target file's existing BOM and line endings, and prints a change preview. It writes only structured content you already authored — it never generates prose, selects members, or synthesizes examples. Normal surgical edits may still use your editor; the writer exists for repeatable, encoding-safe overwrite creation. + +## Family exemptions + +A coherent type series whose members differ primarily by generic arity, inherited specialization, overload shape, or repeated type-parameter combinations may replace redundant per-type examples with one anchor example plus deep namespace guidance. Declare these explicitly in `.docfx/family-exemptions.json` so the policy is reviewable and validator-checkable: + +```json +{ + "families": [ + { + "familyId": "tuple-arity", + "namespaceUid": "Cuemon.Collections", + "anchorUid": "Cuemon.Collections.MutableTuple`1", + "anchorExampleFile": ".docfx/api/types/Cuemon.Collections.MutableTuple`1.md", + "rationale": "generic-arity", + "coveredUids": ["Cuemon.Collections.MutableTuple`2", "Cuemon.Collections.MutableTuple`3"] + } + ] +} +``` + +`rationale` must be one of `generic-arity`, `inherited-specialization`, `overload-series`, or `type-parameter-series`. The validator removes covered siblings from standalone-example obligations only after every UID resolves to a public type target in the declared namespace, with no duplicate or circular coverage (`FAMILY_EXEMPTION_INVALID` otherwise). The anchor must carry a real behavioral example (`FAMILY_ANCHOR_EXAMPLE_MISSING` otherwise), the namespace page must name the anchor and explain how consumers choose among siblings (`FAMILY_NAMESPACE_GUIDANCE_MISSING` otherwise), and every sibling still needs accurate purpose-first prose. Category alone never exempts options, exceptions, delegates, records, or data carriers; they are evaluated on their actual API role. + + +Overwrite models should follow the target model shape. Existing properties can be replaced or merged depending on the DocFX model rules; properties not already present can be added. For managed reference docs, common useful overwrite targets include `summary`, `remarks`, `example`, `exceptions`, `see`, `seealso`, and parameter descriptions under `syntax`. The official managed reference model lists `example` as an overwriteable property, so usage examples can be added through overwrite sections when generated metadata lacks them. + +The `build.overwrite` entry in `docfx.json` tells DocFX which conceptual Markdown files contain overwrite sections. All relative paths in `docfx.json` are resolved relative to the directory containing `docfx.json`, not necessarily the repository root. + +When a repository has no obvious overwrite location, inspect `docfx.json` first. Look at `build.content`, `build.overwrite`, `metadata.dest`, include paths, and existing Markdown layout before deciding where a new namespace page belongs. + +If a public non-abstraction type lacks an example, create a matching type-UID overwrite section in a separate per-type Markdown file by default, and make sure that file is included by `build.overwrite` so the example appears on the generated type API page. Extension-method examples follow the same type-targeted pattern by default: keep them on the declaring extension class page or another readable file under `.docfx/api/types/`, not inside the namespace overview file. In Codebelt repositories, keep type overwrite files under `.docfx/api/types/{TypeUid}.md`, such as `.docfx/api/types/X.Y.Z.Class1.md`, and namespace overview pages under `.docfx/api/namespaces/{Namespace}.md`. File location does not decide whether the page is a namespace page or a type page; the YAML front matter `uid` does. Keep both `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite`, exclude both `api/namespaces/**` and `api/types/**` from `build.content`, and do not use `api/**/*.md` under either section. If authored overwrite Markdown already exists directly under `.docfx/api/*.md`, move it into either `api/namespaces/` (for namespace UIDs) or `api/types/` (for type UIDs) without deleting the content. Namespace overview pages and `Extension Members` tables complement examples; they do not replace type-page examples. + +## Practical Rules + +- Run `agents.cs` before finishing so root `AGENTS.md` receives persistent DocFX maintenance guidance. +- Use overwrite files to complement generated API metadata, not to hide incorrect XML documentation. +- Correct bad XML comments at source when the generated summary is wrong. +- Use namespace overview pages only for namespace fly-ins and extension-member tables; keep type/member overwrite mappings out of them. +- Keep examples and remarks close to the API item or namespace they explain. +- Create per-type overwrite files for missing concrete-type examples even when the repository currently has only namespace overview files. +- Keep namespace overview Markdown under `.docfx/api/namespaces/` and type overwrite Markdown under `.docfx/api/types/`. Move legacy `.docfx/api/*.md` files into the appropriate subdirectory: namespace UIDs go to `api/namespaces/`, type UIDs go to `api/types/`. +- Keep `api/namespaces/**/*.md` and `api/types/**/*.md` under `build.overwrite` only; do not use `api/**/*.md` under `build.content` or `build.overwrite`. +- Add examples through overwrite sections when XML comments or generated metadata do not already provide developer-friendly examples. +- Preserve existing hand-written overwrite sections unless they are stale or contradictory. +- Prefer additive edits, but remove or revise contradictions. +- Re-run `docfx.cs` after edits so missing namespace pages, extension tables, availability, and sample compilation are checked deterministically. + +## Section rendering order + +Overwrite files control what content is merged into the DocFX model. DocFX templates control where each property renders on the output page. Do not attempt to fix the order of sections such as "Examples before See Also" through overwrite paths, body headings, or front matter — that order is determined by the active template. If section ordering is wrong, the fix belongs in the template, not in the overwrite file. diff --git a/skills/dotnet-docfx-digest/references/scripts.md b/skills/dotnet-docfx-digest/references/scripts.md new file mode 100644 index 0000000..faefaab --- /dev/null +++ b/skills/dotnet-docfx-digest/references/scripts.md @@ -0,0 +1,166 @@ +# dotnet-docfx-digest script reference + +Two deterministic .NET 10 file-based apps back the skill so repository guidance and documentation rules are enforced by code instead of AI memory. Each script is a single `.cs` file with no `.csproj` and runs directly: + +```bash +dotnet run --file