feat(p1-1): kb-source-fs filesystem source connector #6
Reference in New Issue
Block a user
Delete Branch "feat/p1-1-source-fs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
요약
P1-1 task spec 구현.
kb-source-fs신규 crate — 워크스페이스 root walk +.kbignore∪config.workspace.exclude합집합 필터 + BLAKE3 streaming hash →Vec<RawAsset>결정적 산출.SourceConnectortrait 첫 구현체.기준: tasks/p1/p1-1-source-fs.md, docs/superpowers/specs/2026-04-27-kb-final-form-design.md (§3.3/§6.2/§6.6/§7.1/§7.2 SourceConnector/§8).
구현
crates/kb-source-fs:hash.rs— 64 KiB 버퍼 streaming BLAKE3 (whole-file load 없음)media.rs— extension →MediaTypewalker.rs—walkdir+ canonical-path visited set (sibling-subtree symlink cycle 차단),ignore::Override합집합connector.rs—FsSourceConnector::new(&Config)+SourceConnector::scan(&SourceScope)기타:
tests/symlink_cycle.rs— dangling 1-step + real 2-step directory cycletests/snapshot_tree1.rs—tree-1.snapshot.json결정적 round-tripfixtures/source-fs/tree-1/kb-core::AssetStoragerustdoc 갱신 (Copied.pathsemantics 명시)검증
cargo check / build (warnings-as-errors) / test / clippy모두 cleancargo test --workspace→ 68 passed (kb-source-fs 26 신규)cargo tree -p kb-source-fs --depth 1→ 허용 deps만Review
f8d00bd,967a6a6)scope.includeglob (P1-2/P1-3 router), tilde +${VAR}확장 (kb-config 도입 시)다음
머지 후 feat/p1-2-parse-md-frontmatter 분기 → P1-2 진행.
Walk config.workspace.root, apply gitignore-style filters (config.workspace.exclude ∪ .kbignore ∪ baked-in defaults for .DS_Store / ._*), stream BLAKE3 over each file, and emit a deterministic Vec<RawAsset> sorted by workspace_path. Modules: - hash: streaming blake3::Hasher + 64 KiB read buffer (no whole-file loads); pinned digests for empty input and "hello world". - media: extension → MediaType (markdown/pdf/image/audio/other). - walker: ignore::OverrideBuilder for filter union; walkdir with manual visited-set cycle protection on top of follow_links. - connector: public FsSourceConnector::new(&Config) + SourceConnector::scan(&SourceScope) impl. Uses kb_core::to_posix for WorkspacePath construction (carries P0-1 # rejection through unchanged) and kb_core::id_for_asset for AssetId derivation. Storage variant signals intent only; actual byte copy is P1-6's responsibility. Per design §3.3, §6.2, §6.6, §7.1, §7.2, §8. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>fixtures/source-fs/tree-1/: README.md notes/alpha.md notes/beta.md ignored/skip.tmp (excluded by .kbignore *.tmp) .kbignore ("*.tmp") .DS_Store (implicitly excluded by FsSourceConnector) The committed baseline (tree-1.snapshot.json) has discovered_at, source_uri.value, and stored.path replaced with "<stripped>" so the JSON is portable across checkout locations and CI runs. The test applies the same stripping to scan output before comparing. The determinism test runs scan twice and asserts byte-identical serialized JSON (post-strip) — same filesystem state must yield the same Vec<RawAsset>. Regenerate baseline with `KB_REGEN_SNAPSHOT=1 cargo test -p kb-source-fs --test snapshot_tree1 -- tree_1_snapshot_matches_baseline`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>- walker.rs: document why we pick walkdir over ignore::WalkBuilder (explicit canonical-path comparison for sibling-subtree symlinks). - walker.rs: log canonicalize failures via tracing::debug! (was a silent `Err(_) => continue`) so broken/permission-denied symlink targets are observable at debug verbosity. - connector.rs: TODO marker on the scope.include debug-log noting the filter belongs at the extractor router (P1-2/P1-3). - connector.rs: TODO marker on expand_tilde to hoist tilde + ${VAR} expansion into a kb-config helper once available. - connector.rs: comment on the .kbignore read documenting the re-read-on-every-scan() contract. - connector.rs test: tighten the `.kbignore`-itself ADR comment and upgrade the assertion to actively pin "`.kbignore` IS emitted" instead of "either is fine"; future drift will now fail the test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>리뷰: 모든 항목 해소 — APPROVE 권고 (gate 정책상 COMMENT 등록)
내부 2단계 review (spec compliance + code quality) 통과 후 important 2 + minor 5 모두 반영 완료 (commit
f8d00bd,967a6a6).검증 요약
AssetStorage.pathsemantics, real dir-cycle test)expand_tildeTODO,.kbignoreADR)cargo check / build (RUSTFLAGS=-D warnings) / test / clippy --all-targets -D warningscargo tree -p kb-source-fs --depth 1허용 deps만 (kb-core, kb-config, anyhow, serde, time, blake3, tracing, walkdir, ignore)핵심 강점
READ_BUFFER_BYTES * 3 + 17로 실제 boundary 통과 검증)ignore::Override음수(!pat) 시맨틱 정확 (whitelist 모드 우발 방지)#-in-path 거부 (P0-1 invariant 계승)workspace_path사전식 정렬 +scan_idempotent_modulo_timestamp+tree_1_scan_is_deterministic이중 검증discovered_at/source_uri.value/stored.pathstrip 양쪽 일관 적용a/loop -> ../b,b/loop -> ../a) 신규 test로 visited-set 동작 검증후속 자연 해소 (비차단)
scope.includeglob 적용 — P1-2/P1-3 router 책임 (TODO 마커 박힘)${VAR}path 확장 —kb-configpath-expander helper 도입 시 hoist결론
papered over 없음. P1-2/P1-3로 진행 가능. self-review gate 정책상 본 코멘트는 COMMENT — author 측 수동 APPROVE + merge 부탁.