Aller au contenu

CI/CD Integration

Ce contenu n’est pas encore disponible dans votre langue.

Contextia’s check command verifies the integrity of your knowledge layer: specs, decisions, norms, tasks, and annotations. Running it in CI ensures that documentation stays synchronized with code as the project evolves.

Without automated checking, knowledge artifacts drift from code. Specs reference files that no longer exist. Annotations point to deleted specs. Decisions are marked as accepted but have no implementing code. Over time, the knowledge layer becomes unreliable, and agents stop trusting it.

contextia check --ci catches these issues on every pull request.

Create .github/workflows/contextia.yml:

name: Contextia Check
on:
pull_request:
paths:
- '.contextia/**'
- 'src/**'
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install Contextia
run: uv tool install contextia
- name: Run integrity check
run: contextia check --ci --format json > contextia-report.json
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: contextia-report
path: contextia-report.json

The paths filter ensures the workflow only runs when knowledge artifacts or source files change, saving CI minutes on documentation-only or infrastructure changes.

contextia check uses exit codes to signal results:

Exit codeMeaning
0All checks passed
1One or more violations found
2Configuration error (missing config.yaml, invalid schema)

In --ci mode, the command never prompts for input and always exits with a clear code.

The check command validates several categories of integrity:

  • Every spec has a valid id, title, and status.
  • All decisions referenced in spec frontmatter exist in .contextia/system/rationale/.
  • All norms referenced in spec frontmatter exist in .contextia/system/norms/.
  • All paths listed in spec frontmatter exist in the filesystem.
  • Every decision has a valid id, title, and status.
  • Every norm has a valid id, title, and status.
  • Back-references are consistent (if SPEC-001 references DEC-001, DEC-001 should reference SPEC-001).
  • Every task has a valid id, title, status, and kind.
  • All specs referenced in task frontmatter exist.
  • Active tasks have corresponding directories in work/active/.
  • Every @spec annotation in source code references a spec that exists.
  • Every @decision annotation references a decision that exists.
  • No orphan annotations (pointing to deleted artifacts).
  • Bidirectional consistency: if a spec lists paths: [src/auth.py] and src/auth.py has no @spec annotation for that spec, a warning is raised.

With --format json, the output is machine-parseable:

{
"version": "1.0",
"timestamp": "2026-03-02T14:30:00Z",
"summary": {
"total_checks": 47,
"passed": 45,
"warnings": 1,
"errors": 1
},
"violations": [
{
"severity": "error",
"category": "spec_integrity",
"message": "Spec SPEC-012 references decision DEC-099 which does not exist",
"file": ".contextia/system/specs/SPEC-012.md",
"field": "decisions"
},
{
"severity": "warning",
"category": "annotation_integrity",
"message": "File src/auth/login.py has @spec SPEC-001 but SPEC-001 does not list this path",
"file": "src/auth/login.py",
"line": 5
}
]
}

You can pipe this to jq for custom processing:

Terminal window
# Count errors only
contextia check --format json | jq '.violations | map(select(.severity == "error")) | length'
# List all files with violations
contextia check --format json | jq '[.violations[].file] | unique'

When adding Contextia to an existing project, you likely have many pre-existing inconsistencies. The baseline feature lets you suppress known violations so that CI only fails on new ones.

Run the check and save the current violations as accepted:

Terminal window
contextia check --create-baseline

This writes .contextia/.baseline.json containing the fingerprints of all current violations. Commit this file.

On subsequent runs, contextia check compares current violations against the baseline:

  • Known violations (in baseline): reported as informational, do not cause failure.
  • New violations (not in baseline): cause failure.
  • Resolved violations (in baseline but no longer occurring): reported as resolved. The baseline can be updated to remove them.
Terminal window
# Update baseline to remove resolved violations
contextia check --update-baseline

You can post check results as PR comments using the GitHub CLI:

- name: Run check and comment
if: github.event_name == 'pull_request'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RESULT=$(contextia check --ci --format json)
ERRORS=$(echo "$RESULT" | jq '.summary.errors')
WARNINGS=$(echo "$RESULT" | jq '.summary.warnings')
BODY="## Contextia Check\n\n"
if [ "$ERRORS" = "0" ]; then
BODY+="All checks passed. "
else
BODY+="**${ERRORS} error(s) found.** "
fi
BODY+="${WARNINGS} warning(s).\n\n"
if [ "$ERRORS" != "0" ]; then
BODY+="<details><summary>Violations</summary>\n\n"
BODY+=$(echo "$RESULT" | jq -r '.violations[] | "- **\(.severity)**: \(.message) (`\(.file)`)"')
BODY+="\n\n</details>"
fi
gh pr comment ${{ github.event.pull_request.number }} --body "$BODY"

Relevant settings in .contextia/config.yaml:

check:
strict_bidirectional: false # Promote bidirectional warnings to errors
ignore_patterns: # Skip these paths during annotation scan
- "tests/fixtures/**"
- "scripts/**"
required_fields: # Extra fields to require in frontmatter
spec: [description, paths]
decision: [date]

Contextia check is fast (typically under 5 seconds for projects with 100+ artifacts) because it reads local files with no network calls. Place it early in your CI pipeline alongside linting:

jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install tools
run: |
uv tool install contextia
uv tool install ruff
- name: Lint
run: ruff check src/
- name: Type check
run: uv run mypy src/
- name: Knowledge integrity
run: contextia check --ci