Skip to content

feat(safety-net): vault-integrity-check for Hive vault_patch corruption (SDD-006)#63

Merged
mlorentedev merged 1 commit into
mainfrom
feat/SDD-006-vault-integrity-check
May 20, 2026
Merged

feat(safety-net): vault-integrity-check for Hive vault_patch corruption (SDD-006)#63
mlorentedev merged 1 commit into
mainfrom
feat/SDD-006-vault-integrity-check

Conversation

@mlorentedev
Copy link
Copy Markdown
Owner

Summary

Closes a meta-issue surfaced by the user: the safety net has to keep improving itself. In one session, Hive's vault_patch MCP wrote the literal [BS-n] sequence into dotfiles/11-tasks.md four times instead of interpreting it as a newline. The corruption is invisible in rendered markdown but breaks init-spec.sh's vault-gate grep and any downstream line-based parser. Each occurrence was patched manually; no guard was added. By the 4th occurrence the principle was clear: every bug class encountered must emit a CI assertion or health check in the SAME PR.

Three sibling instances this session reinforce the pattern: BUG-001/002 verify-string drift (fixed retroactively with tests/setup-windows.bats parity asserts), AI-019 missing .github/copilot-instructions.md Model Tier section (fixed in SDD-005 with tests/docs-drift.bats), and now this Hive [BS-n] corruption.

SDD checklist

  • Vault entry SDD-006-vault-integrity-check in 11-tasks.md
  • Spec folder specs/SDD-006-vault-integrity-check/
  • proposal.md filled (Why / What / AC / Risks)
  • tasks.md in TDD order
  • verification.md filled with evidence

SDD skip rationale

Changes

  • scripts/check-md-escapes.sh: standalone scanner. Accepts file/dir, exits 0/1/2. Detects the canonical corruption signature ([BS-n] followed by -#>*). set -euo pipefail; shellcheck --severity=error clean.
  • tests/check-md-escapes.bats: 9 test cases including a self-test that scans the entire dotfiles repo. Future corruption in this repo fails CI loud at PR time.
  • Vault lesson dotfiles/90-lessons.md: incident-to-guard pattern documented with three sibling instances.

Test plan

  • bats tests/check-md-escapes.bats → 9/9 green:
    • existence + executable
    • usage error (no args)
    • missing-path error
    • bullet-merge corruption detected
    • header-merge corruption detected
    • healthy markdown stays silent
    • recursive directory scan
    • excludes .obsidian/ + node_modules/ + .git/
    • self-test: dotfiles repo markdown is clean
  • bats tests/*.bats659/659 pass (was 650; +9 from new bats file)
  • shellcheck --severity=error scripts/check-md-escapes.sh clean
  • Manual smoke against vault 11-tasks.md and entire dotfiles repo → both clean

Notable decisions

  • Narrow pattern [BS-n][-#>*] over [BS-n] alone. Real corruption matched the narrow pattern in 4/4 occurrences; broadening only adds noise.
  • Standalone script + bats coverage instead of wiring into vault-health.sh. vault-health.sh requires Obsidian GUI running which CI cannot satisfy. Standalone script + self-test runs anywhere.
  • Self-test runs against entire $DOTFILES_DIR, not curated allowlist. Catches future markdown corruption without maintenance.

Out of scope

  • Fixing Hive's MCP tool. Out of this repo's control.
  • Wiring into vault-health.sh Section 7. Defer (GUI dependency).
  • Pre-commit hook in the vault repo. Lives in the vault repo, not dotfiles.
  • Triple-backtick code-block exclusion in v1 (re-evaluate if a real false positive emerges).

…on (SDD-006)

In a single session today, Hive's vault_patch MCP wrote the literal 2-character
sequence backslash-n into dotfiles/11-tasks.md four times instead of interpreting
it as a newline. The corruption is invisible in rendered markdown but breaks
init-spec.sh's vault-gate grep and any downstream line-based parser.

User surfaced the meta-issue: the safety net has to keep improving itself. Every
bug class encountered MUST emit a CI assertion or health check in the SAME PR.
Captured as a vault lesson ("Incident → guard pattern (red-team thyself)").

Changes:
* scripts/check-md-escapes.sh: standalone scanner. Accepts file/dir, exits 0/1/2.
  Detects the canonical corruption signature ([BS-n] followed by -#>*).
  set -euo pipefail; shellcheck --severity=error clean.
* tests/check-md-escapes.bats: 9 cases including a self-test that scans the
  entire dotfiles repo. Future corruption in this repo fails CI loud at PR time.
* Vault lesson dotfiles/90-lessons.md: incident-to-guard pattern documented with
  three sibling instances (BUG-001/002 verify-string drift, AI-019 missed
  .github/copilot-instructions.md, this Hive [BS-n] corruption).

Tests: 659/659 bats green (was 650; +9 from check-md-escapes.bats).
Spec: specs/SDD-006-vault-integrity-check/.
@mlorentedev mlorentedev merged commit e454445 into main May 20, 2026
6 checks passed
@mlorentedev mlorentedev deleted the feat/SDD-006-vault-integrity-check branch May 20, 2026 02:45
mlorentedev added a commit that referenced this pull request May 21, 2026
Move from specs/ to specs/archive/ per SDD lifecycle close (the
folder move IS the archive marker; status: archived frontmatter
update deferred to per-spec follow-up if needed).

This session shipped (today, 2026-05-21):
  - AI-014-opencode-windows-bootstrap (PR #78)
  - BUG-014-claude-mem-marketplace-register (PR #75)
  - BUG-016-claude-mem-heal-v13-refresh (PR #83)
  - BUG-017-claude-mem-heal-hooks-json-race (PR #84)
  - BUG-018-userpromptsubmit-continue-directive (PR #85)
  - REFACTOR-003-diff-check-ps1 (PR #82)

Catch-up archive (merged earlier weeks but specs/ folder lingered):
  - BUG-007-remove-github-plugin-broken (PR #65, 2026-05-19)
  - BUG-011-mcp-loop-claude-json-guard (PR #69, 2026-05-20)
  - BUG-012-claude-mem-marketplace-junction (PR #70, 2026-05-20)
  - SDD-005-github-copilot-instructions-sync (PR #62, 2026-05-19)
  - SDD-006-vault-integrity-check (PR #63, 2026-05-19)

Active specs remaining in specs/ (not yet merged):
  - REFACTOR-002-paths-in-env-contract (queued, still draft)
  - WIN-002-windows-smoke-sweep (partial closure via PR #73, full
    clean-VM sweep still open)

33 file moves total (3 files per spec × 11 specs). Zero content change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant