Get the FREE Ultimate OpenClaw Setup Guide →

shipkit-framework-integrity

Scanned
npx machina-cli add skill stefan-stepzero/shipkit/shipkit-framework-integrity --openclaw
Files (1)
SKILL.md
35.7 KB

shipkit-framework-integrity - Framework Integrity Checker

Purpose: Validate the Shipkit framework repo is internally consistent and ready for release

What it does: Comprehensive integrity validation with smart caching:

  • Manifest ↔ disk sync (skills, agents)
  • Broken file references in all SKILL.md files
  • Cross-skill references validity
  • Hook file references and syntax
  • Installer integrity (paths, syntax)
  • Documentation counts and accuracy
  • Skips unchanged files since last check

When to Invoke

User says:

  • "Check framework integrity"
  • "Validate repo before release"
  • "Are there broken references?"
  • "Audit shipkit repo"
  • "Pre-release check"
  • "Run integrity check"

Use when:

  • Before publishing to GitHub
  • After aggressive refactoring or culling
  • After adding/removing skills
  • When skills fail to load unexpectedly
  • During release preparation

Prerequisites

Required:

  • Running from Shipkit framework repo root
  • install/skills/ directory exists
  • install/profiles/shipkit.manifest.json exists

Not required:

  • No external dependencies
  • No API keys

State File (Smart Caching)

Location: .claude/skills/shipkit-framework-integrity/.integrity-state.json

Structure:

{
  "lastFullCheck": "2025-02-05T10:30:00Z",
  "lastVerifiedVersion": "2.1.34",
  "fileHashes": {
    "install/skills/shipkit-spec/SKILL.md": "sha256:abc123...",
    "install/skills/shipkit-plan/SKILL.md": "sha256:def456...",
    "installers/install.py": "sha256:789xyz..."
  },
  "lastResults": {
    "errors": 0,
    "warnings": 2,
    "skipped": 15
  }
}

Caching Logic:

  1. On run, compute SHA-256 hash of each file
  2. Compare to stored hash in state file
  3. If unchanged → skip detailed validation, carry forward previous result
  4. If changed → run full validation
  5. Always re-check cross-cutting concerns (counts, manifest sync) since they depend on multiple files
  6. Update state file after check

Force full check: Pass --full or delete state file


Process

Step 0a: Ensure Changelog Freshness (Always Run)

Before running any checks, verify the Claude Code changelog is current.

1. Check if docs/development/claude-code-changelog.meta.json exists
   If NOT exists → run: bash docs/development/fetch-changelog.sh

2. If exists, read fetchedAt timestamp
   If older than 7 days → run: bash docs/development/fetch-changelog.sh

3. Read latestVersion from meta.json
   Store as: claude_code_version (e.g., "2.1.34")
   Display: "Claude Code changelog: v{claude_code_version} (fetched {date})"

Why: Framework integrity includes alignment with Claude Code's evolving feature set. Stale changelog = blind spots.


Step 0b: VERSION File Validation (Always Run)

Check VERSION file exists and is valid:

1. Verify VERSION exists
   If NOT exists:
     → ERROR: VERSION file missing (single source of truth for releases)

2. Read VERSION content, trim whitespace
   If empty or invalid semver:
     → ERROR: VERSION must contain valid semver (e.g., "1.3.0")

3. Check VERSION matches latest git tag (if tags exist):
   git describe --tags --abbrev=0 2>/dev/null
   If tag exists and doesn't match VERSION:
     → WARNING: VERSION ({version}) doesn't match latest git tag ({tag})

Why this matters: VERSION is the single source of truth. During installation:

  • Written to _shipkit key in settings.json
  • Inserted into CLAUDE.md markers

Stale VERSION = users get wrong version after update.


Step 1: Load State & Compute Hashes

import hashlib
import json
from pathlib import Path
from datetime import datetime

STATE_FILE = Path('.claude/skills/shipkit-framework-integrity/.integrity-state.json')

def load_state():
    if STATE_FILE.exists():
        return json.loads(STATE_FILE.read_text())
    return {"fileHashes": {}, "lastResults": {}}

def compute_hash(filepath):
    content = Path(filepath).read_bytes()
    return f"sha256:{hashlib.sha256(content).hexdigest()[:16]}"

def file_changed(filepath, state):
    current_hash = compute_hash(filepath)
    stored_hash = state.get("fileHashes", {}).get(str(filepath))
    return current_hash != stored_hash, current_hash

Step 2: Inventory Collection

Collect all skills on disk:

ls -1d install/skills/shipkit-*/

Collect all skills in manifest: Read install/profiles/shipkit.manifest.json and extract:

  • skills.mandatory[]
  • skills.optional[*][].name

Collect all agents on disk:

ls -1d install/agents/shipkit-*

Collect all agents in manifest: Read install/profiles/shipkit.manifest.jsonagents[].name


Step 3: Manifest ↔ Disk Sync (Always Run)

Check for orphan skills (on disk but not in manifest):

For each skill directory in install/skills/shipkit-*/:
  If skill_name NOT in manifest.skills.mandatory AND NOT in manifest.skills.optional:
    → ERROR: Orphan skill "{skill_name}" exists on disk but not in manifest

Check for ghost skills (in manifest but not on disk):

For each skill in manifest:
  If no directory exists at install/skills/{skill_name}/:
    → ERROR: Ghost skill "{skill_name}" in manifest but no directory exists

Check for orphan/ghost agents: Same logic for install/agents/


Step 4: Reference Validation in SKILL.md Files (Cached)

For each skill, if SKILL.md changed since last check:

CRITICAL: There are THREE types of references. Handle each differently:

TypePattern ExampleResolves ToCommon Use
Localreferences/foo.md{skill}/references/foo.mdSkill-specific docs
Sharedshared/references/foo.mdinstall/shared/references/foo.mdCross-skill standards
Cross-Skillshipkit-spec/references/foo.mdinstall/skills/shipkit-spec/references/foo.mdReuse another skill's docs

Type 1: Local References (most common)

Pattern: references/foo.md or templates/foo.md (NO prefix)

Example: "See references/best-practices.md for patterns"
Resolution: {skill_dir}/references/best-practices.md
Check: Does install/skills/shipkit-spec/references/best-practices.md exist?

Detection regex: (?<![/\w])references/[\w-]+\.md or (?<![/\w])templates/[\w-]+\.md (Negative lookbehind ensures no prefix like shared/ or shipkit-spec/)

Type 2: Shared References

Pattern: shared/references/foo.md

Example: "See also: shared/references/VERIFICATION-PROTOCOL.md"
Resolution: install/shared/references/VERIFICATION-PROTOCOL.md
Check: Does install/shared/references/VERIFICATION-PROTOCOL.md exist?

Detection regex: shared/references/[\w-]+\.md

Type 3: Cross-Skill References

Pattern: shipkit-{name}/references/foo.md or other-skill/references/foo.md

Example: "Reference: See shipkit-spec/references/best-practices.md"
Resolution: install/skills/shipkit-spec/references/best-practices.md
Check: Does install/skills/shipkit-spec/references/best-practices.md exist?

Detection regex: shipkit-[\w-]+/references/[\w-]+\.md


Validation logic (bash):

for skill in install/skills/shipkit-*/; do
  name=$(basename "$skill")

  # Type 1: Local references (no prefix)
  local_refs=$(grep -oE '(?<![/\w])references/[\w-]+\.md' "$skill/SKILL.md" 2>/dev/null | sort -u)
  for ref in $local_refs; do
    if [ ! -f "$skill/$ref" ]; then
      echo "BROKEN LOCAL: $name → $ref"
    fi
  done

  # Type 2: Shared references
  shared_refs=$(grep -oE 'shared/references/[\w-]+\.md' "$skill/SKILL.md" 2>/dev/null | sort -u)
  for ref in $shared_refs; do
    if [ ! -f "install/$ref" ]; then
      echo "BROKEN SHARED: $name → $ref"
    fi
  done

  # Type 3: Cross-skill references
  cross_refs=$(grep -oE 'shipkit-[\w-]+/references/[\w-]+\.md' "$skill/SKILL.md" 2>/dev/null | sort -u)
  for ref in $cross_refs; do
    if [ ! -f "install/skills/$ref" ]; then
      echo "BROKEN CROSS-SKILL: $name → $ref"
    fi
  done
done

Skip validation for:

  • URLs (http://, https://)
  • Placeholder paths (contains {variable})
  • User project paths (.shipkit/ context - these are templates for user projects)

Step 4b: Broken Reference Triage

When a broken reference is found, don't automatically create the file. First determine if the reference is necessary.

Decision Tree:

Broken reference found: {skill}/SKILL.md → references/{file}.md
    │
    ├─► Is this reference USED in the skill logic?
    │   (Does the skill say "Read:", "Load:", "See:" this file?)
    │       │
    │       ├─► YES, actively used
    │       │   └─► Does similar content exist elsewhere?
    │       │       ├─► YES → Consolidate/move content, update reference
    │       │       └─► NO  → Create the reference file with needed content
    │       │
    │       └─► NO, just mentioned/aspirational
    │           └─► REMOVE the stale reference from SKILL.md
    │
    └─► Is this a "shared/references/" path?
        └─► Check if ANY skill actually needs it
            ├─► YES → Create shared file
            └─► NO  → Remove references from all skills

Reference Necessity Indicators:

Pattern in SKILL.mdLikely NecessaryAction
Read: references/X.mdYes - actively loadedCreate or fix
Load references/X.mdYes - actively loadedCreate or fix
**See:** references/X.mdMaybe - informationalCheck if content exists inline
See references/X.md for...Maybe - informationalCheck if content exists inline
Just mentioned in passingNo - staleRemove reference

Report format for broken references:

BROKEN REFERENCE TRIAGE
───────────────────────
shipkit-spec/SKILL.md → references/best-practices.md
  Usage: "See references/best-practices.md for quality standards"
  Necessity: INFORMATIONAL (not actively loaded)
  Recommendation: Check if content exists inline; if yes, REMOVE reference

shipkit-project-context/SKILL.md → references/bash-commands.md
  Usage: "**Commands**: See references/bash-commands.md for platform-specific..."
  Necessity: LIKELY NEEDED (documentation reference)
  Recommendation: CREATE file or INLINE the content

Step 5: Cross-Skill Reference Validation (Cached)

For each SKILL.md, extract skill references:

Patterns:

  • /shipkit-{name} — slash command references
  • shipkit-{name} in "After This Skill" / "Before This Skill" sections
  • install/skills/shipkit-{name} — explicit paths

Validate each reference:

For each referenced skill name:
  If install/skills/{skill_name}/ does NOT exist:
    → ERROR: {source_skill} references non-existent skill "{skill_name}"

Step 6: Hook Validation

6.1: Hook files exist:

Required hooks in install/shared/hooks/:
- shipkit-session-start.py
- shipkit-after-skill-router.py
- shipkit-track-skill-usage.py
- shipkit-relentless-stop-hook.py

For each required hook:
  If NOT exists:
    → ERROR: Required hook missing: {hook_name}

6.2: Hook syntax validation:

python -m py_compile install/shared/hooks/*.py

6.3: Skills referencing hooks:

For each SKILL.md mentioning a hook file:
  Extract hook filename
  If hook file does NOT exist:
    → ERROR: {skill_name} references non-existent hook "{hook_file}"

Step 7: Installer Integrity (Cached)

Two installers exist and must stay in sync: the npx CLI (cli/src/) and the Python installer (installers/install.py).

7.1a: npx CLI syntax validation:

node -e "require('./cli/src/index')"
node -e "require('./cli/src/hooks')"
node -e "require('./cli/src/settings')"

7.1b: Python installer syntax validation:

python -m py_compile installers/install.py
python -m py_compile installers/uninstall.py

7.2: Installer path references:

Both installers reference these paths (must exist on disk):

INSTALLER_REQUIRED_PATHS = [
    "install/shared",
    "install/shared/hooks",
    "install/skills",
    "install/agents",
    "install/settings",
    "install/claude-md",
    "install/profiles",
    "docs/generated"
]

The npx CLI also requires:

NPX_CLI_REQUIRED_PATHS = [
    "cli/bin/shipkit.js",
    "cli/src/index.js",
    "cli/src/init.js",
    "cli/src/update.js",
    "cli/src/hooks.js",
    "cli/src/settings.js",
    "VERSION",
    "package.json"
]

Validate:

For each required path:
  If NOT exists:
    → ERROR: Installer references missing path: {path}

7.3: Manifest validity:

For each .manifest.json in install/profiles/:
  Try to parse as JSON
  If fails:
    → ERROR: Invalid JSON in {manifest_file}

  Check required keys exist:
  - skills.mandatory (array)
  - skills.optional (object)
  - agents (array)

7.4: Installer Coverage Check (CRITICAL):

Both installers have hardcoded hook mappings. If a new hook is added to install/shared/hooks/, it won't be installed unless BOTH installers are updated.

npx CLI hooks — defined in cli/src/hooks.js (buildHooksConfig) and cli/src/init.js (HOOK_FILES mapping):

// cli/src/init.js HOOK_FILES — maps source name to installed name
const HOOK_FILES = {
    "shipkit-session-start.py": "session-start.py",
    "shipkit-after-skill-router.py": "after-skill-router.py",
    "shipkit-relentless-stop-hook.py": "shipkit-relentless-stop-hook.py",
    "shipkit-track-skill-usage.py": "shipkit-track-skill-usage.py",
    "shipkit-task-completed-hook.py": "shipkit-task-completed-hook.py",
    "shipkit-teammate-idle-hook.py": "shipkit-teammate-idle-hook.py"
};

// cli/src/hooks.js buildHooksConfig — hooks wired in settings.json
// Must reference the DESTINATION names from HOOK_FILES above

Python installer hooks — hardcoded in install_shared_core():

# Extract from shutil.copy2() calls
INSTALLER_HARDCODED_HOOKS = [
    "shipkit-session-start.py",
    "shipkit-after-skill-router.py",
    "shipkit-track-skill-usage.py",
    "shipkit-relentless-stop-hook.py",
    "shipkit-task-completed-hook.py",
    "shipkit-teammate-idle-hook.py"
]

Validate coverage:

1. List all .py files in install/shared/hooks/
2. Compare to HOOK_FILES keys from cli/src/init.js
3. Compare to INSTALLER_HARDCODED_HOOKS from installers/install.py
4. For each hook on disk NOT in npx CLI:
   → ERROR: Hook "{hook}" exists but npx CLI won't install it
   → Action: Update cli/src/init.js HOOK_FILES

5. For each hook on disk NOT in Python installer:
   → ERROR: Hook "{hook}" exists but Python installer won't install it
   → Action: Update installers/install.py

6. For each hook in settings.json wiring NOT in HOOK_FILES destinations:
   → ERROR: settings.json references hook "{dest}" but CLI won't copy it

7.5: npx CLI ↔ Python installer consistency:

The canonical settings structure is defined in install/settings/shipkit.settings.json. Both installers must produce equivalent output.

1. Read cli/src/hooks.js buildHooksConfig() output structure
2. Read install/settings/shipkit.settings.json hooks section
3. Compare: hook events, matchers, commands, timeouts must match
   → ERROR if any mismatch between CLI hooks and canonical settings

4. Read cli/src/settings.js generateSettings() permission list
5. Read install/settings/shipkit.settings.json permissions
6. Compare: base permissions (non-Skill entries) must match
   → WARNING if base permissions differ between CLI and canonical settings

7. Check package.json version matches VERSION file
   → ERROR if version mismatch (npm publish will fail)

Why this matters:

  • Skills: Driven by manifest → auto-discovered ✓
  • Agents: Driven by manifest → auto-discovered ✓
  • Hooks: Hardcoded in both installers → must be manually synced ✗
  • Settings: Duplicated in npx CLI → must match canonical file ✗

Step 8: 7-File Integration Consistency

File 1: SKILL.md exists — Covered in Step 3

File 2: Overview HTML:

Read: docs/generated/shipkit-overview.html
For each skill in manifest:
  If skill_name NOT found in HTML:
    → WARNING: {skill_name} not listed in overview HTML

Extract skill count from HTML (stat-number)
Compare to manifest count
If mismatch:
  → WARNING: HTML shows {html_count} skills, manifest has {manifest_count}

File 3: Rules file skill reference:

Read: install/rules/shipkit.md
For each skill in manifest (excluding shipkit-detect, shipkit-master):
  If "/{skill_name}" NOT found:
    → WARNING: {skill_name} not in rules skill reference table

Note: The skill reference table lives in install/rules/shipkit.md (not
install/claude-md/shipkit.md). This file is installed to .claude/rules/
and auto-loaded every session, so missing skills = invisible to users.

File 4: Manifest — Covered in Step 7.3

File 5: Hooks — Covered in Step 6

File 6: Master routing:

Read: install/skills/shipkit-master/SKILL.md
For each skill in manifest (excluding shipkit-master, shipkit-detect):
  If skill_name NOT found in master routing:
    → WARNING: {skill_name} not in master routing table

File 7: Settings permissions:

Read: install/settings/shipkit.settings.json
Validate JSON syntax
For each skill in manifest:
  If "Skill({skill_name})" NOT in permissions.allow:
    → ERROR: {skill_name} missing from settings permissions

Step 9: Documentation Count Validation (Always Run)

README.md skill count:

Read: README.md
Extract claimed skill count (pattern: "\d+ skills")
Compare to actual count from manifest
If mismatch:
  → WARNING: README claims {claimed} skills, manifest has {actual}

CLAUDE.md skill count:

Read: CLAUDE.md
Extract claimed skill count from "Total:" line
Compare to actual count
If mismatch:
  → WARNING: CLAUDE.md claims {claimed} skills, manifest has {actual}

Step 9b: JSON Artifact Migration Tracking (Always Run)

Check: Which skills output structured data to .shipkit/ and whether they use the JSON artifact convention.

Logic:

1. Scan all SKILL.md files for "Context Files This Skill Writes" sections
2. Extract output paths that write to .shipkit/
3. Classify each:
   - .json with $schema: "shipkit-artifact" → ✓ Migrated
   - .json without convention → ⚠ JSON but missing convention
   - .md with structured data (lists, status, counts) → ⚠ Should migrate
   - .md with narrative content (specs, plans, decisions) → ✓ Correct as markdown

4. Report migration progress

Classification rules:

Output PatternClassification
.shipkit/*.json with $schema: "shipkit-artifact" in SKILL.md✓ JSON artifact
.shipkit/*.md with structured/countable data⚠ Migration candidate
.shipkit/specs/active/*.json, .shipkit/plans/active/*.json✓ Migrated to JSON
.shipkit/architecture.json✓ Migrated to JSON
.shipkit/why.json✓ Migrated to JSON
No .shipkit/ output (NONE strategy)⊘ N/A

Report format:

JSON ARTIFACT MIGRATION
───────────────────────
Migrated to JSON:     1/N skills (goals.json)
Candidates for JSON:  X skills
Correct as markdown:  Y skills
No output:           Z skills

Migration candidates:
  ✓ shipkit-project-status → .shipkit/status.json (migrated)
  ✓ shipkit-work-memory → .shipkit/progress.json (migrated)

Reference: install/skills/shipkit-goals/SKILL.md (JSON artifact pattern)
Convention: $schema, type, version, lastUpdated, source, summary

Why this matters: JSON artifacts are natively visualizable by external dashboards. Progressive migration ensures tooling gets richer data over time without requiring a big-bang rewrite.


Step 9c: Claude Code Compatibility Audit (Always Run)

Framework-wide check against current Claude Code changelog.

Read docs/development/claude-code-changelog.md and validate:

9b.1: Hook Event Coverage

Check: All hook events our hooks handle still exist in Claude Code

Current hook events (from changelog):
- SessionStart (v1.0.62)
- PreToolUse (v1.0.38) — supports additionalContext (v2.1.9)
- PostToolUse (v1.0.38)
- Stop (v1.0.38)
- SubagentStart (v2.0.43)
- SubagentStop (v1.0.41) — has agent_id, agent_transcript_path (v2.0.42)
- Notification (v2.0.37)
- PermissionRequest (v2.0.45)
- PreCompact (v1.0.48)
- TeammateIdle (v2.1.33)
- TaskCompleted (v2.1.33)

For each hook in install/shared/hooks/:
  Extract which events it handles (from settings.json hook config)
  If event NOT in known events list:
    → WARNING: Hook handles unknown event "{event}" - may be deprecated

9b.2: Settings Schema Compatibility

Check: Our settings.json uses valid structure and fields

For install/settings/shipkit.settings.json:
  Validate known top-level keys:
  - permissions.allow — array of permission strings
  - hooks — hook configuration
  - env — environment variables (if any)

  Check permission string formats:
  - Skill({name}) — valid since v2.0.20
  - Bash({pattern}) — wildcard patterns valid since v2.1.0
  - mcp__{server}__{tool} — wildcard valid since v2.1.0

  If any permission uses unrecognized format:
    → WARNING: Permission "{perm}" uses unrecognized format

9b.3: Framework-Wide Deprecated Pattern Scan

Check: Scan ALL skills and agents for deprecated patterns

Deprecated patterns to scan for across entire install/:
- ".claude.json" references (allowedTools/ignorePatterns removed v2.0.8)
- "includeCoAuthoredBy" (deprecated v2.0.62, use attribution)
- Legacy SDK entrypoint references (removed v1.0.123)
- Bash commands doing file operations (Read/Edit/Glob/Grep preferred since v2.1.0)

For each match found:
  → WARNING: {file} uses deprecated pattern: {pattern}
  → Suggestion: {replacement}

9b.4: New Feature Adoption Summary

Check: Which newer Claude Code features the framework could leverage

Feature adoption report (INFO level):

Agent Memory (v2.1.33):
  Agents using `memory` field: {count}/{total}
  Agents that could benefit: [list]

Skill Context Fork (v2.1.0):
  Skills using `context: fork`: {count}/{total}

Frontmatter Hooks (v2.1.0):
  Skills/agents using inline `hooks`: {count}/{total}

YAML-style allowed-tools (v2.1.0):
  Skills using YAML lists: {count}/{total}

Plugin System (v2.0.12):
  Framework packaged as plugin: YES/NO

Note: This is informational only — no errors or warnings. Helps track modernization progress.


9b.5: Changelog Version Drift Alert

Check: How far behind our last-verified version is

Read: docs/development/claude-code-changelog.meta.json → latestVersion
Read: .claude/skills/shipkit-framework-integrity/.integrity-state.json → lastVerifiedVersion (if exists)

If latestVersion != lastVerifiedVersion:
  Count versions between them
  Summarize key changes affecting framework:
    - New frontmatter fields
    - New hook events
    - Breaking changes
    - Deprecations

  → INFO: {N} new Claude Code versions since last integrity check
  → Key changes: [summary list]

Store lastVerifiedVersion in state file after successful check.


Step 10: Save State & Generate Report

Update state file:

def save_state(state, new_hashes, results):
    state["lastFullCheck"] = datetime.utcnow().isoformat() + "Z"
    state["fileHashes"] = new_hashes
    state["lastResults"] = results
    STATE_FILE.parent.mkdir(parents=True, exist_ok=True)
    STATE_FILE.write_text(json.dumps(state, indent=2))

Output format:

============================================
SHIPKIT FRAMEWORK INTEGRITY REPORT
============================================
Timestamp: 2025-02-05T10:30:00Z
Mode: Incremental (15 files unchanged, 3 files checked)

MANIFEST ↔ DISK SYNC
─────────────────────
Skills on disk:     27
Skills in manifest: 27
Agents on disk:     6
Agents in manifest: 6

✓ All skills synced
✓ All agents synced

BROKEN REFERENCES
─────────────────
Files checked: 3 (24 skipped - unchanged)

Local References (references/foo.md → skill's own directory):
  ✗ shipkit-verify → references/quality-checklist.md (NOT FOUND)
  ✗ shipkit-preflight → templates/audit-template.md (NOT FOUND)

Shared References (shared/references/foo.md → install/shared/):
  ✓ All shared references valid

Cross-Skill References (shipkit-X/references/foo.md → other skill):
  ✓ All cross-skill references valid

CROSS-SKILL REFERENCES
──────────────────────
✓ All cross-skill references valid

HOOK VALIDATION
───────────────
✓ All 4 required hooks present
✓ Hook syntax valid
✓ No broken hook references in skills

INSTALLER INTEGRITY
───────────────────
✓ npx CLI syntax valid (cli/src/*.js)
✓ installers/install.py syntax valid
✓ installers/uninstall.py syntax valid
✓ All installer paths exist (shared + CLI)
✓ All manifest files valid JSON
✓ Hook coverage: 6/6 hooks in npx CLI, 6/6 in Python installer
✓ npx CLI hooks match canonical settings
✓ package.json version matches VERSION

7-FILE INTEGRATION
──────────────────
✓ File 1: All SKILL.md files exist
✓ File 2: Overview HTML complete
⚠ File 3: rules/shipkit.md missing 1 skill
✓ File 4: Manifest valid
✓ File 5: Hooks valid
✓ File 6: Master routing complete
✓ File 7: Settings permissions complete

DOCUMENTATION COUNTS
────────────────────
README.md:      27 skills ✓
CLAUDE.md:      27 skills ✓
Overview HTML:  27 skills ✓

JSON ARTIFACT MIGRATION
───────────────────────
Migrated to JSON:     1 skill (goals.json)
Candidates for JSON:  3 skills
Correct as markdown:  12 skills
No output:           11 skills

⚠ Migration candidates:
  shipkit-project-status → structured health data
  shipkit-work-memory → session progress log

CLAUDE CODE COMPATIBILITY (v{claude_code_version})
───────────────────────────────────────────────────
✓ All hook events recognized
✓ Settings schema valid
⚠ 2 deprecated patterns found
ⓘ Feature adoption: 3/9 agents use memory field

============================================
SUMMARY
============================================
Errors:   2 (must fix before release)
Warnings: 1 (should fix)
Skipped:  24 files (unchanged since last check)

ERRORS:
1. [BROKEN] shipkit-verify references non-existent file
2. [BROKEN] shipkit-preflight references non-existent file

WARNINGS:
1. [DOCS] shipkit-new-skill not in shipkit.md

============================================
RESULT: FAIL (2 errors must be resolved)
============================================

State saved to: .claude/skills/shipkit-framework-integrity/.integrity-state.json

Validation Rules Summary

CheckSeverityCachedDescription
VERSION missingERRORNoVERSION file doesn't exist
VERSION invalidERRORNoVERSION file empty or not valid semver
VERSION/tag mismatchWARNINGNoVERSION doesn't match latest git tag
Orphan skillERRORNoSkill directory exists but not in manifest
Ghost skillERRORNoSkill in manifest but no directory
Broken referenceERRORYesSKILL.md references file that doesn't exist
Cross-skill ref invalidERRORYesSkill references another skill that doesn't exist
Missing hookERRORNoRequired hook file missing
Hook syntax errorERRORYesPython file has syntax errors
Installer syntax errorERRORYesInstaller Python files have syntax errors
Installer path missingERRORNoPath referenced by installer doesn't exist
Hook not in installerERRORNoHook exists on disk but installer won't copy it
Invalid manifest JSONERRORYesManifest file has JSON syntax errors
Missing permissionERRORNoSkill not in settings.json allow list
Count mismatchWARNINGNoDoc counts don't match manifest
Missing from routingWARNINGNoSkill not in master routing table
Missing from docsWARNINGNoSkill not in rules/shipkit.md skill reference table
Stale referenceWARNINGYesReference exists but isn't actively used (triage needed)
Unknown hook eventWARNINGNoHook handles event not in changelog's known events
Deprecated patternWARNINGNoCode uses pattern deprecated in changelog
Stale changelogWARNINGNoChangelog >7 days old or missing
Version driftINFONoNew Claude Code versions since last check
Feature opportunityINFONoFramework could leverage newer features
JSON migration candidateWARNINGNoSkill outputs structured .md that should be .json
JSON convention missingWARNINGNoSkill outputs .json but missing artifact convention

Command Line Options

/shipkit-framework-integrity [options]

Options:
  --full        Force full check, ignore cache
  --quick       Only check manifest sync and counts (fastest)
  --fix         Attempt to auto-fix simple issues
  --json        Output results as JSON
  --loop N      Run up to N iterations, re-checking after fixes (default: 3 if no N)

Loop Mode

When invoked with --loop N, the skill runs iteratively — checking, fixing, and re-checking — until either zero errors/warnings remain or N iterations are exhausted.

State file: .shipkit/framework-integrity-loop.local.md

Default completion promise: "Framework integrity check reports zero errors and zero warnings"

How it works:

  1. Parse --loop N from arguments (default N=3 if omitted)
  2. Create state file with frontmatter (skill, iteration, max_iterations, completion_promise)
  3. Run the normal integrity check
  4. Update the Progress section in the state file with findings and fixes applied
  5. If zero errors and zero warnings → delete state file, report success, stop
  6. If issues remain → end response; the relentless stop hook blocks exit and re-prompts

Example:

/shipkit-framework-integrity --loop 3 --fix

This runs up to 3 iterations of check-fix-recheck. Combines with --fix for automated repair across passes (e.g., pass 1 fixes manifest sync, pass 2 fixes references revealed by the sync fix).

Shared reference: See .claude/skills/_shared/loop-mode-reference.md for state file format and protocol details.


When This Skill Integrates with Others

Before This Skill

  • After refactoring skills or removing files
  • After adding/removing skills or agents
  • Before git push to main branch

After This Skill

  • Fix identified issues manually
  • Re-run with --full to verify fixes
  • Proceed with release/commit

Related Skills

  • shipkit-dev-specshipkit-dev-plan — Design and plan new skills/changes
  • shipkit-dev-review — Reviews changes for quality after implementation

Context Files This Skill Reads

Core files:

  • install/profiles/shipkit.manifest.json — Source of truth for skills/agents
  • install/settings/shipkit.settings.json — Permissions list
  • install/claude-md/shipkit.md — User-facing project instructions template
  • install/rules/shipkit.md — Skill reference table (auto-loaded every session)
  • install/skills/shipkit-master/SKILL.md — Routing table

Installer files:

  • cli/bin/shipkit.js — npx CLI entry point
  • cli/src/hooks.js — npx CLI canonical hooks config
  • cli/src/settings.js — npx CLI settings generator
  • cli/src/init.js — npx CLI HOOK_FILES mapping
  • package.json — npm package config (version must match VERSION)
  • installers/install.py — Python installer (fallback)
  • installers/uninstall.py — Uninstaller

All skill files:

  • install/skills/shipkit-*/SKILL.md — Each skill's definition
  • install/skills/shipkit-*/references/* — Reference files
  • install/skills/shipkit-*/templates/* — Template files

All agent files:

  • install/agents/shipkit-*.md — Agent persona files

Hook files:

  • install/shared/hooks/*.py — All hook files

Documentation:

  • README.md — Skill count claims
  • CLAUDE.md — Skill count claims
  • docs/generated/shipkit-overview.html — HTML help

Claude Code changelog (auto-fetched if stale):

  • docs/development/claude-code-changelog.md - Full changelog from GitHub
  • docs/development/claude-code-changelog.meta.json - Freshness metadata
  • docs/development/fetch-changelog.sh - Fetch script

State file:

  • .claude/skills/shipkit-framework-integrity/.integrity-state.json

Context Files This Skill Writes

Write Strategy: STATE FILE ONLY

  • .claude/skills/shipkit-framework-integrity/.integrity-state.json — Caching state
  • .shipkit/framework-integrity-loop.local.md — Loop mode state (only when --loop N used, deleted on completion)

This skill:

  • Does NOT modify source files (unless --fix is used)
  • Reports issues found
  • User must fix issues manually (unless --fix)

Success Criteria

Validation is complete when:

  • Changelog freshness verified (fetched if stale >7 days)
  • Manifest ↔ disk sync verified
  • All SKILL.md files scanned for broken references (or skipped if unchanged)
  • Cross-skill references validated
  • All hooks present and syntax valid
  • Installer syntax and paths valid
  • 7-file integration consistency verified
  • Documentation counts validated
  • Claude Code compatibility audit complete
  • State file updated with current hashes and lastVerifiedVersion
  • Clear PASS/FAIL result with actionable items

Example Session

User: "/shipkit-framework-integrity"

Claude:
Loading state file...
  Last check: 2025-02-04T15:00:00Z
  24 files unchanged, 3 files modified since last check

Running integrity check...

1. Checking manifest ↔ disk sync...
   ✓ 28 skills synced
   ✓ 6 agents synced

2. Scanning SKILL.md files for broken references...

   LOCAL REFERENCES (references/foo.md → skill's own directory):
   ✗ shipkit-ux-audit → references/common-patterns.md (NOT FOUND)
   ✗ shipkit-ux-audit → references/ux-principles.md (NOT FOUND)
   ✓ shipkit-spec → references/best-practices.md
   ✓ shipkit-master → references/file-freshness-logic.md

   SHARED REFERENCES (shared/references/foo.md → install/shared/):
   ✓ VERIFICATION-PROTOCOL.md exists (used by 5 skills)

   CROSS-SKILL REFERENCES (shipkit-X/references/foo.md):
   ✓ shipkit-plan → shipkit-spec/references/best-practices.md

3. Checking hooks...
   ✓ All 4 required hooks present
   ✓ Syntax valid
   ✓ All hooks covered by installer

4. Checking installer integrity...
   ✓ Installer syntax valid
   ✓ All paths exist

5. Validating 7-file integration...
   ✓ All integration files consistent

6. Checking documentation counts...
   ✓ All counts match (28 skills)

============================================
RESULT: FAIL (2 broken local references)

BROKEN LOCAL REFERENCES:
  shipkit-ux-audit/SKILL.md:
    ✗ references/common-patterns.md
    ✗ references/ux-principles.md

To fix: CREATE the missing files OR REMOVE the references from SKILL.md
(Use sub-agent triage to determine which action is appropriate)
============================================

Source

git clone https://github.com/stefan-stepzero/shipkit/blob/main/.claude/skills/shipkit-framework-integrity/SKILL.mdView on GitHub

Overview

Validates the Shipkit framework repo is internally consistent and ready for release. It performs comprehensive integrity checks including manifest ↔ disk sync for skills and agents, broken SKILL.md references, cross-skill dependencies, hook references, installer integrity, and documentation counts, while auto-fetching the Claude Code changelog to ensure compatibility. It uses smart caching to skip unchanged files and flags deprecated patterns, unknown hook events, and feature adoption gaps.

How This Skill Works

On each run, it computes SHA-256 hashes of tracked files and compares them to a stored state at .claude/skills/shipkit-framework-integrity/.integrity-state.json. Unchanged files skip detailed validation; changed ones trigger full checks across references, manifest-disk sync, installers, hooks, and docs accuracy, then update the state. It also auto-fetches the Claude Code changelog (Step 0a) and validates the VERSION file (Step 0b) before validation; force a full recheck with --full or by deleting the state file.

When to Use It

  • Before publishing to GitHub
  • After aggressive refactoring or culling
  • After adding or removing skills
  • When skills fail to load unexpectedly
  • During release preparation

Quick Start

  1. Step 1: Run the integrity checker from the Shipkit framework repo root
  2. Step 2: Run with --full (or use --quick/--json as needed) if you recently refactored or added/removed skills; caching will skip unchanged files
  3. Step 3: Inspect .claude/skills/shipkit-framework-integrity/.integrity-state.json and fix any issues, then re-run

Best Practices

  • Run after major refactors or changes to skills, installers, or docs
  • Run with --full on first pass after refactors to ensure comprehensive checks
  • Let the tool fetch the Claude Code changelog automatically (Step 0a) before finalizing release
  • Verify VERSION and git tag alignment (Step 0b) as part of the release process
  • Review and fix flagged deprecated patterns, unknown hook events, and feature adoption gaps

Example Use Cases

  • Pre-release audit to catch broken SKILL.md references across skills
  • Post-refactor audit after reorganizing install/skills tree and hooks
  • Changelog compatibility check to ensure Claude Code alignment
  • Detected deprecated patterns and unknown hook events to be updated
  • Incremental check using state caching to save time on unchanged files

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers