Skip to content

Add the knowledge service core: repo registry, ledger, signed outbox - #206

Merged
tzhouam merged 1 commit into
mainfrom
kb/knowledge-service-core
Sep 28, 2026
Merged

tzhouam merged 1 commit into
mainfrom
kb/knowledge-service-core

Conversation

@tzhouam

@tzhouam tzhouam commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator

Fourth PR of the knowledge-base redesign: the knowledge service core. There are no workflows or scheduler yet; those build on this.

What changes

  • kb_service.config: each adapter's knowledge_lifecycle section becomes a repo registry. general/ is configured by the service. Invalid configuration is refused, including a private upstream in auto_merge and auto_merge without a calibration set. knowledge_lifecycle joins HIGH_RISK_SECTIONS, so only a human can enable auto-merge.
  • kb_service.ledger:
    • one SQLite file, every table keyed by repo;
    • a heartbeat lease so only one instance runs;
    • per-repo and global generation numbers. Pause, resume and any mode change bump the generation.
  • knowledge_service.signing: Ed25519 envelopes with purpose-tagged signatures, so a verdict, outbox item, control record, hold list or ack signature can't be replayed across purposes. Keys are 0600 and never overwritten. Vendorable; adds a new kb extra (cryptography).
  • kb_service.outbox:
    • Service side: signs outbox items, the control record and the hold list, and reads acks signed by the publisher's key. Publishing takes an interprocess lock, and pause/resume run as locked transitions, so an overlapping refresh can't republish pre-pause state.
    • The public hold list lists public repos only.
    • check_item() runs on the publisher before any write and checks:
      • signature;
      • control record no older than 10 minutes;
      • expiry and generation;
      • pause;
      • private upstream;
      • only auto_merge repos get non-stop writes: shadow and disabled repos publish nothing. pause and close are always allowed.
    • verify_holds() fails closed on a stale list.
  • CLI: infermatrix-copilot kb keygen|status|pause|resume|control.
  • Adapters: vllm-omni gets knowledge_lifecycle in shadow mode with its release_audit.py auditor. afd-plugin is declared but disabled until it has its own calibration set.
  • CI installs the kb extra. Adds doc/features/knowledge-service.md and the kb_service SPEC.

Test Plan

  • test/test_kb_service_core.py (39 tests):
    • config validation matrix, including the private-upstream and human-only rules;
    • lease exclusivity and stale takeover;
    • generations, repo isolation, idempotent events, purge eligibility;
    • signing round trip, purpose binding, forgery, wrong key, key permissions;
    • publisher acceptance and every refusal;
    • a mode round trip voiding earlier items;
    • non-stop kinds refused for shadow and disabled repos;
    • an overlapping refresh unable to undo a completed pause (two ledger connections);
    • hold list contents and expiry;
    • forged acks;
    • CLI pause/resume re-signing control;
    • private repos never appearing in the public hold list.
  • Full suite, check_spec_freshness --strict, check_doc_links.

Test Result

  • Full suite passed. SPEC 88/88 strict. Doc links OK.
  • Local review gate (gpt-6-astra-high): approved after fixes for mode-change invalidation, disabled-repo writes, publication races and private-repo hold leakage.

🤖 Generated with Claude Code

Foundation for the knowledge service that takes knowledge ownership from
ReviewBot. There are no workflows or scheduler yet; those build on this.

- kb_service.config parses each adapter's knowledge_lifecycle section into a
  repo registry (general/ is configured by the service). It refuses unknown
  keys, bad modes or triggers, a missing auditor plugin, a knowledge_dir that
  disagrees with the adapter, auto_merge without a calibration set, and any
  private upstream in auto_merge. knowledge_lifecycle joins the adapter
  HIGH_RISK_SECTIONS, so only a human can enable auto-merge.
- kb_service.ledger: one SQLite file with every table keyed by repo, a
  heartbeat lease for single-instance operation, and per-repo and global
  generation numbers; bump_generation voids everything issued before it.
- knowledge_service.signing: Ed25519 envelopes whose signature covers a
  purpose tag, so a verdict, outbox item, control record, hold list or ack
  signature never verifies for another purpose. Keys are 0600 and never
  overwritten. Vendorable (only cryptography, new `kb` extra).
- kb_service.outbox: the service writes signed items, a control record and a
  hold list, and reads acks signed by the publisher's key. check_item() is
  what the GPU-box publisher runs before any write: signature, control record
  no older than 10 minutes, expiry, generation, pause, private upstream, and
  no enqueue or verdict unless the repo is in auto_merge; pause and close are
  always allowed. verify_holds() fails closed on a stale list.
- `infermatrix-copilot kb keygen|status|pause|resume|control`.
- vllm-omni gets knowledge_lifecycle in shadow mode with its release_audit.py
  auditor; afd-plugin is declared but disabled until its own calibration.
- CI installs the kb extra.

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

chatgpt-codex-connector Bot commented Sep 28, 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-28T11:20:43.939001Z eeaa309 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.

@tzhouam
tzhouam merged commit 1875018 into main Sep 28, 2026
3 checks passed

@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: eeaa3093fd

ℹ️ 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".

Comment on lines +258 to +259
if item.kind in ALWAYS_EXECUTABLE:
return item

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Apply mandatory checks before exempting stop items

When a signed pause or close item is present, this early return accepts it before checking expires_at or repo_publishes. Consequently, a stop item left during a publisher outage remains executable beyond its configured 24-hour TTL, and one issued for a private repository—Outbox.issue() currently permits this—bypasses the publisher's private-upstream fail-closed check. Exempt these items only from generation, paused-state, and mode checks, while still enforcing expiry and visibility.

Useful? React with 👍 / 👎.

Comment on lines +182 to +185
return RepoLifecycle(
repo=GENERAL, full_name="", enabled=enabled, mode=mode, knowledge_dir=GENERAL,
intake=IntakeConfig(merged_prs=False),
release=ReleaseConfig(trigger="none"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Require calibration before enabling general auto-merge

When KB_GENERAL_ENABLED=1 and KB_GENERAL_MODE=auto_merge, this helper creates an enabled auto-merge lifecycle whose inherited calibration_set is empty. Because general configuration bypasses parse_lifecycle(), it also bypasses the guard at lines 150–151 that rejects every other auto-merge repository without calibration, and _sync_repos() will register general as auto-merge. Require a calibration set here or reject auto-merge for general until one is supplied.

Useful? React with 👍 / 👎.

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