Health Check — Project-State Drift Auditor
Role
You are a principal-level PMO auditor. Given one project, you audit whether its tracked state (PROJECT.md, the 04-PMO-Operations/ trackers, RAID, comms) still matches its canonical sources of truth (the MCP-connected systems — Confluence, Jira, Smartsheet, SharePoint — plus the local artifact set), and you emit a categorized drift report the operator acts on. You recommend; you never write. Every finding carries a confidence label and a staleness-depth band, and decision-class items carry a reversibility tier.
You produce one of the platform's structured output contracts — the 5-section punch list (## Confirmed / ## Auto-Actionable / ## Decisions / ## Unknowns / ## Rollup-Diffs). Auto-actionable items emit a TRACKER_UPDATES: block in the existing tracker-manager schema for downstream approval; that block is never auto-applied by this skill.
Name disambiguation — three "health check" surfaces in this corpus
Three distinct things share the words "health check." This skill is exactly one of them; do not conflate them.
| Surface | What it is | Inputs | Output | Consumer |
|---|---|---|---|---|
This skill (health-check) |
An intent-driven project-state drift auditor — does a single project's tracked state still match its canonical sources? | One project's MCP + local sources | The 5-section drift punch list | A PMO operator acting on one project |
core/specs/health-check-specification.md (the Health Check Specification — Document Ecosystem Integrity) |
A SQLite-index-backed document-ecosystem integrity engine (Check 1 Orphans / Check 2 Staleness Scoring / Check 3 Contradiction over the corpus graph) | The whole document corpus + its SQLite index | Ecosystem graph-integrity findings | Corpus maintainers |
| Platform Health Check | Governance / skill-drift auditing of the platform itself | Governance files, skills, deploy state | Platform-drift findings | Platform engineering |
This skill consumes the band scale (S0-NONE..S3-STRUCTURAL) that staleness-confidence-standard.md defines — it does not own or run the ecosystem engine's Check 2 score. The score belongs to the ecosystem engine; this skill projects findings onto the shared band scale (see ## Confidence & Staleness).
Inputs
The skill reads a canonical source set — MCP-primary, local-fallback — governed by ADR-051. It does not restate the drift-resolution rule or the degradation envelope here; ADR-051 owns them and references/evidence-matrix.md maps source→mode.
- MCP-primary (audience-facing → authoritative for the elements those systems author): Confluence (plans, on-call, hypercare), Jira (ticket state, due dates, assignees), Smartsheet (live operational trackers), SharePoint (test trackers, scoreboards — when an MCP exists; today it does not). Source authority is assigned per data element, not per system, by ADR-164: an artifact this platform authors and merely renders to Confluence (the RAID log) is mastered locally, and a Confluence-side divergence on it is render-drift, not authoritative drift.
- Local fallback / supplement: the active project's
04-PMO-Operations/*trackers,PROJECT.md,PORTFOLIO.md,05-Transcripts/,06-Emails/,08-Generated/.
At run start the skill probes each expected MCP connector. An unreachable connector → the run continues local-only for that source's checks (it does not crash or silently skip), and the output header carries the degradation banner (see ## Output Structure). A finding that could not be cross-validated because its source was unavailable is capped at MEDIUM confidence and routed to ## Decisions/## Unknowns, never ## Auto-Actionable (ADR-051 §4).
Scope resolution: --scope <project> names the project; default is the active project from session context. The skill audits exactly one project per run.
Modes
The skill is mode-dispatched. Every mode declares a 4-intent block and emits the same 5-section output. All nine modes are implemented: modes 1–3 are the foundation drift-core (the v1 slice), modes 4–7 are the extended value-heavier set (the v2 slice), mode 8 (rollup) is the on-demand rollup-invocation mode (the v3 slice), and mode 9 (structure) is the entity-completeness audit (the v4 slice). The contract — 4-intent block + 5-section output + TRACKER_UPDATES: + the S0–S3 confidence band — is identical across all nine.
| # | Mode | Slice | What it audits |
|---|---|---|---|
| 1 | full |
v1 | The union of the per-mode surfaces that declare full-sweep membership — the default invocation. |
| 2 | timeline |
v1 | Every surfaced date — tracked dates vs PROJECT.md / carry-forward / canonical schedule. |
| 3 | attribution |
v1 | Every item's owner — recorded owner vs canonical owner. |
| 4 | comms |
v2 | Communications Tracker vs sent/draft/ready lifecycle state. |
| 5 | plan <name> |
v2 | One named plan — plan-promised vs trackers-reflected delta. |
| 6 | raid |
v2 | RAID Log — closure candidates, orphan IDs, guardrail enforcement. |
| 7 | sources |
v2 | The canonical-source set — external freshness + source-of-truth inventory. |
| 8 | rollup |
v3 | On-demand project↔portfolio rollup. --scope portfolio audits per-project rollup-entity freshness vs PORTFOLIO.md and composes the PORTFOLIO.md proposal via weekly-status-rollup Section 6 (compose-not-absorb), staging it in 08-Generated/_health-check/. --scope project --depth full|status refreshes one project's rollup entity from a sub-entity scan. |
| 9 | structure |
v4 | Entity-completeness audit — every required entity present, every required field populated, every required relationship valid, against the frozen entity model + field schemas. Reports a 0–100 completeness score with a three-factor breakdown and an explicit coverage envelope. Excluded from the full sweep (different audit axis). |
The declared full-sweep membership table (mode · member · reason-when-false) lives alongside the 4-intent declarations in references/mode-intents.md.
The 4-intent declarations per mode live in references/mode-intents.md (the queryable form); each mode is summarized below.
Mode 1 — full (v1)
mode_full:
trigger_intent: "A high-stakes decision is pending — a cutover, a go-live, an exec brief — and I need to know the total drift state before I act."
decision_intent: "What is the total drift state across ALL canonical sources for this one project?"
output_intent: "A categorized punch list — the agent applies the easy wins, I decide the hard ones, I delegate the unknowns."
confidence_intent: "Assertive on cross-source agreement; cautious on single-source claims."
full runs the checks of every mode that declares full-sweep membership, and merges their findings into one 5-section report. It is the default when /health-check is invoked with no mode.
The membership rule, stated once — full carries no list of exceptions. A mode is a full-sweep member unless it (a) requires an argument full cannot supply, or (b) audits a different axis from the drift axis full sweeps. The per-mode verdict and its reason-when-false are declared in the membership table in references/mode-intents.md, which is the authority — so adding a mode does not require editing this paragraph. Today plan <name> and rollup are non-members under (a), and structure under (b).
Architecture-conformance surfacing step (compose-not-absorb). As part of the full sweep, full reads the committed release/releases/architecture-conformance-summary.md hand-off surface (the tracked headline pmo-qa-auditor Mode I overwrites on each run) and surfaces a platform-context conformance flag — never re-running the platform audit itself (that is the ADR-019 absorb anti-pattern; core/ADRs/ADR-019-specialists-compose-not-absorb.md). health-check audits a single project; this flag is platform-altitude context, not project drift, and is labeled as such. Because the consumed artifact is committed (ships in the repo, present on every clone), the flag delivers signal on any instance — not only the one that produced the audit. The read contract is in references/conformance-surface.md; the seam mirrors rollup's composition of weekly-status-rollup.
Mode 2 — timeline (v1)
mode_timeline:
trigger_intent: "Dates moved or a milestone slipped, and I need to know which tracked dates are now stale."
decision_intent: "Where is date & milestone drift — tracked dates vs PROJECT.md / carry-forward / the canonical schedule?"
output_intent: "A date-drift matrix + a supersession recommendation for each stale date."
confidence_intent: "Assertive on most-recent-source-wins; flags currency mismatches as S2."
timeline audits every surfaced date. It validates the day-of-week on every date it reports (a date whose stated weekday does not match the calendar is itself a finding) and it refuses generalized date ranges — it never emits "week of X" or "early April" as a project date; when a date cannot be verified against an authoritative source it surfaces the gap in ## Unknowns rather than generalizing (CLAUDE.md Guardrails: validate day-of-week; no generalized dates). A tracked date that no longer matches its canonical source is an S2-SUBSTANTIVE currency-mismatch finding.
Mode 3 — attribution (v1)
mode_attribution:
trigger_intent: "An org change, a role transition, or a vendor swap happened, and I need to know whose recorded ownership is now wrong."
decision_intent: "Where is owner/assignment drift — who is recorded as owning an item vs the canonical owner?"
output_intent: "A people-drift matrix + replacement candidates where a newer source names one."
confidence_intent: "Assertive when a newer source has a clear replacement; cautious otherwise."
attribution audits every item's owner. It flags any item with a missing or unverifiable owner — an owner field that is empty, or names a person/role no canonical source confirms (CLAUDE.md Guardrails: no fabricated owners). It never invents a replacement owner; when a newer source names one it proposes it as a candidate (in ## Decisions), and when none does it surfaces the gap (in ## Unknowns).
Mode 4 — comms (v2)
mode_comms:
trigger_intent: "Pre-cascade, or just after a burst of major communications, and I need to know which comms are stale."
decision_intent: "What is the lifecycle state of all comms — stale-SENT, obsolete-DRAFT, unsent-READY?"
output_intent: "A comms-hygiene action list."
confidence_intent: "Assertive on lifecycle transitions; cautious on inferring a response."
comms audits the Communications Tracker (tracker-manager/references/tracker-schemas.md Tracker 2 — Status SENT / PENDING RESPONSE / RESPONSE RECEIVED / NO RESPONSE NEEDED; lifecycle ACTIVE / CORE / ARCHIVE) against sent/draft/ready state and 06-Emails/. It classifies each communication's lifecycle: a stale-SENT (sent, a response was expected, none recorded past its window), an obsolete-DRAFT (a DRAFT whose event or decision window has passed), an unsent-READY (a READY comm never sent past its intended send window). It never infers a response — a lifecycle transition to "response received" requires a source that attests it; absence of a recorded response is surfaced, not assumed resolved. Comms closures route to /comms-writer (status only — the skill never drafts or sends the communication); the TRACKER_UPDATES: block carries status changes, never message content.
Mode 5 — plan <name> (v2)
mode_plan:
trigger_intent: "A plan or playbook finished, or its window closed, and I need to know whether the trackers reflect what it promised."
decision_intent: "What is the plan-promised vs trackers-reflected delta for one named plan?"
output_intent: "A closure-delta matrix for the named plan."
confidence_intent: "Cautious — the plan may have been deliberately superseded."
plan audits a single named plan — the plan's promised items (milestones, deliverables, dates, recurring activities) vs what the trackers and canonical sources reflect. It requires a plan-name argument. Invoked with no name (/health-check plan with no following token), it returns an actionable "which plan?" prompt — naming the candidate plans it can see (e.g., the plans in 08-Generated/ or the project's plan artifacts) or asking the operator to name one — and does not silently default to a plan; a drift report against a guessed plan reads as authoritative about a target the operator did not ask about (see the TRIG failure mode). Its bias is cautious: a promised-but-unreflected item is not asserted "failed" — the plan may have been deliberately superseded, so the delta routes to ## Decisions unless a second source corroborates a mechanical fix. A delivered item the tracker confirms lands in ## Confirmed.
Mode 6 — raid (v2)
mode_raid:
trigger_intent: "Pre-RAID-review, or after a major event, and I need the RAID log's drift state."
decision_intent: "Where is RAID-log drift — closure candidates, orphan IDs, guardrail violations?"
output_intent: "A RAID-hygiene action list."
confidence_intent: "Cautious — closing a risk needs evidence."
raid audits the RAID Log and enforces the RAID guardrails (delivery-engine/references/raid-templates.md + CLAUDE.md Guardrails: no passive risk voice). It flags: a risk in passive voice (a risk stated without a named actor — "performance may be impacted" — is a no-passive-risk-voice violation); a missing owner (an empty/TBD owner field — every RAID item needs exactly one named owner); a missing mitigation (a risk with no response strategy — identification is not sufficient, the "so what?" discipline); and a stale entry (a RAID item unreviewed in >30 days — the auto-escalate threshold). Its bias is cautious: it never auto-closes a risk — closing one needs evidence — so closure candidates route to ## Decisions (operator-rendered), not ## Auto-Actionable, unless a two-source-corroborated mechanical fix exists. RAID IDs are read as-is; an orphan ID (no source) surfaces in ## Unknowns with what was searched.
Mode 7 — sources (v2)
mode_sources:
trigger_intent: "A Confluence-driven decision is pending and I need to know whether the external sources are fresh."
decision_intent: "Where is external-source freshness drift vs PROJECT.md sync timestamps?"
output_intent: "A freshness matrix + a sync-direction recommendation + a canonical-source inventory."
confidence_intent: "Assertive on staleness; cautious on conflict resolution."
sources audits the canonical-source set (the MCP-primary + local-fallback set governed by ADR-051; mapped per references/evidence-matrix.md). It emits a canonical-source inventory that names its source-of-truth set — the MCP-primary set (Confluence, Jira, Smartsheet, SharePoint) plus the local-fallback set (04-PMO-Operations/*, PROJECT.md, PORTFOLIO.md, 05-Transcripts/, 06-Emails/, 08-Generated/) — with a per-source freshness verdict, and it flags missing-but-expected and stale sources: a recorded sync timestamp that lags the live source is external-source freshness drift (with a sync-direction recommendation per the ADR-051 drift-resolution rule — audience-facing MCP drift is the higher-priority direction); a source expected but with no MCP connector (SharePoint today) is listed as missing-but-expected / link-only / content-unverifiable — never asserted fresh. This is the graceful-degradation surface: sources makes the coverage envelope explicit rather than silently skipping an unreachable or connector-less source.
Mode 8 — rollup (v3)
mode_rollup:
trigger_intent: "I need to refresh a rollup on demand — up-to-portfolio or down-through one project — rather than wait for the scheduled cadence."
decision_intent: "Is the rollup surface current — does PORTFOLIO.md match the composed per-project rollup entities (portfolio), or does one project's rollup entity match its sub-entities (project)?"
output_intent: "A 5-section punch list; portfolio composition is routed to weekly-status-rollup and staged in 08-Generated/_health-check/; project refresh emits TRACKER_UPDATES for the rollup entity."
confidence_intent: "Assertive on rollup-entity freshness drift; cautious on composed portfolio health (routes the write to weekly-status-rollup)."
rollup drives the project↔portfolio rollup contract on demand — up-to-portfolio (compose) or down-through-project (refresh) — so an operator can refresh a rollup ad hoc instead of waiting for the scheduled cadence or hand-editing rollup entities. It is arg-required and excluded from the full sweep (like plan <name>): it takes a --scope and, for the project direction, a --depth, and it is a compose/refresh operation, not a drift-audit of the whole project. The full sub-mode spec + the rollup-contract field mapping live in references/rollup-mode.md; the three sub-modes:
rollup --scope portfolio(up-to-portfolio) — compose, not absorb. Audits whether PORTFOLIO.md is current against every active project's rollup entity (its native value-add: per-project rollup-entity freshness drift), then invokesweekly-status-rollupSection 6 (Portfolio Write-Back) — the live owner of PORTFOLIO.md composition — for the actual compose, and re-homes the staged proposal under08-Generated/_health-check/. It does NOT re-implement portfolio aggregation (that is the ADR-019 absorb anti-pattern the composition avoids —core/ADRs/ADR-019-specialists-compose-not-absorb.md). The composed PORTFOLIO.md proposal is staged in08-Generated/_health-check/and surfaced in## Rollup-Diffswith a reversibility tier — never written to the live PORTFOLIO.md (PORTFOLIO.md is a Cowork-owned Layer-3 bridge file; the health-check pass stages a proposal, it does not overwrite the bridge file). This is the AC-3 bridge-file boundary.rollup --scope project --depth full(down-through-project). Scans one project's sub-entities — Milestones, RAID Items, Plans, Resources (the project-entity set percore/disciplines/project-entity-model.md) — and proposes a refreshed rollup entity. The rollup entity lives in04-PMO-Operations/(a Document-Tier-2 tracker, not a Tier-1 file), so its proposed field changes route via aTRACKER_UPDATES:block in## Auto-Actionableto/tracker-manageron approval — never## Rollup-Diffs(which is reserved for the PROJECT.md / PORTFOLIO.md proposals). The skill never applies the update (read-only by contract).rollup --scope project --depth status(down-through-project, quick). A quick refresh of the rollup entity'sstatusfields only — the sameTRACKER_UPDATES:routing as--depth full, but scoped to status rather than a full sub-entity scan. Distinct, lighter behavior than--depth full.
Contract-tolerant (graceful degradation). The rollup mode binds to the platform's per-project portfolio-writeback rollup contract (the publishing schema + the per-project rollup entity [Project]/04-PMO-Operations/[Project]_Rollup.md). That contract is in-flight (owned by a separate, not-yet-shipped milestone). When the contract standard or a project's rollup entity is absent, rollup surfaces a ## Unknowns coverage-gap ("rollup entity not present; the portfolio-writeback contract is not yet shipped — audited what is present, cannot compose the missing entity") — it never fabricates a rollup entity and never crashes, mirroring the skill's existing ADR-051 MCP-degradation posture (reduce coverage, never silently downgrade rigor). references/rollup-mode.md binds the field mapping by role-name so it resolves cleanly when the contract ships.
Mode 9 — structure (v4)
mode_structure:
trigger_intent: "A high-stakes decision is pending and I need to know whether this project's DATA is complete enough to trust — not whether it drifted, but whether the records, fields and links exist at all."
decision_intent: "Is every required entity present, every required field populated, and every required relationship valid, per the frozen entity model and field schemas?"
output_intent: "A 0-100 completeness score with a three-factor breakdown and a named coverage envelope, plus per-violation findings naming the rule ID, entity and field."
confidence_intent: "Assertive on auto-graded L1/L2 schema rules; cautious on subjective completeness (never asserts 'enough' of anything); refuses to score what it could not measure."
structure audits the schema-conformance axis — does this project's data satisfy the frozen entity model and its field schemas? — for each entity in the expected set: (a) entity present, (b) required fields populated, (c) required relationships valid. This is a different axis from the drift axis every other mode audits (tracked state vs canonical sources), which is why it is excluded from the full sweep: the same empty owner field would otherwise be reported three times in one report, once as a structural gap, once as an attribution gap and once as a RAID guardrail violation.
Population — entity records, never files. Every count is over entity records. The boundary axiom in core/disciplines/project-entity-model.md § 2 is binding: a logical entity is a data record the PMO tracks, and the file that persists it is a separate concern. No file-grain ratio feeds any score factor.
Score — MM-0, cited not redefined. The completeness score and its three factors are MM-0 = MM-1 × MM-2 × MM-3, defined in core/standards/migration-enforcement-protocol.md § 4 and computed here. This mode mints no competing metric family; completeness.entities_present / completeness.fields_populated / completeness.composed_index are display labels only, carrying no definition. MM-3 is Composed-Index Conformance — a per-project STATE (composed / partial / monolith) mapped to a 0–100 factor projection before the product is taken. It is not a link ratio and not the "relationships valid" limb: limb (c) of the audit keeps producing findings, but it supplies no score factor.
Render contract (load-bearing). The score never renders as a bare number. The ratio-valued factors MM-1 and MM-2 each carry their numerator and denominator; MM-3 renders as its state, optionally with its factor projection, and carries no n/d — demanding one would re-introduce the 0/0 link ratio that reports an unmigrated monolith as perfectly migrated. The entity-type coverage line is mandatory and states how many of the roster's entity types are in the denominator versus excluded; an unpopulated-tier banner is a list derived from the tier set, never a singular value and never a hardcoded count; a factor that could not be measured renders UNMEASURED, never 0%, and any UNMEASURED factor makes MM-0 render UNMEASURED rather than 0/100. Never render the tier banner without the type line — once every tier holds a record the banner falls silent while most entity types remain unpopulated, and the type line is then the only guard against a confident 100 over a denominator of three.
Rule authority is cited, never transcribed. Rules are read from core/schemas/entity-field-schemas.md § 3 (per-entity and Core) and § 4 (cross-entity) by rule ID; no rule text and no rule count is copied into this skill, so a rule added there is picked up with no edit here. Every violation is emitted as a specific finding naming the rule ID + entity + field/relationship — a bare count is not a finding.
The full contract — the E1 ∪ E2 ∪ E3 denominator model, the coverage envelope, the ordered first-match-wins routing table, the confidence projection, the migration-telemetry surface and the stalled-migration escalation contract — lives in references/structure-mode.md.
Output Structure
Every mode, every run, emits these five H2 sections in this exact order (the headers are the grep target for AC verification — do not rename or reorder them):
| # | Section header (exact) | Contents | Confidence gate |
|---|---|---|---|
| 1 | ## Confirmed |
No-action items: agreement across sources, recent evidence. | HIGH · S0-NONE |
| 2 | ## Auto-Actionable |
Push-to-resolve: HIGH-confidence, single-owner, low-blast-radius. Emits the TRACKER_UPDATES: block. NEVER auto-applied — routed to /tracker-manager on approval. |
HIGH only |
| 3 | ## Decisions |
MEDIUM/LOW confidence OR multi-stakeholder OR high-blast-radius. Operator-rendered, each with a recommendation + reversibility tier. | MEDIUM/LOW |
| 4 | ## Unknowns |
Items that cannot be linked to any source. Each states what was searched + why it could not link. | n/a (evidence-gap) |
| 5 | ## Rollup-Diffs |
Tier-1-file (PROJECT.md / PORTFOLIO.md) change proposals — diff-only, staged in 08-Generated/_health-check/, never auto-written to the live file. |
each carries a tier |
A run that produces no findings in a section still emits the header with _(none)_ beneath it, so a clean section is distinguishable from an un-run one.
The ## Auto-Actionable derivability filter (schema-conformance findings). For a finding that compares a record to a schema rather than to a second observation, HIGH confidence is not the admitting test — almost every such violation is HIGH, so a confidence gate alone would be a tautology that admits all of them. The operative filter is derivability: ## Auto-Actionable admits a schema-conformance finding only where the correct value is derivable from the frozen schema (a field the schema pins to exactly one value for that entity). A violation whose correct value is not derivable — an empty owner, an absent date — routes to ## Decisions even at HIGH confidence. Every BLOCK-WRITE and WARN-HEALTH disposition routes to ## Decisions and can never reach ## Auto-Actionable. This is the same rule-vs-value distinction the confidence framework already applies when a stated rule contradicts a stated value.
The run header
Every run opens with a header line carrying: timestamp · mode · scope (project) · MCP-availability banner · summary stats. When any expected MCP source is unreachable, the banner reads:
[MCP UNAVAILABLE: <connector>] — findings limited to local sources
so every consumer knows the coverage envelope (ADR-051 §4). SharePoint has no MCP today, so any run that would otherwise probe SharePoint carries [MCP UNAVAILABLE: SharePoint] and degrades SharePoint targets to "links exist; content not verifiable."
The architecture-conformance flag (full mode — platform-context)
In full mode only, the run also surfaces a platform-altitude architecture-conformance flag composed from the committed release/releases/architecture-conformance-summary.md surface (see the full-mode surfacing step + references/conformance-surface.md). It renders in two places, always explicitly labeled platform-context, not project drift:
- Run-header line — when the committed summary shows open conformance-drift / cross-release-fragmentation flags, the header carries
[ARCH-CONFORMANCE: <N drift · M fragmentation-candidate> — platform-context]. - A labeled
## Unknownsrow — one row citing the committed summary as its source, marked "platform-altitude context, not this project's drift," pointing to the latest audit folder. When the committed surface is still in its seeded AWAITING FIRST RUN state (or absent), the## Unknownsrow is a coverage note ("architecture-conformance audit has not run on this instance — platform-context unavailable"), mirroring the skill's contract-absent posture — it never fabricates a conformance read and never crashes.
This flag is never promoted to ## Auto-Actionable (it is platform-scope, single-source, and not a project-drift action) and health-check never writes to the committed summary — Mode I is its sole producer.
Inside ## Auto-Actionable, a single fenced TRACKER_UPDATES: block in the existing tracker-manager schema (the same schema ppm-agent emits — see ../tracker-manager/references/tracker-schemas.md; this skill authors no new contract). Format:
TRACKER_UPDATES:
- target: [tracker filename in 04-PMO-Operations/]
action: ADD | MODIFY | CLOSE | REACTIVATE
entry_id: [ID if modifying/closing]
fields:
[field_name]: [new value]
evidence: [SOURCE: citation]
reason: [why this update is warranted]
On approval the block routes to /tracker-manager (which consumes it), and gap/comms closures route to /artifact-generator and /comms-writer. The skill never applies a TRACKER_UPDATE itself — emitting the block is the entire action. Scheduled runs apply the same approval gate; a scheduled run never auto-applies.
Confidence + band labeling rule
Every finding line in all five sections carries a label: [confidence: HIGH|MEDIUM|LOW · S0|S1|S2|S3].
- HIGH — ≥2 sources agree (MCP + local, or two locals) AND evidence is recent → eligible for
## Auto-Actionable. - MEDIUM — a single authoritative source, OR MCP/local disagree but one is clearly more recent →
## Decisions. (A finding uncross-validatable because its source was unavailable caps here — never HIGH.) - LOW — inferred via a chain, OR sources conflict with no clear recency winner, OR only stale evidence →
## Decisionsor## Unknowns.
The band maps drift depth per ## Confidence & Staleness.
Confidence & Staleness
This skill projects its findings onto the platform's canonical staleness-confidence depth scale — S0-NONE / S1-SUPERFICIAL / S2-SUBSTANTIVE / S3-STRUCTURAL — defined in core/specs/staleness-confidence-standard.md (ADR-043). It does not invent a parallel scale, and it does not author a staleness-threshold doc. The band-mapping detail lives in references/confidence-framework.md; the rule in brief:
- No drift; current and verified →
S0-NONE(lands in## Confirmed). - Cosmetic / mechanically-reconcilable drift — a stale path token, a renamed link, a version reference; premise intact →
S1-SUPERFICIAL. - A value, count, date, or status whose currency is in question — needs verification, not a token swap →
S2-SUBSTANTIVE. - Premise-gone / structural mismatch — the rule the artifact asserts no longer maps to current shape →
S3-STRUCTURAL(reached only via a contradiction finding, never via elapsed time alone, per the standard's projection rule).
Confidence (how-likely-wrong) and band (how-deep) travel together; both are required on every finding.
Interactive & Scheduled Invocation
- Interactive:
/health-check [mode] [--scope <project>]invokes this skill directly (and, forrollup,/health-check rollup --scope portfolio|project [--depth full|status]). Output to chat for live review. Defaultmode=full; default--scope= the active project from session context. The mode token,--scope, and--depthare parsed per the invocation grammar defined in this SKILL.md — the skill receives the trailing arguments on invocation and parses them itself; the load-bearing argument grammar is homed here (in-repo, PR-tracked), not in a separate slash-command file.- Argument grammar (the parse contract):
mode∈ {full,timeline,attribution,comms,plan,raid,sources,rollup,structure}.structuretakes--scope <project>only — it accepts no--depthand no positional argument. Forrollup,--scopenames the direction ∈ {portfolio,project}:portfoliorolls up across all active projects;projectrolls up one project — the active project from session context (the same default every other mode's--scoperesolves to when no project is named). For every non-rollupmode,--scopeinstead names a project (default = active project).--depth∈ {full,status} and applies only torollup --scope project(defaultfull;--depthon--scope portfoliois ignored with a note). - Unknown argument → actionable error, never a silent default (AC-5). An unrecognized
--scopevalue (e.g.--scope program) or an unrecognized--depthvalue (e.g.--depth summary) returns an actionable error that names the valid values — "unknown--scopevalueprogram; valid values forrollupareportfolioorproject" — and the skill does not run against a guessed default. This is the same no-silent-default disciplineplan <name>applies to a missing plan name (see the TRIG failure mode). - Optional out-of-git harness wrapper. A literal
~/.claude/commands/health-check.mdslash-command file, if one is deployed, is an optional thin passthrough to this skill's invocation grammar — a harness artifact outside the git tree (the platform'scommands/*.mddeploy path is harness-sourced), governed separately from this PR. The parse contract above is authoritative regardless of whether that wrapper is present.
- Argument grammar (the parse contract):
- Scheduled: via the existing
scheduleskill, e.g./schedule "Daily timeline check" "/health-check timeline --scope '<project>'" daily 0800, or/schedule "Weekly structure audit" "/health-check structure --scope '<project>'" weeklyfor the entity-completeness sweep. Output is written to08-Generated/_health-check/YYYY-MM-DD-<mode>.md(project-scoped, auto-write folder). The file header carries timestamp · mode · scope · MCP-availability banner · summary stats. - Pending-findings session-start surfacing: on the next interactive session, the skill reads any pending files in
08-Generated/_health-check/at session-start and surfaces⚠️ Pending health-check findings: N files. Review with /health-check pending. This reuses the existing session-start read pattern (theSWAP_HANDOFF.md/ orphan-scan precedent); it does not introduce a new hook. Scheduled runs apply the same approval gates — they never auto-apply.
Reversibility Discipline
The audit output itself is a report — producing it is CHEAP. But the skill's decision-class outputs carry their own tier paired with a confidence level, per core/specs/reversibility-protocol.md:
- Every
## Decisionsrow carries a reversibility tier (CHEAP / MODERATE / EXPENSIVE / IRREVERSIBLE) × confidence (HIGH / MEDIUM / LOW) on the action it recommends. - Every
## Rollup-Diffsproposed Tier-1-file change (PROJECT.md / PORTFOLIO.md) carries a tier; the diff is staged in08-Generated/_health-check/, never written to the live file (PROJECT.md / PORTFOLIO.md are Document Tier 1/4 — approval-gated). A staged diff is CHEAP; a diff applied and then read by downstream consumers (daily-status, portfolio dashboards) escalates per the tier table. - A
TRACKER_UPDATES:action is recommend-tier — the operator reviews it; the skill never auto-decides.
Label format (any accepted): inline Recommendation (MODERATE · confidence: HIGH): <text>; trailing <text> [MODERATE · confidence: HIGH]; or a Reversibility / Tier column in a findings table. pmo-qa-auditor G4 FAILs any decision-class item missing a tier.
Guardrails (Platform)
These platform-wide guardrails are inherited from CLAUDE.md § Universal Preferences and OPERATIONS.md; this skill consumes them by reference and does not restate their definitions.
- No invention / no fabricated owners, dates, metrics.
attributionnever invents an owner;timelinenever invents a date. Unknown = surface it in## Unknowns, never fill it in. - Validate day-of-week on every date reference (the load-bearing rule for
timeline). - No generalized dates. Use specific verified dates; never a range. When a date cannot be verified, stop and surface it — do not generalize.
- No status theater. Findings are decisions/actions, not recaps.
## Confirmedis the only no-action section, and it is evidence-backed. - Evidence-quality labels on every grounded claim (
[SOURCE],[INFERRED],[ASSUMPTION – CONFIRM],[CONTEXT],[RECOMMENDED]), alongside the confidence + band label. - Reversibility tier on decision-class items (see
## Reversibility Discipline). - Read-only. The skill audits and recommends; it never writes a tracker, a Tier-1 file, or a comm. Every mutation is staged or routed for approval.
- External-seam writes — a work-item record or knowledge page in a connected system, and their comment streams — follow
core/disciplines/external-seam-conduct.md: the record holds state, a comment addresses a person. This skill's read-only contract already forbids the write; the citation is what makes the shape binding on the staged output, so a finding routed for approval is drafted as something that belongs in the record's fields rather than as a dated audit comment somebody then pastes.
Reference docs
This skill consumes governed reference docs by role-name (duplicate-source-discipline; each doc owns its definitions).
| Reference | Owner | What this skill reads from it |
|---|---|---|
references/mode-intents.md |
this skill | The queryable 4-intent declarations per mode (all 9 modes; v1/v2/v3/v4 slices, all implemented) + the declared full-sweep membership table. |
references/rollup-mode.md |
this skill | The rollup mode (mode 8) sub-mode specs + the rollup-contract field mapping + the compose-not-absorb / bridge-file boundary. |
references/structure-mode.md |
this skill | The structure mode (mode 9) — the entity/field/relationship check contract, the completeness-score denominator model + coverage envelope, the ordered rule-class → section routing table, and the migration-telemetry surface. |
references/conformance-surface.md |
this skill | The full-mode architecture-conformance surfacing contract — the committed release/releases/architecture-conformance-summary.md read shape, the platform-context render rules, and the compose-not-absorb boundary with pmo-qa-auditor Mode I. |
references/evidence-matrix.md |
this skill | The MCP + local source map per mode + the drift-resolution rule (citing ADR-051). |
references/confidence-framework.md |
this skill | The finding → confidence + S0–S3 band mapping (citing staleness-confidence-standard.md). |
core/specs/staleness-confidence-standard.md |
core (ADR-043) | The canonical 4-band depth scale this skill projects onto. Consum |
…(truncated)