neurain 0.1.0-alpha.0 → 0.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - No unreleased changes recorded.
6
+
7
+ ## 0.1.0-alpha.2
8
+
9
+ - Documentation currency gate: README and development-status version strings are asserted against package.json in readiness; volatile metric snapshots de-hardcoded (verified green in CI, not pinned in docs).
10
+
11
+
12
+ ## 0.1.0-alpha.1
13
+
14
+ - Capture: file/asset capture + R2/R4/R6 enrichment (overlap candidates, numeric conflicts, sha256 duplicate detection) ported to the engine.
15
+ - Memory-write: completed the generic ledger-primitive set (appendLine/enqueue/setQueueStatus/appendBlock/writeFileGuarded) so a consumer can forward every fact/task primitive to the engine.
16
+ - Release automation: tag-triggered npm publish via Trusted Publishing (OIDC), a push-CI gate (fast readiness + `npm publish --dry-run`), and a prerelease-never-`latest` dist-tag guard.
5
17
  - Expanded the recall markdown corpus to the general area knowledge class (`10_areas/<area>/**`, hubs, area registry), with config-extensible include/exclude (`recall.include`/`recall.exclude`).
6
18
  - Added label-based privacy gating (`labels.mjs`): per-file frontmatter `sensitivity`, area baseline from `_area.md`, and boundary-aware path markers exclude private content at index time. Fixes a substring marker that could exclude a whole legitimate folder.
7
19
  - Added a routed lexical recall branch (`recall_lexical.mjs`): BM25 + structural/layer/entity/domain/fact-ledger boosts, unioned ahead of exact-token and semantic in hybrid search. Auto-enabled when a search index registry has areas or `--area` is set; off by default on a bare vault.
package/README.md CHANGED
@@ -126,7 +126,7 @@ The canonical product development snapshot is maintained in:
126
126
  - `docs/development-status.en.md`
127
127
  - `docs/development-status.kr.md`
128
128
 
129
- As of 2026-06-09 KST, the package is a publish-ready alpha for private beta or alpha user tests. It is not public SaaS GA. The current verified gates are `npm test` 37/37, `node scripts/readiness.mjs --json` score 100, and `npm run readiness -- --json` score 100.
129
+ The package is a publish-ready alpha for private beta or alpha user tests, not public SaaS GA. All gates (`npm test`, the readiness leakage/secret/pack/tarball-install checks, and `npm audit`) run green in CI on every release — see `.github/workflows/release.yml`. The live score is `node scripts/readiness.mjs --json`.
130
130
 
131
131
  Watch reports are also read-only. They do not start a daemon and do not write durable knowledge. They observe recent text files, event journal entries, recap hints, and lesson candidates so a future review worker can decide what deserves attention.
132
132
 
@@ -159,7 +159,7 @@ For multi-area vaults, preview commands do not scan every area by default. Use `
159
159
  See also:
160
160
 
161
161
  - `docs/knowledge-os.en.md`
162
- - `docs/self-improve-90-roadmap.en.md`
162
+ - `docs/self-improvement-90-roadmap.en.md`
163
163
  - `docs/connect-runtime.en.md`
164
164
 
165
165
  ## Existing Folder Adoption
@@ -188,7 +188,7 @@ It exposes read/capture/scan/preview tools only. It does not silently compile, p
188
188
 
189
189
  ## Status
190
190
 
191
- This is `0.1.0-alpha.0`. It is not a public SaaS GA release. The alpha exists to prove installability, local-first onboarding, Codex, Claude, Gemini, and Runtime connectivity, plus safety receipts.
191
+ This is `0.1.0-alpha.2`. It is not a public SaaS GA release. The alpha exists to prove installability, local-first onboarding, Codex, Claude, Gemini, and Runtime connectivity, plus safety receipts.
192
192
 
193
193
  Alpha publish command:
194
194
 
@@ -45,7 +45,7 @@ Safety boundary:
45
45
  - Durable Neurain writes still require explicit CLI confirmation.
46
46
  - The alpha snippet does not support paths containing newline or control bytes.
47
47
  - Scheduler access is read-only and cannot install background jobs or start daemons.
48
- - Scheduler eval access is read-only and checks trigger precision, trigger recall, no-recursion, private-boundary handling, case-file size limits, and target-root non-write snapshots.
48
+ - Scheduler eval access is read-only and checks trigger precision, trigger recall, no-recursion, private-boundary handling, case-file size limits, temp cleanup, and target-root non-write snapshots.
49
49
  - Lifecycle access is read-only through MCP. The runtime can inspect session lineage, while deeper lifecycle event emission uses the separate host-proxy contract below.
50
50
 
51
51
  ## Lifecycle Boundary
@@ -45,7 +45,7 @@ Safety boundary:
45
45
  - Durable Neurain write는 여전히 explicit CLI confirmation이 필요합니다.
46
46
  - Alpha snippet은 newline 또는 control byte가 포함된 path를 지원하지 않습니다.
47
47
  - Scheduler access는 read-only이며 background job을 설치하거나 daemon을 시작할 수 없습니다.
48
- - Scheduler eval access도 read-only이며 trigger precision, trigger recall, no-recursion, private-boundary handling, case-file size limit, target-root non-write snapshot을 확인합니다.
48
+ - Scheduler eval access도 read-only이며 trigger precision, trigger recall, no-recursion, private-boundary handling, case-file size limit, temp cleanup, target-root non-write snapshot을 확인합니다.
49
49
  - Lifecycle access는 MCP에서 read-only입니다. Runtime은 session lineage를 읽을 수 있고, 더 깊은 lifecycle event emission은 아래 host-proxy contract를 사용합니다.
50
50
 
51
51
  ## Lifecycle Boundary
@@ -1,9 +1,9 @@
1
1
  # Development Status
2
2
 
3
3
  Version: v0.1
4
- Last updated: 2026-06-09 KST
5
- Package: `neurain@0.1.0-alpha.0`
6
- Latest documented commit: `3496262 Add E24 onboarding and Gemini MCP connector`
4
+ Last updated: 2026-06-14 KST
5
+ Package: `neurain@0.1.0-alpha.2`
6
+ Latest documented commit: `66016ba docs(dev-status): note unified reindex + adopt auto-reindex in the command surface`
7
7
 
8
8
  This document is the canonical product development snapshot for the public package. It tracks what is shipped, what has evidence, and what must not be claimed yet.
9
9
 
@@ -11,16 +11,9 @@ This document is the canonical product development snapshot for the public packa
11
11
 
12
12
  Neurain is a publish-ready alpha CLI and MCP package. It is ready for private beta or alpha user tests, not public SaaS GA.
13
13
 
14
- Current verified score:
14
+ Current verification: every gate runs green in CI on each release — `npm test`, the full `npm run readiness` suite (leakage/secret scan, `npm audit`, `npm pack --dry-run`, and a temporary tarball-install smoke), and `node scripts/readiness.mjs --json` for the live score. See `.github/workflows/release.yml`.
15
15
 
16
- | Gate | Result |
17
- |---|---:|
18
- | `npm test` | 37/37 pass |
19
- | `node scripts/readiness.mjs --json` | `ok:true`, score `100`, 35 checks |
20
- | `npm run readiness -- --json` | `ok:true`, score `100` |
21
- | `npm audit` | 0 vulnerabilities |
22
- | `npm pack --dry-run` | pass |
23
- | Temporary tarball install smoke | pass |
16
+ Volatile metrics (exact test counts, readiness scores, check counts) are intentionally NOT pinned in this document — they are verified green in CI, not hand-copied, so this snapshot cannot silently drift from the suite.
24
17
 
25
18
  ## Shipped Development
26
19
 
@@ -28,6 +21,7 @@ Current verified score:
28
21
 
29
22
  - Starter vault initialization with `neurain init`.
30
23
  - Existing folder adoption scan, apply, receipt, and rollback.
24
+ - Unified `reindex` (register areas + per-area index refresh + recall rebuild in one pass; curated indexes are never auto-overwritten); `adopt --apply` auto-reindexes so an adopted folder is registered and searchable in one command.
31
25
  - Local doctor, search, capabilities, recap, and wrap preview.
32
26
  - Event journal add/list/verify with explicit confirmation.
33
27
  - Lesson list, candidates, eval, promotion, and rollback.
@@ -1,9 +1,9 @@
1
1
  # 개발 진행 상태
2
2
 
3
3
  Version: v0.1
4
- Last updated: 2026-06-09 KST
5
- Package: `neurain@0.1.0-alpha.0`
6
- Latest documented commit: `3496262 Add E24 onboarding and Gemini MCP connector`
4
+ Last updated: 2026-06-14 KST
5
+ Package: `neurain@0.1.0-alpha.2`
6
+ Latest documented commit: `66016ba docs(dev-status): note unified reindex + adopt auto-reindex in the command surface`
7
7
 
8
8
  이 문서는 public package 기준의 canonical 개발 상태 스냅샷입니다. 무엇이 shipped인지, 어떤 증거가 있는지, 아직 주장하면 안 되는 것이 무엇인지 함께 기록합니다.
9
9
 
@@ -11,16 +11,9 @@ Latest documented commit: `3496262 Add E24 onboarding and Gemini MCP connector`
11
11
 
12
12
  Neurain은 publish-ready alpha CLI 및 MCP package입니다. private beta 또는 alpha user test에는 들어갈 수 있지만 public SaaS GA는 아닙니다.
13
13
 
14
- 현재 검증된 상태:
14
+ 현재 검증: 매 릴리스마다 모든 게이트가 CI에서 green으로 통과합니다 — `npm test`, 전체 `npm run readiness`(leakage/secret 스캔, `npm audit`, `npm pack --dry-run`, 임시 tarball-install smoke), 라이브 점수는 `node scripts/readiness.mjs --json`. `.github/workflows/release.yml` 참조.
15
15
 
16
- | Gate | Result |
17
- |---|---:|
18
- | `npm test` | 37/37 pass |
19
- | `node scripts/readiness.mjs --json` | `ok:true`, score `100`, 35 checks |
20
- | `npm run readiness -- --json` | `ok:true`, score `100` |
21
- | `npm audit` | 0 vulnerabilities |
22
- | `npm pack --dry-run` | pass |
23
- | Temporary tarball install smoke | pass |
16
+ 휘발성 지표(정확한 테스트 수·readiness 점수·check 수)는 의도적으로 이 문서에 박지 않습니다 — CI에서 green으로 검증되며 손으로 복사하지 않으므로, 이 스냅샷이 suite와 조용히 어긋나지 않습니다.
24
17
 
25
18
  ## shipped 개발 범위
26
19
 
@@ -28,6 +21,7 @@ Neurain은 publish-ready alpha CLI 및 MCP package입니다. private beta 또는
28
21
 
29
22
  - `neurain init` starter vault initialization.
30
23
  - 기존 폴더 adoption scan, apply, receipt, rollback.
24
+ - 통합 `reindex`(영역 등록 + per-area 색인 새로고침 + recall rebuild를 한 번에; 큐레이티드 색인은 자동 덮어쓰기 안 함); `adopt --apply`가 자동 reindex하여 채택한 폴더가 한 명령으로 등록·검색 가능.
31
25
  - local doctor, search, capabilities, recap, wrap preview.
32
26
  - 명시적 confirmation이 필요한 event journal add/list/verify.
33
27
  - lesson list, candidates, eval, promotion, rollback.
@@ -2,7 +2,40 @@
2
2
 
3
3
  Use this checklist before publishing an alpha release.
4
4
 
5
- ## Local Checks
5
+ ## Automated Release (preferred)
6
+
7
+ Releases are automated. You only decide WHEN to ship:
8
+
9
+ ```bash
10
+ npm version prerelease --preid=alpha # 0.1.0-alpha.0 -> 0.1.0-alpha.1 (commits + tags)
11
+ git push origin main --follow-tags # push the commit AND the new tag
12
+ ```
13
+
14
+ The tag push triggers `.github/workflows/release.yml`, which runs the full
15
+ readiness gate and then `npm publish --tag alpha` via npm Trusted Publishing
16
+ (OIDC) — no stored token, no interactive 2FA. Every push (untagged) is gated by
17
+ `.github/workflows/test.yml` (tests + fast readiness + `npm publish --dry-run`).
18
+
19
+ One-time setup: on npmjs.com, the package -> Settings -> Trusted Publisher ->
20
+ GitHub Actions, with this repo's owner/name and workflow `release.yml`.
21
+
22
+ ## Versioning policy
23
+
24
+ - Pre-1.0 alpha: increment with `npm version prerelease --preid=alpha`
25
+ (`-alpha.0 -> -alpha.1 -> ...`). Publish ALWAYS with `--tag alpha`; never move
26
+ the `latest` dist-tag to a prerelease. Only a deliberate stable (>= the first
27
+ non-prerelease) should ever hold `latest`.
28
+
29
+ ## Rollback / yank
30
+
31
+ - A published version cannot be overwritten and cannot be unpublished after 72h.
32
+ To pull a bad alpha: `npm deprecate neurain@<bad> "broken, use <good>"` and ship
33
+ a fixed `-alpha.<next>`.
34
+ - To roll the consuming vault back to a prior engine: point `NEURAIN_ENGINE_BIN`
35
+ at the previous tag's checkout (or pin the previous npm version), or set
36
+ `NEURAIN_LEGACY=1` to fall back to the vault's preserved implementations.
37
+
38
+ ## Local Checks (manual fallback)
6
39
 
7
40
  ```bash
8
41
  npm ci
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neurain",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.0-alpha.2",
4
4
  "description": "Local-first Neurain Knowledge OS CLI and MCP connector.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -27,7 +27,10 @@
27
27
  "scripts": {
28
28
  "test": "node --test",
29
29
  "pack:dry-run": "npm pack --dry-run",
30
- "readiness": "node scripts/readiness.mjs --full"
30
+ "readiness": "node scripts/readiness.mjs --full",
31
+ "docs:check": "node scripts/sync-docs.mjs --check",
32
+ "docs:fix": "node scripts/sync-docs.mjs --write",
33
+ "version": "node scripts/sync-docs.mjs --write && git add -u README.md CHANGELOG.md docs/development-status.en.md docs/development-status.kr.md"
31
34
  },
32
35
  "dependencies": {
33
36
  "@modelcontextprotocol/sdk": "^1.17.5"
package/src/cli.mjs CHANGED
@@ -31,6 +31,21 @@ import { queueArchiveCommand } from './core/queue_archive.mjs';
31
31
  import { captureCommand } from './core/capture_durable.mjs';
32
32
  import { completeCommand } from './core/complete.mjs';
33
33
  import { linkCheckCommand } from './core/link_check.mjs';
34
+ import { sessionLintCommand } from './core/session_lint.mjs';
35
+ import { labelCommand } from './core/label.mjs';
36
+ import { orphansCommand } from './core/orphans.mjs';
37
+ import { hubsCommand } from './core/hubs.mjs';
38
+ import { areaIndexCommand } from './core/area_index.mjs';
39
+ import { reindexCommand } from './core/reindex.mjs';
40
+ import { lintCommand } from './core/lint.mjs';
41
+ import { sessionPulseCommand } from './core/session_pulse.mjs';
42
+ import { syncCommand } from './core/sync.mjs';
43
+ import { healthCommand } from './core/health.mjs';
44
+ import { memoryCommand } from './core/memory.mjs';
45
+ import { retentionCommand } from './core/retention.mjs';
46
+ import { freezeCommand } from './core/freeze.mjs';
47
+ import { memoryWriteCommand } from './core/memory_write_cli.mjs';
48
+ import { backupCommand } from './core/backup.mjs';
34
49
  import { schedulerCommand } from './core/scheduler.mjs';
35
50
  import { searchCommand } from './core/search.mjs';
36
51
  import { watchCommand } from './core/watch.mjs';
@@ -67,6 +82,7 @@ export async function runCli(argv) {
67
82
  if (command === 'curator') return render(await curatorCommand(args));
68
83
  if (command === 'daemon') return render(await daemonCommand(args));
69
84
  if (command === 'recall') return render(await recallCommand(args));
85
+ if (command === 'reindex') return render(await reindexCommand(args));
70
86
  if (command === 'status') return render(await statusCommand(args));
71
87
  if (command === 'digest') return render(await digestCommand(args));
72
88
  if (command === 'queue') return render(await queueCommand(args));
@@ -83,6 +99,20 @@ export async function runCli(argv) {
83
99
  if (command === 'capture') return render(await captureCommand(args));
84
100
  if (command === 'complete') return render(await completeCommand(args));
85
101
  if (command === 'link-check') return render(await linkCheckCommand(args));
102
+ if (command === 'session-lint') return render(await sessionLintCommand(args));
103
+ if (command === 'label') return render(await labelCommand(args));
104
+ if (command === 'orphans') return render(await orphansCommand(args));
105
+ if (command === 'hubs') return render(await hubsCommand(args));
106
+ if (command === 'area-index') return render(await areaIndexCommand(args));
107
+ if (command === 'lint') return render(await lintCommand(args));
108
+ if (command === 'session-pulse') return render(await sessionPulseCommand(args));
109
+ if (command === 'sync') return render(await syncCommand(args));
110
+ if (command === 'health') return render(await healthCommand(args));
111
+ if (command === 'memory') return render(await memoryCommand(args));
112
+ if (command === 'retention') return render(await retentionCommand(args));
113
+ if (command === 'freeze') return render(await freezeCommand(args));
114
+ if (command === 'memory-write') return render(await memoryWriteCommand(args));
115
+ if (command === 'backup') return render(await backupCommand(args));
86
116
  if (command === 'capabilities') return render(await capabilitiesCommand(args));
87
117
  if (command === 'recap') return render(await recapCommand(args));
88
118
  if (command === 'watch') return render(await watchCommand(args));
@@ -152,8 +182,9 @@ function helpText() {
152
182
  Usage:
153
183
  neurain init <folder> [--area general] [--lang ko|en] [--dry-run]
154
184
  neurain onboard <folder> [--lang ko|en] [--host codex|claude|gemini|runtime] [--json]
155
- neurain adopt <folder> [--dry-run] [--apply --confirm "<N>건 저장 진행"]
185
+ neurain adopt <folder> [--dry-run] [--apply --confirm "<N>건 저장 진행"] [--no-reindex]
156
186
  neurain adopt --rollback <receipt> [--root <folder>]
187
+ neurain reindex <folder> [--dry-run] [--json]
157
188
  neurain doctor <folder> [--json]
158
189
  neurain search <folder> <query> [--top 10] [--json]
159
190
  neurain journal list <folder> [--type type] [--top 20] [--json]
@@ -203,6 +234,20 @@ Usage:
203
234
  neurain capture <folder> [--text "..." | <text> | --file rel] [--session-id id] [--type memo] [--title t] [--area name] [--sensitivity s] [--intent i] [--allow-secret] [--dry-run] [--json]
204
235
  neurain complete <folder> --source-id id --compiled-to "a.md,b.md" [--status compiled] [--completed-at ts] [--dry-run] [--json]
205
236
  neurain link-check <folder> [--scope .] [--top 20] [--include-raw] [--include-archive] [--include-output] [--json]
237
+ neurain session-lint <folder> [--stale-days 7] [--now ms] [--json]
238
+ neurain label <folder> [--check | --apply] [--area name | --all] [--glob substr] [--limit N] [--json]
239
+ neurain orphans <folder> [--area name] [--fix] [--json]
240
+ neurain hubs <folder> [--check | --apply] [--area name] [--json]
241
+ neurain area-index <folder> [--build area | --refresh area | --register-curated area [--sensitivity private] | --detect [--fix] [--restamp-curated]] [--force] [--dry-run] [--json]
242
+ neurain lint <folder> [--json]
243
+ neurain session-pulse <folder> --session-id id --summary "..." [--focus t] [--next t] [--max-notes 8] [--no-area-brief] [--queue ...] [--now ts] [--dry-run] [--allow-secret] [--json]
244
+ neurain sync <folder> --session-id id [--summary "..."] [--level light|standard|full] [--no-pulse] [--no-area-brief] [--queue ...] [--now ts] [--dry-run] [--json]
245
+ neurain health <folder> [--fix] [--now ts] [--json]
246
+ neurain memory <folder> [--facts q | --tasks q | --conflicts | --verify | --stats] [--area name] [--top 10] [--json]
247
+ neurain retention <folder> [--area name] [--stale-days 120] [--write] [--now ms] [--json]
248
+ neurain freeze <folder> <acquire|release|status> [--owner name] [--json]
249
+ neurain memory-write <folder> --area name --file ledger.md --op add-fact|add-task|set-status|append-event [--fields json] [--changes json] [--event json] [--fact-id id] [--id id] [--apply] [--json]
250
+ neurain backup <folder> --target <dir> [--label name] | --verify <name> | --restore <name> [--to <dir>] | --drill <name> [--target <dir>] | --list [--json]
206
251
  neurain recap <folder> [--area name] [--json]
207
252
  neurain watch <folder> [--area name] [--since-minutes 1440] [--top 10] [--poll-once] [--json]
208
253
  neurain review <folder> [--area name] [--since-minutes 1440] [--top 10] [--json]
@@ -249,7 +294,16 @@ Alpha principles:
249
294
  - Source-digest and plan-receipt are W-B writers that touch only their own non-canonical artifacts: source-digest writes the rebuildable source-digest manifest (dry by default, --write to update) and plan-receipt writes an optional receipt under output/receipts/. Every durable write goes through an atomic temp+fsync+rename plus a cross-process lock, and the manifest's path sensitivity is decided by the label resolver, never hardcoded area names.
250
295
  - Stage is the secret gate: content lands in .neurain-staging (excluded from every walk), is scanned fail-closed for high-confidence secret shapes, mnemonics, context-aware hex keys, and high-entropy tokens, and is promoted to its canonical target by an atomic rename ONLY if clean; a hit holds the content in staging, leaves the target untouched, and exits 2. Queue-archive moves terminal queue rows into an append-only archive under one lock (archive appended before the hot-queue rewrite, so a crash never loses a row).
251
296
  - Capture and complete are the durable pipeline writers. They write raw markdown (capture, routed through the stage secret gate), the _inbox envelope, the writeback queue (capture appends, complete rewrites - both under a lock), and a wiki/log line, but they NEVER write session-state, handoff, or area-brief files: those stay W-D-owned, returned as an unapplied session_state_delta whose pending_count is advisory (the future vault shuttle recomputes at apply time). Capture is text-only in this increment; file capture and overlap/numeric enrichment are the documented flip gate.
252
- - Link-check (W-C) is a read-only graph validator: it resolves every markdown link and wikilink against the vault and reports unresolved targets by file and area, writing nothing. Area buckets use the configured structural dirs, not hardcoded area names.
297
+ - Link-check and session-lint (W-C) are read-only validators that write nothing. Link-check resolves every markdown link and wikilink against the vault and reports unresolved targets by file and area. Session-lint validates the session layer: required paths, session-state vs handoff consistency, pending-count drift vs the queue, handoff frontmatter, and queue rows referencing known sessions. Both use the configured structural dirs, not hardcoded area names.
298
+ - Label (W-C) is the label-system CLI: --check (default, read-only) proposes the managed label block (type/areas/entities/domains/sensitivity/tags) per knowledge file and reports private leaks; --apply writes it additively and idempotently, atomic per file, refusing symlinks. The label brain (label_intel) hard-codes nothing vault-specific — vocabulary comes from each area's entity dictionary and tuning from an optional label-config.json. A private/published file never gets entity/domain tags.
299
+ - Backup (W-E) is the local snapshot + EXACT restore + restore-drill: the manifest records files (sha256+size) and dirs, symlinks/special files are refused, and restore reconstructs the target byte-exactly (and proves it) via stage-verify-rename-aside-reverify, so a no-git vault still has a verifiable rollback. The macOS/iCloud encrypted external backup stays vault-side.
300
+ - Memory-write (W-E) is the registry-driven fact/task ledger writer: schemas, ID templates, mandatory/dash columns and paths come from memory-write-registry.json, so every area is handled by the same code. It appends rows or edits a fact's lifecycle columns while keeping every other row byte-identical, under an O_EXCL lock with a sha256 compare-and-swap (concurrent modification aborts) + fsync. Default dry-run; a live write needs the area's write_enabled:true, a realpath inside area_root, a fail-closed secret scan, and the freeze lock not held.
301
+ - Memory and retention (W-E, read-only) query the per-area fact/task ledgers via a config-driven reader that maps heterogeneous table schemas by column name. Memory does status-aware fact/task lookup, conflicts, and verify; retention flags active facts for human review (contradicted / unverified / stale / low-confidence / missing-metadata) and never deletes (optional --write emits a report). Neither touches the ledgers.
302
+ - Health (W-D) composes doctor + lint into one verdict and reconciles session-state drift: pending_count's source of truth is the writeback queue and last_pulse's is the handoff frontmatter, so a session can drift. Read-only without --fix; with --fix it repairs drift via the locked session-state path and runs the W-C maintenance fixers (orphans, label, area-index) before a final lint.
303
+ - Session-pulse (W-D) is the session working-memory writer: it pulses one durable note into the handoff, optionally the area brief and a queue row, then advances session-state. Hardened per cross-review: markdown is written first and the authoritative session-state.json last (a crash leaves the markdown ahead but state recoverable), every write is atomic, the area brief is rendered + labelled in memory and written once, and the note is secret-scanned fail-closed. session-state writes are this wave's (W-D) responsibility; W-B's capture/complete only returned a delta for it to apply.
304
+ - Lint (W-C) is a read-only STRUCTURAL aggregator: it composes the ported validators (link-check, session-lint, advisory orphans) into one health verdict. It deliberately does NOT re-implement the vault's documentation-governance checks (master version, clipper templates, instruction lengths, progressive disclosure) — those stay vault-side.
305
+ - Area-index (W-C) generates a per-area search index from the area's own signals (wiki/entities pages, frontmatter entity_candidates, area-tagged raw envelopes, salience-gated content terms), registers it, detects staleness via a file signature, and refreshes drifted generated indexes. Curated indexes are never auto-overwritten; --detect is read-only, writes happen only with --build/--refresh/--register-curated/--detect --fix.
306
+ - Orphans and hubs (W-C) are the graph connection layer. Orphans reports knowledge files with no inbound and no outbound wikilink, classified (structural / has-entities / no-entities); --fix adds one additive per-area graph-backlog page (source files untouched). Hubs generates per-entity hub pages linking member notes (dry-run by default, --apply writes and prunes only its own hub_generated pages); private areas and private files are excluded, member files are never modified.
253
307
  - Live-cases scaffold creates a redacted E23 reviewed-case pack scaffold with hash-only source refs. It does not claim human evidence and stores no raw source text or absolute paths.
254
308
  - Onboard is a read-only first-run guide for non-developers. It explains the next command without creating files or calling a model.
255
309
  - Answer eval checks faithfulness, citation accuracy, conflict surfacing, abstention, private boundaries, and stale-source handling without model calls or writes.
@@ -3,6 +3,7 @@ import os from 'node:os';
3
3
  import path from 'node:path';
4
4
  import { absPath, compactStamp, ensureDir, exists, generatedPath, isTextFile, relPath, safeResolve, sha256, slug, timestamp, writeFileNoOverwrite } from './fs.mjs';
5
5
  import { inferSensitivityFromPath, secretLike } from './safety.mjs';
6
+ import { reindexCommand } from './reindex.mjs';
6
7
 
7
8
  const maxFileBytes = 20 * 1024 * 1024;
8
9
  const maxFiles = 5000;
@@ -17,6 +18,17 @@ export async function adoptCommand(args) {
17
18
  throw new Error(`Apply requires --confirm "${expected}".`);
18
19
  }
19
20
  scan.apply = applyAdoption(scan, { root: target });
21
+ // Once the adapters land, register the area and rebuild search in one pass so the
22
+ // adopted folder is immediately searchable. Best-effort: a reindex hiccup must
23
+ // never fail the adoption itself, and --no-reindex opts out.
24
+ if (scan.apply?.ok && !args['no-reindex']) {
25
+ try {
26
+ const r = await reindexCommand({ _: [target], json: true });
27
+ scan.reindex = r.payload || null;
28
+ } catch (error) {
29
+ scan.reindex = { ok: false, error: String((error && error.message) || error) };
30
+ }
31
+ }
20
32
  }
21
33
  if (args.json) return { json: true, payload: scan };
22
34
  return {
@@ -32,6 +44,7 @@ export async function adoptCommand(args) {
32
44
  `- Risks: ${scan.summary.risk_count}`,
33
45
  `- Confirmation required: ${scan.confirmation_required}`,
34
46
  scan.apply ? `- Apply receipt: ${scan.apply.receipt_path}` : '',
47
+ scan.reindex ? `- Reindex: ${scan.reindex.ok ? 'registered + searchable' : 'skipped (' + (scan.reindex.error || 'n/a') + ')'}` : '',
35
48
  ].filter(Boolean).join('\n'),
36
49
  };
37
50
  }