portfolio-optimiser-claude/CLAUDE.md
Kjell Tore Guttormsen e6bc1832a2 docs(links): the commons pointer must resolve for a stranger, not just for me
Both links named the private ktg/ namespace. commons published the repo at
open/ (identical history, same HEAD) and reported the four hits it measured
in our working copy. These are the two we own; the two in shared/README.md
are commons-owned and arrive via subtree pull, never edited in place.

README.md:64 is the one that mattered: it sits on the published surface and
promised a clonable source a stranger gets a 404 on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qr6TwWrHDHeukHy3bL4hgb
2026-08-09 09:58:22 +02:00

69 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# portfolio-optimiser-claude
## Kontekst
Søsken-implementasjon (beslutning D7) av portfolio-optimiser-metoden på **Claude Agent SDK**:
generisk, åpent Python-rammeverk som finner kostnadsbesparelser INNI hvert prosjekt i en
portefølje. Bygges **fra metode-spec-en alene** (`shared/method-spec.md`) — aldri ved
reverse-engineering av MAF-søskenet (`~/repos/portfolio-optimiser`). Program-planer
(sesjonsplan S5S12, sammenligningsprotokoll, frossent målbilde) bor i hovedrepoets
`docs/plan/`. Løpende state: `STATE.md` (local-only).
## Stack
Python ≥3.10. **Claude Agent SDK** (`claude-agent-sdk` ≥0.2, verifisert 0.2.110 per
2026-07-03: MIT-lisens, bundler Claude Code CLI — ingen separat installasjon; import og
konstruksjon fungerer uten API-nøkkel, nøkkel trengs kun ved faktisk `query()`).
Pakkehåndtering: `uv`. Pydantic for kontrakts-validering.
## Konvensjoner
- Type hints overalt; `mypy --strict`. `ruff` for lint+format. `pytest` for test.
- **Testsuiten kjører uten API-nøkkel og uten nettverk** (invariant fra S5; håndhevet ved at
all kontrakts-/kontekst-logikk er ren config/fil-lag).
- Modell-valg som konfig: `src/portfolio_optimiser_claude/data/model_map.json`
(rolle→Claude-modell-id per backend-profil, hver profil krever `default`; validert av
`contracts.py`). Modell-id-er verifiseres mot offisiell doc før endring.
- SDK-primitiver (verifisert 2026-07-03): `query()`/`ClaudeSDKClient`, `ClaudeAgentOptions`
(`max_turns`, `max_budget_usd` — førsteklasses USD-tak), `AgentDefinition` (subagenter;
sub-felt er camelCase), `@tool` + `create_sdk_mcp_server` (in-process MCP), hooks
(`PreToolUse` med `permissionDecision: "deny"` for deterministisk gating). MERK:
`SessionStart`/`SessionEnd` finnes IKKE som Python-callback-hooks.
- `shared/` er en **git subtree** av
[`portfolio-optimiser-commons`](https://git.fromaitochitta.com/open/portfolio-optimiser-commons)
(source of truth; remote `commons`). Synk er **PULL-ONLY**: endringer committes i commons og
hentes med `git subtree pull --prefix=shared commons main --squash`. ALDRI `git subtree push`
fra konsument — re-split lekker hele konsument-historikken inn i commons (observert + opprydd
i MAF-repoet 2026-07-03). Se `shared/README.md`.
## Kommandoer
- Sync: `uv sync`
- Test: `uv run pytest`
- Lint: `uv run ruff check .` + `uv run ruff format .`
- Type: `uv run mypy src`
## Arbeidsflyt (invarianter)
- **Rent teknisk rammeverk:** deployer eier DPIA/ROS/behandlingsformål — kun tekniske
forutsetninger (lokal-only, provenance, ingen stille egress) + disclaimer.
- **Metode-spec-en er normativ** (RFC 2119). Ærlighets-regelen (§1) er ufravikelig: ingen
artefakt påstår mer enn implementasjonen gjør; skriptede stand-ins merkes som det.
- **Deterministisk validator obligatorisk + blokkerende** (§3 steg 4); golden-suiten
(`shared/examples/bygg-energi-mikro/golden.json`) er ENESTE fasit (§7).
- **Load-bearing tester** (§11): hver søm bevises med en test som blir RØD når sømmen
detaches — grønn-men-død er feilmoden regelen finnes for.
- **Stoppkriterier + budsjett-tak påkrevd ved oppstart** (§8; `contracts.py` fail-fast).
På kjørestien kommer USD-taket i tillegg via `ClaudeAgentOptions.max_budget_usd`.
- **Kostnadsdisiplin (D6):** alt utvikles offline/deterministisk; den ENE ekte API-kjøringen
i programmet er S10 (mikro-bundle, billigste egnede modell — per model_map Haiku 4.5 —
harde tak, kost loggføres).
- **STATE.md er local-only** (gitignored — repoet skal publiseres; STATE når aldri et
offentlig speil).
## Communication patterns
### Linking to local files
When pointing to local files in responses, always use markdown link syntax with a descriptive name:
- Use `[Human-friendly name](file:///absolute/path)` — never bare `file:///...` URLs or autolinks `<file://...>`.
- Always use absolute paths. Never `~/` or relative paths.
- For multiple files, render as a bullet list of named markdown links.
Why: bare `file://` URLs only render the first as clickable across multiple lines. Named markdown links make each entry independently clickable and look cleaner.