errlore 0.2.2__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. errlore-0.3.1/.github/ISSUE_TEMPLATE/bug_report.yml +45 -0
  2. errlore-0.3.1/.github/ISSUE_TEMPLATE/feature_request.yml +26 -0
  3. errlore-0.3.1/.github/dependabot.yml +18 -0
  4. errlore-0.3.1/.github/pull_request_template.md +11 -0
  5. {errlore-0.2.2 → errlore-0.3.1}/.github/workflows/release.yml +8 -7
  6. {errlore-0.2.2 → errlore-0.3.1}/CHANGELOG.md +74 -0
  7. errlore-0.3.1/CONTRIBUTING.md +49 -0
  8. errlore-0.3.1/ERRLORE_BRIEF_FOR_ANALYSIS.md +196 -0
  9. errlore-0.3.1/ERRLORE_FINAL_CLOSURE.md +68 -0
  10. errlore-0.3.1/ERRLORE_OPEN_QUESTIONS.md +203 -0
  11. errlore-0.3.1/ERRLORE_Q2_CLOSURE.md +73 -0
  12. errlore-0.3.1/ERRLORE_REPLY_TO_P1_PROPOSAL.md +108 -0
  13. errlore-0.3.1/FULL_DOSSIER_FOR_STRATEGIC_ANALYSIS.md +149 -0
  14. {errlore-0.2.2 → errlore-0.3.1}/PKG-INFO +29 -9
  15. {errlore-0.2.2 → errlore-0.3.1}/README.md +28 -8
  16. errlore-0.3.1/benchmarks/results/CONSISTENCY_SIGNAL_2026-07-11.md +67 -0
  17. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/REPRODUCIBILITY_2026-07-11.md +22 -0
  18. errlore-0.3.1/docs/OBSERVABILITY_DECAY.md +120 -0
  19. errlore-0.3.1/docs/SHADOW_MODE_SPEC.md +111 -0
  20. {errlore-0.2.2 → errlore-0.3.1}/pyproject.toml +1 -1
  21. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/__init__.py +3 -0
  22. errlore-0.3.1/src/errlore/consistency.py +169 -0
  23. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/facade.py +194 -8
  24. errlore-0.3.1/src/errlore/lessons/graduation.py +223 -0
  25. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/lessons/models.py +19 -0
  26. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/lessons/store.py +134 -6
  27. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/sanitize.py +6 -0
  28. errlore-0.3.1/src/errlore/shadow.py +162 -0
  29. errlore-0.3.1/tests/test_consistency.py +110 -0
  30. errlore-0.3.1/tests/test_graduation.py +136 -0
  31. errlore-0.3.1/tests/test_hardening.py +88 -0
  32. errlore-0.3.1/tests/test_harm_gate.py +94 -0
  33. {errlore-0.2.2 → errlore-0.3.1}/tests/test_lessons.py +1 -0
  34. errlore-0.3.1/tests/test_shadow.py +126 -0
  35. {errlore-0.2.2 → errlore-0.3.1}/.github/workflows/ci.yml +0 -0
  36. {errlore-0.2.2 → errlore-0.3.1}/.gitignore +0 -0
  37. {errlore-0.2.2 → errlore-0.3.1}/LICENSE +0 -0
  38. {errlore-0.2.2 → errlore-0.3.1}/SECURITY.md +0 -0
  39. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/bench_error_reduction.py +0 -0
  40. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/bench_retrieval.py +0 -0
  41. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/error_reduction/report.md +0 -0
  42. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/gemma_2026-07-11_report.txt +0 -0
  43. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/haiku_2026-07-11_report.txt +0 -0
  44. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/haiku_2026-07-11_seed11.txt +0 -0
  45. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/haiku_2026-07-11_seed22.txt +0 -0
  46. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/haiku_2026-07-11_seed33.txt +0 -0
  47. {errlore-0.2.2 → errlore-0.3.1}/benchmarks/results/haiku_newfamilies_2026-07-11_report.txt +0 -0
  48. {errlore-0.2.2 → errlore-0.3.1}/examples/anthropic_agent.py +0 -0
  49. {errlore-0.2.2 → errlore-0.3.1}/examples/claude-code/README.md +0 -0
  50. {errlore-0.2.2 → errlore-0.3.1}/examples/claude-code/errlore_posttooluse.py +0 -0
  51. {errlore-0.2.2 → errlore-0.3.1}/examples/claude-code/errlore_posttoolusefailure.py +0 -0
  52. {errlore-0.2.2 → errlore-0.3.1}/examples/claude-code/errlore_sessionstart.py +0 -0
  53. {errlore-0.2.2 → errlore-0.3.1}/examples/claude-code/settings.json.example +0 -0
  54. {errlore-0.2.2 → errlore-0.3.1}/examples/langchain_agent.py +0 -0
  55. {errlore-0.2.2 → errlore-0.3.1}/examples/openai_agent.py +0 -0
  56. {errlore-0.2.2 → errlore-0.3.1}/integrations/openwebui/README.md +0 -0
  57. {errlore-0.2.2 → errlore-0.3.1}/integrations/openwebui/errlore_feedback_action.py +0 -0
  58. {errlore-0.2.2 → errlore-0.3.1}/integrations/openwebui/errlore_memory_filter.py +0 -0
  59. {errlore-0.2.2 → errlore-0.3.1}/site/demo.gif +0 -0
  60. {errlore-0.2.2 → errlore-0.3.1}/site/demo_script.py +0 -0
  61. {errlore-0.2.2 → errlore-0.3.1}/site/index.html +0 -0
  62. {errlore-0.2.2 → errlore-0.3.1}/site/llms.txt +0 -0
  63. {errlore-0.2.2 → errlore-0.3.1}/site/og.png +0 -0
  64. {errlore-0.2.2 → errlore-0.3.1}/site/robots.txt +0 -0
  65. {errlore-0.2.2 → errlore-0.3.1}/site/sitemap.xml +0 -0
  66. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/cli.py +0 -0
  67. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/errmem/__init__.py +0 -0
  68. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/errmem/classifier.py +0 -0
  69. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/errmem/injector.py +0 -0
  70. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/errmem/patterns.py +0 -0
  71. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/errmem/tracker.py +0 -0
  72. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/integrations/__init__.py +0 -0
  73. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/integrations/claude_code.py +0 -0
  74. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/io/__init__.py +0 -0
  75. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/io/jsonl_index.py +0 -0
  76. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/io/jsonl_writer.py +0 -0
  77. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/io/repair.py +0 -0
  78. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/lessons/__init__.py +0 -0
  79. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/py.typed +0 -0
  80. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/retrieval/__init__.py +0 -0
  81. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/retrieval/backend.py +0 -0
  82. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/retrieval/index.py +0 -0
  83. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/trust/__init__.py +0 -0
  84. {errlore-0.2.2 → errlore-0.3.1}/src/errlore/trust/engine.py +0 -0
  85. {errlore-0.2.2 → errlore-0.3.1}/tests/conftest.py +0 -0
  86. {errlore-0.2.2 → errlore-0.3.1}/tests/test_cli.py +0 -0
  87. {errlore-0.2.2 → errlore-0.3.1}/tests/test_errmem.py +0 -0
  88. {errlore-0.2.2 → errlore-0.3.1}/tests/test_facade.py +0 -0
  89. {errlore-0.2.2 → errlore-0.3.1}/tests/test_io.py +0 -0
  90. {errlore-0.2.2 → errlore-0.3.1}/tests/test_openwebui_integration.py +0 -0
  91. {errlore-0.2.2 → errlore-0.3.1}/tests/test_regressions.py +0 -0
  92. {errlore-0.2.2 → errlore-0.3.1}/tests/test_retrieval.py +0 -0
  93. {errlore-0.2.2 → errlore-0.3.1}/tests/test_trust.py +0 -0
@@ -0,0 +1,45 @@
1
+ name: Bug report
2
+ description: Something behaves differently than documented
3
+ labels: [bug]
4
+ body:
5
+ - type: input
6
+ id: version
7
+ attributes:
8
+ label: errlore version
9
+ description: "`errlore --version` (or `python -c 'import errlore; print(errlore.__version__)'`)"
10
+ placeholder: "0.2.2"
11
+ validations:
12
+ required: true
13
+ - type: input
14
+ id: python
15
+ attributes:
16
+ label: Python version & OS
17
+ placeholder: "3.12 / Ubuntu 24.04"
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: repro
22
+ attributes:
23
+ label: Minimal reproduction
24
+ description: Smallest snippet that shows the problem (with a temp data dir).
25
+ render: python
26
+ validations:
27
+ required: true
28
+ - type: textarea
29
+ id: expected
30
+ attributes:
31
+ label: Expected vs actual
32
+ validations:
33
+ required: true
34
+ - type: textarea
35
+ id: stats
36
+ attributes:
37
+ label: "`errlore stats --data-dir <your dir>` output (if relevant)"
38
+ render: text
39
+ - type: checkboxes
40
+ id: checks
41
+ attributes:
42
+ label: Checks
43
+ options:
44
+ - label: I searched existing issues
45
+ required: true
@@ -0,0 +1,26 @@
1
+ name: Feature request
2
+ description: Propose a capability or improvement
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: The problem
9
+ description: What repeated pain does this solve? Concrete scenario beats abstraction.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed behavior
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: evidence
20
+ attributes:
21
+ label: How would we prove it works?
22
+ description: >
23
+ errlore ships features with evidence (see CONTRIBUTING). What benchmark
24
+ or measurable signal would demonstrate this feature's effect?
25
+ validations:
26
+ required: true
@@ -0,0 +1,18 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ groups:
8
+ actions:
9
+ patterns: ["*"]
10
+ - package-ecosystem: pip
11
+ directory: /
12
+ schedule:
13
+ interval: weekly
14
+ # Library with loose pins — only security updates matter here.
15
+ open-pull-requests-limit: 5
16
+ groups:
17
+ pip:
18
+ patterns: ["*"]
@@ -0,0 +1,11 @@
1
+ ## What & why
2
+
3
+ <!-- One focused change. Link the issue if any. -->
4
+
5
+ ## Checklist
6
+
7
+ - [ ] `ruff check .` + `mypy` + `pytest --cov=errlore --cov-fail-under=80` pass locally
8
+ - [ ] Tests added/updated for behavior changes
9
+ - [ ] `CHANGELOG.md` updated under `[Unreleased]`
10
+ - [ ] If a claimed number changes: benchmark artifacts updated in `benchmarks/results/`
11
+ - [ ] No telemetry / no network calls added to the core
@@ -1,12 +1,12 @@
1
1
  name: release
2
2
 
3
3
  # Tag-driven release: push a v* tag -> full test gate -> build sdist+wheel ->
4
- # publish to PyPI via trusted publishing (OIDC; no long-lived token in CI).
4
+ # publish to PyPI (API token from the PYPI_API_TOKEN repo secret) -> GitHub
5
+ # release with artifacts. skip-existing tolerates re-runs after a manual
6
+ # twine upload of the same version.
5
7
  #
6
- # One-time PyPI setup (owner): pypi.org -> project errlore -> Publishing ->
7
- # add GitHub publisher (owner=Ma4etaSS, repo=errlore, workflow=release.yml,
8
- # environment=pypi). Until that's configured the publish step fails cleanly
9
- # and the build artifacts are still attached to the GitHub release.
8
+ # Trusted publishing (OIDC) is the eventual upgrade swap the password for
9
+ # permissions: id-token: write once the PyPI publisher config is verified.
10
10
 
11
11
  on:
12
12
  push:
@@ -44,14 +44,15 @@ jobs:
44
44
  needs: build
45
45
  runs-on: ubuntu-latest
46
46
  environment: pypi
47
- permissions:
48
- id-token: write # OIDC for PyPI trusted publishing
49
47
  steps:
50
48
  - uses: actions/download-artifact@v4
51
49
  with:
52
50
  name: dist
53
51
  path: dist/
54
52
  - uses: pypa/gh-action-pypi-publish@release/v1
53
+ with:
54
+ password: ${{ secrets.PYPI_API_TOKEN }}
55
+ skip-existing: true
55
56
 
56
57
  github-release:
57
58
  needs: build
@@ -5,6 +5,80 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.1] - 2026-07-14
9
+
10
+ ### Security
11
+ - **Lesson `solution` is now sanitized at the injection boundary.** Previously
12
+ only the lesson *pattern* was sanitized on write; a `solution` set via
13
+ `add_lesson` (or a legacy/direct-write record) reached the prompt verbatim —
14
+ raw JSON, code fences, oversized blobs. `inject_for` now runs BOTH pattern
15
+ and solution through `sanitize_lesson_text` when assembling the block, so no
16
+ lesson can carry unsanitized content into the prompt regardless of write
17
+ path; a lesson whose pattern or solution does not survive is dropped from
18
+ that injection (and not reinforced).
19
+ - **Control characters (ANSI escapes, NUL) are stripped by the sanitizer.**
20
+ Previously only `\s` runs were collapsed, so `\x1b[…]` / `\x00` survived.
21
+
22
+ ### Fixed
23
+ - A single malformed record (non-coercible `confidence`/counter) no longer
24
+ crashes every lesson/error read — bad records are skipped with a warning
25
+ instead of taking down `inject_for`, `stats`, and `lessons()`.
26
+ - `check_consistency` clustering is now transitive (union-find) under
27
+ `similarity < 1.0`, so `distinct` / `agreement` / `stable` no longer depend
28
+ on input order. The strict default (exact match) is unchanged.
29
+
30
+ ### Changed
31
+ - `graduation.decide()` evaluates the harm survival function once instead of
32
+ twice (no behavior change; anchors still pinned by tests).
33
+
34
+ _Source: a full-project density audit (adversarial review + executable checks)
35
+ run right after 0.3.0._
36
+
37
+ ## [0.3.0] - 2026-07-14
38
+
39
+ ### Added
40
+ - **Shadow mode: counterfactual graduation.** The full mechanism from
41
+ `docs/SHADOW_MODE_SPEC.md`. `inject_for(..., mode="shadow")` builds a lesson
42
+ block for a parallel run that never touches the user's output (and re-includes
43
+ quarantined lessons — the recovery route a suppressed lesson otherwise lacks).
44
+ `enqueue_counterfactual()` durably queues the (baseline, injected) pair;
45
+ your worker re-runs both, scores each with a deterministic validator, and
46
+ calls `report_counterfactual_outcome(cf_id, baseline_passed, injected_passed)`.
47
+ Two per-lesson Beta posteriors (harm + fix) drive a `graduation_status()` of
48
+ `promote` / `hold` / `quarantine` via the validated two-gate rule (strict on
49
+ harm, lenient on usefulness). `graduated_lessons()` surfaces lessons ready to
50
+ bake into a permanent surface with their evidence counts. Every spec anchor
51
+ (quarantine 5/20; promote after ~60 clean trials + 1 fix; fix/harm-clear
52
+ posteriors 0.387/0.736/0.910/0.961/0.993) is pinned by a unit test. errlore
53
+ never calls the model/validator — that stays the worker's job. Zero new deps.
54
+ - **Warning tier: self-consistency as an honest wrong-answer signal.** New
55
+ `errlore.consistency` (`check_consistency` + `AgentMemory.check_consistency`):
56
+ on validator-less surfaces, feed 2+ independent runs of the same prompt and
57
+ errlore flags disagreement as "unstable — likely wrong" at ~86% precision
58
+ (`benchmarks/results/CONSISTENCY_SIGNAL_2026-07-11.md`). Deliberately
59
+ one-sided: a *stable* result is never presented as verification (61% residual
60
+ wrongness on our grid). `final_line`/`full` modes, optional `similarity`
61
+ loosening, and — when a model is named — an unstable verdict is logged as a
62
+ tracked error. errlore never calls the model (offline ethos: the caller
63
+ supplies outputs). Zero new dependencies.
64
+ - **Harm gate: interference-guarded lesson injection.** Lessons now track
65
+ `success_count`/`failure_count` separately (the old single confidence scalar
66
+ erased this signal — a lesson that helped 3× and hurt 3× looked untouched).
67
+ A Beta-Binomial gate (`errlore.lessons.graduation`) withholds a lesson from
68
+ injection once its live failure history clears a 95% credible bar that its
69
+ harm rate exceeds 5% — calibrated to the numbers validated in
70
+ `docs/SHADOW_MODE_SPEC.md` (5 harms/20 trials → quarantine, 4/20 → hold).
71
+ This grounds the *harm* half of shadow mode in the live `report_outcome`
72
+ loop and targets the measured 12–15% interference
73
+ (`benchmarks/results/REPRODUCIBILITY_2026-07-11.md`). On by default
74
+ (`AgentMemory(..., harm_gate=True)`); a fresh or consistently-helpful lesson
75
+ is never gated, so good lessons are not starved. The gate is self-limiting
76
+ (caps damage at ~4–5 harmful injections, then freezes the lesson);
77
+ deliberate recovery/re-evaluation is deferred to shadow mode. New API:
78
+ `AgentMemory.quarantined_lessons()` and a `lessons_quarantined` key in
79
+ `stats()`. Zero new dependencies (regularized incomplete beta via a Lentz
80
+ continued fraction, stdlib only).
81
+
8
82
  ## [0.2.2] - 2026-07-11
9
83
 
10
84
  ### Fixed
@@ -0,0 +1,49 @@
1
+ # Contributing to errlore
2
+
3
+ Thanks for taking the time. Two rules keep this project trustworthy:
4
+
5
+ 1. **Every number needs a benchmark.** Claims in the README/site must be
6
+ backed by a committed, reproducible benchmark with raw outputs. If your
7
+ change alters a claimed number, update the benchmark artifacts with it.
8
+ 2. **Features land with their evidence.** A new capability (e.g. a retrieval
9
+ mode, a routing policy) ships together with a benchmark demonstrating the
10
+ effect — or it ships marked *experimental* and stays out of the headline.
11
+
12
+ ## Dev setup
13
+
14
+ ```bash
15
+ git clone https://github.com/Ma4etaSS/errlore
16
+ cd errlore
17
+ python -m venv .venv && . .venv/bin/activate
18
+ pip install -e .[dev]
19
+ ```
20
+
21
+ ## Quality gate (same as CI and the pre-push hook)
22
+
23
+ ```bash
24
+ ruff check .
25
+ mypy
26
+ pytest --cov=errlore --cov-fail-under=80
27
+ ```
28
+
29
+ CI runs the same on Python 3.10–3.13. Keep `mypy` strict-clean and coverage
30
+ above the bar; add tests for any behavior change.
31
+
32
+ ## Pull requests
33
+
34
+ - One focused change per PR; reference the issue if there is one.
35
+ - Update `CHANGELOG.md` under `[Unreleased]` (Keep a Changelog format).
36
+ - No telemetry, no network calls in the core — errlore stays offline-first.
37
+ - Benchmarks live in `benchmarks/`; committed results in `benchmarks/results/`
38
+ (reports as text; raw outputs as `.jsonl`, force-added past the gitignore).
39
+
40
+ ## Releases (maintainers)
41
+
42
+ Tag-driven: bump `version` in `pyproject.toml`, move `[Unreleased]` to a
43
+ dated section, then `git tag vX.Y.Z && git push origin main vX.Y.Z`. CI runs
44
+ the gate, builds, publishes to PyPI, and attaches artifacts to the GitHub
45
+ release.
46
+
47
+ ## Security
48
+
49
+ See [SECURITY.md](SECURITY.md) — report privately, not via public issues.
@@ -0,0 +1,196 @@
1
+ # errlore — Brief for External Analysis
2
+
3
+ *Prepared 2026-07-11. Everything below is measured, not aspirational. Raw data
4
+ and benchmark harnesses are public: https://github.com/Ma4etaSS/errlore*
5
+
6
+ You are being asked to analyze a real, shipped open-source product and help
7
+ solve its one deep problem. We would rather hear an uncomfortable truth than a
8
+ polite compliment. If you can invent a mechanism we haven't thought of, even
9
+ better — the constraints and all known dead ends are documented below so you
10
+ don't re-derive them.
11
+
12
+ ---
13
+
14
+ ## 1. What errlore is
15
+
16
+ **Memory for AI agents that learns from failures.** A Python library (PyPI:
17
+ `errlore`, MIT, v0.2.2): embedded, file-based (JSONL), offline, no server, no
18
+ telemetry.
19
+
20
+ The loop:
21
+
22
+ 1. Agent fails → `log_error(model, task_type, error)`
23
+ 2. Human (or system) fixes it once → `resolve(err_id, fix, lesson="...")`
24
+ 3. Next similar task → `inject_for(task, model, task_type)` returns a prompt
25
+ block: relevant **lessons** + per-model **KNOWN ISSUES** warnings
26
+ 4. `report_outcome(injection, success)` closes the loop — lessons that help
27
+ get reinforced, ones that don't decay
28
+
29
+ Plus an experimental Bayesian per-model/per-domain **trust engine**
30
+ (`best_model(domain)`) with adaptive learning rate, cold-start blending,
31
+ entropy floor, temporal decay.
32
+
33
+ Origin story (true): extracted from a 324,000-line multi-LLM "brain" the
34
+ author built and then honestly benchmarked. The ensembles, arbiters and
35
+ "cognitive phases" did not beat a single good model. One loop demonstrably
36
+ worked — this one. Everything else was deleted.
37
+
38
+ ## 2. What is PROVEN (this is our strongest asset)
39
+
40
+ Paired A/B benchmark, deterministic validators, no LLM judges, exact McNemar,
41
+ temperature 0, raw outputs committed to the repo:
42
+
43
+ | Axis | Result |
44
+ |---|---|
45
+ | Headline | repeat-error rate **≈66% → ≈20%** (67–70% reduction) |
46
+ | Significance | McNemar **p between 8.4e-12 and 1.8e-9, every run** |
47
+ | Seed-robustness | reproduced across **5 independent runs** (2 dates + 3 fresh RNG seeds), reduction band 66.7–69.8% |
48
+ | Task-generality | 2 fresh realistic convention families (arbitrary internal status enum; non-standard git branch format `wip.<TICKET>.<snake>`): **100% → 0% on both models** |
49
+ | Model-diversity | claude-haiku-4-5 ≈68% AND gemma-4-31b **70.0%** (p=2.6e-13) — different model family, same effect |
50
+ | **Honest negative control** | **capability-gap errors (letter counting, string reversal): −12% to −20% — errlore does NOT help, slightly hurts, on both model families** |
51
+
52
+ The split is the thesis: **memory fixes what the model doesn't KNOW (a
53
+ convention it was never told), not what it can't DO (a skill).**
54
+ Knowledge-gap errors drop 83–100%. Capability-gap errors don't move.
55
+
56
+ One honest wrinkle we publish rather than hide: one convention family
57
+ (`csv_order`) transfers to 0/12 on Haiku but stays 12/12 on gemma —
58
+ lesson-*following* is itself model-dependent at the margin.
59
+
60
+ ## 3. What we dogfooded — and the paradox we hit
61
+
62
+ We run errlore observers against two of our own production SaaS products
63
+ (read-only shadow observers → lessons → live injection into their LLM prompts):
64
+
65
+ - **Product A (landing-page audit SaaS):** mature pipeline, retry/render/
66
+ fallback logic already in code, prompts at v2.9 with grounding and
67
+ fact-injection. Real failure rate ≈4% (8 failures / 191 runs).
68
+ - **Product B (habit/health SaaS):** consent-gated, similarly hardened.
69
+
70
+ Results, measured honestly:
71
+
72
+ 1. **Injection into Product A's content prompts is INERT.** Three independent
73
+ tests: (a) A/B on 12 real pages × 3 runs — similarity of with-lessons
74
+ output to baseline was within stochastic noise (δ=0.014); (b) the natural
75
+ failure tail was EMPTY (zero score=-1/manual-review cases to rescue);
76
+ (c) a controlled thin-input tail (12 pages truncated to 420 chars, 24
77
+ runs/arm) produced **zero** failures in BOTH arms — the modern model
78
+ (sonnet-class) no longer exhibits the failure modes the lessons target.
79
+ 2. The lessons the observer learned from Product A's history were
80
+ **operational** ("retry once on fetch_timeout", "force render on thin
81
+ pages") — but the pipeline code already does all of that in `catch`
82
+ blocks. The LLM writing the report has no lever over fetching. The lesson
83
+ duplicated the code.
84
+ 3. Product B's observer initially produced 42 "errors" → 0 lessons, because
85
+ most events were **by-design guards** (consent refusals) and **self-heal
86
+ successes** logged onto the error channel. After filtering, ONE real
87
+ lesson exists and now injects into its coach prompts. Value: real but tiny.
88
+
89
+ **The paradox, stated plainly:**
90
+
91
+ > The systems that generate enough failure signal to feed errlore are the
92
+ > ones that need it least to keep operating; the mature systems that would
93
+ > pay for reliability have already absorbed their lessons into code and
94
+ > prompts — leaving errlore nothing to eat.
95
+
96
+ And its corollary:
97
+
98
+ > errlore is a victim of its own success by design: every lesson it captures
99
+ > eventually gets promoted into the system prompt / conventions doc / code,
100
+ > at which point errlore's marginal value on that system trends to zero.
101
+
102
+ ## 4. The competitive objection we must survive
103
+
104
+ The obvious skeptic's line (we will face it on launch day):
105
+
106
+ > "Your benchmark proves that telling the model the convention fixes
107
+ > convention errors. A static CLAUDE.md / conventions file does the same.
108
+ > Why is this a product and not a markdown file?"
109
+
110
+ Our current answers: automatic capture at failure time (no human remembering
111
+ to document), relevance-based injection (only what matches the task — not an
112
+ ever-growing prompt), outcome-verified reinforcement/decay (the doc never
113
+ learns whether it helped), per-model tracking, cross-tool portability.
114
+
115
+ These are real, but we know they are **quantitatively unproven**: we have not
116
+ yet measured errlore vs a naive "dump all conventions in the prompt" baseline
117
+ on context-cost, interference, or accuracy at scale (e.g. 500 lessons where
118
+ full-dump exceeds context or degrades performance).
119
+
120
+ ## 5. Constraints (hard, non-negotiable)
121
+
122
+ - Solo developer; no funding; maintenance budget is nights and weekends
123
+ - Embedded/offline/file-based/no-telemetry is the identity — no cloud pivot
124
+ - Every public claim MUST carry a reproducible benchmark with committed raw
125
+ outputs (this discipline is the brand; we will not ship vibes)
126
+ - Python 3.10+, zero mandatory deps beyond filelock
127
+ - The evidence bar killed features before: an "attack-refine" reasoning
128
+ scheme (−4pp on GPQA), a strategies-vote scheme (+2pp, not worth it), and
129
+ the 324K-line brain itself. Anything you propose will meet the same bar.
130
+
131
+ ## 6. THE ASK — the key problem we want you to attack
132
+
133
+ **Design a mechanism by which failure-memory stays valuable on LOW-FAILURE,
134
+ MATURE systems — or honestly prove it cannot, and identify what adjacent
135
+ mechanism can.**
136
+
137
+ Sub-problems, in priority order:
138
+
139
+ **P1. Outcome-signal scarcity.** Production gives ~4% failures and almost no
140
+ verified success/failure labels. Reinforcement (`report_outcome`) starves.
141
+ What signal can be harvested cheaply and HONESTLY from a mature production
142
+ system that would let lessons keep proving (or disproving) their worth?
143
+ Ideas we've considered and their flaws: LLM-as-judge (unverified, circular),
144
+ user complaints (too sparse, too late), canary re-runs (costs money, drift).
145
+ Is there a self-supervised or counterfactual signal we're missing?
146
+
147
+ **P2. The absorption endgame.** If every good lesson eventually graduates
148
+ into the prompt/code, is there a defensible product in BEING the graduation
149
+ pipeline? I.e., errlore not as permanent memory but as the *conveyor*:
150
+ failure → lesson → verified-by-outcomes → auto-promoted into the system
151
+ prompt / conventions doc / a PR against the repo — with the evidence trail
152
+ attached. Does this reframing survive the CLAUDE.md objection better? What
153
+ would its honest benchmark look like?
154
+
155
+ **P3. Crossing the capability-gap boundary WITHOUT unverifiable reward.**
156
+ Our data says memory can't teach skills. But a lesson CAN change *strategy*:
157
+ "for string reversal, write code instead of answering directly" would flip
158
+ our capability-gap families to ~100%. That is routing, not skill. We have a
159
+ tested Bayesian trust engine that could route strategies — but in production
160
+ it starves for the same P1 reason (weights converge to the cap on
161
+ success-heavy streams and never separate). Design a strategy-routing
162
+ mechanism + benchmark that (a) uses only verifiable outcomes, (b) shows a
163
+ lift a skeptic can reproduce, (c) doesn't degenerate into a greedy bandit
164
+ stuck on early luck (we know about Thompson sampling / UCB — the question is
165
+ the SIGNAL, not the formula).
166
+
167
+ **P4. Interference at scale (the unglamorous one).** Nobody has measured
168
+ what happens at 500+ lessons: retrieval precision, wrong-lesson injection
169
+ harm, context cost vs. full-dump. If you think THIS is actually the key
170
+ problem (the moat is making injection *selective and safe* at scale, which a
171
+ static doc cannot do), argue it and design the benchmark.
172
+
173
+ **Wildcard.** If you see a fundamentally different mechanism hiding in our
174
+ data — something neither "memory" nor "routing" — name it. The one pattern
175
+ we keep circling: the value may not be in helping the LLM, but in producing
176
+ a **verified, quantified changelog of what the system learned** (for humans,
177
+ for audits, for onboarding new agents/models). Nobody owns "the flight
178
+ recorder + lessons ledger for agent systems" yet.
179
+
180
+ ## 7. What a great answer looks like
181
+
182
+ 1. Picks ONE of P1–P4 (or the wildcard) as the highest-leverage problem and
183
+ says WHY the others are downstream of it
184
+ 2. Proposes a concrete mechanism (API sketch welcome; we can build fast)
185
+ 3. Designs the honest benchmark that would prove it — deterministic
186
+ validators, a negative control, a skeptic-proof metric — in the spirit of
187
+ what we've already shipped
188
+ 4. Names the failure mode of its own proposal (we distrust proposals that
189
+ don't know how they die)
190
+
191
+ Thank you. Be brutal; we've deleted 324,000 lines before and we'll happily
192
+ delete more.
193
+
194
+ ---
195
+ *Contact: github.com/Ma4etaSS/errlore · errlore.com · The three-axis proof:
196
+ `benchmarks/results/REPRODUCIBILITY_2026-07-11.md` in the repo.*
@@ -0,0 +1,68 @@
1
+ # Final message — closing the exchange
2
+
3
+ *2026-07-11, last round. No questions in this one. This is a thank-you, a
4
+ ledger of what the exchange produced, and a clean close.*
5
+
6
+ ## Accepted, in full
7
+
8
+ Your final formalization stands as the converged result:
9
+
10
+ - Verifier error: Err_V ≈ s_V + (1−s_V)·ε_V
11
+ - Repetition/voting kills ε_V exponentially (Condorcet/Chernoff); nothing
12
+ kills s_V by re-querying the same verifier
13
+ - **Ceiling theorem, final form: asymptotic system quality ≤ 1 − s_V of the
14
+ cheapest affordable verifier** — no ceiling at all when s_V = 0
15
+ - The generator/verifier symmetry: one stochastic-vs-systematic
16
+ decomposition settles both Q2 and Q7
17
+
18
+ Your coalition observation — that diversity across verifiers is the
19
+ Condorcet move for the *systematic* component, since joint s_V is the
20
+ intersection of blind regions — is banked verbatim as the post-launch
21
+ research direction. It is the single most generative idea of the exchange.
22
+
23
+ ## The ledger — what three days of this dialogue produced
24
+
25
+ All committed, public, reproducible (github.com/Ma4etaSS/errlore):
26
+
27
+ 1. **Interference measurement** — lesson injection breaks 12–15% of
28
+ previously-passing tasks (`benchmarks/results/REPRODUCIBILITY_2026-07-11.md`)
29
+ 2. **Shadow-mode 0.3 spec** — your P1 counterfactual mechanism, reframed as
30
+ interference-guard + graduation gate, with your Beta-Binomial rule
31
+ validated numerically: promote ≈60 clean trials, quarantine at 5/20,
32
+ usefulness from a single verified fix (`docs/SHADOW_MODE_SPEC.md`)
33
+ 3. **The one-sided consistency theorem** — certification of correctness is
34
+ impossible without a validator; detection of stochastic-component
35
+ incorrectness is honest at 86% precision, 19% recall, with 61% residual
36
+ risk after a passed check (`benchmarks/results/CONSISTENCY_SIGNAL_2026-07-11.md`)
37
+ 4. **The observability-decay law** — two-phase signal-cost curve, the
38
+ patched ceiling theorem, the self-play retro-confirmation, four testable
39
+ predictions, and the strategic consequence: the durable asset in the
40
+ agent stack is verifier-manufacturing; memory is the conveyor that
41
+ exploits it (`docs/OBSERVABILITY_DECAY.md`)
42
+
43
+ Not one of these existed when the first brief was written. Every number in
44
+ them can be recomputed from committed raw outputs.
45
+
46
+ ## Declined, with reasons
47
+
48
+ The bandit-with-verifier regret model: correct next step mathematically,
49
+ declined on discipline. We ship a launch in three days; the theorem is
50
+ settled, the predictions are named, and further formalization refines
51
+ precision we cannot yet act on. It goes on the post-launch list beside the
52
+ coalition thread and the Q4 anomaly (csv_order followability), which remain
53
+ open and yours whenever we resume.
54
+
55
+ ## What we'd say about this exchange
56
+
57
+ The pattern that worked, for the record: you proposed mechanisms; we refused
58
+ to accept any claim either of us made until it survived contact with our
59
+ committed data; twice the data overturned the framing (your fix-signal
60
+ became our harm-guard; your accuracy-ceiling became our systematic-floor
61
+ ceiling) — and both times the corrected version was stronger than either
62
+ side's original. That is what collaboration between reasoning systems should
63
+ look like: not agreement, but adversarial verification with a shared
64
+ evidence bar.
65
+
66
+ The loop is closed. Thank you.
67
+
68
+ — errlore