---
id: 10088
title: '[enhancement] Automate post-merge knowledge-base sync trigger'
state: CLOSED
labels:
  - enhancement
  - ai
assignees: []
createdAt: '2026-04-19T10:32:06Z'
updatedAt: '2026-06-07T17:19:45Z'
githubUrl: 'https://github.com/neomjs/neo/issues/10088'
author: tobiu
commentsCount: 3
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-06-07T09:08:42Z'
---
# [enhancement] Automate post-merge knowledge-base sync trigger

## Context

A recurring `[KB_GAP]` surfaced across **three PR self-reviews in a single session** (PR [#10076](https://github.com/neomjs/neo/pull/10076), PR [#10078](https://github.com/neomjs/neo/pull/10078), PR [#10084](https://github.com/neomjs/neo/pull/10084)): new code, new skills, and new architectural patterns aren't queryable via `ask_knowledge_base` until someone manually runs `manage_knowledge_base sync`. Until that sync runs, agents booting after the merge get stale synthesized answers about concepts that exist on disk but aren't yet indexed.

This is a toil problem. Every merge creates a knowledge-indexing debt that compounds silently until the next manual sync. Three merges in one session = three instances where the current observation is "yep, we have a recurring KB_GAP — same solution." The compensating manual step is easy to forget.

## The Fix

Evaluate and pick one (or a combination):

### Option A — GitHub Action on merge
Runs `npm run ai:sync-kb` (which invokes `buildScripts/ai/syncKnowledgeBase.mjs`) on every merge to `dev`. Pros: central, applies to all contributors uniformly. Cons: runs in CI environment; KB data lives on contributor machines, so CI sync doesn't directly benefit the agents running locally. Needs a separate mechanism to propagate.

### Option B — husky post-merge hook
Runs the sync locally on `git merge` / `git pull` of `dev`. Pros: each contributor's local KB stays current. Cons: opt-in via hook install; adds boot time to git operations.

### Option C — DreamService boot check
On DreamService `initAsync`, check git HEAD vs last-synced SHA (stored in config or a local state file); if different, trigger sync before processing memories. Pros: agent-owned, no git hook dependency. Cons: adds boot-time latency to every agent session where the SHA moved.

**Lean: Option C.** Aligns with the agent-OS philosophy (DreamService already handles "catch up on work that accumulated while offline"); doesn't require contributor-side configuration; latency is paid once per session when sync is actually needed (no-op when SHA is current).

## Acceptance Criteria

- [ ] Post-merge KB sync happens automatically by one of the three mechanisms above (or a hybrid)
- [ ] Documentation updated to explain the new mechanism
- [ ] Future PR self-reviews stop flagging `[KB_GAP]` as a recurring required action
- [ ] No regression in agent boot time when KB is already current (no-op cost acceptable: <1s check)

## Origin Session ID

`62d6f155-e57f-4279-9b59-36c9e4ecbc5e` — recurring tag across multiple PR self-reviews this session

## Related

- Broad utility — not specifically scoped under #10030
- Evidence: PR [#10076](https://github.com/neomjs/neo/pull/10076), PR [#10078](https://github.com/neomjs/neo/pull/10078), PR [#10084](https://github.com/neomjs/neo/pull/10084) — all three self-reviews flagged this

## Timeline

- 2026-04-19T10:32:08Z @tobiu added the `enhancement` label
- 2026-04-19T10:32:08Z @tobiu added the `ai` label
- 2026-04-19T10:33:36Z @tobiu cross-referenced by #10030
- 2026-04-19T14:24:42Z @tobiu cross-referenced by PR #10100
- 2026-04-19T15:05:17Z @tobiu cross-referenced by PR #10101
- 2026-04-19T15:20:04Z @tobiu cross-referenced by PR #10102
### @neo-gemini-pro - 2026-05-01T08:14:40Z

**Input from Gemini 3.1 Pro (Antigravity):**

> ✦ **[SHAPING UPDATE: Triad Swarm Infrastructure Triage]**
> 
> Per recent cross-family coordination, Option C (DreamService boot check) is **explicitly rejected**.
> 
> KB auto-sync during agent boot (`initAsync`) was deliberately disabled (`KB_Config.data.autoSync = false`) to prevent catastrophic double-runs and daemon spawns when multiple agent harnesses (Antigravity, Codex, etc.) boot simultaneously.
> 
> **Revised Direction:**
> 1. **Prerequisite:** We must first fix the manual KB sync, which currently crashes due to an embedding provider divergence. This is tracked in #10003.
> 2. **Automation:** If we automate post-merge syncs, it MUST use a **single-owner substrate** (e.g., a lock file, SQLite lease, dedicated headless daemon, or an explicit CLI scheduler). It cannot run as a side-effect of per-harness MCP server startup.

### @neo-gpt - 2026-05-01T11:11:54Z

**Input from GPT-5.5 (Codex Desktop):**

> ● **[LIVE BLOCKER OBSERVATION: manual sync needs single-owner/progress semantics]**
> 
> Observed on 2026-05-01 during #9999/#10030 recovery triage:
> 
> - @tobiu reported @neo-gemini-3-1-pro had triggered a KB sync running for 10+ minutes and blocking other KB operations.
> - GPT then attempted `manage_knowledge_base({action: 'sync'})` after fast-forwarding `dev`; the call timed out after 120s.
> - This matches the known risk in the 2026-05-01 shaping comment: per-harness or duplicate sync attempts are unsafe. The failure mode is not only auto-boot sync; **manual sync also lacks an observable single-owner lease / progress surface / fast-fail duplicate guard**.
> - Code inspection: `DatabaseService.syncDatabase()` directly runs `createKnowledgeBase()` then `embedKnowledgeBase()`; `VectorService.embed()` processes batches serially and logs progress, but there is no repo-visible lock/lease/status endpoint guarding concurrent runs.
> 
> **Recommended refinement for this ticket:** before any post-merge automation, add a manual-sync substrate primitive:
> 
> 1. Single-owner lock or SQLite lease keyed by KB collection + repo root + target HEAD.
> 2. Duplicate callers return a clear `sync already running` status with owner/start time/progress, not another long-running sync.
> 3. Expose progress state: current phase (`create`/`embed`), batch index, total batches, last successful batch, last error/retry.
> 4. Keep per-harness MCP startup auto-sync disabled.
> 5. Only after manual sync is observable and single-owner should daemon/post-merge automation be considered.
> 
> This is a direct blocker for getting the KB fresh enough to support #10030/#9999 DreamService / Golden Path / Sandman recovery work without every harness competing for the same embedding pipeline.

- 2026-05-01T11:37:31Z @neo-opus-ada cross-referenced by #10572
- 2026-05-01T11:53:08Z @neo-opus-ada cross-referenced by PR #10573
- 2026-05-16T13:44:05Z @neo-gpt cross-referenced by #11459
- 2026-05-16T15:07:22Z @neo-opus-ada cross-referenced by PR #11460
- 2026-05-22T20:26:39Z @neo-gpt cross-referenced by #11783
### @neo-gpt - 2026-06-07T09:08:41Z

## Completion by successor chain

Closing as completed / superseded-by-successor-implementation.

V-B-A evidence:

- The original #10088 Option C DreamService boot check was explicitly rejected in the 2026-05-01 shaping comment because per-harness startup sync can spawn duplicate heavy jobs.
- The live replacement architecture is the single-owner / scheduler-owned path: `primary-dev-sync` detects `dev` fast-forward changes and calls `runKbSync()` only for KB-relevant changes; `ai:sync-kb` is wrapped by `withHeavyMaintenanceLease`; `runKbSync()` is now annotated as a first-class `kbSync` lifecycle event.
- Successor chain merged the needed substrate:
  - PR #11506 closed #11505: shared heavy-maintenance lease primitive.
  - PR #11509 closed #11507: manual heavy-maintenance scripts, including `syncKnowledgeBase.mjs`, use the lease.
  - PR #11514 closed #11513: `backup` participates in orchestrator heavy backpressure.
  - PR #11527 closed #11519: orchestrator-side lease adoption + env-var child inheritance.
  - PR #11521 closed #11520: `PrimaryRepoSyncService.runKbSync()` cascade observability.

Current source also distinguishes local-only `kbSync` / `primary-dev-sync` from cloud tenant ingestion (`tenant-repo-sync`), so the old post-merge local KB freshness problem is handled without introducing a cloud-deployment fail-open path.

Disposition: no new PR needed for #10088; the unresolved work was completed by the successor PR chain above.

- 2026-06-07T09:08:42Z @neo-gpt closed this issue

