Commit graph

52 commits

Author SHA1 Message Date
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
15e41dd1fa feat(fase2): wire local + Foundry profiles + model-map + env template 2026-06-24 13:38:43 +02:00
f981c51e0b feat(fase2): expose retriever as citation-bearing data source 2026-06-24 13:34:53 +02:00
3104e18b07 feat(fase2): real-UsageDetails token meter + budget middleware 2026-06-24 13:31:39 +02:00
22b039235a feat(fase2): VerdictStore + ExpeL + capture_verdict (two-arg, real SessionContext test) 2026-06-24 13:29:02 +02:00
a0f263bf41 feat(fase2): first-class Pydantic provenance stamp 2026-06-24 13:26:55 +02:00
ebe12a8675 feat(fase2): local-folder retriever core with path-security 2026-06-24 13:26:00 +02:00
bbba6e7337 feat(fase2): promote blocking validator + IR to src 2026-06-24 13:24:03 +02:00
99f0dd79fe build(fase2): promote orchestrations + pulp to core deps 2026-06-24 13:22:04 +02:00
9973d9fe58 docs(fase2): /trekplan — adversarial-reviewed implementation plan [skip-docs]
14-step plan composing the four Fase 1 spikes into a src/ vertical slice
(debate -> blocking validator -> two-layer HITL + provenance -> ExpeL learning),
deterministic-core-first, on real chat clients in both profiles. Grounded in the
3 research briefs + installed-1.9.0-source introspection (7 exploration agents).

Adversarial review: plan-critic REVISE (3 blockers/7 major/4 minor) -> all
addressed; scope-guardian ALIGNED (0 creep, 9/9 criteria mapped, 6/6 Non-Goals
honored). Key revisions: in-process retriever-as-tool MVP path (mcp dep
conditional/GA-only); two-layer HITL capture + stable Verdict.id minting;
extend_instructions retired by a REAL SessionContext test; TextSpan ownership +
wave re-ordering; budget None-as-hard-fail with synthetic-usage test double;
self_repair token-bound in the generate loop (validator.py frozen); global
stop-on-failure rule. gemini-bridge Pass 2 unavailable (MCP SDK broke).
plan-validator strict 0 errors. brief research_status pending to complete.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 12:58:33 +02:00
c72730941e docs(fase2): 3 /trekresearch briefs — installed-source-verified [skip-docs]
Topic 1 (HITL): native HITL is GA (ctx.request_info/@response_handler/
run(responses=); GroupChatBuilder.with_request_info → AgentApprovalExecutor),
but durable checkpoint-resume is fragile (open #5818/#6127/#6372 into 1.9.0)
→ capture verdict out-of-band in VerdictStore, defer checkpointing off MVP path.

Topic 2 (MCP citation): REVERSES brief lean — official server-filesystem cannot
cite (raw text + bare paths) → build thin custom local-folder MCP server
returning {file,locator,snippet,score} over a framework-agnostic in-process
retriever (D7 seam). Corrected docs error: ContextProvider(source_id) +
before_run/after_run + extend_instructions(source_id,...) DO exist in 1.9.0.

Topic 3 (local chat client): use OpenAIChatCompletionClient(base_url) NON-STREAMING
(not OpenAIChatClient/Responses) — installed, 0 new deps, UsageDetails None-safe
and populated non-streaming. Native OllamaChatClient is --pre fallback (spike-gated).
validator-as-retry mitigates weak small-model tool-calling; Intel-CPU = plumbing only.

All grounded in installed 1.9.0 source (source wins over Learn docs). Gemini
bridge unavailable (MCP SDK predates Google May-2026 API change).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 12:33:42 +02:00
78e03c3254 docs(fase2): /trekbrief — gated MVP vertical-slice brief (6/6) [skip-docs]
Fase 2 started. Brief for the MVP vertical slice (one synthetic project
end-to-end on MAF 1.9.0: debate -> blocking validator -> two-layer HITL +
provenance -> ExpeL learning) produced via /trekbrief from documented intent
(incremental-plan §Fase 2 + capability-map §1/§5 + Fase 1 findings), not live
Q&A per the project operating model. framing=preserve; phase_signals=high/opus.

Brief-reviewer gate passed 6/6 (all dimensions 5; verdict PROCEED_WITH_RISKS)
after 2 iterations: iter 1 flagged a no-op token-accounting criterion and a
false-positive on research-field order; 3 derivable refinements applied
(retargeted the UsageDetails assertion, added Open Questions for the concrete
local model + Foundry deployment names, added a topic-count note). Validator
green (0 errors/warnings).

3 research topics identified (gaps the capability-map did not resolve): native
HITL in MAF workflows, local_folder via MCPStdioTool + citation provenance, and
a real local-profile chat client (spikes used only FakeChatClient). Manual path:
stopped at the brief as a gated checkpoint; research must run before /trekplan.

.gitignore: ignore generated .html annotation + progress.json render-derivatives
under .claude/projects/ (the .md sources stay tracked).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 11:56:57 +02:00
2613a5183e docs(research): MAF 1.9.0 capability map — feature-utilization for Fase 2 [skip-docs]
Two independent grounded passes (installed-source introspection + official MS
Learn via MCP) produce a per-need adopt/keep decision table for using MAF
features well in Fase 2, instead of reinventing them.

Headline: Microsoft's Workflows "State Isolation" page documents verbatim the
exact footgun Spike B(b) found today — a reused Workflow accumulates agent
threads across runs; the fix is a fresh-instance-per-run factory. Our
fresh_workflow() IS the official pattern.

Key verdicts: ADOPT real UsageDetails token counts + a budget ChatMiddleware +
native builder round caps + GA @tool/MCP + observability; KEEP the hand-rolled
structural VerdictStore and inline validator (MAF memory/eval are the wrong
shape); ROLL a tiny role->deployment map (declarative is preview/not installed).
Corrections recorded: CLAUDE.md "Magentic experimental" stands at doc-level (no
code gate); Spike D extend_instructions is two-arg (source_id, instructions).

Skills answer: method-as-Skill yes (MAF consumes SKILL.md natively, experimental);
MAF-docs-mirror Skill no (rots vs live MCP); the digest lives in this map.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 11:36:26 +02:00
8c83fc5cfc docs(fase1): trekreview round-2 ALLOW — Fase 1 formally closed [skip-docs]
Independent post-hoc review (brief-conformance + code-correctness) of the
de-risk spikes against brief.md. Round 1 verdict was BLOCK (Spike B(b) fan-out
was a tautological counter); after remediation commit a2dff21 both reviewers
return 0 findings. Code-correctness reviewer verified the fan-out bleed fix
against MAF internals (AgentExecutor._session reuse + InMemoryHistoryProvider +
SessionContext.get_messages). Verdict: ALLOW. Fase 1 is clear to close.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 11:15:41 +02:00
a2dff210ce fix(fase1): spike B fan-out measures real conversation bleed, not a counter
/trekreview flagged the Spike B(b) fan-out experiment as BROKEN_SUCCESS_CRITERION
(BLOCKER): it asserted a per-client call_count reached 3 on a reused instance vs
1 on a fresh one — a tautology true for any un-reset mutable counter, independent
of MAF, that never exercised the real G2/B7 shared-Workflow state-corruption
footgun. It was a false-confirm of a de-risk assumption.

Rebuilt to observe genuine MAF thread state via the messages each participant
RECEIVES (new FakeChatClient.received_texts seam):
- shared_instance_conversation_bleed: a reused built ConcurrentBuilder Workflow
  accumulates the conversation across .run() calls — run N's participants receive
  runs 0..N-1's prompts/replies (measured [[p0],[p0,p1],[p0,p1,p2]], strictly
  monotonic) => genuine cross-run contamination.
- fresh_instance_conversation_isolation: a fresh instance per run gives each a
  clean thread => each participant sees only its own project ([[p0],[p1],[p2]]).

Assumption now CONFIRMED with a meaningful observable. findings-b.md gains a
Method note recording why it was rebuilt; README rows updated.

Also fixes the MINOR: a_groupchat.run_live now mkdirs the findings dir before
write_text so a post-disposal run does not lose the measured result.

Gate green: ruff check + format, mypy src, pytest 48 passed / 1 skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 11:09:55 +02:00
b81e22b637 docs(fase1): consolidate spike findings + confirm green quality gate 2026-06-24 10:35:33 +02:00
c1317689f1 style(fase1): ruff format spike modules 2026-06-24 10:34:27 +02:00
f7a36b59ac feat(fase1): spike D - verdictstore + expel retrieval [skip-docs] 2026-06-24 10:32:39 +02:00
85439646ec feat(fase1): spike C - blocking hybrid validator (IR/solver/monte-carlo) [skip-docs] 2026-06-24 10:28:19 +02:00
44111113fb feat(fase1): spike B - magentic unbounded + concurrent state isolation [skip-docs] 2026-06-24 10:22:02 +02:00
9b9a17e2ed feat(fase1): spike A - group chat maker-checker vs single-agent [skip-docs] 2026-06-24 10:13:23 +02:00
432476346c feat(fase1): shared spike harness + builder smoke (budget caps, fake client, live gate) [skip-docs] 2026-06-24 10:08:24 +02:00
ffbfe00317 build(fase1): add dev orchestration + solver + async deps, scaffold spikes 2026-06-24 09:57:57 +02:00
ffd3ad4dd7 docs: plain-text brief — goal + two approaches (MAF vs Claude Agent SDK) + learning goal
Framework-neutral narrative of what portfolio-optimiser aims to achieve and the
two hypothesised approaches to the same method. Claude Agent SDK paragraphs
corrected by the user: the SDK spans both emergent (one agent + subagents) and
explicit orchestration (hand-written or agent-authored workflow script with a
non-LLM validator gate). The real difference vs MAF is ready-made named
constructs vs building blocks — not emergent vs explicit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 09:21:31 +02:00
25bb07a46e docs(research): MAF vs Claude Agent SDK comparison + D7 sibling-impl decision
Verified comparison of Microsoft Agent Framework (ground-truth introspection of
installed agent-framework-core 1.9.0 + Microsoft Learn) and Claude Agent SDK
(Anthropic docs + npm/PyPI). Grounds decision D7: rebuild the same method on
Claude Agent SDK as a separate sibling repo, in sequence, sharing only the
spec + golden/conformance suite — not orchestration code.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fif1r1En5W542HbZV88yMH
2026-06-24 06:51:24 +02:00
8b1ff745b9 docs(fase1): Voyage brief + plan for de-risk spikes (A-D)
Planning-only artifacts (no code yet). Plan A- after adversarial review
(critic REVISE -> revised; scope MIXED -> addressed; 19 findings, 0 overlap).
Ground truth: agent-framework-orchestrations is a separate GA 1.0.0 pkg
(-> dev dep); core is 1.9.0; MAF orchestrations are async. Next: /trekexecute.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9FyyENxebxVThjrn9et8C
2026-06-24 01:09:35 +02:00
b57aa83a30 feat(fase0): synthetic reference domain (D4) + backend profile skeleton (D2)
Completes Fase 0 (skeleton & decision-lock):

- reference_domain.py + data/reference_projects.json: a synthetic
  "anleggskostnad" portfolio (3 fictional construction-cost projects with
  cost line items) as the framework's bundled reference input. Plain typed
  loader (frozen dataclasses); the JSON-Schema data-source *contract* (B5)
  is deliberately deferred to Fase 2.
- backends.py: Profile (azure|local) + ChatBackend Protocol seam +
  AzureFoundryBackend/LocalBackend stubs + get_backend() selector
  (fail-fast on unknown profile). Empty skeleton per D2 — create_chat_client
  raises NotImplementedError until live wiring in Fase 1. Return type is the
  MAF BaseChatClient (the common base of FoundryChatClient/OpenAIChatClient).

Quality gate green: ruff format + check, mypy (src) clean, 12 pytest passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9FyyENxebxVThjrn9et8C
2026-06-23 22:38:41 +02:00
491a746bba build(deps): pin GA MAF packages, drop [all] meta, add lockfile
The `agent-framework[all]` meta package pulls still-beta integrations
(azure-ai-search/cosmos/ollama/...) that force --prerelease and drag in an
ALPHA pydantic — unacceptable for the IR/validation layer (B1). Per the
official Semantic Kernel -> Agent Framework migration guide, install only
the packages we actually need:

- agent-framework-core / -foundry / -openai (all GA)
- pydantic pinned to stable 2.x (>=2.11,<3)

Resolves cleanly on the stable channel (pydantic 2.13.4, was 2.14.0a1).
Only remaining pre-release pin is Azure's own azure-ai-inference
(transitive via -foundry; no stable release exists yet). uv.lock committed
for reproducibility.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9FyyENxebxVThjrn9et8C
2026-06-23 22:34:54 +02:00