Skip to content

STD-DOC-003 — Documentation Integrity Audit

Purpose

Defines the check taxonomy, finding severity contract, authority routing table, Bead deduplication contract, and model-escalation policy for the documentation-integrity-audit Factory capability.

Not a documentation product. A Factory maintenance capability.


1. Capability Components

Component Location Surface
doc-integrity-check.sh BluCity-Packs/foundation/assets/scripts/ Script
documentation-integrity-audit.toml BluCity-Packs/foundation/formulas/ Formula
doc-integrity-scheduled.toml BluCity-Packs/foundation/orders/ Order
doc-integrity-check/template.yml gitlab_components/templates/ CI component

One script. Two surfaces. CI runs it at MR time (prevention). Formula runs it on schedule (reconciliation).


2. Check Taxonomy

All checks are deterministic. No model required.

Check ID Hard/Warn Description
doc-authority-collision HARD Two documents share the same standard_id
doc-task-state-leak HARD Bead IDs, MR refs, or TODO: found in evergreen prose
doc-local-path HARD Machine-local paths (/Users/, /home/user/) in docs
doc-filename-collision WARN Multiple .md files share a basename
doc-content-hash WARN Exact content duplicate by SHA-256
doc-frontmatter-missing WARN Governed .md with no YAML frontmatter
doc-frontmatter-invalid WARN Missing required field: owner, type, bluefly_document
doc-review-expiry WARN review_cycle exceeded since updated_at

Critical distinction:

FILENAME_COLLISION != AUTHORITY_COLLISION

A filename collision is a signal requiring classification. It does not prove semantic duplication or competing authority. Do not delete on filename evidence alone.


3. Finding Severity

Severity Meaning CI behaviour Formula behaviour
P1 Hard finding — always wrong Fail Create Bead P1, emit event
P2 Requires semantic judgment Warn Create Bead P2, emit event
P3 Informational Warn Create Bead P3 if not already open

4. Output Contract

Every run MUST emit:

CHECK=document-authority-integrity
REPOSITORY=
COMMIT=
FILES_SCANNED=N
[counter fields]
STATE=CLEAN | FINDINGS

A run that does not report FILES_SCANNED is not a valid check. A run with FILES_SCANNED=0 is a broken detector, not a clean corpus.

Per finding:

FINDING_TYPE=
SEVERITY=
SOURCE_A=
SOURCE_B=       (when applicable)
NOTE=
CAPTURE_METHOD=
LIMITATION=     (what the check cannot prove)

5. Bead Deduplication Contract

Finding signature:

sha256(repository:finding_type:source_a:source_b)[0:12]

Before creating a Bead:

SEARCH existing open Beads by signature substring in title
→ FOUND open Bead: update evidence timestamp
→ FOUND closed Bead + same finding: reopen or create regression relationship
→ NOT FOUND: create Bead with signature in title

No Bead on STATE=CLEAN. No duplicate Beads for the same finding across runs.


6. Authority Routing Table

Route findings to the real owner. Do not default to HARBORMASTER.

Document type Route to
Drupal standard DRUPAL owner
Factory / Gas City standard BLU
Infrastructure standard DEACON / infra owner
Security policy SENTINEL
Cross-domain collision BLU
Documentation taxonomy / governance BLU
Filename collision (ambiguous) BLU for triage

HARBORMASTER handles repository/durability mechanics. That does not make it the semantic owner of every document.


7. Model Escalation Policy

Exact duplicate content          → deterministic (no model)
Filename collision               → Bead → triage by owner (no model at creation)
80% semantic overlap             → cheaper model for classification
Two competing architecture stds  → BLU + senior model
Changing canonical architecture  → human authority where required

Agents are invoked only when a finding requires semantic judgment. The Formula itself runs with no model unless a finding escalates.


8. CI Gate Behaviour

Event Action
MR touches *.md Run doc-integrity-check component
Hard finding (P1) Fail MR
Warning (P2/P3) Warn; route to Bead
No .md changes Skip
Label doc:integrity-exempt Skip (written justification required in MR)

CI = prevention. Formula + Order = reconciliation (catches stale dates, cross-repo drift). Agent = semantic resolution (invoked only on ambiguous findings).


9. What to Put in Evergreen Docs vs. Where

BluCity-Docs          → durable architecture, standards, ADRs
Beads / Dolt          → work items, status, dependencies
GitLab                → delivery (MRs, pipelines, branches)
Receipt system        → proof (evidence, verification)

Never put in evergreen docs: - Current Bead statuses - Current MR numbers as operational status - Temporary blockers - Session handoffs - Active task assignments - Machine-local paths

The doc-task-state-leak check enforces this mechanically.


10. Scheduling

Primary enforcement: event-driven (CI on every documentation MR).

Reconciliation: weekly cron (Monday 09:00 UTC via doc-integrity-scheduled Order).

Periodic scanning catches what CI cannot: - Stale review dates - Cross-repository authority drift - External link rot (future check: doc-broken-link)


11. Future Checks (Not Yet Implemented)

doc-broken-link         internal markdown links resolving to missing files
doc-retired-term        references to retired Gas Town, old architecture names
doc-orphan              document with no inbound references
doc-upstream-copy       bluefly doc duplicates upstream documentation verbatim
doc-supersession        superseded doc not linked to its successor

These are checks. Not Agents. Not separate products. Add to doc-integrity-check.sh when needed.


12. Self-Applied Economic Gate

IS_THE_NEXT_RUN_GETTING_CHEAPER_AND_MORE_REUSABLE=NOT_ESTABLISHED
WHY=Standard written. Formula and CI component merged (pending). No confirmed
    second run with Bead dedup proven. No confirmed CI catch before merge.
    Transitions to YES after:
      (a) Monday run updates existing Beads rather than creating duplicates
      (b) A documentation MR is caught by CI before merge
REUSE_EFFECT=CREATED_REUSABLE_CAPABILITY (candidate)
WHAT_WILL_THE_NEXT_AGENT_REUSE=doc-integrity-check.sh, Formula, Order, CI component,
    finding-signature dedup pattern, authority routing table.
WHAT_WOULD_STILL_HAVE_TO_BE_RE_DERIVED=Nothing once merged. Future checks extend
    the existing script, not a new capability.