Commit graph

79 commits

Author SHA1 Message Date
84d19c97d6 docs(plan): session-by-session execution plan from the 2026-07-02 status analysis
Sequences the decided arc (R1 extraction -> D7 sibling -> comparison) into
12 single-session increments (S1-S12), folding in the analysis findings:
truth maintenance (S1), the missing shared method spec (S2), extraction
de-risking + comparison protocol (S3), and per-session verification
criteria + key-assumption tests. Target picture stays the frozen north star.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PAnzFPa9KXqjQEkw9q5Zs
2026-07-02 17:11:10 +02:00
6f861a0078 feat(persona): build the shared expert-reviewer persona as a framework-neutral Agent Skill
The expert reviewer was only a hardcoded verdict_input dict inside the offline
simulation. Build it as the real, shared artifact target picture §8 calls for:
shared/skills/expert-reviewer/ — a SKILL.md persona prompt (energy-advisor / M&V
role + the realization-gap methodology the validator cannot compute) plus a
canonical references/example-verdict.json. shared/ stays pure data; the MAF side
reads it via portfolio_optimiser.persona.load_persona_example (call-time,
fail-fast) and the Claude-SDK sibling reads the same JSON with its own loader.

This de-stubs the simulation: its persona judgement (decision + rationale + traced
marker) is now sourced from the artifact at call time, not an inline literal — so
the shared persona is genuinely consumed and cannot rot silently. decision is
binary (approved/rejected, the FeedbackContract the run path accepts);
approved_with_adjustment is rejected there and lives only in the bundle seed
frontmatter + the promotion gate, so the realization correction is carried in the
rationale prose.

Load-bearing trio (tests/test_persona_skill_loadbearing.py), each proven RED on its
own detach: structure + framework-neutrality, the example is valid pipeline input
(incl. FeedbackContract, on a throwaway copy), and the simulation's marker follows
the artifact file. Suite 149->152.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-30 13:59:42 +02:00
a9144cb9bb feat(sim): offline end-to-end simulation proving the learning loop closes
The primary method proof, offline — a deliberate, cost-driven substitution
for målbilde §11.8's real-model run (the operator runs MAF against no real
model; API for both repos is too costly privately).

`portfolio_optimiser.simulation` drives `run_project` with a scripted
synthetic chat client across two runs separated by a promotion, and shows
the learning loop close end to end:

- ScriptedChatClient subclasses the LAYERED OpenAIChatCompletionClient (not
  bare BaseChatClient — else the always-attached BudgetMiddleware no-ops),
  constructs offline (loopback url + dummy key), role-keys proposer/checker
  replies, and records every prompt into a shared sink.
- simulate_learning_loop: Run A (fresh wiki) -> validated, persona-approved
  verdict carrying a realization marker absent from the bundle -> promote_verdict
  into the OKF wiki -> seed_store_from_bundle re-reads it -> Run B's hypothesis
  prompt carries the marker. An empty-wiki control on Run A proves causality.
- `python -m portfolio_optimiser.simulation` prints an honest trace.

Honesty (§1): this proves the plumbing, the deterministic spine, and that the
learning dataflow closes — NOT that a live LLM would produce the proposal or
verdict (scripted stand-ins). The genuine model-behaviour comparison lives on
the Claude-SDK side (a minimal API run); the scripted client is MAF-side
scaffolding, not part of the framework-neutral shared/ core.

Load-bearing: tests/test_simulation_loadbearing.py goes red when promotion is
detached (the marker never crosses into Run B). Suite 148->149.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-30 12:55:15 +02:00
6b645ad32a feat(fase6): gate-promote approved verdicts back into the OKF wiki (Steg 8)
Close the last agentic-loop seam (målbilde §3/§6/§7/§11 step 6): an
APPROVED verdict is promoted from the raw output layer into the context
layer (the OKF bundle) as a navigable `type: verdict` concept file, so
human/persona-approved knowledge reaches the next run's hypothesis.

- okf.py (pure stdlib, MAF-free): render_frontmatter / write_concept_file
  / link_in_index — the D7-portable OKF write counterpart of navigate.
- verdicts.py: promote_verdict + PromotionRefused gate (fail-closed; only
  approved decisions enter the wiki, never raw agent output), provenance
  stamp (who/experiment/when; timestamp a required kwarg), neutral index
  label (signal reaches a prompt only via the gated ExpeL fold, never
  bundle_context), _safe_filename_token (id sanitised for path/link).
- R4 = optional+gated: a public opt-in primitive, NOT wired into
  run_project (mirrors write_verdict — the system reads, the gate promotes).
- Load-bearing trio (test_step8_promotion_loadbearing.py): gate refuses a
  non-approved verdict, approved verdict is navigable, promoted signal
  stays out of the read-context — all proven RED-on-detach. Suite 144->148.

Design hardened by an adversarial plan-critic (12 findings; the BLOCKER —
index-link leak into bundle_context via index_summary — closed by the
neutral label + a no-leak test). Honesty limits documented: promoted file
is minimal (signal as prose only), and the learning-key id means
same-candidate approvals share a filename (last-write-wins).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-30 11:06:28 +02:00
e2861cac0c feat(fase5): add the long/async verdict file inbox (Steg 7 resumable feedback)
The short loop captured the expert verdict inline into an in-memory store, so a
verdict arriving days/weeks later in a separate run could not influence any future
hypothesis (målbilde §5 row 7). Steg 7 adds the long timescale: run_project gains an
opt-in verdict_dir async inbox that load_verdicts_from_dir -> store.add MERGES into the
store BEFORE the Step-1 ExpeL fold, so a verdict dropped after an earlier run reaches a
separate, later run's hypothesis — fully resumable across runs separated in time.

- verdicts.py: verdict_to_dict / verdict_from_dict (id read verbatim, never re-minted),
  write_verdict (public authoring primitive, NOT wired into run_project — system reads
  the folder, expert/persona writes it, §3 role split), tolerant load_verdicts_from_dir
  (missing/foreign/half-written files skipped, not raised — RAW layer per §10 R2),
  VerdictStore.from_dir.
- run.py: verdict_dir kwarg; ingest-merge block after load_contracts (merge not replace
  keeps run_portfolio's cross-project threading; store.add idempotent on content-hash id;
  no change to the fold). CLI --bundle-dir/--verdict-dir thread the long loop to the
  console entry. No auto-persist of the run's own captured verdict (outbox/Steg 8).
- Load-bearing PAIR (test_step7_async_loop_loadbearing.py): a verdict dropped after run A
  must reach run B's prompt (run B uses a FRESH store -> the transfer is the file loop,
  not in-memory carryover); empty-inbox control proves causality. Marker = a realization
  value absent from the bundle (not the seed's 0.82). Proven RED on ingest detach.

Suite 138 -> 140 passed, 4 skipped; mypy + ruff check clean. Målbilde treated as frozen
(no §3/§5/§7 edit). Step 8 (gated wiki promotion) remains.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-30 09:54:23 +02:00
f7c81b45ec feat(fase4): route the validator falsification into the next hypothesis (informed refinement)
Closes gap #5 (maalbilde §5/§7): generate_via_llm's outer max_attempts loop
built the prompt ONCE and re-sent it identically — a BLIND retry. The validator's
per-attempt Rejection.reason was captured in `last` but never reached the next
prompt, so the proposer re-answered the same question with no knowledge of WHY
the prior candidate failed. Step 5 routes that reason into the next attempt.

- generate.py: _build_messages() gains prior_rejection; when set it appends a
  revision block carrying ONLY the falsification reason verbatim (never the
  rejected proposal JSON). None -> the byte-identical base prompt, so attempt 1
  is unchanged. generate_via_llm() rebuilds messages inside the outer loop with
  prior_rejection=`last` (None on attempt 1); _fetch_parsed() takes messages as
  an explicit parameter. `last` is overwritten each round -> only the most-recent
  falsification ("forrige"), never an accumulated history. Bound unchanged:
  max_attempts + meter.tick_round (no new loop; §6 — "improve until good enough"
  without a ceiling stays impossible).
- Scope honesty: the only per-attempt falsifier here is the validator. The
  checker is a run-level, one-shot signal (run.py, before generation); seeding
  generation with the checker critique is separately scoped and NOT done here.
  The boundary is written into the generate_via_llm docstring + README + CLAUDE.

Load-bearing (maalbilde §7): tests/test_step5_refine_loadbearing.py is a PAIR —
the positive test keys the proposer's flip on the validator REASON PAYLOAD (the
rejected claim value, derived from validate_proposal(bad).reason so test and SUT
share one source of truth), and asserts the reason reached attempt 2's prompt
VERBATIM (the green-but-dead guard). It goes RED on detach (build messages once):
the flip token never arrives, so the outcome never flips AND the verbatim
assertion fails — proven double-red. The bounded control proves a never-fixed
proposer exhausts exactly max_attempts and returns a Rejection.

Adversarial Plan agent hardened the design pre-implementation (flip on payload
not wrapper/call-count; derive flip-key from the validator reason; drive through
generate_via_llm directly; docstring honesty). Suite 136->138 passed, 4 skipped;
mypy + ruff check clean. New test ruff-formatted; pre-existing ruff-format drift
(budget/verdicts/test_contracts) left untouched for a surgical diff.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-30 09:08:02 +02:00
4ec778c855 feat(fase3): make the maker-checker checker actually gate the reasoning
Closes gap #3 (maalbilde §5): the GroupChat checker critiqued into the void —
output_from=[proposer] surfaced only the proposer, so an explicit checker
rejection was ignored and the deterministic validator was the sole gate. Two
falsifiers now act on the same candidate: the validator gates the NUMBERS
(blocking, unchanged), the checker gates the REASONING (maalbilde §2/§6).

- workflow.py: output_from=agents surfaces both participants; the checker
  instruction ends with a VERDICT: APPROVE / VERDICT: REJECT - <reason> line.
- run.py: _authored_texts() reads author_name through out.messages (MAF 1.9.0
  puts it there, not on the AgentResponse); _debate_text() now selects the
  PROPOSER-authored output (fixes a latent texts[-1] regression that would feed
  the checker's verdict to generation at even round counts); _checker_verdict()
  parses the gate decision. An explicit REJECT overrides an otherwise-validated
  outcome to a checker-sourced Rejection. Opt-in-reject (fail-open on a missing
  marker). RunResult gains checker_verdict; provenance.validator_decision is
  stamped from the validator outcome BEFORE the override, so it never conflates
  the two falsifiers (provenance honesty).

Load-bearing (maalbilde §7): tests/test_checker_gate_loadbearing.py is a PAIR —
an explicit checker REJECT on a VALIDATOR-VALID proposal yields a Rejection whose
reason carries the checker's reason while validator_decision stays "validated";
the causality control (checker APPROVE, same proposer) validates normally. Proven
RED on BOTH detach points (revert output_from, or drop the override).

Suite 134->136 passed, 4 skipped; mypy + ruff check clean. Pre-existing
ruff-format drift (backends/budget/verdicts/test_contracts) left untouched for a
surgical diff.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-30 07:24:30 +02:00
8814a698c2 feat(fase2b): OKF-navigated bundle context replaces chunk-stuffing
Closes the honest Fase 2a limitation: docs_dir==bundle_dir let keyword
chunk-stuffing leak the verdict's realization rate ("0.82") into the debate /
generation prompt regardless of the ExpeL fold (it surfaced from both
verdict-led-fro.md AND golden.json). The realization signal now reaches the
hypothesis prompt ONLY via the gated ExpeL fold.

- okf.py: bundle_context() + Bundle.context_files render the navigated bundle
  (index + frontmatter + cross-links) as the agent read-context, EXCLUDING
  type: verdict (maalbilde §2/§4). Pure stdlib, still MAF-free.
- datasource.py: bundle_citations() derives first-class citations from the
  navigated non-verdict files.
- run_project: on the bundle path context + citations + debate tools come from
  navigation (tools=[]; navigation replaces query-time RAG); the road path keeps
  chunk-stuffing unchanged.

Load-bearing (maalbilde §7): the marker is upgraded from the minted verdict id
to the realization signal itself. The empty-store control now asserts "0.82"
reaches NO prompt — RED against the pre-2b chunk-stuffing path, green after
navigation (TDD red->green). New okf-level test_bundle_context_excludes_verdict_layer
guards the seam directly.

Suite 133->134 passed, 4 skipped; mypy + ruff check clean. Reverted unrelated
ruff-format drift (backends/budget/verdicts/test_contracts) to keep the diff
surgical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-30 06:42:19 +02:00
812db2363e docs(shared): conform bygg-energi-mikro to the shared OKF spec (okf_version 0.1)
Cross-coordination with the marketplace OKF convention
(ktg-plugin-marketplace/catalog/docs/okf-second-brain/spec.md v0.1). The
bundle already passed the shared acceptance gate; the one spec MUST-gap was the
root index okf_version marker (spec §3). Added it.

Verified: `node catalog/scripts/okf-check.mjs <bundle>` -> okf_version: 0.1,
"OK: valid OKF bundle", exit 0. Bundle-consuming tests green (14).

Scope note (honest): portfolio-optimiser uses OKF for framework per-project
runtime knowledge, NOT the user "second brain" the marketplace convention is
scoped to. Same FORM (now conformant + gate-clean), different SCOPE. Two
recommended `resource` warnings left deliberately (spec §4 sanctions omission;
no canonical URI to assert without fabricating). The index.md frontmatter is a
known deviation from spec §6 (reserved index = no frontmatter) kept for now
because okf.py navigation classifies the index by its type.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-29 14:50:04 +02:00
d6d83d42b5 feat(fase2): wire Step-1 ExpeL retrieval into the hypothesis prompt
Closes maalbilde §5 gap #1 (the one missing "feedback-into-prompt" dataflow)
for the OKF-bundle path. Before, ExpeL was computed AFTER generation into a
discarded SessionContext, so a prior verdict could not influence any hypothesis
(context_providers=0).

- New okf.py: framework-neutral OKF bundle navigation (index + frontmatter +
  cross-links), pure stdlib, no agent_framework/mcp (D7-portable), enforced by
  test_okf_is_maf_free.
- verdicts.py: seed_store_from_bundle + bundle_candidate_features build the
  ExpeL substrate + the pre-hypothesis query key from a bundle.
- run_project(bundle_dir=...): folds the candidate's prior verdicts into the
  generation context BEFORE generate_via_llm; the road path is unchanged.

Load-bearing (maalbilde §7): test_step1_expel_loadbearing proves a prior verdict
reaches the hypothesis prompt and goes RED when the fold is detached (shown via
TDD red->green). The marker is the minted verdict id (content hash) because
docs_dir==bundle_dir lets keyword chunk-stuffing leak the realization rate;
clean layer separation is Fase 2b.

Suite 121->133 passed; mypy + ruff check clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-29 10:56:48 +02:00
2b1a1832ef docs(claude-md): compress communication-patterns block (−93 always-tok)
CLAUDE.md loads every turn while working in this repo (776 always-loaded
tokens). The file is otherwise lean (project context + conventions +
workflow invariants, all kept). The one verbose block was the
"Linking to local files" section: a 3-bullet rule plus a "Why" paragraph
and a 2-line worked example with full absolute paths. Compressed to a
single sentence that keeps the rule (named markdown links, absolute paths,
one bullet per file) and the reason (bare file:// renders only the first
as clickable). 50→36 lines, 776→683 tok. Docs-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01683eAqVecv9VZfQzL8CQ9h
2026-06-29 10:25:49 +02:00
cbc7a22c78 docs(shared): bygg-energi mikro-eksempel — OKF-bundle + golden + load-bearing test
Persistent dev-fixture for energieffektivisering (energiledelse/M&V), valgt for
sin lærings-overflate: gapet mellom modellert besparelse (validatoren regner) og
faktisk realisert besparelse i drift (eksperten kjenner) — det ExpeL skal lære.

Ett kontorbygg, ett LED-retrofit-tiltak. OKF-bundle (index/project/hypothesis/
methodology/reference/verdict) bærer kontekst-laget; verdict-led-fro.md koder
realiseringsgraden (RR ≈ 0,82, forankret i National Grid SBS 2010) som ExpeL-frø.

Energi mappet inn i den EKSISTERENDE kost-IR-en uendret (affected = byggets totale
energikostnad, claimed = modellert besparelse ~10 % < 30 %-cap), så validatoren
kjører som-den-er — src/ urørt. golden.json fryser de seeded percentilene; testen
beviser at fixturen er konsumerbar (validerer, ikke Rejection), ikke bare til stede.

Domenetall verifisert mot primærkilder (EVO/IPMVP, DOE/NREL UMP, CPUC, fire
evalueringsstudier); norsk energipris mot SSB Q1 2026. README + shared/README
oppdatert (eksempel finnes, ikke lenger "planned"). Suite 121/4, ruff+mypy rene.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE
2026-06-29 09:42:13 +02:00
dd8529e132 docs(shared): konsept-notat til norsk (Forgejo-publikum = norsk marked)
Operatørens private Forgejo retter seg i praksis mot det norske markedet;
konseptnotatet er reader-facing for norske forretningslesere, så norsk gjør det
mer tilgjengelig. README (dev-facing shared-core-kontrakt) holdes engelsk inntil
videre.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 21:31:02 +02:00
65e4f5d9e4 docs(shared): framework-neutral concept note + shared-core contract
First artifact in the framework-neutral shared core (R1 effectuated). CONCEPT.md
is a plain-language business description of the method for a non-specialist
audience; README.md documents the shared-core contract (consumed unchanged by
both the MAF impl and the future Claude Agents SDK sibling; extract to commons
repo via git subtree split when sibling work starts). English per the repo's
documentation-language convention + open-publish intent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 21:26:45 +02:00
7df6a66712 docs(maalbilde): konsolidert agentisk-loop baseline + OKF-kontekstarkitektur
Nordstjerne fra design-samtale 2026-06-26. Konsoliderer: 8-stegs sverm-loop,
trelagsmodell (OKF-kontekst/output-inbox/promoteringsgate), to feedback-
tidsskalaer (kort synkron + lang fil-basert/gjenopptakbar), OKF/LLM-Wiki
datagrunnlag (web-verifisert mot Google knowledge-catalog), den samlende
diagnosen (tilbakemelding-inn-i-prompt-dataflyt mangler 3 steder), invarianter,
testbar "ferdig", delt eksempel for begge repo, fase-nedbrytning. 2 Mermaid-
diagrammer. STATE peker hit. R1 besluttet (shared/-dir nå). Domene lener mot
energieffektivisering (lærings-overflate > FinOps' for-deterministiske kjerne).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 20:56:14 +02:00
129a40baea docs(fot-i-bakken): ground-truth-verifisert levert-vs-lovet — agentiske lag inerte
Fot i bakken før fase-valg (Fase 4 vs D7). Explore-agent kartla; hovedkontekst
selv-verifiserte de konsekvensrike funnene mot kildekoden:

- ExpeL-laeringssloyfa ER APEN: retrieval naar aldri modellen (generering run.py:194
  for retrieval run.py:216-221; sctx run.py:219 forkastes; 0 context_providers i src/).
- README 'Not yet usable' (README.md:5) motsier 'Fase 1-3 lukket' — release-blokkerende.
- Maker-checker-checker gater ingenting (modulo-selector workflow.py:93-96).
- Ingen ekte-modell-kjoring (alle 4 skip = live-provider). Ingen SKILL.md. Ingen entry-point.

Deterministisk ryggrad (validator/budsjett/provenance/sti-sikkerhet/onboarding) holder.
Neste: operatorbeslutning — lukk kjerne-gjeld (A) vs aerlig nedgrader+release (B).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 15:25:03 +02:00
55f98f2af7 docs(fase3): remediation plan for the 2 /trekreview MAJOR findings (F1+F2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 15:07:48 +02:00
a7c69dbd55 test(fase3): portfolio rejection arm + provenance-seam assertions (F2 + F1 follow-up)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 15:05:41 +02:00
e0f93dfa7b fix(fase3): stamp real proposer model into provenance, kill fake-model leak (F1)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 15:03:45 +02:00
4253dd6388 review(fase3): /trekreview WARN — 2 MAJOR (provenance fake-model + rejection-arm utestet)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 14:08:34 +02:00
207f057075 docs(fase3): extension-point guide (add project / data source / model-map) + SC6 test 2026-06-26 12:16:01 +02:00
ac49b0795f fix(fase3): relax hardcoded project-count assert in spike test (SC1 4th-project follow-up) 2026-06-26 12:14:34 +02:00
0020776b26 test(fase3): SC1 new project via config-only + no-hardcoded-id src guard 2026-06-26 12:13:44 +02:00
dd4a6ef4af test(fase3): SC7 both profiles offline + gated Azure portfolio arm 2026-06-26 12:10:04 +02:00
66065053b1 test(fase3): SC3 load-bearing meter-isolation detach guard 2026-06-26 12:07:28 +02:00
70ab2e6555 test(fase3): SC4 shared-store accumulation + load-bearing cross-project retrieval 2026-06-26 12:04:28 +02:00
6119e85e6a fix(fase3): mypy-clean single-arg joinpath in reference_domain loader (Step 2 follow-up) 2026-06-26 12:02:31 +02:00
52f6f65b7d feat(fase3): run_portfolio sequential orchestrator + PortfolioResult aggregate 2026-06-26 12:02:08 +02:00
c7c42eeb75 feat(fase3): config-driven docs_dir + verdict_input on Project loader 2026-06-26 11:55:21 +02:00
8b64c7f8de feat(fase3): additive meter= seam on run_project (SC3 detach hook) 2026-06-26 11:51:25 +02:00
497399e0aa docs(fase3): /trekplan — implementation plan (8 steps; plan-critic APPROVE_WITH_NOTES + scope-guardian ALIGNED) [skip-docs]
8-step TDD plan composing run_project into a sequential run_portfolio orchestrator.
3 authorized one-time core seams (meter=, config docs_dir + verdict_input); load-bearing
SC3 meter-detach guard + SC4 overlap-ranking; SC7 resolve_model teeth. Both majors from
plan-critic (SC4 fixture magnitudes; Step 3/4 coupling) folded in via the REPLIES table.
gemini Pass 2 unavailable (Gemini-API deprecation, operator-side tooling).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 11:41:58 +02:00
4cdd172522 docs(fase3): /trekbrief — fan-out brief (PROCEED, gate 6/6) [skip-docs]
Fase 3 brief: sequential fan-out orchestrator over N portfolio projects,
reusing the single-project run_project seam. Four operator design decisions
locked via interview: isolate execution-state per project but SHARE one
VerdictStore (ExpeL accumulates across the portfolio); sequential (concurrency
= documented extension point); fixed config-list topology (resolves plan §12
open decision); list-of-RunResult + thin aggregate output. 0 research topics
(all internal; MAF concurrency already spiked in Fase 1 + de-scoped).

brief-reviewer (opus) → PROCEED on first iteration, all 6 dimensions pass
(completeness 5, consistency 4, testability 4, scope 5, research 5, memory 5).
Folded in its PROCEED-level refinements before finalize: per-project docs_dir
MUST be config-driven or SC1 breaks; SC7 given a concrete parametrised-test
assertion; SC5 baseline made relative (current+new, not a guessed 103); SC3
detach encodable as an automatic guard; SC4 fixture must yield overlapping
features; new synthetic project flagged AI-authored (user-not-domain-expert).
Validator: valid, 0 warnings. phase_signals: plan/execute/review = high/opus.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 11:01:01 +02:00
fc167deb59 docs(fase2): trekreview review.md — verdict ALLOW (0 funn), Fase 2 LUKKET
Remediation review of scope 6ef4efc..01c3f0d (high-effort, both reviewers).
Two independent reviewers (brief-conformance + code-correctness) each returned
zero findings after verifying the load-bearing detach criterion against the
actual code and the installed MAF source — explicitly refusing to treat the
green suite (103 passed / 3 skipped, offline) as evidence. All 7 actionable
original findings (2 BLOCKER + 5 MAJOR) confirmed RESOLVED:
  F1 debate→generation (test_g), F2/F5/F8 BudgetMiddleware (test_h +
  test_budget.py:70; conftest re-base verified necessary vs _clients.py:214-231),
  F7 retrieval-tool exposure (spy tests). Coordinator verdict: ALLOW.
Standing items (not findings): F9 MINOR deferred, SC9 real-profile coverage,
retrieval-exposed-not-invoked, strict_usage fail-closed untested offline.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019any9zfGNNwWJPX5Zq2QRz
2026-06-26 10:03:38 +02:00
01c3f0dc8a docs(fase2): remediation plan (Handover 6) — consumes 2 BLOCKER + 5 MAJOR 2026-06-26 00:46:23 +02:00
b4f00bf0ca style(fase2): ruff-format the re-based synthetic client (Step 1 follow-up) 2026-06-26 00:45:54 +02:00
bbb991b23e docs(fase2): record PEP 735 dependency-groups as intentional Step 1 deviation 2026-06-26 00:43:46 +02:00
fb58f9a23d docs(fase2): add env.template documenting both profiles + no-egress notes 2026-06-26 00:43:26 +02:00
7b08b37da3 test(fase2): assert BudgetMiddleware short-circuits a real chat call + the debate 2026-06-26 00:42:51 +02:00
1694141bff feat(fase2): feed debate converged output into candidate generation 2026-06-26 00:40:44 +02:00
7573c4439f feat(fase2): wire BudgetMiddleware + retrieval tool onto the debate in run_project 2026-06-26 00:37:45 +02:00
434ecb92c9 feat(fase2): thread tools + budget middleware through fresh_workflow onto agents 2026-06-26 00:36:06 +02:00
bf0bbfffae test(fase2): re-base synthetic client on layered client so chat middleware fires 2026-06-26 00:34:06 +02:00
6ef4efcdd1 docs(fase2): trekreview review.md — verdict BLOCK (2 BLOCKER, 5 MAJOR, 1 MINOR)
Independent post-hoc review (high-effort) of the Fase 2 vertical slice
(scope 9973d9f..308b553, 32 files). Two independent reviewers converged,
ground-truth-verified against source:

- F1 BLOCKER (run.py:124): maker-checker debate output discarded; the
  validated proposal comes from a separate generate_via_llm call.
- F2 BLOCKER (budget.py:81): BudgetMiddleware defined+tested but never
  wired onto the debate; the NFR short-circuit path is absent.
- F7/F3/F4/F8/F5 MAJOR, F9 MINOR.

The slice's three load-bearing seams are built + unit-tested but not
connected by the orchestrator; the green e2e suite asserts proposal
shape only. Fase 2 not closed — awaits operator decision.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 15:10:07 +02:00
308b5539e2 test(fase2): gated live local + Foundry profile checks 2026-06-24 14:02:44 +02:00
156df15417 test(fase2): end-to-end vertical-slice integration suite 2026-06-24 14:01:28 +02:00
4e87e473e4 fix(fase2): mypy-clean src — typed workflow factory + third-party stub config 2026-06-24 14:01:27 +02:00
7491367fb6 feat(fase2): vertical-slice orchestrator + two-layer HITL wiring 2026-06-24 13:54:54 +02:00
36606ebee7 feat(fase2): fail-fast contract loaders 2026-06-24 13:50:28 +02:00
0abc7083df feat(fase2): LLM->IR generation with validator-as-retry 2026-06-24 13:48:54 +02:00
a0a8edd58c feat(fase2): fresh_workflow factory + maker-checker GroupChat 2026-06-24 13:41:30 +02:00