79 lines
6.1 KiB
Markdown
79 lines
6.1 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to this project will be documented in this file.
|
||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||
|
||
## [Unreleased]
|
||
|
||
### Added
|
||
- Deterministic backbone: mandatory blocking validator (solver + Monte Carlo against the shared
|
||
golden suite), budget meter with hard fail-fast caps, provenance stamping.
|
||
- Agentic learning loop wired end to end, one load-bearing seam at a time (target-picture steps
|
||
1, 3/4, 5, 7, 8): OKF-navigated bundle context with the gated ExpeL fold, maker-checker debate
|
||
where the checker gates the reasoning, informed refinement (previous rejection reason fed into
|
||
the next bounded attempt), async verdict file inbox, and gated wiki promotion (fail-closed).
|
||
- Offline end-to-end simulation proving the learning loop closes with a scripted client
|
||
(`uv run python -m portfolio_optimiser.simulation`) — plumbing proof, not live-model proof.
|
||
- Framework-neutral shared core in `shared/`: OKF concept + example bundle, golden validator
|
||
suite, and the expert-reviewer persona as an Agent Skill.
|
||
- CLI parity (S5.3): `run.py` drives the whole method from the command line in **two modes** —
|
||
single-project (`--dimension-config`, `--outbox-dir`/`--run-id`, plus the already-wired
|
||
`--bundle-dir`/`--verdict-dir`) and portfolio (`--portfolio` with `--goals`/`--ledger`), the
|
||
latter printing an observable `goal reached: …` line when a savings goal is met. Adds a
|
||
fail-fast `load_dimension` loader and structured refusals (rc 1, no traceback) for misuse and
|
||
mode-exclusivity violations. The prior-verdict fold is on the `--bundle-dir` path only; a
|
||
`--docs-dir`-only run is single-shot.
|
||
- Value report (S5.4): a read-only `--report [--json] --ledger <file>` surface on `run.py` that
|
||
rolls up the accumulated `SavingsLedger` — per-project + portfolio totals (dimension-free-deduped
|
||
integer øre), flagged cross-dimension overlaps (each counted once), and per-entry provenance — as
|
||
a human table or deterministic JSON. Makes no model calls; mode-exclusive (only `--ledger`/`--json`
|
||
permitted with `--report`, which requires `--ledger`). Honest scope boundary: the report core
|
||
(`value_report.py`) now **exists** but is deliberately **not** wired into `costsim`'s
|
||
`kost_mot_verdi` placeholder — that cost-vs-value integration is a separate, deferred step. The
|
||
`costsim` seam note was reworded from the stale "fylles av S5.4 verdirapport" to a truthful
|
||
forward reference so `costsim`'s own output no longer claims the wiring is done.
|
||
- Semantic retrieval seam (S3.1): a new MAF-free `semretrieval.py` adds an `Embedder`/`Retriever`
|
||
pair and a `HybridRanker` blending a numpy cosine term over the embedded feature triple (sorted
|
||
cost codes, measure type, magnitude bucket) with the existing structural score, exposed as
|
||
`--semantic-retrieval`. **What ships is the seam, not better retrieval quality**: the bundled
|
||
`FakeEmbedder` is a deterministic sha256 projection with no semantics, so over a structural tie
|
||
the order is deterministic but arbitrary. A real embedder is selected from a CLOSED registry via
|
||
`--embedder-config` / `build_embedder` — deliberately never an import path, so a config file can
|
||
never name arbitrary code to load.
|
||
**Off by default and additive**: with no retriever passed the store delegates to
|
||
`StructuralRetriever`, which reproduces the pre-seam ranking exactly, so the text-excluded
|
||
default and every existing test are unchanged. The embedding excludes `description`, matching
|
||
`similarity` ("text is ignored by design") and the verdict-id hash — so a flag-on run reads no
|
||
surface text either, and a genuine expert verdict can no longer be outranked by the framework's
|
||
own echo of the query. The ranker is passed PER CALL, never assigned to the caller's store, so
|
||
the opt-in cannot outlive the run that asked for it. Accepted in both run modes; in
|
||
single-project mode it requires `--bundle-dir` and `--verdict-dir` and is refused — never
|
||
silently ignored — without them.
|
||
Determinism, precisely: ranking order rests on the total order `(-round(score, 9), id)`; the
|
||
BLAS thread pins set before numpy is imported (`VECLIB_MAXIMUM_THREADS` for Accelerate,
|
||
`OPENBLAS`/`MKL`/`OMP` for other backends) defend the narrower claim that vector artifacts are
|
||
byte-identical across environments. Ships an optional, rebuildable `vectors.npy` +
|
||
`vectors.jsonl` store (byte-identical regardless of insertion order; fail-fast on a row/line
|
||
mismatch; missing loads as `None`) — an authoring primitive with no caller in `src/`, offered to
|
||
extenders like `write_verdict` and `promote_verdict`. numpy is confined to `semretrieval.py` and
|
||
never enters `okf.py`, `retrieval.py` or `shared/`.
|
||
- Azure/Foundry offline preflight config gate (`preflight.py`, S4.1).
|
||
- Offline live-dry-run drill (`--live-dry-run`, S4.2): walks the whole path up to the eager
|
||
client build and stops before the first model call — zero chat calls.
|
||
- Out-of-band HITL verdict routing CLI (`hitl.py`, S5.1): code-prefix routing on the candidate id.
|
||
- Expert-notification contract (`notify.py`, S5.2): the declared `Notifier` with `ConsoleNotifier`,
|
||
`FileNotifier` (byte-deterministic JSONL), and `WebhookNotifier`, plus a fail-fast
|
||
`build_notifier`; the webhook is the only egress point, fail-closed behind an explicit per-run
|
||
`allow_egress` opt-in. Not auto-wired into `run.py`.
|
||
- `docs/knowledge-base-recipe.md` (S5.3, D-H item 1): the documented team process (technical +
|
||
domain expert) for building a knowledge base, with the honest 1–2 week expectation.
|
||
- Test suite: 512 passing tests (4 skips are live-provider-only). Every wired seam is covered by a
|
||
load-bearing test that goes red when the seam is detached — including, since the S3.1 review
|
||
remediation, the `--semantic-retrieval` wiring at `main()` level. That claim did not hold for
|
||
S3.1 as first shipped: the flag was covered only below the CLI, so hardcoding it off left the
|
||
suite green. Each remediated seam now carries a recorded detach point, verified by mutation.
|
||
|
||
### Notes
|
||
- Licensed under the MIT License (see `LICENSE`).
|