Commit graph

12 commits

Author SHA1 Message Date
8d1d29edf0 fix(ingest): narrow mcp_timeout to our OWN deadline, not the exception type (kø-z follow-up)
Advisor review of the prior commit (5269b7d) found the except TimeoutError
branch was wider than the brief asked for: builtin TimeoutError is also
socket.timeout (3.10+) and asyncio.TimeoutError (3.11+), so any TimeoutError
reaching that clause got relabeled mcp_timeout regardless of source. Gate on
anyio.CancelScope.cancelled_caught instead, mirroring _unwrap_ingest_error's
ownership rule (own it, wrap it; otherwise, untouched).

Measured: no live trigger exists today (MCP's own internal read-timeout
converts to McpError before reaching us; a server-side TimeoutError becomes
an ordinary isError result) -- pinned with a synthetic test raising from
StdioServerParameters construction, inside our fail_after scope but before
either nested task group, so it arrives ungrouped. Four mutations red against
the full 625-test suite: drop the translation, revert to asyncio.wait_for,
relabel the code, and drop the cancelled_caught gate.

Also promotes anyio to a declared direct dependency (was transitive via mcp
only) -- ingest_mcp.py now imports it directly.
2026-08-03 21:22:00 +02:00
8a8c4f0fca fix(s31): pin numpy <2.3 — >=2.3 breaks the >=3.10 floor and mypy stub parsing 2026-07-25 06:12:56 +02:00
440278a050 build(s31): add numpy dependency for hybrid verdict retriever 2026-07-25 06:07:07 +02:00
0a11af74a4 refactor(ingest): adopt shared llm-ingestion-okf v0.3.1 behind a thin adapter
Door A (manifest -> connector -> deterministic materialization -> index) is no
longer implemented here. src/portfolio_optimiser/ingest.py becomes a thin
consumer seam over the shared library, git-pinned to v0.3.1 on the same Forgejo
channel portfolio-optimiser-claude uses. Net -626/+385; ingest.py 599 -> 145 lines.

shared/ingest-spec.md remains the normative spec: the library implements it, it
does not replace it. Spec changes continue to go via commons.

Acceptance criterion met and proven: all three golden bundles (file/sql/http)
are byte-exact before and after, including the idempotence re-run. examples/ and
shared/ carry ZERO modifications -- the fasit was not adjusted to fit.

The rejection set was verified equivalent, not assumed: all 22 malformations the
repo's pydantic models refused are refused by the library, with typed codes
(okf_type_reserved, credential_embedded, extraction_id_duplicate, ...).

Test rebinding (invariants preserved, vehicle changed): the library has zero
runtime dependencies by design, so pydantic is unavailable to it.
ManifestV1.model_validate(dict) -> load_manifest_bytes(bytes); ValidationError ->
ManifestError; model_fields -> dataclasses.fields; PathSecurityError ->
SourceError(path_escape); ValueError -> MaterializationError(ingested_at_invalid).
Tests now also pin the refusal `code`, the library's documented stability
contract -- a sharper assertion than "some validation error was raised".

Two accepted behavioural deltas, recorded rather than silently dropped:
- Title whitespace is stored verbatim instead of collapsed at validation, so the
  frontmatter title and the index label are no longer guaranteed identical for
  irregular whitespace. Both behaviours are spec-conformant (the spec is SILENT;
  the old one was a repo-local pinned decision). Queued as a commons-amendment
  candidate so both stacks pin the same answer. Goldens unaffected.
- The section 8 audit log moves to logger llm_ingestion_okf.materialize. Nothing
  in the repo consumed the old channel.
Also: the `type` discriminator is no longer a dataclass field, so the spec
cross-check asserts it explicitly -- without that line the swap would have
silently narrowed the test.

New tests/test_ingest_library_seam.py pins the seam itself: the restated section 5
stamp formula against the stamp the library actually writes (the one place the
adapter does not purely delegate, since v0.3.1 exposes no stamp helper), the
local-only allow_network default, the list[Path] unwrapping, and a guard that the
adapter never regrows local Door A machinery. All four verified RED when detached,
as were both golden regressions under a byte-level render mutation.

Door A is UNGATED: it calls no guard before writing to disk. Gating untrusted
content remains the caller's responsibility (guard wiring still planned).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4jNN186eVqfe1x5DnTU6r
2026-07-20 07:47:55 +02:00
82c85d5e7c fix(s41): pass required credential in AzureFoundryBackend.create_chat_client 2026-07-15 11:18:40 +02:00
73c24fc69a feat(fase2a): MAF version-guard (test-tidsvakt, dist-metadata) + pin agent-framework-core<2 (S2.5) 2026-07-15 07:28:40 +02:00
bbb991b23e docs(fase2): record PEP 735 dependency-groups as intentional Step 1 deviation 2026-06-26 00:43:46 +02:00
4e87e473e4 fix(fase2): mypy-clean src — typed workflow factory + third-party stub config 2026-06-24 14:01:27 +02:00
99f0dd79fe build(fase2): promote orchestrations + pulp to core deps 2026-06-24 13:22:04 +02:00
ffbfe00317 build(fase1): add dev orchestration + solver + async deps, scaffold spikes 2026-06-24 09:57:57 +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
ec9ac74976 feat: initial scaffold (Python framework on Microsoft Agent Framework)
Plan-fase: repo-skjelett, dokumentasjon (research + inkrementell plan),
Python/uv-oppsett, MAF-avhengighet. Ingen rammeverkskode ennå.

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