Repository navigation
feat(kb): read and list summaries carry each Experience's identity - #1910
Conversation
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>
Code metrics gate: PASSED with waived findings (
|
| 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-baselineand commitscripts/code_metrics_baseline.txt; the command only lowers or removes entries. - Override: the
baseline-raisePR 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.16andnpm install -g jscpd@5.4.1(or pointCODE_METRICS_JSCPDat another jscpd command, such asnpx --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.
PR #1910 -- feat(kb): read and list summaries carry each Experience's identityWhat 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 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. Checked: src/hyperloom_kb/http_service.py LGTM |
POST /v1/readreturns inexperiencesandGET /v1/listreturns initemsname 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 throughGET /v1/exportto find each record. The multi-branch recall (hyperloom_multibranch/notebook/knowledge/recall.pyon 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._summaryinsrc/hyperloom_kb/http_service.pynow addsidentity, the record's identity map as it holds it.docs/reference/experience-kb.mddocuments the field, and the summary field list insrc/hyperloom/inference_optimizer/SKILL.mdnames it.src/hyperloom_kb/tests/test_http_service.py::test_write_is_immediately_readable_immutable_and_rendered_losslesslyto assertidentityon a read summary and a list item, through the running service andRemoteClient; it fails on main withKeyError: 'identity'. Ranpytest src/hyperloom_kbwith and without the commit (the same results),ruff format --checkandruff checkon the changed files.baseline-raiselabel for it.src/hyperloom_kb/http_service.pyis 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 underbaseline-raise, so the row is not inscripts/code_metrics_baseline.txtand 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.POST /v1/readexperiencesandGET /v1/listitems(and so inhyperloom-kb listoutput and in the old flow'sexperience_kb_injectionsrecords, which copy the read summaries) carries anidentityobject. 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_refsand every other field are unchanged.experience_kb.py,read_optimizer_state.py,conversation.py,dispatch.pyandcli.pycopy or print named keys).