feat(lint): P84 — lint --fix-wiki-invocations for legacy wiki self-ingest cleanup (#82 follow-up)#86
Conversation
…ingest cleanup (#82 follow-up) P83 (#85) 머지 후 신규 wiki invocation 세션은 marker 검사로 차단되지만, 머지 전 ingest 된 legacy 세션에는 marker 가 없어 자동 정리가 안 된다. 사용자가 한 번 실행해 일괄 archive 할 수 있는 lint 옵션 추가. - `ingest/lint.rs`: `check_wiki_invocations()` 함수 추가 (L011 신규). cwd 가 `[vault].path` 와 일치하는 codex/claude 세션을 Info 레벨로 finding. - `commands/lint.rs`: `--fix-wiki-invocations` flag 처리하는 `run_fix_wiki_invocations()` 추가. SessionRepo::archive_session 호출. - `main.rs`: clap arg + call site 갱신. - 신규 unit test 5건 (codex/claude detect, archived skip, cwd outside vault, non-codex/claude agents). 사용: - `secall lint` → L011 finding 표시 - `secall lint --fix-wiki-invocations` → 일괄 archive - 의도와 다르면 `secall unarchive <id>` 로 복원 (reversible) 검증: - cargo fmt --check: clean - cargo clippy --workspace --all-targets -D warnings: clean - cargo test -p secall-core --lib ingest::lint: 18 passed - cargo test --workspace --no-fail-fast: all green (lib 426 + integration) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a new lint rule, L011, to detect legacy wiki self-invocation sessions where the current working directory matches the vault path for 'codex' and 'claude-code' agents. It also adds a --fix-wiki-invocations command-line flag to automate the archiving of these sessions, along with corresponding unit tests and documentation. Feedback was provided to optimize the linting process by moving the directory filtering logic directly into the SQL query to improve performance and simplify the code.
| let mut stmt = conn.prepare( | ||
| "SELECT id, cwd, agent FROM sessions \ | ||
| WHERE is_archived = 0 \ | ||
| AND cwd IS NOT NULL \ | ||
| AND agent IN ('codex', 'claude-code')", | ||
| )?; | ||
| let rows = stmt.query_map([], |r| { | ||
| Ok(( | ||
| r.get::<_, String>(0)?, | ||
| r.get::<_, String>(1)?, | ||
| r.get::<_, String>(2)?, | ||
| )) | ||
| })?; | ||
| for row in rows { | ||
| let (id, cwd, agent) = row?; | ||
| if cwd == vault_str { | ||
| findings.push(LintFinding { | ||
| code: "L011".to_string(), | ||
| severity: Severity::Info, | ||
| message: format!( | ||
| "{agent} session at vault path (likely wiki self-invocation): cwd={cwd}" | ||
| ), | ||
| session_id: Some(id), | ||
| path: None, | ||
| }); | ||
| } | ||
| } |
There was a problem hiding this comment.
The filtering of sessions by cwd can be performed directly in the SQL query instead of fetching all sessions for the specified agents and filtering them in Rust. This is more efficient as it reduces the amount of data transferred from the database and the number of iterations in the application code. Additionally, it simplifies the logic by removing the conditional check inside the loop.
let mut stmt = conn.prepare(
"SELECT id, cwd, agent FROM sessions \
WHERE is_archived = 0 \
AND cwd = ?1 \
AND agent IN ('codex', 'claude-code')",
)?;
let rows = stmt.query_map([&vault_str], |r| {
Ok((
r.get::<_, String>(0)?,
r.get::<_, String>(1)?,
r.get::<_, String>(2)?,
))
})?;
for row in rows {
let (id, cwd, agent) = row?;
findings.push(LintFinding {
code: "L011".to_string(),
severity: Severity::Info,
message: format!(
"{agent} session at vault path (likely wiki self-invocation): cwd={cwd}"
),
session_id: Some(id),
path: None,
});
}`check_wiki_invocations()` 의 cwd 매치를 SQL WHERE 절로 옮김 — DB level 에서 필터링해 불필요한 row 전송/순회 회피. Rust loop 의 조건문 제거로 가독성 ↑. 검증: - cargo fmt --check: clean - cargo clippy --workspace --all-targets -D warnings: clean - cargo test -p secall-core --lib ingest::lint: 18 passed Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Gemini 리뷰 반영 (commit 7337d3e). |
Summary
P83 (#85) fast-follow. 머지 전에 이미 ingest 된 wiki invocation 세션을 사용자가 한 번 실행해 일괄 archive 할 수 있는 lint 옵션 추가.
ingest/lint.rs:check_wiki_invocations()함수 추가 — L011 신규. cwd 가[vault].path와 일치하는 codex/claude 세션을 Info 레벨로 finding.commands/lint.rs:--fix-wiki-invocationsflag 처리하는run_fix_wiki_invocations()—SessionRepo::archive_session호출.main.rs: clap arg + call site 갱신.Why
P83 marker 는 신규 ingest 만 보호. 기존 세션은 marker 가 없어 자동 정리 안 됨. dicebattle (issue #82) 등 사용자가 수동으로
secall archive또는 파일 삭제로 정리해야 하는 부담 해소.Usage
```bash
1. 검사 (자동 fix 없이)
secall lint
→ L011 [INFO] codex session at vault path (likely wiki self-invocation): cwd=/Users/me/Documents/Obsidian Vault/seCall
2. 자동 archive
secall lint --fix-wiki-invocations
→ [fix-wiki-invocations] Archiving 12 wiki invocation session(s)...
3. 의도와 다르면 개별 복원 (reversible)
secall unarchive
```
Detection rule (L011)
```sql
SELECT id, cwd, agent FROM sessions
WHERE is_archived = 0
AND cwd IS NOT NULL
AND agent IN ('codex', 'claude-code')
```
→ `cwd == config.vault.path` 인 경우 L011 finding.
근거: `wiki/{codex,claude}.rs` 가 subprocess 를 `cwd = vault_path` 으로 spawn. wiki 호출이 만든 세션의 cwd 는 정확히 vault path.
Risks
Test plan
🤖 Generated with Claude Code