docs(readme): one coherent start-to-finish walkthrough a downloader can follow
Measured before writing: the commands existed but were scattered across the
mode partition, and there was no path a newcomer could walk end to end. The
capability gap that made a complete offline walk impossible is closed in
3abc61b; this is the door onto it in the README.
Five steps, each RUN FROM A FRESH CLONE before being written down (git clone +
uv sync + uv run pytest -> 652 passed): read the knowledge base, watch the
learning loop close, run the loop with your own scripted answers, watch the
validator say NO, and price a real run before spending anything. Step 4 is the
one that was missing entirely -- the demo only ever showed a yes, and a
refusal carries far more weight than another approval.
Also documents that `Rejection (..., decision=approved)` is not a
contradiction: the first is the validator's outcome, the second echoes the
human's recorded verdict. Documented rather than changed -- altering a public
output format is the operator's call, not a side effect of writing docs.
`costsim` gets its first mention in the README at all; it was finished, tested
and completely invisible from the surface.
Also points the commons link at open/ (published 2026-08-04). NB: the
repo-standard v0.3.0 register still lists 19 repos and does not know that repo,
so pointing at the correct live URL now trips a false LINK-DEAD. Reported to
org-ops; the URL answers HTTP 200.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GWsexbQjPo9rsV3aUE54ZS
This commit is contained in:
parent
3abc61bac3
commit
93608d008d
1 changed files with 76 additions and 2 deletions
78
README.md
78
README.md
|
|
@ -35,6 +35,77 @@ uv run pytest
|
|||
There is no CI runner in this organization, so nothing runs that suite automatically — the command
|
||||
above is the verification.
|
||||
|
||||
## Walk the whole chain offline
|
||||
|
||||
Five commands, no API key, no network, no cost. They exercise the real loop — context navigation
|
||||
over the knowledge base, the maker/checker debate, the deterministic validator, the verdict — with
|
||||
**scripted stand-ins for the agents' answers**. Every scripted invocation prints a banner saying so,
|
||||
because a scripted run that reads like a model run would be worse than having no offline mode at
|
||||
all. What this shows is that the loop closes and the gate bites; it does not show how well a given
|
||||
model would propose or judge.
|
||||
|
||||
**1 — Look at the knowledge base.** It is curated markdown, not a black box:
|
||||
|
||||
```bash
|
||||
ls shared/examples/bygg-energi-mikro/
|
||||
```
|
||||
|
||||
**2 — Watch the learning loop close.** Two runs separated by an expert approval, with the second
|
||||
demonstrably informed by the first:
|
||||
|
||||
```bash
|
||||
uv run python -m portfolio_optimiser.simulation
|
||||
```
|
||||
|
||||
The trace ends with the approved verdict's marker present in Run B's prompt and absent from Run A's
|
||||
— knowledge crossing runs purely through the file-backed wiki (promote → re-seed → fold).
|
||||
|
||||
**3 — Run the loop over a knowledge base, with answers you supply.** Write the stand-in replies,
|
||||
then point the CLI at the bundle:
|
||||
|
||||
```bash
|
||||
cat > replies.json <<'JSON'
|
||||
{
|
||||
"proposer": "{\"measure\":\"LED-retrofit\",\"affected_items\":[{\"code\":\"ENERGI-TOTAL-EL\",\"quantity\":300000,\"unit_cost\":1.0}],\"claimed_saving_nok\":30000}",
|
||||
"checker": "The numbers are within a feasible range. VERDICT: APPROVE"
|
||||
}
|
||||
JSON
|
||||
|
||||
uv run python -m portfolio_optimiser.run BYGG-KONTOR-NORD \
|
||||
--docs-dir shared/examples/bygg-energi-mikro \
|
||||
--bundle-dir shared/examples/bygg-energi-mikro \
|
||||
--scripted-replies replies.json
|
||||
```
|
||||
|
||||
Ends in `ValidatedProposal`. Swap `--bundle-dir`/`--docs-dir` for your own bundle to run it over
|
||||
your own data — that is the point of this door, and the reason it is not the same thing as step 2.
|
||||
|
||||
**4 — Watch it say no.** Raise `claimed_saving_nok` to `250000` in `replies.json` and run the same
|
||||
command again. The outcome becomes `Rejection`: the deterministic validator refuses a saving the
|
||||
project's own numbers cannot support, no matter how confidently the proposer asserted it. This is
|
||||
the part of the method that carries the weight — the agents propose, and something that cannot be
|
||||
argued with decides.
|
||||
|
||||
Read that summary line carefully: `Rejection (verdict id=…, decision=approved)` is not a
|
||||
contradiction. `Rejection` is the **validator's** outcome, while `decision=` echoes the
|
||||
**human's** recorded verdict — here the `--decision` default, since nobody reviewed this run.
|
||||
The two are deliberately separate: a machine gate that blocks, and a human judgement that
|
||||
approves, are different questions and are never collapsed into one field.
|
||||
|
||||
**5 — See what it would cost with a real model**, before spending anything:
|
||||
|
||||
```bash
|
||||
uv run python -m portfolio_optimiser.costsim --projects 4 --profile local
|
||||
```
|
||||
|
||||
Modelled upper bounds per role and model, with the source of each price quoted. `--profile local`
|
||||
prices the free local backend; the estimate is a ceiling, not a bill.
|
||||
|
||||
> `--live-dry-run` is a different, narrower drill: it builds contracts, clients and budget against
|
||||
> your own configuration and **stops before the first model call**. It verifies the setup; it does
|
||||
> not run the loop. `--scripted-replies` runs the whole loop. The two are mutually exclusive and
|
||||
> passing both is refused rather than one silently winning.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- **Not a compliance product.** It ships the technical prerequisites — local-only operation,
|
||||
|
|
@ -131,7 +202,7 @@ when the seam is detached, so the loop cannot silently degrade into theater.
|
|||
## How it is set up
|
||||
|
||||
- **One shared, framework-neutral core** ([`shared/`](shared/README.md), a git subtree of
|
||||
[`portfolio-optimiser-commons`](https://git.fromaitochitta.com/ktg/portfolio-optimiser-commons)):
|
||||
[`portfolio-optimiser-commons`](https://git.fromaitochitta.com/open/portfolio-optimiser-commons)):
|
||||
the business concept, the normative [method spec](shared/method-spec.md) and
|
||||
[ingest spec](shared/ingest-spec.md), the expert-reviewer persona as an Agent Skill, and an
|
||||
example bundle with a golden suite as the only ground truth. Both stacks implement from the
|
||||
|
|
@ -145,7 +216,10 @@ when the seam is detached, so the loop cannot silently degrade into theater.
|
|||
cannot exercise every flag:
|
||||
- **Single-project** — `PROJECT_ID --docs-dir <dir>`, plus optional `--bundle-dir`,
|
||||
`--verdict-dir`, `--outbox-dir` (which requires `--run-id`), `--dimension-config`,
|
||||
`--semantic-retrieval`, `--decision`/`--rationale`, and `--live-dry-run`.
|
||||
`--semantic-retrieval`, `--decision`/`--rationale`, `--live-dry-run`, and
|
||||
`--scripted-replies <file>` (the offline whole-loop door — see
|
||||
[Walk the whole chain offline](#walk-the-whole-chain-offline); mutually exclusive with
|
||||
`--live-dry-run`, which stops before the first model call rather than answering it).
|
||||
- **Portfolio** — `--portfolio`, plus optional `--goals`, `--ledger`, `--dimension-config`,
|
||||
`--semantic-retrieval`; it stops early and prints a `goal reached: …` line when the
|
||||
accumulated ledger meets a goal.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue