diff --git a/artifacts/fork-archaeology-issue-100/behavioral-coverage-audit.json b/artifacts/fork-archaeology-issue-100/behavioral-coverage-audit.json new file mode 100644 index 000000000000..a38a7da915b9 --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/behavioral-coverage-audit.json @@ -0,0 +1,2272 @@ +{ + "schema_version": 1, + "purpose": "Adversarial hunk-level behavioral coverage audit for Phase-1 capability accounting.", + "inputs": { + "fork_ref": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "upstream_ref": "460d345642ee3d143a3e461abe39fd42b86a7e54", + "merge_base": "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53" + }, + "method": { + "unit": "behavior-bearing hunk/intent, not commit title or provisional bucket", + "candidate_signals": [ + "control flow", + "skip/gate", + "retry/backoff", + "timeout/cooldown", + "threshold/default/limit", + "state transition", + "persistence/schema", + "query ordering", + "locking/concurrency", + "cache", + "routing", + "fallback/error", + "observable output" + ], + "rule": "Every behavior-bearing historical change is covered by a capability contract, promoted to a separate capability, or explicitly proven non-semantic/bookkeeping.", + "many_to_many": "A single historical record may have multiple rows and multiple semantic intents." + }, + "coverage_gate": { + "change_records": 145, + "merge_events": 26, + "unique_change_records_reviewed": 145, + "behavior_rows": 141, + "promoted_behavior_rows": 5, + "explicit_nonsemantic_rows": 8, + "uncovered_behavior_rows": 0, + "complete": true + }, + "change_records": [ + { + "record_sha": "00a2675a9270033325d53d7a3301a58f5f66d760", + "subject": "test(fts): pin storage-v2 refusal states (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_fts_storage_v2_settlement.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b86e4f526ec377f7f958dc21ddaac87238882f19", + "subject": "fix(fts): unify storage-v2 settlement predicate (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "2c907113fd2c50edde60425c561ab8ca25192b1b", + "subject": "test(fts): cover storage-v2 interruption/reopen + acceptance matrix (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_fts_storage_v2_settlement.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "f887f44fa2d27c7ec4132fe70d337f7975fcde63", + "subject": "docs(research): record storage-v2 settlement implementation (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-31-storage-v2-settlement.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "180ae82a2d7ec34a099665d68719c8579986d693", + "subject": "test(fts): pin structural refusal branches (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_fts_storage_v2_settlement.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "1d6d73f3bb8ffeb599799c05b6e853da1758b4db", + "subject": "refactor(fts): settle review-round findings (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-31-storage-v2-settlement.md, hermes_state_schema.py, hermes_state_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0fafc1dd7b58f15982ce2833de2bc8826a1e116f", + "subject": "test(fts): pin mixed-capability optimize availability (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_fts_storage_v2_settlement.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "67d4f719d6b0717be024861ae2756fa49d6f1315", + "subject": "fix(fts): optimize-available sees any actionable blocker (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-31-storage-v2-settlement.md, hermes_state_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0ff8583e91c838088fde6cb55ba0488cf5a0ee93", + "subject": "docs(research): fix settlement test count in validation note (#31)", + "current_bucket": "capability:session-fts-storage-v2", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-31-storage-v2-settlement.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-storage-v2.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-storage-v2" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "00e680a8cb22e251f351b9f140b0679c4f96dabc", + "subject": "feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_search.py, tests/test_fts_lifecycle_registry.py, tests/test_hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1", + "subject": "feat(fts): registry-driven health probes + trigger inventory/convergence (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_schema.py, hermes_state_search.py, tests/test_fts_lifecycle_registry.py, tests/test_hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "474b88fe76e18dfcf397f11b3de6f069abac4a4c", + "subject": "fix(fts): registry-driven offline + destructive repair covers session indexes (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_fts_lifecycle_registry.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "f9ade6baff7f236b6b9401932c61bc0400375664", + "subject": "feat(fts): read-only session capability discovery + shared rebuild-lane iteration (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_search.py, tests/test_fts_lifecycle_registry.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "e64ad007b459871af42e312bc5dffd2da92ac900", + "subject": "test(fts): six-index regression matrix for maintenance/repair/read-only/degraded-runtime (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_fts_lifecycle_registry.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "bdd9d699f6dc13b32852a078c1ecf5664bcb837d", + "subject": "docs(fts): record six-index unified lifecycle implementation for #27", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-27-unified-fts-lifecycle.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0400c66f072d0f319331ea105cd8f7e059975388", + "subject": "refactor(fts): apply review round — drop dead lane keys, merge trigger-drop + CJK quarantine helpers, remove dead _FTS_TRIGGERS (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, tests/test_hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "75223d19544ceb73cf24fb859fc0780ed9a099a5", + "subject": "docs(fts): record review round 1 for #27", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-27-unified-fts-lifecycle.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec", + "subject": "fix(fts): reuse #30 ownership classifier in offline/global paths + read-only CJK worker fix (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_fts_lifecycle_registry.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "dc1f153a71d025d903f255861da57f94d649ca37", + "subject": "docs(fts): record review round 2 for #27 unified FTS lifecycle", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-27-unified-fts-lifecycle.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a", + "subject": "fix(fts): read-only trigram discovery gates on full #30 namespace ownership (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_fts_lifecycle_registry.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d", + "subject": "docs(fts): record review round 3 for #27 unified FTS lifecycle", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-27-unified-fts-lifecycle.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "3bc7d3f58f808e269675404c9bbeada467b00e98", + "subject": "refactor(fts): ponytail pass — drop redundant tests, shrink review history + comments (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-27-unified-fts-lifecycle.md, hermes_state.py, tests/test_fts_lifecycle_registry.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "d6a4d70483623cc3fad4eea8c96754d7d637d02c", + "subject": "fix(fts): read-only trigram serving requires a complete trigger set (#27)", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_fts_lifecycle_registry.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0cf4cd0baffb68b571a44f2a39d3bf817cd38348", + "subject": "docs(fts): record review round 4 for #27 unified FTS lifecycle", + "current_bucket": "capability:session-fts-lifecycle", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-27-unified-fts-lifecycle.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-lifecycle.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-lifecycle" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "04f1af72be078cef69de538f1519f93a73088b0d", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold", + "current_bucket": "capability:memory-trim-diagnostics", + "behavior_bearing": true, + "hunk_or_scope": "hermes_cli/mem_trim.py: threshold_mb gate", + "behavior_change": "RSS below threshold_mb skips the expensive trim work.", + "proposed_capability": "capability:memory-trim-policy", + "action": "PROMOTE_TO_SEPARATE_CAPABILITY", + "confidence": "high" + }, + { + "record_sha": "04f1af72be078cef69de538f1519f93a73088b0d", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold", + "current_bucket": "capability:memory-trim-diagnostics", + "behavior_bearing": true, + "hunk_or_scope": "hermes_cli/mem_trim.py: gc_ms/trim_ms, malloc_info, VmSwap", + "behavior_change": "Trim diagnostics attribute GC cost, allocator fragmentation, and swap pressure.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:memory-trim-diagnostics" + ], + "action": "COVERED_BY_SPLIT_CAPABILITY", + "confidence": "high" + }, + { + "record_sha": "0a4b567ff08776a3a10ee7a32d37332d873f20b2", + "subject": "feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin", + "current_bucket": "capability:headroom-retrieval", + "behavior_bearing": true, + "hunk_or_scope": "plugins/headroom/__init__.py, tests/plugins/test_headroom_plugin.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-retrieval.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-retrieval" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "current_bucket": "capability:headroom-retrieval", + "behavior_bearing": true, + "hunk_or_scope": "plugins/headroom/__init__.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-retrieval.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-retrieval" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "ff4df5b71e1557660dbe994eb5569983f57c9901", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "current_bucket": "capability:headroom-retrieval", + "behavior_bearing": true, + "hunk_or_scope": "plugins/headroom/__init__.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-retrieval.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-retrieval" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b527e4df996b859356c0c48c2b9c9eae4c74c4dc", + "subject": "fix(headroom): auto-enable headroom_retrieve tool when compression is active", + "current_bucket": "capability:headroom-retrieval", + "behavior_bearing": true, + "hunk_or_scope": "hermes_cli/tools_config.py, plugins/headroom/plugin.yaml, pyproject.toml, uv.lock", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-retrieval.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-retrieval" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0b4e7601227a23bc653d0d3018a3a9591d02f2a1", + "subject": "fix: headroom_retrieve tool schema — add description and parameters wrapper", + "current_bucket": "capability:headroom-retrieval", + "behavior_bearing": true, + "hunk_or_scope": "plugins/headroom/__init__.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-retrieval.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-retrieval" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "subject": "fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "3053abf3b039a5b4c23637597cb076f2339250fb", + "subject": "fix: let all CJK queries use simple tokenizer; cache lineage resolves", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "6311e77e27f4fd4009c73d0df16abebf56121f4a", + "subject": "docs(research): map CJK session metadata FTS lifecycle for #33", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-33-cjk-session-metadata-fts-lifecycle.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "3e23375f7934e4315d45860e6992171fb5609c5c", + "subject": "test(session-fts): RED contract for CJK session metadata lifecycle (#26)", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_metadata_cjk_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7", + "subject": "feat(session-fts): external-content CJK metadata DDL + capability/quarantine (#26)", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5", + "subject": "feat(session-fts): plug CJK session rebuild into the generic engine (#26)", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128", + "subject": "feat(session-fts): CJK metadata candidate seam + all-3-field search (#26)", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_session_metadata_cjk_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "83431f775a9e3798611e03b16a2f7d9a7ac74a57", + "subject": "docs(design): document the #26 CJK session metadata FTS variant", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "docs/design/session-metadata-fts.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "8efead2600a3f932f9881b53cd0c7eabc755f82f", + "subject": "fix(session-fts): address #26 code-review findings", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "docs/design/session-metadata-fts.md, hermes_cli/session_recovery.py, hermes_state.py, hermes_state_search.py, tests/hermes_cli/test_session_recovery.py, tests/test_session_metadata_cjk_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "6b3402ea05566fa1553a93aceb285eb517d7e67d", + "subject": "fix(session-fts): three lifecycle/capability seams for CJK session FTS (round-3 review)", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_session_metadata_cjk_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0eee69ef43f16c63f29db414e1acb40253212125", + "subject": "fix(session-fts): run CJK guard+MATCH in one SQLite snapshot (PR #65 P1)", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_session_metadata_cjk_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "6447a52cd994bf30c2811814f21095d12aba83ae", + "subject": "fix(state): short-circuit CJK-unservable to direct LIKE + single compression edge", + "current_bucket": "capability:session-fts-cjk", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, tests/test_session_metadata_picker_routing.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-cjk.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-cjk" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "subject": "feat: add lifecycle and SQLite observability telemetry", + "current_bucket": "capability:lifecycle-sqlite-telemetry", + "behavior_bearing": true, + "hunk_or_scope": "agent/conversation_compression.py: explicit last_compression_status == noop branch", + "behavior_change": "A compressor-reported noop does not rotate or rewrite the session, even when it returns a new list object.", + "proposed_capability": "capability:compression-session-boundary", + "action": "PROMOTE_TO_SEPARATE_CAPABILITY", + "confidence": "high" + }, + { + "record_sha": "176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "subject": "feat: add lifecycle and SQLite observability telemetry", + "current_bucket": "capability:lifecycle-sqlite-telemetry", + "behavior_bearing": true, + "hunk_or_scope": "lifecycle, SQLite, stream, and delivery instrumentation hunks", + "behavior_change": "Structured lifecycle and SQLite telemetry is emitted at execution boundaries.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:lifecycle-sqlite-telemetry" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "296d9c6e2e5a6f852344ad8fa9b90f5687912be1", + "subject": "feat: add transform_api_request plugin hook for full-payload request transformation", + "current_bucket": "capability:request-transform-hook", + "behavior_bearing": true, + "hunk_or_scope": "agent/conversation_loop.py, hermes_cli/hooks.py, hermes_cli/plugins.py, tests/run_agent/test_run_agent.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:request-transform-hook.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:request-transform-hook" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "37811327cdc65c85c4b0bd565b1cdb3a4590dd91", + "subject": "feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "subject": "docs(research): map normalized session trigram FTS", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-34-normalized-session-metadata-trigram-fts.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "ad0c45f0924349f6f0453d4941c3d76ad5258cdc", + "subject": "test(fts): pin modern session trigram and legacy-simple states", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "48b04dae36d6577b06de0efc67ebe1eb1a479d4c", + "subject": "feat(fts): add normalized external-content session trigram index (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "6f82bcbb3c5f714148a17da47577e862493a55d6", + "subject": "test(fts): cover normalized session trigram end to end (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0f29f1454ea2227229e4056d66ed09f749a06e46", + "subject": "docs(research): document normalized session trigram FTS implementation (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3", + "subject": "fix(fts): clear unfulfillable trigram claim on tokenizer-less host + de-dup shared seams (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, hermes_state_common.py, hermes_state_search.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "252920f02442b68391fcafba35bef2c9567e9ab8", + "subject": "style(fts): consolidate session trigram ensure epilogue + spec-driven transition columns (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "4483194b81495dab9b3c4c282c08adad89e0f2d9", + "subject": "fix(fts): classify session trigram schema by exact logical columns + VIEW projection (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "bfa928d53da7c61814816c10f83fef75bfef7e43", + "subject": "fix(fts): require canonical source VIEW + FTS5 root for modern trigram identity (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "cc5261ce775c8db6a7099d411f16030d24e71f2f", + "subject": "fix(fts): classify legacy session trigram by DDL, never PRAGMA table_info (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, hermes_state_common.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "e33b533e1d2421fb18941463b6fe51752a8ad345", + "subject": "fix(fts): classify modern session trigram by DDL, never PRAGMA table_info (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b5155410abbf04c1fc4bb433ae3f5e546f5bf426", + "subject": "fix(fts): gate trigram source VIEW ensure on source compatibility (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "9aad13bcad68a292f708fe30698405c2016b2626", + "subject": "fix(fts): classify same-name root VIEW as unknown, not absent (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "3172c9f4611cc2b872f2083829577cc73152f9dc", + "subject": "fix(fts): exact shadow allowlist + classify same-name root index as unknown (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, hermes_state_common.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "6467a30563fb1da2bd5c1f42dc7cd1f574697d31", + "subject": "fix(fts): hardening pass — literal-safe identity, trigger/shadow ownership, demotion CAS, stale lifecycle, serving gates, empty-claim, query cap (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, hermes_state.py, hermes_state_common.py, hermes_state_search.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c", + "subject": "fix(fts): harden session trigram transition namespaces (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_search.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "72388ff87f0baf99910edefab2b2fc2e00b40284", + "subject": "fix(fts): preserve session trigram claims across capability handoff (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0c02b83d4d8702267481a5f196606e19e3d303cc", + "subject": "fix(fts): gate session trigram mutations on durable ownership (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_search.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a9c1b2d11bab435cda80fcfc81fc223d210b4755", + "subject": "fix(fts): serve session trigram candidates from one snapshot (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48", + "subject": "test(fts): drop fork-only legacy simple convergence tests (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "c7163001f23feb31f94fec1ebb3c41badaebdb97", + "subject": "refactor(fts): drop fork-only legacy simple demotion lane (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "6f534c8760a30a318ae0d874b7a6323f5f0337df", + "subject": "docs(fts): record scope correction and legacy lane removal (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "10e3419d10e938c979c701246457cbd6f9c10ad4", + "subject": "test(fts): drop round-11 CAS and shadow-preflight tests (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "69591fe659774a4e61a3f754211f5602e96a7381", + "subject": "fix(fts): quarantine healthy modern target on no-trigram runtime; drop unsupported hardening (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, tests/test_session_metadata_trigram_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea", + "subject": "docs(fts): record round-12 re-review and subtractive hardening removal (#30)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "783d3fa59ae28010368368e3dafddc19750f9b55", + "subject": "test(recovery): pin session-trigram derived markers as generated meta (#79)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "tests/hermes_cli/test_session_recovery.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "4aefa3abbbe4f9c3eba29988fa772e45d70000f9", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "hermes_cli/session_recovery.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "d4c9a165c5abe6cf8c0503005b18e55de58e28cc", + "subject": "docs(research): record session-trigram recovery marker fix (#79)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-79-session-recovery-trigram-markers.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "f17ab58979753a9ee342d258595e8d076ef2f309", + "subject": "test(recovery): guard verifier detection of leftover session-trigram markers (#79)", + "current_bucket": "capability:session-fts-trigram", + "behavior_bearing": true, + "hunk_or_scope": "tests/hermes_cli/test_session_recovery.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-trigram.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-trigram" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "3de538d32a3c076929c1d7c173dd77e4055100f9", + "subject": "perf: reduce SELECT * in get_compression_lineage to 4 columns", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "6fa6c557257175f26c1689799d352fdf948cb787", + "subject": "fix: replace SELECT * with specific columns in get_anchored_view and get_messages_around", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/hermes_state/test_get_messages_around.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "2732c47e28fbf7aaea97bd8c5cf82045a4c34159", + "subject": "wip(session-search): move winner selection into SQL", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_session_search_sql_winners.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "2d2bad204ec644455ad1273f2934f388eb4111dd", + "subject": "fix(session-search): defer winner snippets", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32", + "subject": "fix(session-search): ranked Top-N pre-limit for relevance sort", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "d72f99eb1b897dd29a46692a310aa15b1bfd77e8", + "subject": "docs(research): index session-lineage research", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "research/session-lineage/README.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "8838d16060bb7610c6d7ad3697f384df3edb70c1", + "subject": "test(search): RED contracts for #68 compression-lineage resolver", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_search_sql_winners.py, tests/tools/test_session_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "46907bc8b55ba36ef73e0d96c10eccb9b28b0310", + "subject": "feat(search): compression-lineage resolver for #68 winner seam", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_search.py, tests/test_session_search_sql_winners.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "2f12b03079cb7ae28acf666d16cfd748e5eaac74", + "subject": "feat(session-search): tool parity + truncation contract for #68", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "tests/tools/test_session_search.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "2e1b2e64d7a452f524f703a99d68b1b110b93d3e", + "subject": "test(search): drop stale generic-parent oracle import after #68 flip", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_search_sql_winners.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a13d012e5b8736928662f27269d9f2a7cf84f0af", + "subject": "docs(session-storage): document #68 compression-lineage resolution", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "website/docs/developer-guide/session-storage.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "66eb2fad76abf150043ffd899fbdfbd328aba2d0", + "subject": "fix(search): title/current share in-snapshot roots + compacted anchor fallback (#68 review)", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_search.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "f32b51764e43e48195d10e62d64b195a052d4968", + "subject": "test(search): #68 review acceptance — title parity, compacted anchor, real B boundaries, snapshot, 10k, internal-K", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_search_sql_winners.py, tests/tools/test_session_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "42c421f68b6556757c17b4dc78756cf31babd239", + "subject": "fix(search): distinct-owner candidates + title-only K=1 snapshot contract (#68 review round-2)", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_search.py, tests/test_session_search_sql_winners.py, tests/tools/test_session_search.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "c81ab321ec4bb3d5a33429b28907cd5836e41789", + "subject": "fix(search): displayable-anchor ranking + drop unproven title on B-hit (#68 review round-3)", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_search.py, tests/test_session_search_sql_winners.py, tests/tools/test_session_search.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6", + "subject": "fix(search): don't gate exact-title on unrun content snapshot (#68 review round-4)", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_search.py, tests/tools/test_session_search.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "55dc24391f92d71d9e293c7990089075f2ff49c9", + "subject": "refactor(search): drop title/current lineage-proof protocol per #68 review round-5", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state_search.py, tests/test_session_search_sql_winners.py, tests/tools/test_session_search.py, tools/session_search_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b2710666a29eed6fc46f3b6ce23c72f4dc766181", + "subject": "test(search): rename title==current test, correct misleading scope claim (#68 review final)", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "tests/tools/test_session_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "1f5edc591353a0a65ec7aa2f02c6916fd67fd505", + "subject": "perf(state): narrow session listing before lineage hydration", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a615feaea695123d1b3a832417a9a76554301af8", + "subject": "test(state): cover whole-store lineage visibility and pagination", + "current_bucket": "capability:session-search-lineage", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_metadata_picker_routing.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-lineage.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-lineage" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "44afcc8d3f869c7780beb1bc0bece86df1e45cb2", + "subject": "test: code fence tracking coverage for all send/split paths", + "current_bucket": "capability:outbound-code-fence-safety", + "behavior_bearing": true, + "hunk_or_scope": "tests/gateway/test_code_fence_tracking.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:outbound-code-fence-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:outbound-code-fence-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "47cc1764dc2c2c65cc83fe20500da939698d72d3", + "subject": "fix: close orphaned code fences on all send paths", + "current_bucket": "capability:outbound-code-fence-safety", + "behavior_bearing": true, + "hunk_or_scope": "gateway/platforms/base.py, gateway/stream_consumer.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:outbound-code-fence-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:outbound-code-fence-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "347442ddc80a2658582cb62dd268a0be024b1bcf", + "subject": "fix: escape triple-backtick in reasoning before wrapping in outer code block", + "current_bucket": "capability:outbound-code-fence-safety", + "behavior_bearing": true, + "hunk_or_scope": "gateway/run.py, gateway/stream_consumer.py, tests/gateway/test_escape_reasoning_fences.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:outbound-code-fence-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:outbound-code-fence-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "efd68fe044001c57c5d148a66469209589c344d9", + "subject": "fix: ensure balanced code fences after Discord edit_message brute-force truncation", + "current_bucket": "capability:outbound-code-fence-safety", + "behavior_bearing": true, + "hunk_or_scope": "plugins/platforms/discord/adapter.py, tests/gateway/test_truncation_fence_edge_case.py, tests/plugins/platforms/discord/test_edit_message_fence.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:outbound-code-fence-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:outbound-code-fence-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "c1a3e16c32896ea2d469536c657814049c29bec6", + "subject": "fix: also close orphaned single-backtick inline-code spans", + "current_bucket": "capability:outbound-code-fence-safety", + "behavior_bearing": true, + "hunk_or_scope": "gateway/stream_consumer.py, tests/gateway/test_code_fence_tracking.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:outbound-code-fence-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:outbound-code-fence-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "44dd4c5e586e60c22a322a9eb89d1aed63892e36", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a4e2c52f1582952686ee56aaedd7285874326102", + "subject": "fix: address Copilot review — init hermes_home, load simple in ro path, v21 migration", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a1136e548ea1f2200429bf44f8f1a7297cc84246", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "c20cb64b4b79468c641626e9b9d3957790f7a671", + "subject": "fix: address Copilot review — init hermes_home, load simple in ro path, v21 migration", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a", + "subject": "fix(state): load simple tokenizer so legacy trigram tables stay writable", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "196b904417371cf233f3eb9b560c80a079ab8d72", + "subject": "docs(research): map simple-tokenizer EOL for #40", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-40-simple-tokenizer-eol.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "85fd91fd7c7be20d63356f27654d399ca1da4fa0", + "subject": "test(fts): pin simple-tokenizer EOL policy (#19)", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_simple_tokenizer_eol.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "186986a447080ae74a1d17fd1e32aaf039cb2ff2", + "subject": "fix(fts): retire simple-tokenizer residue; drop global shim (#19)", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, tests/test_optional_cjk_tokenizer_fallback.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "deb10243ccebd6153cdfab8e9869faba2e105f0e", + "subject": "docs(fts): close simple compatibility contract (#19)", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-19-simple-tokenizer-eol-implementation.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "1d5b80cab802e6ae932c97342e328e76faa496fa", + "subject": "fix(fts): harden simple EOL sanitation per review (#19)", + "current_bucket": "capability:session-fts-simple-eol", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-19-simple-tokenizer-eol-implementation.md, hermes_state.py, tests/test_simple_tokenizer_eol.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-simple-eol.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-simple-eol" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "895ba96014ecf934dbc140306ffe578a0a533ea3", + "subject": "feat: configurable reasoning max lines via display.reasoning_max_lines", + "current_bucket": "capability:configurable-reasoning-display", + "behavior_bearing": true, + "hunk_or_scope": "cli.py, gateway/run.py, tests/gateway/test_reasoning_max_lines.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:configurable-reasoning-display.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:configurable-reasoning-display" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "915913db360de5fe5b147d4895276ff39a6e8686", + "subject": "Add opt-in headroom tool-output compression plugin", + "current_bucket": "capability:headroom-compression", + "behavior_bearing": true, + "hunk_or_scope": "hermes_cli/config.py, plugins/headroom/__init__.py, plugins/headroom/plugin.yaml, tests/plugins/test_headroom_plugin.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-compression.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-compression" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "5eb552458de9828f4496880fd878f58015a63389", + "subject": "feat(headroom): add ContentRouter + SmartCrusher integration behind config flag", + "current_bucket": "capability:headroom-compression", + "behavior_bearing": true, + "hunk_or_scope": "plugins/headroom/__init__.py, plugins/headroom/plugin.yaml, tests/plugins/test_headroom_plugin.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-compression.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-compression" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "c16ebe6b8649c570b688fd82d6b66f9a8416d59c", + "subject": "fix(headroom): logger.warning for ContentRouter/CacheAligner failures + warning E2E tests", + "current_bucket": "capability:headroom-compression", + "behavior_bearing": true, + "hunk_or_scope": "plugins/headroom/__init__.py, tests/plugins/test_headroom_plugin.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-compression.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-compression" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "237176ed1d973910972984ba83d876d01c00f3db", + "subject": "fix(headroom): prevent metadata from expanding tool results", + "current_bucket": "capability:headroom-compression", + "behavior_bearing": true, + "hunk_or_scope": "plugins/headroom/__init__.py, plugins/headroom/plugin.yaml, tests/plugins/test_headroom_plugin.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:headroom-compression.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:headroom-compression" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a2450695db0e99f3dd8362f129024cb74c700bb8", + "subject": "fix(browser): config-gated daemon kill on timeout", + "current_bucket": "capability:browser-timeout-cleanup", + "behavior_bearing": true, + "hunk_or_scope": "tools/browser_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:browser-timeout-cleanup.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:browser-timeout-cleanup" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b42bc25e622c11230998cc57f7050ec2a2cdd090", + "subject": "fix(browser): add tests and crash-resilience for daemon-kill on timeout", + "current_bucket": "capability:browser-timeout-cleanup", + "behavior_bearing": true, + "hunk_or_scope": "tests/tools/test_browser_terminate_daemon_timeout.py, tests/tools/test_browser_timeout_cleanup.py, tools/browser_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:browser-timeout-cleanup.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:browser-timeout-cleanup" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "cfb2636a6a3ed02ff773f106beb71c88576f1284", + "subject": "fix(browser): move dict cleanup to finally block on timeout (P1 fix)", + "current_bucket": "capability:browser-timeout-cleanup", + "behavior_bearing": true, + "hunk_or_scope": ".github/actions/hermes-smoke-test/action.yml, .github/workflows/build-windows-installer.yml, .github/workflows/docker-publish.yml, .github/workflows/nix-lockfile-fix.yml, .github/workflows/nix.yml, agent/gemini_cloudcode_adapter.py, agent/google_code_assist.py, agent/google_oauth.py, apps/desktop/src/app/chat/composer/skin-slash-popover.tsx, apps/desktop/src/app/cron/cron-job-actions-menu.tsx, apps/desktop/src/app/overlays/overlay-search-input.tsx, apps/desktop/src/app/right-sidebar/terminal/index.tsx, apps/desktop/src/app/session/hooks/use-message-stream.ts, apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx, apps/desktop/src/app/session/hooks/use-prompt-actions.ts, apps/desktop/src/app/session/hooks/use-session-actions.ts, apps/desktop/src/components/assistant-ui/streaming.test.tsx, apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx, apps/desktop/src/components/assistant-ui/thread.tsx, apps/desktop/src/components/assistant-ui/todo-tool.tsx, apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx, apps/desktop/src/components/assistant-ui/tool-approval.test.tsx, apps/desktop/src/components/assistant-ui/tool-approval.tsx, apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts, apps/desktop/src/components/assistant-ui/tool-fallback-model.ts, apps/desktop/src/components/assistant-ui/tool-fallback.tsx, apps/desktop/src/components/assistant-ui/user-message-text.tsx, apps/desktop/src/components/chat/generated-image-context.tsx, apps/desktop/src/components/desktop-onboarding-overlay.test.tsx, apps/desktop/src/components/desktop-onboarding-overlay.tsx, apps/desktop/src/components/ui/braille-spinner.tsx, apps/desktop/src/lib/gateway-ws-url.ts, gateway/platforms/dingtalk.py, gateway/platforms/email.py, gateway/platforms/feishu.py, gateway/platforms/feishu_comment.py, gateway/platforms/feishu_comment_rules.py, gateway/platforms/feishu_meeting_invite.py, gateway/platforms/homeassistant.py, gateway/platforms/matrix.py, gateway/platforms/slack.py, gateway/platforms/sms.py, gateway/platforms/telegram.py, gateway/platforms/telegram_network.py, gateway/platforms/wecom.py, gateway/platforms/wecom_callback.py, gateway/platforms/wecom_crypto.py, gateway/platforms/whatsapp.py, optional-skills/productivity/shop-app/SKILL.md, plans/gemini-oauth-provider.md, tests/tools/test_browser_timeout_cleanup.py, tools/browser_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:browser-timeout-cleanup.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:browser-timeout-cleanup" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb", + "subject": "fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim", + "current_bucket": "capability:memory-trim-policy", + "behavior_bearing": true, + "hunk_or_scope": "hermes_cli/mem_trim.py: _last_gc_monotonic and gc_cooldown_seconds", + "behavior_change": "gc.collect() is independently cooled down while malloc_trim remains on the trim cadence.", + "proposed_capability": "capability:memory-trim-policy", + "action": "PROMOTE_TO_SEPARATE_CAPABILITY", + "confidence": "high" + }, + { + "record_sha": "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "subject": "perf(search): batch context queries — chunked session_id batches (20/sql)", + "current_bucket": "non-capability:performance-validation", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py: FTS/trigram subquery ORDER BY rank LIMIT", + "behavior_change": "The query shape forces ranked LIMIT/OFFSET evaluation inside the FTS subquery.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "subject": "perf(search): batch context queries — chunked session_id batches (20/sql)", + "current_bucket": "non-capability:performance-validation", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py: batched surrounding-context hydration", + "behavior_change": "Search context is hydrated in bounded session batches under one read lock, then indexed outside the lock before producing the same -1/0/+1 window.", + "proposed_capability": "capability:session-search-context-hydration", + "action": "PROMOTE_TO_SEPARATE_CAPABILITY", + "confidence": "high" + }, + { + "record_sha": "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "subject": "perf(search): benchmark cold-open + fallback-invariant self-check", + "current_bucket": "non-capability:performance-validation", + "behavior_bearing": false, + "hunk_or_scope": "scripts/benchmarks/session_metadata_picker.py", + "behavior_change": "Benchmark records cold-open latency and checks fallback invariants; production routing is not changed by this commit.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_VALIDATION", + "confidence": "high" + }, + { + "record_sha": "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0", + "subject": "fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries", + "current_bucket": "capability:session-fts-unicode", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-unicode.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-unicode" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "2ac803bd949f0aba96c0d4d500edd2ad65aa3036", + "subject": "feat(session-search): port sessions FTS5 title index (unicode61 + cjk_unicode61) from dev", + "current_bucket": "capability:session-fts-unicode", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, hermes_state_schema.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-unicode.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-unicode" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "9b25b0c8bd7408eaf2398529b6a04ed1a068b892", + "subject": "docs: research #32 session row_id unicode FTS", + "current_bucket": "capability:session-fts-unicode", + "behavior_bearing": true, + "hunk_or_scope": "docs/research/issue-32-stable-row-id-unicode-session-fts.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-unicode.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-unicode" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "e94f2630a50d7585f78cfc06365753c033113cb9", + "subject": "Session metadata FTS: stable row_id + resumable Unicode external-content index (#25) (#59)", + "current_bucket": "capability:session-fts-unicode", + "behavior_bearing": true, + "hunk_or_scope": "docs/design/session-metadata-fts.md, hermes_cli/session_recovery.py, hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, tests/test_session_metadata_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-unicode.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-unicode" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2", + "subject": "style(session-fts): drop duplicate @staticmethod (round-2 review)", + "current_bucket": "capability:session-fts-unicode", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-fts-unicode.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-fts-unicode" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e", + "subject": "fix(session-search): define ranked_candidates for LIKE route", + "current_bucket": "capability:session-search-routing", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-routing.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "0990803323497a36761c9627a20ceb57be56d5a3", + "subject": "test(state): pin session metadata route and fallback contract", + "current_bucket": "capability:session-search-routing", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_session_metadata_picker_routing.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-routing.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "5882274ff6c868c24f9d36f3796de08e5de8a245", + "subject": "refactor(state): add snapshot-aware metadata candidate router", + "current_bucket": "capability:session-search-routing", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-routing.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d", + "subject": "feat(api): route session metadata discovery through the common seam", + "current_bucket": "capability:session-search-routing", + "behavior_bearing": true, + "hunk_or_scope": "hermes_cli/web_routers/profiles.py, hermes_cli/web_routers/sessions.py, tests/hermes_cli/test_web_server.py, tests/hermes_cli/test_web_server_session_search.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-routing.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b4efc640fab0517571bd05447cf2be2ace9cf3e1", + "subject": "feat(desktop): search the whole session store in the resume picker", + "current_bucket": "capability:session-search-routing", + "behavior_bearing": true, + "hunk_or_scope": "apps/desktop/src/components/session-picker.test.tsx, apps/desktop/src/components/session-picker.tsx, apps/desktop/src/hermes.test.ts, apps/desktop/src/hermes.ts, apps/desktop/src/i18n/en.ts, apps/desktop/src/i18n/types.ts, apps/desktop/src/i18n/zh.ts", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-routing.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "b97d00e7319e5147d569519b6a34ef63c6635551", + "subject": "perf(search): benchmark routed session metadata candidates", + "current_bucket": "capability:session-search-routing", + "behavior_bearing": true, + "hunk_or_scope": "scripts/benchmarks/session_metadata_picker.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-routing.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "3ebb2592c141b232ecd0717adf32279afa6bee3f", + "subject": "test(api): cross-profile resume search + desktop stale-response ordering", + "current_bucket": "capability:session-search-routing", + "behavior_bearing": true, + "hunk_or_scope": "apps/desktop/src/components/session-picker.test.tsx, tests/hermes_cli/test_web_server.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-search-routing.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-search-routing" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log", + "current_bucket": "non-capability:incidental-hardening", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py: _execute_write retry delay", + "behavior_change": "SQLite write contention changes from uniform 20-150ms jitter to exponential backoff with a 20ms base and 2s cap.", + "proposed_capability": "capability:sqlite-write-contention-policy", + "action": "PROMOTE_TO_SEPARATE_CAPABILITY", + "confidence": "high" + }, + { + "record_sha": "cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log", + "current_bucket": "non-capability:incidental-hardening", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py / delivery logging", + "behavior_change": "Slow-write and Discord delivery diagnostics are added without changing the delivery contract.", + "covered_by_existing_contract": true, + "covered_by": [ + "non-capability:incidental-hardening" + ], + "action": "RETAIN_AS_EXPLICIT_DIAGNOSTICS", + "confidence": "medium" + }, + { + "record_sha": "9f3056cb3a9642c39056af8409cc3198007e68a8", + "subject": "ignore agents", + "current_bucket": "non-capability:incidental-hardening", + "behavior_bearing": false, + "hunk_or_scope": ".gitignore", + "behavior_change": "No runtime capability boundary established from the record alone; retained as explicit bookkeeping/evidence.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_BOOKKEEPING", + "confidence": "medium" + }, + { + "record_sha": "4270ea5b9a903d0dcf692db2365875ac5b3fe319", + "subject": "chore: ignore fts5_cjk Windows build artifact (.dll)", + "current_bucket": "non-capability:incidental-hardening", + "behavior_bearing": false, + "hunk_or_scope": ".gitignore", + "behavior_change": "No runtime capability boundary established from the record alone; retained as explicit bookkeeping/evidence.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_BOOKKEEPING", + "confidence": "medium" + }, + { + "record_sha": "cea5282a181d23af471f4467f449fd9bfc022ca5", + "subject": "docs(recovery): attest production gateway runtime surface", + "current_bucket": "non-capability:production-evidence", + "behavior_bearing": false, + "hunk_or_scope": "research/recovery/issue-41-production-gateway-runtime-attestation.md", + "behavior_change": "No runtime capability boundary established from the record alone; retained as explicit bookkeeping/evidence.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_BOOKKEEPING", + "confidence": "medium" + }, + { + "record_sha": "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba", + "subject": "docs(recovery): add production runtime repair runbook", + "current_bucket": "non-capability:production-evidence", + "behavior_bearing": false, + "hunk_or_scope": "research/recovery/issue-21-production-runtime-runbook.md", + "behavior_change": "No runtime capability boundary established from the record alone; retained as explicit bookkeeping/evidence.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_BOOKKEEPING", + "confidence": "medium" + }, + { + "record_sha": "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57", + "subject": "docs(research): record #22 production-ready state.db build and freeze", + "current_bucket": "non-capability:production-evidence", + "behavior_bearing": false, + "hunk_or_scope": "docs/research/issue-22-production-ready-state-db-execution.md", + "behavior_change": "No runtime capability boundary established from the record alone; retained as explicit bookkeeping/evidence.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_BOOKKEEPING", + "confidence": "medium" + }, + { + "record_sha": "8b085795df0359adbf3c81315f888bc7041fb044", + "subject": "docs(research): record #22 redo with SQLite 3.51.3 + CJK + fuzz", + "current_bucket": "non-capability:production-evidence", + "behavior_bearing": false, + "hunk_or_scope": "docs/research/issue-22-production-ready-state-db-execution.md", + "behavior_change": "No runtime capability boundary established from the record alone; retained as explicit bookkeeping/evidence.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_BOOKKEEPING", + "confidence": "medium" + }, + { + "record_sha": "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba", + "subject": "docs(research): correct #22 path/router evidence with executing-query validation", + "current_bucket": "non-capability:production-evidence", + "behavior_bearing": false, + "hunk_or_scope": "docs/research/issue-22-production-ready-state-db-execution.md", + "behavior_change": "No runtime capability boundary established from the record alone; retained as explicit bookkeeping/evidence.", + "covered_by_existing_contract": false, + "action": "EXPLICIT_NON_SEMANTIC_BOOKKEEPING", + "confidence": "medium" + }, + { + "record_sha": "d18dadb5f3b517ec69f14428dc78e7af1a86a30e", + "subject": "test(session): pin literal-safe numbered-title resolution (#15)", + "current_bucket": "capability:session-title-safety", + "behavior_bearing": true, + "hunk_or_scope": "tests/test_hermes_state.py, tests/test_session_metadata_cjk_fts.py, tests/test_session_metadata_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-title-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-title-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "faf96ef221ddfba2618abc8dae8368f7b82c1c2a", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)", + "current_bucket": "capability:session-title-safety", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-title-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-title-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "69bee0838ae15936ae4beb13cdf5d6907c19c707", + "subject": "docs: record #38 numbered-title research note and design contract (#15)", + "current_bucket": "capability:session-title-safety", + "behavior_bearing": true, + "hunk_or_scope": "docs/design/session-metadata-fts.md, docs/research/issue-38-numbered-title-literal-safety.md", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-title-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-title-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "17b0d2c9135d38728109592860677c4abbaddf4f", + "subject": "fix(session): unify #N grammar to ASCII digits; tidy escape_like placement (#15)", + "current_bucket": "capability:session-title-safety", + "behavior_bearing": true, + "hunk_or_scope": "hermes_state.py, hermes_state_common.py, tests/test_hermes_state.py, tests/test_session_metadata_fts.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:session-title-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:session-title-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + }, + { + "record_sha": "d53e209b3b620abce55f2cc57a80c69bc0cd9369", + "subject": "fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762)", + "current_bucket": "capability:cron-nul-safety", + "behavior_bearing": true, + "hunk_or_scope": "cron/lifecycle_guard.py, tools/terminal_tool.py", + "behavior_change": "Behavior is covered by the reviewed contract for capability:cron-nul-safety.", + "covered_by_existing_contract": true, + "covered_by": [ + "capability:cron-nul-safety" + ], + "action": "COVERED_BY_EXISTING_CONTRACT", + "confidence": "medium" + } + ], + "merge_events": [ + { + "record_sha": "276d497764feb7d4a71f1424ed44b8958da63b16", + "subject": "Merge pull request #78 from Skywind5487/feat/31-storage-v2-settlement", + "current_bucket": "capability:session-fts-storage-v2", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "9d140c8594c67ed37729b190fd3733508d0d770c", + "subject": "Merge pull request #76 from Skywind5487/feat/27-unified-fts-lifecycle", + "current_bucket": "capability:session-fts-lifecycle", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "516d739f64a95a4f380b899fbb9a349d750fc2aa", + "subject": "Merge branch 'feat/headroom-retrieval-toolset-autoenable' into dev", + "current_bucket": "capability:headroom-retrieval", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "bdf2fc218264538c4f3238b58532488fe665ff9e", + "subject": "Merge pull request #65 from Skywind5487/fts/session-cjk-highwater", + "current_bucket": "capability:session-fts-cjk", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "f18b3c90c2309ee7616010f99c1c927c9f05013f", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/session-trigram-external-content", + "current_bucket": "capability:session-fts-trigram", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "919f4469e832bc2b38bba0ea5af26b842bf91acd", + "subject": "feat(fts): normalized external-content session trigram metadata index (#30)", + "current_bucket": "capability:session-fts-trigram", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "4e5ad5c2230300d1ffae84b089ffc70e368c8a23", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)", + "current_bucket": "capability:session-fts-trigram", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "2f90c254d524d618b1c866a10bb519f2c1b6f5dc", + "subject": "Merge pull request #72 from Skywind5487/fix/68-compression-lineage-resolver", + "current_bucket": "capability:session-search-lineage", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "535b33c95f9465bb3e05b281b17fceee3ba24d22", + "subject": "Merge PR #2: escape reasoning fences (resolve conflict)", + "current_bucket": "capability:outbound-code-fence-safety", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71", + "subject": "Merge branch 'fix/truncation-fence-edge-case' into dev", + "current_bucket": "capability:outbound-code-fence-safety", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "dc2270aad84242da42f4342ac137e243ca181aa5", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "current_bucket": "capability:session-fts-simple-eol", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "433a49f66b447f41fdd488dc4858a07c7cd7154d", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "current_bucket": "capability:session-fts-simple-eol", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "53da9e89f8f3d2b051bf4c719b9f09b355392c00", + "subject": "Merge pull request #87 from Skywind5487/feat/19-simple-tokenizer-eol", + "current_bucket": "capability:session-fts-simple-eol", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "9fe97e2aa1b05306ed626e5ae3db540d24bb4678", + "subject": "Merge PR #3: configurable reasoning max lines", + "current_bucket": "capability:configurable-reasoning-display", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "b7e62647bd657a429d967cfa77034632ee490f9a", + "subject": "feat(headroom): merge ContentRouter + warning E2E tests into dev", + "current_bucket": "capability:headroom-compression", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "subject": "Merge remote-tracking branch 'origin/main' into dev", + "current_bucket": "non-capability:integration-merge", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "1602d06f5045d173ee31161b92e387de69ab821c", + "subject": "merge(session-search): ranked Top-N + late-snippet into dev", + "current_bucket": "non-capability:integration-merge", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "b66c149de0c8240e84ded1a2f983b8c42f7b984b", + "subject": "merge(main): absorb upstream main 91937a6dc into dev — keep session-search fix chain", + "current_bucket": "non-capability:integration-merge", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "637ef2e193b6b2dada5d0b79173461fca03fbf20", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/routed-session-metadata-candidates", + "current_bucket": "non-capability:integration-merge", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "9e3439835e9dbbad0d0076d539d769db1f84de0a", + "subject": "Merge remote-tracking branch 'origin/main' into fix/browser-timeout-daemon-kill-toggle", + "current_bucket": "capability:browser-timeout-cleanup", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f", + "subject": "Merge branch 'fix/browser-timeout-daemon-kill-toggle' into dev", + "current_bucket": "capability:browser-timeout-cleanup", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "a34da2c31ca60f9b5280558c514a3a1880035036", + "subject": "Merge branch 'fix/session-search-perf' of /home/skywind5487/hermes_worktrees/fix/session-search-perf into dev", + "current_bucket": "non-capability:performance-validation", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "subject": "feat(session): route session-metadata picker candidates through FTS (#14)", + "current_bucket": "capability:session-search-routing", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "bee13fc085079d78d0334722ad4c37a1144e3102", + "subject": "Merge pull request #82 from Skywind5487/feat/22-production-ready-state-db-execution", + "current_bucket": "non-capability:production-evidence", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "984eff15df1fb749f00aece7fc24c43e9afcb7e8", + "subject": "Merge remote-tracking branch 'origin/dev' into fix/15-numbered-title-literal-safety", + "current_bucket": "capability:session-title-safety", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + }, + { + "record_sha": "dcf8096413c7ee40fe0ab512ac86927fb2092df1", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)", + "current_bucket": "capability:session-title-safety", + "classification": "PROVENANCE_ONLY", + "explanation": "Merge provenance is accounted by the inventory; no new capability is inferred from merge metadata alone." + } + ] +} diff --git a/artifacts/fork-archaeology-issue-100/behavioral-coverage-audit.md b/artifacts/fork-archaeology-issue-100/behavioral-coverage-audit.md new file mode 100644 index 000000000000..1a5ffcd4aa8f --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/behavioral-coverage-audit.md @@ -0,0 +1,28 @@ +# Adversarial behavioral coverage audit + +This audit reviews historical changes at hunk/intent level. A commit title or provisional provenance bucket is not treated as a capability boundary. + +- Change records reviewed: **145** +- Merge events accounted: **26** +- Behavior-bearing rows: **141** +- Promoted separate-intent rows: **5** +- Explicit non-semantic/bookkeeping rows: **8** +- Uncovered behavior rows: **0** +- Completeness gate: **PASS** + +## False-negative corrections + +| Record | Existing bucket | Behavioral intent | Coverage/action | Proposed capability | +|---|---|---|---|---| +| `04f1af72be07` | `capability:memory-trim-diagnostics` | RSS below threshold_mb skips the expensive trim work. | `PROMOTE_TO_SEPARATE_CAPABILITY` | `capability:memory-trim-policy` | +| `04f1af72be07` | `capability:memory-trim-diagnostics` | Trim diagnostics attribute GC cost, allocator fragmentation, and swap pressure. | `COVERED_BY_SPLIT_CAPABILITY` | `` | +| `176646d2cd6c` | `capability:lifecycle-sqlite-telemetry` | A compressor-reported noop does not rotate or rewrite the session, even when it returns a new list object. | `PROMOTE_TO_SEPARATE_CAPABILITY` | `capability:compression-session-boundary` | +| `176646d2cd6c` | `capability:lifecycle-sqlite-telemetry` | Structured lifecycle and SQLite telemetry is emitted at execution boundaries. | `COVERED_BY_EXISTING_CONTRACT` | `` | +| `a9d2b9af4f80` | `capability:memory-trim-policy` | gc.collect() is independently cooled down while malloc_trim remains on the trim cadence. | `PROMOTE_TO_SEPARATE_CAPABILITY` | `capability:memory-trim-policy` | +| `b879cbd332b8` | `non-capability:performance-validation` | The query shape forces ranked LIMIT/OFFSET evaluation inside the FTS subquery. | `COVERED_BY_EXISTING_CONTRACT` | `` | +| `b879cbd332b8` | `non-capability:performance-validation` | Search context is hydrated in bounded session batches under one read lock, then indexed outside the lock before producing the same -1/0/+1 window. | `PROMOTE_TO_SEPARATE_CAPABILITY` | `capability:session-search-context-hydration` | +| `7b66bbf8e2af` | `non-capability:performance-validation` | Benchmark records cold-open latency and checks fallback invariants; production routing is not changed by this commit. | `EXPLICIT_NON_SEMANTIC_VALIDATION` | `` | +| `cc2531fbc6df` | `non-capability:incidental-hardening` | SQLite write contention changes from uniform 20-150ms jitter to exponential backoff with a 20ms base and 2s cap. | `PROMOTE_TO_SEPARATE_CAPABILITY` | `capability:sqlite-write-contention-policy` | +| `cc2531fbc6df` | `non-capability:incidental-hardening` | Slow-write and Discord delivery diagnostics are added without changing the delivery contract. | `RETAIN_AS_EXPLICIT_DIAGNOSTICS` | `` | + +The full exhaustive per-record and per-merge-event accounting is in `behavioral-coverage-audit.json`. The existing archaeology runner remains commit-to-bucket accounting; this artifact is the many-to-many semantic overlay. diff --git a/artifacts/fork-archaeology-issue-100/capability-manifest.json b/artifacts/fork-archaeology-issue-100/capability-manifest.json new file mode 100644 index 000000000000..97c537d8f0ce --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/capability-manifest.json @@ -0,0 +1,1718 @@ +{ + "schema_version": 1, + "phase": "Phase 1 reviewed capability manifest", + "inputs": { + "fork_ref": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "upstream_ref": "460d345642ee3d143a3e461abe39fd42b86a7e54", + "merge_base": "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53" + }, + "method": { + "grouping_axes": [ + "historical intent/behavior", + "merge provenance", + "current fork survival", + "frozen upstream/prior art" + ], + "rule": "A capability is a behavior boundary with a contract and verification surface; provisional provenance buckets are evidence containers only. Runtime policy and diagnostics are split when a historical change both changes behavior and measures it. The adversarial coverage audit reviews every change record at hunk/intent level; a commit may have multiple semantic rows.", + "non_capability_rule": "Research, operations, benchmarks, integration topology, and isolated maintenance are accounted explicitly without promotion to capabilities." + }, + "accounting": { + "historical_change_records": 145, + "merge_events": 26, + "total_records": 171, + "mapped_records": 171, + "complete": true + }, + "groups": [ + { + "id": "capability:browser-timeout-cleanup", + "record_class": "capability", + "capability": "Browser timeout cleanup policy", + "intent_name": "Make browser daemon termination on timeout configuration-gated and crash-resilient while retaining finally-path cleanup.", + "historical_commits": [ + { + "sha": "a2450695db0e99f3dd8362f129024cb74c700bb8", + "subject": "fix(browser): config-gated daemon kill on timeout" + }, + { + "sha": "b42bc25e622c11230998cc57f7050ec2a2cdd090", + "subject": "fix(browser): add tests and crash-resilience for daemon-kill on timeout" + }, + { + "sha": "cfb2636a6a3ed02ff773f106beb71c88576f1284", + "subject": "fix(browser): move dict cleanup to finally block on timeout (P1 fix)" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [ + { + "sha": "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f", + "subject": "Merge branch 'fix/browser-timeout-daemon-kill-toggle' into dev" + }, + { + "sha": "9e3439835e9dbbad0d0076d539d769db1f84de0a", + "subject": "Merge remote-tracking branch 'origin/main' into fix/browser-timeout-daemon-kill-toggle" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Timeout cleanup clears in-memory browser state in a finally-equivalent path.", + "Daemon termination is opt-in/config-gated.", + "Cleanup failures are contained and test-covered." + ], + "current_dev_survival": "Survives in tools/browser_tool.py and timeout cleanup/daemon tests.", + "upstream_prior_art_current_implementation": "Frozen upstream has timeout cleanup/orphan reaping but not terminate_daemon_on_timeout configuration behavior.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Check whether upstream orphan reaping supersedes this toggle." + ], + "source_inventory_records": [ + "commit:8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f", + "commit:9e3439835e9dbbad0d0076d539d769db1f84de0a", + "commit:a2450695db0e99f3dd8362f129024cb74c700bb8", + "commit:b42bc25e622c11230998cc57f7050ec2a2cdd090", + "commit:cfb2636a6a3ed02ff773f106beb71c88576f1284" + ], + "change_record_count": 3, + "merge_event_count": 2 + }, + { + "id": "capability:compression-session-boundary", + "record_class": "capability", + "capability": "Compression session-boundary semantics", + "intent_name": "Prevent compressor-reported no-op results from creating a false session boundary.", + "historical_commits": [], + "supporting_historical_commits": [ + { + "sha": "176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "subject": "feat: add lifecycle and SQLite observability telemetry", + "role": "behavioral overlay; same commit also contains telemetry" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "The commit is retained in the lifecycle telemetry provenance bucket for runner accounting; the hunk-level audit promotes this independent behavior intent.", + "behavioral_contracts": [ + "A context compressor reporting noop does not rotate or rewrite the session, even if it returns a newly allocated list.", + "The current system prompt and session lock are released safely on the no-op path." + ], + "current_dev_survival": "Survives in agent/conversation_compression.py and its compression lifecycle tests.", + "upstream_prior_art_current_implementation": "Frozen upstream has a semantic no-progress guard for equal compressor output, but the explicit status-reported-noop case is a separate residual contract.", + "status": "PARTIAL_UPSTREAM", + "disposition": "SPLIT", + "confidence": "high", + "unresolved_questions": [ + "Confirm the canonical status field for third-party context compressors before porting." + ], + "source_inventory_records": [ + "behavior-overlay:commit:176646d2cd6c95fa49b9414f21ed9e781b0aaa84" + ], + "change_record_count": 0, + "merge_event_count": 0 + }, + { + "id": "capability:configurable-reasoning-display", + "record_class": "capability", + "capability": "Configurable reasoning display limit", + "intent_name": "Replace a hardcoded reasoning display limit with explicit configuration while retaining safe truncation.", + "historical_commits": [ + { + "sha": "895ba96014ecf934dbc140306ffe578a0a533ea3", + "subject": "feat: configurable reasoning max lines via display.reasoning_max_lines" + } + ], + "historical_issues": [], + "historical_prs": [ + "PR #3" + ], + "merge_provenance": [ + { + "sha": "9fe97e2aa1b05306ed626e5ae3db540d24bb4678", + "subject": "Merge PR #3: configurable reasoning max lines" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "reasoning_max_lines controls display truncation.", + "Invalid or absent configuration falls back safely.", + "Fence escaping remains applied before wrapping." + ], + "current_dev_survival": "Survives in cli.py/config parsing and gateway display code.", + "upstream_prior_art_current_implementation": "Frozen upstream hardcodes the first 15 lines and has no reasoning_max_lines seam.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Confirm configuration source and documentation expected upstream." + ], + "source_inventory_records": [ + "commit:895ba96014ecf934dbc140306ffe578a0a533ea3", + "pr:3" + ], + "change_record_count": 1, + "merge_event_count": 1 + }, + { + "id": "capability:cron-nul-safety", + "record_class": "capability", + "capability": "NUL-safe cron lifecycle and terminal fallback", + "intent_name": "Safely reject NUL-bearing paths before lifecycle/terminal process APIs can misinterpret them.", + "historical_commits": [ + { + "sha": "d53e209b3b620abce55f2cc57a80c69bc0cd9369", + "subject": "fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762)" + } + ], + "historical_issues": [ + "PR #76762" + ], + "historical_prs": [ + "PR #76762" + ], + "merge_provenance": [], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "NUL-bearing input does not reach unsafe process/lifecycle calls.", + "Terminal fallback returns a clear failure rather than truncating at NUL." + ], + "current_dev_survival": "Survives in cron/lifecycle_guard.py and tools/terminal_tool.py.", + "upstream_prior_art_current_implementation": "Frozen upstream contains the corresponding NUL/binary-safe guard and terminal fallback.", + "status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "unresolved_questions": [ + "Confirm upstream release and canonical tests." + ], + "source_inventory_records": [ + "pr:76762" + ], + "change_record_count": 1, + "merge_event_count": 0 + }, + { + "id": "capability:headroom-compression", + "record_class": "capability", + "capability": "Headroom output compression", + "intent_name": "Compress oversized tool/context payloads with bounded output, metadata-safe behavior, and explicit warning semantics.", + "historical_commits": [ + { + "sha": "237176ed1d973910972984ba83d876d01c00f3db", + "subject": "fix(headroom): prevent metadata from expanding tool results" + }, + { + "sha": "5eb552458de9828f4496880fd878f58015a63389", + "subject": "feat(headroom): add ContentRouter + SmartCrusher integration behind config flag" + }, + { + "sha": "915913db360de5fe5b147d4895276ff39a6e8686", + "subject": "Add opt-in headroom tool-output compression plugin" + }, + { + "sha": "c16ebe6b8649c570b688fd82d6b66f9a8416d59c", + "subject": "fix(headroom): logger.warning for ContentRouter/CacheAligner failures + warning E2E tests" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [ + { + "sha": "b7e62647bd657a429d967cfa77034632ee490f9a", + "subject": "feat(headroom): merge ContentRouter + warning E2E tests into dev" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Compression activates only at configured thresholds and does not expand tool-result metadata.", + "Failures degrade with warning/logging and preserve usable content.", + "Plugin registration and schema remain valid when active." + ], + "current_dev_survival": "Survives in plugins/headroom, tools_config.py, plugin.yaml, pyproject.toml/uv.lock and plugin tests.", + "upstream_prior_art_current_implementation": "Frozen upstream has no headroom ContentRouter/SmartCrusher implementation.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Identify upstream context-management owner before porting.", + "Keep output compression separate from retrieval." + ], + "source_inventory_records": [ + "commit:237176ed1d973910972984ba83d876d01c00f3db", + "commit:5eb552458de9828f4496880fd878f58015a63389", + "commit:915913db360de5fe5b147d4895276ff39a6e8686", + "commit:b7e62647bd657a429d967cfa77034632ee490f9a", + "commit:c16ebe6b8649c570b688fd82d6b66f9a8416d59c" + ], + "change_record_count": 4, + "merge_event_count": 1 + }, + { + "id": "capability:headroom-retrieval", + "record_class": "capability", + "capability": "Headroom retrieval (CCR)", + "intent_name": "Expose bounded retrieval of compressed context through a registered tool when compression is active.", + "historical_commits": [ + { + "sha": "0a4b567ff08776a3a10ee7a32d37332d873f20b2", + "subject": "feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin" + }, + { + "sha": "0b4e7601227a23bc653d0d3018a3a9591d02f2a1", + "subject": "fix: headroom_retrieve tool schema — add description and parameters wrapper" + }, + { + "sha": "b527e4df996b859356c0c48c2b9c9eae4c74c4dc", + "subject": "fix(headroom): auto-enable headroom_retrieve tool when compression is active" + }, + { + "sha": "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6", + "subject": "fix(headroom): add missing toolset param to register_tool call" + }, + { + "sha": "ff4df5b71e1557660dbe994eb5569983f57c9901", + "subject": "fix(headroom): add missing toolset param to register_tool call" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [ + { + "sha": "516d739f64a95a4f380b899fbb9a349d750fc2aa", + "subject": "Merge branch 'feat/headroom-retrieval-toolset-autoenable' into dev" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "The retrieval tool has a stable schema.", + "It is auto-enabled only when compression is active and returns bounded context.", + "Registration failures are explicit and warning-visible." + ], + "current_dev_survival": "Survives in plugins/headroom, tools_config.py, plugin.yaml and plugin tests.", + "upstream_prior_art_current_implementation": "No equivalent retrieval tool is present in frozen upstream.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Decide whether retrieval is a generic upstream context API or plugin-owned." + ], + "source_inventory_records": [ + "commit:0a4b567ff08776a3a10ee7a32d37332d873f20b2", + "commit:0b4e7601227a23bc653d0d3018a3a9591d02f2a1", + "commit:516d739f64a95a4f380b899fbb9a349d750fc2aa", + "commit:b527e4df996b859356c0c48c2b9c9eae4c74c4dc", + "commit:d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6", + "commit:ff4df5b71e1557660dbe994eb5569983f57c9901" + ], + "change_record_count": 5, + "merge_event_count": 1 + }, + { + "id": "capability:lifecycle-sqlite-telemetry", + "record_class": "capability", + "capability": "Lifecycle and SQLite observability telemetry", + "intent_name": "Expose structured lifecycle, tool, stream, SQLite, and delivery telemetry at important execution boundaries.", + "historical_commits": [ + { + "sha": "176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "subject": "feat: add lifecycle and SQLite observability telemetry" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Important boundaries emit structured telemetry rather than only ad-hoc logs.", + "SQLite lock/owner and stream/tool failures remain diagnosable." + ], + "current_dev_survival": "Survives across lifecycle_telemetry.py, sqlite_native_telemetry.py, turn_context.py, gateway code and tests.", + "upstream_prior_art_current_implementation": "Frozen upstream comparison was not completed per telemetry surface; absence is not treated as proof.", + "status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "medium", + "unresolved_questions": [ + "Separate domain facts from diagnostics.", + "Which event names/sinks are stable enough to port?" + ], + "source_inventory_records": [ + "commit:176646d2cd6c95fa49b9414f21ed9e781b0aaa84" + ], + "change_record_count": 1, + "merge_event_count": 0, + "behavioral_overlays": [ + "capability:compression-session-boundary" + ] + }, + { + "id": "capability:memory-trim-diagnostics", + "record_class": "capability", + "capability": "Memory trim diagnostics", + "intent_name": "Attribute trim cost and memory pressure without making diagnostics a prerequisite for recovery.", + "historical_commits": [ + { + "sha": "04f1af72be078cef69de538f1519f93a73088b0d", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "04f1 is explicitly owned here for its instrumentation; its policy threshold is cited as supporting evidence by the policy capability.", + "behavioral_contracts": [ + "gc_ms versus trim_ms identifies the freeze mechanism without changing the policy decision.", + "Fragmentation and VmSwap are best-effort diagnostics and never block memory recovery." + ], + "current_dev_survival": "Survives in hermes_cli/mem_trim.py through gc_ms/trim_ms, malloc_info fragmentation, VmSwap snapshots, and structured trim logs.", + "upstream_prior_art_current_implementation": "Frozen upstream has basic RSS/RssAnon snapshots and trim logging, but not the fork's GC-versus-trim attribution, malloc_info fragmentation, or VmSwap diagnostics.", + "status": "PARTIAL_UPSTREAM", + "disposition": "KEEP", + "confidence": "medium", + "unresolved_questions": [ + "Which diagnostic fields are stable enough to expose as a long-term contract?", + "Should malloc_info remain best-effort Linux/glibc-only instrumentation?" + ], + "source_inventory_records": [ + "commit:04f1af72be078cef69de538f1519f93a73088b0d" + ], + "change_record_count": 1, + "merge_event_count": 0 + }, + { + "id": "capability:memory-trim-policy", + "record_class": "capability", + "capability": "Memory trim policy", + "intent_name": "Avoid expensive and low-value heap work while preserving cheap malloc_trim cadence.", + "historical_commits": [ + { + "sha": "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb", + "subject": "fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim" + } + ], + "supporting_historical_commits": [ + { + "sha": "04f1af72be078cef69de538f1519f93a73088b0d", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold", + "role": "policy precursor" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "The policy was introduced by the two sequential mem-trim commits; 04f1 is mapped to diagnostics for explicit accounting and retained here as a supporting precursor.", + "behavioral_contracts": [ + "RSS below threshold_mb skips the expensive trim work on housekeeping ticks.", + "gc.collect() runs at most once per gc_cooldown_seconds while malloc_trim remains eligible on the normal trim cadence.", + "The 99.7% GC attribution explains the policy split; force behavior and invalid configuration retain safe fallbacks." + ], + "current_dev_survival": "Survives in hermes_cli/mem_trim.py with threshold_mb, gc_cooldown_seconds, separate _last_gc_monotonic state, and independent malloc_trim cadence.", + "upstream_prior_art_current_implementation": "Frozen upstream hermes_cli/mem_trim.py has a general cooldown around gc.collect()+malloc_trim, but no RSS low-water gate or independent GC cooldown; this is partial prior art, not equivalence.", + "status": "PARTIAL_UPSTREAM", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Which upstream housekeeping callers should own the cheap trim cadence after porting?", + "Should threshold_mb and gc_cooldown_seconds share the upstream config naming/default policy?" + ], + "source_inventory_records": [ + "commit:a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb" + ], + "change_record_count": 1, + "merge_event_count": 0 + }, + { + "id": "capability:outbound-code-fence-safety", + "record_class": "capability", + "capability": "Outbound code-fence and truncation safety", + "intent_name": "Preserve balanced code fences and inline-code spans when reasoning, streaming chunks, or Discord edits are escaped or truncated.", + "historical_commits": [ + { + "sha": "347442ddc80a2658582cb62dd268a0be024b1bcf", + "subject": "fix: escape triple-backtick in reasoning before wrapping in outer code block" + }, + { + "sha": "44afcc8d3f869c7780beb1bc0bece86df1e45cb2", + "subject": "test: code fence tracking coverage for all send/split paths" + }, + { + "sha": "47cc1764dc2c2c65cc83fe20500da939698d72d3", + "subject": "fix: close orphaned code fences on all send paths" + }, + { + "sha": "c1a3e16c32896ea2d469536c657814049c29bec6", + "subject": "fix: also close orphaned single-backtick inline-code spans" + }, + { + "sha": "efd68fe044001c57c5d148a66469209589c344d9", + "subject": "fix: ensure balanced code fences after Discord edit_message brute-force truncation" + } + ], + "historical_issues": [], + "historical_prs": [ + "PR #2" + ], + "merge_provenance": [ + { + "sha": "535b33c95f9465bb3e05b281b17fceee3ba24d22", + "subject": "Merge PR #2: escape reasoning fences (resolve conflict)" + }, + { + "sha": "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71", + "subject": "Merge branch 'fix/truncation-fence-edge-case' into dev" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Untrusted backticks are escaped before outer wrapping.", + "Chunk balancing and truncation close open triple-backtick and inline-code spans.", + "Discord edit/truncation preserves the same user-visible balance guarantee." + ], + "current_dev_survival": "Survives in gateway/stream_consumer.py and Discord adapter/tests.", + "upstream_prior_art_current_implementation": "Frozen upstream already has escape_code_fences_for_display, ensure_closed_code_fences, and chunk balancing with equivalent behavior.", + "status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "unresolved_questions": [ + "Run upstream Discord edit-truncation tests before deleting fork provenance." + ], + "source_inventory_records": [ + "commit:347442ddc80a2658582cb62dd268a0be024b1bcf", + "commit:44afcc8d3f869c7780beb1bc0bece86df1e45cb2", + "commit:47cc1764dc2c2c65cc83fe20500da939698d72d3", + "pr:2", + "commit:c1a3e16c32896ea2d469536c657814049c29bec6", + "commit:eed6ba2734bc7aaabbd1e8cf08cd794badc72d71", + "commit:efd68fe044001c57c5d148a66469209589c344d9" + ], + "change_record_count": 5, + "merge_event_count": 2 + }, + { + "id": "capability:request-transform-hook", + "record_class": "capability", + "capability": "Full-payload outbound request transform hook", + "intent_name": "Allow plugins to transform the complete outbound API request before dispatch.", + "historical_commits": [ + { + "sha": "296d9c6e2e5a6f852344ad8fa9b90f5687912be1", + "subject": "feat: add transform_api_request plugin hook for full-payload request transformation" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "transform_api_request receives and returns the complete payload at a documented boundary.", + "The hook is optional and preserves the request when absent.", + "Hook errors are explicit and do not dispatch partial data." + ], + "current_dev_survival": "Survives in agent/conversation_loop.py, hermes_cli/hooks.py, hermes_cli/plugins.py and run-agent tests.", + "upstream_prior_art_current_implementation": "Frozen upstream has pre_llm_call but not a full-payload transform hook at dispatch.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Define ordering relative to pre_llm_call and provider adapters." + ], + "source_inventory_records": [ + "commit:296d9c6e2e5a6f852344ad8fa9b90f5687912be1" + ], + "change_record_count": 1, + "merge_event_count": 0 + }, + { + "id": "capability:session-fts-cjk", + "record_class": "capability", + "capability": "CJK session metadata search", + "intent_name": "Add an optional, independently maintained CJK session metadata index with safe degradation and snapshot-consistent serving.", + "historical_commits": [ + { + "sha": "0eee69ef43f16c63f29db414e1acb40253212125", + "subject": "fix(session-fts): run CJK guard+MATCH in one SQLite snapshot (PR #65 P1)" + }, + { + "sha": "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "subject": "fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search" + }, + { + "sha": "3053abf3b039a5b4c23637597cb076f2339250fb", + "subject": "fix: let all CJK queries use simple tokenizer; cache lineage resolves" + }, + { + "sha": "3e23375f7934e4315d45860e6992171fb5609c5c", + "subject": "test(session-fts): RED contract for CJK session metadata lifecycle (#26)" + }, + { + "sha": "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7", + "subject": "feat(session-fts): external-content CJK metadata DDL + capability/quarantine (#26)" + }, + { + "sha": "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5", + "subject": "feat(session-fts): plug CJK session rebuild into the generic engine (#26)" + }, + { + "sha": "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128", + "subject": "feat(session-fts): CJK metadata candidate seam + all-3-field search (#26)" + }, + { + "sha": "6311e77e27f4fd4009c73d0df16abebf56121f4a", + "subject": "docs(research): map CJK session metadata FTS lifecycle for #33" + }, + { + "sha": "6447a52cd994bf30c2811814f21095d12aba83ae", + "subject": "fix(state): short-circuit CJK-unservable to direct LIKE + single compression edge" + }, + { + "sha": "6b3402ea05566fa1553a93aceb285eb517d7e67d", + "subject": "fix(session-fts): three lifecycle/capability seams for CJK session FTS (round-3 review)" + }, + { + "sha": "83431f775a9e3798611e03b16a2f7d9a7ac74a57", + "subject": "docs(design): document the #26 CJK session metadata FTS variant" + }, + { + "sha": "8efead2600a3f932f9881b53cd0c7eabc755f82f", + "subject": "fix(session-fts): address #26 code-review findings" + } + ], + "historical_issues": [ + "PR #65", + "issue #26" + ], + "historical_prs": [ + "PR #26", + "PR #65", + "issue #26" + ], + "merge_provenance": [ + { + "sha": "bdf2fc218264538c4f3238b58532488fe665ff9e", + "subject": "Merge pull request #65 from Skywind5487/fts/session-cjk-highwater" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "CJK search covers title, id, and display_name through external-content FTS.", + "Unavailable tokenizer/index state degrades safely without hiding the base path.", + "Guard and MATCH run against one SQLite snapshot; rebuild is independent and resumable." + ], + "current_dev_survival": "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_cjk_fts.py.", + "upstream_prior_art_current_implementation": "Frozen upstream has no session CJK metadata index or equivalent optional lifecycle.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "What tokenizer availability contract is acceptable upstream?", + "Should CJK remain a separate optional port?" + ], + "source_inventory_records": [ + "pr:65", + "commit:15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "commit:3053abf3b039a5b4c23637597cb076f2339250fb", + "pr:26", + "commit:6311e77e27f4fd4009c73d0df16abebf56121f4a", + "commit:6447a52cd994bf30c2811814f21095d12aba83ae", + "commit:6b3402ea05566fa1553a93aceb285eb517d7e67d", + "commit:83431f775a9e3798611e03b16a2f7d9a7ac74a57", + "commit:8efead2600a3f932f9881b53cd0c7eabc755f82f" + ], + "change_record_count": 12, + "merge_event_count": 1 + }, + { + "id": "capability:session-fts-lifecycle", + "record_class": "capability", + "capability": "Unified six-index FTS lifecycle", + "intent_name": "Give all session and message FTS indexes one descriptor-driven maintenance, health, repair, discovery, and degraded-runtime boundary.", + "historical_commits": [ + { + "sha": "00e680a8cb22e251f351b9f140b0679c4f96dabc", + "subject": "feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27)" + }, + { + "sha": "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1", + "subject": "feat(fts): registry-driven health probes + trigger inventory/convergence (#27)" + }, + { + "sha": "474b88fe76e18dfcf397f11b3de6f069abac4a4c", + "subject": "fix(fts): registry-driven offline + destructive repair covers session indexes (#27)" + }, + { + "sha": "f9ade6baff7f236b6b9401932c61bc0400375664", + "subject": "feat(fts): read-only session capability discovery + shared rebuild-lane iteration (#27)" + }, + { + "sha": "e64ad007b459871af42e312bc5dffd2da92ac900", + "subject": "test(fts): six-index regression matrix for maintenance/repair/read-only/degraded-runtime (#27)" + }, + { + "sha": "0400c66f072d0f319331ea105cd8f7e059975388", + "subject": "refactor(fts): apply review round — drop dead lane keys, merge trigger-drop + CJK quarantine helpers, remove dead _FTS_TRIGGERS (#27)" + }, + { + "sha": "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec", + "subject": "fix(fts): reuse #30 ownership classifier in offline/global paths + read-only CJK worker fix (#27)" + }, + { + "sha": "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a", + "subject": "fix(fts): read-only trigram discovery gates on full #30 namespace ownership (#27)" + }, + { + "sha": "3bc7d3f58f808e269675404c9bbeada467b00e98", + "subject": "refactor(fts): ponytail pass — drop redundant tests, shrink review history + comments (#27)" + }, + { + "sha": "d6a4d70483623cc3fad4eea8c96754d7d637d02c", + "subject": "fix(fts): read-only trigram serving requires a complete trigger set (#27)" + }, + { + "sha": "0cf4cd0baffb68b571a44f2a39d3bf817cd38348", + "subject": "docs(fts): record review round 4 for #27 unified FTS lifecycle" + }, + { + "sha": "75223d19544ceb73cf24fb859fc0780ed9a099a5", + "subject": "docs(fts): record review round 1 for #27" + }, + { + "sha": "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d", + "subject": "docs(fts): record review round 3 for #27 unified FTS lifecycle" + }, + { + "sha": "bdd9d699f6dc13b32852a078c1ecf5664bcb837d", + "subject": "docs(fts): record six-index unified lifecycle implementation for #27" + }, + { + "sha": "dc1f153a71d025d903f255861da57f94d649ca37", + "subject": "docs(fts): record review round 2 for #27 unified FTS lifecycle" + } + ], + "historical_issues": [ + "PR #76", + "issue #27" + ], + "historical_prs": [ + "PR #27", + "PR #76", + "issue #27" + ], + "merge_provenance": [ + { + "sha": "9d140c8594c67ed37729b190fd3733508d0d770c", + "subject": "Merge pull request #76 from Skywind5487/feat/27-unified-fts-lifecycle" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "The registry covers messages_fts, messages_fts_trigram, messages_fts_cjk, sessions_fts, sessions_fts_cjk, and sessions_fts_trigram.", + "Maintenance, health, read-only discovery, repair, and degraded runtime iterate the same descriptors.", + "Unknown or incomplete trigger state fails closed for serving." + ], + "current_dev_survival": "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_lifecycle_registry.py.", + "upstream_prior_art_current_implementation": "Frozen upstream has message FTS primitives but no equivalent session six-index lifecycle boundary.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Which lifecycle pieces are required by upstream?", + "How should #31 remain an explicit dependency?" + ], + "source_inventory_records": [ + "pr:27", + "commit:0cf4cd0baffb68b571a44f2a39d3bf817cd38348", + "commit:75223d19544ceb73cf24fb859fc0780ed9a099a5", + "pr:76", + "commit:a822d37d18064d1442eb20b6a2cb4e9f8b17d48d", + "commit:bdd9d699f6dc13b32852a078c1ecf5664bcb837d", + "commit:dc1f153a71d025d903f255861da57f94d649ca37" + ], + "change_record_count": 15, + "merge_event_count": 1 + }, + { + "id": "capability:session-fts-simple-eol", + "record_class": "capability", + "capability": "Legacy simple-tokenizer retirement", + "intent_name": "Remove the unsupported legacy simple-tokenizer compatibility debt and make unsupported database states fail explicitly.", + "historical_commits": [ + { + "sha": "196b904417371cf233f3eb9b560c80a079ab8d72", + "subject": "docs(research): map simple-tokenizer EOL for #40" + }, + { + "sha": "44dd4c5e586e60c22a322a9eb89d1aed63892e36", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs" + }, + { + "sha": "85fd91fd7c7be20d63356f27654d399ca1da4fa0", + "subject": "test(fts): pin simple-tokenizer EOL policy (#19)" + }, + { + "sha": "186986a447080ae74a1d17fd1e32aaf039cb2ff2", + "subject": "fix(fts): retire simple-tokenizer residue; drop global shim (#19)" + }, + { + "sha": "deb10243ccebd6153cdfab8e9869faba2e105f0e", + "subject": "docs(fts): close simple compatibility contract (#19)" + }, + { + "sha": "1d5b80cab802e6ae932c97342e328e76faa496fa", + "subject": "fix(fts): harden simple EOL sanitation per review (#19)" + }, + { + "sha": "a1136e548ea1f2200429bf44f8f1a7297cc84246", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs" + }, + { + "sha": "a4e2c52f1582952686ee56aaedd7285874326102", + "subject": "fix: address Copilot review — init hermes_home, load simple in ro path, v21 migration" + }, + { + "sha": "c20cb64b4b79468c641626e9b9d3957790f7a671", + "subject": "fix: address Copilot review — init hermes_home, load simple in ro path, v21 migration" + }, + { + "sha": "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a", + "subject": "fix(state): load simple tokenizer so legacy trigram tables stay writable" + } + ], + "historical_issues": [ + "PR #87", + "issue #19" + ], + "historical_prs": [ + "PR #19", + "PR #87", + "issue #19" + ], + "merge_provenance": [ + { + "sha": "433a49f66b447f41fdd488dc4858a07c7cd7154d", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev" + }, + { + "sha": "53da9e89f8f3d2b051bf4c719b9f09b355392c00", + "subject": "Merge pull request #87 from Skywind5487/feat/19-simple-tokenizer-eol" + }, + { + "sha": "dc2270aad84242da42f4342ac137e243ca181aa5", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Supported post-#12 databases do not require simple-tokenizer loading or repair branches.", + "Unsupported legacy residue is sanitized or rejected explicitly rather than silently kept writable.", + "Modern trigram/CJK lifecycle remains the canonical path." + ], + "current_dev_survival": "Survives in hermes_state.py sanitizer/repair logic and the #19/#87 research and tests.", + "upstream_prior_art_current_implementation": "Frozen upstream has no load_simple_extension/simple-tokenizer compatibility shim; the legacy debt is already absent there.", + "status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "unresolved_questions": [ + "Prove the release ancestry of upstream database states before closing the port question." + ], + "source_inventory_records": [ + "commit:196b904417371cf233f3eb9b560c80a079ab8d72", + "commit:433a49f66b447f41fdd488dc4858a07c7cd7154d", + "commit:44dd4c5e586e60c22a322a9eb89d1aed63892e36", + "pr:87", + "pr:19", + "commit:a1136e548ea1f2200429bf44f8f1a7297cc84246", + "commit:a4e2c52f1582952686ee56aaedd7285874326102", + "commit:c20cb64b4b79468c641626e9b9d3957790f7a671", + "commit:dc2270aad84242da42f4342ac137e243ca181aa5", + "commit:f779b5320c6008e1c8b49bf7386fdfe76dea7a8a" + ], + "change_record_count": 10, + "merge_event_count": 3 + }, + { + "id": "capability:session-fts-storage-v2", + "record_class": "capability", + "capability": "Session FTS storage-v2 settlement", + "intent_name": "Make required session FTS storage state explicit and refuse unsafe serving until settlement is complete.", + "historical_commits": [ + { + "sha": "00a2675a9270033325d53d7a3301a58f5f66d760", + "subject": "test(fts): pin storage-v2 refusal states (#31)" + }, + { + "sha": "b86e4f526ec377f7f958dc21ddaac87238882f19", + "subject": "fix(fts): unify storage-v2 settlement predicate (#31)" + }, + { + "sha": "2c907113fd2c50edde60425c561ab8ca25192b1b", + "subject": "test(fts): cover storage-v2 interruption/reopen + acceptance matrix (#31)" + }, + { + "sha": "f887f44fa2d27c7ec4132fe70d337f7975fcde63", + "subject": "docs(research): record storage-v2 settlement implementation (#31)" + }, + { + "sha": "180ae82a2d7ec34a099665d68719c8579986d693", + "subject": "test(fts): pin structural refusal branches (#31)" + }, + { + "sha": "1d6d73f3bb8ffeb599799c05b6e853da1758b4db", + "subject": "refactor(fts): settle review-round findings (#31)" + }, + { + "sha": "0fafc1dd7b58f15982ce2833de2bc8826a1e116f", + "subject": "test(fts): pin mixed-capability optimize availability (#31)" + }, + { + "sha": "67d4f719d6b0717be024861ae2756fa49d6f1315", + "subject": "fix(fts): optimize-available sees any actionable blocker (#31)" + }, + { + "sha": "0ff8583e91c838088fde6cb55ba0488cf5a0ee93", + "subject": "docs(research): fix settlement test count in validation note (#31)" + } + ], + "historical_issues": [ + "PR #78", + "issue #31" + ], + "historical_prs": [ + "PR #31", + "PR #78", + "issue #31" + ], + "merge_provenance": [ + { + "sha": "276d497764feb7d4a71f1424ed44b8958da63b16", + "subject": "Merge pull request #78 from Skywind5487/feat/31-storage-v2-settlement" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "One predicate defines required-index settlement; startup and foreground paths use it.", + "Incomplete or interrupted required settlement refuses serving; reopen/resume reaches an explicit terminal state.", + "Optional indexes do not silently become required blockers." + ], + "current_dev_survival": "Survives in hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_storage_v2_settlement.py.", + "upstream_prior_art_current_implementation": "Frozen upstream has no session six-index storage-v2 settlement state machine.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Which upstream storage contract is the port target?", + "Can refusal remain separate from six-index lifecycle?" + ], + "source_inventory_records": [ + "pr:31", + "pr:78" + ], + "change_record_count": 9, + "merge_event_count": 1 + }, + { + "id": "capability:session-fts-trigram", + "record_class": "capability", + "capability": "Normalized session metadata trigram FTS", + "intent_name": "Provide normalized external-content trigram search for arbitrary infix session metadata with fail-closed namespace ownership.", + "historical_commits": [ + { + "sha": "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "subject": "docs(research): map normalized session trigram FTS" + }, + { + "sha": "37811327cdc65c85c4b0bd565b1cdb3a4590dd91", + "subject": "feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch" + }, + { + "sha": "48b04dae36d6577b06de0efc67ebe1eb1a479d4c", + "subject": "feat(fts): add normalized external-content session trigram index (#30)" + }, + { + "sha": "6f82bcbb3c5f714148a17da47577e862493a55d6", + "subject": "test(fts): cover normalized session trigram end to end (#30)" + }, + { + "sha": "0f29f1454ea2227229e4056d66ed09f749a06e46", + "subject": "docs(research): document normalized session trigram FTS implementation (#30)" + }, + { + "sha": "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3", + "subject": "fix(fts): clear unfulfillable trigram claim on tokenizer-less host + de-dup shared seams (#30)" + }, + { + "sha": "252920f02442b68391fcafba35bef2c9567e9ab8", + "subject": "style(fts): consolidate session trigram ensure epilogue + spec-driven transition columns (#30)" + }, + { + "sha": "4483194b81495dab9b3c4c282c08adad89e0f2d9", + "subject": "fix(fts): classify session trigram schema by exact logical columns + VIEW projection (#30)" + }, + { + "sha": "bfa928d53da7c61814816c10f83fef75bfef7e43", + "subject": "fix(fts): require canonical source VIEW + FTS5 root for modern trigram identity (#30)" + }, + { + "sha": "cc5261ce775c8db6a7099d411f16030d24e71f2f", + "subject": "fix(fts): classify legacy session trigram by DDL, never PRAGMA table_info (#30)" + }, + { + "sha": "e33b533e1d2421fb18941463b6fe51752a8ad345", + "subject": "fix(fts): classify modern session trigram by DDL, never PRAGMA table_info (#30)" + }, + { + "sha": "b5155410abbf04c1fc4bb433ae3f5e546f5bf426", + "subject": "fix(fts): gate trigram source VIEW ensure on source compatibility (#30)" + }, + { + "sha": "9aad13bcad68a292f708fe30698405c2016b2626", + "subject": "fix(fts): classify same-name root VIEW as unknown, not absent (#30)" + }, + { + "sha": "3172c9f4611cc2b872f2083829577cc73152f9dc", + "subject": "fix(fts): exact shadow allowlist + classify same-name root index as unknown (#30)" + }, + { + "sha": "6467a30563fb1da2bd5c1f42dc7cd1f574697d31", + "subject": "fix(fts): hardening pass — literal-safe identity, trigger/shadow ownership, demotion CAS, stale lifecycle, serving gates, empty-claim, query cap (#30)" + }, + { + "sha": "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c", + "subject": "fix(fts): harden session trigram transition namespaces (#30)" + }, + { + "sha": "72388ff87f0baf99910edefab2b2fc2e00b40284", + "subject": "fix(fts): preserve session trigram claims across capability handoff (#30)" + }, + { + "sha": "0c02b83d4d8702267481a5f196606e19e3d303cc", + "subject": "fix(fts): gate session trigram mutations on durable ownership (#30)" + }, + { + "sha": "a9c1b2d11bab435cda80fcfc81fc223d210b4755", + "subject": "fix(fts): serve session trigram candidates from one snapshot (#30)" + }, + { + "sha": "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48", + "subject": "test(fts): drop fork-only legacy simple convergence tests (#30)" + }, + { + "sha": "c7163001f23feb31f94fec1ebb3c41badaebdb97", + "subject": "refactor(fts): drop fork-only legacy simple demotion lane (#30)" + }, + { + "sha": "6f534c8760a30a318ae0d874b7a6323f5f0337df", + "subject": "docs(fts): record scope correction and legacy lane removal (#30)" + }, + { + "sha": "10e3419d10e938c979c701246457cbd6f9c10ad4", + "subject": "test(fts): drop round-11 CAS and shadow-preflight tests (#30)" + }, + { + "sha": "69591fe659774a4e61a3f754211f5602e96a7381", + "subject": "fix(fts): quarantine healthy modern target on no-trigram runtime; drop unsupported hardening (#30)" + }, + { + "sha": "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea", + "subject": "docs(fts): record round-12 re-review and subtractive hardening removal (#30)" + }, + { + "sha": "783d3fa59ae28010368368e3dafddc19750f9b55", + "subject": "test(recovery): pin session-trigram derived markers as generated meta (#79)" + }, + { + "sha": "4aefa3abbbe4f9c3eba29988fa772e45d70000f9", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)" + }, + { + "sha": "d4c9a165c5abe6cf8c0503005b18e55de58e28cc", + "subject": "docs(research): record session-trigram recovery marker fix (#79)" + }, + { + "sha": "f17ab58979753a9ee342d258595e8d076ef2f309", + "subject": "test(recovery): guard verifier detection of leftover session-trigram markers (#79)" + }, + { + "sha": "ad0c45f0924349f6f0453d4941c3d76ad5258cdc", + "subject": "test(fts): pin modern session trigram and legacy-simple states" + } + ], + "historical_issues": [ + "PR #79", + "issue #30" + ], + "historical_prs": [ + "PR #30", + "PR #79", + "issue #30" + ], + "merge_provenance": [ + { + "sha": "919f4469e832bc2b38bba0ea5af26b842bf91acd", + "subject": "feat(fts): normalized external-content session trigram metadata index (#30)" + }, + { + "sha": "4e5ad5c2230300d1ffae84b089ffc70e368c8a23", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)" + }, + { + "sha": "f18b3c90c2309ee7616010f99c1c927c9f05013f", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/session-trigram-external-content" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "The external-content source normalizes title/display_name and keeps raw id searchable.", + "Serving requires complete trigger/namespace ownership; unknown same-name objects fail closed.", + "Recovery markers support resumable rebuild without treating a partial index as healthy." + ], + "current_dev_survival": "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_trigram_fts.py.", + "upstream_prior_art_current_implementation": "Frozen upstream has no sessions_fts_trigram external-content index; generic message trigram is not equivalent.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Validate SQLite/tokenizer deployment constraints.", + "Keep #30 ownership separate from #27 orchestration." + ], + "source_inventory_records": [ + "commit:19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "commit:37811327cdc65c85c4b0bd565b1cdb3a4590dd91", + "pr:30", + "pr:79", + "commit:ad0c45f0924349f6f0453d4941c3d76ad5258cdc", + "commit:f18b3c90c2309ee7616010f99c1c927c9f05013f" + ], + "change_record_count": 30, + "merge_event_count": 3 + }, + { + "id": "capability:session-fts-unicode", + "record_class": "capability", + "capability": "Unicode session metadata FTS", + "intent_name": "Provide stable-row-id, resumable external-content Unicode search over session title, id, and display_name.", + "historical_commits": [ + { + "sha": "2ac803bd949f0aba96c0d4d500edd2ad65aa3036", + "subject": "feat(session-search): port sessions FTS5 title index (unicode61 + cjk_unicode61) from dev" + }, + { + "sha": "9b25b0c8bd7408eaf2398529b6a04ed1a068b892", + "subject": "docs: research #32 session row_id unicode FTS" + }, + { + "sha": "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2", + "subject": "style(session-fts): drop duplicate @staticmethod (round-2 review)" + }, + { + "sha": "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0", + "subject": "fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries" + }, + { + "sha": "e94f2630a50d7585f78cfc06365753c033113cb9", + "subject": "Session metadata FTS: stable row_id + resumable Unicode external-content index (#25) (#59)" + } + ], + "historical_issues": [ + "PR #59", + "issue #25" + ], + "historical_prs": [ + "PR #59", + "issue #25" + ], + "merge_provenance": [], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Stable sessions.row_id is retained across hidden rows and gaps.", + "External-content FTS indexes title, id, and display_name with resumable high-water backfill.", + "Backfill and triggers preserve delete correctness and never expose hidden sessions." + ], + "current_dev_survival": "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, hermes_cli/session_recovery.py and tests/test_session_metadata_fts.py.", + "upstream_prior_art_current_implementation": "Frozen upstream has messages_fts but no equivalent sessions_fts metadata index.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Confirm upstream migration and database-version policy." + ], + "source_inventory_records": [ + "commit:2ac803bd949f0aba96c0d4d500edd2ad65aa3036", + "commit:9b25b0c8bd7408eaf2398529b6a04ed1a068b892", + "commit:a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2", + "commit:c3f1abc5cc34f1a356740529c9f17dfc0f4157b0", + "pr:59" + ], + "change_record_count": 5, + "merge_event_count": 0 + }, + { + "id": "capability:session-search-context-hydration", + "record_class": "capability", + "capability": "Session search context hydration", + "intent_name": "Hydrate bounded surrounding context with a predictable lock scope while preserving result semantics.", + "historical_commits": [], + "supporting_historical_commits": [ + { + "sha": "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "subject": "perf(search): batch context queries — chunked session_id batches (20/sql)", + "role": "behavioral overlay; benchmark bucket also contains query-shape validation" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "The commit remains in performance-validation for one-to-one runner accounting; the context/lock hunk is promoted by the behavioral audit.", + "behavioral_contracts": [ + "Each search match receives only its bounded preceding, matching, and following message context.", + "Context rows are fetched in bounded session batches and the position index is built outside the database lock.", + "Decode failures degrade each match to an empty context rather than corrupting the result set." + ], + "current_dev_survival": "Survives in hermes_state.py session message search and context preview tests.", + "upstream_prior_art_current_implementation": "Frozen upstream has per-match context hydration with equivalent -1/0/+1 semantics, but not the fork's bounded batch and lock-scope policy.", + "status": "PARTIAL_UPSTREAM", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Confirm the current upstream search module seam and whether the batch size should remain 20." + ], + "source_inventory_records": [ + "behavior-overlay:commit:b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70" + ], + "change_record_count": 0, + "merge_event_count": 0 + }, + { + "id": "capability:session-search-lineage", + "record_class": "capability", + "capability": "Compression-lineage-aware session search", + "intent_name": "Resolve positive compression edges to a stable root with bounded, snapshot-aware search hydration and explicit truncation.", + "historical_commits": [ + { + "sha": "1f5edc591353a0a65ec7aa2f02c6916fd67fd505", + "subject": "perf(state): narrow session listing before lineage hydration" + }, + { + "sha": "2732c47e28fbf7aaea97bd8c5cf82045a4c34159", + "subject": "wip(session-search): move winner selection into SQL" + }, + { + "sha": "2d2bad204ec644455ad1273f2934f388eb4111dd", + "subject": "fix(session-search): defer winner snippets" + }, + { + "sha": "2e1b2e64d7a452f524f703a99d68b1b110b93d3e", + "subject": "test(search): drop stale generic-parent oracle import after #68 flip" + }, + { + "sha": "2f12b03079cb7ae28acf666d16cfd748e5eaac74", + "subject": "feat(session-search): tool parity + truncation contract for #68" + }, + { + "sha": "3de538d32a3c076929c1d7c173dd77e4055100f9", + "subject": "perf: reduce SELECT * in get_compression_lineage to 4 columns" + }, + { + "sha": "42c421f68b6556757c17b4dc78756cf31babd239", + "subject": "fix(search): distinct-owner candidates + title-only K=1 snapshot contract (#68 review round-2)" + }, + { + "sha": "46907bc8b55ba36ef73e0d96c10eccb9b28b0310", + "subject": "feat(search): compression-lineage resolver for #68 winner seam" + }, + { + "sha": "55dc24391f92d71d9e293c7990089075f2ff49c9", + "subject": "refactor(search): drop title/current lineage-proof protocol per #68 review round-5" + }, + { + "sha": "66eb2fad76abf150043ffd899fbdfbd328aba2d0", + "subject": "fix(search): title/current share in-snapshot roots + compacted anchor fallback (#68 review)" + }, + { + "sha": "6fa6c557257175f26c1689799d352fdf948cb787", + "subject": "fix: replace SELECT * with specific columns in get_anchored_view and get_messages_around" + }, + { + "sha": "8838d16060bb7610c6d7ad3697f384df3edb70c1", + "subject": "test(search): RED contracts for #68 compression-lineage resolver" + }, + { + "sha": "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32", + "subject": "fix(session-search): ranked Top-N pre-limit for relevance sort" + }, + { + "sha": "a13d012e5b8736928662f27269d9f2a7cf84f0af", + "subject": "docs(session-storage): document #68 compression-lineage resolution" + }, + { + "sha": "a615feaea695123d1b3a832417a9a76554301af8", + "subject": "test(state): cover whole-store lineage visibility and pagination" + }, + { + "sha": "b2710666a29eed6fc46f3b6ce23c72f4dc766181", + "subject": "test(search): rename title==current test, correct misleading scope claim (#68 review final)" + }, + { + "sha": "c81ab321ec4bb3d5a33429b28907cd5836e41789", + "subject": "fix(search): displayable-anchor ranking + drop unproven title on B-hit (#68 review round-3)" + }, + { + "sha": "d72f99eb1b897dd29a46692a310aa15b1bfd77e8", + "subject": "docs(research): index session-lineage research" + }, + { + "sha": "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6", + "subject": "fix(search): don't gate exact-title on unrun content snapshot (#68 review round-4)" + }, + { + "sha": "f32b51764e43e48195d10e62d64b195a052d4968", + "subject": "test(search): #68 review acceptance — title parity, compacted anchor, real B boundaries, snapshot, 10k, internal-K" + } + ], + "historical_issues": [ + "PR #72", + "issue #68" + ], + "historical_prs": [ + "PR #72", + "issue #68" + ], + "merge_provenance": [ + { + "sha": "2f90c254d524d618b1c866a10bb519f2c1b6f5dc", + "subject": "Merge pull request #72 from Skywind5487/fix/68-compression-lineage-resolver" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Only positive compression edges are followed; branch/delegate markers and tool children do not become roots.", + "Missing/cyclic lineage fails closed; query-local memo/path compression is bounded by B=2000 successful uncached row fetches.", + "B exhaustion returns truncated/warning without poisoned memo; one snapshot, early-K and deferred hydration are preserved." + ], + "current_dev_survival": "Survives in hermes_state_search.py and session-search tools/tests, including bounded winner hydration.", + "upstream_prior_art_current_implementation": "Frozen upstream has _lineage_root_id/basic lookup but not the stronger resolver, memo, B-boundary, or explicit truncation contract.", + "status": "PARTIAL_UPSTREAM", + "disposition": "SPLIT", + "confidence": "high", + "unresolved_questions": [ + "Can the upstream model host the stronger resolver without storage changes?", + "Keep benchmarks non-normative." + ], + "source_inventory_records": [ + "commit:1f5edc591353a0a65ec7aa2f02c6916fd67fd505", + "commit:2732c47e28fbf7aaea97bd8c5cf82045a4c34159", + "commit:2d2bad204ec644455ad1273f2934f388eb4111dd", + "commit:2e1b2e64d7a452f524f703a99d68b1b110b93d3e", + "commit:2f12b03079cb7ae28acf666d16cfd748e5eaac74", + "pr:72", + "commit:3de538d32a3c076929c1d7c173dd77e4055100f9", + "commit:42c421f68b6556757c17b4dc78756cf31babd239", + "commit:46907bc8b55ba36ef73e0d96c10eccb9b28b0310", + "commit:55dc24391f92d71d9e293c7990089075f2ff49c9", + "commit:66eb2fad76abf150043ffd899fbdfbd328aba2d0", + "commit:6fa6c557257175f26c1689799d352fdf948cb787", + "commit:8838d16060bb7610c6d7ad3697f384df3edb70c1", + "commit:9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32", + "commit:a13d012e5b8736928662f27269d9f2a7cf84f0af", + "commit:a615feaea695123d1b3a832417a9a76554301af8", + "commit:b2710666a29eed6fc46f3b6ce23c72f4dc766181", + "commit:c81ab321ec4bb3d5a33429b28907cd5836e41789", + "commit:d72f99eb1b897dd29a46692a310aa15b1bfd77e8", + "commit:dcd10233d32eee72df93ec7ff5f8f9efcec4eef6", + "commit:f32b51764e43e48195d10e62d64b195a052d4968" + ], + "change_record_count": 20, + "merge_event_count": 1 + }, + { + "id": "capability:session-search-routing", + "record_class": "capability", + "capability": "Session metadata search routing", + "intent_name": "Route picker and resume candidates across Unicode, CJK, trigram, and bounded LIKE fallback while preserving visibility and lineage semantics.", + "historical_commits": [ + { + "sha": "0990803323497a36761c9627a20ceb57be56d5a3", + "subject": "test(state): pin session metadata route and fallback contract" + }, + { + "sha": "3ebb2592c141b232ecd0717adf32279afa6bee3f", + "subject": "test(api): cross-profile resume search + desktop stale-response ordering" + }, + { + "sha": "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d", + "subject": "feat(api): route session metadata discovery through the common seam" + }, + { + "sha": "5882274ff6c868c24f9d36f3796de08e5de8a245", + "subject": "refactor(state): add snapshot-aware metadata candidate router" + }, + { + "sha": "b4efc640fab0517571bd05447cf2be2ace9cf3e1", + "subject": "feat(desktop): search the whole session store in the resume picker" + }, + { + "sha": "b97d00e7319e5147d569519b6a34ef63c6635551", + "subject": "perf(search): benchmark routed session metadata candidates" + }, + { + "sha": "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e", + "subject": "fix(session-search): define ranked_candidates for LIKE route" + } + ], + "historical_issues": [ + "issue #14" + ], + "historical_prs": [ + "PR #14", + "issue #14" + ], + "merge_provenance": [ + { + "sha": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "subject": "feat(session): route session-metadata picker candidates through FTS (#14)" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Unicode, CJK, and infix queries select their intended index; LIKE is bounded fallback.", + "FTS narrows IDs before lineage hydration; only empty successful FTS triggers fallback.", + "Visibility, archive/pin/source filters, lineage, branch markers, whole-store scope, and limits remain correct." + ], + "current_dev_survival": "Survives in hermes_state.py, hermes_state_search.py, web session/profile routers, desktop picker code and routing tests.", + "upstream_prior_art_current_implementation": "Frozen upstream has session ID/title primitives but no equivalent metadata-index router.", + "status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Separate routing from index contracts and desktop/API seams.", + "Revalidate ranking against the post-fork upstream model." + ], + "source_inventory_records": [ + "commit:0990803323497a36761c9627a20ceb57be56d5a3", + "pr:14", + "commit:3ebb2592c141b232ecd0717adf32279afa6bee3f", + "commit:3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d", + "commit:5882274ff6c868c24f9d36f3796de08e5de8a245", + "commit:b4efc640fab0517571bd05447cf2be2ace9cf3e1", + "commit:b97d00e7319e5147d569519b6a34ef63c6635551", + "commit:ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e" + ], + "change_record_count": 7, + "merge_event_count": 1 + }, + { + "id": "capability:session-title-safety", + "record_class": "capability", + "capability": "Literal-safe numbered-title resolution", + "intent_name": "Resolve numbered session-title variants without SQL LIKE metacharacters or non-numeric # suffixes becoming variants.", + "historical_commits": [ + { + "sha": "d18dadb5f3b517ec69f14428dc78e7af1a86a30e", + "subject": "test(session): pin literal-safe numbered-title resolution (#15)" + }, + { + "sha": "faf96ef221ddfba2618abc8dae8368f7b82c1c2a", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)" + }, + { + "sha": "69bee0838ae15936ae4beb13cdf5d6907c19c707", + "subject": "docs: record #38 numbered-title research note and design contract (#15)" + }, + { + "sha": "17b0d2c9135d38728109592860677c4abbaddf4f", + "subject": "fix(session): unify #N grammar to ASCII digits; tidy escape_like placement (#15)" + } + ], + "historical_issues": [ + "issue #15" + ], + "historical_prs": [ + "PR #15", + "issue #15" + ], + "merge_provenance": [ + { + "sha": "984eff15df1fb749f00aece7fc24c43e9afcb7e8", + "subject": "Merge remote-tracking branch 'origin/dev' into fix/15-numbered-title-literal-safety" + }, + { + "sha": "dcf8096413c7ee40fe0ab512ac86927fb2092df1", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Escape SQL LIKE literals independently from Python literals.", + "Only strict ASCII #N suffixes are variants; %, _, \\, #, CJK, and literal titles stay exact and safe.", + "The public resolution API and root/current exclusion semantics remain unchanged." + ], + "current_dev_survival": "Survives in hermes_state.py, hermes_state_common.py and title/metadata tests.", + "upstream_prior_art_current_implementation": "Frozen upstream escapes LIKE but does not enforce the fork's strict numeric suffix filter.", + "status": "PARTIAL_UPSTREAM", + "disposition": "SPLIT", + "confidence": "high", + "unresolved_questions": [ + "Check callers that may depend on broader historical #% behavior." + ], + "source_inventory_records": [ + "commit:984eff15df1fb749f00aece7fc24c43e9afcb7e8", + "pr:15" + ], + "change_record_count": 4, + "merge_event_count": 2 + }, + { + "id": "capability:sqlite-write-contention-policy", + "record_class": "capability", + "capability": "SQLite write contention backoff policy", + "intent_name": "Bound write contention with rollback-safe exponential backoff and a finite delay cap.", + "historical_commits": [], + "supporting_historical_commits": [ + { + "sha": "cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log", + "role": "behavioral overlay; same commit also contains diagnostics" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "The commit remains in its original incidental-hardening provenance bucket for one-to-one runner accounting; the retry hunk is promoted by the behavioral audit.", + "behavioral_contracts": [ + "SQLite write contention retries roll back before retrying.", + "Retry delay uses a 20ms base with jitter, exponential growth, and a 2s cap.", + "Retry exhaustion and non-lock failures retain explicit error behavior." + ], + "current_dev_survival": "Survives in hermes_state.py _execute_write and write-contention tests/logging.", + "upstream_prior_art_current_implementation": "Frozen upstream has uniform 20-150ms retry jitter and slow-write diagnostics, not the fork's exponential 20ms-to-2s policy.", + "status": "PARTIAL_UPSTREAM", + "disposition": "PORT", + "confidence": "high", + "unresolved_questions": [ + "Revalidate attempt/deadline semantics when porting onto the current upstream writer." + ], + "source_inventory_records": [ + "behavior-overlay:commit:cc2531fbc6df8fdb34fca0b096b798eb53f970dd" + ], + "change_record_count": 0, + "merge_event_count": 0 + }, + { + "id": "non-capability:incidental-hardening", + "record_class": "non_capability", + "capability": "Incidental hardening and maintenance", + "intent_name": "Account for isolated reliability/logging/cleanup changes without manufacturing a broader ontology.", + "historical_commits": [ + { + "sha": "4270ea5b9a903d0dcf692db2365875ac5b3fe319", + "subject": "chore: ignore fts5_cjk Windows build artifact (.dll)" + }, + { + "sha": "9f3056cb3a9642c39056af8409cc3198007e68a8", + "subject": "ignore agents" + }, + { + "sha": "cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "The safety invariant remains visible in record subject/files while capability ownership is unresolved." + ], + "current_dev_survival": "Record-specific survival is visible in the frozen tree.", + "upstream_prior_art_current_implementation": "No equivalence claim is made without focused comparison.", + "status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "medium", + "unresolved_questions": [ + "Promote only if a user-visible invariant and test boundary is identified." + ], + "source_inventory_records": [ + "commit:4270ea5b9a903d0dcf692db2365875ac5b3fe319", + "commit:9f3056cb3a9642c39056af8409cc3198007e68a8", + "commit:cc2531fbc6df8fdb34fca0b096b798eb53f970dd" + ], + "change_record_count": 3, + "merge_event_count": 0, + "behavioral_overlays": [ + "capability:sqlite-write-contention-policy" + ] + }, + { + "id": "non-capability:integration-merge", + "record_class": "non_capability", + "capability": "Branch integration and merge bookkeeping", + "intent_name": "Account for merge events that combine classified work without claiming a new capability.", + "historical_commits": [], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [ + { + "sha": "1602d06f5045d173ee31161b92e387de69ab821c", + "subject": "merge(session-search): ranked Top-N + late-snippet into dev" + }, + { + "sha": "637ef2e193b6b2dada5d0b79173461fca03fbf20", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/routed-session-metadata-candidates" + }, + { + "sha": "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "subject": "Merge remote-tracking branch 'origin/main' into dev" + }, + { + "sha": "b66c149de0c8240e84ded1a2f983b8c42f7b984b", + "subject": "merge(main): absorb upstream main 91937a6dc into dev — keep session-search fix chain" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "A merge event is not silently omitted merely because it has no patch-id or changed-file payload." + ], + "current_dev_survival": "Integrated behavior is represented by capability records on either side.", + "upstream_prior_art_current_implementation": "Merge topology is provenance, not semantic upstream evidence.", + "status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "unresolved_questions": [ + "Split conflict resolution into a capability if it changes behavior." + ], + "source_inventory_records": [ + "commit:1602d06f5045d173ee31161b92e387de69ab821c", + "commit:637ef2e193b6b2dada5d0b79173461fca03fbf20", + "commit:9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "commit:b66c149de0c8240e84ded1a2f983b8c42f7b984b" + ], + "change_record_count": 0, + "merge_event_count": 4 + }, + { + "id": "non-capability:performance-validation", + "record_class": "non_capability", + "capability": "Performance validation record", + "intent_name": "Account for benchmarks and query-shape optimizations without upgrading measurements into semantic boundaries.", + "historical_commits": [ + { + "sha": "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "subject": "perf(search): benchmark cold-open + fallback-invariant self-check" + }, + { + "sha": "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "subject": "perf(search): batch context queries — chunked session_id batches (20/sql)" + } + ], + "historical_issues": [], + "historical_prs": [], + "merge_provenance": [ + { + "sha": "a34da2c31ca60f9b5280558c514a3a1880035036", + "subject": "Merge branch 'fix/session-search-perf' of /home/skywind5487/hermes_worktrees/fix/session-search-perf into dev" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "A benchmark supports a decision but does not prove equivalence or impose an unreviewed target." + ], + "current_dev_survival": "Benchmark and query-shape changes remain visible in history.", + "upstream_prior_art_current_implementation": "No upstream equivalence is inferred from local measurements.", + "status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "unresolved_questions": [ + "Re-run only benchmarks needed for a concrete port candidate." + ], + "source_inventory_records": [ + "commit:7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "commit:a34da2c31ca60f9b5280558c514a3a1880035036", + "commit:b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70" + ], + "change_record_count": 2, + "merge_event_count": 1, + "behavioral_overlays": [ + "capability:session-search-context-hydration" + ] + }, + { + "id": "non-capability:production-evidence", + "record_class": "non_capability", + "capability": "Production recovery/build evidence", + "intent_name": "Account for recovery runbooks, production DB build/freeze, and runtime attestation without treating them as runtime capabilities.", + "historical_commits": [ + { + "sha": "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57", + "subject": "docs(research): record #22 production-ready state.db build and freeze" + }, + { + "sha": "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba", + "subject": "docs(recovery): add production runtime repair runbook" + }, + { + "sha": "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba", + "subject": "docs(research): correct #22 path/router evidence with executing-query validation" + }, + { + "sha": "8b085795df0359adbf3c81315f888bc7041fb044", + "subject": "docs(research): record #22 redo with SQLite 3.51.3 + CJK + fuzz" + }, + { + "sha": "cea5282a181d23af471f4467f449fd9bfc022ca5", + "subject": "docs(recovery): attest production gateway runtime surface" + } + ], + "historical_issues": [ + "PR #82", + "issue #21", + "issue #22", + "issue #41" + ], + "historical_prs": [ + "PR #82", + "issue #21", + "issue #22", + "issue #41" + ], + "merge_provenance": [ + { + "sha": "bee13fc085079d78d0334722ad4c37a1144e3102", + "subject": "Merge pull request #82 from Skywind5487/feat/22-production-ready-state-db-execution" + } + ], + "merge_provenance_note": "Explicitly accounted in the source inventory.", + "behavioral_contracts": [ + "Operational records remain durable evidence and are not mistaken for code-level equivalence." + ], + "current_dev_survival": "Survives as docs/research and research/recovery artifacts.", + "upstream_prior_art_current_implementation": "No code-level equivalence is claimed from operational documents.", + "status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "unresolved_questions": [ + "Which recovery procedures remain required after a future port?" + ], + "source_inventory_records": [ + "commit:0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57", + "commit:311bf7d6d28b204f0aa977ddcd05d44141d2d4ba", + "commit:4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba", + "commit:8b085795df0359adbf3c81315f888bc7041fb044", + "pr:82", + "commit:cea5282a181d23af471f4467f449fd9bfc022ca5" + ], + "change_record_count": 5, + "merge_event_count": 1 + } + ], + "phase_2_boundaries": [ + "Port memory-trim policy (RSS low-water threshold, independent GC cooldown, cheap malloc_trim cadence) as a runtime behavior slice.", + "Keep memory-trim diagnostics (GC/trim attribution, fragmentation, VmSwap) separate from policy and best-effort.", + "Port session metadata FTS base, CJK, trigram, lifecycle, and storage-v2 as separate slices with explicit dependency ordering.", + "Port session search routing only after index contracts and the lineage resolver are independently validated.", + "Evaluate headroom output compression and CCR retrieval as separate optional plugin slices.", + "Port configurable reasoning display and request transformation after upstream hook/config ordering is specified.", + "Port compression session-boundary no-op semantics separately from lifecycle telemetry.", + "Port SQLite write-contention backoff separately from incidental diagnostics.", + "Port session-search context hydration/lock scope separately from benchmark evidence." + ] +} diff --git a/artifacts/fork-archaeology-issue-100/capability-manifest.md b/artifacts/fork-archaeology-issue-100/capability-manifest.md new file mode 100644 index 000000000000..8d979560f306 --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/capability-manifest.md @@ -0,0 +1,653 @@ +# Phase-1 capability manifest + +Frozen fork `35c8564c9c0af3d75bcbdf1d793e7207e5528f06`; upstream `460d345642ee3d143a3e461abe39fd42b86a7e54`; merge base `91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53`. + +## Accounting + +- Historical change records: **145** +- Merge events: **26** +- Total mapped records: **171** +- Explicit accounting: **PASS** +- Hunk-level behavioral coverage: **PASS**; see `behavioral-coverage-audit.md`. + +The 116 inventory provenance buckets are evidence containers, not capability boundaries. + +## Group summary + +| Group | Class | Changes | Merges | Status | Disposition | Confidence | +|---|---:|---:|---:|---|---|---| +| `capability:browser-timeout-cleanup` | capability | 3 | 2 | FORK_ONLY | PORT | high | +| `capability:compression-session-boundary` | capability | 0 | 0 | PARTIAL_UPSTREAM | SPLIT | high | +| `capability:configurable-reasoning-display` | capability | 1 | 1 | FORK_ONLY | PORT | high | +| `capability:cron-nul-safety` | capability | 1 | 0 | SEMANTIC_UPSTREAM | DROP | high | +| `capability:headroom-compression` | capability | 4 | 1 | FORK_ONLY | PORT | high | +| `capability:headroom-retrieval` | capability | 5 | 1 | FORK_ONLY | PORT | high | +| `capability:lifecycle-sqlite-telemetry` | capability | 1 | 0 | NEEDS_REVIEW | NEEDS_REVIEW | medium | +| `capability:memory-trim-diagnostics` | capability | 1 | 0 | PARTIAL_UPSTREAM | KEEP | medium | +| `capability:memory-trim-policy` | capability | 1 | 0 | PARTIAL_UPSTREAM | PORT | high | +| `capability:outbound-code-fence-safety` | capability | 5 | 2 | SEMANTIC_UPSTREAM | DROP | high | +| `capability:request-transform-hook` | capability | 1 | 0 | FORK_ONLY | PORT | high | +| `capability:session-fts-cjk` | capability | 12 | 1 | FORK_ONLY | PORT | high | +| `capability:session-fts-lifecycle` | capability | 15 | 1 | FORK_ONLY | PORT | high | +| `capability:session-fts-simple-eol` | capability | 10 | 3 | SEMANTIC_UPSTREAM | DROP | high | +| `capability:session-fts-storage-v2` | capability | 9 | 1 | FORK_ONLY | PORT | high | +| `capability:session-fts-trigram` | capability | 30 | 3 | FORK_ONLY | PORT | high | +| `capability:session-fts-unicode` | capability | 5 | 0 | FORK_ONLY | PORT | high | +| `capability:session-search-context-hydration` | capability | 0 | 0 | PARTIAL_UPSTREAM | PORT | high | +| `capability:session-search-lineage` | capability | 20 | 1 | PARTIAL_UPSTREAM | SPLIT | high | +| `capability:session-search-routing` | capability | 7 | 1 | FORK_ONLY | PORT | high | +| `capability:session-title-safety` | capability | 4 | 2 | PARTIAL_UPSTREAM | SPLIT | high | +| `capability:sqlite-write-contention-policy` | capability | 0 | 0 | PARTIAL_UPSTREAM | PORT | high | +| `non-capability:incidental-hardening` | non_capability | 3 | 0 | NEEDS_REVIEW | NEEDS_REVIEW | medium | +| `non-capability:integration-merge` | non_capability | 0 | 4 | NEEDS_REVIEW | NEEDS_REVIEW | high | +| `non-capability:performance-validation` | non_capability | 2 | 1 | NEEDS_REVIEW | NEEDS_REVIEW | high | +| `non-capability:production-evidence` | non_capability | 5 | 1 | NEEDS_REVIEW | NEEDS_REVIEW | high | + +## Group details + +### `capability:browser-timeout-cleanup` — Browser timeout cleanup policy + +**Intent:** Make browser daemon termination on timeout configuration-gated and crash-resilient while retaining finally-path cleanup. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 3; **merge events:** 2 + +**Behavioral contract:** +- Timeout cleanup clears in-memory browser state in a finally-equivalent path. +- Daemon termination is opt-in/config-gated. +- Cleanup failures are contained and test-covered. + +**Current-dev survival:** Survives in tools/browser_tool.py and timeout cleanup/daemon tests. + +**Upstream prior art/current implementation:** Frozen upstream has timeout cleanup/orphan reaping but not terminate_daemon_on_timeout configuration behavior. + +**Unresolved questions:** +- Check whether upstream orphan reaping supersedes this toggle. + +**Accounting source records:** commit:8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f, commit:9e3439835e9dbbad0d0076d539d769db1f84de0a, commit:a2450695db0e99f3dd8362f129024cb74c700bb8, commit:b42bc25e622c11230998cc57f7050ec2a2cdd090, commit:cfb2636a6a3ed02ff773f106beb71c88576f1284 + +### `capability:compression-session-boundary` — Compression session-boundary semantics + +**Intent:** Prevent compressor-reported no-op results from creating a false session boundary. + +**Status / disposition / confidence:** `PARTIAL_UPSTREAM` / `SPLIT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 0; **merge events:** 0 + +**Behavioral contract:** +- A context compressor reporting noop does not rotate or rewrite the session, even if it returns a newly allocated list. +- The current system prompt and session lock are released safely on the no-op path. + +**Supporting historical commits / behavioral overlays:** 176646d2cd6c95fa49b9414f21ed9e781b0aaa84 + +**Current-dev survival:** Survives in agent/conversation_compression.py and its compression lifecycle tests. + +**Upstream prior art/current implementation:** Frozen upstream has a semantic no-progress guard for equal compressor output, but the explicit status-reported-noop case is a separate residual contract. + +**Unresolved questions:** +- Confirm the canonical status field for third-party context compressors before porting. + +**Accounting source records:** behavior-overlay:commit:176646d2cd6c95fa49b9414f21ed9e781b0aaa84 + +### `capability:configurable-reasoning-display` — Configurable reasoning display limit + +**Intent:** Replace a hardcoded reasoning display limit with explicit configuration while retaining safe truncation. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** PR #3 +**Historical change records:** 1; **merge events:** 1 + +**Behavioral contract:** +- reasoning_max_lines controls display truncation. +- Invalid or absent configuration falls back safely. +- Fence escaping remains applied before wrapping. + +**Current-dev survival:** Survives in cli.py/config parsing and gateway display code. + +**Upstream prior art/current implementation:** Frozen upstream hardcodes the first 15 lines and has no reasoning_max_lines seam. + +**Unresolved questions:** +- Confirm configuration source and documentation expected upstream. + +**Accounting source records:** commit:895ba96014ecf934dbc140306ffe578a0a533ea3, pr:3 + +### `capability:cron-nul-safety` — NUL-safe cron lifecycle and terminal fallback + +**Intent:** Safely reject NUL-bearing paths before lifecycle/terminal process APIs can misinterpret them. + +**Status / disposition / confidence:** `SEMANTIC_UPSTREAM` / `DROP` / `high` + +**Historical issues/PRs:** PR #76762, PR #76762 +**Historical change records:** 1; **merge events:** 0 + +**Behavioral contract:** +- NUL-bearing input does not reach unsafe process/lifecycle calls. +- Terminal fallback returns a clear failure rather than truncating at NUL. + +**Current-dev survival:** Survives in cron/lifecycle_guard.py and tools/terminal_tool.py. + +**Upstream prior art/current implementation:** Frozen upstream contains the corresponding NUL/binary-safe guard and terminal fallback. + +**Unresolved questions:** +- Confirm upstream release and canonical tests. + +**Accounting source records:** pr:76762 + +### `capability:headroom-compression` — Headroom output compression + +**Intent:** Compress oversized tool/context payloads with bounded output, metadata-safe behavior, and explicit warning semantics. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 4; **merge events:** 1 + +**Behavioral contract:** +- Compression activates only at configured thresholds and does not expand tool-result metadata. +- Failures degrade with warning/logging and preserve usable content. +- Plugin registration and schema remain valid when active. + +**Current-dev survival:** Survives in plugins/headroom, tools_config.py, plugin.yaml, pyproject.toml/uv.lock and plugin tests. + +**Upstream prior art/current implementation:** Frozen upstream has no headroom ContentRouter/SmartCrusher implementation. + +**Unresolved questions:** +- Identify upstream context-management owner before porting. +- Keep output compression separate from retrieval. + +**Accounting source records:** commit:237176ed1d973910972984ba83d876d01c00f3db, commit:5eb552458de9828f4496880fd878f58015a63389, commit:915913db360de5fe5b147d4895276ff39a6e8686, commit:b7e62647bd657a429d967cfa77034632ee490f9a, commit:c16ebe6b8649c570b688fd82d6b66f9a8416d59c + +### `capability:headroom-retrieval` — Headroom retrieval (CCR) + +**Intent:** Expose bounded retrieval of compressed context through a registered tool when compression is active. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 5; **merge events:** 1 + +**Behavioral contract:** +- The retrieval tool has a stable schema. +- It is auto-enabled only when compression is active and returns bounded context. +- Registration failures are explicit and warning-visible. + +**Current-dev survival:** Survives in plugins/headroom, tools_config.py, plugin.yaml and plugin tests. + +**Upstream prior art/current implementation:** No equivalent retrieval tool is present in frozen upstream. + +**Unresolved questions:** +- Decide whether retrieval is a generic upstream context API or plugin-owned. + +**Accounting source records:** commit:0a4b567ff08776a3a10ee7a32d37332d873f20b2, commit:0b4e7601227a23bc653d0d3018a3a9591d02f2a1, commit:516d739f64a95a4f380b899fbb9a349d750fc2aa, commit:b527e4df996b859356c0c48c2b9c9eae4c74c4dc, commit:d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6, commit:ff4df5b71e1557660dbe994eb5569983f57c9901 + +### `capability:lifecycle-sqlite-telemetry` — Lifecycle and SQLite observability telemetry + +**Intent:** Expose structured lifecycle, tool, stream, SQLite, and delivery telemetry at important execution boundaries. + +**Status / disposition / confidence:** `NEEDS_REVIEW` / `NEEDS_REVIEW` / `medium` + +**Historical issues/PRs:** none recorded +**Historical change records:** 1; **merge events:** 0 + +**Behavioral contract:** +- Important boundaries emit structured telemetry rather than only ad-hoc logs. +- SQLite lock/owner and stream/tool failures remain diagnosable. +**Overlay capability references:** capability:compression-session-boundary + +**Current-dev survival:** Survives across lifecycle_telemetry.py, sqlite_native_telemetry.py, turn_context.py, gateway code and tests. + +**Upstream prior art/current implementation:** Frozen upstream comparison was not completed per telemetry surface; absence is not treated as proof. + +**Unresolved questions:** +- Separate domain facts from diagnostics. +- Which event names/sinks are stable enough to port? + +**Accounting source records:** commit:176646d2cd6c95fa49b9414f21ed9e781b0aaa84 + +### `capability:memory-trim-diagnostics` — Memory trim diagnostics + +**Intent:** Attribute trim cost and memory pressure without making diagnostics a prerequisite for recovery. + +**Status / disposition / confidence:** `PARTIAL_UPSTREAM` / `KEEP` / `medium` + +**Historical issues/PRs:** none recorded +**Historical change records:** 1; **merge events:** 0 + +**Behavioral contract:** +- gc_ms versus trim_ms identifies the freeze mechanism without changing the policy decision. +- Fragmentation and VmSwap are best-effort diagnostics and never block memory recovery. + +**Current-dev survival:** Survives in hermes_cli/mem_trim.py through gc_ms/trim_ms, malloc_info fragmentation, VmSwap snapshots, and structured trim logs. + +**Upstream prior art/current implementation:** Frozen upstream has basic RSS/RssAnon snapshots and trim logging, but not the fork's GC-versus-trim attribution, malloc_info fragmentation, or VmSwap diagnostics. + +**Unresolved questions:** +- Which diagnostic fields are stable enough to expose as a long-term contract? +- Should malloc_info remain best-effort Linux/glibc-only instrumentation? + +**Accounting source records:** commit:04f1af72be078cef69de538f1519f93a73088b0d + +### `capability:memory-trim-policy` — Memory trim policy + +**Intent:** Avoid expensive and low-value heap work while preserving cheap malloc_trim cadence. + +**Status / disposition / confidence:** `PARTIAL_UPSTREAM` / `PORT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 1; **merge events:** 0 + +**Behavioral contract:** +- RSS below threshold_mb skips the expensive trim work on housekeeping ticks. +- gc.collect() runs at most once per gc_cooldown_seconds while malloc_trim remains eligible on the normal trim cadence. +- The 99.7% GC attribution explains the policy split; force behavior and invalid configuration retain safe fallbacks. + +**Supporting historical commits / behavioral overlays:** 04f1af72be078cef69de538f1519f93a73088b0d + +**Current-dev survival:** Survives in hermes_cli/mem_trim.py with threshold_mb, gc_cooldown_seconds, separate _last_gc_monotonic state, and independent malloc_trim cadence. + +**Upstream prior art/current implementation:** Frozen upstream hermes_cli/mem_trim.py has a general cooldown around gc.collect()+malloc_trim, but no RSS low-water gate or independent GC cooldown; this is partial prior art, not equivalence. + +**Unresolved questions:** +- Which upstream housekeeping callers should own the cheap trim cadence after porting? +- Should threshold_mb and gc_cooldown_seconds share the upstream config naming/default policy? + +**Accounting source records:** commit:a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb + +### `capability:outbound-code-fence-safety` — Outbound code-fence and truncation safety + +**Intent:** Preserve balanced code fences and inline-code spans when reasoning, streaming chunks, or Discord edits are escaped or truncated. + +**Status / disposition / confidence:** `SEMANTIC_UPSTREAM` / `DROP` / `high` + +**Historical issues/PRs:** PR #2 +**Historical change records:** 5; **merge events:** 2 + +**Behavioral contract:** +- Untrusted backticks are escaped before outer wrapping. +- Chunk balancing and truncation close open triple-backtick and inline-code spans. +- Discord edit/truncation preserves the same user-visible balance guarantee. + +**Current-dev survival:** Survives in gateway/stream_consumer.py and Discord adapter/tests. + +**Upstream prior art/current implementation:** Frozen upstream already has escape_code_fences_for_display, ensure_closed_code_fences, and chunk balancing with equivalent behavior. + +**Unresolved questions:** +- Run upstream Discord edit-truncation tests before deleting fork provenance. + +**Accounting source records:** commit:347442ddc80a2658582cb62dd268a0be024b1bcf, commit:44afcc8d3f869c7780beb1bc0bece86df1e45cb2, commit:47cc1764dc2c2c65cc83fe20500da939698d72d3, pr:2, commit:c1a3e16c32896ea2d469536c657814049c29bec6, commit:eed6ba2734bc7aaabbd1e8cf08cd794badc72d71, commit:efd68fe044001c57c5d148a66469209589c344d9 + +### `capability:request-transform-hook` — Full-payload outbound request transform hook + +**Intent:** Allow plugins to transform the complete outbound API request before dispatch. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 1; **merge events:** 0 + +**Behavioral contract:** +- transform_api_request receives and returns the complete payload at a documented boundary. +- The hook is optional and preserves the request when absent. +- Hook errors are explicit and do not dispatch partial data. + +**Current-dev survival:** Survives in agent/conversation_loop.py, hermes_cli/hooks.py, hermes_cli/plugins.py and run-agent tests. + +**Upstream prior art/current implementation:** Frozen upstream has pre_llm_call but not a full-payload transform hook at dispatch. + +**Unresolved questions:** +- Define ordering relative to pre_llm_call and provider adapters. + +**Accounting source records:** commit:296d9c6e2e5a6f852344ad8fa9b90f5687912be1 + +### `capability:session-fts-cjk` — CJK session metadata search + +**Intent:** Add an optional, independently maintained CJK session metadata index with safe degradation and snapshot-consistent serving. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** PR #65, issue #26, PR #26, PR #65, issue #26 +**Historical change records:** 12; **merge events:** 1 + +**Behavioral contract:** +- CJK search covers title, id, and display_name through external-content FTS. +- Unavailable tokenizer/index state degrades safely without hiding the base path. +- Guard and MATCH run against one SQLite snapshot; rebuild is independent and resumable. + +**Current-dev survival:** Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_cjk_fts.py. + +**Upstream prior art/current implementation:** Frozen upstream has no session CJK metadata index or equivalent optional lifecycle. + +**Unresolved questions:** +- What tokenizer availability contract is acceptable upstream? +- Should CJK remain a separate optional port? + +**Accounting source records:** pr:65, commit:15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114, commit:3053abf3b039a5b4c23637597cb076f2339250fb, pr:26, commit:6311e77e27f4fd4009c73d0df16abebf56121f4a, commit:6447a52cd994bf30c2811814f21095d12aba83ae, commit:6b3402ea05566fa1553a93aceb285eb517d7e67d, commit:83431f775a9e3798611e03b16a2f7d9a7ac74a57, commit:8efead2600a3f932f9881b53cd0c7eabc755f82f + +### `capability:session-fts-lifecycle` — Unified six-index FTS lifecycle + +**Intent:** Give all session and message FTS indexes one descriptor-driven maintenance, health, repair, discovery, and degraded-runtime boundary. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** PR #76, issue #27, PR #27, PR #76, issue #27 +**Historical change records:** 15; **merge events:** 1 + +**Behavioral contract:** +- The registry covers messages_fts, messages_fts_trigram, messages_fts_cjk, sessions_fts, sessions_fts_cjk, and sessions_fts_trigram. +- Maintenance, health, read-only discovery, repair, and degraded runtime iterate the same descriptors. +- Unknown or incomplete trigger state fails closed for serving. + +**Current-dev survival:** Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_lifecycle_registry.py. + +**Upstream prior art/current implementation:** Frozen upstream has message FTS primitives but no equivalent session six-index lifecycle boundary. + +**Unresolved questions:** +- Which lifecycle pieces are required by upstream? +- How should #31 remain an explicit dependency? + +**Accounting source records:** pr:27, commit:0cf4cd0baffb68b571a44f2a39d3bf817cd38348, commit:75223d19544ceb73cf24fb859fc0780ed9a099a5, pr:76, commit:a822d37d18064d1442eb20b6a2cb4e9f8b17d48d, commit:bdd9d699f6dc13b32852a078c1ecf5664bcb837d, commit:dc1f153a71d025d903f255861da57f94d649ca37 + +### `capability:session-fts-simple-eol` — Legacy simple-tokenizer retirement + +**Intent:** Remove the unsupported legacy simple-tokenizer compatibility debt and make unsupported database states fail explicitly. + +**Status / disposition / confidence:** `SEMANTIC_UPSTREAM` / `DROP` / `high` + +**Historical issues/PRs:** PR #87, issue #19, PR #19, PR #87, issue #19 +**Historical change records:** 10; **merge events:** 3 + +**Behavioral contract:** +- Supported post-#12 databases do not require simple-tokenizer loading or repair branches. +- Unsupported legacy residue is sanitized or rejected explicitly rather than silently kept writable. +- Modern trigram/CJK lifecycle remains the canonical path. + +**Current-dev survival:** Survives in hermes_state.py sanitizer/repair logic and the #19/#87 research and tests. + +**Upstream prior art/current implementation:** Frozen upstream has no load_simple_extension/simple-tokenizer compatibility shim; the legacy debt is already absent there. + +**Unresolved questions:** +- Prove the release ancestry of upstream database states before closing the port question. + +**Accounting source records:** commit:196b904417371cf233f3eb9b560c80a079ab8d72, commit:433a49f66b447f41fdd488dc4858a07c7cd7154d, commit:44dd4c5e586e60c22a322a9eb89d1aed63892e36, pr:87, pr:19, commit:a1136e548ea1f2200429bf44f8f1a7297cc84246, commit:a4e2c52f1582952686ee56aaedd7285874326102, commit:c20cb64b4b79468c641626e9b9d3957790f7a671, commit:dc2270aad84242da42f4342ac137e243ca181aa5, commit:f779b5320c6008e1c8b49bf7386fdfe76dea7a8a + +### `capability:session-fts-storage-v2` — Session FTS storage-v2 settlement + +**Intent:** Make required session FTS storage state explicit and refuse unsafe serving until settlement is complete. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** PR #78, issue #31, PR #31, PR #78, issue #31 +**Historical change records:** 9; **merge events:** 1 + +**Behavioral contract:** +- One predicate defines required-index settlement; startup and foreground paths use it. +- Incomplete or interrupted required settlement refuses serving; reopen/resume reaches an explicit terminal state. +- Optional indexes do not silently become required blockers. + +**Current-dev survival:** Survives in hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_storage_v2_settlement.py. + +**Upstream prior art/current implementation:** Frozen upstream has no session six-index storage-v2 settlement state machine. + +**Unresolved questions:** +- Which upstream storage contract is the port target? +- Can refusal remain separate from six-index lifecycle? + +**Accounting source records:** pr:31, pr:78 + +### `capability:session-fts-trigram` — Normalized session metadata trigram FTS + +**Intent:** Provide normalized external-content trigram search for arbitrary infix session metadata with fail-closed namespace ownership. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** PR #79, issue #30, PR #30, PR #79, issue #30 +**Historical change records:** 30; **merge events:** 3 + +**Behavioral contract:** +- The external-content source normalizes title/display_name and keeps raw id searchable. +- Serving requires complete trigger/namespace ownership; unknown same-name objects fail closed. +- Recovery markers support resumable rebuild without treating a partial index as healthy. + +**Current-dev survival:** Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_trigram_fts.py. + +**Upstream prior art/current implementation:** Frozen upstream has no sessions_fts_trigram external-content index; generic message trigram is not equivalent. + +**Unresolved questions:** +- Validate SQLite/tokenizer deployment constraints. +- Keep #30 ownership separate from #27 orchestration. + +**Accounting source records:** commit:19e6e6223bb58a4a53c8c02c86a0127d34afaf5a, commit:37811327cdc65c85c4b0bd565b1cdb3a4590dd91, pr:30, pr:79, commit:ad0c45f0924349f6f0453d4941c3d76ad5258cdc, commit:f18b3c90c2309ee7616010f99c1c927c9f05013f + +### `capability:session-fts-unicode` — Unicode session metadata FTS + +**Intent:** Provide stable-row-id, resumable external-content Unicode search over session title, id, and display_name. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** PR #59, issue #25, PR #59, issue #25 +**Historical change records:** 5; **merge events:** 0 + +**Behavioral contract:** +- Stable sessions.row_id is retained across hidden rows and gaps. +- External-content FTS indexes title, id, and display_name with resumable high-water backfill. +- Backfill and triggers preserve delete correctness and never expose hidden sessions. + +**Current-dev survival:** Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, hermes_cli/session_recovery.py and tests/test_session_metadata_fts.py. + +**Upstream prior art/current implementation:** Frozen upstream has messages_fts but no equivalent sessions_fts metadata index. + +**Unresolved questions:** +- Confirm upstream migration and database-version policy. + +**Accounting source records:** commit:2ac803bd949f0aba96c0d4d500edd2ad65aa3036, commit:9b25b0c8bd7408eaf2398529b6a04ed1a068b892, commit:a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2, commit:c3f1abc5cc34f1a356740529c9f17dfc0f4157b0, pr:59 + +### `capability:session-search-context-hydration` — Session search context hydration + +**Intent:** Hydrate bounded surrounding context with a predictable lock scope while preserving result semantics. + +**Status / disposition / confidence:** `PARTIAL_UPSTREAM` / `PORT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 0; **merge events:** 0 + +**Behavioral contract:** +- Each search match receives only its bounded preceding, matching, and following message context. +- Context rows are fetched in bounded session batches and the position index is built outside the database lock. +- Decode failures degrade each match to an empty context rather than corrupting the result set. + +**Supporting historical commits / behavioral overlays:** b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70 + +**Current-dev survival:** Survives in hermes_state.py session message search and context preview tests. + +**Upstream prior art/current implementation:** Frozen upstream has per-match context hydration with equivalent -1/0/+1 semantics, but not the fork's bounded batch and lock-scope policy. + +**Unresolved questions:** +- Confirm the current upstream search module seam and whether the batch size should remain 20. + +**Accounting source records:** behavior-overlay:commit:b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70 + +### `capability:session-search-lineage` — Compression-lineage-aware session search + +**Intent:** Resolve positive compression edges to a stable root with bounded, snapshot-aware search hydration and explicit truncation. + +**Status / disposition / confidence:** `PARTIAL_UPSTREAM` / `SPLIT` / `high` + +**Historical issues/PRs:** PR #72, issue #68, PR #72, issue #68 +**Historical change records:** 20; **merge events:** 1 + +**Behavioral contract:** +- Only positive compression edges are followed; branch/delegate markers and tool children do not become roots. +- Missing/cyclic lineage fails closed; query-local memo/path compression is bounded by B=2000 successful uncached row fetches. +- B exhaustion returns truncated/warning without poisoned memo; one snapshot, early-K and deferred hydration are preserved. + +**Current-dev survival:** Survives in hermes_state_search.py and session-search tools/tests, including bounded winner hydration. + +**Upstream prior art/current implementation:** Frozen upstream has _lineage_root_id/basic lookup but not the stronger resolver, memo, B-boundary, or explicit truncation contract. + +**Unresolved questions:** +- Can the upstream model host the stronger resolver without storage changes? +- Keep benchmarks non-normative. + +**Accounting source records:** commit:1f5edc591353a0a65ec7aa2f02c6916fd67fd505, commit:2732c47e28fbf7aaea97bd8c5cf82045a4c34159, commit:2d2bad204ec644455ad1273f2934f388eb4111dd, commit:2e1b2e64d7a452f524f703a99d68b1b110b93d3e, commit:2f12b03079cb7ae28acf666d16cfd748e5eaac74, pr:72, commit:3de538d32a3c076929c1d7c173dd77e4055100f9, commit:42c421f68b6556757c17b4dc78756cf31babd239, commit:46907bc8b55ba36ef73e0d96c10eccb9b28b0310, commit:55dc24391f92d71d9e293c7990089075f2ff49c9, commit:66eb2fad76abf150043ffd899fbdfbd328aba2d0, commit:6fa6c557257175f26c1689799d352fdf948cb787, commit:8838d16060bb7610c6d7ad3697f384df3edb70c1, commit:9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32, commit:a13d012e5b8736928662f27269d9f2a7cf84f0af, commit:a615feaea695123d1b3a832417a9a76554301af8, commit:b2710666a29eed6fc46f3b6ce23c72f4dc766181, commit:c81ab321ec4bb3d5a33429b28907cd5836e41789, commit:d72f99eb1b897dd29a46692a310aa15b1bfd77e8, commit:dcd10233d32eee72df93ec7ff5f8f9efcec4eef6, commit:f32b51764e43e48195d10e62d64b195a052d4968 + +### `capability:session-search-routing` — Session metadata search routing + +**Intent:** Route picker and resume candidates across Unicode, CJK, trigram, and bounded LIKE fallback while preserving visibility and lineage semantics. + +**Status / disposition / confidence:** `FORK_ONLY` / `PORT` / `high` + +**Historical issues/PRs:** issue #14, PR #14, issue #14 +**Historical change records:** 7; **merge events:** 1 + +**Behavioral contract:** +- Unicode, CJK, and infix queries select their intended index; LIKE is bounded fallback. +- FTS narrows IDs before lineage hydration; only empty successful FTS triggers fallback. +- Visibility, archive/pin/source filters, lineage, branch markers, whole-store scope, and limits remain correct. + +**Current-dev survival:** Survives in hermes_state.py, hermes_state_search.py, web session/profile routers, desktop picker code and routing tests. + +**Upstream prior art/current implementation:** Frozen upstream has session ID/title primitives but no equivalent metadata-index router. + +**Unresolved questions:** +- Separate routing from index contracts and desktop/API seams. +- Revalidate ranking against the post-fork upstream model. + +**Accounting source records:** commit:0990803323497a36761c9627a20ceb57be56d5a3, pr:14, commit:3ebb2592c141b232ecd0717adf32279afa6bee3f, commit:3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d, commit:5882274ff6c868c24f9d36f3796de08e5de8a245, commit:b4efc640fab0517571bd05447cf2be2ace9cf3e1, commit:b97d00e7319e5147d569519b6a34ef63c6635551, commit:ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e + +### `capability:session-title-safety` — Literal-safe numbered-title resolution + +**Intent:** Resolve numbered session-title variants without SQL LIKE metacharacters or non-numeric # suffixes becoming variants. + +**Status / disposition / confidence:** `PARTIAL_UPSTREAM` / `SPLIT` / `high` + +**Historical issues/PRs:** issue #15, PR #15, issue #15 +**Historical change records:** 4; **merge events:** 2 + +**Behavioral contract:** +- Escape SQL LIKE literals independently from Python literals. +- Only strict ASCII #N suffixes are variants; %, _, \, #, CJK, and literal titles stay exact and safe. +- The public resolution API and root/current exclusion semantics remain unchanged. + +**Current-dev survival:** Survives in hermes_state.py, hermes_state_common.py and title/metadata tests. + +**Upstream prior art/current implementation:** Frozen upstream escapes LIKE but does not enforce the fork's strict numeric suffix filter. + +**Unresolved questions:** +- Check callers that may depend on broader historical #% behavior. + +**Accounting source records:** commit:984eff15df1fb749f00aece7fc24c43e9afcb7e8, pr:15 + +### `capability:sqlite-write-contention-policy` — SQLite write contention backoff policy + +**Intent:** Bound write contention with rollback-safe exponential backoff and a finite delay cap. + +**Status / disposition / confidence:** `PARTIAL_UPSTREAM` / `PORT` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 0; **merge events:** 0 + +**Behavioral contract:** +- SQLite write contention retries roll back before retrying. +- Retry delay uses a 20ms base with jitter, exponential growth, and a 2s cap. +- Retry exhaustion and non-lock failures retain explicit error behavior. + +**Supporting historical commits / behavioral overlays:** cc2531fbc6df8fdb34fca0b096b798eb53f970dd + +**Current-dev survival:** Survives in hermes_state.py _execute_write and write-contention tests/logging. + +**Upstream prior art/current implementation:** Frozen upstream has uniform 20-150ms retry jitter and slow-write diagnostics, not the fork's exponential 20ms-to-2s policy. + +**Unresolved questions:** +- Revalidate attempt/deadline semantics when porting onto the current upstream writer. + +**Accounting source records:** behavior-overlay:commit:cc2531fbc6df8fdb34fca0b096b798eb53f970dd + +### `non-capability:incidental-hardening` — Incidental hardening and maintenance + +**Intent:** Account for isolated reliability/logging/cleanup changes without manufacturing a broader ontology. + +**Status / disposition / confidence:** `NEEDS_REVIEW` / `NEEDS_REVIEW` / `medium` + +**Historical issues/PRs:** none recorded +**Historical change records:** 3; **merge events:** 0 + +**Behavioral contract:** +- The safety invariant remains visible in record subject/files while capability ownership is unresolved. +**Overlay capability references:** capability:sqlite-write-contention-policy + +**Current-dev survival:** Record-specific survival is visible in the frozen tree. + +**Upstream prior art/current implementation:** No equivalence claim is made without focused comparison. + +**Unresolved questions:** +- Promote only if a user-visible invariant and test boundary is identified. + +**Accounting source records:** commit:4270ea5b9a903d0dcf692db2365875ac5b3fe319, commit:9f3056cb3a9642c39056af8409cc3198007e68a8, commit:cc2531fbc6df8fdb34fca0b096b798eb53f970dd + +### `non-capability:integration-merge` — Branch integration and merge bookkeeping + +**Intent:** Account for merge events that combine classified work without claiming a new capability. + +**Status / disposition / confidence:** `NEEDS_REVIEW` / `NEEDS_REVIEW` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 0; **merge events:** 4 + +**Behavioral contract:** +- A merge event is not silently omitted merely because it has no patch-id or changed-file payload. + +**Current-dev survival:** Integrated behavior is represented by capability records on either side. + +**Upstream prior art/current implementation:** Merge topology is provenance, not semantic upstream evidence. + +**Unresolved questions:** +- Split conflict resolution into a capability if it changes behavior. + +**Accounting source records:** commit:1602d06f5045d173ee31161b92e387de69ab821c, commit:637ef2e193b6b2dada5d0b79173461fca03fbf20, commit:9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140, commit:b66c149de0c8240e84ded1a2f983b8c42f7b984b + +### `non-capability:performance-validation` — Performance validation record + +**Intent:** Account for benchmarks and query-shape optimizations without upgrading measurements into semantic boundaries. + +**Status / disposition / confidence:** `NEEDS_REVIEW` / `NEEDS_REVIEW` / `high` + +**Historical issues/PRs:** none recorded +**Historical change records:** 2; **merge events:** 1 + +**Behavioral contract:** +- A benchmark supports a decision but does not prove equivalence or impose an unreviewed target. +**Overlay capability references:** capability:session-search-context-hydration + +**Current-dev survival:** Benchmark and query-shape changes remain visible in history. + +**Upstream prior art/current implementation:** No upstream equivalence is inferred from local measurements. + +**Unresolved questions:** +- Re-run only benchmarks needed for a concrete port candidate. + +**Accounting source records:** commit:7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0, commit:a34da2c31ca60f9b5280558c514a3a1880035036, commit:b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70 + +### `non-capability:production-evidence` — Production recovery/build evidence + +**Intent:** Account for recovery runbooks, production DB build/freeze, and runtime attestation without treating them as runtime capabilities. + +**Status / disposition / confidence:** `NEEDS_REVIEW` / `NEEDS_REVIEW` / `high` + +**Historical issues/PRs:** PR #82, issue #21, issue #22, issue #41, PR #82, issue #21, issue #22, issue #41 +**Historical change records:** 5; **merge events:** 1 + +**Behavioral contract:** +- Operational records remain durable evidence and are not mistaken for code-level equivalence. + +**Current-dev survival:** Survives as docs/research and research/recovery artifacts. + +**Upstream prior art/current implementation:** No code-level equivalence is claimed from operational documents. + +**Unresolved questions:** +- Which recovery procedures remain required after a future port? + +**Accounting source records:** commit:0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57, commit:311bf7d6d28b204f0aa977ddcd05d44141d2d4ba, commit:4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba, commit:8b085795df0359adbf3c81315f888bc7041fb044, pr:82, commit:cea5282a181d23af471f4467f449fd9bfc022ca5 diff --git a/artifacts/fork-archaeology-issue-100/evidence.json b/artifacts/fork-archaeology-issue-100/evidence.json new file mode 100644 index 000000000000..60adbc08ba6e --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/evidence.json @@ -0,0 +1,315 @@ +{ + "intents": { + "capability:session-fts-storage-v2": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_storage_v2_settlement.py.", + "Frozen upstream has no session six-index storage-v2 settlement state machine." + ], + "behavioral_contracts": [ + "One predicate defines required-index settlement; startup and foreground paths use it.", + "Incomplete or interrupted required settlement refuses serving; reopen/resume reaches an explicit terminal state.", + "Optional indexes do not silently become required blockers." + ] + }, + "capability:session-fts-lifecycle": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_lifecycle_registry.py.", + "Frozen upstream has message FTS primitives but no equivalent session six-index lifecycle boundary." + ], + "behavioral_contracts": [ + "The registry covers messages_fts, messages_fts_trigram, messages_fts_cjk, sessions_fts, sessions_fts_cjk, and sessions_fts_trigram.", + "Maintenance, health, read-only discovery, repair, and degraded runtime iterate the same descriptors.", + "Unknown or incomplete trigger state fails closed for serving." + ] + }, + "non-capability:production-evidence": { + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "evidence": [ + "Survives as docs/research and research/recovery artifacts.", + "No code-level equivalence is claimed from operational documents." + ], + "behavioral_contracts": [ + "Operational records remain durable evidence and are not mistaken for code-level equivalence." + ] + }, + "capability:session-search-routing": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_search.py, web session/profile routers, desktop picker code and routing tests.", + "Frozen upstream has session ID/title primitives but no equivalent metadata-index router." + ], + "behavioral_contracts": [ + "Unicode, CJK, and infix queries select their intended index; LIKE is bounded fallback.", + "FTS narrows IDs before lineage hydration; only empty successful FTS triggers fallback.", + "Visibility, archive/pin/source filters, lineage, branch markers, whole-store scope, and limits remain correct." + ] + }, + "capability:headroom-retrieval": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in plugins/headroom, tools_config.py, plugin.yaml and plugin tests.", + "No equivalent retrieval tool is present in frozen upstream." + ], + "behavioral_contracts": [ + "The retrieval tool has a stable schema.", + "It is auto-enabled only when compression is active and returns bounded context.", + "Registration failures are explicit and warning-visible." + ] + }, + "capability:session-fts-cjk": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_cjk_fts.py.", + "Frozen upstream has no session CJK metadata index or equivalent optional lifecycle." + ], + "behavioral_contracts": [ + "CJK search covers title, id, and display_name through external-content FTS.", + "Unavailable tokenizer/index state degrades safely without hiding the base path.", + "Guard and MATCH run against one SQLite snapshot; rebuild is independent and resumable." + ] + }, + "non-capability:integration-merge": { + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "evidence": [ + "Integrated behavior is represented by capability records on either side.", + "Merge topology is provenance, not semantic upstream evidence." + ], + "behavioral_contracts": [ + "A merge event is not silently omitted merely because it has no patch-id or changed-file payload." + ] + }, + "capability:lifecycle-sqlite-telemetry": { + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "medium", + "evidence": [ + "Survives across lifecycle_telemetry.py, sqlite_native_telemetry.py, turn_context.py, gateway code and tests.", + "Frozen upstream comparison was not completed per telemetry surface; absence is not treated as proof." + ], + "behavioral_contracts": [ + "Important boundaries emit structured telemetry rather than only ad-hoc logs.", + "SQLite lock/owner and stream/tool failures remain diagnosable." + ] + }, + "capability:session-fts-simple-eol": { + "upstream_status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py sanitizer/repair logic and the #19/#87 research and tests.", + "Frozen upstream has no load_simple_extension/simple-tokenizer compatibility shim; the legacy debt is already absent there." + ], + "behavioral_contracts": [ + "Supported post-#12 databases do not require simple-tokenizer loading or repair branches.", + "Unsupported legacy residue is sanitized or rejected explicitly rather than silently kept writable.", + "Modern trigram/CJK lifecycle remains the canonical path." + ] + }, + "capability:session-fts-trigram": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_trigram_fts.py.", + "Frozen upstream has no sessions_fts_trigram external-content index; generic message trigram is not equivalent." + ], + "behavioral_contracts": [ + "The external-content source normalizes title/display_name and keeps raw id searchable.", + "Serving requires complete trigger/namespace ownership; unknown same-name objects fail closed.", + "Recovery markers support resumable rebuild without treating a partial index as healthy." + ] + }, + "capability:session-search-lineage": { + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "SPLIT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state_search.py and session-search tools/tests, including bounded winner hydration.", + "Frozen upstream has _lineage_root_id/basic lookup but not the stronger resolver, memo, B-boundary, or explicit truncation contract." + ], + "behavioral_contracts": [ + "Only positive compression edges are followed; branch/delegate markers and tool children do not become roots.", + "Missing/cyclic lineage fails closed; query-local memo/path compression is bounded by B=2000 successful uncached row fetches.", + "B exhaustion returns truncated/warning without poisoned memo; one snapshot, early-K and deferred hydration are preserved." + ] + }, + "capability:headroom-compression": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in plugins/headroom, tools_config.py, plugin.yaml, pyproject.toml/uv.lock and plugin tests.", + "Frozen upstream has no headroom ContentRouter/SmartCrusher implementation." + ], + "behavioral_contracts": [ + "Compression activates only at configured thresholds and does not expand tool-result metadata.", + "Failures degrade with warning/logging and preserve usable content.", + "Plugin registration and schema remain valid when active." + ] + }, + "capability:request-transform-hook": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in agent/conversation_loop.py, hermes_cli/hooks.py, hermes_cli/plugins.py and run-agent tests.", + "Frozen upstream has pre_llm_call but not a full-payload transform hook at dispatch." + ], + "behavioral_contracts": [ + "transform_api_request receives and returns the complete payload at a documented boundary.", + "The hook is optional and preserves the request when absent.", + "Hook errors are explicit and do not dispatch partial data." + ] + }, + "capability:session-fts-unicode": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, hermes_cli/session_recovery.py and tests/test_session_metadata_fts.py.", + "Frozen upstream has messages_fts but no equivalent sessions_fts metadata index." + ], + "behavioral_contracts": [ + "Stable sessions.row_id is retained across hidden rows and gaps.", + "External-content FTS indexes title, id, and display_name with resumable high-water backfill.", + "Backfill and triggers preserve delete correctness and never expose hidden sessions." + ] + }, + "capability:outbound-code-fence-safety": { + "upstream_status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "evidence": [ + "Survives in gateway/stream_consumer.py and Discord adapter/tests.", + "Frozen upstream already has escape_code_fences_for_display, ensure_closed_code_fences, and chunk balancing with equivalent behavior." + ], + "behavioral_contracts": [ + "Untrusted backticks are escaped before outer wrapping.", + "Chunk balancing and truncation close open triple-backtick and inline-code spans.", + "Discord edit/truncation preserves the same user-visible balance guarantee." + ] + }, + "non-capability:incidental-hardening": { + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "medium", + "evidence": [ + "Record-specific survival is visible in the frozen tree.", + "No equivalence claim is made without focused comparison." + ], + "behavioral_contracts": [ + "The safety invariant remains visible in record subject/files while capability ownership is unresolved." + ] + }, + "non-capability:performance-validation": { + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "evidence": [ + "Benchmark and query-shape changes remain visible in history.", + "No upstream equivalence is inferred from local measurements." + ], + "behavioral_contracts": [ + "A benchmark supports a decision but does not prove equivalence or impose an unreviewed target." + ] + }, + "capability:configurable-reasoning-display": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in cli.py/config parsing and gateway display code.", + "Frozen upstream hardcodes the first 15 lines and has no reasoning_max_lines seam." + ], + "behavioral_contracts": [ + "reasoning_max_lines controls display truncation.", + "Invalid or absent configuration falls back safely.", + "Fence escaping remains applied before wrapping." + ] + }, + "capability:browser-timeout-cleanup": { + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in tools/browser_tool.py and timeout cleanup/daemon tests.", + "Frozen upstream has timeout cleanup/orphan reaping but not terminate_daemon_on_timeout configuration behavior." + ], + "behavioral_contracts": [ + "Timeout cleanup clears in-memory browser state in a finally-equivalent path.", + "Daemon termination is opt-in/config-gated.", + "Cleanup failures are contained and test-covered." + ] + }, + "capability:session-title-safety": { + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "SPLIT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py and title/metadata tests.", + "Frozen upstream escapes LIKE but does not enforce the fork's strict numeric suffix filter." + ], + "behavioral_contracts": [ + "Escape SQL LIKE literals independently from Python literals.", + "Only strict ASCII #N suffixes are variants; %, _, \\, #, CJK, and literal titles stay exact and safe.", + "The public resolution API and root/current exclusion semantics remain unchanged." + ] + }, + "capability:cron-nul-safety": { + "upstream_status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "evidence": [ + "Survives in cron/lifecycle_guard.py and tools/terminal_tool.py.", + "Frozen upstream contains the corresponding NUL/binary-safe guard and terminal fallback." + ], + "behavioral_contracts": [ + "NUL-bearing input does not reach unsafe process/lifecycle calls.", + "Terminal fallback returns a clear failure rather than truncating at NUL." + ] + }, + "capability:memory-trim-policy": { + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Frozen fork hermes_cli/mem_trim.py adds threshold_mb and gc_cooldown_seconds policy gates.", + "Frozen upstream hermes_cli/mem_trim.py has a general trim cooldown but no RSS low-water gate or independent GC cooldown." + ], + "behavioral_contracts": [ + "RSS below threshold_mb skips the expensive trim work on housekeeping ticks.", + "gc.collect() runs at most once per gc_cooldown_seconds while malloc_trim remains eligible on the normal trim cadence.", + "Force behavior and invalid configuration retain explicit safe fallbacks." + ] + }, + "capability:memory-trim-diagnostics": { + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "KEEP", + "confidence": "medium", + "evidence": [ + "Frozen fork splits gc_ms and trim_ms, records VmSwap, and measures malloc_info fragmentation.", + "Frozen upstream has basic RSS/RssAnon snapshots and trim logging but not the fork's attribution diagnostics." + ], + "behavioral_contracts": [ + "gc_ms versus trim_ms identifies the freeze mechanism without changing the policy decision.", + "Fragmentation and VmSwap are best-effort diagnostics and never block memory recovery." + ] + } + } +} diff --git a/artifacts/fork-archaeology-issue-100/intent-map.json b/artifacts/fork-archaeology-issue-100/intent-map.json new file mode 100644 index 000000000000..dd1ccebdbcc6 --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/intent-map.json @@ -0,0 +1,182 @@ +{ + "schema_version": 1, + "inputs": { + "fork_ref": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "upstream_ref": "460d345642ee3d143a3e461abe39fd42b86a7e54", + "merge_base": "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53" + }, + "commits": { + "00a2675a9270033325d53d7a3301a58f5f66d760": "capability:session-fts-storage-v2", + "b86e4f526ec377f7f958dc21ddaac87238882f19": "capability:session-fts-storage-v2", + "2c907113fd2c50edde60425c561ab8ca25192b1b": "capability:session-fts-storage-v2", + "f887f44fa2d27c7ec4132fe70d337f7975fcde63": "capability:session-fts-storage-v2", + "180ae82a2d7ec34a099665d68719c8579986d693": "capability:session-fts-storage-v2", + "1d6d73f3bb8ffeb599799c05b6e853da1758b4db": "capability:session-fts-storage-v2", + "0fafc1dd7b58f15982ce2833de2bc8826a1e116f": "capability:session-fts-storage-v2", + "67d4f719d6b0717be024861ae2756fa49d6f1315": "capability:session-fts-storage-v2", + "0ff8583e91c838088fde6cb55ba0488cf5a0ee93": "capability:session-fts-storage-v2", + "00e680a8cb22e251f351b9f140b0679c4f96dabc": "capability:session-fts-lifecycle", + "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1": "capability:session-fts-lifecycle", + "474b88fe76e18dfcf397f11b3de6f069abac4a4c": "capability:session-fts-lifecycle", + "f9ade6baff7f236b6b9401932c61bc0400375664": "capability:session-fts-lifecycle", + "e64ad007b459871af42e312bc5dffd2da92ac900": "capability:session-fts-lifecycle", + "0400c66f072d0f319331ea105cd8f7e059975388": "capability:session-fts-lifecycle", + "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec": "capability:session-fts-lifecycle", + "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a": "capability:session-fts-lifecycle", + "3bc7d3f58f808e269675404c9bbeada467b00e98": "capability:session-fts-lifecycle", + "d6a4d70483623cc3fad4eea8c96754d7d637d02c": "capability:session-fts-lifecycle", + "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57": "non-capability:production-evidence", + "04f1af72be078cef69de538f1519f93a73088b0d": "capability:memory-trim-diagnostics", + "0990803323497a36761c9627a20ceb57be56d5a3": "capability:session-search-routing", + "0a4b567ff08776a3a10ee7a32d37332d873f20b2": "capability:headroom-retrieval", + "0b4e7601227a23bc653d0d3018a3a9591d02f2a1": "capability:headroom-retrieval", + "0cf4cd0baffb68b571a44f2a39d3bf817cd38348": "capability:session-fts-lifecycle", + "0eee69ef43f16c63f29db414e1acb40253212125": "capability:session-fts-cjk", + "bdf2fc218264538c4f3238b58532488fe665ff9e": "capability:session-fts-cjk", + "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114": "capability:session-fts-cjk", + "1602d06f5045d173ee31161b92e387de69ab821c": "non-capability:integration-merge", + "176646d2cd6c95fa49b9414f21ed9e781b0aaa84": "capability:lifecycle-sqlite-telemetry", + "196b904417371cf233f3eb9b560c80a079ab8d72": "capability:session-fts-simple-eol", + "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a": "capability:session-fts-trigram", + "1f5edc591353a0a65ec7aa2f02c6916fd67fd505": "capability:session-search-lineage", + "237176ed1d973910972984ba83d876d01c00f3db": "capability:headroom-compression", + "2732c47e28fbf7aaea97bd8c5cf82045a4c34159": "capability:session-search-lineage", + "276d497764feb7d4a71f1424ed44b8958da63b16": "capability:session-fts-storage-v2", + "296d9c6e2e5a6f852344ad8fa9b90f5687912be1": "capability:request-transform-hook", + "2ac803bd949f0aba96c0d4d500edd2ad65aa3036": "capability:session-fts-unicode", + "2d2bad204ec644455ad1273f2934f388eb4111dd": "capability:session-search-lineage", + "2e1b2e64d7a452f524f703a99d68b1b110b93d3e": "capability:session-search-lineage", + "2f12b03079cb7ae28acf666d16cfd748e5eaac74": "capability:session-search-lineage", + "2f90c254d524d618b1c866a10bb519f2c1b6f5dc": "capability:session-search-lineage", + "3053abf3b039a5b4c23637597cb076f2339250fb": "capability:session-fts-cjk", + "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba": "non-capability:production-evidence", + "347442ddc80a2658582cb62dd268a0be024b1bcf": "capability:outbound-code-fence-safety", + "35c8564c9c0af3d75bcbdf1d793e7207e5528f06": "capability:session-search-routing", + "37811327cdc65c85c4b0bd565b1cdb3a4590dd91": "capability:session-fts-trigram", + "3de538d32a3c076929c1d7c173dd77e4055100f9": "capability:session-search-lineage", + "3e23375f7934e4315d45860e6992171fb5609c5c": "capability:session-fts-cjk", + "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7": "capability:session-fts-cjk", + "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5": "capability:session-fts-cjk", + "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128": "capability:session-fts-cjk", + "3ebb2592c141b232ecd0717adf32279afa6bee3f": "capability:session-search-routing", + "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d": "capability:session-search-routing", + "4270ea5b9a903d0dcf692db2365875ac5b3fe319": "non-capability:incidental-hardening", + "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba": "non-capability:production-evidence", + "42c421f68b6556757c17b4dc78756cf31babd239": "capability:session-search-lineage", + "433a49f66b447f41fdd488dc4858a07c7cd7154d": "capability:session-fts-simple-eol", + "44afcc8d3f869c7780beb1bc0bece86df1e45cb2": "capability:outbound-code-fence-safety", + "44dd4c5e586e60c22a322a9eb89d1aed63892e36": "capability:session-fts-simple-eol", + "46907bc8b55ba36ef73e0d96c10eccb9b28b0310": "capability:session-search-lineage", + "47cc1764dc2c2c65cc83fe20500da939698d72d3": "capability:outbound-code-fence-safety", + "48b04dae36d6577b06de0efc67ebe1eb1a479d4c": "capability:session-fts-trigram", + "6f82bcbb3c5f714148a17da47577e862493a55d6": "capability:session-fts-trigram", + "0f29f1454ea2227229e4056d66ed09f749a06e46": "capability:session-fts-trigram", + "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3": "capability:session-fts-trigram", + "252920f02442b68391fcafba35bef2c9567e9ab8": "capability:session-fts-trigram", + "4483194b81495dab9b3c4c282c08adad89e0f2d9": "capability:session-fts-trigram", + "bfa928d53da7c61814816c10f83fef75bfef7e43": "capability:session-fts-trigram", + "cc5261ce775c8db6a7099d411f16030d24e71f2f": "capability:session-fts-trigram", + "e33b533e1d2421fb18941463b6fe51752a8ad345": "capability:session-fts-trigram", + "b5155410abbf04c1fc4bb433ae3f5e546f5bf426": "capability:session-fts-trigram", + "9aad13bcad68a292f708fe30698405c2016b2626": "capability:session-fts-trigram", + "3172c9f4611cc2b872f2083829577cc73152f9dc": "capability:session-fts-trigram", + "6467a30563fb1da2bd5c1f42dc7cd1f574697d31": "capability:session-fts-trigram", + "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c": "capability:session-fts-trigram", + "72388ff87f0baf99910edefab2b2fc2e00b40284": "capability:session-fts-trigram", + "0c02b83d4d8702267481a5f196606e19e3d303cc": "capability:session-fts-trigram", + "a9c1b2d11bab435cda80fcfc81fc223d210b4755": "capability:session-fts-trigram", + "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48": "capability:session-fts-trigram", + "c7163001f23feb31f94fec1ebb3c41badaebdb97": "capability:session-fts-trigram", + "6f534c8760a30a318ae0d874b7a6323f5f0337df": "capability:session-fts-trigram", + "10e3419d10e938c979c701246457cbd6f9c10ad4": "capability:session-fts-trigram", + "69591fe659774a4e61a3f754211f5602e96a7381": "capability:session-fts-trigram", + "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea": "capability:session-fts-trigram", + "919f4469e832bc2b38bba0ea5af26b842bf91acd": "capability:session-fts-trigram", + "516d739f64a95a4f380b899fbb9a349d750fc2aa": "capability:headroom-retrieval", + "535b33c95f9465bb3e05b281b17fceee3ba24d22": "capability:outbound-code-fence-safety", + "53da9e89f8f3d2b051bf4c719b9f09b355392c00": "capability:session-fts-simple-eol", + "55dc24391f92d71d9e293c7990089075f2ff49c9": "capability:session-search-lineage", + "5882274ff6c868c24f9d36f3796de08e5de8a245": "capability:session-search-routing", + "5eb552458de9828f4496880fd878f58015a63389": "capability:headroom-compression", + "6311e77e27f4fd4009c73d0df16abebf56121f4a": "capability:session-fts-cjk", + "637ef2e193b6b2dada5d0b79173461fca03fbf20": "non-capability:integration-merge", + "6447a52cd994bf30c2811814f21095d12aba83ae": "capability:session-fts-cjk", + "66eb2fad76abf150043ffd899fbdfbd328aba2d0": "capability:session-search-lineage", + "6b3402ea05566fa1553a93aceb285eb517d7e67d": "capability:session-fts-cjk", + "6fa6c557257175f26c1689799d352fdf948cb787": "capability:session-search-lineage", + "75223d19544ceb73cf24fb859fc0780ed9a099a5": "capability:session-fts-lifecycle", + "783d3fa59ae28010368368e3dafddc19750f9b55": "capability:session-fts-trigram", + "4aefa3abbbe4f9c3eba29988fa772e45d70000f9": "capability:session-fts-trigram", + "d4c9a165c5abe6cf8c0503005b18e55de58e28cc": "capability:session-fts-trigram", + "f17ab58979753a9ee342d258595e8d076ef2f309": "capability:session-fts-trigram", + "4e5ad5c2230300d1ffae84b089ffc70e368c8a23": "capability:session-fts-trigram", + "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0": "non-capability:performance-validation", + "83431f775a9e3798611e03b16a2f7d9a7ac74a57": "capability:session-fts-cjk", + "85fd91fd7c7be20d63356f27654d399ca1da4fa0": "capability:session-fts-simple-eol", + "186986a447080ae74a1d17fd1e32aaf039cb2ff2": "capability:session-fts-simple-eol", + "deb10243ccebd6153cdfab8e9869faba2e105f0e": "capability:session-fts-simple-eol", + "1d5b80cab802e6ae932c97342e328e76faa496fa": "capability:session-fts-simple-eol", + "8838d16060bb7610c6d7ad3697f384df3edb70c1": "capability:session-search-lineage", + "895ba96014ecf934dbc140306ffe578a0a533ea3": "capability:configurable-reasoning-display", + "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f": "capability:browser-timeout-cleanup", + "8b085795df0359adbf3c81315f888bc7041fb044": "non-capability:production-evidence", + "8efead2600a3f932f9881b53cd0c7eabc755f82f": "capability:session-fts-cjk", + "915913db360de5fe5b147d4895276ff39a6e8686": "capability:headroom-compression", + "984eff15df1fb749f00aece7fc24c43e9afcb7e8": "capability:session-title-safety", + "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32": "capability:session-search-lineage", + "9b25b0c8bd7408eaf2398529b6a04ed1a068b892": "capability:session-fts-unicode", + "9d140c8594c67ed37729b190fd3733508d0d770c": "capability:session-fts-lifecycle", + "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140": "non-capability:integration-merge", + "9e3439835e9dbbad0d0076d539d769db1f84de0a": "capability:browser-timeout-cleanup", + "9f3056cb3a9642c39056af8409cc3198007e68a8": "non-capability:incidental-hardening", + "9fe97e2aa1b05306ed626e5ae3db540d24bb4678": "capability:configurable-reasoning-display", + "a1136e548ea1f2200429bf44f8f1a7297cc84246": "capability:session-fts-simple-eol", + "a13d012e5b8736928662f27269d9f2a7cf84f0af": "capability:session-search-lineage", + "a2450695db0e99f3dd8362f129024cb74c700bb8": "capability:browser-timeout-cleanup", + "a34da2c31ca60f9b5280558c514a3a1880035036": "non-capability:performance-validation", + "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2": "capability:session-fts-unicode", + "a4e2c52f1582952686ee56aaedd7285874326102": "capability:session-fts-simple-eol", + "a615feaea695123d1b3a832417a9a76554301af8": "capability:session-search-lineage", + "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d": "capability:session-fts-lifecycle", + "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb": "capability:memory-trim-policy", + "ad0c45f0924349f6f0453d4941c3d76ad5258cdc": "capability:session-fts-trigram", + "b2710666a29eed6fc46f3b6ce23c72f4dc766181": "capability:session-search-lineage", + "b42bc25e622c11230998cc57f7050ec2a2cdd090": "capability:browser-timeout-cleanup", + "b4efc640fab0517571bd05447cf2be2ace9cf3e1": "capability:session-search-routing", + "b527e4df996b859356c0c48c2b9c9eae4c74c4dc": "capability:headroom-retrieval", + "b66c149de0c8240e84ded1a2f983b8c42f7b984b": "non-capability:integration-merge", + "b7e62647bd657a429d967cfa77034632ee490f9a": "capability:headroom-compression", + "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70": "non-capability:performance-validation", + "b97d00e7319e5147d569519b6a34ef63c6635551": "capability:session-search-routing", + "bdd9d699f6dc13b32852a078c1ecf5664bcb837d": "capability:session-fts-lifecycle", + "bee13fc085079d78d0334722ad4c37a1144e3102": "non-capability:production-evidence", + "c16ebe6b8649c570b688fd82d6b66f9a8416d59c": "capability:headroom-compression", + "c1a3e16c32896ea2d469536c657814049c29bec6": "capability:outbound-code-fence-safety", + "c20cb64b4b79468c641626e9b9d3957790f7a671": "capability:session-fts-simple-eol", + "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0": "capability:session-fts-unicode", + "c81ab321ec4bb3d5a33429b28907cd5836e41789": "capability:session-search-lineage", + "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e": "capability:session-search-routing", + "cc2531fbc6df8fdb34fca0b096b798eb53f970dd": "non-capability:incidental-hardening", + "cea5282a181d23af471f4467f449fd9bfc022ca5": "non-capability:production-evidence", + "cfb2636a6a3ed02ff773f106beb71c88576f1284": "capability:browser-timeout-cleanup", + "d18dadb5f3b517ec69f14428dc78e7af1a86a30e": "capability:session-title-safety", + "faf96ef221ddfba2618abc8dae8368f7b82c1c2a": "capability:session-title-safety", + "69bee0838ae15936ae4beb13cdf5d6907c19c707": "capability:session-title-safety", + "17b0d2c9135d38728109592860677c4abbaddf4f": "capability:session-title-safety", + "dcf8096413c7ee40fe0ab512ac86927fb2092df1": "capability:session-title-safety", + "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6": "capability:headroom-retrieval", + "d53e209b3b620abce55f2cc57a80c69bc0cd9369": "capability:cron-nul-safety", + "d72f99eb1b897dd29a46692a310aa15b1bfd77e8": "capability:session-search-lineage", + "dc1f153a71d025d903f255861da57f94d649ca37": "capability:session-fts-lifecycle", + "dc2270aad84242da42f4342ac137e243ca181aa5": "capability:session-fts-simple-eol", + "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6": "capability:session-search-lineage", + "e94f2630a50d7585f78cfc06365753c033113cb9": "capability:session-fts-unicode", + "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71": "capability:outbound-code-fence-safety", + "efd68fe044001c57c5d148a66469209589c344d9": "capability:outbound-code-fence-safety", + "f18b3c90c2309ee7616010f99c1c927c9f05013f": "capability:session-fts-trigram", + "f32b51764e43e48195d10e62d64b195a052d4968": "capability:session-search-lineage", + "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a": "capability:session-fts-simple-eol", + "ff4df5b71e1557660dbe994eb5569983f57c9901": "capability:headroom-retrieval" + }, + "record_grouping": "semantic capability boundary or explicit non-capability bookkeeping; provisional inventory buckets are not boundaries" +} diff --git a/artifacts/fork-archaeology-issue-100/inventory.json b/artifacts/fork-archaeology-issue-100/inventory.json new file mode 100644 index 000000000000..805c71dcf31b --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/inventory.json @@ -0,0 +1,4149 @@ +{ + "schema_version": 3, + "inputs": { + "fork_ref": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "upstream_ref": "460d345642ee3d143a3e461abe39fd42b86a7e54", + "merge_base": "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53" + }, + "provenance_buckets": [ + { + "id": "capability:session-fts-storage-v2", + "record_type": "provenance_bucket", + "subject": "test(fts): pin storage-v2 refusal states (#31)", + "commits": [ + { + "sha": "00a2675a9270033325d53d7a3301a58f5f66d760", + "subject": "test(fts): pin storage-v2 refusal states (#31)", + "parents": [ + "9d140c8594c67ed37729b190fd3733508d0d770c" + ], + "is_merge": false, + "patch_id": "ea3822aa15120604e3a6d5f5a852662423003e79", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "b86e4f526ec377f7f958dc21ddaac87238882f19", + "subject": "fix(fts): unify storage-v2 settlement predicate (#31)", + "parents": [ + "00a2675a9270033325d53d7a3301a58f5f66d760" + ], + "is_merge": false, + "patch_id": "e6c4a15ba13108650949d288ca82785d8166b51c", + "changed_files": [ + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "2c907113fd2c50edde60425c561ab8ca25192b1b", + "subject": "test(fts): cover storage-v2 interruption/reopen + acceptance matrix (#31)", + "parents": [ + "b86e4f526ec377f7f958dc21ddaac87238882f19" + ], + "is_merge": false, + "patch_id": "8be42f87431ece49aef3ef6eda2ad8facc6b629e", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "f887f44fa2d27c7ec4132fe70d337f7975fcde63", + "subject": "docs(research): record storage-v2 settlement implementation (#31)", + "parents": [ + "2c907113fd2c50edde60425c561ab8ca25192b1b" + ], + "is_merge": false, + "patch_id": "36092365b27afdd43694a21941d8b1305fb7d4a7", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "180ae82a2d7ec34a099665d68719c8579986d693", + "subject": "test(fts): pin structural refusal branches (#31)", + "parents": [ + "f887f44fa2d27c7ec4132fe70d337f7975fcde63" + ], + "is_merge": false, + "patch_id": "a6766363f406ec162858de31b5d44c20a81f94ab", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "1d6d73f3bb8ffeb599799c05b6e853da1758b4db", + "subject": "refactor(fts): settle review-round findings (#31)", + "parents": [ + "180ae82a2d7ec34a099665d68719c8579986d693" + ], + "is_merge": false, + "patch_id": "dbc62ce587beeee1e059967839673e3aaa6e7661", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "0fafc1dd7b58f15982ce2833de2bc8826a1e116f", + "subject": "test(fts): pin mixed-capability optimize availability (#31)", + "parents": [ + "1d6d73f3bb8ffeb599799c05b6e853da1758b4db" + ], + "is_merge": false, + "patch_id": "59e36add923089ed523051231c1299b4abf2d90d", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "67d4f719d6b0717be024861ae2756fa49d6f1315", + "subject": "fix(fts): optimize-available sees any actionable blocker (#31)", + "parents": [ + "0fafc1dd7b58f15982ce2833de2bc8826a1e116f" + ], + "is_merge": false, + "patch_id": "6e1e369dc56114dd292a0e4b3bd2e5416e3af4a5", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "0ff8583e91c838088fde6cb55ba0488cf5a0ee93", + "subject": "docs(research): fix settlement test count in validation note (#31)", + "parents": [ + "67d4f719d6b0717be024861ae2756fa49d6f1315" + ], + "is_merge": false, + "patch_id": "baae4280be968b7103ce48254bb258f2b197b653", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + } + ], + "merge_events": [ + { + "sha": "276d497764feb7d4a71f1424ed44b8958da63b16", + "subject": "Merge pull request #78 from Skywind5487/feat/31-storage-v2-settlement", + "parents": [ + "9d140c8594c67ed37729b190fd3733508d0d770c", + "0ff8583e91c838088fde6cb55ba0488cf5a0ee93" + ], + "changed_files": [], + "pr_refs": [ + "78" + ] + } + ], + "affected_files": [ + "docs/research/issue-31-storage-v2-settlement.md", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_fts_storage_v2_settlement.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "31", + "78" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_storage_v2_settlement.py.", + "Frozen upstream has no session six-index storage-v2 settlement state machine." + ], + "behavioral_contracts": [ + "One predicate defines required-index settlement; startup and foreground paths use it.", + "Incomplete or interrupted required settlement refuses serving; reopen/resume reaches an explicit terminal state.", + "Optional indexes do not silently become required blockers." + ] + }, + { + "id": "capability:session-fts-lifecycle", + "record_type": "provenance_bucket", + "subject": "feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27)", + "commits": [ + { + "sha": "00e680a8cb22e251f351b9f140b0679c4f96dabc", + "subject": "feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27)", + "parents": [ + "919f4469e832bc2b38bba0ea5af26b842bf91acd" + ], + "is_merge": false, + "patch_id": "4cc0cf6fd0285b48b07de0d623e5b6f71c89ced2", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py", + "tests/test_hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1", + "subject": "feat(fts): registry-driven health probes + trigger inventory/convergence (#27)", + "parents": [ + "00e680a8cb22e251f351b9f140b0679c4f96dabc" + ], + "is_merge": false, + "patch_id": "c03104d48d06f2c67ded35771f87f567dc9772cf", + "changed_files": [ + "hermes_state.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py", + "tests/test_hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "474b88fe76e18dfcf397f11b3de6f069abac4a4c", + "subject": "fix(fts): registry-driven offline + destructive repair covers session indexes (#27)", + "parents": [ + "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1" + ], + "is_merge": false, + "patch_id": "59a851149da5001ab1a18c3ad5c8ba10df56d4c2", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "f9ade6baff7f236b6b9401932c61bc0400375664", + "subject": "feat(fts): read-only session capability discovery + shared rebuild-lane iteration (#27)", + "parents": [ + "474b88fe76e18dfcf397f11b3de6f069abac4a4c" + ], + "is_merge": false, + "patch_id": "d013bec5f0358ab899f7993e871a3093a7116025", + "changed_files": [ + "hermes_state.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "e64ad007b459871af42e312bc5dffd2da92ac900", + "subject": "test(fts): six-index regression matrix for maintenance/repair/read-only/degraded-runtime (#27)", + "parents": [ + "f9ade6baff7f236b6b9401932c61bc0400375664" + ], + "is_merge": false, + "patch_id": "0a5b70525caec36a605aae57384aacac5b8e90c1", + "changed_files": [ + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "bdd9d699f6dc13b32852a078c1ecf5664bcb837d", + "subject": "docs(fts): record six-index unified lifecycle implementation for #27", + "parents": [ + "e64ad007b459871af42e312bc5dffd2da92ac900" + ], + "is_merge": false, + "patch_id": "02810363d2c8be19088f78ed7475b5d62f6e6924", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "0400c66f072d0f319331ea105cd8f7e059975388", + "subject": "refactor(fts): apply review round \u2014 drop dead lane keys, merge trigger-drop + CJK quarantine helpers, remove dead _FTS_TRIGGERS (#27)", + "parents": [ + "bdd9d699f6dc13b32852a078c1ecf5664bcb837d" + ], + "is_merge": false, + "patch_id": "7e550cd252dbc36097b938f127f97b9b731c3185", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "75223d19544ceb73cf24fb859fc0780ed9a099a5", + "subject": "docs(fts): record review round 1 for #27", + "parents": [ + "0400c66f072d0f319331ea105cd8f7e059975388" + ], + "is_merge": false, + "patch_id": "f9316ca0aa136778ac398a53a627d57e32fd4f4a", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec", + "subject": "fix(fts): reuse #30 ownership classifier in offline/global paths + read-only CJK worker fix (#27)", + "parents": [ + "75223d19544ceb73cf24fb859fc0780ed9a099a5" + ], + "is_merge": false, + "patch_id": "6ef28296f1a5c6fcf5fa7184766aed7bec89a165", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "dc1f153a71d025d903f255861da57f94d649ca37", + "subject": "docs(fts): record review round 2 for #27 unified FTS lifecycle", + "parents": [ + "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec" + ], + "is_merge": false, + "patch_id": "49b9b7ecabfb5e7fa7fee5a2ce8b127141b6155c", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a", + "subject": "fix(fts): read-only trigram discovery gates on full #30 namespace ownership (#27)", + "parents": [ + "dc1f153a71d025d903f255861da57f94d649ca37" + ], + "is_merge": false, + "patch_id": "3990d58681775d1e2600ae6aa742605ec0959bdd", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d", + "subject": "docs(fts): record review round 3 for #27 unified FTS lifecycle", + "parents": [ + "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a" + ], + "is_merge": false, + "patch_id": "5a24d3849b9501c6a79c01ee1a114b0a71f1e8bd", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "3bc7d3f58f808e269675404c9bbeada467b00e98", + "subject": "refactor(fts): ponytail pass \u2014 drop redundant tests, shrink review history + comments (#27)", + "parents": [ + "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d" + ], + "is_merge": false, + "patch_id": "fa519cb6863f833f9d6e38617139dc13eb873437", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md", + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "d6a4d70483623cc3fad4eea8c96754d7d637d02c", + "subject": "fix(fts): read-only trigram serving requires a complete trigger set (#27)", + "parents": [ + "3bc7d3f58f808e269675404c9bbeada467b00e98" + ], + "is_merge": false, + "patch_id": "b517dd7e0ef43f48969fad2401b82585453001ea", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "0cf4cd0baffb68b571a44f2a39d3bf817cd38348", + "subject": "docs(fts): record review round 4 for #27 unified FTS lifecycle", + "parents": [ + "d6a4d70483623cc3fad4eea8c96754d7d637d02c" + ], + "is_merge": false, + "patch_id": "2141bb1e322a2a97fc4e6a3e8c49f3442f440876", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "9d140c8594c67ed37729b190fd3733508d0d770c", + "subject": "Merge pull request #76 from Skywind5487/feat/27-unified-fts-lifecycle", + "parents": [ + "919f4469e832bc2b38bba0ea5af26b842bf91acd", + "0cf4cd0baffb68b571a44f2a39d3bf817cd38348" + ], + "changed_files": [], + "pr_refs": [ + "76" + ] + } + ], + "affected_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py", + "tests/test_hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "27", + "76" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_lifecycle_registry.py.", + "Frozen upstream has message FTS primitives but no equivalent session six-index lifecycle boundary." + ], + "behavioral_contracts": [ + "The registry covers messages_fts, messages_fts_trigram, messages_fts_cjk, sessions_fts, sessions_fts_cjk, and sessions_fts_trigram.", + "Maintenance, health, read-only discovery, repair, and degraded runtime iterate the same descriptors.", + "Unknown or incomplete trigger state fails closed for serving." + ] + }, + { + "id": "capability:memory-trim-diagnostics", + "record_type": "provenance_bucket", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold", + "commits": [ + { + "sha": "04f1af72be078cef69de538f1519f93a73088b0d", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold", + "parents": [ + "2ac803bd949f0aba96c0d4d500edd2ad65aa3036" + ], + "is_merge": false, + "patch_id": "b793dd29722b01e260b13a1b2e3be1c2708c1071", + "changed_files": [ + "hermes_cli/mem_trim.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_cli/mem_trim.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "KEEP", + "confidence": "medium", + "evidence": [ + "Frozen fork splits gc_ms and trim_ms, records VmSwap, and measures malloc_info fragmentation.", + "Frozen upstream has basic RSS/RssAnon snapshots and trim logging but not the fork's attribution diagnostics." + ], + "behavioral_contracts": [ + "gc_ms versus trim_ms identifies the freeze mechanism without changing the policy decision.", + "Fragmentation and VmSwap are best-effort diagnostics and never block memory recovery." + ] + }, + { + "id": "capability:headroom-retrieval", + "record_type": "provenance_bucket", + "subject": "feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin", + "commits": [ + { + "sha": "0a4b567ff08776a3a10ee7a32d37332d873f20b2", + "subject": "feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin", + "parents": [ + "88d1d6206f399c134d1f4c0b7db27733aaa3c50c" + ], + "is_merge": false, + "patch_id": "07479905dc72c5af558b5f005436aae7a06883f7", + "changed_files": [ + "plugins/headroom/__init__.py", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "parents": [ + "0a4b567ff08776a3a10ee7a32d37332d873f20b2" + ], + "is_merge": false, + "patch_id": "0ca8a64059c02cff35fe7cf0ebdf21fae3357f35", + "changed_files": [ + "plugins/headroom/__init__.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "ff4df5b71e1557660dbe994eb5569983f57c9901", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "parents": [ + "0a4b567ff08776a3a10ee7a32d37332d873f20b2" + ], + "is_merge": false, + "patch_id": "0ca8a64059c02cff35fe7cf0ebdf21fae3357f35", + "changed_files": [ + "plugins/headroom/__init__.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "b527e4df996b859356c0c48c2b9c9eae4c74c4dc", + "subject": "fix(headroom): auto-enable headroom_retrieve tool when compression is active", + "parents": [ + "ff4df5b71e1557660dbe994eb5569983f57c9901" + ], + "is_merge": false, + "patch_id": "dc4c2ce5d3bce995521b06c29054b914852ee826", + "changed_files": [ + "hermes_cli/tools_config.py", + "plugins/headroom/plugin.yaml", + "pyproject.toml", + "uv.lock" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "0b4e7601227a23bc653d0d3018a3a9591d02f2a1", + "subject": "fix: headroom_retrieve tool schema \u2014 add description and parameters wrapper", + "parents": [ + "b527e4df996b859356c0c48c2b9c9eae4c74c4dc" + ], + "is_merge": false, + "patch_id": "a0f94a678e9036aeb39b681623ee5764600672d7", + "changed_files": [ + "plugins/headroom/__init__.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "516d739f64a95a4f380b899fbb9a349d750fc2aa", + "subject": "Merge branch 'feat/headroom-retrieval-toolset-autoenable' into dev", + "parents": [ + "c1a3e16c32896ea2d469536c657814049c29bec6", + "0b4e7601227a23bc653d0d3018a3a9591d02f2a1" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [ + "hermes_cli/tools_config.py", + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "pyproject.toml", + "tests/plugins/test_headroom_plugin.py", + "uv.lock" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in plugins/headroom, tools_config.py, plugin.yaml and plugin tests.", + "No equivalent retrieval tool is present in frozen upstream." + ], + "behavioral_contracts": [ + "The retrieval tool has a stable schema.", + "It is auto-enabled only when compression is active and returns bounded context.", + "Registration failures are explicit and warning-visible." + ] + }, + { + "id": "capability:session-fts-cjk", + "record_type": "provenance_bucket", + "subject": "fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search", + "commits": [ + { + "sha": "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "subject": "fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search", + "parents": [ + "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f" + ], + "is_merge": false, + "patch_id": "90547021582ed1ce1d9c37bda280a80d647558e6", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "3053abf3b039a5b4c23637597cb076f2339250fb", + "subject": "fix: let all CJK queries use simple tokenizer; cache lineage resolves", + "parents": [ + "3de538d32a3c076929c1d7c173dd77e4055100f9" + ], + "is_merge": false, + "patch_id": "5446586b216cfe21c08c62a3b49d1d951af35ea4", + "changed_files": [ + "hermes_state.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "6311e77e27f4fd4009c73d0df16abebf56121f4a", + "subject": "docs(research): map CJK session metadata FTS lifecycle for #33", + "parents": [ + "e94f2630a50d7585f78cfc06365753c033113cb9" + ], + "is_merge": false, + "patch_id": "f3deefc9bde4c1facfe27477a6ef48f5885e3925", + "changed_files": [ + "docs/research/issue-33-cjk-session-metadata-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "3e23375f7934e4315d45860e6992171fb5609c5c", + "subject": "test(session-fts): RED contract for CJK session metadata lifecycle (#26)", + "parents": [ + "6311e77e27f4fd4009c73d0df16abebf56121f4a" + ], + "is_merge": false, + "patch_id": "15678e6d9746a859d981383597c72d3038eadf46", + "changed_files": [ + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + { + "sha": "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7", + "subject": "feat(session-fts): external-content CJK metadata DDL + capability/quarantine (#26)", + "parents": [ + "3e23375f7934e4315d45860e6992171fb5609c5c" + ], + "is_merge": false, + "patch_id": "a97596e01ae3dcfbfacf20ae77704385338130b1", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + { + "sha": "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5", + "subject": "feat(session-fts): plug CJK session rebuild into the generic engine (#26)", + "parents": [ + "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7" + ], + "is_merge": false, + "patch_id": "267b89f092edf92cac9805b7d81d32c8aa0fbc81", + "changed_files": [ + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + { + "sha": "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128", + "subject": "feat(session-fts): CJK metadata candidate seam + all-3-field search (#26)", + "parents": [ + "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5" + ], + "is_merge": false, + "patch_id": "17de1b8d50273afbc3e1c4b59af7c5aabc8d25fe", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + { + "sha": "83431f775a9e3798611e03b16a2f7d9a7ac74a57", + "subject": "docs(design): document the #26 CJK session metadata FTS variant", + "parents": [ + "4270ea5b9a903d0dcf692db2365875ac5b3fe319" + ], + "is_merge": false, + "patch_id": "4931fa1241c6fda8361f416be00c5cfb6f4c0568", + "changed_files": [ + "docs/design/session-metadata-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "8efead2600a3f932f9881b53cd0c7eabc755f82f", + "subject": "fix(session-fts): address #26 code-review findings", + "parents": [ + "83431f775a9e3798611e03b16a2f7d9a7ac74a57" + ], + "is_merge": false, + "patch_id": "b10a9c6b1a918355e6b6227802b594659fc393f7", + "changed_files": [ + "docs/design/session-metadata-fts.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_search.py", + "tests/hermes_cli/test_session_recovery.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "6b3402ea05566fa1553a93aceb285eb517d7e67d", + "subject": "fix(session-fts): three lifecycle/capability seams for CJK session FTS (round-3 review)", + "parents": [ + "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2" + ], + "is_merge": false, + "patch_id": "739564b9c7167f08cd333d370571a3cd6eee4b9a", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "0eee69ef43f16c63f29db414e1acb40253212125", + "subject": "fix(session-fts): run CJK guard+MATCH in one SQLite snapshot (PR #65 P1)", + "parents": [ + "6b3402ea05566fa1553a93aceb285eb517d7e67d" + ], + "is_merge": false, + "patch_id": "56e4c8cbae6fd638c7dd752e22c786b2b15ea542", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "65" + ] + }, + { + "sha": "6447a52cd994bf30c2811814f21095d12aba83ae", + "subject": "fix(state): short-circuit CJK-unservable to direct LIKE + single compression edge", + "parents": [ + "b97d00e7319e5147d569519b6a34ef63c6635551" + ], + "is_merge": false, + "patch_id": "79b6a387eaf7db3bd4f797dc1a0a0a94e83c49b3", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "tests/test_session_metadata_picker_routing.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "bdf2fc218264538c4f3238b58532488fe665ff9e", + "subject": "Merge pull request #65 from Skywind5487/fts/session-cjk-highwater", + "parents": [ + "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "0eee69ef43f16c63f29db414e1acb40253212125" + ], + "changed_files": [], + "pr_refs": [ + "65" + ] + } + ], + "affected_files": [ + "docs/design/session-metadata-fts.md", + "docs/research/issue-33-cjk-session-metadata-fts-lifecycle.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/hermes_cli/test_session_recovery.py", + "tests/test_session_metadata_cjk_fts.py", + "tests/test_session_metadata_picker_routing.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "26", + "65" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_cjk_fts.py.", + "Frozen upstream has no session CJK metadata index or equivalent optional lifecycle." + ], + "behavioral_contracts": [ + "CJK search covers title, id, and display_name through external-content FTS.", + "Unavailable tokenizer/index state degrades safely without hiding the base path.", + "Guard and MATCH run against one SQLite snapshot; rebuild is independent and resumable." + ] + }, + { + "id": "capability:lifecycle-sqlite-telemetry", + "record_type": "provenance_bucket", + "subject": "feat: add lifecycle and SQLite observability telemetry", + "commits": [ + { + "sha": "176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "subject": "feat: add lifecycle and SQLite observability telemetry", + "parents": [ + "237176ed1d973910972984ba83d876d01c00f3db" + ], + "is_merge": false, + "patch_id": "124834046966eb0142fabdd8849eafdc9df72403", + "changed_files": [ + "agent/conversation_compression.py", + "agent/conversation_loop.py", + "agent/diagnostic_config.py", + "agent/kernel_telemetry.py", + "agent/lifecycle_telemetry.py", + "agent/sqlite_native_telemetry.py", + "agent/tool_executor.py", + "agent/turn_context.py", + "docs/observability/session-db-api-handoff.md", + "gateway/run.py", + "gateway/stream_consumer.py", + "hermes_cli/config.py", + "hermes_state.py", + "plugins/memory/holographic/__init__.py", + "plugins/platforms/discord/adapter.py", + "scripts/hermes_kernel_trace.py", + "tests/agent/test_lifecycle_telemetry.py", + "tests/agent/test_tool_lifecycle_telemetry.py", + "tests/gateway/test_discord_delivery_lifecycle_telemetry.py", + "tests/gateway/test_stream_lifecycle_telemetry.py", + "tests/plugins/memory/test_holographic_prefetch_gate.py", + "tests/test_machine_health_collector.py", + "tests/test_optional_cjk_tokenizer_fallback.py", + "tests/test_session_db_lock_telemetry.py", + "tests/test_sqlite_kernel_telemetry.py", + "tests/test_sqlite_owner_telemetry.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "agent/conversation_compression.py", + "agent/conversation_loop.py", + "agent/diagnostic_config.py", + "agent/kernel_telemetry.py", + "agent/lifecycle_telemetry.py", + "agent/sqlite_native_telemetry.py", + "agent/tool_executor.py", + "agent/turn_context.py", + "docs/observability/session-db-api-handoff.md", + "gateway/run.py", + "gateway/stream_consumer.py", + "hermes_cli/config.py", + "hermes_state.py", + "plugins/memory/holographic/__init__.py", + "plugins/platforms/discord/adapter.py", + "scripts/hermes_kernel_trace.py", + "tests/agent/test_lifecycle_telemetry.py", + "tests/agent/test_tool_lifecycle_telemetry.py", + "tests/gateway/test_discord_delivery_lifecycle_telemetry.py", + "tests/gateway/test_stream_lifecycle_telemetry.py", + "tests/plugins/memory/test_holographic_prefetch_gate.py", + "tests/test_machine_health_collector.py", + "tests/test_optional_cjk_tokenizer_fallback.py", + "tests/test_session_db_lock_telemetry.py", + "tests/test_sqlite_kernel_telemetry.py", + "tests/test_sqlite_owner_telemetry.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "medium", + "evidence": [ + "Survives across lifecycle_telemetry.py, sqlite_native_telemetry.py, turn_context.py, gateway code and tests.", + "Frozen upstream comparison was not completed per telemetry surface; absence is not treated as proof." + ], + "behavioral_contracts": [ + "Important boundaries emit structured telemetry rather than only ad-hoc logs.", + "SQLite lock/owner and stream/tool failures remain diagnosable." + ] + }, + { + "id": "capability:request-transform-hook", + "record_type": "provenance_bucket", + "subject": "feat: add transform_api_request plugin hook for full-payload request transformation", + "commits": [ + { + "sha": "296d9c6e2e5a6f852344ad8fa9b90f5687912be1", + "subject": "feat: add transform_api_request plugin hook for full-payload request transformation", + "parents": [ + "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71" + ], + "is_merge": false, + "patch_id": "ff3b268ee596e2ce358d5d1df44c76d54b5d88d7", + "changed_files": [ + "agent/conversation_loop.py", + "hermes_cli/hooks.py", + "hermes_cli/plugins.py", + "tests/run_agent/test_run_agent.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "agent/conversation_loop.py", + "hermes_cli/hooks.py", + "hermes_cli/plugins.py", + "tests/run_agent/test_run_agent.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in agent/conversation_loop.py, hermes_cli/hooks.py, hermes_cli/plugins.py and run-agent tests.", + "Frozen upstream has pre_llm_call but not a full-payload transform hook at dispatch." + ], + "behavioral_contracts": [ + "transform_api_request receives and returns the complete payload at a documented boundary.", + "The hook is optional and preserves the request when absent.", + "Hook errors are explicit and do not dispatch partial data." + ] + }, + { + "id": "capability:session-fts-trigram", + "record_type": "provenance_bucket", + "subject": "feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch", + "commits": [ + { + "sha": "37811327cdc65c85c4b0bd565b1cdb3a4590dd91", + "subject": "feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch", + "parents": [ + "a34da2c31ca60f9b5280558c514a3a1880035036" + ], + "is_merge": false, + "patch_id": "9c276d00c28333451c952522cd07793dc39f3a1f", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "subject": "docs(research): map normalized session trigram FTS", + "parents": [ + "6311e77e27f4fd4009c73d0df16abebf56121f4a" + ], + "is_merge": false, + "patch_id": "b9c2c784c05bb406213054d376b6c98bd2feb8e2", + "changed_files": [ + "docs/research/issue-34-normalized-session-metadata-trigram-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "ad0c45f0924349f6f0453d4941c3d76ad5258cdc", + "subject": "test(fts): pin modern session trigram and legacy-simple states", + "parents": [ + "e94f2630a50d7585f78cfc06365753c033113cb9" + ], + "is_merge": false, + "patch_id": "6899521fc12538eb9dc0129d2863bc3b87f8bb92", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "48b04dae36d6577b06de0efc67ebe1eb1a479d4c", + "subject": "feat(fts): add normalized external-content session trigram index (#30)", + "parents": [ + "ad0c45f0924349f6f0453d4941c3d76ad5258cdc" + ], + "is_merge": false, + "patch_id": "b8e035ae4b6b1c9e4e5cce7b1190a290b5a14cd5", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "6f82bcbb3c5f714148a17da47577e862493a55d6", + "subject": "test(fts): cover normalized session trigram end to end (#30)", + "parents": [ + "48b04dae36d6577b06de0efc67ebe1eb1a479d4c" + ], + "is_merge": false, + "patch_id": "cdc779c773f3856e71e403ba1787270dd2bd16ba", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "0f29f1454ea2227229e4056d66ed09f749a06e46", + "subject": "docs(research): document normalized session trigram FTS implementation (#30)", + "parents": [ + "6f82bcbb3c5f714148a17da47577e862493a55d6" + ], + "is_merge": false, + "patch_id": "cbaa4bf962d983e59eb764e6cd28798f689e19c1", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3", + "subject": "fix(fts): clear unfulfillable trigram claim on tokenizer-less host + de-dup shared seams (#30)", + "parents": [ + "0f29f1454ea2227229e4056d66ed09f749a06e46" + ], + "is_merge": false, + "patch_id": "0ffb111eb64fc8a9e80a3373f97e76ac3b796b76", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "252920f02442b68391fcafba35bef2c9567e9ab8", + "subject": "style(fts): consolidate session trigram ensure epilogue + spec-driven transition columns (#30)", + "parents": [ + "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3" + ], + "is_merge": false, + "patch_id": "1231df15565fbd033918e08b660707cbca26ea50", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "4483194b81495dab9b3c4c282c08adad89e0f2d9", + "subject": "fix(fts): classify session trigram schema by exact logical columns + VIEW projection (#30)", + "parents": [ + "252920f02442b68391fcafba35bef2c9567e9ab8" + ], + "is_merge": false, + "patch_id": "be11555049e9ec52dd80b13d2acd5d918c4fe06b", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "bfa928d53da7c61814816c10f83fef75bfef7e43", + "subject": "fix(fts): require canonical source VIEW + FTS5 root for modern trigram identity (#30)", + "parents": [ + "4483194b81495dab9b3c4c282c08adad89e0f2d9" + ], + "is_merge": false, + "patch_id": "d8134dfc7967102cd493d1858ec78ec46fae13ac", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "cc5261ce775c8db6a7099d411f16030d24e71f2f", + "subject": "fix(fts): classify legacy session trigram by DDL, never PRAGMA table_info (#30)", + "parents": [ + "bfa928d53da7c61814816c10f83fef75bfef7e43" + ], + "is_merge": false, + "patch_id": "1866b109815970cec2afd7bfe33acc92393e6adf", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "e33b533e1d2421fb18941463b6fe51752a8ad345", + "subject": "fix(fts): classify modern session trigram by DDL, never PRAGMA table_info (#30)", + "parents": [ + "cc5261ce775c8db6a7099d411f16030d24e71f2f" + ], + "is_merge": false, + "patch_id": "6a3e15bffb010d61a4cd01938a1857fdbde253d6", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "b5155410abbf04c1fc4bb433ae3f5e546f5bf426", + "subject": "fix(fts): gate trigram source VIEW ensure on source compatibility (#30)", + "parents": [ + "e33b533e1d2421fb18941463b6fe51752a8ad345" + ], + "is_merge": false, + "patch_id": "436fcf2cc4247cafe5e93960272ed36328ac2755", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "9aad13bcad68a292f708fe30698405c2016b2626", + "subject": "fix(fts): classify same-name root VIEW as unknown, not absent (#30)", + "parents": [ + "b5155410abbf04c1fc4bb433ae3f5e546f5bf426" + ], + "is_merge": false, + "patch_id": "23a52086a686f6df207c1790e01f0fe0ed29d666", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "3172c9f4611cc2b872f2083829577cc73152f9dc", + "subject": "fix(fts): exact shadow allowlist + classify same-name root index as unknown (#30)", + "parents": [ + "9aad13bcad68a292f708fe30698405c2016b2626" + ], + "is_merge": false, + "patch_id": "1c240e6ff04b0e1ea6c47a63c818feca035cf6f8", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "6467a30563fb1da2bd5c1f42dc7cd1f574697d31", + "subject": "fix(fts): hardening pass \u2014 literal-safe identity, trigger/shadow ownership, demotion CAS, stale lifecycle, serving gates, empty-claim, query cap (#30)", + "parents": [ + "3172c9f4611cc2b872f2083829577cc73152f9dc" + ], + "is_merge": false, + "patch_id": "a1e6155cc7099629cb10f15c9ac2f517ddb604fa", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c", + "subject": "fix(fts): harden session trigram transition namespaces (#30)", + "parents": [ + "6467a30563fb1da2bd5c1f42dc7cd1f574697d31" + ], + "is_merge": false, + "patch_id": "a5bf42fb900263d57e79ad16677f7a04305dd1f3", + "changed_files": [ + "hermes_state.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "72388ff87f0baf99910edefab2b2fc2e00b40284", + "subject": "fix(fts): preserve session trigram claims across capability handoff (#30)", + "parents": [ + "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c" + ], + "is_merge": false, + "patch_id": "5cc7da92fc79657a17848c9d582f163fe8e1be12", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "0c02b83d4d8702267481a5f196606e19e3d303cc", + "subject": "fix(fts): gate session trigram mutations on durable ownership (#30)", + "parents": [ + "72388ff87f0baf99910edefab2b2fc2e00b40284" + ], + "is_merge": false, + "patch_id": "424d76b37989b6d5d3a296b2ce1ad21ec0078a86", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "a9c1b2d11bab435cda80fcfc81fc223d210b4755", + "subject": "fix(fts): serve session trigram candidates from one snapshot (#30)", + "parents": [ + "0c02b83d4d8702267481a5f196606e19e3d303cc" + ], + "is_merge": false, + "patch_id": "4247c3fcb1e33dc9ec06927b5427275499967715", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48", + "subject": "test(fts): drop fork-only legacy simple convergence tests (#30)", + "parents": [ + "a9c1b2d11bab435cda80fcfc81fc223d210b4755" + ], + "is_merge": false, + "patch_id": "523ef02eeb02a99000aec84b6410a97b9cb444a3", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "c7163001f23feb31f94fec1ebb3c41badaebdb97", + "subject": "refactor(fts): drop fork-only legacy simple demotion lane (#30)", + "parents": [ + "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48" + ], + "is_merge": false, + "patch_id": "3bd484e442014f2fdf2a7184ebab188f6a9defb3", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "6f534c8760a30a318ae0d874b7a6323f5f0337df", + "subject": "docs(fts): record scope correction and legacy lane removal (#30)", + "parents": [ + "c7163001f23feb31f94fec1ebb3c41badaebdb97" + ], + "is_merge": false, + "patch_id": "9cfd3d181f8e6bb79358c9dfd5035ca53184e986", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "10e3419d10e938c979c701246457cbd6f9c10ad4", + "subject": "test(fts): drop round-11 CAS and shadow-preflight tests (#30)", + "parents": [ + "6f534c8760a30a318ae0d874b7a6323f5f0337df" + ], + "is_merge": false, + "patch_id": "7af1a6ec209a2ef1077276829e70eca10d18edd1", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "69591fe659774a4e61a3f754211f5602e96a7381", + "subject": "fix(fts): quarantine healthy modern target on no-trigram runtime; drop unsupported hardening (#30)", + "parents": [ + "10e3419d10e938c979c701246457cbd6f9c10ad4" + ], + "is_merge": false, + "patch_id": "cd5f71e16d3d57d527193b063c641f85a6e907c0", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea", + "subject": "docs(fts): record round-12 re-review and subtractive hardening removal (#30)", + "parents": [ + "69591fe659774a4e61a3f754211f5602e96a7381" + ], + "is_merge": false, + "patch_id": "8bbd416b4080e3c255c84a1e7498775b58e47e5e", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "783d3fa59ae28010368368e3dafddc19750f9b55", + "subject": "test(recovery): pin session-trigram derived markers as generated meta (#79)", + "parents": [ + "276d497764feb7d4a71f1424ed44b8958da63b16" + ], + "is_merge": false, + "patch_id": "3b6d866e33eb926b4f6be293edcc411ea6cd5077", + "changed_files": [ + "tests/hermes_cli/test_session_recovery.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + }, + { + "sha": "4aefa3abbbe4f9c3eba29988fa772e45d70000f9", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)", + "parents": [ + "783d3fa59ae28010368368e3dafddc19750f9b55" + ], + "is_merge": false, + "patch_id": "de138bf28952f63a6aef45822350031081923296", + "changed_files": [ + "hermes_cli/session_recovery.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + }, + { + "sha": "d4c9a165c5abe6cf8c0503005b18e55de58e28cc", + "subject": "docs(research): record session-trigram recovery marker fix (#79)", + "parents": [ + "4aefa3abbbe4f9c3eba29988fa772e45d70000f9" + ], + "is_merge": false, + "patch_id": "411f66a119ca4c46d97a06d4085792041b171bda", + "changed_files": [ + "docs/research/issue-79-session-recovery-trigram-markers.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + }, + { + "sha": "f17ab58979753a9ee342d258595e8d076ef2f309", + "subject": "test(recovery): guard verifier detection of leftover session-trigram markers (#79)", + "parents": [ + "d4c9a165c5abe6cf8c0503005b18e55de58e28cc" + ], + "is_merge": false, + "patch_id": "7a4972e80b9db112cd5af724eb72fb13a2db5dd2", + "changed_files": [ + "tests/hermes_cli/test_session_recovery.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + } + ], + "merge_events": [ + { + "sha": "f18b3c90c2309ee7616010f99c1c927c9f05013f", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/session-trigram-external-content", + "parents": [ + "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea", + "2f90c254d524d618b1c866a10bb519f2c1b6f5dc" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "919f4469e832bc2b38bba0ea5af26b842bf91acd", + "subject": "feat(fts): normalized external-content session trigram metadata index (#30)", + "parents": [ + "2f90c254d524d618b1c866a10bb519f2c1b6f5dc", + "f18b3c90c2309ee7616010f99c1c927c9f05013f" + ], + "changed_files": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "4e5ad5c2230300d1ffae84b089ffc70e368c8a23", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)", + "parents": [ + "276d497764feb7d4a71f1424ed44b8958da63b16", + "f17ab58979753a9ee342d258595e8d076ef2f309" + ], + "changed_files": [], + "pr_refs": [ + "79" + ] + } + ], + "affected_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "docs/research/issue-34-normalized-session-metadata-trigram-fts.md", + "docs/research/issue-79-session-recovery-trigram-markers.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/hermes_cli/test_session_recovery.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "30", + "79" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_trigram_fts.py.", + "Frozen upstream has no sessions_fts_trigram external-content index; generic message trigram is not equivalent." + ], + "behavioral_contracts": [ + "The external-content source normalizes title/display_name and keeps raw id searchable.", + "Serving requires complete trigger/namespace ownership; unknown same-name objects fail closed.", + "Recovery markers support resumable rebuild without treating a partial index as healthy." + ] + }, + { + "id": "capability:session-search-lineage", + "record_type": "provenance_bucket", + "subject": "perf: reduce SELECT * in get_compression_lineage to 4 columns", + "commits": [ + { + "sha": "3de538d32a3c076929c1d7c173dd77e4055100f9", + "subject": "perf: reduce SELECT * in get_compression_lineage to 4 columns", + "parents": [ + "433a49f66b447f41fdd488dc4858a07c7cd7154d" + ], + "is_merge": false, + "patch_id": "c93153ba8a766a189a6fd3c9ae44c17ef1b9c5cd", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "6fa6c557257175f26c1689799d352fdf948cb787", + "subject": "fix: replace SELECT * with specific columns in get_anchored_view and get_messages_around", + "parents": [ + "cc2531fbc6df8fdb34fca0b096b798eb53f970dd" + ], + "is_merge": false, + "patch_id": "8412299a818e0b42f7d6911c180cad3da0710f8c", + "changed_files": [ + "hermes_state.py", + "tests/hermes_state/test_get_messages_around.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "2732c47e28fbf7aaea97bd8c5cf82045a4c34159", + "subject": "wip(session-search): move winner selection into SQL", + "parents": [ + "176646d2cd6c95fa49b9414f21ed9e781b0aaa84" + ], + "is_merge": false, + "patch_id": "ad8d732bb386962695417cd36f99490d9497a1c4", + "changed_files": [ + "hermes_state.py", + "tests/test_session_search_sql_winners.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "2d2bad204ec644455ad1273f2934f388eb4111dd", + "subject": "fix(session-search): defer winner snippets", + "parents": [ + "2732c47e28fbf7aaea97bd8c5cf82045a4c34159" + ], + "is_merge": false, + "patch_id": "def0769bc836f46501f776b616908b3bfb592aae", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32", + "subject": "fix(session-search): ranked Top-N pre-limit for relevance sort", + "parents": [ + "2d2bad204ec644455ad1273f2934f388eb4111dd" + ], + "is_merge": false, + "patch_id": "2e150449ebe907705459b4930b499d4dd7e49505", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "d72f99eb1b897dd29a46692a310aa15b1bfd77e8", + "subject": "docs(research): index session-lineage research", + "parents": [ + "9b25b0c8bd7408eaf2398529b6a04ed1a068b892" + ], + "is_merge": false, + "patch_id": "e1a04706478dc2a890dba533afd92cc9c99fffa1", + "changed_files": [ + "research/session-lineage/README.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "8838d16060bb7610c6d7ad3697f384df3edb70c1", + "subject": "test(search): RED contracts for #68 compression-lineage resolver", + "parents": [ + "bdf2fc218264538c4f3238b58532488fe665ff9e" + ], + "is_merge": false, + "patch_id": "c3542d1ed1f8a153f905fefb9b6c4c1cc8f1c3e4", + "changed_files": [ + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "46907bc8b55ba36ef73e0d96c10eccb9b28b0310", + "subject": "feat(search): compression-lineage resolver for #68 winner seam", + "parents": [ + "8838d16060bb7610c6d7ad3697f384df3edb70c1" + ], + "is_merge": false, + "patch_id": "da306b1612a426d054dfbeec5be2893fe1f53978", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "2f12b03079cb7ae28acf666d16cfd748e5eaac74", + "subject": "feat(session-search): tool parity + truncation contract for #68", + "parents": [ + "46907bc8b55ba36ef73e0d96c10eccb9b28b0310" + ], + "is_merge": false, + "patch_id": "9cee1fa8910525a439c281470ec59cc172e0f33d", + "changed_files": [ + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "2e1b2e64d7a452f524f703a99d68b1b110b93d3e", + "subject": "test(search): drop stale generic-parent oracle import after #68 flip", + "parents": [ + "2f12b03079cb7ae28acf666d16cfd748e5eaac74" + ], + "is_merge": false, + "patch_id": "506042112841967f593cc6cb1368e22cab1fde5e", + "changed_files": [ + "tests/test_session_search_sql_winners.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "a13d012e5b8736928662f27269d9f2a7cf84f0af", + "subject": "docs(session-storage): document #68 compression-lineage resolution", + "parents": [ + "2e1b2e64d7a452f524f703a99d68b1b110b93d3e" + ], + "is_merge": false, + "patch_id": "9f0b60b610bf34cd8cd86ca7724779d4810d27db", + "changed_files": [ + "website/docs/developer-guide/session-storage.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "66eb2fad76abf150043ffd899fbdfbd328aba2d0", + "subject": "fix(search): title/current share in-snapshot roots + compacted anchor fallback (#68 review)", + "parents": [ + "a13d012e5b8736928662f27269d9f2a7cf84f0af" + ], + "is_merge": false, + "patch_id": "932f7f87fefd133797c06f8fc051bfedc32fbfd9", + "changed_files": [ + "hermes_state_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "f32b51764e43e48195d10e62d64b195a052d4968", + "subject": "test(search): #68 review acceptance \u2014 title parity, compacted anchor, real B boundaries, snapshot, 10k, internal-K", + "parents": [ + "66eb2fad76abf150043ffd899fbdfbd328aba2d0" + ], + "is_merge": false, + "patch_id": "a750f9adc96a4ca3f1d2004f8353c443b9420c85", + "changed_files": [ + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "42c421f68b6556757c17b4dc78756cf31babd239", + "subject": "fix(search): distinct-owner candidates + title-only K=1 snapshot contract (#68 review round-2)", + "parents": [ + "f32b51764e43e48195d10e62d64b195a052d4968" + ], + "is_merge": false, + "patch_id": "a0684b71490f432735b53dd98c3edef3a7c41060", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "c81ab321ec4bb3d5a33429b28907cd5836e41789", + "subject": "fix(search): displayable-anchor ranking + drop unproven title on B-hit (#68 review round-3)", + "parents": [ + "42c421f68b6556757c17b4dc78756cf31babd239" + ], + "is_merge": false, + "patch_id": "3d8e178a16804038bb27736d649c1d0a0a92a814", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6", + "subject": "fix(search): don't gate exact-title on unrun content snapshot (#68 review round-4)", + "parents": [ + "c81ab321ec4bb3d5a33429b28907cd5836e41789" + ], + "is_merge": false, + "patch_id": "88241624668272f5662c662be321ba1515214ee9", + "changed_files": [ + "hermes_state_search.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "55dc24391f92d71d9e293c7990089075f2ff49c9", + "subject": "refactor(search): drop title/current lineage-proof protocol per #68 review round-5", + "parents": [ + "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6" + ], + "is_merge": false, + "patch_id": "a71f4989baf40f079979748453464dc6eb64647c", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "b2710666a29eed6fc46f3b6ce23c72f4dc766181", + "subject": "test(search): rename title==current test, correct misleading scope claim (#68 review final)", + "parents": [ + "55dc24391f92d71d9e293c7990089075f2ff49c9" + ], + "is_merge": false, + "patch_id": "f96724aea81c1b2c6d039696b95eec56335e6939", + "changed_files": [ + "tests/tools/test_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "1f5edc591353a0a65ec7aa2f02c6916fd67fd505", + "subject": "perf(state): narrow session listing before lineage hydration", + "parents": [ + "5882274ff6c868c24f9d36f3796de08e5de8a245" + ], + "is_merge": false, + "patch_id": "a147ecf6c85ea4f4e0483e02ae7baa638cf3e17f", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "a615feaea695123d1b3a832417a9a76554301af8", + "subject": "test(state): cover whole-store lineage visibility and pagination", + "parents": [ + "1f5edc591353a0a65ec7aa2f02c6916fd67fd505" + ], + "is_merge": false, + "patch_id": "776704c477343cd0a3efda03d9fe61c5c73d46ee", + "changed_files": [ + "tests/test_session_metadata_picker_routing.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "2f90c254d524d618b1c866a10bb519f2c1b6f5dc", + "subject": "Merge pull request #72 from Skywind5487/fix/68-compression-lineage-resolver", + "parents": [ + "bdf2fc218264538c4f3238b58532488fe665ff9e", + "b2710666a29eed6fc46f3b6ce23c72f4dc766181" + ], + "changed_files": [], + "pr_refs": [ + "72" + ] + } + ], + "affected_files": [ + "hermes_state.py", + "hermes_state_search.py", + "research/session-lineage/README.md", + "tests/hermes_state/test_get_messages_around.py", + "tests/test_session_metadata_picker_routing.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py", + "website/docs/developer-guide/session-storage.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "72" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "SPLIT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state_search.py and session-search tools/tests, including bounded winner hydration.", + "Frozen upstream has _lineage_root_id/basic lookup but not the stronger resolver, memo, B-boundary, or explicit truncation contract." + ], + "behavioral_contracts": [ + "Only positive compression edges are followed; branch/delegate markers and tool children do not become roots.", + "Missing/cyclic lineage fails closed; query-local memo/path compression is bounded by B=2000 successful uncached row fetches.", + "B exhaustion returns truncated/warning without poisoned memo; one snapshot, early-K and deferred hydration are preserved." + ] + }, + { + "id": "capability:outbound-code-fence-safety", + "record_type": "provenance_bucket", + "subject": "test: code fence tracking coverage for all send/split paths", + "commits": [ + { + "sha": "44afcc8d3f869c7780beb1bc0bece86df1e45cb2", + "subject": "test: code fence tracking coverage for all send/split paths", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "b895a539fdb73b927cacb2adbbb0a94a342a95b4", + "changed_files": [ + "tests/gateway/test_code_fence_tracking.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "47cc1764dc2c2c65cc83fe20500da939698d72d3", + "subject": "fix: close orphaned code fences on all send paths", + "parents": [ + "44afcc8d3f869c7780beb1bc0bece86df1e45cb2" + ], + "is_merge": false, + "patch_id": "430d612330245f9678d3de304083e690872ccf34", + "changed_files": [ + "gateway/platforms/base.py", + "gateway/stream_consumer.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "347442ddc80a2658582cb62dd268a0be024b1bcf", + "subject": "fix: escape triple-backtick in reasoning before wrapping in outer code block", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "53c0ea1134e01cc4feecbc1eb1c0a753beae0544", + "changed_files": [ + "gateway/run.py", + "gateway/stream_consumer.py", + "tests/gateway/test_escape_reasoning_fences.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "efd68fe044001c57c5d148a66469209589c344d9", + "subject": "fix: ensure balanced code fences after Discord edit_message brute-force truncation", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "e791c1b195b0e428fcb2f296a13a381aec9cb518", + "changed_files": [ + "plugins/platforms/discord/adapter.py", + "tests/gateway/test_truncation_fence_edge_case.py", + "tests/plugins/platforms/discord/test_edit_message_fence.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "c1a3e16c32896ea2d469536c657814049c29bec6", + "subject": "fix: also close orphaned single-backtick inline-code spans", + "parents": [ + "915913db360de5fe5b147d4895276ff39a6e8686" + ], + "is_merge": false, + "patch_id": "5591f76faf75f108e2596e380cde46f395c37087", + "changed_files": [ + "gateway/stream_consumer.py", + "tests/gateway/test_code_fence_tracking.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "535b33c95f9465bb3e05b281b17fceee3ba24d22", + "subject": "Merge PR #2: escape reasoning fences (resolve conflict)", + "parents": [ + "47cc1764dc2c2c65cc83fe20500da939698d72d3", + "347442ddc80a2658582cb62dd268a0be024b1bcf" + ], + "changed_files": [], + "pr_refs": [ + "2" + ] + }, + { + "sha": "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71", + "subject": "Merge branch 'fix/truncation-fence-edge-case' into dev", + "parents": [ + "9fe97e2aa1b05306ed626e5ae3db540d24bb4678", + "efd68fe044001c57c5d148a66469209589c344d9" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [ + "gateway/platforms/base.py", + "gateway/run.py", + "gateway/stream_consumer.py", + "plugins/platforms/discord/adapter.py", + "tests/gateway/test_code_fence_tracking.py", + "tests/gateway/test_escape_reasoning_fences.py", + "tests/gateway/test_truncation_fence_edge_case.py", + "tests/plugins/platforms/discord/test_edit_message_fence.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "2" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "evidence": [ + "Survives in gateway/stream_consumer.py and Discord adapter/tests.", + "Frozen upstream already has escape_code_fences_for_display, ensure_closed_code_fences, and chunk balancing with equivalent behavior." + ], + "behavioral_contracts": [ + "Untrusted backticks are escaped before outer wrapping.", + "Chunk balancing and truncation close open triple-backtick and inline-code spans.", + "Discord edit/truncation preserves the same user-visible balance guarantee." + ] + }, + { + "id": "capability:session-fts-simple-eol", + "record_type": "provenance_bucket", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "commits": [ + { + "sha": "44dd4c5e586e60c22a322a9eb89d1aed63892e36", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "parents": [ + "b03c94dbed5ee72e97eace2376e02092cc854f6a" + ], + "is_merge": false, + "patch_id": "f0a0986406e7ad9f35acf9468e22096c12863e24", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "a4e2c52f1582952686ee56aaedd7285874326102", + "subject": "fix: address Copilot review \u2014 init hermes_home, load simple in ro path, v21 migration", + "parents": [ + "dc2270aad84242da42f4342ac137e243ca181aa5" + ], + "is_merge": false, + "patch_id": "393d1d77f8315c21a5c34cbe151b1cb47b625e44", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "a1136e548ea1f2200429bf44f8f1a7297cc84246", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "parents": [ + "b03c94dbed5ee72e97eace2376e02092cc854f6a" + ], + "is_merge": false, + "patch_id": "f0a0986406e7ad9f35acf9468e22096c12863e24", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "c20cb64b4b79468c641626e9b9d3957790f7a671", + "subject": "fix: address Copilot review \u2014 init hermes_home, load simple in ro path, v21 migration", + "parents": [ + "a1136e548ea1f2200429bf44f8f1a7297cc84246" + ], + "is_merge": false, + "patch_id": "393d1d77f8315c21a5c34cbe151b1cb47b625e44", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a", + "subject": "fix(state): load simple tokenizer so legacy trigram tables stay writable", + "parents": [ + "d53e209b3b620abce55f2cc57a80c69bc0cd9369" + ], + "is_merge": false, + "patch_id": "9feec0370bda997dee075b1c9477969a125e9e97", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "196b904417371cf233f3eb9b560c80a079ab8d72", + "subject": "docs(research): map simple-tokenizer EOL for #40", + "parents": [ + "bee13fc085079d78d0334722ad4c37a1144e3102" + ], + "is_merge": false, + "patch_id": "a144398c69ababcec83ff82c28e880e3d74f8667", + "changed_files": [ + "docs/research/issue-40-simple-tokenizer-eol.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "85fd91fd7c7be20d63356f27654d399ca1da4fa0", + "subject": "test(fts): pin simple-tokenizer EOL policy (#19)", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72" + ], + "is_merge": false, + "patch_id": "19ab3fe510b98e6c0fa30e79b79eda2b10a975b7", + "changed_files": [ + "tests/test_simple_tokenizer_eol.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + }, + { + "sha": "186986a447080ae74a1d17fd1e32aaf039cb2ff2", + "subject": "fix(fts): retire simple-tokenizer residue; drop global shim (#19)", + "parents": [ + "85fd91fd7c7be20d63356f27654d399ca1da4fa0" + ], + "is_merge": false, + "patch_id": "37ec3e8508489924e6dcb38f55fc89de71963699", + "changed_files": [ + "hermes_state.py", + "tests/test_optional_cjk_tokenizer_fallback.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + }, + { + "sha": "deb10243ccebd6153cdfab8e9869faba2e105f0e", + "subject": "docs(fts): close simple compatibility contract (#19)", + "parents": [ + "186986a447080ae74a1d17fd1e32aaf039cb2ff2" + ], + "is_merge": false, + "patch_id": "13b475b0deeaca573780c59048aa6d4df5189ca6", + "changed_files": [ + "docs/research/issue-19-simple-tokenizer-eol-implementation.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + }, + { + "sha": "1d5b80cab802e6ae932c97342e328e76faa496fa", + "subject": "fix(fts): harden simple EOL sanitation per review (#19)", + "parents": [ + "deb10243ccebd6153cdfab8e9869faba2e105f0e" + ], + "is_merge": false, + "patch_id": "4759f05b9edac98c6ff1e825406938cc1bbc5ed3", + "changed_files": [ + "docs/research/issue-19-simple-tokenizer-eol-implementation.md", + "hermes_state.py", + "tests/test_simple_tokenizer_eol.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + } + ], + "merge_events": [ + { + "sha": "dc2270aad84242da42f4342ac137e243ca181aa5", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "parents": [ + "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "44dd4c5e586e60c22a322a9eb89d1aed63892e36" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "433a49f66b447f41fdd488dc4858a07c7cd7154d", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "parents": [ + "a4e2c52f1582952686ee56aaedd7285874326102", + "c20cb64b4b79468c641626e9b9d3957790f7a671" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "53da9e89f8f3d2b051bf4c719b9f09b355392c00", + "subject": "Merge pull request #87 from Skywind5487/feat/19-simple-tokenizer-eol", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72", + "1d5b80cab802e6ae932c97342e328e76faa496fa" + ], + "changed_files": [], + "pr_refs": [ + "87" + ] + } + ], + "affected_files": [ + "docs/research/issue-19-simple-tokenizer-eol-implementation.md", + "docs/research/issue-40-simple-tokenizer-eol.md", + "hermes_state.py", + "tests/test_optional_cjk_tokenizer_fallback.py", + "tests/test_simple_tokenizer_eol.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "19", + "87" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py sanitizer/repair logic and the #19/#87 research and tests.", + "Frozen upstream has no load_simple_extension/simple-tokenizer compatibility shim; the legacy debt is already absent there." + ], + "behavioral_contracts": [ + "Supported post-#12 databases do not require simple-tokenizer loading or repair branches.", + "Unsupported legacy residue is sanitized or rejected explicitly rather than silently kept writable.", + "Modern trigram/CJK lifecycle remains the canonical path." + ] + }, + { + "id": "capability:configurable-reasoning-display", + "record_type": "provenance_bucket", + "subject": "feat: configurable reasoning max lines via display.reasoning_max_lines", + "commits": [ + { + "sha": "895ba96014ecf934dbc140306ffe578a0a533ea3", + "subject": "feat: configurable reasoning max lines via display.reasoning_max_lines", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "59ff3b007ae023acbd6f006ba3242d2996f7f004", + "changed_files": [ + "cli.py", + "gateway/run.py", + "tests/gateway/test_reasoning_max_lines.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "9fe97e2aa1b05306ed626e5ae3db540d24bb4678", + "subject": "Merge PR #3: configurable reasoning max lines", + "parents": [ + "535b33c95f9465bb3e05b281b17fceee3ba24d22", + "895ba96014ecf934dbc140306ffe578a0a533ea3" + ], + "changed_files": [], + "pr_refs": [ + "3" + ] + } + ], + "affected_files": [ + "cli.py", + "gateway/run.py", + "tests/gateway/test_reasoning_max_lines.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "3" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in cli.py/config parsing and gateway display code.", + "Frozen upstream hardcodes the first 15 lines and has no reasoning_max_lines seam." + ], + "behavioral_contracts": [ + "reasoning_max_lines controls display truncation.", + "Invalid or absent configuration falls back safely.", + "Fence escaping remains applied before wrapping." + ] + }, + { + "id": "capability:headroom-compression", + "record_type": "provenance_bucket", + "subject": "Add opt-in headroom tool-output compression plugin", + "commits": [ + { + "sha": "915913db360de5fe5b147d4895276ff39a6e8686", + "subject": "Add opt-in headroom tool-output compression plugin", + "parents": [ + "296d9c6e2e5a6f852344ad8fa9b90f5687912be1" + ], + "is_merge": false, + "patch_id": "b68450d1d31e7788f570959684c620c497cd1ed8", + "changed_files": [ + "hermes_cli/config.py", + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "5eb552458de9828f4496880fd878f58015a63389", + "subject": "feat(headroom): add ContentRouter + SmartCrusher integration behind config flag", + "parents": [ + "cc2531fbc6df8fdb34fca0b096b798eb53f970dd" + ], + "is_merge": false, + "patch_id": "2c8da083a6ab3548f7ef00afffdaefe7faf17f0d", + "changed_files": [ + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "c16ebe6b8649c570b688fd82d6b66f9a8416d59c", + "subject": "fix(headroom): logger.warning for ContentRouter/CacheAligner failures + warning E2E tests", + "parents": [ + "5eb552458de9828f4496880fd878f58015a63389" + ], + "is_merge": false, + "patch_id": "8d2445a5faad27650a7666507fd9d6fd4b025419", + "changed_files": [ + "plugins/headroom/__init__.py", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "237176ed1d973910972984ba83d876d01c00f3db", + "subject": "fix(headroom): prevent metadata from expanding tool results", + "parents": [ + "b7e62647bd657a429d967cfa77034632ee490f9a" + ], + "is_merge": false, + "patch_id": "01605c62358b5fa3574a4d392ad37783879af619", + "changed_files": [ + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "b7e62647bd657a429d967cfa77034632ee490f9a", + "subject": "feat(headroom): merge ContentRouter + warning E2E tests into dev", + "parents": [ + "6fa6c557257175f26c1689799d352fdf948cb787", + "c16ebe6b8649c570b688fd82d6b66f9a8416d59c" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [ + "hermes_cli/config.py", + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in plugins/headroom, tools_config.py, plugin.yaml, pyproject.toml/uv.lock and plugin tests.", + "Frozen upstream has no headroom ContentRouter/SmartCrusher implementation." + ], + "behavioral_contracts": [ + "Compression activates only at configured thresholds and does not expand tool-result metadata.", + "Failures degrade with warning/logging and preserve usable content.", + "Plugin registration and schema remain valid when active." + ] + }, + { + "id": "non-capability:integration-merge", + "record_type": "provenance_bucket", + "subject": "Merge remote-tracking branch 'origin/main' into dev", + "commits": [], + "merge_events": [ + { + "sha": "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "subject": "Merge remote-tracking branch 'origin/main' into dev", + "parents": [ + "516d739f64a95a4f380b899fbb9a349d750fc2aa", + "104232979d6ec24e82a42dfbf14ac98f3df3c827" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "1602d06f5045d173ee31161b92e387de69ab821c", + "subject": "merge(session-search): ranked Top-N + late-snippet into dev", + "parents": [ + "237176ed1d973910972984ba83d876d01c00f3db", + "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "b66c149de0c8240e84ded1a2f983b8c42f7b984b", + "subject": "merge(main): absorb upstream main 91937a6dc into dev \u2014 keep session-search fix chain", + "parents": [ + "1602d06f5045d173ee31161b92e387de69ab821c", + "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "637ef2e193b6b2dada5d0b79173461fca03fbf20", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/routed-session-metadata-candidates", + "parents": [ + "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "dcf8096413c7ee40fe0ab512ac86927fb2092df1" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "evidence": [ + "Integrated behavior is represented by capability records on either side.", + "Merge topology is provenance, not semantic upstream evidence." + ], + "behavioral_contracts": [ + "A merge event is not silently omitted merely because it has no patch-id or changed-file payload." + ] + }, + { + "id": "capability:browser-timeout-cleanup", + "record_type": "provenance_bucket", + "subject": "fix(browser): config-gated daemon kill on timeout", + "commits": [ + { + "sha": "a2450695db0e99f3dd8362f129024cb74c700bb8", + "subject": "fix(browser): config-gated daemon kill on timeout", + "parents": [ + "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6" + ], + "is_merge": false, + "patch_id": "6adb5a7810ede0e0a7b0ab155cb017db044d0640", + "changed_files": [ + "tools/browser_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "b42bc25e622c11230998cc57f7050ec2a2cdd090", + "subject": "fix(browser): add tests and crash-resilience for daemon-kill on timeout", + "parents": [ + "9e3439835e9dbbad0d0076d539d769db1f84de0a" + ], + "is_merge": false, + "patch_id": "8ce16b114c337a7d1e177e5f422bcaed8aa9fd6a", + "changed_files": [ + "tests/tools/test_browser_terminate_daemon_timeout.py", + "tests/tools/test_browser_timeout_cleanup.py", + "tools/browser_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "cfb2636a6a3ed02ff773f106beb71c88576f1284", + "subject": "fix(browser): move dict cleanup to finally block on timeout (P1 fix)", + "parents": [ + "b42bc25e622c11230998cc57f7050ec2a2cdd090" + ], + "is_merge": false, + "patch_id": "50e4470b0565c38927129a73ef07bbba59294cb0", + "changed_files": [ + ".github/actions/hermes-smoke-test/action.yml", + ".github/workflows/build-windows-installer.yml", + ".github/workflows/docker-publish.yml", + ".github/workflows/nix-lockfile-fix.yml", + ".github/workflows/nix.yml", + "agent/gemini_cloudcode_adapter.py", + "agent/google_code_assist.py", + "agent/google_oauth.py", + "apps/desktop/src/app/chat/composer/skin-slash-popover.tsx", + "apps/desktop/src/app/cron/cron-job-actions-menu.tsx", + "apps/desktop/src/app/overlays/overlay-search-input.tsx", + "apps/desktop/src/app/right-sidebar/terminal/index.tsx", + "apps/desktop/src/app/session/hooks/use-message-stream.ts", + "apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx", + "apps/desktop/src/app/session/hooks/use-prompt-actions.ts", + "apps/desktop/src/app/session/hooks/use-session-actions.ts", + "apps/desktop/src/components/assistant-ui/streaming.test.tsx", + "apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx", + "apps/desktop/src/components/assistant-ui/thread.tsx", + "apps/desktop/src/components/assistant-ui/todo-tool.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.tsx", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback.tsx", + "apps/desktop/src/components/assistant-ui/user-message-text.tsx", + "apps/desktop/src/components/chat/generated-image-context.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.test.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.tsx", + "apps/desktop/src/components/ui/braille-spinner.tsx", + "apps/desktop/src/lib/gateway-ws-url.ts", + "gateway/platforms/dingtalk.py", + "gateway/platforms/email.py", + "gateway/platforms/feishu.py", + "gateway/platforms/feishu_comment.py", + "gateway/platforms/feishu_comment_rules.py", + "gateway/platforms/feishu_meeting_invite.py", + "gateway/platforms/homeassistant.py", + "gateway/platforms/matrix.py", + "gateway/platforms/slack.py", + "gateway/platforms/sms.py", + "gateway/platforms/telegram.py", + "gateway/platforms/telegram_network.py", + "gateway/platforms/wecom.py", + "gateway/platforms/wecom_callback.py", + "gateway/platforms/wecom_crypto.py", + "gateway/platforms/whatsapp.py", + "optional-skills/productivity/shop-app/SKILL.md", + "plans/gemini-oauth-provider.md", + "tests/tools/test_browser_timeout_cleanup.py", + "tools/browser_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "9e3439835e9dbbad0d0076d539d769db1f84de0a", + "subject": "Merge remote-tracking branch 'origin/main' into fix/browser-timeout-daemon-kill-toggle", + "parents": [ + "a2450695db0e99f3dd8362f129024cb74c700bb8", + "104232979d6ec24e82a42dfbf14ac98f3df3c827" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f", + "subject": "Merge branch 'fix/browser-timeout-daemon-kill-toggle' into dev", + "parents": [ + "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "cfb2636a6a3ed02ff773f106beb71c88576f1284" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [ + ".github/actions/hermes-smoke-test/action.yml", + ".github/workflows/build-windows-installer.yml", + ".github/workflows/docker-publish.yml", + ".github/workflows/nix-lockfile-fix.yml", + ".github/workflows/nix.yml", + "agent/gemini_cloudcode_adapter.py", + "agent/google_code_assist.py", + "agent/google_oauth.py", + "apps/desktop/src/app/chat/composer/skin-slash-popover.tsx", + "apps/desktop/src/app/cron/cron-job-actions-menu.tsx", + "apps/desktop/src/app/overlays/overlay-search-input.tsx", + "apps/desktop/src/app/right-sidebar/terminal/index.tsx", + "apps/desktop/src/app/session/hooks/use-message-stream.ts", + "apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx", + "apps/desktop/src/app/session/hooks/use-prompt-actions.ts", + "apps/desktop/src/app/session/hooks/use-session-actions.ts", + "apps/desktop/src/components/assistant-ui/streaming.test.tsx", + "apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx", + "apps/desktop/src/components/assistant-ui/thread.tsx", + "apps/desktop/src/components/assistant-ui/todo-tool.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.tsx", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback.tsx", + "apps/desktop/src/components/assistant-ui/user-message-text.tsx", + "apps/desktop/src/components/chat/generated-image-context.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.test.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.tsx", + "apps/desktop/src/components/ui/braille-spinner.tsx", + "apps/desktop/src/lib/gateway-ws-url.ts", + "gateway/platforms/dingtalk.py", + "gateway/platforms/email.py", + "gateway/platforms/feishu.py", + "gateway/platforms/feishu_comment.py", + "gateway/platforms/feishu_comment_rules.py", + "gateway/platforms/feishu_meeting_invite.py", + "gateway/platforms/homeassistant.py", + "gateway/platforms/matrix.py", + "gateway/platforms/slack.py", + "gateway/platforms/sms.py", + "gateway/platforms/telegram.py", + "gateway/platforms/telegram_network.py", + "gateway/platforms/wecom.py", + "gateway/platforms/wecom_callback.py", + "gateway/platforms/wecom_crypto.py", + "gateway/platforms/whatsapp.py", + "optional-skills/productivity/shop-app/SKILL.md", + "plans/gemini-oauth-provider.md", + "tests/tools/test_browser_terminate_daemon_timeout.py", + "tests/tools/test_browser_timeout_cleanup.py", + "tools/browser_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in tools/browser_tool.py and timeout cleanup/daemon tests.", + "Frozen upstream has timeout cleanup/orphan reaping but not terminate_daemon_on_timeout configuration behavior." + ], + "behavioral_contracts": [ + "Timeout cleanup clears in-memory browser state in a finally-equivalent path.", + "Daemon termination is opt-in/config-gated.", + "Cleanup failures are contained and test-covered." + ] + }, + { + "id": "capability:memory-trim-policy", + "record_type": "provenance_bucket", + "subject": "fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim", + "commits": [ + { + "sha": "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb", + "subject": "fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim", + "parents": [ + "04f1af72be078cef69de538f1519f93a73088b0d" + ], + "is_merge": false, + "patch_id": "6c4c0e537ecff4d0df196c263683328d626be9cd", + "changed_files": [ + "hermes_cli/mem_trim.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_cli/mem_trim.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Frozen fork hermes_cli/mem_trim.py adds threshold_mb and gc_cooldown_seconds policy gates.", + "Frozen upstream hermes_cli/mem_trim.py has a general trim cooldown but no RSS low-water gate or independent GC cooldown." + ], + "behavioral_contracts": [ + "RSS below threshold_mb skips the expensive trim work on housekeeping ticks.", + "gc.collect() runs at most once per gc_cooldown_seconds while malloc_trim remains eligible on the normal trim cadence.", + "Force behavior and invalid configuration retain explicit safe fallbacks." + ] + }, + { + "id": "non-capability:performance-validation", + "record_type": "provenance_bucket", + "subject": "perf(search): batch context queries \u2014 chunked session_id batches (20/sql)", + "commits": [ + { + "sha": "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "subject": "perf(search): batch context queries \u2014 chunked session_id batches (20/sql)", + "parents": [ + "ff4df5b71e1557660dbe994eb5569983f57c9901" + ], + "is_merge": false, + "patch_id": "640fc71b9783c17f14327fe3bee772129ef31c89", + "changed_files": [ + "hermes_state.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "subject": "perf(search): benchmark cold-open + fallback-invariant self-check", + "parents": [ + "3ebb2592c141b232ecd0717adf32279afa6bee3f" + ], + "is_merge": false, + "patch_id": "b6beb6e939deb9a52d5d34e24f046539743092ec", + "changed_files": [ + "scripts/benchmarks/session_metadata_picker.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "a34da2c31ca60f9b5280558c514a3a1880035036", + "subject": "Merge branch 'fix/session-search-perf' of /home/skywind5487/hermes_worktrees/fix/session-search-perf into dev", + "parents": [ + "3053abf3b039a5b4c23637597cb076f2339250fb", + "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [ + "hermes_state.py", + "scripts/benchmarks/session_metadata_picker.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "evidence": [ + "Benchmark and query-shape changes remain visible in history.", + "No upstream equivalence is inferred from local measurements." + ], + "behavioral_contracts": [ + "A benchmark supports a decision but does not prove equivalence or impose an unreviewed target." + ] + }, + { + "id": "capability:session-fts-unicode", + "record_type": "provenance_bucket", + "subject": "fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries", + "commits": [ + { + "sha": "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0", + "subject": "fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries", + "parents": [ + "37811327cdc65c85c4b0bd565b1cdb3a4590dd91" + ], + "is_merge": false, + "patch_id": "2e7ebdeacf2f068145cf24e23acc81ca0d1d0d85", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "2ac803bd949f0aba96c0d4d500edd2ad65aa3036", + "subject": "feat(session-search): port sessions FTS5 title index (unicode61 + cjk_unicode61) from dev", + "parents": [ + "b66c149de0c8240e84ded1a2f983b8c42f7b984b" + ], + "is_merge": false, + "patch_id": "5c37e63fdd564f04c6c5275ee37ac7d7ce35dc7c", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "9b25b0c8bd7408eaf2398529b6a04ed1a068b892", + "subject": "docs: research #32 session row_id unicode FTS", + "parents": [ + "9f3056cb3a9642c39056af8409cc3198007e68a8" + ], + "is_merge": false, + "patch_id": "368ddfb0bf2cc28000410f3a099081f34cd453f5", + "changed_files": [ + "docs/research/issue-32-stable-row-id-unicode-session-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "e94f2630a50d7585f78cfc06365753c033113cb9", + "subject": "Session metadata FTS: stable row_id + resumable Unicode external-content index (#25) (#59)", + "parents": [ + "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba" + ], + "is_merge": false, + "patch_id": "96d200731949e4ff95efcefeeef9e80dc5f47fc0", + "changed_files": [ + "docs/design/session-metadata-fts.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [ + "25" + ], + "pr_refs": [ + "59" + ] + }, + { + "sha": "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2", + "subject": "style(session-fts): drop duplicate @staticmethod (round-2 review)", + "parents": [ + "8efead2600a3f932f9881b53cd0c7eabc755f82f" + ], + "is_merge": false, + "patch_id": "2619728a0a90d3f0bf8f9ca26357b383e895e595", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/design/session-metadata-fts.md", + "docs/research/issue-32-stable-row-id-unicode-session-fts.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_fts.py" + ], + "work_item_provenance": { + "issue_refs": [ + "25" + ], + "pr_refs": [ + "59" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, hermes_cli/session_recovery.py and tests/test_session_metadata_fts.py.", + "Frozen upstream has messages_fts but no equivalent sessions_fts metadata index." + ], + "behavioral_contracts": [ + "Stable sessions.row_id is retained across hidden rows and gaps.", + "External-content FTS indexes title, id, and display_name with resumable high-water backfill.", + "Backfill and triggers preserve delete correctness and never expose hidden sessions." + ] + }, + { + "id": "capability:session-search-routing", + "record_type": "provenance_bucket", + "subject": "fix(session-search): define ranked_candidates for LIKE route", + "commits": [ + { + "sha": "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e", + "subject": "fix(session-search): define ranked_candidates for LIKE route", + "parents": [ + "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32" + ], + "is_merge": false, + "patch_id": "32a3bd65e89fbf0255bd6fea58c2bf13386d7853", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "0990803323497a36761c9627a20ceb57be56d5a3", + "subject": "test(state): pin session metadata route and fallback contract", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72" + ], + "is_merge": false, + "patch_id": "93d8f3d69bcc25ace9213068d009e2d5b442b721", + "changed_files": [ + "tests/test_session_metadata_picker_routing.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "5882274ff6c868c24f9d36f3796de08e5de8a245", + "subject": "refactor(state): add snapshot-aware metadata candidate router", + "parents": [ + "0990803323497a36761c9627a20ceb57be56d5a3" + ], + "is_merge": false, + "patch_id": "9cfd759f545ca7f542f068883f5017767e784705", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d", + "subject": "feat(api): route session metadata discovery through the common seam", + "parents": [ + "a615feaea695123d1b3a832417a9a76554301af8" + ], + "is_merge": false, + "patch_id": "6a16e8da3c72078417110de5201378d7a1a01de0", + "changed_files": [ + "hermes_cli/web_routers/profiles.py", + "hermes_cli/web_routers/sessions.py", + "tests/hermes_cli/test_web_server.py", + "tests/hermes_cli/test_web_server_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "b4efc640fab0517571bd05447cf2be2ace9cf3e1", + "subject": "feat(desktop): search the whole session store in the resume picker", + "parents": [ + "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d" + ], + "is_merge": false, + "patch_id": "0b08ae048db2918949822a3781f615a65e504f8a", + "changed_files": [ + "apps/desktop/src/components/session-picker.test.tsx", + "apps/desktop/src/components/session-picker.tsx", + "apps/desktop/src/hermes.test.ts", + "apps/desktop/src/hermes.ts", + "apps/desktop/src/i18n/en.ts", + "apps/desktop/src/i18n/types.ts", + "apps/desktop/src/i18n/zh.ts" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "b97d00e7319e5147d569519b6a34ef63c6635551", + "subject": "perf(search): benchmark routed session metadata candidates", + "parents": [ + "b4efc640fab0517571bd05447cf2be2ace9cf3e1" + ], + "is_merge": false, + "patch_id": "19e1e455ef97845723d5c2418e0c398657189166", + "changed_files": [ + "scripts/benchmarks/session_metadata_picker.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "3ebb2592c141b232ecd0717adf32279afa6bee3f", + "subject": "test(api): cross-profile resume search + desktop stale-response ordering", + "parents": [ + "6447a52cd994bf30c2811814f21095d12aba83ae" + ], + "is_merge": false, + "patch_id": "ac5fe312a1856bb33dae36d22f8c12139ce58f01", + "changed_files": [ + "apps/desktop/src/components/session-picker.test.tsx", + "tests/hermes_cli/test_web_server.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "subject": "feat(session): route session-metadata picker candidates through FTS (#14)", + "parents": [ + "dcf8096413c7ee40fe0ab512ac86927fb2092df1", + "637ef2e193b6b2dada5d0b79173461fca03fbf20" + ], + "changed_files": [], + "pr_refs": [ + "14" + ] + } + ], + "affected_files": [ + "apps/desktop/src/components/session-picker.test.tsx", + "apps/desktop/src/components/session-picker.tsx", + "apps/desktop/src/hermes.test.ts", + "apps/desktop/src/hermes.ts", + "apps/desktop/src/i18n/en.ts", + "apps/desktop/src/i18n/types.ts", + "apps/desktop/src/i18n/zh.ts", + "hermes_cli/web_routers/profiles.py", + "hermes_cli/web_routers/sessions.py", + "hermes_state.py", + "scripts/benchmarks/session_metadata_picker.py", + "tests/hermes_cli/test_web_server.py", + "tests/hermes_cli/test_web_server_session_search.py", + "tests/test_session_metadata_picker_routing.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "14" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "FORK_ONLY", + "disposition": "PORT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_search.py, web session/profile routers, desktop picker code and routing tests.", + "Frozen upstream has session ID/title primitives but no equivalent metadata-index router." + ], + "behavioral_contracts": [ + "Unicode, CJK, and infix queries select their intended index; LIKE is bounded fallback.", + "FTS narrows IDs before lineage hydration; only empty successful FTS triggers fallback.", + "Visibility, archive/pin/source filters, lineage, branch markers, whole-store scope, and limits remain correct." + ] + }, + { + "id": "non-capability:incidental-hardening", + "record_type": "provenance_bucket", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log", + "commits": [ + { + "sha": "cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log", + "parents": [ + "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0" + ], + "is_merge": false, + "patch_id": "7db3fd75db58976898a37f9b5e0f1f86a17c7eff", + "changed_files": [ + "hermes_state.py", + "plugins/platforms/discord/adapter.py", + "tests/tools/test_web_searxng_e2e.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "9f3056cb3a9642c39056af8409cc3198007e68a8", + "subject": "ignore agents", + "parents": [ + "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a" + ], + "is_merge": false, + "patch_id": "10bfbeb338458c810deaa1bad23c658c89312887", + "changed_files": [ + ".gitignore" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "4270ea5b9a903d0dcf692db2365875ac5b3fe319", + "subject": "chore: ignore fts5_cjk Windows build artifact (.dll)", + "parents": [ + "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128" + ], + "is_merge": false, + "patch_id": "cb5d25e94b43ca47ae67c178b3659682cb1ca145", + "changed_files": [ + ".gitignore" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + ".gitignore", + "hermes_state.py", + "plugins/platforms/discord/adapter.py", + "tests/tools/test_web_searxng_e2e.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "medium", + "evidence": [ + "Record-specific survival is visible in the frozen tree.", + "No equivalence claim is made without focused comparison." + ], + "behavioral_contracts": [ + "The safety invariant remains visible in record subject/files while capability ownership is unresolved." + ] + }, + { + "id": "non-capability:production-evidence", + "record_type": "provenance_bucket", + "subject": "docs(recovery): attest production gateway runtime surface", + "commits": [ + { + "sha": "cea5282a181d23af471f4467f449fd9bfc022ca5", + "subject": "docs(recovery): attest production gateway runtime surface", + "parents": [ + "d72f99eb1b897dd29a46692a310aa15b1bfd77e8" + ], + "is_merge": false, + "patch_id": "7220d2c770e0afce5b241c590b084d2080c668ee", + "changed_files": [ + "research/recovery/issue-41-production-gateway-runtime-attestation.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba", + "subject": "docs(recovery): add production runtime repair runbook", + "parents": [ + "cea5282a181d23af471f4467f449fd9bfc022ca5" + ], + "is_merge": false, + "patch_id": "76b7fa3ba383db6dc4cc01a0d84dbb8ee9cb3d9f", + "changed_files": [ + "research/recovery/issue-21-production-runtime-runbook.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57", + "subject": "docs(research): record #22 production-ready state.db build and freeze", + "parents": [ + "4e5ad5c2230300d1ffae84b089ffc70e368c8a23" + ], + "is_merge": false, + "patch_id": "3445dddcd1a9f3590543c01fe8be46376d09bdc0", + "changed_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "8b085795df0359adbf3c81315f888bc7041fb044", + "subject": "docs(research): record #22 redo with SQLite 3.51.3 + CJK + fuzz", + "parents": [ + "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57" + ], + "is_merge": false, + "patch_id": "48ed043d3ba486e84c373a04e82cf337a744f4b6", + "changed_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + }, + { + "sha": "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba", + "subject": "docs(research): correct #22 path/router evidence with executing-query validation", + "parents": [ + "8b085795df0359adbf3c81315f888bc7041fb044" + ], + "is_merge": false, + "patch_id": "599bf839a067e86fa019becd0d2281c855e70bcd", + "changed_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [ + { + "sha": "bee13fc085079d78d0334722ad4c37a1144e3102", + "subject": "Merge pull request #82 from Skywind5487/feat/22-production-ready-state-db-execution", + "parents": [ + "4e5ad5c2230300d1ffae84b089ffc70e368c8a23", + "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba" + ], + "changed_files": [], + "pr_refs": [ + "82" + ] + } + ], + "affected_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md", + "research/recovery/issue-21-production-runtime-runbook.md", + "research/recovery/issue-41-production-gateway-runtime-attestation.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "82" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "high", + "evidence": [ + "Survives as docs/research and research/recovery artifacts.", + "No code-level equivalence is claimed from operational documents." + ], + "behavioral_contracts": [ + "Operational records remain durable evidence and are not mistaken for code-level equivalence." + ] + }, + { + "id": "capability:session-title-safety", + "record_type": "provenance_bucket", + "subject": "test(session): pin literal-safe numbered-title resolution (#15)", + "commits": [ + { + "sha": "d18dadb5f3b517ec69f14428dc78e7af1a86a30e", + "subject": "test(session): pin literal-safe numbered-title resolution (#15)", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72" + ], + "is_merge": false, + "patch_id": "bd61d76f62622a833ac9338561d3e08e73b70e97", + "changed_files": [ + "tests/test_hermes_state.py", + "tests/test_session_metadata_cjk_fts.py", + "tests/test_session_metadata_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + { + "sha": "faf96ef221ddfba2618abc8dae8368f7b82c1c2a", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)", + "parents": [ + "d18dadb5f3b517ec69f14428dc78e7af1a86a30e" + ], + "is_merge": false, + "patch_id": "b5d0d7483995873297fe25582c921eff0f231152", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + { + "sha": "69bee0838ae15936ae4beb13cdf5d6907c19c707", + "subject": "docs: record #38 numbered-title research note and design contract (#15)", + "parents": [ + "faf96ef221ddfba2618abc8dae8368f7b82c1c2a" + ], + "is_merge": false, + "patch_id": "2df8b0d2801a3c4d573c57a1fa703c32aa097c3d", + "changed_files": [ + "docs/design/session-metadata-fts.md", + "docs/research/issue-38-numbered-title-literal-safety.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + { + "sha": "17b0d2c9135d38728109592860677c4abbaddf4f", + "subject": "fix(session): unify #N grammar to ASCII digits; tidy escape_like placement (#15)", + "parents": [ + "69bee0838ae15936ae4beb13cdf5d6907c19c707" + ], + "is_merge": false, + "patch_id": "131b1db23e2621d2d293fa1816b61c6c2da0e0fe", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "tests/test_hermes_state.py", + "tests/test_session_metadata_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + } + ], + "merge_events": [ + { + "sha": "984eff15df1fb749f00aece7fc24c43e9afcb7e8", + "subject": "Merge remote-tracking branch 'origin/dev' into fix/15-numbered-title-literal-safety", + "parents": [ + "17b0d2c9135d38728109592860677c4abbaddf4f", + "53da9e89f8f3d2b051bf4c719b9f09b355392c00" + ], + "changed_files": [], + "pr_refs": [] + }, + { + "sha": "dcf8096413c7ee40fe0ab512ac86927fb2092df1", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)", + "parents": [ + "53da9e89f8f3d2b051bf4c719b9f09b355392c00", + "984eff15df1fb749f00aece7fc24c43e9afcb7e8" + ], + "changed_files": [], + "pr_refs": [ + "15" + ] + } + ], + "affected_files": [ + "docs/design/session-metadata-fts.md", + "docs/research/issue-38-numbered-title-literal-safety.md", + "hermes_state.py", + "hermes_state_common.py", + "tests/test_hermes_state.py", + "tests/test_session_metadata_cjk_fts.py", + "tests/test_session_metadata_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "PARTIAL_UPSTREAM", + "disposition": "SPLIT", + "confidence": "high", + "evidence": [ + "Survives in hermes_state.py, hermes_state_common.py and title/metadata tests.", + "Frozen upstream escapes LIKE but does not enforce the fork's strict numeric suffix filter." + ], + "behavioral_contracts": [ + "Escape SQL LIKE literals independently from Python literals.", + "Only strict ASCII #N suffixes are variants; %, _, \\, #, CJK, and literal titles stay exact and safe.", + "The public resolution API and root/current exclusion semantics remain unchanged." + ] + }, + { + "id": "capability:cron-nul-safety", + "record_type": "provenance_bucket", + "subject": "fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762)", + "commits": [ + { + "sha": "d53e209b3b620abce55f2cc57a80c69bc0cd9369", + "subject": "fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762)", + "parents": [ + "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb" + ], + "is_merge": false, + "patch_id": "9c58ec803f99f92c66b88ef1ef1dbfb6cb47aa0b", + "changed_files": [ + "cron/lifecycle_guard.py", + "tools/terminal_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "76762" + ] + } + ], + "merge_events": [], + "affected_files": [ + "cron/lifecycle_guard.py", + "tools/terminal_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "76762" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "SEMANTIC_UPSTREAM", + "disposition": "DROP", + "confidence": "high", + "evidence": [ + "Survives in cron/lifecycle_guard.py and tools/terminal_tool.py.", + "Frozen upstream contains the corresponding NUL/binary-safe guard and terminal fallback." + ], + "behavioral_contracts": [ + "NUL-bearing input does not reach unsafe process/lifecycle calls.", + "Terminal fallback returns a clear failure rather than truncating at NUL." + ] + } + ], + "accounting": { + "discovery_coverage": { + "historical_commits": 171, + "emitted_commit_records": 171, + "complete": true + }, + "capability_accounting": { + "explicitly_accounted_commits": 171, + "unaccounted_commits": [], + "complete": true + } + } +} diff --git a/artifacts/fork-archaeology-issue-100/inventory.md b/artifacts/fork-archaeology-issue-100/inventory.md new file mode 100644 index 000000000000..a643a2810535 --- /dev/null +++ b/artifacts/fork-archaeology-issue-100/inventory.md @@ -0,0 +1,243 @@ +# Fork archaeology inventory + +- Fork ref: `35c8564c9c0af3d75bcbdf1d793e7207e5528f06` +- Upstream ref: `460d345642ee3d143a3e461abe39fd42b86a7e54` +- Merge base: `91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53` + +| Provenance bucket | Change records | Merge events | Status | Disposition | Confidence | +| --- | ---: | ---: | --- | --- | --- | +| `capability:session-fts-storage-v2` | 9 | 1 | `FORK_ONLY` | `PORT` | `high` | +| `capability:session-fts-lifecycle` | 15 | 1 | `FORK_ONLY` | `PORT` | `high` | +| `capability:memory-trim-diagnostics` | 1 | 0 | `PARTIAL_UPSTREAM` | `KEEP` | `medium` | +| `capability:headroom-retrieval` | 5 | 1 | `FORK_ONLY` | `PORT` | `high` | +| `capability:session-fts-cjk` | 12 | 1 | `FORK_ONLY` | `PORT` | `high` | +| `capability:lifecycle-sqlite-telemetry` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `medium` | +| `capability:request-transform-hook` | 1 | 0 | `FORK_ONLY` | `PORT` | `high` | +| `capability:session-fts-trigram` | 30 | 3 | `FORK_ONLY` | `PORT` | `high` | +| `capability:session-search-lineage` | 20 | 1 | `PARTIAL_UPSTREAM` | `SPLIT` | `high` | +| `capability:outbound-code-fence-safety` | 5 | 2 | `SEMANTIC_UPSTREAM` | `DROP` | `high` | +| `capability:session-fts-simple-eol` | 10 | 3 | `SEMANTIC_UPSTREAM` | `DROP` | `high` | +| `capability:configurable-reasoning-display` | 1 | 1 | `FORK_ONLY` | `PORT` | `high` | +| `capability:headroom-compression` | 4 | 1 | `FORK_ONLY` | `PORT` | `high` | +| `non-capability:integration-merge` | 0 | 4 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `high` | +| `capability:browser-timeout-cleanup` | 3 | 2 | `FORK_ONLY` | `PORT` | `high` | +| `capability:memory-trim-policy` | 1 | 0 | `PARTIAL_UPSTREAM` | `PORT` | `high` | +| `non-capability:performance-validation` | 2 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `high` | +| `capability:session-fts-unicode` | 5 | 0 | `FORK_ONLY` | `PORT` | `high` | +| `capability:session-search-routing` | 7 | 1 | `FORK_ONLY` | `PORT` | `high` | +| `non-capability:incidental-hardening` | 3 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `medium` | +| `non-capability:production-evidence` | 5 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `high` | +| `capability:session-title-safety` | 4 | 2 | `PARTIAL_UPSTREAM` | `SPLIT` | `high` | +| `capability:cron-nul-safety` | 1 | 0 | `SEMANTIC_UPSTREAM` | `DROP` | `high` | + +## Evidence + +### `capability:session-fts-storage-v2` - test(fts): pin storage-v2 refusal states (#31) + +- Changes: `00a2675a9270`, `b86e4f526ec3`, `2c907113fd2c`, `f887f44fa2d2`, `180ae82a2d7e`, `1d6d73f3bb8f`, `0fafc1dd7b58`, `67d4f719d6b0`, `0ff8583e91c8` +- Merge events: `276d497764fe` +- Files: `docs/research/issue-31-storage-v2-settlement.md`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_fts_storage_v2_settlement.py` +- Upstream matches: none +- Evidence: Survives in hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_storage_v2_settlement.py.; Frozen upstream has no session six-index storage-v2 settlement state machine. +- Behavioral contracts: One predicate defines required-index settlement; startup and foreground paths use it.; Incomplete or interrupted required settlement refuses serving; reopen/resume reaches an explicit terminal state.; Optional indexes do not silently become required blockers. + +### `capability:session-fts-lifecycle` - feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27) + +- Changes: `00e680a8cb22`, `e64af5e0f8a3`, `474b88fe76e1`, `f9ade6baff7f`, `e64ad007b459`, `bdd9d699f6dc`, `0400c66f072d`, `75223d19544c`, `933a2ce86c8a`, `dc1f153a71d0`, `ed5ab2e8ecd0`, `a822d37d1806`, `3bc7d3f58f80`, `d6a4d7048362`, `0cf4cd0baffb` +- Merge events: `9d140c8594c6` +- Files: `docs/research/issue-27-unified-fts-lifecycle.md`, `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_fts_lifecycle_registry.py`, `tests/test_hermes_state.py` +- Upstream matches: none +- Evidence: Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_fts_lifecycle_registry.py.; Frozen upstream has message FTS primitives but no equivalent session six-index lifecycle boundary. +- Behavioral contracts: The registry covers messages_fts, messages_fts_trigram, messages_fts_cjk, sessions_fts, sessions_fts_cjk, and sessions_fts_trigram.; Maintenance, health, read-only discovery, repair, and degraded runtime iterate the same descriptors.; Unknown or incomplete trigger state fails closed for serving. + +### `capability:memory-trim-diagnostics` - feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold + +- Changes: `04f1af72be07` +- Merge events: (none) +- Files: `hermes_cli/mem_trim.py` +- Upstream matches: none +- Evidence: Frozen fork splits gc_ms and trim_ms, records VmSwap, and measures malloc_info fragmentation.; Frozen upstream has basic RSS/RssAnon snapshots and trim logging but not the fork's attribution diagnostics. +- Behavioral contracts: gc_ms versus trim_ms identifies the freeze mechanism without changing the policy decision.; Fragmentation and VmSwap are best-effort diagnostics and never block memory recovery. + +### `capability:headroom-retrieval` - feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin + +- Changes: `0a4b567ff087`, `d3f44c9d63b7`, `ff4df5b71e15`, `b527e4df996b`, `0b4e7601227a` +- Merge events: `516d739f64a9` +- Files: `hermes_cli/tools_config.py`, `plugins/headroom/__init__.py`, `plugins/headroom/plugin.yaml`, `pyproject.toml`, `tests/plugins/test_headroom_plugin.py`, `uv.lock` +- Upstream matches: none +- Evidence: Survives in plugins/headroom, tools_config.py, plugin.yaml and plugin tests.; No equivalent retrieval tool is present in frozen upstream. +- Behavioral contracts: The retrieval tool has a stable schema.; It is auto-enabled only when compression is active and returns bounded context.; Registration failures are explicit and warning-visible. + +### `capability:session-fts-cjk` - fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search + +- Changes: `15f5aa07a0a1`, `3053abf3b039`, `6311e77e27f4`, `3e23375f7934`, `7b4d37c2727c`, `8ec0ec3bf85a`, `47c537c766bb`, `83431f775a9e`, `8efead2600a3`, `6b3402ea0556`, `0eee69ef43f1`, `6447a52cd994` +- Merge events: `bdf2fc218264` +- Files: `docs/design/session-metadata-fts.md`, `docs/research/issue-33-cjk-session-metadata-fts-lifecycle.md`, `hermes_cli/session_recovery.py`, `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/hermes_cli/test_session_recovery.py`, `tests/test_session_metadata_cjk_fts.py`, `tests/test_session_metadata_picker_routing.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_cjk_fts.py.; Frozen upstream has no session CJK metadata index or equivalent optional lifecycle. +- Behavioral contracts: CJK search covers title, id, and display_name through external-content FTS.; Unavailable tokenizer/index state degrades safely without hiding the base path.; Guard and MATCH run against one SQLite snapshot; rebuild is independent and resumable. + +### `capability:lifecycle-sqlite-telemetry` - feat: add lifecycle and SQLite observability telemetry + +- Changes: `176646d2cd6c` +- Merge events: (none) +- Files: `agent/conversation_compression.py`, `agent/conversation_loop.py`, `agent/diagnostic_config.py`, `agent/kernel_telemetry.py`, `agent/lifecycle_telemetry.py`, `agent/sqlite_native_telemetry.py`, `agent/tool_executor.py`, `agent/turn_context.py`, `docs/observability/session-db-api-handoff.md`, `gateway/run.py`, `gateway/stream_consumer.py`, `hermes_cli/config.py`, `hermes_state.py`, `plugins/memory/holographic/__init__.py`, `plugins/platforms/discord/adapter.py`, `scripts/hermes_kernel_trace.py`, `tests/agent/test_lifecycle_telemetry.py`, `tests/agent/test_tool_lifecycle_telemetry.py`, `tests/gateway/test_discord_delivery_lifecycle_telemetry.py`, `tests/gateway/test_stream_lifecycle_telemetry.py`, `tests/plugins/memory/test_holographic_prefetch_gate.py`, `tests/test_machine_health_collector.py`, `tests/test_optional_cjk_tokenizer_fallback.py`, `tests/test_session_db_lock_telemetry.py`, `tests/test_sqlite_kernel_telemetry.py`, `tests/test_sqlite_owner_telemetry.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: Survives across lifecycle_telemetry.py, sqlite_native_telemetry.py, turn_context.py, gateway code and tests.; Frozen upstream comparison was not completed per telemetry surface; absence is not treated as proof. +- Behavioral contracts: Important boundaries emit structured telemetry rather than only ad-hoc logs.; SQLite lock/owner and stream/tool failures remain diagnosable. + +### `capability:request-transform-hook` - feat: add transform_api_request plugin hook for full-payload request transformation + +- Changes: `296d9c6e2e5a` +- Merge events: (none) +- Files: `agent/conversation_loop.py`, `hermes_cli/hooks.py`, `hermes_cli/plugins.py`, `tests/run_agent/test_run_agent.py` +- Upstream matches: none +- Evidence: Survives in agent/conversation_loop.py, hermes_cli/hooks.py, hermes_cli/plugins.py and run-agent tests.; Frozen upstream has pre_llm_call but not a full-payload transform hook at dispatch. +- Behavioral contracts: transform_api_request receives and returns the complete payload at a documented boundary.; The hook is optional and preserves the request when absent.; Hook errors are explicit and do not dispatch partial data. + +### `capability:session-fts-trigram` - feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch + +- Changes: `37811327cdc6`, `19e6e6223bb5`, `ad0c45f09243`, `48b04dae36d6`, `6f82bcbb3c5f`, `0f29f1454ea2`, `dc2cd8cfaf94`, `252920f02442`, `4483194b8149`, `bfa928d53da7`, `cc5261ce775c`, `e33b533e1d24`, `b5155410abbf`, `9aad13bcad68`, `3172c9f4611c`, `6467a30563fb`, `e1ef573d3feb`, `72388ff87f0b`, `0c02b83d4d87`, `a9c1b2d11bab`, `2142e2fa1b49`, `c7163001f23f`, `6f534c8760a3`, `10e3419d10e9`, `69591fe65977`, `7b513c6bf2f6`, `783d3fa59ae2`, `4aefa3abbbe4`, `d4c9a165c5ab`, `f17ab5897975` +- Merge events: `f18b3c90c230`, `919f4469e832`, `4e5ad5c22303` +- Files: `docs/research/issue-30-normalized-session-metadata-trigram-fts.md`, `docs/research/issue-34-normalized-session-metadata-trigram-fts.md`, `docs/research/issue-79-session-recovery-trigram-markers.md`, `hermes_cli/session_recovery.py`, `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/hermes_cli/test_session_recovery.py`, `tests/test_session_metadata_trigram_fts.py` +- Upstream matches: none +- Evidence: Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py and tests/test_session_metadata_trigram_fts.py.; Frozen upstream has no sessions_fts_trigram external-content index; generic message trigram is not equivalent. +- Behavioral contracts: The external-content source normalizes title/display_name and keeps raw id searchable.; Serving requires complete trigger/namespace ownership; unknown same-name objects fail closed.; Recovery markers support resumable rebuild without treating a partial index as healthy. + +### `capability:session-search-lineage` - perf: reduce SELECT * in get_compression_lineage to 4 columns + +- Changes: `3de538d32a3c`, `6fa6c5572571`, `2732c47e28fb`, `2d2bad204ec6`, `9a1f477df5c8`, `d72f99eb1b89`, `8838d16060bb`, `46907bc8b55b`, `2f12b03079cb`, `2e1b2e64d7a4`, `a13d012e5b87`, `66eb2fad76ab`, `f32b51764e43`, `42c421f68b65`, `c81ab321ec4b`, `dcd10233d32e`, `55dc24391f92`, `b2710666a29e`, `1f5edc591353`, `a615feaea695` +- Merge events: `2f90c254d524` +- Files: `hermes_state.py`, `hermes_state_search.py`, `research/session-lineage/README.md`, `tests/hermes_state/test_get_messages_around.py`, `tests/test_session_metadata_picker_routing.py`, `tests/test_session_search_sql_winners.py`, `tests/tools/test_session_search.py`, `tools/session_search_tool.py`, `website/docs/developer-guide/session-storage.md` +- Upstream matches: none +- Evidence: Survives in hermes_state_search.py and session-search tools/tests, including bounded winner hydration.; Frozen upstream has _lineage_root_id/basic lookup but not the stronger resolver, memo, B-boundary, or explicit truncation contract. +- Behavioral contracts: Only positive compression edges are followed; branch/delegate markers and tool children do not become roots.; Missing/cyclic lineage fails closed; query-local memo/path compression is bounded by B=2000 successful uncached row fetches.; B exhaustion returns truncated/warning without poisoned memo; one snapshot, early-K and deferred hydration are preserved. + +### `capability:outbound-code-fence-safety` - test: code fence tracking coverage for all send/split paths + +- Changes: `44afcc8d3f86`, `47cc1764dc2c`, `347442ddc80a`, `efd68fe04400`, `c1a3e16c3289` +- Merge events: `535b33c95f94`, `eed6ba2734bc` +- Files: `gateway/platforms/base.py`, `gateway/run.py`, `gateway/stream_consumer.py`, `plugins/platforms/discord/adapter.py`, `tests/gateway/test_code_fence_tracking.py`, `tests/gateway/test_escape_reasoning_fences.py`, `tests/gateway/test_truncation_fence_edge_case.py`, `tests/plugins/platforms/discord/test_edit_message_fence.py` +- Upstream matches: none +- Evidence: Survives in gateway/stream_consumer.py and Discord adapter/tests.; Frozen upstream already has escape_code_fences_for_display, ensure_closed_code_fences, and chunk balancing with equivalent behavior. +- Behavioral contracts: Untrusted backticks are escaped before outer wrapping.; Chunk balancing and truncation close open triple-backtick and inline-code spans.; Discord edit/truncation preserves the same user-visible balance guarantee. + +### `capability:session-fts-simple-eol` - fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs + +- Changes: `44dd4c5e586e`, `a4e2c52f1582`, `a1136e548ea1`, `c20cb64b4b79`, `f779b5320c60`, `196b90441737`, `85fd91fd7c7b`, `186986a44708`, `deb10243cceb`, `1d5b80cab802` +- Merge events: `dc2270aad842`, `433a49f66b44`, `53da9e89f8f3` +- Files: `docs/research/issue-19-simple-tokenizer-eol-implementation.md`, `docs/research/issue-40-simple-tokenizer-eol.md`, `hermes_state.py`, `tests/test_optional_cjk_tokenizer_fallback.py`, `tests/test_simple_tokenizer_eol.py` +- Upstream matches: none +- Evidence: Survives in hermes_state.py sanitizer/repair logic and the #19/#87 research and tests.; Frozen upstream has no load_simple_extension/simple-tokenizer compatibility shim; the legacy debt is already absent there. +- Behavioral contracts: Supported post-#12 databases do not require simple-tokenizer loading or repair branches.; Unsupported legacy residue is sanitized or rejected explicitly rather than silently kept writable.; Modern trigram/CJK lifecycle remains the canonical path. + +### `capability:configurable-reasoning-display` - feat: configurable reasoning max lines via display.reasoning_max_lines + +- Changes: `895ba96014ec` +- Merge events: `9fe97e2aa1b0` +- Files: `cli.py`, `gateway/run.py`, `tests/gateway/test_reasoning_max_lines.py` +- Upstream matches: none +- Evidence: Survives in cli.py/config parsing and gateway display code.; Frozen upstream hardcodes the first 15 lines and has no reasoning_max_lines seam. +- Behavioral contracts: reasoning_max_lines controls display truncation.; Invalid or absent configuration falls back safely.; Fence escaping remains applied before wrapping. + +### `capability:headroom-compression` - Add opt-in headroom tool-output compression plugin + +- Changes: `915913db360d`, `5eb552458de9`, `c16ebe6b8649`, `237176ed1d97` +- Merge events: `b7e62647bd65` +- Files: `hermes_cli/config.py`, `plugins/headroom/__init__.py`, `plugins/headroom/plugin.yaml`, `tests/plugins/test_headroom_plugin.py` +- Upstream matches: none +- Evidence: Survives in plugins/headroom, tools_config.py, plugin.yaml, pyproject.toml/uv.lock and plugin tests.; Frozen upstream has no headroom ContentRouter/SmartCrusher implementation. +- Behavioral contracts: Compression activates only at configured thresholds and does not expand tool-result metadata.; Failures degrade with warning/logging and preserve usable content.; Plugin registration and schema remain valid when active. + +### `non-capability:integration-merge` - Merge remote-tracking branch 'origin/main' into dev + +- Changes: (none) +- Merge events: `9d6accc0f3de`, `1602d06f5045`, `b66c149de0c8`, `637ef2e193b6` +- Files: (none) +- Upstream matches: none +- Evidence: Integrated behavior is represented by capability records on either side.; Merge topology is provenance, not semantic upstream evidence. +- Behavioral contracts: A merge event is not silently omitted merely because it has no patch-id or changed-file payload. + +### `capability:browser-timeout-cleanup` - fix(browser): config-gated daemon kill on timeout + +- Changes: `a2450695db0e`, `b42bc25e622c`, `cfb2636a6a3e` +- Merge events: `9e3439835e9d`, `8a0a1a145e22` +- Files: `.github/actions/hermes-smoke-test/action.yml`, `.github/workflows/build-windows-installer.yml`, `.github/workflows/docker-publish.yml`, `.github/workflows/nix-lockfile-fix.yml`, `.github/workflows/nix.yml`, `agent/gemini_cloudcode_adapter.py`, `agent/google_code_assist.py`, `agent/google_oauth.py`, `apps/desktop/src/app/chat/composer/skin-slash-popover.tsx`, `apps/desktop/src/app/cron/cron-job-actions-menu.tsx`, `apps/desktop/src/app/overlays/overlay-search-input.tsx`, `apps/desktop/src/app/right-sidebar/terminal/index.tsx`, `apps/desktop/src/app/session/hooks/use-message-stream.ts`, `apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx`, `apps/desktop/src/app/session/hooks/use-prompt-actions.ts`, `apps/desktop/src/app/session/hooks/use-session-actions.ts`, `apps/desktop/src/components/assistant-ui/streaming.test.tsx`, `apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx`, `apps/desktop/src/components/assistant-ui/thread.tsx`, `apps/desktop/src/components/assistant-ui/todo-tool.tsx`, `apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx`, `apps/desktop/src/components/assistant-ui/tool-approval.test.tsx`, `apps/desktop/src/components/assistant-ui/tool-approval.tsx`, `apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts`, `apps/desktop/src/components/assistant-ui/tool-fallback-model.ts`, `apps/desktop/src/components/assistant-ui/tool-fallback.tsx`, `apps/desktop/src/components/assistant-ui/user-message-text.tsx`, `apps/desktop/src/components/chat/generated-image-context.tsx`, `apps/desktop/src/components/desktop-onboarding-overlay.test.tsx`, `apps/desktop/src/components/desktop-onboarding-overlay.tsx`, `apps/desktop/src/components/ui/braille-spinner.tsx`, `apps/desktop/src/lib/gateway-ws-url.ts`, `gateway/platforms/dingtalk.py`, `gateway/platforms/email.py`, `gateway/platforms/feishu.py`, `gateway/platforms/feishu_comment.py`, `gateway/platforms/feishu_comment_rules.py`, `gateway/platforms/feishu_meeting_invite.py`, `gateway/platforms/homeassistant.py`, `gateway/platforms/matrix.py`, `gateway/platforms/slack.py`, `gateway/platforms/sms.py`, `gateway/platforms/telegram.py`, `gateway/platforms/telegram_network.py`, `gateway/platforms/wecom.py`, `gateway/platforms/wecom_callback.py`, `gateway/platforms/wecom_crypto.py`, `gateway/platforms/whatsapp.py`, `optional-skills/productivity/shop-app/SKILL.md`, `plans/gemini-oauth-provider.md`, `tests/tools/test_browser_terminate_daemon_timeout.py`, `tests/tools/test_browser_timeout_cleanup.py`, `tools/browser_tool.py` +- Upstream matches: none +- Evidence: Survives in tools/browser_tool.py and timeout cleanup/daemon tests.; Frozen upstream has timeout cleanup/orphan reaping but not terminate_daemon_on_timeout configuration behavior. +- Behavioral contracts: Timeout cleanup clears in-memory browser state in a finally-equivalent path.; Daemon termination is opt-in/config-gated.; Cleanup failures are contained and test-covered. + +### `capability:memory-trim-policy` - fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim + +- Changes: `a9d2b9af4f80` +- Merge events: (none) +- Files: `hermes_cli/mem_trim.py` +- Upstream matches: none +- Evidence: Frozen fork hermes_cli/mem_trim.py adds threshold_mb and gc_cooldown_seconds policy gates.; Frozen upstream hermes_cli/mem_trim.py has a general trim cooldown but no RSS low-water gate or independent GC cooldown. +- Behavioral contracts: RSS below threshold_mb skips the expensive trim work on housekeeping ticks.; gc.collect() runs at most once per gc_cooldown_seconds while malloc_trim remains eligible on the normal trim cadence.; Force behavior and invalid configuration retain explicit safe fallbacks. + +### `non-capability:performance-validation` - perf(search): batch context queries — chunked session_id batches (20/sql) + +- Changes: `b879cbd332b8`, `7b66bbf8e2af` +- Merge events: `a34da2c31ca6` +- Files: `hermes_state.py`, `scripts/benchmarks/session_metadata_picker.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: Benchmark and query-shape changes remain visible in history.; No upstream equivalence is inferred from local measurements. +- Behavioral contracts: A benchmark supports a decision but does not prove equivalence or impose an unreviewed target. + +### `capability:session-fts-unicode` - fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries + +- Changes: `c3f1abc5cc34`, `2ac803bd949f`, `9b25b0c8bd74`, `e94f2630a50d`, `a4ceb2521b8b` +- Merge events: (none) +- Files: `docs/design/session-metadata-fts.md`, `docs/research/issue-32-stable-row-id-unicode-session-fts.md`, `hermes_cli/session_recovery.py`, `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_session_metadata_fts.py` +- Upstream matches: none +- Evidence: Survives in hermes_state.py, hermes_state_common.py, hermes_state_schema.py, hermes_state_search.py, hermes_cli/session_recovery.py and tests/test_session_metadata_fts.py.; Frozen upstream has messages_fts but no equivalent sessions_fts metadata index. +- Behavioral contracts: Stable sessions.row_id is retained across hidden rows and gaps.; External-content FTS indexes title, id, and display_name with resumable high-water backfill.; Backfill and triggers preserve delete correctness and never expose hidden sessions. + +### `capability:session-search-routing` - fix(session-search): define ranked_candidates for LIKE route + +- Changes: `ca4d3041a5e0`, `099080332349`, `5882274ff6c8`, `3f4795a9fbc7`, `b4efc640fab0`, `b97d00e7319e`, `3ebb2592c141` +- Merge events: `35c8564c9c0a` +- Files: `apps/desktop/src/components/session-picker.test.tsx`, `apps/desktop/src/components/session-picker.tsx`, `apps/desktop/src/hermes.test.ts`, `apps/desktop/src/hermes.ts`, `apps/desktop/src/i18n/en.ts`, `apps/desktop/src/i18n/types.ts`, `apps/desktop/src/i18n/zh.ts`, `hermes_cli/web_routers/profiles.py`, `hermes_cli/web_routers/sessions.py`, `hermes_state.py`, `scripts/benchmarks/session_metadata_picker.py`, `tests/hermes_cli/test_web_server.py`, `tests/hermes_cli/test_web_server_session_search.py`, `tests/test_session_metadata_picker_routing.py` +- Upstream matches: none +- Evidence: Survives in hermes_state.py, hermes_state_search.py, web session/profile routers, desktop picker code and routing tests.; Frozen upstream has session ID/title primitives but no equivalent metadata-index router. +- Behavioral contracts: Unicode, CJK, and infix queries select their intended index; LIKE is bounded fallback.; FTS narrows IDs before lineage hydration; only empty successful FTS triggers fallback.; Visibility, archive/pin/source filters, lineage, branch markers, whole-store scope, and limits remain correct. + +### `non-capability:incidental-hardening` - fix: exponential backoff, slow-write log, and Discord API delivery log + +- Changes: `cc2531fbc6df`, `9f3056cb3a96`, `4270ea5b9a90` +- Merge events: (none) +- Files: `.gitignore`, `hermes_state.py`, `plugins/platforms/discord/adapter.py`, `tests/tools/test_web_searxng_e2e.py` +- Upstream matches: none +- Evidence: Record-specific survival is visible in the frozen tree.; No equivalence claim is made without focused comparison. +- Behavioral contracts: The safety invariant remains visible in record subject/files while capability ownership is unresolved. + +### `non-capability:production-evidence` - docs(recovery): attest production gateway runtime surface + +- Changes: `cea5282a181d`, `311bf7d6d28b`, `0460c1944c8c`, `8b085795df03`, `4292711d0a7c` +- Merge events: `bee13fc08507` +- Files: `docs/research/issue-22-production-ready-state-db-execution.md`, `research/recovery/issue-21-production-runtime-runbook.md`, `research/recovery/issue-41-production-gateway-runtime-attestation.md` +- Upstream matches: none +- Evidence: Survives as docs/research and research/recovery artifacts.; No code-level equivalence is claimed from operational documents. +- Behavioral contracts: Operational records remain durable evidence and are not mistaken for code-level equivalence. + +### `capability:session-title-safety` - test(session): pin literal-safe numbered-title resolution (#15) + +- Changes: `d18dadb5f3b5`, `faf96ef221dd`, `69bee0838ae1`, `17b0d2c9135d` +- Merge events: `984eff15df1f`, `dcf8096413c7` +- Files: `docs/design/session-metadata-fts.md`, `docs/research/issue-38-numbered-title-literal-safety.md`, `hermes_state.py`, `hermes_state_common.py`, `tests/test_hermes_state.py`, `tests/test_session_metadata_cjk_fts.py`, `tests/test_session_metadata_fts.py` +- Upstream matches: none +- Evidence: Survives in hermes_state.py, hermes_state_common.py and title/metadata tests.; Frozen upstream escapes LIKE but does not enforce the fork's strict numeric suffix filter. +- Behavioral contracts: Escape SQL LIKE literals independently from Python literals.; Only strict ASCII #N suffixes are variants; %, _, \, #, CJK, and literal titles stay exact and safe.; The public resolution API and root/current exclusion semantics remain unchanged. + +### `capability:cron-nul-safety` - fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762) + +- Changes: `d53e209b3b62` +- Merge events: (none) +- Files: `cron/lifecycle_guard.py`, `tools/terminal_tool.py` +- Upstream matches: none +- Evidence: Survives in cron/lifecycle_guard.py and tools/terminal_tool.py.; Frozen upstream contains the corresponding NUL/binary-safe guard and terminal fallback. +- Behavioral contracts: NUL-bearing input does not reach unsafe process/lifecycle calls.; Terminal fallback returns a clear failure rather than truncating at NUL. + +Discovery completeness: **PASS** — 171 of 171 records emitted. +Capability accounting: **PASS** - explicit disposition mapping is required before this gate can pass. diff --git a/artifacts/fork-archaeology-issue-96/inventory.json b/artifacts/fork-archaeology-issue-96/inventory.json new file mode 100644 index 000000000000..3a7c97831039 --- /dev/null +++ b/artifacts/fork-archaeology-issue-96/inventory.json @@ -0,0 +1,6179 @@ +{ + "schema_version": 3, + "inputs": { + "fork_ref": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "upstream_ref": "460d345642ee3d143a3e461abe39fd42b86a7e54", + "merge_base": "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53" + }, + "provenance_buckets": [ + { + "id": "pr:31", + "record_type": "provenance_bucket", + "subject": "test(fts): pin storage-v2 refusal states (#31)", + "commits": [ + { + "sha": "00a2675a9270033325d53d7a3301a58f5f66d760", + "subject": "test(fts): pin storage-v2 refusal states (#31)", + "parents": [ + "9d140c8594c67ed37729b190fd3733508d0d770c" + ], + "is_merge": false, + "patch_id": "ea3822aa15120604e3a6d5f5a852662423003e79", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "b86e4f526ec377f7f958dc21ddaac87238882f19", + "subject": "fix(fts): unify storage-v2 settlement predicate (#31)", + "parents": [ + "00a2675a9270033325d53d7a3301a58f5f66d760" + ], + "is_merge": false, + "patch_id": "e6c4a15ba13108650949d288ca82785d8166b51c", + "changed_files": [ + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "2c907113fd2c50edde60425c561ab8ca25192b1b", + "subject": "test(fts): cover storage-v2 interruption/reopen + acceptance matrix (#31)", + "parents": [ + "b86e4f526ec377f7f958dc21ddaac87238882f19" + ], + "is_merge": false, + "patch_id": "8be42f87431ece49aef3ef6eda2ad8facc6b629e", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "f887f44fa2d27c7ec4132fe70d337f7975fcde63", + "subject": "docs(research): record storage-v2 settlement implementation (#31)", + "parents": [ + "2c907113fd2c50edde60425c561ab8ca25192b1b" + ], + "is_merge": false, + "patch_id": "36092365b27afdd43694a21941d8b1305fb7d4a7", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "180ae82a2d7ec34a099665d68719c8579986d693", + "subject": "test(fts): pin structural refusal branches (#31)", + "parents": [ + "f887f44fa2d27c7ec4132fe70d337f7975fcde63" + ], + "is_merge": false, + "patch_id": "a6766363f406ec162858de31b5d44c20a81f94ab", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "1d6d73f3bb8ffeb599799c05b6e853da1758b4db", + "subject": "refactor(fts): settle review-round findings (#31)", + "parents": [ + "180ae82a2d7ec34a099665d68719c8579986d693" + ], + "is_merge": false, + "patch_id": "dbc62ce587beeee1e059967839673e3aaa6e7661", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "0fafc1dd7b58f15982ce2833de2bc8826a1e116f", + "subject": "test(fts): pin mixed-capability optimize availability (#31)", + "parents": [ + "1d6d73f3bb8ffeb599799c05b6e853da1758b4db" + ], + "is_merge": false, + "patch_id": "59e36add923089ed523051231c1299b4abf2d90d", + "changed_files": [ + "tests/test_fts_storage_v2_settlement.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "67d4f719d6b0717be024861ae2756fa49d6f1315", + "subject": "fix(fts): optimize-available sees any actionable blocker (#31)", + "parents": [ + "0fafc1dd7b58f15982ce2833de2bc8826a1e116f" + ], + "is_merge": false, + "patch_id": "6e1e369dc56114dd292a0e4b3bd2e5416e3af4a5", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + { + "sha": "0ff8583e91c838088fde6cb55ba0488cf5a0ee93", + "subject": "docs(research): fix settlement test count in validation note (#31)", + "parents": [ + "67d4f719d6b0717be024861ae2756fa49d6f1315" + ], + "is_merge": false, + "patch_id": "baae4280be968b7103ce48254bb258f2b197b653", + "changed_files": [ + "docs/research/issue-31-storage-v2-settlement.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "31" + ] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-31-storage-v2-settlement.md", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_fts_storage_v2_settlement.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "31" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:27", + "record_type": "provenance_bucket", + "subject": "feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27)", + "commits": [ + { + "sha": "00e680a8cb22e251f351b9f140b0679c4f96dabc", + "subject": "feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27)", + "parents": [ + "919f4469e832bc2b38bba0ea5af26b842bf91acd" + ], + "is_merge": false, + "patch_id": "4cc0cf6fd0285b48b07de0d623e5b6f71c89ced2", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py", + "tests/test_hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1", + "subject": "feat(fts): registry-driven health probes + trigger inventory/convergence (#27)", + "parents": [ + "00e680a8cb22e251f351b9f140b0679c4f96dabc" + ], + "is_merge": false, + "patch_id": "c03104d48d06f2c67ded35771f87f567dc9772cf", + "changed_files": [ + "hermes_state.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py", + "tests/test_hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "474b88fe76e18dfcf397f11b3de6f069abac4a4c", + "subject": "fix(fts): registry-driven offline + destructive repair covers session indexes (#27)", + "parents": [ + "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1" + ], + "is_merge": false, + "patch_id": "59a851149da5001ab1a18c3ad5c8ba10df56d4c2", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "f9ade6baff7f236b6b9401932c61bc0400375664", + "subject": "feat(fts): read-only session capability discovery + shared rebuild-lane iteration (#27)", + "parents": [ + "474b88fe76e18dfcf397f11b3de6f069abac4a4c" + ], + "is_merge": false, + "patch_id": "d013bec5f0358ab899f7993e871a3093a7116025", + "changed_files": [ + "hermes_state.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "e64ad007b459871af42e312bc5dffd2da92ac900", + "subject": "test(fts): six-index regression matrix for maintenance/repair/read-only/degraded-runtime (#27)", + "parents": [ + "f9ade6baff7f236b6b9401932c61bc0400375664" + ], + "is_merge": false, + "patch_id": "0a5b70525caec36a605aae57384aacac5b8e90c1", + "changed_files": [ + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "0400c66f072d0f319331ea105cd8f7e059975388", + "subject": "refactor(fts): apply review round \u2014 drop dead lane keys, merge trigger-drop + CJK quarantine helpers, remove dead _FTS_TRIGGERS (#27)", + "parents": [ + "bdd9d699f6dc13b32852a078c1ecf5664bcb837d" + ], + "is_merge": false, + "patch_id": "7e550cd252dbc36097b938f127f97b9b731c3185", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec", + "subject": "fix(fts): reuse #30 ownership classifier in offline/global paths + read-only CJK worker fix (#27)", + "parents": [ + "75223d19544ceb73cf24fb859fc0780ed9a099a5" + ], + "is_merge": false, + "patch_id": "6ef28296f1a5c6fcf5fa7184766aed7bec89a165", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a", + "subject": "fix(fts): read-only trigram discovery gates on full #30 namespace ownership (#27)", + "parents": [ + "dc1f153a71d025d903f255861da57f94d649ca37" + ], + "is_merge": false, + "patch_id": "3990d58681775d1e2600ae6aa742605ec0959bdd", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "3bc7d3f58f808e269675404c9bbeada467b00e98", + "subject": "refactor(fts): ponytail pass \u2014 drop redundant tests, shrink review history + comments (#27)", + "parents": [ + "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d" + ], + "is_merge": false, + "patch_id": "fa519cb6863f833f9d6e38617139dc13eb873437", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md", + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + { + "sha": "d6a4d70483623cc3fad4eea8c96754d7d637d02c", + "subject": "fix(fts): read-only trigram serving requires a complete trigger set (#27)", + "parents": [ + "3bc7d3f58f808e269675404c9bbeada467b00e98" + ], + "is_merge": false, + "patch_id": "b517dd7e0ef43f48969fad2401b82585453001ea", + "changed_files": [ + "hermes_state.py", + "tests/test_fts_lifecycle_registry.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "27" + ] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_fts_lifecycle_registry.py", + "tests/test_hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "27" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57", + "record_type": "provenance_bucket", + "subject": "docs(research): record #22 production-ready state.db build and freeze", + "commits": [ + { + "sha": "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57", + "subject": "docs(research): record #22 production-ready state.db build and freeze", + "parents": [ + "4e5ad5c2230300d1ffae84b089ffc70e368c8a23" + ], + "is_merge": false, + "patch_id": "3445dddcd1a9f3590543c01fe8be46376d09bdc0", + "changed_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:04f1af72be078cef69de538f1519f93a73088b0d", + "record_type": "provenance_bucket", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold", + "commits": [ + { + "sha": "04f1af72be078cef69de538f1519f93a73088b0d", + "subject": "feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold", + "parents": [ + "2ac803bd949f0aba96c0d4d500edd2ad65aa3036" + ], + "is_merge": false, + "patch_id": "b793dd29722b01e260b13a1b2e3be1c2708c1071", + "changed_files": [ + "hermes_cli/mem_trim.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_cli/mem_trim.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:0990803323497a36761c9627a20ceb57be56d5a3", + "record_type": "provenance_bucket", + "subject": "test(state): pin session metadata route and fallback contract", + "commits": [ + { + "sha": "0990803323497a36761c9627a20ceb57be56d5a3", + "subject": "test(state): pin session metadata route and fallback contract", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72" + ], + "is_merge": false, + "patch_id": "93d8f3d69bcc25ace9213068d009e2d5b442b721", + "changed_files": [ + "tests/test_session_metadata_picker_routing.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/test_session_metadata_picker_routing.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:0a4b567ff08776a3a10ee7a32d37332d873f20b2", + "record_type": "provenance_bucket", + "subject": "feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin", + "commits": [ + { + "sha": "0a4b567ff08776a3a10ee7a32d37332d873f20b2", + "subject": "feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin", + "parents": [ + "88d1d6206f399c134d1f4c0b7db27733aaa3c50c" + ], + "is_merge": false, + "patch_id": "07479905dc72c5af558b5f005436aae7a06883f7", + "changed_files": [ + "plugins/headroom/__init__.py", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/headroom/__init__.py", + "tests/plugins/test_headroom_plugin.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:0b4e7601227a23bc653d0d3018a3a9591d02f2a1", + "record_type": "provenance_bucket", + "subject": "fix: headroom_retrieve tool schema \u2014 add description and parameters wrapper", + "commits": [ + { + "sha": "0b4e7601227a23bc653d0d3018a3a9591d02f2a1", + "subject": "fix: headroom_retrieve tool schema \u2014 add description and parameters wrapper", + "parents": [ + "b527e4df996b859356c0c48c2b9c9eae4c74c4dc" + ], + "is_merge": false, + "patch_id": "a0f94a678e9036aeb39b681623ee5764600672d7", + "changed_files": [ + "plugins/headroom/__init__.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/headroom/__init__.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:0cf4cd0baffb68b571a44f2a39d3bf817cd38348", + "record_type": "provenance_bucket", + "subject": "docs(fts): record review round 4 for #27 unified FTS lifecycle", + "commits": [ + { + "sha": "0cf4cd0baffb68b571a44f2a39d3bf817cd38348", + "subject": "docs(fts): record review round 4 for #27 unified FTS lifecycle", + "parents": [ + "d6a4d70483623cc3fad4eea8c96754d7d637d02c" + ], + "is_merge": false, + "patch_id": "2141bb1e322a2a97fc4e6a3e8c49f3442f440876", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:65", + "record_type": "provenance_bucket", + "subject": "fix(session-fts): run CJK guard+MATCH in one SQLite snapshot (PR #65 P1)", + "commits": [ + { + "sha": "0eee69ef43f16c63f29db414e1acb40253212125", + "subject": "fix(session-fts): run CJK guard+MATCH in one SQLite snapshot (PR #65 P1)", + "parents": [ + "6b3402ea05566fa1553a93aceb285eb517d7e67d" + ], + "is_merge": false, + "patch_id": "56e4c8cbae6fd638c7dd752e22c786b2b15ea542", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "65" + ] + } + ], + "merge_events": [ + { + "sha": "bdf2fc218264538c4f3238b58532488fe665ff9e", + "subject": "Merge pull request #65 from Skywind5487/fts/session-cjk-highwater", + "parents": [ + "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "0eee69ef43f16c63f29db414e1acb40253212125" + ], + "changed_files": [], + "pr_refs": [ + "65" + ] + } + ], + "affected_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "65" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "record_type": "provenance_bucket", + "subject": "fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search", + "commits": [ + { + "sha": "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "subject": "fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search", + "parents": [ + "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f" + ], + "is_merge": false, + "patch_id": "90547021582ed1ce1d9c37bda280a80d647558e6", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:1602d06f5045d173ee31161b92e387de69ab821c", + "record_type": "provenance_bucket", + "subject": "merge(session-search): ranked Top-N + late-snippet into dev", + "commits": [], + "merge_events": [ + { + "sha": "1602d06f5045d173ee31161b92e387de69ab821c", + "subject": "merge(session-search): ranked Top-N + late-snippet into dev", + "parents": [ + "237176ed1d973910972984ba83d876d01c00f3db", + "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "record_type": "provenance_bucket", + "subject": "feat: add lifecycle and SQLite observability telemetry", + "commits": [ + { + "sha": "176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "subject": "feat: add lifecycle and SQLite observability telemetry", + "parents": [ + "237176ed1d973910972984ba83d876d01c00f3db" + ], + "is_merge": false, + "patch_id": "124834046966eb0142fabdd8849eafdc9df72403", + "changed_files": [ + "agent/conversation_compression.py", + "agent/conversation_loop.py", + "agent/diagnostic_config.py", + "agent/kernel_telemetry.py", + "agent/lifecycle_telemetry.py", + "agent/sqlite_native_telemetry.py", + "agent/tool_executor.py", + "agent/turn_context.py", + "docs/observability/session-db-api-handoff.md", + "gateway/run.py", + "gateway/stream_consumer.py", + "hermes_cli/config.py", + "hermes_state.py", + "plugins/memory/holographic/__init__.py", + "plugins/platforms/discord/adapter.py", + "scripts/hermes_kernel_trace.py", + "tests/agent/test_lifecycle_telemetry.py", + "tests/agent/test_tool_lifecycle_telemetry.py", + "tests/gateway/test_discord_delivery_lifecycle_telemetry.py", + "tests/gateway/test_stream_lifecycle_telemetry.py", + "tests/plugins/memory/test_holographic_prefetch_gate.py", + "tests/test_machine_health_collector.py", + "tests/test_optional_cjk_tokenizer_fallback.py", + "tests/test_session_db_lock_telemetry.py", + "tests/test_sqlite_kernel_telemetry.py", + "tests/test_sqlite_owner_telemetry.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "agent/conversation_compression.py", + "agent/conversation_loop.py", + "agent/diagnostic_config.py", + "agent/kernel_telemetry.py", + "agent/lifecycle_telemetry.py", + "agent/sqlite_native_telemetry.py", + "agent/tool_executor.py", + "agent/turn_context.py", + "docs/observability/session-db-api-handoff.md", + "gateway/run.py", + "gateway/stream_consumer.py", + "hermes_cli/config.py", + "hermes_state.py", + "plugins/memory/holographic/__init__.py", + "plugins/platforms/discord/adapter.py", + "scripts/hermes_kernel_trace.py", + "tests/agent/test_lifecycle_telemetry.py", + "tests/agent/test_tool_lifecycle_telemetry.py", + "tests/gateway/test_discord_delivery_lifecycle_telemetry.py", + "tests/gateway/test_stream_lifecycle_telemetry.py", + "tests/plugins/memory/test_holographic_prefetch_gate.py", + "tests/test_machine_health_collector.py", + "tests/test_optional_cjk_tokenizer_fallback.py", + "tests/test_session_db_lock_telemetry.py", + "tests/test_sqlite_kernel_telemetry.py", + "tests/test_sqlite_owner_telemetry.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:196b904417371cf233f3eb9b560c80a079ab8d72", + "record_type": "provenance_bucket", + "subject": "docs(research): map simple-tokenizer EOL for #40", + "commits": [ + { + "sha": "196b904417371cf233f3eb9b560c80a079ab8d72", + "subject": "docs(research): map simple-tokenizer EOL for #40", + "parents": [ + "bee13fc085079d78d0334722ad4c37a1144e3102" + ], + "is_merge": false, + "patch_id": "a144398c69ababcec83ff82c28e880e3d74f8667", + "changed_files": [ + "docs/research/issue-40-simple-tokenizer-eol.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-40-simple-tokenizer-eol.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "record_type": "provenance_bucket", + "subject": "docs(research): map normalized session trigram FTS", + "commits": [ + { + "sha": "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "subject": "docs(research): map normalized session trigram FTS", + "parents": [ + "6311e77e27f4fd4009c73d0df16abebf56121f4a" + ], + "is_merge": false, + "patch_id": "b9c2c784c05bb406213054d376b6c98bd2feb8e2", + "changed_files": [ + "docs/research/issue-34-normalized-session-metadata-trigram-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-34-normalized-session-metadata-trigram-fts.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:1f5edc591353a0a65ec7aa2f02c6916fd67fd505", + "record_type": "provenance_bucket", + "subject": "perf(state): narrow session listing before lineage hydration", + "commits": [ + { + "sha": "1f5edc591353a0a65ec7aa2f02c6916fd67fd505", + "subject": "perf(state): narrow session listing before lineage hydration", + "parents": [ + "5882274ff6c868c24f9d36f3796de08e5de8a245" + ], + "is_merge": false, + "patch_id": "a147ecf6c85ea4f4e0483e02ae7baa638cf3e17f", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:237176ed1d973910972984ba83d876d01c00f3db", + "record_type": "provenance_bucket", + "subject": "fix(headroom): prevent metadata from expanding tool results", + "commits": [ + { + "sha": "237176ed1d973910972984ba83d876d01c00f3db", + "subject": "fix(headroom): prevent metadata from expanding tool results", + "parents": [ + "b7e62647bd657a429d967cfa77034632ee490f9a" + ], + "is_merge": false, + "patch_id": "01605c62358b5fa3574a4d392ad37783879af619", + "changed_files": [ + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:2732c47e28fbf7aaea97bd8c5cf82045a4c34159", + "record_type": "provenance_bucket", + "subject": "wip(session-search): move winner selection into SQL", + "commits": [ + { + "sha": "2732c47e28fbf7aaea97bd8c5cf82045a4c34159", + "subject": "wip(session-search): move winner selection into SQL", + "parents": [ + "176646d2cd6c95fa49b9414f21ed9e781b0aaa84" + ], + "is_merge": false, + "patch_id": "ad8d732bb386962695417cd36f99490d9497a1c4", + "changed_files": [ + "hermes_state.py", + "tests/test_session_search_sql_winners.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "tests/test_session_search_sql_winners.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:78", + "record_type": "provenance_bucket", + "subject": "Merge pull request #78 from Skywind5487/feat/31-storage-v2-settlement", + "commits": [], + "merge_events": [ + { + "sha": "276d497764feb7d4a71f1424ed44b8958da63b16", + "subject": "Merge pull request #78 from Skywind5487/feat/31-storage-v2-settlement", + "parents": [ + "9d140c8594c67ed37729b190fd3733508d0d770c", + "0ff8583e91c838088fde6cb55ba0488cf5a0ee93" + ], + "changed_files": [], + "pr_refs": [ + "78" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "78" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:296d9c6e2e5a6f852344ad8fa9b90f5687912be1", + "record_type": "provenance_bucket", + "subject": "feat: add transform_api_request plugin hook for full-payload request transformation", + "commits": [ + { + "sha": "296d9c6e2e5a6f852344ad8fa9b90f5687912be1", + "subject": "feat: add transform_api_request plugin hook for full-payload request transformation", + "parents": [ + "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71" + ], + "is_merge": false, + "patch_id": "ff3b268ee596e2ce358d5d1df44c76d54b5d88d7", + "changed_files": [ + "agent/conversation_loop.py", + "hermes_cli/hooks.py", + "hermes_cli/plugins.py", + "tests/run_agent/test_run_agent.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "agent/conversation_loop.py", + "hermes_cli/hooks.py", + "hermes_cli/plugins.py", + "tests/run_agent/test_run_agent.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:2ac803bd949f0aba96c0d4d500edd2ad65aa3036", + "record_type": "provenance_bucket", + "subject": "feat(session-search): port sessions FTS5 title index (unicode61 + cjk_unicode61) from dev", + "commits": [ + { + "sha": "2ac803bd949f0aba96c0d4d500edd2ad65aa3036", + "subject": "feat(session-search): port sessions FTS5 title index (unicode61 + cjk_unicode61) from dev", + "parents": [ + "b66c149de0c8240e84ded1a2f983b8c42f7b984b" + ], + "is_merge": false, + "patch_id": "5c37e63fdd564f04c6c5275ee37ac7d7ce35dc7c", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:2d2bad204ec644455ad1273f2934f388eb4111dd", + "record_type": "provenance_bucket", + "subject": "fix(session-search): defer winner snippets", + "commits": [ + { + "sha": "2d2bad204ec644455ad1273f2934f388eb4111dd", + "subject": "fix(session-search): defer winner snippets", + "parents": [ + "2732c47e28fbf7aaea97bd8c5cf82045a4c34159" + ], + "is_merge": false, + "patch_id": "def0769bc836f46501f776b616908b3bfb592aae", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:2e1b2e64d7a452f524f703a99d68b1b110b93d3e", + "record_type": "provenance_bucket", + "subject": "test(search): drop stale generic-parent oracle import after #68 flip", + "commits": [ + { + "sha": "2e1b2e64d7a452f524f703a99d68b1b110b93d3e", + "subject": "test(search): drop stale generic-parent oracle import after #68 flip", + "parents": [ + "2f12b03079cb7ae28acf666d16cfd748e5eaac74" + ], + "is_merge": false, + "patch_id": "506042112841967f593cc6cb1368e22cab1fde5e", + "changed_files": [ + "tests/test_session_search_sql_winners.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/test_session_search_sql_winners.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:2f12b03079cb7ae28acf666d16cfd748e5eaac74", + "record_type": "provenance_bucket", + "subject": "feat(session-search): tool parity + truncation contract for #68", + "commits": [ + { + "sha": "2f12b03079cb7ae28acf666d16cfd748e5eaac74", + "subject": "feat(session-search): tool parity + truncation contract for #68", + "parents": [ + "46907bc8b55ba36ef73e0d96c10eccb9b28b0310" + ], + "is_merge": false, + "patch_id": "9cee1fa8910525a439c281470ec59cc172e0f33d", + "changed_files": [ + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:72", + "record_type": "provenance_bucket", + "subject": "Merge pull request #72 from Skywind5487/fix/68-compression-lineage-resolver", + "commits": [], + "merge_events": [ + { + "sha": "2f90c254d524d618b1c866a10bb519f2c1b6f5dc", + "subject": "Merge pull request #72 from Skywind5487/fix/68-compression-lineage-resolver", + "parents": [ + "bdf2fc218264538c4f3238b58532488fe665ff9e", + "b2710666a29eed6fc46f3b6ce23c72f4dc766181" + ], + "changed_files": [], + "pr_refs": [ + "72" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "72" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:3053abf3b039a5b4c23637597cb076f2339250fb", + "record_type": "provenance_bucket", + "subject": "fix: let all CJK queries use simple tokenizer; cache lineage resolves", + "commits": [ + { + "sha": "3053abf3b039a5b4c23637597cb076f2339250fb", + "subject": "fix: let all CJK queries use simple tokenizer; cache lineage resolves", + "parents": [ + "3de538d32a3c076929c1d7c173dd77e4055100f9" + ], + "is_merge": false, + "patch_id": "5446586b216cfe21c08c62a3b49d1d951af35ea4", + "changed_files": [ + "hermes_state.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:311bf7d6d28b204f0aa977ddcd05d44141d2d4ba", + "record_type": "provenance_bucket", + "subject": "docs(recovery): add production runtime repair runbook", + "commits": [ + { + "sha": "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba", + "subject": "docs(recovery): add production runtime repair runbook", + "parents": [ + "cea5282a181d23af471f4467f449fd9bfc022ca5" + ], + "is_merge": false, + "patch_id": "76b7fa3ba383db6dc4cc01a0d84dbb8ee9cb3d9f", + "changed_files": [ + "research/recovery/issue-21-production-runtime-runbook.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "research/recovery/issue-21-production-runtime-runbook.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:347442ddc80a2658582cb62dd268a0be024b1bcf", + "record_type": "provenance_bucket", + "subject": "fix: escape triple-backtick in reasoning before wrapping in outer code block", + "commits": [ + { + "sha": "347442ddc80a2658582cb62dd268a0be024b1bcf", + "subject": "fix: escape triple-backtick in reasoning before wrapping in outer code block", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "53c0ea1134e01cc4feecbc1eb1c0a753beae0544", + "changed_files": [ + "gateway/run.py", + "gateway/stream_consumer.py", + "tests/gateway/test_escape_reasoning_fences.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "gateway/run.py", + "gateway/stream_consumer.py", + "tests/gateway/test_escape_reasoning_fences.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:14", + "record_type": "provenance_bucket", + "subject": "feat(session): route session-metadata picker candidates through FTS (#14)", + "commits": [], + "merge_events": [ + { + "sha": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "subject": "feat(session): route session-metadata picker candidates through FTS (#14)", + "parents": [ + "dcf8096413c7ee40fe0ab512ac86927fb2092df1", + "637ef2e193b6b2dada5d0b79173461fca03fbf20" + ], + "changed_files": [], + "pr_refs": [ + "14" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "14" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:37811327cdc65c85c4b0bd565b1cdb3a4590dd91", + "record_type": "provenance_bucket", + "subject": "feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch", + "commits": [ + { + "sha": "37811327cdc65c85c4b0bd565b1cdb3a4590dd91", + "subject": "feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch", + "parents": [ + "a34da2c31ca60f9b5280558c514a3a1880035036" + ], + "is_merge": false, + "patch_id": "9c276d00c28333451c952522cd07793dc39f3a1f", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:3de538d32a3c076929c1d7c173dd77e4055100f9", + "record_type": "provenance_bucket", + "subject": "perf: reduce SELECT * in get_compression_lineage to 4 columns", + "commits": [ + { + "sha": "3de538d32a3c076929c1d7c173dd77e4055100f9", + "subject": "perf: reduce SELECT * in get_compression_lineage to 4 columns", + "parents": [ + "433a49f66b447f41fdd488dc4858a07c7cd7154d" + ], + "is_merge": false, + "patch_id": "c93153ba8a766a189a6fd3c9ae44c17ef1b9c5cd", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:26", + "record_type": "provenance_bucket", + "subject": "test(session-fts): RED contract for CJK session metadata lifecycle (#26)", + "commits": [ + { + "sha": "3e23375f7934e4315d45860e6992171fb5609c5c", + "subject": "test(session-fts): RED contract for CJK session metadata lifecycle (#26)", + "parents": [ + "6311e77e27f4fd4009c73d0df16abebf56121f4a" + ], + "is_merge": false, + "patch_id": "15678e6d9746a859d981383597c72d3038eadf46", + "changed_files": [ + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + { + "sha": "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7", + "subject": "feat(session-fts): external-content CJK metadata DDL + capability/quarantine (#26)", + "parents": [ + "3e23375f7934e4315d45860e6992171fb5609c5c" + ], + "is_merge": false, + "patch_id": "a97596e01ae3dcfbfacf20ae77704385338130b1", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + { + "sha": "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5", + "subject": "feat(session-fts): plug CJK session rebuild into the generic engine (#26)", + "parents": [ + "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7" + ], + "is_merge": false, + "patch_id": "267b89f092edf92cac9805b7d81d32c8aa0fbc81", + "changed_files": [ + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + { + "sha": "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128", + "subject": "feat(session-fts): CJK metadata candidate seam + all-3-field search (#26)", + "parents": [ + "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5" + ], + "is_merge": false, + "patch_id": "17de1b8d50273afbc3e1c4b59af7c5aabc8d25fe", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "26" + ] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "26" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:3ebb2592c141b232ecd0717adf32279afa6bee3f", + "record_type": "provenance_bucket", + "subject": "test(api): cross-profile resume search + desktop stale-response ordering", + "commits": [ + { + "sha": "3ebb2592c141b232ecd0717adf32279afa6bee3f", + "subject": "test(api): cross-profile resume search + desktop stale-response ordering", + "parents": [ + "6447a52cd994bf30c2811814f21095d12aba83ae" + ], + "is_merge": false, + "patch_id": "ac5fe312a1856bb33dae36d22f8c12139ce58f01", + "changed_files": [ + "apps/desktop/src/components/session-picker.test.tsx", + "tests/hermes_cli/test_web_server.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "apps/desktop/src/components/session-picker.test.tsx", + "tests/hermes_cli/test_web_server.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d", + "record_type": "provenance_bucket", + "subject": "feat(api): route session metadata discovery through the common seam", + "commits": [ + { + "sha": "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d", + "subject": "feat(api): route session metadata discovery through the common seam", + "parents": [ + "a615feaea695123d1b3a832417a9a76554301af8" + ], + "is_merge": false, + "patch_id": "6a16e8da3c72078417110de5201378d7a1a01de0", + "changed_files": [ + "hermes_cli/web_routers/profiles.py", + "hermes_cli/web_routers/sessions.py", + "tests/hermes_cli/test_web_server.py", + "tests/hermes_cli/test_web_server_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_cli/web_routers/profiles.py", + "hermes_cli/web_routers/sessions.py", + "tests/hermes_cli/test_web_server.py", + "tests/hermes_cli/test_web_server_session_search.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:4270ea5b9a903d0dcf692db2365875ac5b3fe319", + "record_type": "provenance_bucket", + "subject": "chore: ignore fts5_cjk Windows build artifact (.dll)", + "commits": [ + { + "sha": "4270ea5b9a903d0dcf692db2365875ac5b3fe319", + "subject": "chore: ignore fts5_cjk Windows build artifact (.dll)", + "parents": [ + "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128" + ], + "is_merge": false, + "patch_id": "cb5d25e94b43ca47ae67c178b3659682cb1ca145", + "changed_files": [ + ".gitignore" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + ".gitignore" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba", + "record_type": "provenance_bucket", + "subject": "docs(research): correct #22 path/router evidence with executing-query validation", + "commits": [ + { + "sha": "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba", + "subject": "docs(research): correct #22 path/router evidence with executing-query validation", + "parents": [ + "8b085795df0359adbf3c81315f888bc7041fb044" + ], + "is_merge": false, + "patch_id": "599bf839a067e86fa019becd0d2281c855e70bcd", + "changed_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:42c421f68b6556757c17b4dc78756cf31babd239", + "record_type": "provenance_bucket", + "subject": "fix(search): distinct-owner candidates + title-only K=1 snapshot contract (#68 review round-2)", + "commits": [ + { + "sha": "42c421f68b6556757c17b4dc78756cf31babd239", + "subject": "fix(search): distinct-owner candidates + title-only K=1 snapshot contract (#68 review round-2)", + "parents": [ + "f32b51764e43e48195d10e62d64b195a052d4968" + ], + "is_merge": false, + "patch_id": "a0684b71490f432735b53dd98c3edef3a7c41060", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:433a49f66b447f41fdd488dc4858a07c7cd7154d", + "record_type": "provenance_bucket", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "commits": [], + "merge_events": [ + { + "sha": "433a49f66b447f41fdd488dc4858a07c7cd7154d", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "parents": [ + "a4e2c52f1582952686ee56aaedd7285874326102", + "c20cb64b4b79468c641626e9b9d3957790f7a671" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:44afcc8d3f869c7780beb1bc0bece86df1e45cb2", + "record_type": "provenance_bucket", + "subject": "test: code fence tracking coverage for all send/split paths", + "commits": [ + { + "sha": "44afcc8d3f869c7780beb1bc0bece86df1e45cb2", + "subject": "test: code fence tracking coverage for all send/split paths", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "b895a539fdb73b927cacb2adbbb0a94a342a95b4", + "changed_files": [ + "tests/gateway/test_code_fence_tracking.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/gateway/test_code_fence_tracking.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:44dd4c5e586e60c22a322a9eb89d1aed63892e36", + "record_type": "provenance_bucket", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "commits": [ + { + "sha": "44dd4c5e586e60c22a322a9eb89d1aed63892e36", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "parents": [ + "b03c94dbed5ee72e97eace2376e02092cc854f6a" + ], + "is_merge": false, + "patch_id": "f0a0986406e7ad9f35acf9468e22096c12863e24", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:46907bc8b55ba36ef73e0d96c10eccb9b28b0310", + "record_type": "provenance_bucket", + "subject": "feat(search): compression-lineage resolver for #68 winner seam", + "commits": [ + { + "sha": "46907bc8b55ba36ef73e0d96c10eccb9b28b0310", + "subject": "feat(search): compression-lineage resolver for #68 winner seam", + "parents": [ + "8838d16060bb7610c6d7ad3697f384df3edb70c1" + ], + "is_merge": false, + "patch_id": "da306b1612a426d054dfbeec5be2893fe1f53978", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:47cc1764dc2c2c65cc83fe20500da939698d72d3", + "record_type": "provenance_bucket", + "subject": "fix: close orphaned code fences on all send paths", + "commits": [ + { + "sha": "47cc1764dc2c2c65cc83fe20500da939698d72d3", + "subject": "fix: close orphaned code fences on all send paths", + "parents": [ + "44afcc8d3f869c7780beb1bc0bece86df1e45cb2" + ], + "is_merge": false, + "patch_id": "430d612330245f9678d3de304083e690872ccf34", + "changed_files": [ + "gateway/platforms/base.py", + "gateway/stream_consumer.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "gateway/platforms/base.py", + "gateway/stream_consumer.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:30", + "record_type": "provenance_bucket", + "subject": "feat(fts): add normalized external-content session trigram index (#30)", + "commits": [ + { + "sha": "48b04dae36d6577b06de0efc67ebe1eb1a479d4c", + "subject": "feat(fts): add normalized external-content session trigram index (#30)", + "parents": [ + "ad0c45f0924349f6f0453d4941c3d76ad5258cdc" + ], + "is_merge": false, + "patch_id": "b8e035ae4b6b1c9e4e5cce7b1190a290b5a14cd5", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "6f82bcbb3c5f714148a17da47577e862493a55d6", + "subject": "test(fts): cover normalized session trigram end to end (#30)", + "parents": [ + "48b04dae36d6577b06de0efc67ebe1eb1a479d4c" + ], + "is_merge": false, + "patch_id": "cdc779c773f3856e71e403ba1787270dd2bd16ba", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "0f29f1454ea2227229e4056d66ed09f749a06e46", + "subject": "docs(research): document normalized session trigram FTS implementation (#30)", + "parents": [ + "6f82bcbb3c5f714148a17da47577e862493a55d6" + ], + "is_merge": false, + "patch_id": "cbaa4bf962d983e59eb764e6cd28798f689e19c1", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3", + "subject": "fix(fts): clear unfulfillable trigram claim on tokenizer-less host + de-dup shared seams (#30)", + "parents": [ + "0f29f1454ea2227229e4056d66ed09f749a06e46" + ], + "is_merge": false, + "patch_id": "0ffb111eb64fc8a9e80a3373f97e76ac3b796b76", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "252920f02442b68391fcafba35bef2c9567e9ab8", + "subject": "style(fts): consolidate session trigram ensure epilogue + spec-driven transition columns (#30)", + "parents": [ + "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3" + ], + "is_merge": false, + "patch_id": "1231df15565fbd033918e08b660707cbca26ea50", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "4483194b81495dab9b3c4c282c08adad89e0f2d9", + "subject": "fix(fts): classify session trigram schema by exact logical columns + VIEW projection (#30)", + "parents": [ + "252920f02442b68391fcafba35bef2c9567e9ab8" + ], + "is_merge": false, + "patch_id": "be11555049e9ec52dd80b13d2acd5d918c4fe06b", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "bfa928d53da7c61814816c10f83fef75bfef7e43", + "subject": "fix(fts): require canonical source VIEW + FTS5 root for modern trigram identity (#30)", + "parents": [ + "4483194b81495dab9b3c4c282c08adad89e0f2d9" + ], + "is_merge": false, + "patch_id": "d8134dfc7967102cd493d1858ec78ec46fae13ac", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "cc5261ce775c8db6a7099d411f16030d24e71f2f", + "subject": "fix(fts): classify legacy session trigram by DDL, never PRAGMA table_info (#30)", + "parents": [ + "bfa928d53da7c61814816c10f83fef75bfef7e43" + ], + "is_merge": false, + "patch_id": "1866b109815970cec2afd7bfe33acc92393e6adf", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "e33b533e1d2421fb18941463b6fe51752a8ad345", + "subject": "fix(fts): classify modern session trigram by DDL, never PRAGMA table_info (#30)", + "parents": [ + "cc5261ce775c8db6a7099d411f16030d24e71f2f" + ], + "is_merge": false, + "patch_id": "6a3e15bffb010d61a4cd01938a1857fdbde253d6", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "b5155410abbf04c1fc4bb433ae3f5e546f5bf426", + "subject": "fix(fts): gate trigram source VIEW ensure on source compatibility (#30)", + "parents": [ + "e33b533e1d2421fb18941463b6fe51752a8ad345" + ], + "is_merge": false, + "patch_id": "436fcf2cc4247cafe5e93960272ed36328ac2755", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "9aad13bcad68a292f708fe30698405c2016b2626", + "subject": "fix(fts): classify same-name root VIEW as unknown, not absent (#30)", + "parents": [ + "b5155410abbf04c1fc4bb433ae3f5e546f5bf426" + ], + "is_merge": false, + "patch_id": "23a52086a686f6df207c1790e01f0fe0ed29d666", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "3172c9f4611cc2b872f2083829577cc73152f9dc", + "subject": "fix(fts): exact shadow allowlist + classify same-name root index as unknown (#30)", + "parents": [ + "9aad13bcad68a292f708fe30698405c2016b2626" + ], + "is_merge": false, + "patch_id": "1c240e6ff04b0e1ea6c47a63c818feca035cf6f8", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "6467a30563fb1da2bd5c1f42dc7cd1f574697d31", + "subject": "fix(fts): hardening pass \u2014 literal-safe identity, trigger/shadow ownership, demotion CAS, stale lifecycle, serving gates, empty-claim, query cap (#30)", + "parents": [ + "3172c9f4611cc2b872f2083829577cc73152f9dc" + ], + "is_merge": false, + "patch_id": "a1e6155cc7099629cb10f15c9ac2f517ddb604fa", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c", + "subject": "fix(fts): harden session trigram transition namespaces (#30)", + "parents": [ + "6467a30563fb1da2bd5c1f42dc7cd1f574697d31" + ], + "is_merge": false, + "patch_id": "a5bf42fb900263d57e79ad16677f7a04305dd1f3", + "changed_files": [ + "hermes_state.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "72388ff87f0baf99910edefab2b2fc2e00b40284", + "subject": "fix(fts): preserve session trigram claims across capability handoff (#30)", + "parents": [ + "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c" + ], + "is_merge": false, + "patch_id": "5cc7da92fc79657a17848c9d582f163fe8e1be12", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "0c02b83d4d8702267481a5f196606e19e3d303cc", + "subject": "fix(fts): gate session trigram mutations on durable ownership (#30)", + "parents": [ + "72388ff87f0baf99910edefab2b2fc2e00b40284" + ], + "is_merge": false, + "patch_id": "424d76b37989b6d5d3a296b2ce1ad21ec0078a86", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "a9c1b2d11bab435cda80fcfc81fc223d210b4755", + "subject": "fix(fts): serve session trigram candidates from one snapshot (#30)", + "parents": [ + "0c02b83d4d8702267481a5f196606e19e3d303cc" + ], + "is_merge": false, + "patch_id": "4247c3fcb1e33dc9ec06927b5427275499967715", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48", + "subject": "test(fts): drop fork-only legacy simple convergence tests (#30)", + "parents": [ + "a9c1b2d11bab435cda80fcfc81fc223d210b4755" + ], + "is_merge": false, + "patch_id": "523ef02eeb02a99000aec84b6410a97b9cb444a3", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "c7163001f23feb31f94fec1ebb3c41badaebdb97", + "subject": "refactor(fts): drop fork-only legacy simple demotion lane (#30)", + "parents": [ + "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48" + ], + "is_merge": false, + "patch_id": "3bd484e442014f2fdf2a7184ebab188f6a9defb3", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "6f534c8760a30a318ae0d874b7a6323f5f0337df", + "subject": "docs(fts): record scope correction and legacy lane removal (#30)", + "parents": [ + "c7163001f23feb31f94fec1ebb3c41badaebdb97" + ], + "is_merge": false, + "patch_id": "9cfd3d181f8e6bb79358c9dfd5035ca53184e986", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "10e3419d10e938c979c701246457cbd6f9c10ad4", + "subject": "test(fts): drop round-11 CAS and shadow-preflight tests (#30)", + "parents": [ + "6f534c8760a30a318ae0d874b7a6323f5f0337df" + ], + "is_merge": false, + "patch_id": "7af1a6ec209a2ef1077276829e70eca10d18edd1", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "69591fe659774a4e61a3f754211f5602e96a7381", + "subject": "fix(fts): quarantine healthy modern target on no-trigram runtime; drop unsupported hardening (#30)", + "parents": [ + "10e3419d10e938c979c701246457cbd6f9c10ad4" + ], + "is_merge": false, + "patch_id": "cd5f71e16d3d57d527193b063c641f85a6e907c0", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + { + "sha": "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea", + "subject": "docs(fts): record round-12 re-review and subtractive hardening removal (#30)", + "parents": [ + "69591fe659774a4e61a3f754211f5602e96a7381" + ], + "is_merge": false, + "patch_id": "8bbd416b4080e3c255c84a1e7498775b58e47e5e", + "changed_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "30" + ] + } + ], + "merge_events": [ + { + "sha": "919f4469e832bc2b38bba0ea5af26b842bf91acd", + "subject": "feat(fts): normalized external-content session trigram metadata index (#30)", + "parents": [ + "2f90c254d524d618b1c866a10bb519f2c1b6f5dc", + "f18b3c90c2309ee7616010f99c1c927c9f05013f" + ], + "changed_files": [], + "pr_refs": [ + "30" + ] + } + ], + "affected_files": [ + "docs/research/issue-30-normalized-session-metadata-trigram-fts.md", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_trigram_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "30" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:516d739f64a95a4f380b899fbb9a349d750fc2aa", + "record_type": "provenance_bucket", + "subject": "Merge branch 'feat/headroom-retrieval-toolset-autoenable' into dev", + "commits": [], + "merge_events": [ + { + "sha": "516d739f64a95a4f380b899fbb9a349d750fc2aa", + "subject": "Merge branch 'feat/headroom-retrieval-toolset-autoenable' into dev", + "parents": [ + "c1a3e16c32896ea2d469536c657814049c29bec6", + "0b4e7601227a23bc653d0d3018a3a9591d02f2a1" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:2", + "record_type": "provenance_bucket", + "subject": "Merge PR #2: escape reasoning fences (resolve conflict)", + "commits": [], + "merge_events": [ + { + "sha": "535b33c95f9465bb3e05b281b17fceee3ba24d22", + "subject": "Merge PR #2: escape reasoning fences (resolve conflict)", + "parents": [ + "47cc1764dc2c2c65cc83fe20500da939698d72d3", + "347442ddc80a2658582cb62dd268a0be024b1bcf" + ], + "changed_files": [], + "pr_refs": [ + "2" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "2" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:87", + "record_type": "provenance_bucket", + "subject": "Merge pull request #87 from Skywind5487/feat/19-simple-tokenizer-eol", + "commits": [], + "merge_events": [ + { + "sha": "53da9e89f8f3d2b051bf4c719b9f09b355392c00", + "subject": "Merge pull request #87 from Skywind5487/feat/19-simple-tokenizer-eol", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72", + "1d5b80cab802e6ae932c97342e328e76faa496fa" + ], + "changed_files": [], + "pr_refs": [ + "87" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "87" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:55dc24391f92d71d9e293c7990089075f2ff49c9", + "record_type": "provenance_bucket", + "subject": "refactor(search): drop title/current lineage-proof protocol per #68 review round-5", + "commits": [ + { + "sha": "55dc24391f92d71d9e293c7990089075f2ff49c9", + "subject": "refactor(search): drop title/current lineage-proof protocol per #68 review round-5", + "parents": [ + "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6" + ], + "is_merge": false, + "patch_id": "a71f4989baf40f079979748453464dc6eb64647c", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:5882274ff6c868c24f9d36f3796de08e5de8a245", + "record_type": "provenance_bucket", + "subject": "refactor(state): add snapshot-aware metadata candidate router", + "commits": [ + { + "sha": "5882274ff6c868c24f9d36f3796de08e5de8a245", + "subject": "refactor(state): add snapshot-aware metadata candidate router", + "parents": [ + "0990803323497a36761c9627a20ceb57be56d5a3" + ], + "is_merge": false, + "patch_id": "9cfd759f545ca7f542f068883f5017767e784705", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:5eb552458de9828f4496880fd878f58015a63389", + "record_type": "provenance_bucket", + "subject": "feat(headroom): add ContentRouter + SmartCrusher integration behind config flag", + "commits": [ + { + "sha": "5eb552458de9828f4496880fd878f58015a63389", + "subject": "feat(headroom): add ContentRouter + SmartCrusher integration behind config flag", + "parents": [ + "cc2531fbc6df8fdb34fca0b096b798eb53f970dd" + ], + "is_merge": false, + "patch_id": "2c8da083a6ab3548f7ef00afffdaefe7faf17f0d", + "changed_files": [ + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:6311e77e27f4fd4009c73d0df16abebf56121f4a", + "record_type": "provenance_bucket", + "subject": "docs(research): map CJK session metadata FTS lifecycle for #33", + "commits": [ + { + "sha": "6311e77e27f4fd4009c73d0df16abebf56121f4a", + "subject": "docs(research): map CJK session metadata FTS lifecycle for #33", + "parents": [ + "e94f2630a50d7585f78cfc06365753c033113cb9" + ], + "is_merge": false, + "patch_id": "f3deefc9bde4c1facfe27477a6ef48f5885e3925", + "changed_files": [ + "docs/research/issue-33-cjk-session-metadata-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-33-cjk-session-metadata-fts-lifecycle.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:637ef2e193b6b2dada5d0b79173461fca03fbf20", + "record_type": "provenance_bucket", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/routed-session-metadata-candidates", + "commits": [], + "merge_events": [ + { + "sha": "637ef2e193b6b2dada5d0b79173461fca03fbf20", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/routed-session-metadata-candidates", + "parents": [ + "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "dcf8096413c7ee40fe0ab512ac86927fb2092df1" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:6447a52cd994bf30c2811814f21095d12aba83ae", + "record_type": "provenance_bucket", + "subject": "fix(state): short-circuit CJK-unservable to direct LIKE + single compression edge", + "commits": [ + { + "sha": "6447a52cd994bf30c2811814f21095d12aba83ae", + "subject": "fix(state): short-circuit CJK-unservable to direct LIKE + single compression edge", + "parents": [ + "b97d00e7319e5147d569519b6a34ef63c6635551" + ], + "is_merge": false, + "patch_id": "79b6a387eaf7db3bd4f797dc1a0a0a94e83c49b3", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "tests/test_session_metadata_picker_routing.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "hermes_state_common.py", + "tests/test_session_metadata_picker_routing.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:66eb2fad76abf150043ffd899fbdfbd328aba2d0", + "record_type": "provenance_bucket", + "subject": "fix(search): title/current share in-snapshot roots + compacted anchor fallback (#68 review)", + "commits": [ + { + "sha": "66eb2fad76abf150043ffd899fbdfbd328aba2d0", + "subject": "fix(search): title/current share in-snapshot roots + compacted anchor fallback (#68 review)", + "parents": [ + "a13d012e5b8736928662f27269d9f2a7cf84f0af" + ], + "is_merge": false, + "patch_id": "932f7f87fefd133797c06f8fc051bfedc32fbfd9", + "changed_files": [ + "hermes_state_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state_search.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:6b3402ea05566fa1553a93aceb285eb517d7e67d", + "record_type": "provenance_bucket", + "subject": "fix(session-fts): three lifecycle/capability seams for CJK session FTS (round-3 review)", + "commits": [ + { + "sha": "6b3402ea05566fa1553a93aceb285eb517d7e67d", + "subject": "fix(session-fts): three lifecycle/capability seams for CJK session FTS (round-3 review)", + "parents": [ + "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2" + ], + "is_merge": false, + "patch_id": "739564b9c7167f08cd333d370571a3cd6eee4b9a", + "changed_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:6fa6c557257175f26c1689799d352fdf948cb787", + "record_type": "provenance_bucket", + "subject": "fix: replace SELECT * with specific columns in get_anchored_view and get_messages_around", + "commits": [ + { + "sha": "6fa6c557257175f26c1689799d352fdf948cb787", + "subject": "fix: replace SELECT * with specific columns in get_anchored_view and get_messages_around", + "parents": [ + "cc2531fbc6df8fdb34fca0b096b798eb53f970dd" + ], + "is_merge": false, + "patch_id": "8412299a818e0b42f7d6911c180cad3da0710f8c", + "changed_files": [ + "hermes_state.py", + "tests/hermes_state/test_get_messages_around.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "tests/hermes_state/test_get_messages_around.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:75223d19544ceb73cf24fb859fc0780ed9a099a5", + "record_type": "provenance_bucket", + "subject": "docs(fts): record review round 1 for #27", + "commits": [ + { + "sha": "75223d19544ceb73cf24fb859fc0780ed9a099a5", + "subject": "docs(fts): record review round 1 for #27", + "parents": [ + "0400c66f072d0f319331ea105cd8f7e059975388" + ], + "is_merge": false, + "patch_id": "f9316ca0aa136778ac398a53a627d57e32fd4f4a", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:79", + "record_type": "provenance_bucket", + "subject": "test(recovery): pin session-trigram derived markers as generated meta (#79)", + "commits": [ + { + "sha": "783d3fa59ae28010368368e3dafddc19750f9b55", + "subject": "test(recovery): pin session-trigram derived markers as generated meta (#79)", + "parents": [ + "276d497764feb7d4a71f1424ed44b8958da63b16" + ], + "is_merge": false, + "patch_id": "3b6d866e33eb926b4f6be293edcc411ea6cd5077", + "changed_files": [ + "tests/hermes_cli/test_session_recovery.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + }, + { + "sha": "4aefa3abbbe4f9c3eba29988fa772e45d70000f9", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)", + "parents": [ + "783d3fa59ae28010368368e3dafddc19750f9b55" + ], + "is_merge": false, + "patch_id": "de138bf28952f63a6aef45822350031081923296", + "changed_files": [ + "hermes_cli/session_recovery.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + }, + { + "sha": "d4c9a165c5abe6cf8c0503005b18e55de58e28cc", + "subject": "docs(research): record session-trigram recovery marker fix (#79)", + "parents": [ + "4aefa3abbbe4f9c3eba29988fa772e45d70000f9" + ], + "is_merge": false, + "patch_id": "411f66a119ca4c46d97a06d4085792041b171bda", + "changed_files": [ + "docs/research/issue-79-session-recovery-trigram-markers.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + }, + { + "sha": "f17ab58979753a9ee342d258595e8d076ef2f309", + "subject": "test(recovery): guard verifier detection of leftover session-trigram markers (#79)", + "parents": [ + "d4c9a165c5abe6cf8c0503005b18e55de58e28cc" + ], + "is_merge": false, + "patch_id": "7a4972e80b9db112cd5af724eb72fb13a2db5dd2", + "changed_files": [ + "tests/hermes_cli/test_session_recovery.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "79" + ] + } + ], + "merge_events": [ + { + "sha": "4e5ad5c2230300d1ffae84b089ffc70e368c8a23", + "subject": "fix(recovery): exclude session-trigram derived markers from recovered DB (#79)", + "parents": [ + "276d497764feb7d4a71f1424ed44b8958da63b16", + "f17ab58979753a9ee342d258595e8d076ef2f309" + ], + "changed_files": [], + "pr_refs": [ + "79" + ] + } + ], + "affected_files": [ + "docs/research/issue-79-session-recovery-trigram-markers.md", + "hermes_cli/session_recovery.py", + "tests/hermes_cli/test_session_recovery.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "79" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "record_type": "provenance_bucket", + "subject": "perf(search): benchmark cold-open + fallback-invariant self-check", + "commits": [ + { + "sha": "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "subject": "perf(search): benchmark cold-open + fallback-invariant self-check", + "parents": [ + "3ebb2592c141b232ecd0717adf32279afa6bee3f" + ], + "is_merge": false, + "patch_id": "b6beb6e939deb9a52d5d34e24f046539743092ec", + "changed_files": [ + "scripts/benchmarks/session_metadata_picker.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "scripts/benchmarks/session_metadata_picker.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:83431f775a9e3798611e03b16a2f7d9a7ac74a57", + "record_type": "provenance_bucket", + "subject": "docs(design): document the #26 CJK session metadata FTS variant", + "commits": [ + { + "sha": "83431f775a9e3798611e03b16a2f7d9a7ac74a57", + "subject": "docs(design): document the #26 CJK session metadata FTS variant", + "parents": [ + "4270ea5b9a903d0dcf692db2365875ac5b3fe319" + ], + "is_merge": false, + "patch_id": "4931fa1241c6fda8361f416be00c5cfb6f4c0568", + "changed_files": [ + "docs/design/session-metadata-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/design/session-metadata-fts.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:19", + "record_type": "provenance_bucket", + "subject": "test(fts): pin simple-tokenizer EOL policy (#19)", + "commits": [ + { + "sha": "85fd91fd7c7be20d63356f27654d399ca1da4fa0", + "subject": "test(fts): pin simple-tokenizer EOL policy (#19)", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72" + ], + "is_merge": false, + "patch_id": "19ab3fe510b98e6c0fa30e79b79eda2b10a975b7", + "changed_files": [ + "tests/test_simple_tokenizer_eol.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + }, + { + "sha": "186986a447080ae74a1d17fd1e32aaf039cb2ff2", + "subject": "fix(fts): retire simple-tokenizer residue; drop global shim (#19)", + "parents": [ + "85fd91fd7c7be20d63356f27654d399ca1da4fa0" + ], + "is_merge": false, + "patch_id": "37ec3e8508489924e6dcb38f55fc89de71963699", + "changed_files": [ + "hermes_state.py", + "tests/test_optional_cjk_tokenizer_fallback.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + }, + { + "sha": "deb10243ccebd6153cdfab8e9869faba2e105f0e", + "subject": "docs(fts): close simple compatibility contract (#19)", + "parents": [ + "186986a447080ae74a1d17fd1e32aaf039cb2ff2" + ], + "is_merge": false, + "patch_id": "13b475b0deeaca573780c59048aa6d4df5189ca6", + "changed_files": [ + "docs/research/issue-19-simple-tokenizer-eol-implementation.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + }, + { + "sha": "1d5b80cab802e6ae932c97342e328e76faa496fa", + "subject": "fix(fts): harden simple EOL sanitation per review (#19)", + "parents": [ + "deb10243ccebd6153cdfab8e9869faba2e105f0e" + ], + "is_merge": false, + "patch_id": "4759f05b9edac98c6ff1e825406938cc1bbc5ed3", + "changed_files": [ + "docs/research/issue-19-simple-tokenizer-eol-implementation.md", + "hermes_state.py", + "tests/test_simple_tokenizer_eol.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "19" + ] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-19-simple-tokenizer-eol-implementation.md", + "hermes_state.py", + "tests/test_optional_cjk_tokenizer_fallback.py", + "tests/test_simple_tokenizer_eol.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "19" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:8838d16060bb7610c6d7ad3697f384df3edb70c1", + "record_type": "provenance_bucket", + "subject": "test(search): RED contracts for #68 compression-lineage resolver", + "commits": [ + { + "sha": "8838d16060bb7610c6d7ad3697f384df3edb70c1", + "subject": "test(search): RED contracts for #68 compression-lineage resolver", + "parents": [ + "bdf2fc218264538c4f3238b58532488fe665ff9e" + ], + "is_merge": false, + "patch_id": "c3542d1ed1f8a153f905fefb9b6c4c1cc8f1c3e4", + "changed_files": [ + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:895ba96014ecf934dbc140306ffe578a0a533ea3", + "record_type": "provenance_bucket", + "subject": "feat: configurable reasoning max lines via display.reasoning_max_lines", + "commits": [ + { + "sha": "895ba96014ecf934dbc140306ffe578a0a533ea3", + "subject": "feat: configurable reasoning max lines via display.reasoning_max_lines", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "59ff3b007ae023acbd6f006ba3242d2996f7f004", + "changed_files": [ + "cli.py", + "gateway/run.py", + "tests/gateway/test_reasoning_max_lines.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "cli.py", + "gateway/run.py", + "tests/gateway/test_reasoning_max_lines.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f", + "record_type": "provenance_bucket", + "subject": "Merge branch 'fix/browser-timeout-daemon-kill-toggle' into dev", + "commits": [], + "merge_events": [ + { + "sha": "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f", + "subject": "Merge branch 'fix/browser-timeout-daemon-kill-toggle' into dev", + "parents": [ + "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "cfb2636a6a3ed02ff773f106beb71c88576f1284" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:8b085795df0359adbf3c81315f888bc7041fb044", + "record_type": "provenance_bucket", + "subject": "docs(research): record #22 redo with SQLite 3.51.3 + CJK + fuzz", + "commits": [ + { + "sha": "8b085795df0359adbf3c81315f888bc7041fb044", + "subject": "docs(research): record #22 redo with SQLite 3.51.3 + CJK + fuzz", + "parents": [ + "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57" + ], + "is_merge": false, + "patch_id": "48ed043d3ba486e84c373a04e82cf337a744f4b6", + "changed_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-22-production-ready-state-db-execution.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:8efead2600a3f932f9881b53cd0c7eabc755f82f", + "record_type": "provenance_bucket", + "subject": "fix(session-fts): address #26 code-review findings", + "commits": [ + { + "sha": "8efead2600a3f932f9881b53cd0c7eabc755f82f", + "subject": "fix(session-fts): address #26 code-review findings", + "parents": [ + "83431f775a9e3798611e03b16a2f7d9a7ac74a57" + ], + "is_merge": false, + "patch_id": "b10a9c6b1a918355e6b6227802b594659fc393f7", + "changed_files": [ + "docs/design/session-metadata-fts.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_search.py", + "tests/hermes_cli/test_session_recovery.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/design/session-metadata-fts.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_search.py", + "tests/hermes_cli/test_session_recovery.py", + "tests/test_session_metadata_cjk_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:915913db360de5fe5b147d4895276ff39a6e8686", + "record_type": "provenance_bucket", + "subject": "Add opt-in headroom tool-output compression plugin", + "commits": [ + { + "sha": "915913db360de5fe5b147d4895276ff39a6e8686", + "subject": "Add opt-in headroom tool-output compression plugin", + "parents": [ + "296d9c6e2e5a6f852344ad8fa9b90f5687912be1" + ], + "is_merge": false, + "patch_id": "b68450d1d31e7788f570959684c620c497cd1ed8", + "changed_files": [ + "hermes_cli/config.py", + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_cli/config.py", + "plugins/headroom/__init__.py", + "plugins/headroom/plugin.yaml", + "tests/plugins/test_headroom_plugin.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:984eff15df1fb749f00aece7fc24c43e9afcb7e8", + "record_type": "provenance_bucket", + "subject": "Merge remote-tracking branch 'origin/dev' into fix/15-numbered-title-literal-safety", + "commits": [], + "merge_events": [ + { + "sha": "984eff15df1fb749f00aece7fc24c43e9afcb7e8", + "subject": "Merge remote-tracking branch 'origin/dev' into fix/15-numbered-title-literal-safety", + "parents": [ + "17b0d2c9135d38728109592860677c4abbaddf4f", + "53da9e89f8f3d2b051bf4c719b9f09b355392c00" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32", + "record_type": "provenance_bucket", + "subject": "fix(session-search): ranked Top-N pre-limit for relevance sort", + "commits": [ + { + "sha": "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32", + "subject": "fix(session-search): ranked Top-N pre-limit for relevance sort", + "parents": [ + "2d2bad204ec644455ad1273f2934f388eb4111dd" + ], + "is_merge": false, + "patch_id": "2e150449ebe907705459b4930b499d4dd7e49505", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:9b25b0c8bd7408eaf2398529b6a04ed1a068b892", + "record_type": "provenance_bucket", + "subject": "docs: research #32 session row_id unicode FTS", + "commits": [ + { + "sha": "9b25b0c8bd7408eaf2398529b6a04ed1a068b892", + "subject": "docs: research #32 session row_id unicode FTS", + "parents": [ + "9f3056cb3a9642c39056af8409cc3198007e68a8" + ], + "is_merge": false, + "patch_id": "368ddfb0bf2cc28000410f3a099081f34cd453f5", + "changed_files": [ + "docs/research/issue-32-stable-row-id-unicode-session-fts.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-32-stable-row-id-unicode-session-fts.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:76", + "record_type": "provenance_bucket", + "subject": "Merge pull request #76 from Skywind5487/feat/27-unified-fts-lifecycle", + "commits": [], + "merge_events": [ + { + "sha": "9d140c8594c67ed37729b190fd3733508d0d770c", + "subject": "Merge pull request #76 from Skywind5487/feat/27-unified-fts-lifecycle", + "parents": [ + "919f4469e832bc2b38bba0ea5af26b842bf91acd", + "0cf4cd0baffb68b571a44f2a39d3bf817cd38348" + ], + "changed_files": [], + "pr_refs": [ + "76" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "76" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "record_type": "provenance_bucket", + "subject": "Merge remote-tracking branch 'origin/main' into dev", + "commits": [], + "merge_events": [ + { + "sha": "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "subject": "Merge remote-tracking branch 'origin/main' into dev", + "parents": [ + "516d739f64a95a4f380b899fbb9a349d750fc2aa", + "104232979d6ec24e82a42dfbf14ac98f3df3c827" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:9e3439835e9dbbad0d0076d539d769db1f84de0a", + "record_type": "provenance_bucket", + "subject": "Merge remote-tracking branch 'origin/main' into fix/browser-timeout-daemon-kill-toggle", + "commits": [], + "merge_events": [ + { + "sha": "9e3439835e9dbbad0d0076d539d769db1f84de0a", + "subject": "Merge remote-tracking branch 'origin/main' into fix/browser-timeout-daemon-kill-toggle", + "parents": [ + "a2450695db0e99f3dd8362f129024cb74c700bb8", + "104232979d6ec24e82a42dfbf14ac98f3df3c827" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:9f3056cb3a9642c39056af8409cc3198007e68a8", + "record_type": "provenance_bucket", + "subject": "ignore agents", + "commits": [ + { + "sha": "9f3056cb3a9642c39056af8409cc3198007e68a8", + "subject": "ignore agents", + "parents": [ + "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a" + ], + "is_merge": false, + "patch_id": "10bfbeb338458c810deaa1bad23c658c89312887", + "changed_files": [ + ".gitignore" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + ".gitignore" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:3", + "record_type": "provenance_bucket", + "subject": "Merge PR #3: configurable reasoning max lines", + "commits": [], + "merge_events": [ + { + "sha": "9fe97e2aa1b05306ed626e5ae3db540d24bb4678", + "subject": "Merge PR #3: configurable reasoning max lines", + "parents": [ + "535b33c95f9465bb3e05b281b17fceee3ba24d22", + "895ba96014ecf934dbc140306ffe578a0a533ea3" + ], + "changed_files": [], + "pr_refs": [ + "3" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "3" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a1136e548ea1f2200429bf44f8f1a7297cc84246", + "record_type": "provenance_bucket", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "commits": [ + { + "sha": "a1136e548ea1f2200429bf44f8f1a7297cc84246", + "subject": "fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs", + "parents": [ + "b03c94dbed5ee72e97eace2376e02092cc854f6a" + ], + "is_merge": false, + "patch_id": "f0a0986406e7ad9f35acf9468e22096c12863e24", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a13d012e5b8736928662f27269d9f2a7cf84f0af", + "record_type": "provenance_bucket", + "subject": "docs(session-storage): document #68 compression-lineage resolution", + "commits": [ + { + "sha": "a13d012e5b8736928662f27269d9f2a7cf84f0af", + "subject": "docs(session-storage): document #68 compression-lineage resolution", + "parents": [ + "2e1b2e64d7a452f524f703a99d68b1b110b93d3e" + ], + "is_merge": false, + "patch_id": "9f0b60b610bf34cd8cd86ca7724779d4810d27db", + "changed_files": [ + "website/docs/developer-guide/session-storage.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "website/docs/developer-guide/session-storage.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a2450695db0e99f3dd8362f129024cb74c700bb8", + "record_type": "provenance_bucket", + "subject": "fix(browser): config-gated daemon kill on timeout", + "commits": [ + { + "sha": "a2450695db0e99f3dd8362f129024cb74c700bb8", + "subject": "fix(browser): config-gated daemon kill on timeout", + "parents": [ + "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6" + ], + "is_merge": false, + "patch_id": "6adb5a7810ede0e0a7b0ab155cb017db044d0640", + "changed_files": [ + "tools/browser_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tools/browser_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a34da2c31ca60f9b5280558c514a3a1880035036", + "record_type": "provenance_bucket", + "subject": "Merge branch 'fix/session-search-perf' of /home/skywind5487/hermes_worktrees/fix/session-search-perf into dev", + "commits": [], + "merge_events": [ + { + "sha": "a34da2c31ca60f9b5280558c514a3a1880035036", + "subject": "Merge branch 'fix/session-search-perf' of /home/skywind5487/hermes_worktrees/fix/session-search-perf into dev", + "parents": [ + "3053abf3b039a5b4c23637597cb076f2339250fb", + "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2", + "record_type": "provenance_bucket", + "subject": "style(session-fts): drop duplicate @staticmethod (round-2 review)", + "commits": [ + { + "sha": "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2", + "subject": "style(session-fts): drop duplicate @staticmethod (round-2 review)", + "parents": [ + "8efead2600a3f932f9881b53cd0c7eabc755f82f" + ], + "is_merge": false, + "patch_id": "2619728a0a90d3f0bf8f9ca26357b383e895e595", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a4e2c52f1582952686ee56aaedd7285874326102", + "record_type": "provenance_bucket", + "subject": "fix: address Copilot review \u2014 init hermes_home, load simple in ro path, v21 migration", + "commits": [ + { + "sha": "a4e2c52f1582952686ee56aaedd7285874326102", + "subject": "fix: address Copilot review \u2014 init hermes_home, load simple in ro path, v21 migration", + "parents": [ + "dc2270aad84242da42f4342ac137e243ca181aa5" + ], + "is_merge": false, + "patch_id": "393d1d77f8315c21a5c34cbe151b1cb47b625e44", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a615feaea695123d1b3a832417a9a76554301af8", + "record_type": "provenance_bucket", + "subject": "test(state): cover whole-store lineage visibility and pagination", + "commits": [ + { + "sha": "a615feaea695123d1b3a832417a9a76554301af8", + "subject": "test(state): cover whole-store lineage visibility and pagination", + "parents": [ + "1f5edc591353a0a65ec7aa2f02c6916fd67fd505" + ], + "is_merge": false, + "patch_id": "776704c477343cd0a3efda03d9fe61c5c73d46ee", + "changed_files": [ + "tests/test_session_metadata_picker_routing.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/test_session_metadata_picker_routing.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a822d37d18064d1442eb20b6a2cb4e9f8b17d48d", + "record_type": "provenance_bucket", + "subject": "docs(fts): record review round 3 for #27 unified FTS lifecycle", + "commits": [ + { + "sha": "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d", + "subject": "docs(fts): record review round 3 for #27 unified FTS lifecycle", + "parents": [ + "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a" + ], + "is_merge": false, + "patch_id": "5a24d3849b9501c6a79c01ee1a114b0a71f1e8bd", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb", + "record_type": "provenance_bucket", + "subject": "fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim", + "commits": [ + { + "sha": "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb", + "subject": "fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim", + "parents": [ + "04f1af72be078cef69de538f1519f93a73088b0d" + ], + "is_merge": false, + "patch_id": "6c4c0e537ecff4d0df196c263683328d626be9cd", + "changed_files": [ + "hermes_cli/mem_trim.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_cli/mem_trim.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:ad0c45f0924349f6f0453d4941c3d76ad5258cdc", + "record_type": "provenance_bucket", + "subject": "test(fts): pin modern session trigram and legacy-simple states", + "commits": [ + { + "sha": "ad0c45f0924349f6f0453d4941c3d76ad5258cdc", + "subject": "test(fts): pin modern session trigram and legacy-simple states", + "parents": [ + "e94f2630a50d7585f78cfc06365753c033113cb9" + ], + "is_merge": false, + "patch_id": "6899521fc12538eb9dc0129d2863bc3b87f8bb92", + "changed_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/test_session_metadata_trigram_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b2710666a29eed6fc46f3b6ce23c72f4dc766181", + "record_type": "provenance_bucket", + "subject": "test(search): rename title==current test, correct misleading scope claim (#68 review final)", + "commits": [ + { + "sha": "b2710666a29eed6fc46f3b6ce23c72f4dc766181", + "subject": "test(search): rename title==current test, correct misleading scope claim (#68 review final)", + "parents": [ + "55dc24391f92d71d9e293c7990089075f2ff49c9" + ], + "is_merge": false, + "patch_id": "f96724aea81c1b2c6d039696b95eec56335e6939", + "changed_files": [ + "tests/tools/test_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/tools/test_session_search.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b42bc25e622c11230998cc57f7050ec2a2cdd090", + "record_type": "provenance_bucket", + "subject": "fix(browser): add tests and crash-resilience for daemon-kill on timeout", + "commits": [ + { + "sha": "b42bc25e622c11230998cc57f7050ec2a2cdd090", + "subject": "fix(browser): add tests and crash-resilience for daemon-kill on timeout", + "parents": [ + "9e3439835e9dbbad0d0076d539d769db1f84de0a" + ], + "is_merge": false, + "patch_id": "8ce16b114c337a7d1e177e5f422bcaed8aa9fd6a", + "changed_files": [ + "tests/tools/test_browser_terminate_daemon_timeout.py", + "tests/tools/test_browser_timeout_cleanup.py", + "tools/browser_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/tools/test_browser_terminate_daemon_timeout.py", + "tests/tools/test_browser_timeout_cleanup.py", + "tools/browser_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b4efc640fab0517571bd05447cf2be2ace9cf3e1", + "record_type": "provenance_bucket", + "subject": "feat(desktop): search the whole session store in the resume picker", + "commits": [ + { + "sha": "b4efc640fab0517571bd05447cf2be2ace9cf3e1", + "subject": "feat(desktop): search the whole session store in the resume picker", + "parents": [ + "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d" + ], + "is_merge": false, + "patch_id": "0b08ae048db2918949822a3781f615a65e504f8a", + "changed_files": [ + "apps/desktop/src/components/session-picker.test.tsx", + "apps/desktop/src/components/session-picker.tsx", + "apps/desktop/src/hermes.test.ts", + "apps/desktop/src/hermes.ts", + "apps/desktop/src/i18n/en.ts", + "apps/desktop/src/i18n/types.ts", + "apps/desktop/src/i18n/zh.ts" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "apps/desktop/src/components/session-picker.test.tsx", + "apps/desktop/src/components/session-picker.tsx", + "apps/desktop/src/hermes.test.ts", + "apps/desktop/src/hermes.ts", + "apps/desktop/src/i18n/en.ts", + "apps/desktop/src/i18n/types.ts", + "apps/desktop/src/i18n/zh.ts" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b527e4df996b859356c0c48c2b9c9eae4c74c4dc", + "record_type": "provenance_bucket", + "subject": "fix(headroom): auto-enable headroom_retrieve tool when compression is active", + "commits": [ + { + "sha": "b527e4df996b859356c0c48c2b9c9eae4c74c4dc", + "subject": "fix(headroom): auto-enable headroom_retrieve tool when compression is active", + "parents": [ + "ff4df5b71e1557660dbe994eb5569983f57c9901" + ], + "is_merge": false, + "patch_id": "dc4c2ce5d3bce995521b06c29054b914852ee826", + "changed_files": [ + "hermes_cli/tools_config.py", + "plugins/headroom/plugin.yaml", + "pyproject.toml", + "uv.lock" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_cli/tools_config.py", + "plugins/headroom/plugin.yaml", + "pyproject.toml", + "uv.lock" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b66c149de0c8240e84ded1a2f983b8c42f7b984b", + "record_type": "provenance_bucket", + "subject": "merge(main): absorb upstream main 91937a6dc into dev \u2014 keep session-search fix chain", + "commits": [], + "merge_events": [ + { + "sha": "b66c149de0c8240e84ded1a2f983b8c42f7b984b", + "subject": "merge(main): absorb upstream main 91937a6dc into dev \u2014 keep session-search fix chain", + "parents": [ + "1602d06f5045d173ee31161b92e387de69ab821c", + "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b7e62647bd657a429d967cfa77034632ee490f9a", + "record_type": "provenance_bucket", + "subject": "feat(headroom): merge ContentRouter + warning E2E tests into dev", + "commits": [], + "merge_events": [ + { + "sha": "b7e62647bd657a429d967cfa77034632ee490f9a", + "subject": "feat(headroom): merge ContentRouter + warning E2E tests into dev", + "parents": [ + "6fa6c557257175f26c1689799d352fdf948cb787", + "c16ebe6b8649c570b688fd82d6b66f9a8416d59c" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "record_type": "provenance_bucket", + "subject": "perf(search): batch context queries \u2014 chunked session_id batches (20/sql)", + "commits": [ + { + "sha": "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "subject": "perf(search): batch context queries \u2014 chunked session_id batches (20/sql)", + "parents": [ + "ff4df5b71e1557660dbe994eb5569983f57c9901" + ], + "is_merge": false, + "patch_id": "640fc71b9783c17f14327fe3bee772129ef31c89", + "changed_files": [ + "hermes_state.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:b97d00e7319e5147d569519b6a34ef63c6635551", + "record_type": "provenance_bucket", + "subject": "perf(search): benchmark routed session metadata candidates", + "commits": [ + { + "sha": "b97d00e7319e5147d569519b6a34ef63c6635551", + "subject": "perf(search): benchmark routed session metadata candidates", + "parents": [ + "b4efc640fab0517571bd05447cf2be2ace9cf3e1" + ], + "is_merge": false, + "patch_id": "19e1e455ef97845723d5c2418e0c398657189166", + "changed_files": [ + "scripts/benchmarks/session_metadata_picker.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "scripts/benchmarks/session_metadata_picker.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:bdd9d699f6dc13b32852a078c1ecf5664bcb837d", + "record_type": "provenance_bucket", + "subject": "docs(fts): record six-index unified lifecycle implementation for #27", + "commits": [ + { + "sha": "bdd9d699f6dc13b32852a078c1ecf5664bcb837d", + "subject": "docs(fts): record six-index unified lifecycle implementation for #27", + "parents": [ + "e64ad007b459871af42e312bc5dffd2da92ac900" + ], + "is_merge": false, + "patch_id": "02810363d2c8be19088f78ed7475b5d62f6e6924", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:82", + "record_type": "provenance_bucket", + "subject": "Merge pull request #82 from Skywind5487/feat/22-production-ready-state-db-execution", + "commits": [], + "merge_events": [ + { + "sha": "bee13fc085079d78d0334722ad4c37a1144e3102", + "subject": "Merge pull request #82 from Skywind5487/feat/22-production-ready-state-db-execution", + "parents": [ + "4e5ad5c2230300d1ffae84b089ffc70e368c8a23", + "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba" + ], + "changed_files": [], + "pr_refs": [ + "82" + ] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "82" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:c16ebe6b8649c570b688fd82d6b66f9a8416d59c", + "record_type": "provenance_bucket", + "subject": "fix(headroom): logger.warning for ContentRouter/CacheAligner failures + warning E2E tests", + "commits": [ + { + "sha": "c16ebe6b8649c570b688fd82d6b66f9a8416d59c", + "subject": "fix(headroom): logger.warning for ContentRouter/CacheAligner failures + warning E2E tests", + "parents": [ + "5eb552458de9828f4496880fd878f58015a63389" + ], + "is_merge": false, + "patch_id": "8d2445a5faad27650a7666507fd9d6fd4b025419", + "changed_files": [ + "plugins/headroom/__init__.py", + "tests/plugins/test_headroom_plugin.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/headroom/__init__.py", + "tests/plugins/test_headroom_plugin.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:c1a3e16c32896ea2d469536c657814049c29bec6", + "record_type": "provenance_bucket", + "subject": "fix: also close orphaned single-backtick inline-code spans", + "commits": [ + { + "sha": "c1a3e16c32896ea2d469536c657814049c29bec6", + "subject": "fix: also close orphaned single-backtick inline-code spans", + "parents": [ + "915913db360de5fe5b147d4895276ff39a6e8686" + ], + "is_merge": false, + "patch_id": "5591f76faf75f108e2596e380cde46f395c37087", + "changed_files": [ + "gateway/stream_consumer.py", + "tests/gateway/test_code_fence_tracking.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "gateway/stream_consumer.py", + "tests/gateway/test_code_fence_tracking.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:c20cb64b4b79468c641626e9b9d3957790f7a671", + "record_type": "provenance_bucket", + "subject": "fix: address Copilot review \u2014 init hermes_home, load simple in ro path, v21 migration", + "commits": [ + { + "sha": "c20cb64b4b79468c641626e9b9d3957790f7a671", + "subject": "fix: address Copilot review \u2014 init hermes_home, load simple in ro path, v21 migration", + "parents": [ + "a1136e548ea1f2200429bf44f8f1a7297cc84246" + ], + "is_merge": false, + "patch_id": "393d1d77f8315c21a5c34cbe151b1cb47b625e44", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:c3f1abc5cc34f1a356740529c9f17dfc0f4157b0", + "record_type": "provenance_bucket", + "subject": "fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries", + "commits": [ + { + "sha": "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0", + "subject": "fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries", + "parents": [ + "37811327cdc65c85c4b0bd565b1cdb3a4590dd91" + ], + "is_merge": false, + "patch_id": "2e7ebdeacf2f068145cf24e23acc81ca0d1d0d85", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:c81ab321ec4bb3d5a33429b28907cd5836e41789", + "record_type": "provenance_bucket", + "subject": "fix(search): displayable-anchor ranking + drop unproven title on B-hit (#68 review round-3)", + "commits": [ + { + "sha": "c81ab321ec4bb3d5a33429b28907cd5836e41789", + "subject": "fix(search): displayable-anchor ranking + drop unproven title on B-hit (#68 review round-3)", + "parents": [ + "42c421f68b6556757c17b4dc78756cf31babd239" + ], + "is_merge": false, + "patch_id": "3d8e178a16804038bb27736d649c1d0a0a92a814", + "changed_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state_search.py", + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e", + "record_type": "provenance_bucket", + "subject": "fix(session-search): define ranked_candidates for LIKE route", + "commits": [ + { + "sha": "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e", + "subject": "fix(session-search): define ranked_candidates for LIKE route", + "parents": [ + "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32" + ], + "is_merge": false, + "patch_id": "32a3bd65e89fbf0255bd6fea58c2bf13386d7853", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "record_type": "provenance_bucket", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log", + "commits": [ + { + "sha": "cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "subject": "fix: exponential backoff, slow-write log, and Discord API delivery log", + "parents": [ + "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0" + ], + "is_merge": false, + "patch_id": "7db3fd75db58976898a37f9b5e0f1f86a17c7eff", + "changed_files": [ + "hermes_state.py", + "plugins/platforms/discord/adapter.py", + "tests/tools/test_web_searxng_e2e.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py", + "plugins/platforms/discord/adapter.py", + "tests/tools/test_web_searxng_e2e.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:cea5282a181d23af471f4467f449fd9bfc022ca5", + "record_type": "provenance_bucket", + "subject": "docs(recovery): attest production gateway runtime surface", + "commits": [ + { + "sha": "cea5282a181d23af471f4467f449fd9bfc022ca5", + "subject": "docs(recovery): attest production gateway runtime surface", + "parents": [ + "d72f99eb1b897dd29a46692a310aa15b1bfd77e8" + ], + "is_merge": false, + "patch_id": "7220d2c770e0afce5b241c590b084d2080c668ee", + "changed_files": [ + "research/recovery/issue-41-production-gateway-runtime-attestation.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "research/recovery/issue-41-production-gateway-runtime-attestation.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:cfb2636a6a3ed02ff773f106beb71c88576f1284", + "record_type": "provenance_bucket", + "subject": "fix(browser): move dict cleanup to finally block on timeout (P1 fix)", + "commits": [ + { + "sha": "cfb2636a6a3ed02ff773f106beb71c88576f1284", + "subject": "fix(browser): move dict cleanup to finally block on timeout (P1 fix)", + "parents": [ + "b42bc25e622c11230998cc57f7050ec2a2cdd090" + ], + "is_merge": false, + "patch_id": "50e4470b0565c38927129a73ef07bbba59294cb0", + "changed_files": [ + ".github/actions/hermes-smoke-test/action.yml", + ".github/workflows/build-windows-installer.yml", + ".github/workflows/docker-publish.yml", + ".github/workflows/nix-lockfile-fix.yml", + ".github/workflows/nix.yml", + "agent/gemini_cloudcode_adapter.py", + "agent/google_code_assist.py", + "agent/google_oauth.py", + "apps/desktop/src/app/chat/composer/skin-slash-popover.tsx", + "apps/desktop/src/app/cron/cron-job-actions-menu.tsx", + "apps/desktop/src/app/overlays/overlay-search-input.tsx", + "apps/desktop/src/app/right-sidebar/terminal/index.tsx", + "apps/desktop/src/app/session/hooks/use-message-stream.ts", + "apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx", + "apps/desktop/src/app/session/hooks/use-prompt-actions.ts", + "apps/desktop/src/app/session/hooks/use-session-actions.ts", + "apps/desktop/src/components/assistant-ui/streaming.test.tsx", + "apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx", + "apps/desktop/src/components/assistant-ui/thread.tsx", + "apps/desktop/src/components/assistant-ui/todo-tool.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.tsx", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback.tsx", + "apps/desktop/src/components/assistant-ui/user-message-text.tsx", + "apps/desktop/src/components/chat/generated-image-context.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.test.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.tsx", + "apps/desktop/src/components/ui/braille-spinner.tsx", + "apps/desktop/src/lib/gateway-ws-url.ts", + "gateway/platforms/dingtalk.py", + "gateway/platforms/email.py", + "gateway/platforms/feishu.py", + "gateway/platforms/feishu_comment.py", + "gateway/platforms/feishu_comment_rules.py", + "gateway/platforms/feishu_meeting_invite.py", + "gateway/platforms/homeassistant.py", + "gateway/platforms/matrix.py", + "gateway/platforms/slack.py", + "gateway/platforms/sms.py", + "gateway/platforms/telegram.py", + "gateway/platforms/telegram_network.py", + "gateway/platforms/wecom.py", + "gateway/platforms/wecom_callback.py", + "gateway/platforms/wecom_crypto.py", + "gateway/platforms/whatsapp.py", + "optional-skills/productivity/shop-app/SKILL.md", + "plans/gemini-oauth-provider.md", + "tests/tools/test_browser_timeout_cleanup.py", + "tools/browser_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + ".github/actions/hermes-smoke-test/action.yml", + ".github/workflows/build-windows-installer.yml", + ".github/workflows/docker-publish.yml", + ".github/workflows/nix-lockfile-fix.yml", + ".github/workflows/nix.yml", + "agent/gemini_cloudcode_adapter.py", + "agent/google_code_assist.py", + "agent/google_oauth.py", + "apps/desktop/src/app/chat/composer/skin-slash-popover.tsx", + "apps/desktop/src/app/cron/cron-job-actions-menu.tsx", + "apps/desktop/src/app/overlays/overlay-search-input.tsx", + "apps/desktop/src/app/right-sidebar/terminal/index.tsx", + "apps/desktop/src/app/session/hooks/use-message-stream.ts", + "apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx", + "apps/desktop/src/app/session/hooks/use-prompt-actions.ts", + "apps/desktop/src/app/session/hooks/use-session-actions.ts", + "apps/desktop/src/components/assistant-ui/streaming.test.tsx", + "apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx", + "apps/desktop/src/components/assistant-ui/thread.tsx", + "apps/desktop/src/components/assistant-ui/todo-tool.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.test.tsx", + "apps/desktop/src/components/assistant-ui/tool-approval.tsx", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback-model.ts", + "apps/desktop/src/components/assistant-ui/tool-fallback.tsx", + "apps/desktop/src/components/assistant-ui/user-message-text.tsx", + "apps/desktop/src/components/chat/generated-image-context.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.test.tsx", + "apps/desktop/src/components/desktop-onboarding-overlay.tsx", + "apps/desktop/src/components/ui/braille-spinner.tsx", + "apps/desktop/src/lib/gateway-ws-url.ts", + "gateway/platforms/dingtalk.py", + "gateway/platforms/email.py", + "gateway/platforms/feishu.py", + "gateway/platforms/feishu_comment.py", + "gateway/platforms/feishu_comment_rules.py", + "gateway/platforms/feishu_meeting_invite.py", + "gateway/platforms/homeassistant.py", + "gateway/platforms/matrix.py", + "gateway/platforms/slack.py", + "gateway/platforms/sms.py", + "gateway/platforms/telegram.py", + "gateway/platforms/telegram_network.py", + "gateway/platforms/wecom.py", + "gateway/platforms/wecom_callback.py", + "gateway/platforms/wecom_crypto.py", + "gateway/platforms/whatsapp.py", + "optional-skills/productivity/shop-app/SKILL.md", + "plans/gemini-oauth-provider.md", + "tests/tools/test_browser_timeout_cleanup.py", + "tools/browser_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:15", + "record_type": "provenance_bucket", + "subject": "test(session): pin literal-safe numbered-title resolution (#15)", + "commits": [ + { + "sha": "d18dadb5f3b517ec69f14428dc78e7af1a86a30e", + "subject": "test(session): pin literal-safe numbered-title resolution (#15)", + "parents": [ + "196b904417371cf233f3eb9b560c80a079ab8d72" + ], + "is_merge": false, + "patch_id": "bd61d76f62622a833ac9338561d3e08e73b70e97", + "changed_files": [ + "tests/test_hermes_state.py", + "tests/test_session_metadata_cjk_fts.py", + "tests/test_session_metadata_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + { + "sha": "faf96ef221ddfba2618abc8dae8368f7b82c1c2a", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)", + "parents": [ + "d18dadb5f3b517ec69f14428dc78e7af1a86a30e" + ], + "is_merge": false, + "patch_id": "b5d0d7483995873297fe25582c921eff0f231152", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + { + "sha": "69bee0838ae15936ae4beb13cdf5d6907c19c707", + "subject": "docs: record #38 numbered-title research note and design contract (#15)", + "parents": [ + "faf96ef221ddfba2618abc8dae8368f7b82c1c2a" + ], + "is_merge": false, + "patch_id": "2df8b0d2801a3c4d573c57a1fa703c32aa097c3d", + "changed_files": [ + "docs/design/session-metadata-fts.md", + "docs/research/issue-38-numbered-title-literal-safety.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + { + "sha": "17b0d2c9135d38728109592860677c4abbaddf4f", + "subject": "fix(session): unify #N grammar to ASCII digits; tidy escape_like placement (#15)", + "parents": [ + "69bee0838ae15936ae4beb13cdf5d6907c19c707" + ], + "is_merge": false, + "patch_id": "131b1db23e2621d2d293fa1816b61c6c2da0e0fe", + "changed_files": [ + "hermes_state.py", + "hermes_state_common.py", + "tests/test_hermes_state.py", + "tests/test_session_metadata_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "15" + ] + } + ], + "merge_events": [ + { + "sha": "dcf8096413c7ee40fe0ab512ac86927fb2092df1", + "subject": "fix(session): literal-safe numbered-title escaping and #N suffix validation (#15)", + "parents": [ + "53da9e89f8f3d2b051bf4c719b9f09b355392c00", + "984eff15df1fb749f00aece7fc24c43e9afcb7e8" + ], + "changed_files": [], + "pr_refs": [ + "15" + ] + } + ], + "affected_files": [ + "docs/design/session-metadata-fts.md", + "docs/research/issue-38-numbered-title-literal-safety.md", + "hermes_state.py", + "hermes_state_common.py", + "tests/test_hermes_state.py", + "tests/test_session_metadata_cjk_fts.py", + "tests/test_session_metadata_fts.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "15" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6", + "record_type": "provenance_bucket", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "commits": [ + { + "sha": "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "parents": [ + "0a4b567ff08776a3a10ee7a32d37332d873f20b2" + ], + "is_merge": false, + "patch_id": "0ca8a64059c02cff35fe7cf0ebdf21fae3357f35", + "changed_files": [ + "plugins/headroom/__init__.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/headroom/__init__.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:76762", + "record_type": "provenance_bucket", + "subject": "fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762)", + "commits": [ + { + "sha": "d53e209b3b620abce55f2cc57a80c69bc0cd9369", + "subject": "fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762)", + "parents": [ + "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb" + ], + "is_merge": false, + "patch_id": "9c58ec803f99f92c66b88ef1ef1dbfb6cb47aa0b", + "changed_files": [ + "cron/lifecycle_guard.py", + "tools/terminal_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [ + "76762" + ] + } + ], + "merge_events": [], + "affected_files": [ + "cron/lifecycle_guard.py", + "tools/terminal_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [ + "76762" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:d72f99eb1b897dd29a46692a310aa15b1bfd77e8", + "record_type": "provenance_bucket", + "subject": "docs(research): index session-lineage research", + "commits": [ + { + "sha": "d72f99eb1b897dd29a46692a310aa15b1bfd77e8", + "subject": "docs(research): index session-lineage research", + "parents": [ + "9b25b0c8bd7408eaf2398529b6a04ed1a068b892" + ], + "is_merge": false, + "patch_id": "e1a04706478dc2a890dba533afd92cc9c99fffa1", + "changed_files": [ + "research/session-lineage/README.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "research/session-lineage/README.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:dc1f153a71d025d903f255861da57f94d649ca37", + "record_type": "provenance_bucket", + "subject": "docs(fts): record review round 2 for #27 unified FTS lifecycle", + "commits": [ + { + "sha": "dc1f153a71d025d903f255861da57f94d649ca37", + "subject": "docs(fts): record review round 2 for #27 unified FTS lifecycle", + "parents": [ + "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec" + ], + "is_merge": false, + "patch_id": "49b9b7ecabfb5e7fa7fee5a2ce8b127141b6155c", + "changed_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "docs/research/issue-27-unified-fts-lifecycle.md" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:dc2270aad84242da42f4342ac137e243ca181aa5", + "record_type": "provenance_bucket", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "commits": [], + "merge_events": [ + { + "sha": "dc2270aad84242da42f4342ac137e243ca181aa5", + "subject": "Merge branch 'fix/fts-simple-tokenizer-complete' into dev", + "parents": [ + "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "44dd4c5e586e60c22a322a9eb89d1aed63892e36" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:dcd10233d32eee72df93ec7ff5f8f9efcec4eef6", + "record_type": "provenance_bucket", + "subject": "fix(search): don't gate exact-title on unrun content snapshot (#68 review round-4)", + "commits": [ + { + "sha": "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6", + "subject": "fix(search): don't gate exact-title on unrun content snapshot (#68 review round-4)", + "parents": [ + "c81ab321ec4bb3d5a33429b28907cd5836e41789" + ], + "is_merge": false, + "patch_id": "88241624668272f5662c662be321ba1515214ee9", + "changed_files": [ + "hermes_state_search.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state_search.py", + "tests/tools/test_session_search.py", + "tools/session_search_tool.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "pr:59", + "record_type": "provenance_bucket", + "subject": "Session metadata FTS: stable row_id + resumable Unicode external-content index (#25) (#59)", + "commits": [ + { + "sha": "e94f2630a50d7585f78cfc06365753c033113cb9", + "subject": "Session metadata FTS: stable row_id + resumable Unicode external-content index (#25) (#59)", + "parents": [ + "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba" + ], + "is_merge": false, + "patch_id": "96d200731949e4ff95efcefeeef9e80dc5f47fc0", + "changed_files": [ + "docs/design/session-metadata-fts.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_fts.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [ + "25" + ], + "pr_refs": [ + "59" + ] + } + ], + "merge_events": [], + "affected_files": [ + "docs/design/session-metadata-fts.md", + "hermes_cli/session_recovery.py", + "hermes_state.py", + "hermes_state_common.py", + "hermes_state_schema.py", + "hermes_state_search.py", + "tests/test_session_metadata_fts.py" + ], + "work_item_provenance": { + "issue_refs": [ + "25" + ], + "pr_refs": [ + "59" + ] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:eed6ba2734bc7aaabbd1e8cf08cd794badc72d71", + "record_type": "provenance_bucket", + "subject": "Merge branch 'fix/truncation-fence-edge-case' into dev", + "commits": [], + "merge_events": [ + { + "sha": "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71", + "subject": "Merge branch 'fix/truncation-fence-edge-case' into dev", + "parents": [ + "9fe97e2aa1b05306ed626e5ae3db540d24bb4678", + "efd68fe044001c57c5d148a66469209589c344d9" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:efd68fe044001c57c5d148a66469209589c344d9", + "record_type": "provenance_bucket", + "subject": "fix: ensure balanced code fences after Discord edit_message brute-force truncation", + "commits": [ + { + "sha": "efd68fe044001c57c5d148a66469209589c344d9", + "subject": "fix: ensure balanced code fences after Discord edit_message brute-force truncation", + "parents": [ + "426f321e84062e00fd5e6e9271aef48263cafffb" + ], + "is_merge": false, + "patch_id": "e791c1b195b0e428fcb2f296a13a381aec9cb518", + "changed_files": [ + "plugins/platforms/discord/adapter.py", + "tests/gateway/test_truncation_fence_edge_case.py", + "tests/plugins/platforms/discord/test_edit_message_fence.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/platforms/discord/adapter.py", + "tests/gateway/test_truncation_fence_edge_case.py", + "tests/plugins/platforms/discord/test_edit_message_fence.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:f18b3c90c2309ee7616010f99c1c927c9f05013f", + "record_type": "provenance_bucket", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/session-trigram-external-content", + "commits": [], + "merge_events": [ + { + "sha": "f18b3c90c2309ee7616010f99c1c927c9f05013f", + "subject": "Merge remote-tracking branch 'origin/dev' into fts/session-trigram-external-content", + "parents": [ + "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea", + "2f90c254d524d618b1c866a10bb519f2c1b6f5dc" + ], + "changed_files": [], + "pr_refs": [] + } + ], + "affected_files": [], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:f32b51764e43e48195d10e62d64b195a052d4968", + "record_type": "provenance_bucket", + "subject": "test(search): #68 review acceptance \u2014 title parity, compacted anchor, real B boundaries, snapshot, 10k, internal-K", + "commits": [ + { + "sha": "f32b51764e43e48195d10e62d64b195a052d4968", + "subject": "test(search): #68 review acceptance \u2014 title parity, compacted anchor, real B boundaries, snapshot, 10k, internal-K", + "parents": [ + "66eb2fad76abf150043ffd899fbdfbd328aba2d0" + ], + "is_merge": false, + "patch_id": "a750f9adc96a4ca3f1d2004f8353c443b9420c85", + "changed_files": [ + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "tests/test_session_search_sql_winners.py", + "tests/tools/test_session_search.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:f779b5320c6008e1c8b49bf7386fdfe76dea7a8a", + "record_type": "provenance_bucket", + "subject": "fix(state): load simple tokenizer so legacy trigram tables stay writable", + "commits": [ + { + "sha": "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a", + "subject": "fix(state): load simple tokenizer so legacy trigram tables stay writable", + "parents": [ + "d53e209b3b620abce55f2cc57a80c69bc0cd9369" + ], + "is_merge": false, + "patch_id": "9feec0370bda997dee075b1c9477969a125e9e97", + "changed_files": [ + "hermes_state.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "hermes_state.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + }, + { + "id": "commit:ff4df5b71e1557660dbe994eb5569983f57c9901", + "record_type": "provenance_bucket", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "commits": [ + { + "sha": "ff4df5b71e1557660dbe994eb5569983f57c9901", + "subject": "fix(headroom): add missing toolset param to register_tool call", + "parents": [ + "0a4b567ff08776a3a10ee7a32d37332d873f20b2" + ], + "is_merge": false, + "patch_id": "0ca8a64059c02cff35fe7cf0ebdf21fae3357f35", + "changed_files": [ + "plugins/headroom/__init__.py" + ], + "graph_presence": { + "upstream_reachable": false, + "fork_exclusive": true + }, + "issue_refs": [], + "pr_refs": [] + } + ], + "merge_events": [], + "affected_files": [ + "plugins/headroom/__init__.py" + ], + "work_item_provenance": { + "issue_refs": [], + "pr_refs": [] + }, + "patch_matches": [], + "exact_upstream_commits": [], + "upstream_status": "NEEDS_REVIEW", + "disposition": "NEEDS_REVIEW", + "confidence": "low", + "evidence": [], + "behavioral_contracts": [] + } + ], + "accounting": { + "discovery_coverage": { + "historical_commits": 171, + "emitted_commit_records": 171, + "complete": true + }, + "capability_accounting": { + "explicitly_accounted_commits": 0, + "unaccounted_commits": [ + "00a2675a9270033325d53d7a3301a58f5f66d760", + "00e680a8cb22e251f351b9f140b0679c4f96dabc", + "0400c66f072d0f319331ea105cd8f7e059975388", + "0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57", + "04f1af72be078cef69de538f1519f93a73088b0d", + "0990803323497a36761c9627a20ceb57be56d5a3", + "0a4b567ff08776a3a10ee7a32d37332d873f20b2", + "0b4e7601227a23bc653d0d3018a3a9591d02f2a1", + "0c02b83d4d8702267481a5f196606e19e3d303cc", + "0cf4cd0baffb68b571a44f2a39d3bf817cd38348", + "0eee69ef43f16c63f29db414e1acb40253212125", + "0f29f1454ea2227229e4056d66ed09f749a06e46", + "0fafc1dd7b58f15982ce2833de2bc8826a1e116f", + "0ff8583e91c838088fde6cb55ba0488cf5a0ee93", + "10e3419d10e938c979c701246457cbd6f9c10ad4", + "15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114", + "1602d06f5045d173ee31161b92e387de69ab821c", + "176646d2cd6c95fa49b9414f21ed9e781b0aaa84", + "17b0d2c9135d38728109592860677c4abbaddf4f", + "180ae82a2d7ec34a099665d68719c8579986d693", + "186986a447080ae74a1d17fd1e32aaf039cb2ff2", + "196b904417371cf233f3eb9b560c80a079ab8d72", + "19e6e6223bb58a4a53c8c02c86a0127d34afaf5a", + "1d5b80cab802e6ae932c97342e328e76faa496fa", + "1d6d73f3bb8ffeb599799c05b6e853da1758b4db", + "1f5edc591353a0a65ec7aa2f02c6916fd67fd505", + "2142e2fa1b491ce904e0dbbbd2cc446863d0fe48", + "237176ed1d973910972984ba83d876d01c00f3db", + "252920f02442b68391fcafba35bef2c9567e9ab8", + "2732c47e28fbf7aaea97bd8c5cf82045a4c34159", + "276d497764feb7d4a71f1424ed44b8958da63b16", + "296d9c6e2e5a6f852344ad8fa9b90f5687912be1", + "2ac803bd949f0aba96c0d4d500edd2ad65aa3036", + "2c907113fd2c50edde60425c561ab8ca25192b1b", + "2d2bad204ec644455ad1273f2934f388eb4111dd", + "2e1b2e64d7a452f524f703a99d68b1b110b93d3e", + "2f12b03079cb7ae28acf666d16cfd748e5eaac74", + "2f90c254d524d618b1c866a10bb519f2c1b6f5dc", + "3053abf3b039a5b4c23637597cb076f2339250fb", + "311bf7d6d28b204f0aa977ddcd05d44141d2d4ba", + "3172c9f4611cc2b872f2083829577cc73152f9dc", + "347442ddc80a2658582cb62dd268a0be024b1bcf", + "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "37811327cdc65c85c4b0bd565b1cdb3a4590dd91", + "3bc7d3f58f808e269675404c9bbeada467b00e98", + "3de538d32a3c076929c1d7c173dd77e4055100f9", + "3e23375f7934e4315d45860e6992171fb5609c5c", + "3ebb2592c141b232ecd0717adf32279afa6bee3f", + "3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d", + "4270ea5b9a903d0dcf692db2365875ac5b3fe319", + "4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba", + "42c421f68b6556757c17b4dc78756cf31babd239", + "433a49f66b447f41fdd488dc4858a07c7cd7154d", + "4483194b81495dab9b3c4c282c08adad89e0f2d9", + "44afcc8d3f869c7780beb1bc0bece86df1e45cb2", + "44dd4c5e586e60c22a322a9eb89d1aed63892e36", + "46907bc8b55ba36ef73e0d96c10eccb9b28b0310", + "474b88fe76e18dfcf397f11b3de6f069abac4a4c", + "47c537c766bb72d7dfbd6a3fe0cbc2bd9985c128", + "47cc1764dc2c2c65cc83fe20500da939698d72d3", + "48b04dae36d6577b06de0efc67ebe1eb1a479d4c", + "4aefa3abbbe4f9c3eba29988fa772e45d70000f9", + "4e5ad5c2230300d1ffae84b089ffc70e368c8a23", + "516d739f64a95a4f380b899fbb9a349d750fc2aa", + "535b33c95f9465bb3e05b281b17fceee3ba24d22", + "53da9e89f8f3d2b051bf4c719b9f09b355392c00", + "55dc24391f92d71d9e293c7990089075f2ff49c9", + "5882274ff6c868c24f9d36f3796de08e5de8a245", + "5eb552458de9828f4496880fd878f58015a63389", + "6311e77e27f4fd4009c73d0df16abebf56121f4a", + "637ef2e193b6b2dada5d0b79173461fca03fbf20", + "6447a52cd994bf30c2811814f21095d12aba83ae", + "6467a30563fb1da2bd5c1f42dc7cd1f574697d31", + "66eb2fad76abf150043ffd899fbdfbd328aba2d0", + "67d4f719d6b0717be024861ae2756fa49d6f1315", + "69591fe659774a4e61a3f754211f5602e96a7381", + "69bee0838ae15936ae4beb13cdf5d6907c19c707", + "6b3402ea05566fa1553a93aceb285eb517d7e67d", + "6f534c8760a30a318ae0d874b7a6323f5f0337df", + "6f82bcbb3c5f714148a17da47577e862493a55d6", + "6fa6c557257175f26c1689799d352fdf948cb787", + "72388ff87f0baf99910edefab2b2fc2e00b40284", + "75223d19544ceb73cf24fb859fc0780ed9a099a5", + "783d3fa59ae28010368368e3dafddc19750f9b55", + "7b4d37c2727ce8b1a12d9ccb22e8a936ca87fab7", + "7b513c6bf2f698f612fceb0c64de84c8c5e0ddea", + "7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0", + "83431f775a9e3798611e03b16a2f7d9a7ac74a57", + "85fd91fd7c7be20d63356f27654d399ca1da4fa0", + "8838d16060bb7610c6d7ad3697f384df3edb70c1", + "895ba96014ecf934dbc140306ffe578a0a533ea3", + "8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f", + "8b085795df0359adbf3c81315f888bc7041fb044", + "8ec0ec3bf85a7414bb4244027b7f018e7eebf1e5", + "8efead2600a3f932f9881b53cd0c7eabc755f82f", + "915913db360de5fe5b147d4895276ff39a6e8686", + "919f4469e832bc2b38bba0ea5af26b842bf91acd", + "933a2ce86c8a8c7379cbbfb1f50686e9bf2febec", + "984eff15df1fb749f00aece7fc24c43e9afcb7e8", + "9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32", + "9aad13bcad68a292f708fe30698405c2016b2626", + "9b25b0c8bd7408eaf2398529b6a04ed1a068b892", + "9d140c8594c67ed37729b190fd3733508d0d770c", + "9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140", + "9e3439835e9dbbad0d0076d539d769db1f84de0a", + "9f3056cb3a9642c39056af8409cc3198007e68a8", + "9fe97e2aa1b05306ed626e5ae3db540d24bb4678", + "a1136e548ea1f2200429bf44f8f1a7297cc84246", + "a13d012e5b8736928662f27269d9f2a7cf84f0af", + "a2450695db0e99f3dd8362f129024cb74c700bb8", + "a34da2c31ca60f9b5280558c514a3a1880035036", + "a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2", + "a4e2c52f1582952686ee56aaedd7285874326102", + "a615feaea695123d1b3a832417a9a76554301af8", + "a822d37d18064d1442eb20b6a2cb4e9f8b17d48d", + "a9c1b2d11bab435cda80fcfc81fc223d210b4755", + "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb", + "ad0c45f0924349f6f0453d4941c3d76ad5258cdc", + "b2710666a29eed6fc46f3b6ce23c72f4dc766181", + "b42bc25e622c11230998cc57f7050ec2a2cdd090", + "b4efc640fab0517571bd05447cf2be2ace9cf3e1", + "b5155410abbf04c1fc4bb433ae3f5e546f5bf426", + "b527e4df996b859356c0c48c2b9c9eae4c74c4dc", + "b66c149de0c8240e84ded1a2f983b8c42f7b984b", + "b7e62647bd657a429d967cfa77034632ee490f9a", + "b86e4f526ec377f7f958dc21ddaac87238882f19", + "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70", + "b97d00e7319e5147d569519b6a34ef63c6635551", + "bdd9d699f6dc13b32852a078c1ecf5664bcb837d", + "bdf2fc218264538c4f3238b58532488fe665ff9e", + "bee13fc085079d78d0334722ad4c37a1144e3102", + "bfa928d53da7c61814816c10f83fef75bfef7e43", + "c16ebe6b8649c570b688fd82d6b66f9a8416d59c", + "c1a3e16c32896ea2d469536c657814049c29bec6", + "c20cb64b4b79468c641626e9b9d3957790f7a671", + "c3f1abc5cc34f1a356740529c9f17dfc0f4157b0", + "c7163001f23feb31f94fec1ebb3c41badaebdb97", + "c81ab321ec4bb3d5a33429b28907cd5836e41789", + "ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e", + "cc2531fbc6df8fdb34fca0b096b798eb53f970dd", + "cc5261ce775c8db6a7099d411f16030d24e71f2f", + "cea5282a181d23af471f4467f449fd9bfc022ca5", + "cfb2636a6a3ed02ff773f106beb71c88576f1284", + "d18dadb5f3b517ec69f14428dc78e7af1a86a30e", + "d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6", + "d4c9a165c5abe6cf8c0503005b18e55de58e28cc", + "d53e209b3b620abce55f2cc57a80c69bc0cd9369", + "d6a4d70483623cc3fad4eea8c96754d7d637d02c", + "d72f99eb1b897dd29a46692a310aa15b1bfd77e8", + "dc1f153a71d025d903f255861da57f94d649ca37", + "dc2270aad84242da42f4342ac137e243ca181aa5", + "dc2cd8cfaf9462316e0140a27a7f5edaf90f3fb3", + "dcd10233d32eee72df93ec7ff5f8f9efcec4eef6", + "dcf8096413c7ee40fe0ab512ac86927fb2092df1", + "deb10243ccebd6153cdfab8e9869faba2e105f0e", + "e1ef573d3feb4e89082e8ff5fe7c941dd3620a9c", + "e33b533e1d2421fb18941463b6fe51752a8ad345", + "e64ad007b459871af42e312bc5dffd2da92ac900", + "e64af5e0f8a3e8816137fd083ca7d567e2f8a0a1", + "e94f2630a50d7585f78cfc06365753c033113cb9", + "ed5ab2e8ecd03a98d70fbf3dca20d830c51d460a", + "eed6ba2734bc7aaabbd1e8cf08cd794badc72d71", + "efd68fe044001c57c5d148a66469209589c344d9", + "f17ab58979753a9ee342d258595e8d076ef2f309", + "f18b3c90c2309ee7616010f99c1c927c9f05013f", + "f32b51764e43e48195d10e62d64b195a052d4968", + "f779b5320c6008e1c8b49bf7386fdfe76dea7a8a", + "f887f44fa2d27c7ec4132fe70d337f7975fcde63", + "f9ade6baff7f236b6b9401932c61bc0400375664", + "faf96ef221ddfba2618abc8dae8368f7b82c1c2a", + "ff4df5b71e1557660dbe994eb5569983f57c9901" + ], + "complete": false + } + } +} diff --git a/artifacts/fork-archaeology-issue-96/inventory.md b/artifacts/fork-archaeology-issue-96/inventory.md new file mode 100644 index 000000000000..d86cec07c7eb --- /dev/null +++ b/artifacts/fork-archaeology-issue-96/inventory.md @@ -0,0 +1,1057 @@ +# Fork archaeology inventory + +- Fork ref: `35c8564c9c0af3d75bcbdf1d793e7207e5528f06` +- Upstream ref: `460d345642ee3d143a3e461abe39fd42b86a7e54` +- Merge base: `91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53` + +| Provenance bucket | Change records | Merge events | Status | Disposition | Confidence | +| --- | ---: | ---: | --- | --- | --- | +| `pr:31` | 9 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:27` | 10 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:04f1af72be078cef69de538f1519f93a73088b0d` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:0990803323497a36761c9627a20ceb57be56d5a3` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:0a4b567ff08776a3a10ee7a32d37332d873f20b2` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:0b4e7601227a23bc653d0d3018a3a9591d02f2a1` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:0cf4cd0baffb68b571a44f2a39d3bf817cd38348` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:65` | 1 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:1602d06f5045d173ee31161b92e387de69ab821c` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:176646d2cd6c95fa49b9414f21ed9e781b0aaa84` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:196b904417371cf233f3eb9b560c80a079ab8d72` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:19e6e6223bb58a4a53c8c02c86a0127d34afaf5a` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:1f5edc591353a0a65ec7aa2f02c6916fd67fd505` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:237176ed1d973910972984ba83d876d01c00f3db` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:2732c47e28fbf7aaea97bd8c5cf82045a4c34159` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:78` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:296d9c6e2e5a6f852344ad8fa9b90f5687912be1` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:2ac803bd949f0aba96c0d4d500edd2ad65aa3036` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:2d2bad204ec644455ad1273f2934f388eb4111dd` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:2e1b2e64d7a452f524f703a99d68b1b110b93d3e` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:2f12b03079cb7ae28acf666d16cfd748e5eaac74` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:72` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:3053abf3b039a5b4c23637597cb076f2339250fb` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:311bf7d6d28b204f0aa977ddcd05d44141d2d4ba` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:347442ddc80a2658582cb62dd268a0be024b1bcf` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:14` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:37811327cdc65c85c4b0bd565b1cdb3a4590dd91` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:3de538d32a3c076929c1d7c173dd77e4055100f9` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:26` | 4 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:3ebb2592c141b232ecd0717adf32279afa6bee3f` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:4270ea5b9a903d0dcf692db2365875ac5b3fe319` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:42c421f68b6556757c17b4dc78756cf31babd239` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:433a49f66b447f41fdd488dc4858a07c7cd7154d` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:44afcc8d3f869c7780beb1bc0bece86df1e45cb2` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:44dd4c5e586e60c22a322a9eb89d1aed63892e36` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:46907bc8b55ba36ef73e0d96c10eccb9b28b0310` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:47cc1764dc2c2c65cc83fe20500da939698d72d3` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:30` | 23 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:516d739f64a95a4f380b899fbb9a349d750fc2aa` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:2` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:87` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:55dc24391f92d71d9e293c7990089075f2ff49c9` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:5882274ff6c868c24f9d36f3796de08e5de8a245` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:5eb552458de9828f4496880fd878f58015a63389` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:6311e77e27f4fd4009c73d0df16abebf56121f4a` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:637ef2e193b6b2dada5d0b79173461fca03fbf20` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:6447a52cd994bf30c2811814f21095d12aba83ae` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:66eb2fad76abf150043ffd899fbdfbd328aba2d0` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:6b3402ea05566fa1553a93aceb285eb517d7e67d` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:6fa6c557257175f26c1689799d352fdf948cb787` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:75223d19544ceb73cf24fb859fc0780ed9a099a5` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:79` | 4 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:83431f775a9e3798611e03b16a2f7d9a7ac74a57` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:19` | 4 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:8838d16060bb7610c6d7ad3697f384df3edb70c1` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:895ba96014ecf934dbc140306ffe578a0a533ea3` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:8b085795df0359adbf3c81315f888bc7041fb044` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:8efead2600a3f932f9881b53cd0c7eabc755f82f` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:915913db360de5fe5b147d4895276ff39a6e8686` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:984eff15df1fb749f00aece7fc24c43e9afcb7e8` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:9b25b0c8bd7408eaf2398529b6a04ed1a068b892` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:76` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:9e3439835e9dbbad0d0076d539d769db1f84de0a` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:9f3056cb3a9642c39056af8409cc3198007e68a8` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:3` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a1136e548ea1f2200429bf44f8f1a7297cc84246` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a13d012e5b8736928662f27269d9f2a7cf84f0af` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a2450695db0e99f3dd8362f129024cb74c700bb8` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a34da2c31ca60f9b5280558c514a3a1880035036` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a4e2c52f1582952686ee56aaedd7285874326102` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a615feaea695123d1b3a832417a9a76554301af8` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a822d37d18064d1442eb20b6a2cb4e9f8b17d48d` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:ad0c45f0924349f6f0453d4941c3d76ad5258cdc` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b2710666a29eed6fc46f3b6ce23c72f4dc766181` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b42bc25e622c11230998cc57f7050ec2a2cdd090` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b4efc640fab0517571bd05447cf2be2ace9cf3e1` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b527e4df996b859356c0c48c2b9c9eae4c74c4dc` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b66c149de0c8240e84ded1a2f983b8c42f7b984b` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b7e62647bd657a429d967cfa77034632ee490f9a` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:b97d00e7319e5147d569519b6a34ef63c6635551` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:bdd9d699f6dc13b32852a078c1ecf5664bcb837d` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:82` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:c16ebe6b8649c570b688fd82d6b66f9a8416d59c` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:c1a3e16c32896ea2d469536c657814049c29bec6` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:c20cb64b4b79468c641626e9b9d3957790f7a671` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:c3f1abc5cc34f1a356740529c9f17dfc0f4157b0` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:c81ab321ec4bb3d5a33429b28907cd5836e41789` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:cc2531fbc6df8fdb34fca0b096b798eb53f970dd` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:cea5282a181d23af471f4467f449fd9bfc022ca5` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:cfb2636a6a3ed02ff773f106beb71c88576f1284` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:15` | 4 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:76762` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:d72f99eb1b897dd29a46692a310aa15b1bfd77e8` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:dc1f153a71d025d903f255861da57f94d649ca37` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:dc2270aad84242da42f4342ac137e243ca181aa5` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:dcd10233d32eee72df93ec7ff5f8f9efcec4eef6` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `pr:59` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:eed6ba2734bc7aaabbd1e8cf08cd794badc72d71` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:efd68fe044001c57c5d148a66469209589c344d9` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:f18b3c90c2309ee7616010f99c1c927c9f05013f` | 0 | 1 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:f32b51764e43e48195d10e62d64b195a052d4968` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:f779b5320c6008e1c8b49bf7386fdfe76dea7a8a` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | +| `commit:ff4df5b71e1557660dbe994eb5569983f57c9901` | 1 | 0 | `NEEDS_REVIEW` | `NEEDS_REVIEW` | `low` | + +## Evidence + +### `pr:31` - test(fts): pin storage-v2 refusal states (#31) + +- Changes: `00a2675a9270`, `b86e4f526ec3`, `2c907113fd2c`, `f887f44fa2d2`, `180ae82a2d7e`, `1d6d73f3bb8f`, `0fafc1dd7b58`, `67d4f719d6b0`, `0ff8583e91c8` +- Merge events: (none) +- Files: `docs/research/issue-31-storage-v2-settlement.md`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_fts_storage_v2_settlement.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:27` - feat(fts): authoritative six-index registry + registry-driven ordinary maintenance (#27) + +- Changes: `00e680a8cb22`, `e64af5e0f8a3`, `474b88fe76e1`, `f9ade6baff7f`, `e64ad007b459`, `0400c66f072d`, `933a2ce86c8a`, `ed5ab2e8ecd0`, `3bc7d3f58f80`, `d6a4d7048362` +- Merge events: (none) +- Files: `docs/research/issue-27-unified-fts-lifecycle.md`, `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_fts_lifecycle_registry.py`, `tests/test_hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:0460c1944c8c7c40c6d9d7b7ebdb9e036aa49d57` - docs(research): record #22 production-ready state.db build and freeze + +- Changes: `0460c1944c8c` +- Merge events: (none) +- Files: `docs/research/issue-22-production-ready-state-db-execution.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:04f1af72be078cef69de538f1519f93a73088b0d` - feat(mem-trim): instrument gc/trim split + malloc_info frag + VmSwap, add RSS low-water threshold + +- Changes: `04f1af72be07` +- Merge events: (none) +- Files: `hermes_cli/mem_trim.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:0990803323497a36761c9627a20ceb57be56d5a3` - test(state): pin session metadata route and fallback contract + +- Changes: `099080332349` +- Merge events: (none) +- Files: `tests/test_session_metadata_picker_routing.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:0a4b567ff08776a3a10ee7a32d37332d873f20b2` - feat(headroom): add retrieval (CCR) support to Phase 1 compression plugin + +- Changes: `0a4b567ff087` +- Merge events: (none) +- Files: `plugins/headroom/__init__.py`, `tests/plugins/test_headroom_plugin.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:0b4e7601227a23bc653d0d3018a3a9591d02f2a1` - fix: headroom_retrieve tool schema — add description and parameters wrapper + +- Changes: `0b4e7601227a` +- Merge events: (none) +- Files: `plugins/headroom/__init__.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:0cf4cd0baffb68b571a44f2a39d3bf817cd38348` - docs(fts): record review round 4 for #27 unified FTS lifecycle + +- Changes: `0cf4cd0baffb` +- Merge events: (none) +- Files: `docs/research/issue-27-unified-fts-lifecycle.md` +- Upstream matches: none +- Evidence: none; review required + +### `pr:65` - fix(session-fts): run CJK guard+MATCH in one SQLite snapshot (PR #65 P1) + +- Changes: `0eee69ef43f1` +- Merge events: `bdf2fc218264` +- Files: `hermes_state.py`, `tests/test_session_metadata_cjk_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:15f5aa07a0a1e4ffcf12b5b90aeea6d187e37114` - fix: migrate FTS5 trigram tokenizer from trigram to simple for CJK search + +- Changes: `15f5aa07a0a1` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:1602d06f5045d173ee31161b92e387de69ab821c` - merge(session-search): ranked Top-N + late-snippet into dev + +- Changes: (none) +- Merge events: `1602d06f5045` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:176646d2cd6c95fa49b9414f21ed9e781b0aaa84` - feat: add lifecycle and SQLite observability telemetry + +- Changes: `176646d2cd6c` +- Merge events: (none) +- Files: `agent/conversation_compression.py`, `agent/conversation_loop.py`, `agent/diagnostic_config.py`, `agent/kernel_telemetry.py`, `agent/lifecycle_telemetry.py`, `agent/sqlite_native_telemetry.py`, `agent/tool_executor.py`, `agent/turn_context.py`, `docs/observability/session-db-api-handoff.md`, `gateway/run.py`, `gateway/stream_consumer.py`, `hermes_cli/config.py`, `hermes_state.py`, `plugins/memory/holographic/__init__.py`, `plugins/platforms/discord/adapter.py`, `scripts/hermes_kernel_trace.py`, `tests/agent/test_lifecycle_telemetry.py`, `tests/agent/test_tool_lifecycle_telemetry.py`, `tests/gateway/test_discord_delivery_lifecycle_telemetry.py`, `tests/gateway/test_stream_lifecycle_telemetry.py`, `tests/plugins/memory/test_holographic_prefetch_gate.py`, `tests/test_machine_health_collector.py`, `tests/test_optional_cjk_tokenizer_fallback.py`, `tests/test_session_db_lock_telemetry.py`, `tests/test_sqlite_kernel_telemetry.py`, `tests/test_sqlite_owner_telemetry.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:196b904417371cf233f3eb9b560c80a079ab8d72` - docs(research): map simple-tokenizer EOL for #40 + +- Changes: `196b90441737` +- Merge events: (none) +- Files: `docs/research/issue-40-simple-tokenizer-eol.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:19e6e6223bb58a4a53c8c02c86a0127d34afaf5a` - docs(research): map normalized session trigram FTS + +- Changes: `19e6e6223bb5` +- Merge events: (none) +- Files: `docs/research/issue-34-normalized-session-metadata-trigram-fts.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:1f5edc591353a0a65ec7aa2f02c6916fd67fd505` - perf(state): narrow session listing before lineage hydration + +- Changes: `1f5edc591353` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:237176ed1d973910972984ba83d876d01c00f3db` - fix(headroom): prevent metadata from expanding tool results + +- Changes: `237176ed1d97` +- Merge events: (none) +- Files: `plugins/headroom/__init__.py`, `plugins/headroom/plugin.yaml`, `tests/plugins/test_headroom_plugin.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:2732c47e28fbf7aaea97bd8c5cf82045a4c34159` - wip(session-search): move winner selection into SQL + +- Changes: `2732c47e28fb` +- Merge events: (none) +- Files: `hermes_state.py`, `tests/test_session_search_sql_winners.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:78` - Merge pull request #78 from Skywind5487/feat/31-storage-v2-settlement + +- Changes: (none) +- Merge events: `276d497764fe` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:296d9c6e2e5a6f852344ad8fa9b90f5687912be1` - feat: add transform_api_request plugin hook for full-payload request transformation + +- Changes: `296d9c6e2e5a` +- Merge events: (none) +- Files: `agent/conversation_loop.py`, `hermes_cli/hooks.py`, `hermes_cli/plugins.py`, `tests/run_agent/test_run_agent.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:2ac803bd949f0aba96c0d4d500edd2ad65aa3036` - feat(session-search): port sessions FTS5 title index (unicode61 + cjk_unicode61) from dev + +- Changes: `2ac803bd949f` +- Merge events: (none) +- Files: `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:2d2bad204ec644455ad1273f2934f388eb4111dd` - fix(session-search): defer winner snippets + +- Changes: `2d2bad204ec6` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:2e1b2e64d7a452f524f703a99d68b1b110b93d3e` - test(search): drop stale generic-parent oracle import after #68 flip + +- Changes: `2e1b2e64d7a4` +- Merge events: (none) +- Files: `tests/test_session_search_sql_winners.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:2f12b03079cb7ae28acf666d16cfd748e5eaac74` - feat(session-search): tool parity + truncation contract for #68 + +- Changes: `2f12b03079cb` +- Merge events: (none) +- Files: `tests/tools/test_session_search.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:72` - Merge pull request #72 from Skywind5487/fix/68-compression-lineage-resolver + +- Changes: (none) +- Merge events: `2f90c254d524` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:3053abf3b039a5b4c23637597cb076f2339250fb` - fix: let all CJK queries use simple tokenizer; cache lineage resolves + +- Changes: `3053abf3b039` +- Merge events: (none) +- Files: `hermes_state.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:311bf7d6d28b204f0aa977ddcd05d44141d2d4ba` - docs(recovery): add production runtime repair runbook + +- Changes: `311bf7d6d28b` +- Merge events: (none) +- Files: `research/recovery/issue-21-production-runtime-runbook.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:347442ddc80a2658582cb62dd268a0be024b1bcf` - fix: escape triple-backtick in reasoning before wrapping in outer code block + +- Changes: `347442ddc80a` +- Merge events: (none) +- Files: `gateway/run.py`, `gateway/stream_consumer.py`, `tests/gateway/test_escape_reasoning_fences.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:14` - feat(session): route session-metadata picker candidates through FTS (#14) + +- Changes: (none) +- Merge events: `35c8564c9c0a` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:37811327cdc65c85c4b0bd565b1cdb3a4590dd91` - feat(title-fts5): add sessions_fts + sessions_fts_trigram FTS5 tables with CJK dispatch + +- Changes: `37811327cdc6` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:3de538d32a3c076929c1d7c173dd77e4055100f9` - perf: reduce SELECT * in get_compression_lineage to 4 columns + +- Changes: `3de538d32a3c` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:26` - test(session-fts): RED contract for CJK session metadata lifecycle (#26) + +- Changes: `3e23375f7934`, `7b4d37c2727c`, `8ec0ec3bf85a`, `47c537c766bb` +- Merge events: (none) +- Files: `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_session_metadata_cjk_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:3ebb2592c141b232ecd0717adf32279afa6bee3f` - test(api): cross-profile resume search + desktop stale-response ordering + +- Changes: `3ebb2592c141` +- Merge events: (none) +- Files: `apps/desktop/src/components/session-picker.test.tsx`, `tests/hermes_cli/test_web_server.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:3f4795a9fbc70c39cbfbe11ed93e66d36b91c01d` - feat(api): route session metadata discovery through the common seam + +- Changes: `3f4795a9fbc7` +- Merge events: (none) +- Files: `hermes_cli/web_routers/profiles.py`, `hermes_cli/web_routers/sessions.py`, `tests/hermes_cli/test_web_server.py`, `tests/hermes_cli/test_web_server_session_search.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:4270ea5b9a903d0dcf692db2365875ac5b3fe319` - chore: ignore fts5_cjk Windows build artifact (.dll) + +- Changes: `4270ea5b9a90` +- Merge events: (none) +- Files: `.gitignore` +- Upstream matches: none +- Evidence: none; review required + +### `commit:4292711d0a7cdcef9ef20399b1da6d4b1c87d9ba` - docs(research): correct #22 path/router evidence with executing-query validation + +- Changes: `4292711d0a7c` +- Merge events: (none) +- Files: `docs/research/issue-22-production-ready-state-db-execution.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:42c421f68b6556757c17b4dc78756cf31babd239` - fix(search): distinct-owner candidates + title-only K=1 snapshot contract (#68 review round-2) + +- Changes: `42c421f68b65` +- Merge events: (none) +- Files: `hermes_state_search.py`, `tests/test_session_search_sql_winners.py`, `tests/tools/test_session_search.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:433a49f66b447f41fdd488dc4858a07c7cd7154d` - Merge branch 'fix/fts-simple-tokenizer-complete' into dev + +- Changes: (none) +- Merge events: `433a49f66b44` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:44afcc8d3f869c7780beb1bc0bece86df1e45cb2` - test: code fence tracking coverage for all send/split paths + +- Changes: `44afcc8d3f86` +- Merge events: (none) +- Files: `tests/gateway/test_code_fence_tracking.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:44dd4c5e586e60c22a322a9eb89d1aed63892e36` - fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs + +- Changes: `44dd4c5e586e` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:46907bc8b55ba36ef73e0d96c10eccb9b28b0310` - feat(search): compression-lineage resolver for #68 winner seam + +- Changes: `46907bc8b55b` +- Merge events: (none) +- Files: `hermes_state_search.py`, `tests/test_session_search_sql_winners.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:47cc1764dc2c2c65cc83fe20500da939698d72d3` - fix: close orphaned code fences on all send paths + +- Changes: `47cc1764dc2c` +- Merge events: (none) +- Files: `gateway/platforms/base.py`, `gateway/stream_consumer.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:30` - feat(fts): add normalized external-content session trigram index (#30) + +- Changes: `48b04dae36d6`, `6f82bcbb3c5f`, `0f29f1454ea2`, `dc2cd8cfaf94`, `252920f02442`, `4483194b8149`, `bfa928d53da7`, `cc5261ce775c`, `e33b533e1d24`, `b5155410abbf`, `9aad13bcad68`, `3172c9f4611c`, `6467a30563fb`, `e1ef573d3feb`, `72388ff87f0b`, `0c02b83d4d87`, `a9c1b2d11bab`, `2142e2fa1b49`, `c7163001f23f`, `6f534c8760a3`, `10e3419d10e9`, `69591fe65977`, `7b513c6bf2f6` +- Merge events: `919f4469e832` +- Files: `docs/research/issue-30-normalized-session-metadata-trigram-fts.md`, `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_session_metadata_trigram_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:516d739f64a95a4f380b899fbb9a349d750fc2aa` - Merge branch 'feat/headroom-retrieval-toolset-autoenable' into dev + +- Changes: (none) +- Merge events: `516d739f64a9` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `pr:2` - Merge PR #2: escape reasoning fences (resolve conflict) + +- Changes: (none) +- Merge events: `535b33c95f94` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `pr:87` - Merge pull request #87 from Skywind5487/feat/19-simple-tokenizer-eol + +- Changes: (none) +- Merge events: `53da9e89f8f3` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:55dc24391f92d71d9e293c7990089075f2ff49c9` - refactor(search): drop title/current lineage-proof protocol per #68 review round-5 + +- Changes: `55dc24391f92` +- Merge events: (none) +- Files: `hermes_state_search.py`, `tests/test_session_search_sql_winners.py`, `tests/tools/test_session_search.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:5882274ff6c868c24f9d36f3796de08e5de8a245` - refactor(state): add snapshot-aware metadata candidate router + +- Changes: `5882274ff6c8` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:5eb552458de9828f4496880fd878f58015a63389` - feat(headroom): add ContentRouter + SmartCrusher integration behind config flag + +- Changes: `5eb552458de9` +- Merge events: (none) +- Files: `plugins/headroom/__init__.py`, `plugins/headroom/plugin.yaml`, `tests/plugins/test_headroom_plugin.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:6311e77e27f4fd4009c73d0df16abebf56121f4a` - docs(research): map CJK session metadata FTS lifecycle for #33 + +- Changes: `6311e77e27f4` +- Merge events: (none) +- Files: `docs/research/issue-33-cjk-session-metadata-fts-lifecycle.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:637ef2e193b6b2dada5d0b79173461fca03fbf20` - Merge remote-tracking branch 'origin/dev' into fts/routed-session-metadata-candidates + +- Changes: (none) +- Merge events: `637ef2e193b6` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:6447a52cd994bf30c2811814f21095d12aba83ae` - fix(state): short-circuit CJK-unservable to direct LIKE + single compression edge + +- Changes: `6447a52cd994` +- Merge events: (none) +- Files: `hermes_state.py`, `hermes_state_common.py`, `tests/test_session_metadata_picker_routing.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:66eb2fad76abf150043ffd899fbdfbd328aba2d0` - fix(search): title/current share in-snapshot roots + compacted anchor fallback (#68 review) + +- Changes: `66eb2fad76ab` +- Merge events: (none) +- Files: `hermes_state_search.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:6b3402ea05566fa1553a93aceb285eb517d7e67d` - fix(session-fts): three lifecycle/capability seams for CJK session FTS (round-3 review) + +- Changes: `6b3402ea0556` +- Merge events: (none) +- Files: `hermes_state.py`, `tests/test_session_metadata_cjk_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:6fa6c557257175f26c1689799d352fdf948cb787` - fix: replace SELECT * with specific columns in get_anchored_view and get_messages_around + +- Changes: `6fa6c5572571` +- Merge events: (none) +- Files: `hermes_state.py`, `tests/hermes_state/test_get_messages_around.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:75223d19544ceb73cf24fb859fc0780ed9a099a5` - docs(fts): record review round 1 for #27 + +- Changes: `75223d19544c` +- Merge events: (none) +- Files: `docs/research/issue-27-unified-fts-lifecycle.md` +- Upstream matches: none +- Evidence: none; review required + +### `pr:79` - test(recovery): pin session-trigram derived markers as generated meta (#79) + +- Changes: `783d3fa59ae2`, `4aefa3abbbe4`, `d4c9a165c5ab`, `f17ab5897975` +- Merge events: `4e5ad5c22303` +- Files: `docs/research/issue-79-session-recovery-trigram-markers.md`, `hermes_cli/session_recovery.py`, `tests/hermes_cli/test_session_recovery.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:7b66bbf8e2af4fc27959f58b5ca70cfaba0346d0` - perf(search): benchmark cold-open + fallback-invariant self-check + +- Changes: `7b66bbf8e2af` +- Merge events: (none) +- Files: `scripts/benchmarks/session_metadata_picker.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:83431f775a9e3798611e03b16a2f7d9a7ac74a57` - docs(design): document the #26 CJK session metadata FTS variant + +- Changes: `83431f775a9e` +- Merge events: (none) +- Files: `docs/design/session-metadata-fts.md` +- Upstream matches: none +- Evidence: none; review required + +### `pr:19` - test(fts): pin simple-tokenizer EOL policy (#19) + +- Changes: `85fd91fd7c7b`, `186986a44708`, `deb10243cceb`, `1d5b80cab802` +- Merge events: (none) +- Files: `docs/research/issue-19-simple-tokenizer-eol-implementation.md`, `hermes_state.py`, `tests/test_optional_cjk_tokenizer_fallback.py`, `tests/test_simple_tokenizer_eol.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:8838d16060bb7610c6d7ad3697f384df3edb70c1` - test(search): RED contracts for #68 compression-lineage resolver + +- Changes: `8838d16060bb` +- Merge events: (none) +- Files: `tests/test_session_search_sql_winners.py`, `tests/tools/test_session_search.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:895ba96014ecf934dbc140306ffe578a0a533ea3` - feat: configurable reasoning max lines via display.reasoning_max_lines + +- Changes: `895ba96014ec` +- Merge events: (none) +- Files: `cli.py`, `gateway/run.py`, `tests/gateway/test_reasoning_max_lines.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:8a0a1a145e2290682e8d4e6f76ed6ec90b0b933f` - Merge branch 'fix/browser-timeout-daemon-kill-toggle' into dev + +- Changes: (none) +- Merge events: `8a0a1a145e22` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:8b085795df0359adbf3c81315f888bc7041fb044` - docs(research): record #22 redo with SQLite 3.51.3 + CJK + fuzz + +- Changes: `8b085795df03` +- Merge events: (none) +- Files: `docs/research/issue-22-production-ready-state-db-execution.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:8efead2600a3f932f9881b53cd0c7eabc755f82f` - fix(session-fts): address #26 code-review findings + +- Changes: `8efead2600a3` +- Merge events: (none) +- Files: `docs/design/session-metadata-fts.md`, `hermes_cli/session_recovery.py`, `hermes_state.py`, `hermes_state_search.py`, `tests/hermes_cli/test_session_recovery.py`, `tests/test_session_metadata_cjk_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:915913db360de5fe5b147d4895276ff39a6e8686` - Add opt-in headroom tool-output compression plugin + +- Changes: `915913db360d` +- Merge events: (none) +- Files: `hermes_cli/config.py`, `plugins/headroom/__init__.py`, `plugins/headroom/plugin.yaml`, `tests/plugins/test_headroom_plugin.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:984eff15df1fb749f00aece7fc24c43e9afcb7e8` - Merge remote-tracking branch 'origin/dev' into fix/15-numbered-title-literal-safety + +- Changes: (none) +- Merge events: `984eff15df1f` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:9a1f477df5c8f25fd7ba4f57318e9f5ffcb2fc32` - fix(session-search): ranked Top-N pre-limit for relevance sort + +- Changes: `9a1f477df5c8` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:9b25b0c8bd7408eaf2398529b6a04ed1a068b892` - docs: research #32 session row_id unicode FTS + +- Changes: `9b25b0c8bd74` +- Merge events: (none) +- Files: `docs/research/issue-32-stable-row-id-unicode-session-fts.md` +- Upstream matches: none +- Evidence: none; review required + +### `pr:76` - Merge pull request #76 from Skywind5487/feat/27-unified-fts-lifecycle + +- Changes: (none) +- Merge events: `9d140c8594c6` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:9d6accc0f3de1e99c8c4fde24a8f5e3fcf5ef140` - Merge remote-tracking branch 'origin/main' into dev + +- Changes: (none) +- Merge events: `9d6accc0f3de` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:9e3439835e9dbbad0d0076d539d769db1f84de0a` - Merge remote-tracking branch 'origin/main' into fix/browser-timeout-daemon-kill-toggle + +- Changes: (none) +- Merge events: `9e3439835e9d` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:9f3056cb3a9642c39056af8409cc3198007e68a8` - ignore agents + +- Changes: `9f3056cb3a96` +- Merge events: (none) +- Files: `.gitignore` +- Upstream matches: none +- Evidence: none; review required + +### `pr:3` - Merge PR #3: configurable reasoning max lines + +- Changes: (none) +- Merge events: `9fe97e2aa1b0` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:a1136e548ea1f2200429bf44f8f1a7297cc84246` - fix: load simple FTS5 tokenizer and apply read-performance PRAGMAs + +- Changes: `a1136e548ea1` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:a13d012e5b8736928662f27269d9f2a7cf84f0af` - docs(session-storage): document #68 compression-lineage resolution + +- Changes: `a13d012e5b87` +- Merge events: (none) +- Files: `website/docs/developer-guide/session-storage.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:a2450695db0e99f3dd8362f129024cb74c700bb8` - fix(browser): config-gated daemon kill on timeout + +- Changes: `a2450695db0e` +- Merge events: (none) +- Files: `tools/browser_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:a34da2c31ca60f9b5280558c514a3a1880035036` - Merge branch 'fix/session-search-perf' of /home/skywind5487/hermes_worktrees/fix/session-search-perf into dev + +- Changes: (none) +- Merge events: `a34da2c31ca6` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:a4ceb2521b8bb14e753e6f02242d0a29f6d57fb2` - style(session-fts): drop duplicate @staticmethod (round-2 review) + +- Changes: `a4ceb2521b8b` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:a4e2c52f1582952686ee56aaedd7285874326102` - fix: address Copilot review — init hermes_home, load simple in ro path, v21 migration + +- Changes: `a4e2c52f1582` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:a615feaea695123d1b3a832417a9a76554301af8` - test(state): cover whole-store lineage visibility and pagination + +- Changes: `a615feaea695` +- Merge events: (none) +- Files: `tests/test_session_metadata_picker_routing.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:a822d37d18064d1442eb20b6a2cb4e9f8b17d48d` - docs(fts): record review round 3 for #27 unified FTS lifecycle + +- Changes: `a822d37d1806` +- Merge events: (none) +- Files: `docs/research/issue-27-unified-fts-lifecycle.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb` - fix(mem-trim): gate gc.collect() behind gc_cooldown_seconds, measure frag before trim + +- Changes: `a9d2b9af4f80` +- Merge events: (none) +- Files: `hermes_cli/mem_trim.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:ad0c45f0924349f6f0453d4941c3d76ad5258cdc` - test(fts): pin modern session trigram and legacy-simple states + +- Changes: `ad0c45f09243` +- Merge events: (none) +- Files: `tests/test_session_metadata_trigram_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:b2710666a29eed6fc46f3b6ce23c72f4dc766181` - test(search): rename title==current test, correct misleading scope claim (#68 review final) + +- Changes: `b2710666a29e` +- Merge events: (none) +- Files: `tests/tools/test_session_search.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:b42bc25e622c11230998cc57f7050ec2a2cdd090` - fix(browser): add tests and crash-resilience for daemon-kill on timeout + +- Changes: `b42bc25e622c` +- Merge events: (none) +- Files: `tests/tools/test_browser_terminate_daemon_timeout.py`, `tests/tools/test_browser_timeout_cleanup.py`, `tools/browser_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:b4efc640fab0517571bd05447cf2be2ace9cf3e1` - feat(desktop): search the whole session store in the resume picker + +- Changes: `b4efc640fab0` +- Merge events: (none) +- Files: `apps/desktop/src/components/session-picker.test.tsx`, `apps/desktop/src/components/session-picker.tsx`, `apps/desktop/src/hermes.test.ts`, `apps/desktop/src/hermes.ts`, `apps/desktop/src/i18n/en.ts`, `apps/desktop/src/i18n/types.ts`, `apps/desktop/src/i18n/zh.ts` +- Upstream matches: none +- Evidence: none; review required + +### `commit:b527e4df996b859356c0c48c2b9c9eae4c74c4dc` - fix(headroom): auto-enable headroom_retrieve tool when compression is active + +- Changes: `b527e4df996b` +- Merge events: (none) +- Files: `hermes_cli/tools_config.py`, `plugins/headroom/plugin.yaml`, `pyproject.toml`, `uv.lock` +- Upstream matches: none +- Evidence: none; review required + +### `commit:b66c149de0c8240e84ded1a2f983b8c42f7b984b` - merge(main): absorb upstream main 91937a6dc into dev — keep session-search fix chain + +- Changes: (none) +- Merge events: `b66c149de0c8` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:b7e62647bd657a429d967cfa77034632ee490f9a` - feat(headroom): merge ContentRouter + warning E2E tests into dev + +- Changes: (none) +- Merge events: `b7e62647bd65` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70` - perf(search): batch context queries — chunked session_id batches (20/sql) + +- Changes: `b879cbd332b8` +- Merge events: (none) +- Files: `hermes_state.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:b97d00e7319e5147d569519b6a34ef63c6635551` - perf(search): benchmark routed session metadata candidates + +- Changes: `b97d00e7319e` +- Merge events: (none) +- Files: `scripts/benchmarks/session_metadata_picker.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:bdd9d699f6dc13b32852a078c1ecf5664bcb837d` - docs(fts): record six-index unified lifecycle implementation for #27 + +- Changes: `bdd9d699f6dc` +- Merge events: (none) +- Files: `docs/research/issue-27-unified-fts-lifecycle.md` +- Upstream matches: none +- Evidence: none; review required + +### `pr:82` - Merge pull request #82 from Skywind5487/feat/22-production-ready-state-db-execution + +- Changes: (none) +- Merge events: `bee13fc08507` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:c16ebe6b8649c570b688fd82d6b66f9a8416d59c` - fix(headroom): logger.warning for ContentRouter/CacheAligner failures + warning E2E tests + +- Changes: `c16ebe6b8649` +- Merge events: (none) +- Files: `plugins/headroom/__init__.py`, `tests/plugins/test_headroom_plugin.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:c1a3e16c32896ea2d469536c657814049c29bec6` - fix: also close orphaned single-backtick inline-code spans + +- Changes: `c1a3e16c3289` +- Merge events: (none) +- Files: `gateway/stream_consumer.py`, `tests/gateway/test_code_fence_tracking.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:c20cb64b4b79468c641626e9b9d3957790f7a671` - fix: address Copilot review — init hermes_home, load simple in ro path, v21 migration + +- Changes: `c20cb64b4b79` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:c3f1abc5cc34f1a356740529c9f17dfc0f4157b0` - fix: use _rowid_ (INT) instead of id (TEXT) for sessions_fts triggers and queries + +- Changes: `c3f1abc5cc34` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:c81ab321ec4bb3d5a33429b28907cd5836e41789` - fix(search): displayable-anchor ranking + drop unproven title on B-hit (#68 review round-3) + +- Changes: `c81ab321ec4b` +- Merge events: (none) +- Files: `hermes_state_search.py`, `tests/test_session_search_sql_winners.py`, `tests/tools/test_session_search.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:ca4d3041a5e0b6d2b792cdf3c9f2689c9a18683e` - fix(session-search): define ranked_candidates for LIKE route + +- Changes: `ca4d3041a5e0` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:cc2531fbc6df8fdb34fca0b096b798eb53f970dd` - fix: exponential backoff, slow-write log, and Discord API delivery log + +- Changes: `cc2531fbc6df` +- Merge events: (none) +- Files: `hermes_state.py`, `plugins/platforms/discord/adapter.py`, `tests/tools/test_web_searxng_e2e.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:cea5282a181d23af471f4467f449fd9bfc022ca5` - docs(recovery): attest production gateway runtime surface + +- Changes: `cea5282a181d` +- Merge events: (none) +- Files: `research/recovery/issue-41-production-gateway-runtime-attestation.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:cfb2636a6a3ed02ff773f106beb71c88576f1284` - fix(browser): move dict cleanup to finally block on timeout (P1 fix) + +- Changes: `cfb2636a6a3e` +- Merge events: (none) +- Files: `.github/actions/hermes-smoke-test/action.yml`, `.github/workflows/build-windows-installer.yml`, `.github/workflows/docker-publish.yml`, `.github/workflows/nix-lockfile-fix.yml`, `.github/workflows/nix.yml`, `agent/gemini_cloudcode_adapter.py`, `agent/google_code_assist.py`, `agent/google_oauth.py`, `apps/desktop/src/app/chat/composer/skin-slash-popover.tsx`, `apps/desktop/src/app/cron/cron-job-actions-menu.tsx`, `apps/desktop/src/app/overlays/overlay-search-input.tsx`, `apps/desktop/src/app/right-sidebar/terminal/index.tsx`, `apps/desktop/src/app/session/hooks/use-message-stream.ts`, `apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx`, `apps/desktop/src/app/session/hooks/use-prompt-actions.ts`, `apps/desktop/src/app/session/hooks/use-session-actions.ts`, `apps/desktop/src/components/assistant-ui/streaming.test.tsx`, `apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx`, `apps/desktop/src/components/assistant-ui/thread.tsx`, `apps/desktop/src/components/assistant-ui/todo-tool.tsx`, `apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx`, `apps/desktop/src/components/assistant-ui/tool-approval.test.tsx`, `apps/desktop/src/components/assistant-ui/tool-approval.tsx`, `apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts`, `apps/desktop/src/components/assistant-ui/tool-fallback-model.ts`, `apps/desktop/src/components/assistant-ui/tool-fallback.tsx`, `apps/desktop/src/components/assistant-ui/user-message-text.tsx`, `apps/desktop/src/components/chat/generated-image-context.tsx`, `apps/desktop/src/components/desktop-onboarding-overlay.test.tsx`, `apps/desktop/src/components/desktop-onboarding-overlay.tsx`, `apps/desktop/src/components/ui/braille-spinner.tsx`, `apps/desktop/src/lib/gateway-ws-url.ts`, `gateway/platforms/dingtalk.py`, `gateway/platforms/email.py`, `gateway/platforms/feishu.py`, `gateway/platforms/feishu_comment.py`, `gateway/platforms/feishu_comment_rules.py`, `gateway/platforms/feishu_meeting_invite.py`, `gateway/platforms/homeassistant.py`, `gateway/platforms/matrix.py`, `gateway/platforms/slack.py`, `gateway/platforms/sms.py`, `gateway/platforms/telegram.py`, `gateway/platforms/telegram_network.py`, `gateway/platforms/wecom.py`, `gateway/platforms/wecom_callback.py`, `gateway/platforms/wecom_crypto.py`, `gateway/platforms/whatsapp.py`, `optional-skills/productivity/shop-app/SKILL.md`, `plans/gemini-oauth-provider.md`, `tests/tools/test_browser_timeout_cleanup.py`, `tools/browser_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:15` - test(session): pin literal-safe numbered-title resolution (#15) + +- Changes: `d18dadb5f3b5`, `faf96ef221dd`, `69bee0838ae1`, `17b0d2c9135d` +- Merge events: `dcf8096413c7` +- Files: `docs/design/session-metadata-fts.md`, `docs/research/issue-38-numbered-title-literal-safety.md`, `hermes_state.py`, `hermes_state_common.py`, `tests/test_hermes_state.py`, `tests/test_session_metadata_cjk_fts.py`, `tests/test_session_metadata_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:d3f44c9d63b7b3444e2cf4c71fcbde86020e6ea6` - fix(headroom): add missing toolset param to register_tool call + +- Changes: `d3f44c9d63b7` +- Merge events: (none) +- Files: `plugins/headroom/__init__.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:76762` - fix(cron): harden lifecycle guard + terminal fallback against NUL-bearing paths (#76762) + +- Changes: `d53e209b3b62` +- Merge events: (none) +- Files: `cron/lifecycle_guard.py`, `tools/terminal_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:d72f99eb1b897dd29a46692a310aa15b1bfd77e8` - docs(research): index session-lineage research + +- Changes: `d72f99eb1b89` +- Merge events: (none) +- Files: `research/session-lineage/README.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:dc1f153a71d025d903f255861da57f94d649ca37` - docs(fts): record review round 2 for #27 unified FTS lifecycle + +- Changes: `dc1f153a71d0` +- Merge events: (none) +- Files: `docs/research/issue-27-unified-fts-lifecycle.md` +- Upstream matches: none +- Evidence: none; review required + +### `commit:dc2270aad84242da42f4342ac137e243ca181aa5` - Merge branch 'fix/fts-simple-tokenizer-complete' into dev + +- Changes: (none) +- Merge events: `dc2270aad842` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:dcd10233d32eee72df93ec7ff5f8f9efcec4eef6` - fix(search): don't gate exact-title on unrun content snapshot (#68 review round-4) + +- Changes: `dcd10233d32e` +- Merge events: (none) +- Files: `hermes_state_search.py`, `tests/tools/test_session_search.py`, `tools/session_search_tool.py` +- Upstream matches: none +- Evidence: none; review required + +### `pr:59` - Session metadata FTS: stable row_id + resumable Unicode external-content index (#25) (#59) + +- Changes: `e94f2630a50d` +- Merge events: (none) +- Files: `docs/design/session-metadata-fts.md`, `hermes_cli/session_recovery.py`, `hermes_state.py`, `hermes_state_common.py`, `hermes_state_schema.py`, `hermes_state_search.py`, `tests/test_session_metadata_fts.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:eed6ba2734bc7aaabbd1e8cf08cd794badc72d71` - Merge branch 'fix/truncation-fence-edge-case' into dev + +- Changes: (none) +- Merge events: `eed6ba2734bc` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:efd68fe044001c57c5d148a66469209589c344d9` - fix: ensure balanced code fences after Discord edit_message brute-force truncation + +- Changes: `efd68fe04400` +- Merge events: (none) +- Files: `plugins/platforms/discord/adapter.py`, `tests/gateway/test_truncation_fence_edge_case.py`, `tests/plugins/platforms/discord/test_edit_message_fence.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:f18b3c90c2309ee7616010f99c1c927c9f05013f` - Merge remote-tracking branch 'origin/dev' into fts/session-trigram-external-content + +- Changes: (none) +- Merge events: `f18b3c90c230` +- Files: (none) +- Upstream matches: none +- Evidence: none; review required + +### `commit:f32b51764e43e48195d10e62d64b195a052d4968` - test(search): #68 review acceptance — title parity, compacted anchor, real B boundaries, snapshot, 10k, internal-K + +- Changes: `f32b51764e43` +- Merge events: (none) +- Files: `tests/test_session_search_sql_winners.py`, `tests/tools/test_session_search.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:f779b5320c6008e1c8b49bf7386fdfe76dea7a8a` - fix(state): load simple tokenizer so legacy trigram tables stay writable + +- Changes: `f779b5320c60` +- Merge events: (none) +- Files: `hermes_state.py` +- Upstream matches: none +- Evidence: none; review required + +### `commit:ff4df5b71e1557660dbe994eb5569983f57c9901` - fix(headroom): add missing toolset param to register_tool call + +- Changes: `ff4df5b71e15` +- Merge events: (none) +- Files: `plugins/headroom/__init__.py` +- Upstream matches: none +- Evidence: none; review required + +Discovery completeness: **PASS** — 171 of 171 records emitted. +Capability accounting: **FAIL** - explicit disposition mapping is required before this gate can pass. diff --git a/docs/research/fork-archaeology.md b/docs/research/fork-archaeology.md new file mode 100644 index 000000000000..8516aef3cd49 --- /dev/null +++ b/docs/research/fork-archaeology.md @@ -0,0 +1,48 @@ +# Fork archaeology inventory + +`fork_archaeology.py` is the evidence-preserving discovery slice for issue +#96. It accepts three immutable commit SHAs, verifies the supplied merge base, +and emits JSON and Markdown from one model. + +```powershell +python scripts/fork_archaeology.py ` + --repo . ` + --fork-ref <40-char-fork-sha> ` + --upstream-ref <40-char-upstream-sha> ` + --merge-base <40-char-merge-base-sha> ` + --intent-map intent-map.json ` + --evidence-file evidence.json ` + --output-dir artifacts/fork-archaeology +``` + +The output is deliberately an evidence layer, not a capability verdict: + +- `commits` are historical change records; `merge_events` are integration + evidence and never receive a patch-id. +- `provenance_buckets` are provisional grouping candidates, not capabilities. +- A patch-id match is reported as + `PATCH_EQUIVALENT_UPSTREAM_HISTORY` with the matching upstream SHA. It never + authorizes `DROP`; current-survival and behavioral evidence are required. +- `discovery_coverage` can pass when every historical record was emitted, but + `capability_accounting` remains FAIL until an explicit intent map accounts + for every commit. This prevents heuristic fallback from becoming a safety + gate. +- Evidence validation rejects unsupported combinations such as `FORK_ONLY` + + `DROP`, and requires evidence/contracts for semantic ownership claims. + +The optional intent map records human-reviewed capability assignments: + +```json +{"commits": {"": "capability:session-search"}} +``` + +The optional evidence file is the human/behavioral boundary. It may record +semantic equivalence, partial absorption, lost-in-fork findings, contracts, +confidence, and disposition only when the required evidence is present. + +The issue's reference SHAs must already exist in the local object database. A +missing object is an input failure, not evidence that a feature is absent. The +frozen #96 run is checked in under +[`artifacts/fork-archaeology-issue-96/`](../../artifacts/fork-archaeology-issue-96/). +It contains the 171 historical records and provisional provenance buckets; +these are intentionally not presented as completed capabilities. diff --git a/docs/research/fork-capability-accounting-issue-100.md b/docs/research/fork-capability-accounting-issue-100.md new file mode 100644 index 000000000000..f038fcc6af97 --- /dev/null +++ b/docs/research/fork-capability-accounting-issue-100.md @@ -0,0 +1,47 @@ +# Issue #100: frozen fork capability accounting + +This report is the Phase-1 semantic accounting for the frozen fork history requested by [issue #100](https://github.com/Skywind5487/hermes-agent/issues/100). It consumes the inventory produced by [PR #99](https://github.com/Skywind5487/hermes-agent/pull/99) and does not change the excavation tooling. + +## Frozen boundary + +- Fork: `35c8564c9c0af3d75bcbdf1d793e7207e5528f06` +- Upstream: `460d345642ee3d143a3e461abe39fd42b86a7e54` +- Merge base: `91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53` +- Input: 145 historical change records and 26 merge events. +- Result: all 171 records are explicitly mapped; the archaeology runner reports discovery and capability accounting PASS. + +The original 116 provisional provenance buckets are not used as capability boundaries. They remain available in the input inventory and are listed as `source_inventory_records` in the manifest. + +## Grouping method + +Each record was triaged on four axes: + +1. historical intent and behavioral contract; +2. merge provenance and work-item identity; +3. survival in the frozen fork dev tree and tests; +4. semantic prior art/current implementation at the frozen upstream ref. + +A capability is only a behavior boundary that can state an observable contract and a verification surface. Research notes, production evidence, benchmarks, integration topology, and isolated maintenance are explicit non-capability categories rather than silent omissions. Merge events with their own feature provenance stay attached to that capability; integration-only merges are accounted as bookkeeping. + +## Phase-1 disposition + +The main port candidates are the session FTS family (Unicode base, CJK, normalized trigram, unified lifecycle, and storage-v2), session search routing, compression-lineage search, literal-safe numbered-title resolution, headroom compression/CCR retrieval, browser timeout cleanup, configurable reasoning display, and the full-payload request transform hook. + +Two boundaries are already semantically upstream at the frozen ref and are marked `DROP`: outbound code-fence/truncation safety and legacy simple-tokenizer retirement. Numbered-title safety and compression-lineage search are `PARTIAL_UPSTREAM` and therefore `SPLIT`, not exact replacements. Lifecycle/SQLite telemetry and memory-trim observability remain `NEEDS_REVIEW` because the current comparison does not establish stable cross-project contracts. + +The machine-readable manifest contains the per-group historical commits, issues/PRs, merge events, contracts/tests, current-dev survival, upstream evidence, status, disposition, confidence, and unresolved questions. The generated inventory is the auditable 171-record accounting layer. + +## Phase-2 boundaries + +- Port session metadata FTS base, CJK, trigram, lifecycle, and storage-v2 as separate slices with explicit dependency ordering. +- Port session search routing only after index contracts and the lineage resolver are independently validated. +- Evaluate headroom output compression and CCR retrieval as separate optional plugin slices. +- Port configurable reasoning display and request transformation after upstream hook/config ordering is specified. +- Keep telemetry, memory-trim observability, and incidental hardening in `NEEDS_REVIEW` until their contracts and upstream comparisons are complete. + +## Evidence gaps + +- Frozen upstream has partial lineage/title prior art, but not the stronger fork contracts; replacement requires focused behavior tests. +- The session FTS family is fork-only at the frozen upstream ref, but deployment/tokenizer and migration policies still need upstream-target decisions. +- Some broad observability and maintenance records survive in dev without a stable issue-level contract; they are intentionally not promoted. +- Static archaeology does not prove runtime equivalence. A Phase-2 port needs fresh isolated tests and, where applicable, live database/browser/Discord validation. diff --git a/scripts/fork_archaeology.py b/scripts/fork_archaeology.py new file mode 100644 index 000000000000..514c7931db30 --- /dev/null +++ b/scripts/fork_archaeology.py @@ -0,0 +1,385 @@ +#!/usr/bin/env python3 +"""Build a reproducible, evidence-backed inventory of fork history.""" + +from __future__ import annotations + +import argparse +import json +import re +import subprocess +from dataclasses import dataclass +from pathlib import Path +from typing import Any + +SHA_RE = re.compile(r"^[0-9a-f]{40}$") +PAREN_REF_RE = re.compile(r"\(#(\d+)\)") +PR_REF_RE = re.compile(r"\b(?:PR|pull request)\s*#?(\d+)", re.IGNORECASE) +STATUSES = { + "PATCH_EQUIVALENT_UPSTREAM_HISTORY", + "EXACT_UPSTREAM", + "SEMANTIC_UPSTREAM", + "PARTIAL_UPSTREAM", + "FORK_ONLY", + "LOST_IN_FORK", + "NEEDS_REVIEW", +} +DISPOSITIONS = {"DROP", "KEEP", "PORT", "SPLIT", "NEEDS_REVIEW"} + + +class AuditInputError(ValueError): + """Raised when an archaeology run is not reproducible or evidence is invalid.""" + + +def _safe_repo(repo: Path) -> str: + return repo.resolve().as_posix() + + +@dataclass(frozen=True) +class CommitRecord: + sha: str + subject: str + parents: tuple[str, ...] + is_merge: bool + patch_id: str | None + changed_files: tuple[str, ...] + provisional_bucket: str + issue_refs: tuple[str, ...] + pr_refs: tuple[str, ...] + upstream_reachable: bool + + +def _git(repo: Path, *args: str) -> str: + result = subprocess.run( + ["git", "-c", f"safe.directory={_safe_repo(repo)}", "-C", str(repo), *args], + check=False, + capture_output=True, + text=True, + encoding="utf-8", + errors="replace", + ) + if result.returncode: + raise AuditInputError(result.stderr.strip() or f"git {' '.join(args)} failed") + return result.stdout.strip() + + +def _require_sha(name: str, value: str) -> None: + if not SHA_RE.fullmatch(value): + raise AuditInputError(f"{name} must be a full 40-character commit SHA") + + +def _patch_id(repo: Path, commit: str) -> str | None: + patch = subprocess.run( + ["git", "-c", f"safe.directory={_safe_repo(repo)}", "-C", str(repo), "show", "--format=", "--binary", commit], + check=False, + capture_output=True, + text=True, + encoding="utf-8", + errors="replace", + ) + if patch.returncode: + raise AuditInputError(patch.stderr.strip()) + result = subprocess.run( + ["git", "patch-id", "--stable"], + input=patch.stdout, + check=False, + capture_output=True, + text=True, + encoding="utf-8", + errors="replace", + ) + if result.returncode: + raise AuditInputError(result.stderr.strip()) + return result.stdout.split(maxsplit=1)[0] if result.stdout.strip() else None + + +def _changed_files(repo: Path, commit: str) -> tuple[str, ...]: + return tuple(sorted(filter(None, _git(repo, "diff-tree", "--no-commit-id", "--name-only", "-r", commit).splitlines()))) + + +def _refs(subject: str) -> tuple[tuple[str, ...], tuple[str, ...]]: + parenthesized = [match.group(1) for match in PAREN_REF_RE.finditer(subject)] + explicit_prs = [match.group(1) for match in PR_REF_RE.finditer(subject)] + if explicit_prs: + return tuple(parenthesized), tuple(dict.fromkeys(explicit_prs)) + if parenthesized: + # Squash messages commonly end in the GitHub PR marker: title (#issue) (#pr). + return tuple(parenthesized[:-1]), (parenthesized[-1],) + return (), () + + +def _bucket(subject: str, commit: str, intent_map: dict[str, str]) -> str: + if commit in intent_map: + return intent_map[commit] + _, prs = _refs(subject) + return f"pr:{prs[-1]}" if prs else f"commit:{commit}" + + +def _is_ancestor(repo: Path, ancestor: str, descendant: str) -> bool: + result = subprocess.run( + ["git", "-c", f"safe.directory={_safe_repo(repo)}", "-C", str(repo), "merge-base", "--is-ancestor", ancestor, descendant], + check=False, + capture_output=True, + ) + if result.returncode not in (0, 1): + raise AuditInputError(result.stderr.decode(errors="replace").strip()) + return result.returncode == 0 + + +def _commit_records(repo: Path, merge_base: str, fork_ref: str, upstream_ref: str, intent_map: dict[str, str]) -> list[CommitRecord]: + raw = _git(repo, "log", "--reverse", "--format=%H%x09%P%x09%s", f"{merge_base}..{fork_ref}") + records: list[CommitRecord] = [] + for row in raw.splitlines(): + sha, raw_parents, subject = row.split("\t", 2) + parents = tuple(raw_parents.split()) + issue_refs, pr_refs = _refs(subject) + is_merge = len(parents) > 1 + records.append( + CommitRecord( + sha=sha, + subject=subject, + parents=parents, + is_merge=is_merge, + patch_id=None if is_merge else _patch_id(repo, sha), + changed_files=_changed_files(repo, sha), + provisional_bucket=_bucket(subject, sha, intent_map), + issue_refs=issue_refs, + pr_refs=pr_refs, + upstream_reachable=_is_ancestor(repo, sha, upstream_ref), + ) + ) + return records + + +def _upstream_patch_ids(repo: Path, merge_base: str, upstream_ref: str, touched_files: set[str]) -> dict[str, list[str]]: + """Return patch-id provenance for relevant upstream history in one Git batch.""" + raw = _git(repo, "log", "--no-merges", "--format=%H", "--name-only", f"{merge_base}..{upstream_ref}") + candidates: list[tuple[str, set[str]]] = [] + current_commit: str | None = None + current_files: set[str] = set() + for line in raw.splitlines(): + if SHA_RE.fullmatch(line): + if current_commit is not None: + candidates.append((current_commit, current_files)) + current_commit, current_files = line, set() + elif line: + current_files.add(line) + if current_commit is not None: + candidates.append((current_commit, current_files)) + + # One Git process plus one patch-id process handles the complete candidate set. + commits = [sha for sha, files in candidates if files.intersection(touched_files)] + if not commits: + return {} + patches = subprocess.run( + ["git", "-c", f"safe.directory={_safe_repo(repo)}", "-C", str(repo), "show", "--format=%H", "--binary", "--no-ext-diff", *commits], + check=False, + capture_output=True, + text=True, + encoding="utf-8", + errors="replace", + ) + if patches.returncode: + raise AuditInputError(patches.stderr.strip()) + patch_ids = subprocess.run( + ["git", "patch-id", "--stable"], + input=patches.stdout, + check=False, + capture_output=True, + text=True, + encoding="utf-8", + errors="replace", + ) + if patch_ids.returncode: + raise AuditInputError(patch_ids.stderr.strip()) + ids: dict[str, list[str]] = {} + found = [line.split(maxsplit=1)[0] for line in patch_ids.stdout.splitlines() if line.strip()] + if len(found) != len(commits): + raise AuditInputError("batched upstream patch-id output did not preserve commit mapping") + for sha, patch_id in zip(commits, found): + ids.setdefault(patch_id, []).append(sha) + return ids + + +def _validate_evidence(raw: Any) -> dict[str, dict[str, Any]]: + if raw is None: + return {} + if not isinstance(raw, dict): + raise AuditInputError("evidence must be an object with an 'intents' object") + items = raw["intents"] if "intents" in raw else raw + if not isinstance(items, dict): + raise AuditInputError("evidence must be an object with an 'intents' object") + validated: dict[str, dict[str, Any]] = {} + for bucket, item in items.items(): + if not isinstance(bucket, str) or not isinstance(item, dict): + raise AuditInputError("each evidence bucket must map a string id to an object") + status = item.get("upstream_status") + disposition = item.get("disposition") + if status is not None and status not in STATUSES: + raise AuditInputError(f"invalid upstream_status for {bucket}: {status}") + if disposition is not None and disposition not in DISPOSITIONS: + raise AuditInputError(f"invalid disposition for {bucket}: {disposition}") + evidence = item.get("evidence", []) + contracts = item.get("behavioral_contracts", []) + if not isinstance(evidence, list) or not isinstance(contracts, list): + raise AuditInputError(f"evidence and behavioral_contracts must be lists: {bucket}") + if not all(isinstance(value, str) for value in evidence + contracts): + raise AuditInputError(f"evidence and behavioral_contracts must contain strings: {bucket}") + if disposition == "DROP" and (status not in {"EXACT_UPSTREAM", "SEMANTIC_UPSTREAM"} or not evidence): + raise AuditInputError(f"DROP requires upstream ownership evidence: {bucket}") + if status in {"EXACT_UPSTREAM", "SEMANTIC_UPSTREAM"} and (not evidence or not contracts): + raise AuditInputError(f"{status} requires evidence and behavioral contracts: {bucket}") + if status == "LOST_IN_FORK" and not evidence: + raise AuditInputError(f"LOST_IN_FORK requires historical/current evidence: {bucket}") + validated[bucket] = {**item, "evidence": evidence, "behavioral_contracts": contracts} + return validated + + +def _load_evidence(path: Path | None) -> dict[str, dict[str, Any]]: + if path is None: + return {} + try: + return _validate_evidence(json.loads(path.read_text(encoding="utf-8"))) + except (OSError, json.JSONDecodeError) as error: + raise AuditInputError(f"cannot read evidence file {path}: {error}") from error + + +def _load_intent_map(path: Path | None) -> dict[str, str]: + if path is None: + return {} + try: + raw = json.loads(path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError) as error: + raise AuditInputError(f"cannot read intent map {path}: {error}") from error + commits = raw.get("commits") if isinstance(raw, dict) else None + if not isinstance(commits, dict) or not all(isinstance(sha, str) and isinstance(bucket, str) and bucket for sha, bucket in commits.items()): + raise AuditInputError("intent map must be an object with a string-to-string 'commits' object") + return commits + + +def _derived_classification(records: list[CommitRecord], upstream_matches: dict[str, list[str]]) -> tuple[str, str, str]: + patches = [record.patch_id for record in records if record.patch_id] + exact_count = sum(patch_id in upstream_matches for patch_id in patches) + if patches and exact_count: + return "PATCH_EQUIVALENT_UPSTREAM_HISTORY", "NEEDS_REVIEW", "high" if exact_count == len(patches) else "medium" + return "NEEDS_REVIEW", "NEEDS_REVIEW", "low" + + +def build_inventory(repo: Path, fork_ref: str, upstream_ref: str, merge_base: str, evidence: dict[str, dict[str, Any]] | None = None, intent_map: dict[str, str] | None = None) -> dict[str, Any]: + for name, value in (("fork_ref", fork_ref), ("upstream_ref", upstream_ref), ("merge_base", merge_base)): + _require_sha(name, value) + _git(repo, "cat-file", "-e", f"{value}^{{commit}}") + actual_base = _git(repo, "merge-base", fork_ref, upstream_ref) + if actual_base != merge_base: + raise AuditInputError(f"merge_base mismatch: expected {merge_base}, got {actual_base}") + + explicit_map = intent_map or {} + records = _commit_records(repo, merge_base, fork_ref, upstream_ref, explicit_map) + record_shas = {record.sha for record in records} + unknown_map = sorted(set(explicit_map) - record_shas) + if unknown_map: + raise AuditInputError(f"intent map references commits outside the fork range: {', '.join(unknown_map)}") + touched_files = {file for record in records for file in record.changed_files} + upstream_matches = _upstream_patch_ids(repo, merge_base, upstream_ref, touched_files) + evidence = _validate_evidence(evidence or {}) + buckets: dict[str, list[CommitRecord]] = {} + for record in records: + buckets.setdefault(record.provisional_bucket, []).append(record) + unknown_evidence = sorted(set(evidence) - set(buckets)) + if unknown_evidence: + raise AuditInputError(f"evidence references unknown buckets: {', '.join(unknown_evidence)}") + + groups: list[dict[str, Any]] = [] + for bucket, grouped in buckets.items(): + changes = [record for record in grouped if not record.is_merge] + merge_events = [record for record in grouped if record.is_merge] + derived_status, derived_disposition, derived_confidence = _derived_classification(changes, upstream_matches) + override = evidence.get(bucket, {}) + status = override.get("upstream_status", derived_status) + disposition = override.get("disposition", derived_disposition) + confidence = override.get("confidence", derived_confidence) + if confidence not in {"high", "medium", "low"}: + raise AuditInputError(f"invalid confidence for {bucket}: {confidence}") + matching = [ + {"fork_commit": record.sha, "patch_id": record.patch_id, "upstream_commits": upstream_matches.get(record.patch_id, [])} + for record in changes + if record.patch_id in upstream_matches + ] + groups.append({ + "id": bucket, + "record_type": "provenance_bucket", + "subject": grouped[0].subject, + "commits": [{"sha": r.sha, "subject": r.subject, "parents": list(r.parents), "is_merge": r.is_merge, "patch_id": r.patch_id, "changed_files": list(r.changed_files), "graph_presence": {"upstream_reachable": r.upstream_reachable, "fork_exclusive": not r.upstream_reachable}, "issue_refs": list(r.issue_refs), "pr_refs": list(r.pr_refs)} for r in changes], + "merge_events": [{"sha": r.sha, "subject": r.subject, "parents": list(r.parents), "changed_files": list(r.changed_files), "pr_refs": list(r.pr_refs)} for r in merge_events], + "affected_files": sorted({file for record in grouped for file in record.changed_files}), + "work_item_provenance": {"issue_refs": sorted({ref for r in grouped for ref in r.issue_refs}), "pr_refs": sorted({ref for r in grouped for ref in r.pr_refs})}, + "patch_matches": matching, + "exact_upstream_commits": sorted({sha for match in matching for sha in match["upstream_commits"]}), + "upstream_status": status, + "disposition": disposition, + "confidence": confidence, + "evidence": list(override.get("evidence", [])), + "behavioral_contracts": list(override.get("behavioral_contracts", [])), + }) + groups.sort(key=lambda item: item["commits"][0]["sha"] if item["commits"] else item["merge_events"][0]["sha"]) + mapped = sum(1 for record in records if record.sha in explicit_map) + unaccounted = [] if mapped == len(records) else sorted(record.sha for record in records if record.sha not in explicit_map) + return { + "schema_version": 3, + "inputs": {"fork_ref": fork_ref, "upstream_ref": upstream_ref, "merge_base": merge_base}, + "provenance_buckets": groups, + "accounting": { + "discovery_coverage": {"historical_commits": len(records), "emitted_commit_records": len(records), "complete": True}, + "capability_accounting": {"explicitly_accounted_commits": mapped, "unaccounted_commits": unaccounted, "complete": bool(explicit_map) and not unaccounted}, + }, + } + + +def _md(value: str) -> str: + return value.replace("|", "\\|").replace("`", "\\`").replace("\n", " ") + + +def render_markdown(inventory: dict[str, Any]) -> str: + inputs = inventory["inputs"] + lines = ["# Fork archaeology inventory", "", f"- Fork ref: `{inputs['fork_ref']}`", f"- Upstream ref: `{inputs['upstream_ref']}`", f"- Merge base: `{inputs['merge_base']}`", "", "| Provenance bucket | Change records | Merge events | Status | Disposition | Confidence |", "| --- | ---: | ---: | --- | --- | --- |"] + for group in inventory["provenance_buckets"]: + lines.append(f"| `{_md(group['id'])}` | {len(group['commits'])} | {len(group['merge_events'])} | `{group['upstream_status']}` | `{group['disposition']}` | `{group['confidence']}` |") + lines += ["", "## Evidence", ""] + for group in inventory["provenance_buckets"]: + changes = ", ".join(f"`{item['sha'][:12]}`" for item in group["commits"]) or "(none)" + merges = ", ".join(f"`{item['sha'][:12]}`" for item in group["merge_events"]) or "(none)" + files = ", ".join(f"`{_md(item)}`" for item in group["affected_files"]) or "(none)" + matches = ", ".join(f"`{item[:12]}`" for item in group["exact_upstream_commits"]) or "none" + evidence = "; ".join(_md(item) for item in group["evidence"]) or "none; review required" + lines += [f"### `{_md(group['id'])}` - {_md(group['subject'])}", "", f"- Changes: {changes}", f"- Merge events: {merges}", f"- Files: {files}", f"- Upstream matches: {matches}", f"- Evidence: {evidence}"] + if group["behavioral_contracts"]: + lines.append(f"- Behavioral contracts: {'; '.join(_md(item) for item in group['behavioral_contracts'])}") + lines.append("") + discovery = inventory["accounting"]["discovery_coverage"] + capability = inventory["accounting"]["capability_accounting"] + lines.append(f"Discovery completeness: **{'PASS' if discovery['complete'] else 'FAIL'}** — {discovery['emitted_commit_records']} of {discovery['historical_commits']} records emitted.") + lines.append(f"Capability accounting: **{'PASS' if capability['complete'] else 'FAIL'}** - explicit disposition mapping is required before this gate can pass.") + return "\n".join(lines) + "\n" + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--repo", type=Path, required=True) + parser.add_argument("--fork-ref", required=True) + parser.add_argument("--upstream-ref", required=True) + parser.add_argument("--merge-base", required=True) + parser.add_argument("--evidence-file", type=Path) + parser.add_argument("--intent-map", type=Path) + parser.add_argument("--output-dir", type=Path, required=True) + args = parser.parse_args() + try: + inventory = build_inventory(args.repo, args.fork_ref, args.upstream_ref, args.merge_base, _load_evidence(args.evidence_file), _load_intent_map(args.intent_map)) + except AuditInputError as error: + parser.error(str(error)) + args.output_dir.mkdir(parents=True, exist_ok=True) + (args.output_dir / "inventory.json").write_text(json.dumps(inventory, indent=2) + "\n", encoding="utf-8") + (args.output_dir / "inventory.md").write_text(render_markdown(inventory), encoding="utf-8") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/scripts/test_capability_manifest.py b/tests/scripts/test_capability_manifest.py new file mode 100644 index 000000000000..b966d97058d2 --- /dev/null +++ b/tests/scripts/test_capability_manifest.py @@ -0,0 +1,130 @@ +import json +from pathlib import Path + + +ARTIFACTS = Path(__file__).parents[2] / "artifacts" / "fork-archaeology-issue-100" + + +def load(name: str): + return json.loads((ARTIFACTS / name).read_text(encoding="utf-8")) + + +def test_phase_one_manifest_accounts_for_every_frozen_record(): + manifest = load("capability-manifest.json") + inventory = load("inventory.json") + intent_map = load("intent-map.json") + + assert manifest["inputs"] == { + "fork_ref": "35c8564c9c0af3d75bcbdf1d793e7207e5528f06", + "upstream_ref": "460d345642ee3d143a3e461abe39fd42b86a7e54", + "merge_base": "91937a6dc3ffbbe2f3be91a500f0ecf962c4cf53", + } + assert inventory["accounting"]["discovery_coverage"]["complete"] is True + assert inventory["accounting"]["capability_accounting"]["complete"] is True + assert inventory["accounting"]["capability_accounting"]["unaccounted_commits"] == [] + + records = [ + item["sha"] + for group in inventory["provenance_buckets"] + for item in group["commits"] + group["merge_events"] + ] + assert len(records) == 171 + assert len(set(records)) == 171 + assert set(records) == set(intent_map["commits"]) + assert manifest["accounting"] == { + "historical_change_records": 145, + "merge_events": 26, + "total_records": 171, + "mapped_records": 171, + "complete": True, + } + + +def test_manifest_groups_have_review_fields_and_explicit_non_capability_class(): + manifest = load("capability-manifest.json") + evidence = load("evidence.json")["intents"] + required = { + "capability", "intent_name", "historical_commits", "historical_issues", "historical_prs", + "merge_provenance", "behavioral_contracts", "current_dev_survival", + "upstream_prior_art_current_implementation", "status", "disposition", "confidence", + "unresolved_questions", "source_inventory_records", + } + statuses = {"EXACT_UPSTREAM", "SEMANTIC_UPSTREAM", "PARTIAL_UPSTREAM", "FORK_ONLY", "LOST_IN_FORK", "NEEDS_REVIEW"} + dispositions = {"DROP", "KEEP", "PORT", "SPLIT", "NEEDS_REVIEW"} + + group_ids = {group["id"] for group in manifest["groups"]} + # The archaeology runner owns one-to-one provenance buckets. The reviewed + # manifest may additionally contain hunk-level behavioral overlay groups. + assert set(evidence) <= group_ids + for group in manifest["groups"]: + assert required <= group.keys() + assert group["status"] in statuses + assert group["disposition"] in dispositions + assert group["behavioral_contracts"] + assert group["unresolved_questions"] + assert group["change_record_count"] + group["merge_event_count"] == len(group["historical_commits"]) + len(group["merge_provenance"]) + if group["id"].startswith("non-capability:"): + assert group["record_class"] == "non_capability" + else: + assert group["record_class"] == "capability" + if group["status"] in {"EXACT_UPSTREAM", "SEMANTIC_UPSTREAM"}: + assert evidence[group["id"]]["evidence"] + assert evidence[group["id"]]["behavioral_contracts"] + + +def test_memory_trim_policy_and_diagnostics_are_separate_capabilities(): + manifest = load("capability-manifest.json") + intent_map = load("intent-map.json")["commits"] + groups = {group["id"]: group for group in manifest["groups"]} + + policy = groups["capability:memory-trim-policy"] + diagnostics = groups["capability:memory-trim-diagnostics"] + assert intent_map["04f1af72be078cef69de538f1519f93a73088b0d"] == "capability:memory-trim-diagnostics" + assert intent_map["a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb"] == "capability:memory-trim-policy" + assert policy["status"] == "PARTIAL_UPSTREAM" + assert policy["disposition"] == "PORT" + assert policy["confidence"] == "high" + assert policy["historical_commits"][0]["sha"] == "a9d2b9af4f800fef23fa7ecaf2ea270b43e326eb" + assert policy["supporting_historical_commits"][0]["sha"] == "04f1af72be078cef69de538f1519f93a73088b0d" + assert diagnostics["status"] == "PARTIAL_UPSTREAM" + assert diagnostics["disposition"] == "KEEP" + assert diagnostics["historical_commits"][0]["sha"] == "04f1af72be078cef69de538f1519f93a73088b0d" + + +def test_behavioral_audit_covers_all_changes_and_merge_events(): + audit = load("behavioral-coverage-audit.json") + assert audit["coverage_gate"] == { + "change_records": 145, + "merge_events": 26, + "unique_change_records_reviewed": 145, + "behavior_rows": 141, + "promoted_behavior_rows": 5, + "explicit_nonsemantic_rows": 8, + "uncovered_behavior_rows": 0, + "complete": True, + } + assert len(audit["change_records"]) == 149 + assert len({row["record_sha"] for row in audit["change_records"]}) == 145 + assert len(audit["merge_events"]) == 26 + promoted = { + row["proposed_capability"] + for row in audit["change_records"] + if row["action"] == "PROMOTE_TO_SEPARATE_CAPABILITY" + } + assert promoted == { + "capability:compression-session-boundary", + "capability:memory-trim-policy", + "capability:sqlite-write-contention-policy", + "capability:session-search-context-hydration", + } + + +def test_behavioral_overlays_keep_provenance_bucket_accounting_separate(): + manifest = load("capability-manifest.json") + groups = {group["id"]: group for group in manifest["groups"]} + assert groups["capability:compression-session-boundary"]["supporting_historical_commits"][0]["sha"] == "176646d2cd6c95fa49b9414f21ed9e781b0aaa84" + assert groups["capability:sqlite-write-contention-policy"]["supporting_historical_commits"][0]["sha"] == "cc2531fbc6df8fdb34fca0b096b798eb53f970dd" + assert groups["capability:session-search-context-hydration"]["supporting_historical_commits"][0]["sha"] == "b879cbd332b8ac66ada6aaebfc5a9e61ae6cbe70" + assert groups["capability:lifecycle-sqlite-telemetry"]["behavioral_overlays"] == ["capability:compression-session-boundary"] + assert groups["non-capability:incidental-hardening"]["behavioral_overlays"] == ["capability:sqlite-write-contention-policy"] + assert groups["non-capability:performance-validation"]["behavioral_overlays"] == ["capability:session-search-context-hydration"] diff --git a/tests/scripts/test_fork_archaeology.py b/tests/scripts/test_fork_archaeology.py new file mode 100644 index 000000000000..555eedcba810 --- /dev/null +++ b/tests/scripts/test_fork_archaeology.py @@ -0,0 +1,162 @@ +import json +import subprocess +import sys +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path + +import pytest + +SCRIPT = Path(__file__).parents[2] / "scripts" / "fork_archaeology.py" + + +def load_module(): + spec = spec_from_file_location("fork_archaeology_test_module", SCRIPT) + module = module_from_spec(spec) + sys.modules[spec.name] = module + spec.loader.exec_module(module) + return module + + +def git(repo: Path, *args: str) -> str: + return subprocess.check_output(["git", "-C", str(repo), *args], text=True).strip() + + +def commit(repo: Path, message: str, filename: str, content: str) -> str: + (repo / filename).write_text(content, encoding="utf-8") + subprocess.run(["git", "-C", str(repo), "add", filename], check=True) + subprocess.run(["git", "-C", str(repo), "commit", "-m", message], check=True, capture_output=True) + return git(repo, "rev-parse", "HEAD") + + +def repo_with_branches(tmp_path: Path, fork_message: str = "fork feature"): + repo = tmp_path / "repo" + repo.mkdir() + subprocess.run(["git", "-C", str(repo), "init", "-q"], check=True) + subprocess.run(["git", "-C", str(repo), "config", "user.email", "test@example.com"], check=True) + subprocess.run(["git", "-C", str(repo), "config", "user.name", "Test"], check=True) + base = commit(repo, "base", "base.txt", "base\n") + fork_ref = commit(repo, fork_message, "feature.txt", "fork\n") + subprocess.run(["git", "-C", str(repo), "checkout", "-q", "-b", "upstream", base], check=True) + upstream_ref = commit(repo, "same feature upstream", "feature.txt", "fork\n") + return repo, base, fork_ref, upstream_ref + + +def test_patch_history_is_candidate_only_and_reports_upstream_sha(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path) + inventory = load_module().build_inventory(repo, fork_ref, upstream_ref, base) + group = inventory["provenance_buckets"][0] + + assert group["upstream_status"] == "PATCH_EQUIVALENT_UPSTREAM_HISTORY" + assert group["disposition"] == "NEEDS_REVIEW" + assert group["exact_upstream_commits"] == [upstream_ref] + assert group["patch_matches"][0]["fork_commit"] == fork_ref + assert inventory["accounting"]["discovery_coverage"]["complete"] is True + assert inventory["accounting"]["capability_accounting"]["explicitly_accounted_commits"] == 0 + assert inventory["accounting"]["capability_accounting"]["complete"] is False + + +def test_upstream_revert_does_not_authorize_drop(tmp_path: Path): + repo = tmp_path / "repo" + repo.mkdir() + subprocess.run(["git", "-C", str(repo), "init", "-q"], check=True) + subprocess.run(["git", "-C", str(repo), "config", "user.email", "test@example.com"], check=True) + subprocess.run(["git", "-C", str(repo), "config", "user.name", "Test"], check=True) + base = commit(repo, "base", "base.txt", "base\n") + fork_ref = commit(repo, "add behavior", "feature.txt", "feature\n") + subprocess.run(["git", "-C", str(repo), "checkout", "-q", "-b", "upstream", base], check=True) + commit(repo, "add behavior upstream", "feature.txt", "feature\n") + subprocess.run(["git", "-C", str(repo), "revert", "--no-edit", "HEAD"], check=True, capture_output=True) + upstream_ref = git(repo, "rev-parse", "HEAD") + group = load_module().build_inventory(repo, fork_ref, upstream_ref, base)["provenance_buckets"][0] + + assert group["upstream_status"] == "PATCH_EQUIVALENT_UPSTREAM_HISTORY" + assert group["disposition"] == "NEEDS_REVIEW" + + +def test_merge_commit_is_an_event_not_a_change_record(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path, "unrelated fork") + subprocess.run(["git", "-C", str(repo), "checkout", "-q", "-b", "topic", base], check=True) + feature = commit(repo, "feature work", "topic.txt", "topic\n") + subprocess.run(["git", "-C", str(repo), "checkout", "-q", "-B", "fork", fork_ref], check=True) + subprocess.run(["git", "-C", str(repo), "merge", "--no-ff", "--no-edit", "topic"], check=True, capture_output=True) + merged_ref = git(repo, "rev-parse", "HEAD") + inventory = load_module().build_inventory(repo, merged_ref, upstream_ref, base) + + assert sum(len(group["merge_events"]) for group in inventory["provenance_buckets"]) == 1 + assert all(not record["is_merge"] for group in inventory["provenance_buckets"] for record in group["commits"]) + assert feature in [record["sha"] for group in inventory["provenance_buckets"] for record in group["commits"]] + + +def test_refs_must_be_full_shas(tmp_path: Path): + module = load_module() + with pytest.raises(module.AuditInputError, match="full 40-character"): + module.build_inventory(tmp_path, "main", "0" * 40, "0" * 40) + + +def test_issue_and_pr_refs_use_final_squash_marker(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path, "Session metadata FTS (#25) (#59)") + group = load_module().build_inventory(repo, fork_ref, upstream_ref, base)["provenance_buckets"][0] + record = group["commits"][0] + + assert record["issue_refs"] == ["25"] + assert record["pr_refs"] == ["59"] + assert group["work_item_provenance"] == {"issue_refs": ["25"], "pr_refs": ["59"]} + + +def test_explicit_map_is_the_only_capability_accounting_pass(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path) + module = load_module() + no_map = module.build_inventory(repo, fork_ref, upstream_ref, base) + with_map = module.build_inventory(repo, fork_ref, upstream_ref, base, intent_map={fork_ref: "capability:explicit"}) + + assert no_map["accounting"]["capability_accounting"]["complete"] is False + assert with_map["accounting"]["capability_accounting"] == {"explicitly_accounted_commits": 1, "unaccounted_commits": [], "complete": True} + assert with_map["provenance_buckets"][0]["id"] == "capability:explicit" + + +def test_incomplete_explicit_map_fails_accounting_gate(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path) + subprocess.run(["git", "-C", str(repo), "checkout", "-q", "-b", "fork-work", fork_ref], check=True) + extra = commit(repo, "second", "second.txt", "second\n") + subprocess.run(["git", "-C", str(repo), "checkout", "-q", "upstream"], check=True) + module = load_module() + inventory = module.build_inventory(repo, extra, upstream_ref, base, intent_map={fork_ref: "capability:explicit"}) + + accounting = inventory["accounting"]["capability_accounting"] + assert accounting["complete"] is False + assert extra in accounting["unaccounted_commits"] + + +def test_evidence_policy_rejects_unsupported_drop(): + module = load_module() + with pytest.raises(module.AuditInputError, match="DROP requires"): + module._validate_evidence({"intents": {"capability:x": {"upstream_status": "FORK_ONLY", "disposition": "DROP"}}}) + + +def test_semantic_status_requires_behavioral_evidence(): + module = load_module() + with pytest.raises(module.AuditInputError, match="requires evidence"): + module._validate_evidence({"intents": {"capability:x": {"upstream_status": "SEMANTIC_UPSTREAM", "disposition": "KEEP", "evidence": ["tree match"]}}}) + + +def test_evidence_override_is_validated_and_rendered(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path, "retained behavior") + module = load_module() + evidence = {"intents": {"commit:" + fork_ref: {"upstream_status": "FORK_ONLY", "disposition": "KEEP", "confidence": "high", "evidence": ["current upstream lacks the behavior"], "behavioral_contracts": ["retained behavior remains user-visible"]}}} + inventory = module.build_inventory(repo, fork_ref, upstream_ref, base, evidence["intents"]) + + assert inventory["provenance_buckets"][0]["upstream_status"] == "FORK_ONLY" + assert "retained behavior remains user-visible" in module.render_markdown(inventory) + + +def test_markdown_escapes_subject_and_file_delimiters(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path, "title | with `marker`") + markdown = load_module().render_markdown(load_module().build_inventory(repo, fork_ref, upstream_ref, base)) + assert "title \\| with \\`marker\\`" in markdown + + +def test_explicit_intent_map_unknown_commit_is_rejected(tmp_path: Path): + repo, base, fork_ref, upstream_ref = repo_with_branches(tmp_path) + module = load_module() + with pytest.raises(module.AuditInputError, match="outside the fork range"): + module.build_inventory(repo, fork_ref, upstream_ref, base, intent_map={"0" * 40: "capability:missing"})