Skip to content

Spec Lint Action

Static structural validation for spec files. Checks frontmatter schema, section numbering, AC checkbox format, status comment syntax, and depends_on resolvability. Pure parser, network-free, no Claude spend, no token needed.

uses: canonhq/canon/actions/spec-lint@v1

Inputs

NameRequiredDefaultDescription
specsno"" (read from CANON.yaml)Glob filter for spec files
warnings-as-errorsnofalseTreat lint warnings as errors
fail-onnoerrorThreshold: error, warning, or never
python-versionno3.12
canon-versionno>=1.0.0,<2.0.0

Outputs

NameDescription
error-countNumber of lint errors found
warning-countNumber of lint warnings found
report-pathAbsolute path to the JSON lint report on the runner

Example

yaml
name: Spec Lint
on:
  pull_request:
    paths:
      - "docs/specs/**"
      - "CANON.yaml"

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: canonhq/canon/actions/spec-lint@v1
        with:
          fail-on: error

What it checks

RuleSeverityWhat triggers it
frontmatter.titleerrorEmpty title field
frontmatter.ownerwarningEmpty owner field
frontmatter.teamwarningEmpty team field
frontmatter.created / frontmatter.updatedwarningNot a YYYY-MM-DD date
section.numberingwarningTop-level sections not monotonically increasing
ac.missingwarningSection is todo/in_progress but has no acceptance criteria
comment.unknownwarning<!-- canon:... --> comment with an unknown keyword (typos, malformed comments)
depends_on.unresolvedwarningdepends_on entry that doesn't match any discovered spec
parserwarning/errorAnything the spec parser itself reports (unknown statuses, malformed frontmatter, etc.)

Lint skips text inside markdown inline code spans and fenced code blocks, so docs that describe canon comment syntax don't false-positive.

Step summary

The action writes a markdown table to $GITHUB_STEP_SUMMARY listing every issue with severity, rule, file, line, and message — so failures show up directly in the GitHub UI without diving into raw logs.

Pitfalls

  • fail-on: warning is opinionated: it treats ac.missing warnings as failures, which can be loud on repos with lots of placeholder sections. Start with fail-on: error and tighten over time.
  • No filesystem changes: spec-lint is read-only. It won't fix issues automatically — that's a separate workflow.

AI-native enterprise documentation platform.