Skip to content

temporal validity + consolidation audit + promotion runbook (#463 #464 #465) - #468

Merged
t0k0sh1 merged 14 commits into
mainfrom
impl-temporal-consolidation
Aug 7, 2026
Merged

temporal validity + consolidation audit + promotion runbook (#463 #464 #465)#468
t0k0sh1 merged 14 commits into
mainfrom
impl-temporal-consolidation

Conversation

@t0k0sh1

@t0k0sh1 t0k0sh1 commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Summary

GitHub Actions 停止中のため、指示どおり1ブランチ・対応ごとコミット#463#464#465 を実装(7コミット)。各コミット時点でローカルの cargo fmt / cargo clippy --all-targets(警告ゼロ)/ cargo test 全スイート、および SDK チェック(surface parity py+ts / pytest 174 / vitest 192 / tsc)を通過済み。

#463 — ADR 0011 実装(3コミット)

  • S1 lib: SourceWindow + 4つの *_within 読み取り。EdgeLens で monomorphize し既存レーンのコード生成は不変。窓内 attribution からの正確な weight 再計算、walk 内での eligibility(窓外エッジは報告も伝導もしない)、ghost ルールと合成
  • S2+S3: registry の window_source_names(SourceFilter × SourceMeta join)、HTTP/MCP/SDK の optional since/until(共有バリデータ再利用、cross は明示拒否 — silent unwindowed 防止)、キャッシュキー分離。e2e 9項目
  • S4 docs: README + llm-protocol.md(as-of の意味論と「date を宣言せよ」の対価)

#464 — ADR 0012 実装(4コミット)

  • S1 lib: merge_evidence(構造 Jaccard+証拠リスト、hidden label 除外)/ contradiction_groups(実測 functional tendency)/ sign_conflicts。fingerprint は名前ベース FNV-1a(compaction の id 再割当に不変、pair-order 正規化)
  • S2 HTTP: POST /contexts/{name}/consolidation/auditchecks 必須の3セクション、assertion-time join、undatable 明示、Role::Read + 無条件 heavy-ops。検出器スタンプ consolidation/1
  • S3 CLI: taguru consolidation — communities パターンの judge。fingerprint 一致で LLM ゼロ、dismiss 一級、{name}::consolidation へ import(manifest 最後)。e2e はスタブ chat で incremental 性質を検証(変更なし再実行 = 0 呼び出し、1 fingerprint 移動 = 1 再判定)
  • S4: MCP audit_consolidation + SDK audit_consolidation/auditConsolidation + README

#465 — 昇格 runbook(1コミット)

  • docs/promotion.html(サイト chrome、全ページに nav 追加)+ examples/skills/memory-promotion/SKILL.md。規約(scratch=通常 context / session:{id} / date 必須)と手順(review → extract → import → audit → retract)、サーバ変更ゼロ

#466 について

着手していません — 自身のゲート(#465 runbook の実運用実績)が未充足のため。#464 実装済みなので、runbook 運用後に判断・着手できます。

Closes #463
Closes #464
Closes #465

https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym

Summary by CodeRabbit

  • 新機能

    • グラフ検索・探索・活性化で、sinceuntil による時間範囲指定に対応しました。
    • 期間内のソースに基づき、関連度・重み・引用を再計算します。
    • 統合監査で、重複・矛盾・古い主張の候補を証拠付きで確認できるようになりました。
    • CLI、API、各SDK、MCPから統合監査を利用できます。
  • ドキュメント

    • メモリ昇格ガイドを追加し、ドキュメント全体からアクセスできるようにしました。

t0k0sh1 added 8 commits August 7, 2026 08:08
ADR 0011 §4's lib half: a SourceWindow (window-qualifying source
names, resolved to interned ids once) and four additive reads —
recall_within, query_any_within, explore_within, activate_within.
An edge is visible iff at least one in-window source attests it, its
weight/count re-derive from the in-window AttributionRecords alone
(exact, per-source sums), and a windowed association lists only the
in-window attributions, so an excluded citation cannot leak back
through the edge it once fed.

The existing lanes are untouched in behavior and, by construction, in
codegen: explore/activate/recall/query_any now route through an
EdgeLens the compiler monomorphizes per call site — the unwindowed
FullLens's constant-true alive folds away, the same reasoning
explore_excluding's doc records for the visible closure. Eligibility
runs inside the walks, not as a post-filter: an out-of-window edge
neither bridges explore nor conducts activation, and the fan total
uses windowed magnitudes so excluded evidence cannot dilute a
neighbor's share either (ADR 0011 §4 step 4, §5). The ghost rule
composes for free — a retracted edge's empty attribution chain has no
in-window sources.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
…463)

S2, registry: window_source_names joins a SourceFilter against the
passage store's metadata — the one place SourceMeta lives — and hands
the eligible names to a read_context closure to resolve into a
SourceWindow; run before read_context like hidden_label/schema_of,
for the same lock reasons. Sources with no stored passage have no
metadata and are absent by construction, ADR 0011 §4's rule.

S3, surface: optional since/until on the four single-context graph
lanes (recall/query/explore/activate) over HTTP, MCP inputSchema, and
both SDKs (surface.yaml + python sync/async + typescript). The window
contract is the passage lane's shared validator (source_filter,
since >= until refused as invalid_argument) so the lanes cannot
drift; the window enters the recall/query cache params so windowed
and unwindowed calls never share an entry, with the existing
[graph, passages] lane pair now load-bearing for metadata changes.
The cross-context lanes declare since/until and REFUSE them — request
bodies ignore unknown fields, and a silently unwindowed result is
exactly the failure the no-silent-caps rule exists to prevent.

e2e (tests/http_api/temporal_window.rs): as-of and since windows,
windowed weight/count/citation re-derivation, the undatable
associations-only source invisible to every window, walk lanes not
conducting out-of-window evidence, the shared refusal, the cross
refusal, and cache-key separation in both directions. SDK checks:
check_surface (py+ts), pytest 174 passed, vitest 192 passed.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
README: the sources-metadata section gains the graph-lane half — the
same since/until window, one context at a time, assertion-time
semantics spelled out (visible iff an in-window source attests,
weights/citations re-derived, until alone = as-of, no stored end
time, undatable sources invisible).

llm-protocol.md: the retrieval loop's expand-and-rank step teaches
time-scoped questions (and that judging which dated answer still
holds is the client's job, from the citations' dates); the ingest
loop's register-originals step makes "declare dates" pay explicitly —
date ?? stored_at is what both search surfaces filter on, and a
passage-less source is invisible to every window.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
ADR 0012 §4's lib half, three additive reads over live edges:
merge_evidence (Jaccard over two concepts' live neighborhoods with
the shared/distinct facts listed — capped with exact totals, hidden
labels excluded so a shared schema:type edge is not "structure"),
contradiction_groups (one O(edges) grouped pass: every (subject,
label) holding ≥2 live objects, each label carrying its measured
functional tendency so many-valued labels sink), and sign_conflicts
(per-source attribution sums disagreeing in sign, both sides named).

Candidates, never verdicts, and nothing temporal: rows carry source
NAMES for the registry to join against SourceMeta (the ADR 0011 §4
layering) — dates never enter the library.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
POST /contexts/{name}/consolidation/audit (ADR 0012 §4): one route,
three caller-selected sections behind a required `checks` array —
every section is a full-graph pass, so the caller names what it pays
for, and unknown or empty selectors refuse. Role::Read beside the
other audits, the unconditional heavy-ops group (no cheap default to
protect), deadline prechecked, scans under block_in_place.

merge reuses vocabulary_audit's twin sweep (lexical + semantic,
type-name concepts already excluded) as the candidate generator and
corroborates each pair with the lib's structural evidence, types
attached when a schema is installed, ranked structure-first.
contradiction serves the grouped pass ranked by measured functional
tendency — each object row joined with its latest assertion time via
the new source_effective_times registry helper (date ?? stored_at,
the ADR 0011 layering: dates never enter the library) — with
sign-contested edges after them. staleness measures each live edge's
gap against its own subject's newest assertion, worst first, with the
undatable count reported so "no candidates" and "nothing was datable"
never look alike.

Every candidate carries a hex FNV-1a fingerprint over its FULL
evidence (names, never ids — compaction reassigns ids), pair-order
canonicalized for merge, computed in the lib where the uncapped
evidence lives; the detector stamp (consolidation/1) scopes
comparability, the louvain-cc/1 precedent. e2e covers detection,
the time join, honest caps and selectors, and fingerprints that hold
still until the evidence moves.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
The communities pattern one shelf over (ADR 0012 §5): the verb runs
the audit, looks every candidate's judgment up by fingerprint
(judgment:{fingerprint} sources in the derived {name}::consolidation
context), judges only what has never been judged — dismissals are
first-class judgments, so a benign candidate never re-costs an LLM
call — and writes back through POST /import, one retract-then-apply
batch per judgment with the taguru_consolidation:1 manifest LAST so
its presence attests a complete artifact. A changed detector marks
every stored judgment incomparable, loudly. Judgments are proposals:
each names its suggested write (alias / retract / negative weight /
re-import); nothing is ever applied by this verb.

The CLI deserializes the real audit response types (api::consolidation
made pub(crate), the resolve/evaluate rule) rather than mirrors that
would drift; strict-JSON verdicts are unwrapped leniently (models
decorate) and re-stored normalized. e2e drives the built binary
against a stub chat: dry-run names the work with zero calls, the
first run judges all five seeded candidates, an unchanged graph
re-runs with zero LLM calls, and one moved fingerprint re-judges
exactly one candidate.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
audit_consolidation over MCP — pass-through of the HTTP shape with
checks required, the ADR 0005 §3 boundary — and audit_consolidation /
auditConsolidation in both SDKs (surface.yaml + python sync/async +
typescript), returning the endpoint's own parsed JSON: the report is
judge-facing evidence, not a decode surface, so no mirrored model
types to drift. README gains the consolidation lane beside the
communities one it patterns after; llm-protocol.md's API row landed
with S2 (the route-documentation invariant enforced it there).
Surface parity checked on both SDKs, pytest 174 and vitest 192 green.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
…465)

The conventions-first half of #423, exactly as scoped: scratch is an
ordinary context (scratch-{agent}, no TTL — forgetting stays an
explicit operation), source ids name their session (session:{id}, so
provenance survives promotion through the existing citation
machinery), dates are always declared (date ?? stored_at is what
ADR 0011's windows and ADR 0012's staleness audit run on — an
undatable source is invisible to every window), and promotion is the
existing verbs in a fixed order: review → extract (resolve-first,
never fork the permanent vocabulary) → import (retract-then-apply,
idempotent re-promotion) → consolidation audit on the landing zone →
retract the promoted scratch.

Ships as docs/promotion.html (site chrome, nav link added across the
pages) plus an agent-facing skill template in
examples/skills/memory-promotion/ — the taguru-code-nav precedent.
The runbook's real-world use is what gates #466 (one-command
promotion) and the umbrella's forgetting question, measure-then-build.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 81255917-6184-4312-913b-a940744ad954

📥 Commits

Reviewing files that changed from the base of the PR and between 78a5b7c and 7cf01c7.

📒 Files selected for processing (3)
  • src/mcp/schema.rs
  • tests/fixtures/wire/mcp/audit_consolidation_tool_schema.json
  • tests/http_api/temporal_window.rs
📝 Walkthrough

Walkthrough

グラフ検索に since/until を追加しました。統合監査API、MCP、SDK、CLIを追加しました。scratch context から恒久 context への昇格ガイドとスキル例も追加しました。

Changes

時間範囲付きグラフ読み取り

Layer / File(s) Summary
契約とクライアント連携
src/llm-protocol.md, sdk/*, src/mcp/*
グラフ検索に sinceuntil を追加し、単一コンテキストの検索、探索、活性化へ転送します。
ソース窓とグラフ実装
src/api/*, src/context/*, src/registry/passages.rs
対象ソースを解決し、窓内の帰属、重み、件数、探索経路、活性化順位を再計算します。
統合検証
tests/http_api/temporal_window.rs, tests/http_api/main.rs, README.md
時間窓、入力エラー、クロスコンテキスト制限、キャッシュ分離を検証・記載します。

統合監査

Layer / File(s) Summary
候補検出とAPI
src/context/consolidation.rs, src/api/consolidation.rs, src/main.rs, src/auth.rs
merge、contradiction、staleness 候補を証拠と fingerprint 付きで生成し、HTTP APIへ接続します。
MCP、SDK、CLI
src/mcp/*, sdk/*, src/consolidation.rs, src/cli.rs
統合監査操作を公開し、候補をLLMで判定し、fingerprint単位で再利用してimportとして保存します。
E2E検証
tests/http_api/consolidation.rs, tests/http_api/contract.rs, tests/fixtures/wire/*
監査結果、入力エラー、dry-run、判定再利用、証拠変更後の再判定、ワイヤー契約を検証します。

メモリ昇格ドキュメント

Layer / File(s) Summary
昇格手順
docs/promotion.html, examples/skills/memory-promotion/SKILL.md
scratch context の記録、抽出、import、監査、撤回の手順を追加します。
サイトナビゲーション
docs/*.html
Guide サイドバーに promotion.html へのリンクを追加します。

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant API
  participant SourceRegistry
  participant Context
  Client->>API: recall/query/explore/activate with since/until
  API->>SourceRegistry: resolve eligible source names
  SourceRegistry-->>API: source window
  API->>Context: execute windowed graph read
  Context-->>API: recalculated associations and traversal results
  API-->>Client: filtered response
Loading
sequenceDiagram
  participant Operator
  participant ConsolidationCLI
  participant AuditAPI
  participant LLM
  participant ImportAPI
  Operator->>ConsolidationCLI: run consolidation
  ConsolidationCLI->>AuditAPI: request audit sections
  AuditAPI-->>ConsolidationCLI: fingerprinted candidates
  ConsolidationCLI->>LLM: judge candidates not in cache
  LLM-->>ConsolidationCLI: apply or dismiss verdict
  ConsolidationCLI->>ImportAPI: import judgment batches and manifest
Loading

Possibly related PRs

  • t0k0sh1/taguru#424: src/context/traverse.rs のグラフ探索を変更しており、本変更の時間範囲付き探索とコード接続があります。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルは時間的有効性、統合監査、昇格 runbook という主要変更を明確に示しています。
Linked Issues check ✅ Passed #463]時間窓、[#464]統合監査、[#465]昇格 runbook の主要な実装要件を、コード・SDK・MCP・文書・テストで満たしています。
Out of Scope Changes check ✅ Passed 変更はリンクされた[#463][#464][#465]の時間窓、統合監査、昇格手順の範囲内です。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch impl-temporal-consolidation

Comment @coderabbitai help to get the list of available commands.

Both real findings the local toolchain (clippy 1.96) let through:
reject_userinfo's if-let-return collapses to `?`, and the async
recall signature goes one-parameter-per-line. No behavior change;
the consolidation e2e and unit tests re-run green.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Nitpick comments (4)
src/consolidation.rs (1)

96-135: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

フラグの値が次のフラグを飲み込みます。

--context--into--checks--config--urlrest.next() の値を無条件に採用します。taguru consolidation --context --dry-run sake は、コンテキスト名として --dry-run を採用し、sake を位置指定 URL として扱います。src/calibrate.rssrc/communities.rs の同じ引数は !value.starts_with('-') で守っています。同じガードを追加すると、この取り違えを使用法エラーとして拒否できます。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/consolidation.rs` around lines 96 - 135, Update the argument parsing
matches for --context, --into, --checks, --config, and --url so their consumed
values are accepted only when they do not start with a dash, matching the guards
in calibrate.rs and communities.rs. Return the existing option-specific usage
error when the next token is another flag or missing, rather than consuming it
as a value; preserve duplicate-option handling for valid values.
sdk/typescript/src/client.ts (1)

923-934: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

since/until の意味を JSDoc に記載してください。

Python SDK の recall/query/explore/activate は、半開区間 [since, until)、epoch 秒、ADR 0011 の重み再計算、until 単独は as-of である点を docstring に記載しています。TypeScript 側の同じ 4 メソッドには記載がありません。同じファイル内の searchPassages は窓の契約を詳細に記載しているため、記載方針も一貫していません。

📝 JSDoc の追記例
   /**
    * Associations whose subject/object entry-matches the cue. `after`
    * resumes past the previous page's last match; `total` stays constant
    * across pages.
+   *
+   * `since`/`until` (epoch seconds, half-open `[since, until)`) window
+   * the graph by assertion time: only facts an in-window-dated source
+   * attests, weights re-derived from those attributions alone (ADR
+   * 0011). `until` alone reads as-of.
    */
   async recall(

同じ追記を queryexploreactivate にも適用してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdk/typescript/src/client.ts` around lines 923 - 934, Update the JSDoc for
the TypeScript methods recall, query, explore, and activate to document that
since and until define the half-open interval [since, until) in epoch seconds,
that the interval triggers ADR 0011 weight recomputation, and that specifying
until without since performs an as-of query. Follow the detailed window-contract
style already used by searchPassages.
src/context/window.rs (2)

83-93: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

窓付き経路で windowed_totals が同一エッジに対し繰り返し実行されます。

WindowLens::aliveWindowLens::magnitude はどちらも windowed_totals を呼び、エッジの帰属チェーン全体を走査します。activate_impl はファン合計の filtermap、および伝播ループの filterscore で、同じエッジに対してこれらを最大 4 回呼びます。エッジあたりの帰属数を N とすると、窓付き活性化のホットループのコストが O(1) から O(N) に増えます。無窓経路は FullLens で畳み込まれるため影響を受けません。

帰属数が多いコーパスで窓付き activate の遅延が問題になる場合は、settled 概念ごとに (count, sum) を一度計算して再利用する形を検討してください。現時点では計測結果に基づく判断で構いません。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/context/window.rs` around lines 83 - 93, Measure the windowed activation
path before changing behavior, focusing on repeated calls from WindowLens::alive
and WindowLens::magnitude to windowed_totals during activate_impl. If profiling
confirms this hotspot, compute each edge’s windowed (count, sum) totals once per
settled concept and reuse them across the fan-sum and propagation
filters/scoring, while leaving the FullLens path unchanged.

391-399: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

未インターンのソース名と全ソース窓のケースがテストされていません。

モジュール doc は 2 つの不変条件を宣言しています。1 つ目は「このグラフでインターンされていない名前は黙って脱落する」です。an_empty_window_answers_empty_everywhere は空のイテレータを渡すため、source_windowfilter_map が未知の名前を落とす分岐は実行されません。2 つ目は「無窓の読み取りは不変」です。全ソースを含む窓が無窓の結果と一致することを検証するテストもありません。

🧪 追加テストの例
#[test]
fn unknown_source_names_drop_out_of_the_window() {
    let context = corpus();
    let window = context.source_window(["doc-old", "存在しないソース"]);
    let hits = context.query_any_within(&["蔵"], &["杜氏"], &[], &window);
    assert_eq!(hits.len(), 1, "未知の名前は窓を広げない");
    assert_eq!(hits[0].object, "高瀬");
}

#[test]
fn a_window_holding_every_source_matches_the_unwindowed_read() {
    let context = corpus();
    let window = context.source_window(["doc-old", "doc-new"]);
    assert_eq!(
        context.query_any_within(&["蔵"], &[], &[], &window),
        context.query_any(&["蔵"], &[], &[]),
    );
}

パス指示「テストされていないエッジケース・失敗系…の欠落…を指摘してください」に基づく指摘です。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/context/window.rs` around lines 391 - 399, Add tests alongside
an_empty_window_answers_empty_everywhere covering both documented invariants:
verify source_window drops unknown names while retaining valid sources, and
verify a window containing every known source produces the same query_any_within
result as unwindowed query_any. Use the existing corpus source names and assert
both result count/content and equality of the full-source query.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/promotion.html`:
- Around line 92-95: Document in docs/promotion.html lines 92-95 that the
session {id} in session:{id} and session:{id}/{doc} must be globally unique
across agents and permanent contexts, using a value such as a UUID. Add the same
global-uniqueness requirement to examples/skills/memory-promotion/SKILL.md lines
19-22; no other changes are needed.

In `@src/api/consolidation.rs`:
- Around line 208-209: Clamp the optional evidence_cap in the consolidation
request setup, alongside limit, using DEFAULT_EVIDENCE_CAP as the fallback and
the established maximum evidence-cap bound. Ensure oversized caller-provided
values are capped before merge_evidence processes them.
- Around line 62-71: ConsolidationAudit の互換レスポンスを golden fixture
に追加してください。tests/http_api/contract.rs に監査エンドポイントの契約テストを追加し、HTTP fixture と MCP ツール
audit_consolidation のスキーマを固定してください。HTTP_CONTRACT と MCP_CONTRACT は引き続き 1 のままにします。

In `@src/consolidation.rs`:
- Around line 425-437: Update parse_judgment to return None when the first
opening-brace index is after the last closing-brace index, using an ordering
check or safe slice access before constructing the JSON slice. Add a regression
test covering input such as "} 判定できません {" and verify it does not panic and
returns None.

In `@src/context/consolidation.rs`:
- Around line 371-492: Extend the tests around merge_evidence,
contradiction_groups, and sign_conflicts to cover the missing contracts: verify
capped evidence lists retain exact uncapped totals, fingerprints remain
identical across different caps and reversed entity order, and expired deadlines
cause both graph-scan methods to return errors. Use the existing
deadline-expiration test helper and preserve the current success-case
assertions.
- Around line 224-228: Update the documentation comment for the consolidation
audit result to describe the candidates as deterministically sorted by (label,
subject), matching the sort_unstable_by_key logic applied to groups; remove the
inaccurate “insertion order” wording while preserving the rest of the documented
behavior.

In `@src/mcp/schema.rs`:
- Around line 386-387: Update the MCP route parameter allowlists in route.rs,
specifically the pick lists used by query, recall, activate, and explore, to
include both "since" and "until". Ensure these client-provided time-window
parameters are forwarded instead of discarded.

In `@tests/http_api/consolidation.rs`:
- Around line 144-167: Extend the consolidation audit test around the existing
selector checks to call the endpoint with checks containing “contradiction” and
limit set to 1, then assert that the response has exactly one candidate while
its total remains 2. Use the existing audit/server response helpers and preserve
the current selector validation assertions.
- Around line 169-206: Extend the consolidation HTTP API tests with a second
judge stub, alongside stub_judge, that returns a model response containing no
JSON. Add a test covering the judgment failure path through
src/consolidation.rs::judge and the CLI, asserting exit code 1 and verifying
that no output artifact is written.

In `@tests/http_api/temporal_window.rs`:
- Around line 51-119: テストの時間窓境界を実際のソース日付に一致させ、半開区間 [since, until)
の上限排他を検証してください。tests/http_api/temporal_window.rs の temporal-window テストでは until:
1000 で doc-2019 を除外し、since: 1000 で含め、since と until の同時指定および date なし・stored_at
のみのソースも追加検証してください。src/registry/passages.rs の SourceFilter テストでは until: Some(200)
により date 200 の doc-new を除外して doc-old のみ残ることを確認し、追加された source_effective_times
のテストも実装してください。

---

Nitpick comments:
In `@sdk/typescript/src/client.ts`:
- Around line 923-934: Update the JSDoc for the TypeScript methods recall,
query, explore, and activate to document that since and until define the
half-open interval [since, until) in epoch seconds, that the interval triggers
ADR 0011 weight recomputation, and that specifying until without since performs
an as-of query. Follow the detailed window-contract style already used by
searchPassages.

In `@src/consolidation.rs`:
- Around line 96-135: Update the argument parsing matches for --context, --into,
--checks, --config, and --url so their consumed values are accepted only when
they do not start with a dash, matching the guards in calibrate.rs and
communities.rs. Return the existing option-specific usage error when the next
token is another flag or missing, rather than consuming it as a value; preserve
duplicate-option handling for valid values.

In `@src/context/window.rs`:
- Around line 83-93: Measure the windowed activation path before changing
behavior, focusing on repeated calls from WindowLens::alive and
WindowLens::magnitude to windowed_totals during activate_impl. If profiling
confirms this hotspot, compute each edge’s windowed (count, sum) totals once per
settled concept and reuse them across the fan-sum and propagation
filters/scoring, while leaving the FullLens path unchanged.
- Around line 391-399: Add tests alongside
an_empty_window_answers_empty_everywhere covering both documented invariants:
verify source_window drops unknown names while retaining valid sources, and
verify a window containing every known source produces the same query_any_within
result as unwindowed query_any. Use the existing corpus source names and assert
both result count/content and equality of the full-source query.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f3b6559-5f4d-46e1-84c3-784ecf590d36

📥 Commits

Reviewing files that changed from the base of the PR and between fab1c82 and 2d47580.

📒 Files selected for processing (52)
  • README.md
  • docs/architecture.html
  • docs/aws.html
  • docs/azure.html
  • docs/bedrock.html
  • docs/benchmark.html
  • docs/concepts.html
  • docs/connectors.html
  • docs/docker-compose.html
  • docs/evaluate.html
  • docs/evidence.html
  • docs/extract.html
  • docs/gcp.html
  • docs/getting-started.html
  • docs/import.html
  • docs/index.html
  • docs/kubernetes.html
  • docs/local-rag-walkthrough.html
  • docs/long-running.html
  • docs/mcp-rag-walkthrough.html
  • docs/modeling.html
  • docs/promotion.html
  • docs/schema.html
  • docs/tracing.html
  • examples/skills/memory-promotion/SKILL.md
  • sdk/python/src/taguru/_async/client.py
  • sdk/python/src/taguru/_sync/client.py
  • sdk/spec/surface.yaml
  • sdk/typescript/src/client.ts
  • src/api.rs
  • src/api/consolidation.rs
  • src/api/explore.rs
  • src/api/recall.rs
  • src/api/sources.rs
  • src/api/vocabulary.rs
  • src/auth.rs
  • src/cli.rs
  • src/consolidation.rs
  • src/context.rs
  • src/context/consolidation.rs
  • src/context/query.rs
  • src/context/traverse.rs
  • src/context/window.rs
  • src/llm-protocol.md
  • src/main.rs
  • src/mcp.rs
  • src/mcp/route.rs
  • src/mcp/schema.rs
  • src/registry/passages.rs
  • tests/http_api/consolidation.rs
  • tests/http_api/main.rs
  • tests/http_api/temporal_window.rs

Comment thread docs/promotion.html Outdated
Comment thread src/api/consolidation.rs
Comment thread src/api/consolidation.rs Outdated
Comment thread src/consolidation.rs
Comment thread src/context/consolidation.rs Outdated
Comment thread src/context/consolidation.rs
Comment thread src/mcp/schema.rs
Comment thread tests/http_api/consolidation.rs
Comment thread tests/http_api/consolidation.rs
Comment thread tests/http_api/temporal_window.rs
t0k0sh1 added 4 commits August 7, 2026 10:13
…ardenings

The real one: the MCP router never forwarded since/until on
recall/query/activate/explore — advertised in the inputSchema, dropped
by pick(), which is precisely the silently-unwindowed failure the
cross refusal exists to prevent. Forwarded now, with an e2e asserting
a windowed query through /mcp actually filters.

The rest: parse_judgment no longer panics on reversed delimiters ("}
… {" from an untrusted model) — get() instead of slicing, with the
test; evidence_cap is clamped like limit; the session source-id
convention now requires global uniqueness (session:{agent}:{id}, docs
and skill both) because import replaces per source id;
contradiction_groups' doc credits the sort, not insertion order, for
determinism; and the test gaps are closed — merge_evidence cap vs
exact totals and cap/pair-order-invariant fingerprints, expired
deadlines on both full-graph passes, limit truncation never touching
total, the shapeless-judgment run failing loudly with no artifact,
the [since, until) boundary AT the boundary plus the stored_at
fallback, and golden wire fixtures pinning the consolidation audit's
HTTP shape and the audit_consolidation MCP tool schema (contracts
stay at 1; both SDK structural checks pass).

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
.claude/skills/ is operator-local configuration, deliberately
untracked (the mutants sweep already dropped this same file once);
the file stays on disk, only the accidental tracking is undone.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
format! already satisfies associate's generic bound; the borrows were
noise the local 1.96 toolchain let through, same as the last round.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
The still-open findings from the second CodeRabbit pass:

- taguru consolidation's value-taking flags no longer swallow a
  following flag as their value (--context --dry-run is now a usage
  error, not a context named "--dry-run") — the --url dash guard
  calibrate/communities already carry, extended to all five.
- The registry layer gets its own [since, until) upper-bound-AT-the-
  boundary witness (until == doc-new's date excludes it) plus the
  missing source_effective_times test (dated mapped, undated absent,
  unknown context None).
- window.rs pins its two documented invariants: unknown source names
  drop out without widening the window, and a window holding every
  source reproduces the plain read exactly.
- The four TS graph methods document the window contract in JSDoc,
  matching the Python docstrings and searchPassages' own style.

Skipped with reasons: evidence_cap's clamp already landed in 6bd5d33
(the reviewer's list lagged), and the windowed_totals-per-edge memo
stays unbuilt per the finding's own "measure first" framing —
ADR 0012 §8 already records it as a contained optimization gated on a
real hot path.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/context/consolidation.rs (1)

178-205: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

merge_evidence の fingerprint 衝突を防止してください。

Line 178-205 は directionlabelother| で連結します。概念名とラベル名は | を含められるため、(label = "a|b", other = "c")(label = "a", other = "b|c") は同じ文字列になります。

この衝突は異なる候補に同じ fingerprint を与えます。CLI はその fingerprint で過去の判定を再利用するため、別の証拠へ誤った判定を再利用します。各フィールドを fold_field で個別にハッシュしてください。ソートには区切り文字で連結した文字列ではなく、(direction, label_name, concept_name) のタプルを使用してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/context/consolidation.rs` around lines 178 - 205, Update the fact
fingerprinting in merge_evidence so direction, label_name, and concept_name are
passed to fold_field as separate fields rather than joined with "|" delimiters.
Sort facts by the tuple (direction, label_name, concept_name) before hashing,
preserving deterministic ordering while preventing delimiter-induced collisions.

Source: Path instructions

src/api/consolidation.rs (1)

274-278: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

監査全体で deadline を強制してください。

staleness_sectionDeadline を受け取りません。contradiction_groupssign_conflicts は各 edge の開始時だけを確認します。その後の候補展開と attribution chain の走査中に deadline が過ぎても、リクエストは DeadlineExceeded になりません。

  • src/api/consolidation.rs#L274-L278: Deadlinestaleness_section へ渡し、その全グラフ走査で期限を確認してください。
  • src/context/consolidation.rs#L269-L300: 候補と source の展開中にも期限を確認し、期限超過を呼び出し元へ返してください。
  • src/context/consolidation.rs#L331-L337: attribution chain の走査中にも期限を確認し、期限超過を返してください。

開始時点で期限切れのケースに加えて、走査途中で期限を超えるケースをテストしてください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/consolidation.rs` around lines 274 - 278,
監査全体で期限超過を確実に伝播するよう、src/api/consolidation.rs の274-278行では staleness_section に
Deadline を渡してください。src/context/consolidation.rs の269-300行では候補・source
展開中に期限を確認し、超過時は呼び出し元へ返してください。331-337行では attribution chain
の各走査中にも同様に確認・伝播し、開始時および走査途中の期限超過を検証するテストを追加してください。

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/fixtures/wire/mcp/audit_consolidation_tool_schema.json`:
- Around line 11-21: Update the audit consolidation tool schema’s checks array
to require at least one item by adding the minItems constraint with value 1, and
apply the same constraint to the generated/source schema and this fixture so
empty checks arrays are rejected consistently.

In `@tests/http_api/temporal_window.rs`:
- Around line 183-195: Extend the MCP query coverage in the temporal window test
around server.call_tool to add a since-only request and assert its expected
result, then add a request containing both since and until and verify both
bounds are applied. Preserve the existing until-only assertions.

---

Outside diff comments:
In `@src/api/consolidation.rs`:
- Around line 274-278: 監査全体で期限超過を確実に伝播するよう、src/api/consolidation.rs の274-278行では
staleness_section に Deadline を渡してください。src/context/consolidation.rs
の269-300行では候補・source 展開中に期限を確認し、超過時は呼び出し元へ返してください。331-337行では attribution chain
の各走査中にも同様に確認・伝播し、開始時および走査途中の期限超過を検証するテストを追加してください。

In `@src/context/consolidation.rs`:
- Around line 178-205: Update the fact fingerprinting in merge_evidence so
direction, label_name, and concept_name are passed to fold_field as separate
fields rather than joined with "|" delimiters. Sort facts by the tuple
(direction, label_name, concept_name) before hashing, preserving deterministic
ordering while preventing delimiter-induced collisions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 77400038-0476-4822-9fd9-a713595d22fb

📥 Commits

Reviewing files that changed from the base of the PR and between 2d47580 and 78a5b7c.

📒 Files selected for processing (14)
  • docs/promotion.html
  • examples/skills/memory-promotion/SKILL.md
  • sdk/typescript/src/client.ts
  • src/api/consolidation.rs
  • src/consolidation.rs
  • src/context/consolidation.rs
  • src/context/window.rs
  • src/mcp/route.rs
  • src/registry/passages.rs
  • tests/fixtures/wire/http/consolidation_audit.json
  • tests/fixtures/wire/mcp/audit_consolidation_tool_schema.json
  • tests/http_api/consolidation.rs
  • tests/http_api/contract.rs
  • tests/http_api/temporal_window.rs
🚧 Files skipped from review as they are similar to previous changes (6)
  • examples/skills/memory-promotion/SKILL.md
  • docs/promotion.html
  • sdk/typescript/src/client.ts
  • src/registry/passages.rs
  • src/context/window.rs
  • src/consolidation.rs

Comment thread tests/fixtures/wire/mcp/audit_consolidation_tool_schema.json
Comment thread tests/http_api/temporal_window.rs
The MCP inputSchema now says what the server enforces — checks with
minItems: 1, so a client cannot generate the empty selector the
endpoint refuses — with the golden fixture regenerated to match. And
the MCP window e2e sends a closed [since, until) window, so a router
that forwarded until while dropping since can no longer pass.

Claude-Session: https://claude.ai/code/session_015xiMrm5VWArTNfQJyyMuym
@t0k0sh1

t0k0sh1 commented Aug 7, 2026

Copy link
Copy Markdown
Owner Author

第3ラウンドの2件を 7cf01c7 で対応しました: checks の inputSchema に minItems: 1(fixture 再生成済み)、MCP e2e に閉じた窓 [since, until) を追加して since の転送も検証。全スレッド解決済みです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant