Skip to content

feat(kb): read and list summaries carry each Experience's identity - #1910

Merged
chaojhou merged 1 commit into
mainfrom
fix/siliangchen/kb-summary-identity
Oct 17, 2026
Merged

chaojhou merged 1 commit into
mainfrom
fix/siliangchen/kb-summary-identity

Conversation

@siliangchen-amd

@siliangchen-amd siliangchen-amd commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor
  • Description: The summaries POST /v1/read returns in experiences and GET /v1/list returns in items name a record's id, run, change summary, decision and measurements, but not the conditions it was measured under. A reader that sorts what a read returns by whether it was measured under its own conditions cannot do that from the response; it would have to page through GET /v1/export to find each record. The multi-branch recall (hyperloom_multibranch/notebook/knowledge/recall.py on multibranch-dev) is such a reader: an Experience measured on the same model, GPU, framework, TP, concurrency, bottleneck and sequence lengths is a prior, anything else a lead to re-verify. _summary in src/hyperloom_kb/http_service.py now adds identity, the record's identity map as it holds it. docs/reference/experience-kb.md documents the field, and the summary field list in src/hyperloom/inference_optimizer/SKILL.md names it.
  • Linked issue(s): none
  • Tests: updated src/hyperloom_kb/tests/test_http_service.py::test_write_is_immediately_readable_immutable_and_rendered_losslessly to assert identity on a read summary and a list item, through the running service and RemoteClient; it fails on main with KeyError: 'identity'. Ran pytest src/hyperloom_kb with and without the commit (the same results), ruff format --check and ruff check on the changed files.
  • Size/complexity triggers crossed: one, inherited, and the PR carries the baseline-raise label for it. src/hyperloom_kb/http_service.py is 1539 physical lines on main (module length fails > 1200); Experience KB: operable state, user-declared fields and files, SQLite for a workspace and PostgreSQL for replicated global KBs, observability, and notes #1744 merged it at that size under baseline-raise, so the row is not in scripts/code_metrics_baseline.txt and any change to the file reports it as new (1540 here). This PR adds one line, a key in _summary's dict, and no function or branch; splitting the module is its owner's call, not this change's. 4 files, +9/-4.
  • If this simplifies or refactors: n/a
  • Observable effect: each item in POST /v1/read experiences and GET /v1/list items (and so in hyperloom-kb list output and in the old flow's experience_kb_injections records, which copy the read summaries) carries an identity object. Before, a reader had no way to see an Experience's conditions without fetching the whole export; the multi-branch recall therefore treated every recalled Experience as one to re-verify. prompt_block, rendered_refs and every other field are unchanged.
  • Breaking changes: no; the key is additive, and no reader validates summary keys against a closed set (experience_kb.py, read_optimizer_state.py, conversation.py, dispatch.py and cli.py copy or print named keys).
  • PR addresses single concern: yes
  • Root cause is upstream: no

A reader that sorts what a read returns by whether it was measured under its own conditions (the multi-branch recall: same model, GPU, framework, TP, concurrency and sequence lengths make a prior, anything else a lead to re-verify) had no way to see those conditions: the summaries in POST /v1/read and GET /v1/list name the record, its change summary, decision and measurements, but not its identity, so the reader would have to page through GET /v1/export to find each record. _summary now adds identity, the record's identity map as it holds it. Additive: existing readers ignore the extra key.

Co-authored-by: Cursor <cursoragent@cursor.com>
@siliangchen-amd
siliangchen-amd requested a review from a team as a code owner October 15, 2026 07:59
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Code metrics gate: PASSED with waived findings (baseline-raise)

Judged: the 4 files this change touches. Files it does not touch never fail it; anything found there is listed under Outside this change for information.

Dimension Limit New Worse Baseline out of date Baseline entries vs base
Cyclomatic complexity fails > 20 0 0 0 72 +0
Cognitive complexity fails > 30 0 0 0 284 +0
Function length (lines) fails > 80 0 0 0 450 +0
Nested block depth fails > 5 0 0 0 27 +0
Module length (lines) warns > 800, fails > 1200 1 0 0 53 +0
Duplicated lines per file fails > 0 0 0 0 118 +0
Dead code (vulture) fails > 0 0 0 0 2 +0
Check Findings Effect
Comments 0
English only 0
Production code imports test code 0
Repeated literals 0
A1 Private name of another package 0
A8 Flag argument 0
A9 Tuple return 0
A10 Raw vocabulary comparison 0
A11 Hidden global write 0
A12 Pure forwarder 0
A12 Single-implementation abstraction 0

New violations (not in the baseline) (waived by the baseline-raise label): 1

Unit Dimension Value Limit
src/hyperloom_kb/http_service.py:1 Module length (lines) 1540 fails > 1200

How to fix

  • New or worse: split the unit (extract a function, a class, a module) until it is back under the limit, or no worse than its recorded value. The baseline cannot absorb a new violation: CI refuses any baseline entry added or raised relative to the base branch.
  • Baseline out of date: something improved. Run python scripts/code_metrics.py --update-baseline and commit scripts/code_metrics_baseline.txt; the command only lowers or removes entries.
  • Override: the baseline-raise PR label waives new, worse and baseline-growth findings and the failing design checks (they stay listed here). Use it only with the reason in the PR description; it waives nothing else.
  • Tools for a local run: pip install ruff==0.16.2 complexipy==8.0.1 vulture==2.16 and npm install -g jscpd@5.4.1 (or point CODE_METRICS_JSCPD at another jscpd command, such as npx --yes jscpd@<version>).

Already over at the base (backlog, not this change's): 1

Unit Dimension Base Now
src/hyperloom_kb/http_service.py:1194 RequestHandler._dispatch Function length (lines) 91 91
93 findings in files this change does not touch

Outside this change (informational): 93

Unit Dimension Baseline Now
src/hyperloom/orchestrator/enablement/recipe/projections.py project_launch_evidence Cognitive complexity absent 36
src/hyperloom/orchestrator/state/shared_state.py resolve_graded_comparison Cognitive complexity absent 34
src/hyperloom_kb/collect/mapping.py _experience Cognitive complexity absent 31
src/hyperloom_kb/schema.py FieldDeclaration.__post_init__ Cognitive complexity absent 32
src/kernelforge/cli/forge_loop_command.py _prepare_measurement_driver Cognitive complexity absent 36
src/kernelforge/cli/forge_loop_command.py _read_kb_warm_start Cognitive complexity absent 40
src/kernelforge/loop/runner.py IterationLoop._collect_session_candidate Cognitive complexity absent 44
src/kernelforge/loop/runner.py IterationLoop._rule_on_attempt Cognitive complexity absent 38
src/hyperloom_kb/tests/test_cli.py Duplicated lines per file absent 18
src/hyperloom_kb/tests/test_global_identity_and_pull.py Duplicated lines per file absent 13
src/hyperloom_kb/tests/test_local_state.py Duplicated lines per file absent 18
src/hyperloom/inference_optimizer/cli/__init__.py _reexport_session_environment Function length (lines) absent 112
src/hyperloom/inference_optimizer/cli/__init__.py _resolve_agent_lineup Function length (lines) absent 89
src/hyperloom/inference_optimizer/cli/__init__.py _resolve_run_topology Function length (lines) absent 92
src/hyperloom/inference_optimizer/cli/__init__.py _resume_session Function length (lines) absent 171
src/hyperloom/inference_optimizer/cli/__init__.py _seed_fresh_session Function length (lines) absent 183
src/hyperloom/inference_optimizer/multi_node/cli.py _restart_multinode Function length (lines) absent 107
src/hyperloom/inference_optimizer/multi_node/scripts/launch_multinode.py _build_parser Function length (lines) absent 84
src/hyperloom/inference_optimizer/multi_node/scripts/launch_multinode.py _spawn_rank_actors Function length (lines) absent 90
src/hyperloom_kb/sync.py GlobalSync.pull Function length (lines) absent 86
src/kernelforge/cli/forge_loop_command.py _RunReporter.build_result Function length (lines) absent 91
src/kernelforge/cli/forge_loop_command.py _prepare_measurement_driver Function length (lines) absent 140
src/kernelforge/cli/forge_loop_command.py _read_kb_warm_start Function length (lines) absent 154
src/kernelforge/loop/knowledge_integration.py _measure_warmstart_field Function length (lines) absent 83
src/kernelforge/loop/runner.py IterationLoop._close_iteration Function length (lines) absent 135

...and 68 more; the job log lists every row.

Verdict computed by the gate scripts in /home/runner/work/_temp/code-metrics-gate, not by this tree's copy.

Thresholds and sources: [tool.hyperloom.code_metrics] in pyproject.toml. Tools: complexipy 8.0.1, jscpd 5.4.1, ruff 0.16.2, vulture 2.16.

@siliangchen-amd siliangchen-amd added the baseline-raise Waives new, worse and baseline-growth code-metrics findings; reason required in the PR description label Oct 15, 2026
@chaojhou

Copy link
Copy Markdown
Collaborator

PR #1910 -- feat(kb): read and list summaries carry each Experience's identity

What it does: read and list summaries from the Experience KB service did not include the conditions a record was measured under, so a client had to page GET /v1/export to tell which recalled Experiences match its own setup. _summary in src/hyperloom_kb/http_service.py now adds identity, the record's identity map, which reaches POST /v1/read experiences, GET /v1/list items, hyperloom-kb list and experience_kb_injections; the reference doc and SKILL field list name it.

Blocking issues: none

SKIPPED: V4 -- six open PRs (#1922, #1869, #1675, #1276, #1154, #1032) change more than 100 files and only their first 100 were compared; overlap there is unchecked.
SKIPPED: local test run -- not permitted on this host; relied on the test shards that passed at head.

Checked: src/hyperloom_kb/http_service.py _summary and its two callers (read, list_experiences); src/hyperloom_kb/schema.py identity scalar enforcement (_field_values(..., scalars_only=...), declaration check); tree-wide sweep for every non-test reader of read/list summaries (remote.py, experience_kb.py, conversation.py, dispatch.py, shared_state.py, read_optimizer_state.py, cli.py); doc copies of the summary field list | Ran: git grep/git show at head and base, line counts of http_service.py at base and head | Base: 0f333df | Head: a9b274a

LGTM

@chaojhou
chaojhou merged commit 9845e91 into main Oct 17, 2026
46 of 49 checks passed
@chaojhou
chaojhou deleted the fix/siliangchen/kb-summary-identity branch October 17, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

baseline-raise Waives new, worse and baseline-growth code-metrics findings; reason required in the PR description

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants