Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `context_bundle`: emits a `rangeSource` flag (`symbol` / `window` / `clamped`) and accepts `why_mode: "terse"` for compact `why` tags.
- `snippets_get`: understands the optional `range_source` hint and now keeps explicit `[start_line,end_line]` windows even when the default view is `symbol`, protecting context_bundle workflows.

### Changed

- **Compact-mode defaults**: `files_search` now defaults to `compact: true`, matching `context_bundle` so previews are omitted unless explicitly requested.
- **Why tag control**: `context_bundle` compact responses omit `why[]` arrays by default to save ~170 bytes per item; callers can pass `includeWhy: true` to retain them.
- **Preview clamp**: `files_search` fallback previews are truncated to 100 characters (was 240) for additional token savings.
- Default `snippets_get` view is now `symbol`. Override via the `KIRI_SNIPPETS_DEFAULT_VIEW` environment variable if you need the legacy `auto` behavior.

## [0.25.8] - 2025-12-30

Expand Down
26 changes: 20 additions & 6 deletions docs/api-and-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ The server implements MCP standard endpoints `initialize` / `tools/list`, enabli
- `deps_closure(paths[], direction="out"|"in", depth=2)` - Analyze dependencies
- `recent.changed(since="30d", path_prefix?)` - Find recently changed files
- `who.owns(path)` - Get ownership information from blame summary
- `snippets_get(path, start_line?, end_line?, compact?, include_line_numbers?)` - Retrieve code snippets; `compact` omits content, `include_line_numbers` prefixes each line when content is returned
- `snippets_get(path, start_line?, end_line?, compact?, include_line_numbers?, range_source?)` - Retrieve code snippets; default view is `symbol` (override via `KIRI_SNIPPETS_DEFAULT_VIEW`). Provide `range_source` from `context_bundle` to preserve clamped windows, `compact` omits content, `include_line_numbers` prefixes each line when content is returned
- `semantic_rerank(candidates[], text, k=20)` - Semantic reranking (VSS only)
- `context_bundle(goal, artifacts, includeTokensEstimate?)` ← **Most Important**
- `context_bundle(goal, artifacts, includeTokensEstimate?, why_mode?)` ← **Most Important**
- `goal`: Natural language description (e.g., "Fix failing test: test_verify_token in Auth")
- `artifacts`: {`editing_path`?, `failing_tests`?, `last_diff`?, `hints`?[]}
- Providing `editing_path` with the file you're touching strongly boosts that file and nearby dependencies, returning a cohesive set of related files.
- `hints`: Optional list of short function/file breadcrumbs. They are merged into the search query so abstract goals like "nonparametric test" can still surface concrete implementations.
- Output: Fragment list (path, [start,end], why[], score, optional preview) and `tokens_estimate` **only** when `includeTokensEstimate: true`
- `why_mode`: `"full"` (default) returns verbose reasons; `"terse"` emits compact prefixes like `["sym:startServer","txt:server"]`.
- Output: Fragment list (path, [start,end], `rangeSource`, why[], score, optional preview) and `tokens_estimate` **only** when `includeTokensEstimate: true`

## `context_bundle` Request/Response Example

Expand All @@ -45,7 +46,8 @@ The server implements MCP standard endpoints `initialize` / `tools/list`, enabli
"last_diff": "...",
"hints": ["verifyToken", "src/auth/keys.ts"]
},
"includeTokensEstimate": true
"includeTokensEstimate": true,
"why_mode": "terse"
}
}

Expand All @@ -55,13 +57,15 @@ The server implements MCP standard endpoints `initialize` / `tools/list`, enabli
{
"path": "src/auth/jwt.ts",
"range": [12, 78],
"rangeSource": "symbol",
"why": ["symbol:verifyToken", "dep:src/auth/keys.ts", "recent:7d"],
"score": 0.86,
"preview": "function verifyToken(token:string){...}"
},
{
"path": "src/auth/keys.ts",
"range": [1, 120],
"rangeSource": "window",
"why": ["dep<-jwt.ts"],
"score": 0.74
}
Expand Down Expand Up @@ -92,6 +96,7 @@ for (const item of result.context.slice(0, 3)) {
path: item.path,
start_line: item.range[0],
end_line: item.range[1],
range_source: item.rangeSource, // preserves clamped windows even if defaults change
});
// Perform detailed analysis with content
}
Expand Down Expand Up @@ -120,12 +125,14 @@ for (const item of result.context.slice(0, 3)) {

- Immediate code preview is needed
- Retrieving only a few files (1-3)
- You need inline previews with `why_mode: "full"` for audit logs

### Lightweight inspection options

- `files_search(..., compact: true)` (now the default) removes previews from every result for 60–70% fewer tokens during keyword scans. Use `compact: false` only when the preview text is required inline.
- `snippets_get(..., compact: true)` returns only metadata (`path`, `startLine`, `endLine`, totals, symbol info) so that you can confirm the symbol boundaries without streaming full text.
- `snippets_get(..., includeLineNumbers: true)` prefixes each returned line with an aligned counter such as ` 1375→export async function...`, making it easier to quote exact locations when copying into bug reports or chats.
- `context_bundle(..., why_mode: "terse")` shrinks `why` tags (`symbol:` → `sym:`) without changing ranking; flip back to `"full"` when humans need verbose traceability.

### Real Example: Lambda Function Investigation

Expand Down Expand Up @@ -249,7 +256,7 @@ Watch mode (`--watch`) monitors repository file changes and automatically reinde
- `deps_closure(paths[], direction="out"|"in", depth=2)`
- `recent.changed(since="30d", path_prefix?)`
- `who.owns(path)` → `blame_summary` を要約
- `snippets_get(path, start_line?, end_line?, compact?, include_line_numbers?)`
- `snippets_get(path, start_line?, end_line?, compact?, include_line_numbers?, range_source?)`
- `semantic_rerank(candidates[], text, k=20)`(VSS 有効時のみ)
- `context_bundle(goal, artifacts, includeTokensEstimate?)` ← **最重要**
- `goal`: 自然文(例: "Auth の失敗テスト test_verify_token を修す")
Expand Down Expand Up @@ -335,6 +342,7 @@ for (const item of result.context.slice(0, 3)) {
path: item.path,
start_line: item.range[0],
end_line: item.range[1],
range_source: item.rangeSource,
});
// contentを使って詳細分析
}
Expand All @@ -361,6 +369,9 @@ for (const item of result.context.slice(0, 3)) {

- すぐにコードプレビューが必要な場合
- 少数のファイル(1-3件)のみを取得する場合
- `why_mode: "full"` で詳細な `why` 説明が必要な場合(監査ログなど)

> **Tip**: `context_bundle(..., why_mode: "terse")` + `snippets_get(..., range_source: item.rangeSource)` の組み合わせで、トークンを抑えつつ必要に応じて詳細コードへ拡張できます。

### 実例:Lambda関数の調査

Expand All @@ -371,7 +382,8 @@ for (const item of result.context.slice(0, 3)) {
"params": {
"goal": "ask-agent Lambda handler logic, runtime execution flow",
"limit": 10,
"compact": true
"compact": true,
"why_mode": "terse"
}
}

Expand All @@ -381,13 +393,15 @@ for (const item of result.context.slice(0, 3)) {
{
"path": "lambda/ask-agent/handler.ts",
"range": [15, 89],
"rangeSource": "symbol",
"why": ["phrase:ask-agent", "path-phrase:handler", "boost:impl-file"],
"score": 0.92
// preview フィールドなし → トークン節約
},
{
"path": "lambda/ask-agent/runtime.ts",
"range": [42, 156],
"rangeSource": "window",
"why": ["phrase:ask-agent", "dep:handler.ts"],
"score": 0.85
}
Expand Down
3 changes: 3 additions & 0 deletions docs/doc_index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ documents:
- doc_id: RUN-002
path: docs/operations.md
title: "Operations"
- doc_id: RUN-210
path: docs/uncertainty-issue-210.md
title: "Issue 210 – Uncertainty Register"

# Guide - ユーザー/開発者向けガイド
- doc_id: GUIDE-001
Expand Down
45 changes: 25 additions & 20 deletions docs/tools-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,17 @@ The most powerful tool for getting started with unfamiliar code. Provide a task

### Parameters

| Parameter | Type | Required | Default | Description |
| ------------------ | ------- | -------- | --------- | ------------------------------------------- |
| `goal` | string | Yes | - | Task description or question about the code |
| `limit` | number | No | 7 | Max snippets to return (max: 20) |
| `compact` | boolean | No | true | Return only metadata without preview |
| `includeWhy` | boolean | No | false | Keep `why[]` even when compact mode is used |
| `boost_profile` | string | No | "default" | File type boosting mode |
| `path_prefix` | string | No | - | Filter by path prefix |
| `category` | string | No | - | Query category for adaptive K |
| `metadata_filters` | object | No | - | Filter by document metadata |
| Parameter | Type | Required | Default | Description |
| ------------------ | ------- | -------- | --------- | ---------------------------------------------------------- |
| `goal` | string | Yes | - | Task description or question about the code |
| `limit` | number | No | 7 | Max snippets to return (max: 20) |
| `compact` | boolean | No | true | Return only metadata without preview |
| `includeWhy` | boolean | No | false | Keep `why[]` even when compact mode suppresses them |
| `boost_profile` | string | No | "default" | File type boosting mode |
| `path_prefix` | string | No | - | Filter by path prefix |
| `category` | string | No | - | Query category for adaptive K |
| `metadata_filters` | object | No | - | Filter by document metadata |
| `why_mode` | string | No | "full" | `"full"` returns verbose tags, `"terse"` shortens prefixes |

### Boost Profiles

Expand Down Expand Up @@ -89,7 +90,8 @@ The most powerful tool for getting started with unfamiliar code. Provide a task
- **Be specific**: Include file names, error messages, symptoms
- **Avoid imperatives**: "auth flow JWT validation" not "Find where authentication happens"
- **Use compact mode**: Default is `compact: true` (95% token savings)
- **Follow up with snippets_get**: Get full code after identifying relevant files
- **Need explanations?** Pass `includeWhy: true` when using compact mode to keep `why[]`
- **Follow up with snippets_get**: Get full code after identifying relevant files. Pass `range_source: item.rangeSource` so clamped windows stay intact even if the default view changes.

---

Expand Down Expand Up @@ -145,24 +147,27 @@ Get specific code sections from a file, aligned to function/class boundaries.

### Parameters

| Parameter | Type | Required | Default | Description |
| ---------------------- | ------- | -------- | ------- | ------------------------------------- |
| `path` | string | Yes | - | File path relative to repository root |
| `start_line` | number | No | - | Starting line number |
| `end_line` | number | No | - | Ending line number |
| `view` | string | No | "auto" | Retrieval strategy |
| `compact` | boolean | No | false | Return only metadata |
| `include_line_numbers` | boolean | No | false | Prefix lines with numbers |
| Parameter | Type | Required | Default | Description |
| ---------------------- | ------- | -------- | -------- | --------------------------------------------------------------- |
| `path` | string | Yes | - | File path relative to repository root |
| `start_line` | number | No | - | Starting line number |
| `end_line` | number | No | - | Ending line number |
| `view` | string | No | "symbol" | Retrieval strategy (override with `KIRI_SNIPPETS_DEFAULT_VIEW`) |
| `compact` | boolean | No | false | Return only metadata |
| `include_line_numbers` | boolean | No | false | Prefix lines with numbers |
| `range_source` | string | No | - | `"symbol"`, `"window"`, or `"clamped"` from `context_bundle` |

### View Modes

| Mode | Behavior |
| -------- | ---------------------------------------------------- |
| `auto` | Uses symbol boundaries if available, else line range |
| `symbol` | Forces symbol-based snippets |
| `symbol` | Forces symbol-based snippets (default behavior) |
| `lines` | Line-based retrieval (ignores symbols) |
| `full` | Returns entire file (500 line limit) |

> **Hint**: Pass the `rangeSource` emitted by `context_bundle` as `range_source` so that clamped windows stay compact even when the default view is symbol.

### Examples

**Get entire file:**
Expand Down
86 changes: 86 additions & 0 deletions docs/uncertainty-issue-210.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
doc_id: "RUN-210"
title: "Issue 210 – Uncertainty Register"
category: "runbook"
tags:
- issue-210
- uncertainty
service: "kiri"
---

# Issue 210 – Uncertainty Register (2026-01-02)

## Decision (1-3 lines)

- **Decision**: Ship issue #210 (symbol-first snippets_get + range metadata) via PR #213 without regressing daemon/watch flows or compact-mode defaults.
- **Deadline**: 2026-01-03 (before weekend freeze).
- **Stakes**: Blocking CI prevents token-usage optimizations from landing; daemon regressions would strand MCP server operators.
- **Constraints**: Keep scope within server runtime + config assets; no breaking API surface or new config files in this patch.

## Register (max 10 to start)

| ID | Category | Uncertainty (question) | Current hypothesis | Impact (1-5) | Evidence (1-5) | Urgency (1-5) | Effort (1-5) | Priority | Next observation |
| ---: | -------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -----------: | -------------: | ------------: | -----------: | -------: | ---------------------------------------------------------------------------- |
| U-01 | Build/runtime | Will daemon/watch tests keep failing because dist bundles miss `config/security.yml`? | Runtime currently resolves `dist/config/security.yml`; CI dist lacks copy, so fallback/root detection fix will unblock. | 5 | 2 | 5 | 2 | 50 | Read `src/shared/security/config.ts`, add fallback path, rerun daemon tests. |
| U-02 | Packaging | Are there other non-TS assets (locks, YAML) that dist/runtime needs but tsconfig skips? | Probably only `config/security.yml`; verify other `config/*.yml` references to avoid future ENOENT. | 4 | 3 | 3 | 3 | 12 | Grep for `config/` loads, confirm watchers/integration tests cover them. |
| U-03 | Feature parity | Did issue/210 actually flip `snippets_get` default view to `symbol` after rebasing on compact-mode main? | `resolveDefaultSnippetsView()` returns `symbol`, but need to ensure env var + docs match. | 3 | 4 | 3 | 2 | 9 | Inspect handler/tests + docs for default statements. |
| U-04 | Documentation | Do docs/tests teach users about compact default + symbol default interplay? | Most doc updates merged, but verify API references mention both defaults. | 2 | 3 | 2 | 3 | 4 | Spot-check `docs/tools-reference.md` + API doc for defaults. |

### Top Priorities

- **P1**: U-01 (Priority 50) – fix runtime fallback so CI passes.
- **P2**: U-02 (Priority 12) – ensure no other asset gaps remain.
- **P3**: U-03 (Priority 9) – confirm snippet defaults and note in PR.

## Observation Backlog

### T-01: Patch security config fallback (for U-01)

- **Hypothesis**: Allowing `loadSecurityConfig` to fall back to repository `config/security.yml` when `dist/config/security.yml` is absent will let daemon/watch tests pass without copying assets.
- **Method**: Code inspection + targeted daemon test run.
- **Timebox**: 2h (includes coding + test run).
- **Steps**:
1. Add helper in `src/shared/security/config.ts` that probes `dist/.../config/security.yml` and then `config/security.yml`.
2. Update loader/evaluator to use helper; add regression tests covering both paths.
3. Run `pnpm vitest tests/shared/security` and `pnpm vitest tests/daemon/daemon.watch.spec.ts`.
- **Decision rule**:
- If tests pass locally, accept change and push.
- If daemon test still fails with ENOENT, escalate to asset-copy approach.
- **Evidence artifact to collect**: Vitest logs for security + daemon suites.
- **Output**: Patched TypeScript + new tests.
- **Owner**: Codex.
- **Status**: Done (2026-01-02) – fallback implemented + daemon/spec + security suites passing.

### T-02: Audit other config assets (for U-02)

- **Hypothesis**: `security.yml` is the only runtime-critical YAML referenced via relative disk paths.
- **Method**: Repo search + doc review.
- **Timebox**: 30m.
- **Steps**:
1. `rg -n \"config/.*\\.yml\" src -g\"*.ts\"` to list runtime references.
2. Verify each reference already works under dist (either uses `resolve()` or bundler).
3. Document findings alongside PR notes.
- **Decision rule**:
- If new asset gaps found, add similar fallbacks or copy logic.
- Otherwise, mark risk as mitigated.
- **Evidence artifact**: Search log & summary note.
- **Output**: Confidence note + optional doc snippet.
- **Owner**: Codex.
- **Status**: Done (2026-01-02) – only `config/security.yml` needed fallback; other loaders already probe multiple paths.

### T-03: Confirm symbol default coverage (for U-03)

- **Hypothesis**: Handler + docs already default to `view=symbol` unless explicit view/range overrides.
- **Method**: Read `src/server/handlers/snippets-get.ts` + tests + docs.
- **Timebox**: 20m.
- **Steps**:
1. Inspect `resolveDefaultSnippetsView` and call sites.
2. Review tests ensuring default view is symbol.
3. Check API docs for mention; update if missing.
- **Decision rule**:
- If default mismatch found, file follow-up.
- If consistent, cite evidence in PR summary.
- **Evidence artifact**: Code references + doc diff if needed.
- **Output**: Verified statement in PR description.
- **Owner**: Codex.
- **Status**: Done (2026-01-02) – handler/test/doc review confirms default `view` is `symbol` absent explicit overrides.
1 change: 1 addition & 0 deletions scripts/assay/kiri-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ export class KiriSearchAdapter implements SearchAdapter<KiriQuery, Metrics> {
goal: query.text,
limit: k,
compact: this.config.compact,
why_mode: "terse",
};

if (this.config.boostProfile && this.config.boostProfile !== "default") {
Expand Down
Loading
Loading