Skip to content

fix(knowledge): point diff_policy.py at knowledge/ instead of the missing vault/ - #249

Merged
zyntromedia merged 1 commit into
mainfrom
fix/diff-policy-vault
Sep 13, 2026
Merged

fix(knowledge): point diff_policy.py at knowledge/ instead of the missing vault/#249
zyntromedia merged 1 commit into
mainfrom
fix/diff-policy-vault

Conversation

@fig-ai-agent

@fig-ai-agent fig-ai-agent Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

🔧 Fix / Correction

What was broken

knowledge/scripts/diff_policy.py — the CI policy gate that is supposed to block an
unsafe index push — could not work as written:

VAULT_DIR = Path(__file__).resolve().parents[1] / "vault"

parents[1] is already knowledge/, so this resolved to knowledge/vault/, which
does not exist. Every run failed with:

[policy] FAIL vault directory not found: .../knowledge/vault

The notes have always lived directly in knowledge/. There is no vault/ subfolder.

What this changes

1. The path. The vault now defaults to the script's parent directory
(knowledge/), and the script works from any working directory — verified by running
it from /tmp.

2. The gate is aligned with sync_knowledge_index.py (merged in #245):

Before After
text.startswith("---") only Requires the same seven front matter keys the indexer requires: title, description, tags, doc_kind, status, owner, last_reviewed
Flagged every .md Skips README.md — it is structure, not content (the indexer skips it too)
No index check --index <json> detects a stale staged index: missing notes, changed body_hash, or a note_count that no longer matches the vault
Silent success Prints the note count: [policy] OK — 7 note(s) index-safe.

The docstring's second promise ("a staged index is consistent with the vault
content") was previously unimplemented; --index now delivers it.

Verification

Ran against the live knowledge/ on main, plus 11 cases:

Case Expected Result
knowledge/ as-is pass OK — 7 note(s) index-safe. exit 0
Run from /tmp (not repo root) pass exit 0
Note with no front matter fail exit 1, missing front matter
Note missing keys fail exit 1, lists the 6 missing keys
--changed <note>.md check only that note exit 0
--changed <non-md file> skip (not content) exit 0, 0 notes
--changed <missing>.md fail exit 1, missing:
--vault <nonexistent> fail clearly exit 1, vault directory not found
--index fresh index pass exit 0
--index after body edit fail exit 1, stale body_hash
--index missing a note fail exit 1, note not in index
--index malformed JSON fail exit 1, index unreadable

The indexed JSON used for the --index cases was produced by the merged
sync_knowledge_index.py ([index] 7 note(s), 176 record(s)), so the two agree.

Type

  • Refactor / cleanup
  • Bug fix

Scope

  • Correction / clarification

Checklist

  • No secrets or internal details leaked
  • Code is runnable — stdlib only, no new dependencies
  • Behaviour verified, not assumed — see the table above
  • Nothing else touched: one file changed, no workflows, no note content

Note

This script is not yet called by any workflow (the only reference is a mention in
ZYNTROAI-SCAFFOLD.md), so nothing regresses here — this makes the gate correct for
when it is wired in. A follow-up can add it to the knowledge CI job alongside
sync_knowledge_index.py.

…sing vault/

VAULT_DIR was parents[1] / "vault" = knowledge/vault, which does not exist, so
the policy gate failed on every run. It now defaults to the script's parent
directory (knowledge/) and the script is runnable from any cwd.

Also aligns the gate with sync_knowledge_index.py, which landed in #245:
- require the same seven front matter keys (was a loose 'starts with ---' check)
- skip README.md, which is structure rather than content
- add --index to detect a stale staged index (missing notes, changed body_hash)
- report the note count on success
VAULT_DIR = Path(__file__).resolve().parents[1]

_FRONTMATTER_RE = re.compile(r"^---\s*\n(.*?)\n---\s*\n?", re.DOTALL)
_HEADING_RE = re.compile(r"^#{1,6}\s+.+$", re.MULTILINE)

_FRONTMATTER_RE = re.compile(r"^---\s*\n(.*?)\n---\s*\n?", re.DOTALL)
_HEADING_RE = re.compile(r"^#{1,6}\s+.+$", re.MULTILINE)
_FENCE_RE = re.compile(r"```[\s\S]*?```")
@zyntromedia
zyntromedia merged commit ad37b1c into main Sep 13, 2026
5 of 9 checks passed
@zyntromedia
zyntromedia deleted the fix/diff-policy-vault branch September 13, 2026 21:47
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