Skip to content

chore: add documentation site and rule explanation feature#64

Open
nozaq wants to merge 11 commits into
mainfrom
claude/rule-long-description-rationale-w65wo7
Open

chore: add documentation site and rule explanation feature#64
nozaq wants to merge 11 commits into
mainfrom
claude/rule-long-description-rationale-w65wo7

Conversation

@nozaq

@nozaq nozaq commented Jul 26, 2026

Copy link
Copy Markdown
Member

Summary

This PR adds a comprehensive documentation site for decolint built with Hugo, along with a new -explain flag that displays rule documentation in the terminal. It includes extensive test coverage to ensure documentation stays synchronized with the rule registry.

Key Changes

  • Documentation Site: Added Hugo-based site in docs/ with:

    • Rule reference pages (one per rule) with front matter matching rule metadata
    • Getting started guide and other content pages
    • Responsive CSS styling with light/dark mode support
    • GitHub Pages deployment workflow
  • Rule Documentation Tests (rules/doc_test.go):

    • TestBuiltin_Descriptions: Ensures all rules have descriptions
    • TestBuiltin_DocsPages: Verifies documented rules match registered rules and front matter is accurate
    • TestBuiltin_DocsExamples: Lints Bad/Good examples to verify they behave as documented
    • TestBuiltin_DocsReferences: Validates all reference links are absolute HTTPS URLs with no duplicates
  • Terminal Rule Explanation (-explain flag):

    • New command-line flag to display rule documentation without running linter
    • explainRule() function renders rule metadata and documentation
    • Integrated into main command flow with proper exit codes
  • SARIF Format Enhancement:

    • Added HelpURI field to SARIF rule descriptors, linking to rule documentation
    • Updated SARIF tests to verify the field is populated
  • Code Organization:

    • Moved discovery and substitute packages under cmd/decolint/ (they are CLI-specific)
    • Moved format package under cmd/decolint/ for consistency
    • Added rules/docs.go with DocsURL() function to generate rule documentation URLs
  • Build System:

    • Added Hugo build targets to Makefile (make site, make site-serve)
    • Added GitHub Pages workflow for automated site deployment
    • Updated .gitignore for Hugo build artifacts

Notable Implementation Details

  • Documentation examples are verified by linting them with only the relevant rule enabled, catching drift between examples and actual rule behavior
  • Unverifiable examples (those differing in file permissions or existence) are explicitly listed to prevent silent growth
  • Rule pages use Hugo's data files and partials to automatically generate navigation and rule tables from page metadata
  • The -explain flag output is tested to ensure it includes rule ID, category, platforms, file types, and description

https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR

claude added 4 commits July 25, 2026 04:36
Rules carried only a one-line description of what they check, never why
or where the behavior is defined. Add LongDescription and References to
linter.Rule, fill both in for every built-in rule from the Dev Container
specification and the relevant runtime documentation, and surface them:

- SARIF rule descriptors gain fullDescription and help (text and
  markdown), so the rationale and links show on a Code Scanning alert.
- New -explain <rule-id> flag prints a single rule's documentation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
discovery, format and substitute are imported by package main and
nothing else. Nesting them under the binary keeps the module root to
the packages that are usable on their own: linter, rules, feature and
the ocitest helper.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
The rationale and references each rule carried were compiled into the
binary and repeated in every SARIF log, and neither could show what the
rule accepts or rejects. Move them to a GitHub Pages site built from
docs/, and keep only the one-line Description in the binary, alongside a
documentation address derived from the rule ID.

Each rule page adds Bad and Good examples, which rules/doc_test.go
verifies by linting: the Bad example must report the rule and the Good
one must report nothing, so an example cannot drift from the rule it
documents. The two rules whose examples differ in a file's permission
bits or its absence are listed as unverifiable rather than skipped
silently.

SARIF now carries helpUri and a help message linking to the page. The
README rules table is regenerated from the rule declarations, which also
picks up descriptions it had drifted from.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
Jekyll runs Liquid over every file before converting it, code fences
included, so a snippet containing a GitHub Actions expression was
silently emptied: "token: ${{ secrets.GITHUB_TOKEN }}" published as
"token: $", with the build reporting success. Hugo leaves it alone,
since only "{{<" and "{{%" delimit its shortcodes.

The move also drops the theme. layouts/ and assets/css/ are the site's
own, and the rule index and sidebar are now built from the rule pages
themselves rather than a hand-maintained table, so the list cannot fall
behind the pages the way it already had.

Published paths are unchanged, so the addresses rules.DocsURL derives
still resolve. Hugo is pinned by version and checksum in the Pages
workflow and named in the Makefile, which grows site, site-serve and
site-syntax targets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
@nozaq nozaq changed the title Add documentation site and rule explanation feature chore: Add documentation site and rule explanation featura Jul 26, 2026
@nozaq nozaq changed the title chore: Add documentation site and rule explanation featura chore: add documentation site and rule explanation feature Jul 26, 2026
claude added 7 commits July 26, 2026 00:51
Nesting them under cmd/decolint put library packages in the directory
that holds a binary's entry point, and gave them import paths like
decolint/cmd/decolint/format: still importable from outside the module,
while sitting where nobody looks for a package. This restores the layout
main has.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
With the rule reference published as a site, the flag printed a rule's
one-line description and the address of its page — everything it had
left to say once the rationale moved out of the binary. The SARIF output
carries that address for the rules it reports, and the README's rules
table links each ID to its page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
hugo server keeps the path of the configured baseURL, so it served the
site under /decolint/ and left http://localhost:1313/ a 404 — the top
page only appeared at the address hugo prints, and every link typed by
hand missed. Override the base URL for local preview, with the port a
variable so the two cannot disagree.

Two things around it:

- The build lock is ignored wherever it lands. Hugo writes it in the
  directory it runs from, which is not always docs/, and the anchored
  pattern only covered that one.
- site, site-serve and site-syntax check the hugo on PATH first. The
  layouts use the flat layouts/ lookup from Hugo 0.146, and an older
  hugo renders a page it finds no layout for as an empty one instead of
  failing, which reaches the browser as a blank page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
…ription-rationale-w65wo7

# Conflicts:
#	README.md
#	cmd/decolint/format_test.go
#	format/sarif_test.go
The landing page and getting-started page were written against the old
README and had drifted: the sample output predates the run header, the
setup guide was a short list where the README now walks through five
steps, and neither mentioned linting a published Feature or Template.

Mirror the README's structure — try it, install, the five setup steps,
CI, Features and Templates — with the outputs captured from a real run,
and point at the README's reference section for the exhaustive flag and
config tables rather than repeating them.

Also settles on "color" over "colour" across the site and the Makefile,
which is the spelling the README and the CLI use.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
The Pages workflow downloaded a release tarball and checked its sha256,
and a local build needed hugo installed separately at a version the
Makefile named but could not enforce — an older one on PATH rendered
pages it found no layout for as blank ones. A tool directive pins the
version where every other dependency is pinned, and "make site" builds
it from the module cache with nothing installed.

The version guard and the workflow's download step both go away with it,
and the Pages job now needs only actions/setup-go.

Hugo brings a large graph with it: 64 require lines become 216 and
go.sum grows from 159 lines to 971. None of it reaches the product: the
decolint binary is byte-for-byte the size it was, and "go version -m"
lists no hugo module in it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
Fixes the modernize:stringsseq finding golangci-lint raised on the two
line-splitting loops added for parsing rule doc pages.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141gA9jA24NHbAauanrYjhR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants