Skip to content

DocGuard v0.32.0

Latest

Choose a tag to compare

@github-actions github-actions released this 12 Jul 01:28

Graph-informed release — detection improvements and integration surfaces
adapted from patterns proven in
graphify (MIT), rebuilt
zero-dependency and deterministic for DocGuard. The detectors were empirically
validated read-only against five real production repos before shipping: zero
false positives; the indirect-impact analysis surfaced genuine, explainable
chains on two of them. Validator count unchanged (27).

Added

  • VALIDATION.md — an honest benchmarks-style page documenting the
    empirical method every detector goes through before shipping enabled
    (read-only corpus runs on real production repos, keep/cut/tune, dogfooding)
    and the measured v0.31/v0.32 results, including what DocGuard does NOT
    claim. Linked from the README header.
  • PR doc-conflict analysis — docguard impact --prs. Maps every open
    PR's changed files to the canonical docs they impact (same reference index
    as regular impact; a PR editing a canonical doc directly counts too) and
    reports pairs of PRs impacting the SAME doc — a merge-order risk: whichever
    lands second must re-verify the shared doc. Uses the gh CLI (no token
    handling in DocGuard); degrades to a clear message when gh is missing or
    the repo isn't on GitHub. Capped at 20 open PRs per scan. The
    graph-community version of this idea ships in graphify's prs --conflicts;
    this is the doc-integrity equivalent.
  • MCP Streamable HTTP transport — docguard mcp --transport http. One
    shared process can now serve the DocGuard tools to a whole team: JSON-RPC
    over POST (single + batch), 202 for notification-only bodies, session id
    issued on initialize (stateless server — accepted, never required), GET
    correctly 405s (no SSE stream offered). Zero-dep (node:http). Security
    posture: binds 127.0.0.1 by default; binding any non-loopback host
    REFUSES to start without --api-key/DOCGUARD_API_KEY; when a key is set
    every request must carry it (Authorization: Bearer or X-API-Key);
    browser cross-site origins are rejected (DNS-rebinding guard); 4 MiB body
    cap. Flags: --port (default 8585), --host, --api-key, --path
    (default /mcp). The stdio transport is unchanged and remains the default;
    both share one JSON-RPC dispatcher.
  • Agent nudge hook — docguard hooks --claude (graphify's always-on-hook
    distribution pattern, pointed at doc integrity). Registers a PostToolUse
    hook in the project's .claude/settings.json: after the agent edits a
    canonical/agent doc it is nudged to run docguard guard --changed-only;
    after it edits a code file the docs reference, it is nudged toward
    docguard impact. Merge-safe (only DocGuard's own entry is added/removed;
    an unparseable settings.json is never touched), idempotent, throttled (one
    nudge per file per 30 min via .docguard/nudge-state.json), and the
    docguard nudge-hook runtime is silent-on-error by contract — it can never
    break an agent session. Explicit opt-in; init/ensureSkills never install
    it. Remove with docguard hooks --claude --remove.
  • ADR-citation check (REF002, reference-existence) — the code→doc direction
    of reference existence. A code comment citing a decision record (uppercase
    ADR- + number in a comment) is now verified against the ADR documents the
    repo actually defines (single-file ADR.md sections, ADR-*.md filenames,
    and madr-style docs/adr/0007-*.md). Numbers compare as integers
    (ADR-0011 matches ADR-11). Citations only count inside comments — string
    literals and identifiers are ignored — and tests/fixtures are excluded
    (non-product scoping). IETF RFC citations are deliberately out of scope
    (external registry — would false-positive on every RFC 793 comment). Soft
    (confidence: low), capped at 10 findings, suppressible with
    // docguard:ignore REF002, disable with
    referenceExistence.adrCitations: false.
  • Obsidian wikilink support (Cross-Reference + impact)[[Doc]],
    [[Doc#Heading]], and [[Doc|alias]] are now validated like inline links
    (broken target → XRF001, broken heading → XRF002), and impact's doc→doc
    blast radius sees wikilink dependents. Precision-gated: wikilinks are only
    validated when the repo demonstrably uses them as FILE links (.obsidian/
    exists, or at least one wikilink target resolves) — repos using [[name]]
    as a non-file convention are skipped silently. Image embeds ![[x.png]]
    never count. Wikilink targets resolve sibling-first, then vault-wide by
    basename across the project's doc homes.
  • Indirect impact via the import graph (docguard impact) — a changed file
    with no doc references can still invalidate docs about the modules that
    IMPORT it. impact now walks the reverse import graph (reusing the
    Architecture validator's graph builder — one builder, not two) up to 2 hops
    and reports docs describing an importer of a changed file, with the
    explainable chain (doc describes X, which imports changed Y). Hub modules
    (>15 imports, e.g. a CLI dispatcher) are suppressed — their docs would flag
    on every dependency change. Docs already directly affected are not repeated.
    JSON adds indirectDocs; disable with --no-indirect. JS/TS import graphs
    only (the graph builder's scope).
  • Graphify knowledge-graph interop (Traceability) — teams that commit
    graphify-out/graph.json (a tree-sitter knowledge graph) get its doc↔code
    edges counted as linkage evidence before an "unlinked doc" (TRC002) is
    raised. Trust rules: only EXTRACTED edges count (never the LLM-derived
    INFERRED/AMBIGUOUS tiers), at least one linked code file must still
    exist (a stale graph can't vouch), and the graph is evidence-only — it can
    turn a warning into a pass but never produces a finding. Zero-dependency:
    one JSON read; malformed graphs are silently ignored.

Fixed

  • Cross-Reference link parsing — query strings are stripped before target
    resolution (./DOC.md?plain=1#anchor now resolves to DOC.md instead of a
    phantom file), and CommonMark angle-bracket targets with spaces
    ([t](<my doc.md>)) are resolved instead of being silently skipped.
  • Semantic-claim extractor honors .docguardignore — a doc the user
    explicitly excluded from validation no longer feeds the "unverified claims"
    pool (guard notice, verify --semantic, the ALCOA Accurate pillar). On
    DocGuard's own repo an ignored historical audit contributed 28 of 39
    reported claims, burying the actionable ones.