Skip to content

kb init: check rule claims and evidence at a pinned upstream SHA, and adapter lifecycle flips - #242

Merged
tzhouam merged 3 commits into
mainfrom
kb/init-pinned-claims
Sep 30, 2026
Merged

tzhouam merged 3 commits into
mainfrom
kb/init-pinned-claims

Conversation

@tzhouam

@tzhouam tzhouam commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Part 3/9 of kb init (design v3, sol-approved): the two deterministic checks kb init needs that existing code can't provide.

  • knowledge_service/pinned_claims.py (design §9.1): facts.attest observes the upstream head, but init writes a whole KB against one pinned baseline.
    • PinnedObserver implements facts.Observer over a local clone with head() fixed to the pin, plus is_ancestor().
    • Paths are resolved via ls-tree: a missing entry means absent, while an unreadable object or tree raises FactsError. Directories are paths but have no file text.
    • check_rules() uses the service's own facts.claims_in/observe, and also requires each cited PR's merge commit to be in the pin's history.
    • Evidence / evidence_for / check_evidence bind a 1-based line range at the pin to a SHA-256 that ignores line-ending style.
  • kb_service/lifecycle_flip.py (design §9.3): the one non-knowledge/ file init edits is the adapter manifest, which the knowledge L1 whitelist never sees.
    • check_lifecycle_flip() compares the parsed manifests with only the allowed key paths removed.
    • The comparison is type-strict (YAML 1 ≠ true ≠ 1.0), un-shares YAML aliases so an allowed removal can't hide a change made through an alias, and rejects recursive aliases.
    • check_flip_to_shadow() also requires enabled: true in shadow mode.

The service and publisher paths are unchanged: facts.attest/recheck and the Observer protocol.

Tests

  • test/test_kb_pinned_claims.py runs against temp git repos: claims before and after the pin, missing symbols, PRs merged after the pin or never merged, evidence range and hash, CRLF vs LF, directories, unreadable blob and tree objects, and an invalid pin.
  • test/test_kb_lifecycle_flip.py covers comments kept, the default mode, refused edits, type strictness, aliases, recursive aliases, and invalid YAML.
  • Local CI mirror: full pytest, doc links and citations, SPEC freshness --strict, and the knowledge linters, all green. The commit gate approved it.

🤖 Generated with Claude Code

…lifecycle flips

kb init (design v3 §9.1, §9.3) writes a knowledge base against one pinned
upstream baseline and edits one file outside knowledge/: the adapter
manifest. Neither was checkable with existing code: facts.attest observes
the upstream head, and the knowledge L1 whitelist only covers knowledge/.

- knowledge_service/pinned_claims.py: PinnedObserver implements
  facts.Observer over a local clone with head() fixed to the pin, plus
  is_ancestor(). check_rules() extracts claims exactly as the service does
  (facts.claims_in) and requires cited PRs to be merged into the pin's
  history. Evidence/evidence_for/check_evidence bind a line range at the
  pin to a content hash.
- kb_service/lifecycle_flip.py: check_lifecycle_flip() compares parsed
  manifests with only the allowed key paths removed; check_flip_to_shadow()
  also requires enabled: true in shadow mode.

The service and publisher paths (facts.attest/recheck, Observer) are
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T09:12:59.678563Z 014cfba PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 014cfba90c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

tzhouam and others added 2 commits September 30, 2026 17:36
…tory

git merge-base --is-ancestor exits 1 both for "not an ancestor" and when
the history walk hits an unreadable commit (it then only prints
"error: Could not read" on stderr). PinnedObserver.is_ancestor treated
every non-zero exit as "no", so a corrupt mirror made check_rules report
a PR merged before the pin as merged after it. Now 0 is yes, 1 with a
silent stderr is no, an unknown commit is still no, and anything else
raises FactsError so the caller retries. A corrupt candidate commit is
told apart from an absent one with cat-file --batch-check: both print
"missing", but only corruption writes an unpack error to stderr.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PinnedObserver.pull passed the injected lookup's exceptions straight
through: a missing gh binary raised FileNotFoundError and a network
failure ConnectionError, both bypassing callers' FactsError retry
handling. pull now re-raises FactsError unchanged, wraps anything else
in FactsError, and rejects a non-object answer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tzhouam
tzhouam merged commit e282310 into main Sep 30, 2026
2 checks passed
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