fix(maf): en vakt som gikk inert i STILLHET, funnet ved aa loefte pinnen (F15, ORDRE 20260829T155150Z)
MAF core 1.9.0 -> 1.16.0, orchestrations 1.0.1 -> 1.1.1. De to kan ikke loeftes hver for seg: orchestrations 1.1.1 krever selv core>=1.15.0. Iron Law: vakt-testen kjoert ROED mot 1.9.0 (2 failed) FOER pinnen ble roert. Gulvet bor i EN konstant og pyproject-asserten deriverer sin streng fra den. NEVNER: 16 private/ugaranterte former, derivert fra repoets EGNE siteringer, alle 16 sjekket mot begge versjoner, 2 endret seg. Kjent-positiv: MiddlewareFailure flippet NO -> YES. KP-kandidaten _compaction.py ble FORKASTET (teller 0 i begge, diskriminerer ingenting). DEN FARLIGE ENDRINGEN er den ordren navnga - formen som fortsatt importerer, men har flyttet semantikk i stillhet. En park skriver naa TO checkpoints og bare EN baerer plan-review-typen, saa en feildeklarert _ALLOWED_CHECKPOINT_TYPES toemmer ikke lenger listingen: den taper nOEyaktig den checkpointen som betyr noe, get_latest returnerer den ANDRE, og _parks `latest is None`-vakt passerte mens kjOEringen svarte rc=0 og skrev et spOErsmaal som aldri kan baere svaret. Vakten sjekker naa EGENSKAPEN den alltid mente (request_id in pending_request_info_events - et DEKLARERT felt) i stedet for symptomet som pleide aa innebaere den, og fjerner dermed en privat avhengighet i stedet for aa legge til en. ExperimentalWarning-paret P4 pkt. 2 betalte for aa BEHOLDE er borte fordi MAF sluttet aa sende det: _feature_stage.py emitterer ved FOERSTE BRUK, ikke ved import. Goldenens stderr regenerert som BESLUTNING (fire -> to linjer); site-packages- maskeringen BEHOLDT (spannet er ubebodd, ikke pensjonert). Load-bearing MAALT mot HELE suiten, gronn kontroll 1089/5, stdout BYTE-UENDRET (ea8c534773acdbe41ae68f2c55724d69aaf8be4f): M1 revert av vakten -> 1 rod. EN mutasjon ble IKKE rod og staar som aerlighets-grense, ikke som gate: spikens checkpoint_ids[-1] er rekkefolge-avhengig (Path.glob), altsaa flaky. Rapport: docs/2026-09-02-f15-maf-pinnen.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
67eb8939d3
commit
ef2f1cbe61
15 changed files with 366 additions and 54 deletions
|
|
@ -1,4 +1,2 @@
|
|||
<SITE-PACKAGES>/agent_framework/_skills.py:121: ExperimentalWarning: [SKILLS] SkillResource is experimental and may change or be removed in future versions without notice.
|
||||
<SITE-PACKAGES>/agent_framework/_harness/_memory.py:651: ExperimentalWarning: [HARNESS] MemoryStore is experimental and may change or be removed in future versions without notice.
|
||||
|
||||
(arbeidskopi: <TMPDIR>/po-sim-<SUFFIKS>)
|
||||
|
|
|
|||
|
|
@ -250,9 +250,12 @@ async def test_s4_pending_plan_review_resumes_in_a_fresh_process(tmp_path: Path)
|
|||
assert first["request_id"], "no plan review was raised -- nothing to resume"
|
||||
assert first["outputs"] == []
|
||||
assert first["checkpoint_ids"], "no checkpoint was written -- the resume would be vacuous"
|
||||
# F15: the id must be the checkpoint that CARRIES the review, not the last entry of a listing.
|
||||
# Under core 1.16.0 a park leaves two checkpoints and only one of them can bear the answer.
|
||||
assert first["resume_checkpoint_id"], "no checkpoint carries the pending review"
|
||||
|
||||
resumed = run_resume_subprocess(
|
||||
str(storage), request_id=first["request_id"], checkpoint_id=first["checkpoint_ids"][-1]
|
||||
str(storage), request_id=first["request_id"], checkpoint_id=first["resume_checkpoint_id"]
|
||||
)
|
||||
assert resumed["outputs"] == ["FINAL: the worker did it."]
|
||||
assert resumed["pending_after_resume"] == 0
|
||||
|
|
|
|||
|
|
@ -903,7 +903,7 @@ def test_an_untraced_exploration_writes_nothing_to_stdout_or_stderr() -> None:
|
|||
|
||||
A subprocess and not ``capsys``, for the reason recorded above ``_CHILD_EXPLORATION`` — and the
|
||||
stakes are the pinned artefacts: ``tests/golden/demo-transcript.stdout`` is byte-fixed and the
|
||||
demo's stderr is fixed at four lines, so one stray span dump would break both.
|
||||
demo's stderr is fixed at two lines, so one stray span dump would break both.
|
||||
|
||||
``EXPLORATION-OK`` on stderr is the control. Without it, "stdout was empty" would be equally
|
||||
true of a child that crashed on import, which is the fourth face of the verification law: an
|
||||
|
|
|
|||
|
|
@ -17,8 +17,13 @@ program output, and both were measured to differ between a fresh clone and the w
|
|||
2. the temp directory behind ``(arbeidskopi: ...)`` — a fresh ``mkdtemp`` suffix every run, under a
|
||||
``TMPDIR`` that is per-user.
|
||||
|
||||
Both are masked; everything else is compared byte for byte. Pinned stderr is four lines: the two
|
||||
warnings, a blank line, and the ``arbeidskopi:`` line.
|
||||
Both are masked; everything else is compared byte for byte. **Pinned stderr is two lines: a blank
|
||||
line and the ``arbeidskopi:`` line — it was four until core 1.16.0 (F15, measured).** MAF moved the
|
||||
``ExperimentalWarning`` emission from decoration time to first USE (``_feature_stage.py``'s
|
||||
``_add_runtime_warning``), and the demo instantiates neither ``SkillResource`` nor ``MemoryStore``,
|
||||
so the two warning lines stopped being emitted upstream — they were never suppressed here. Span 1's
|
||||
``site-packages`` masking is KEPT for that reason: the span is currently unoccupied, not retired,
|
||||
and a warning that returns must still trip this pin with its path masked.
|
||||
|
||||
**The narrowness is the point, and it is under test.** P4 pkt. 2 damped the round-cap notices with a
|
||||
filter keyed on the MESSAGE precisely so that a NEW warning — from a MAF bump, or a subtree pull —
|
||||
|
|
|
|||
|
|
@ -22,25 +22,33 @@ import pytest
|
|||
|
||||
_DIST = "agent-framework-core"
|
||||
|
||||
#: F15 (2026-08-30): the floor lives in ONE place and the ``pyproject`` assert below DERIVES its
|
||||
#: expected pin string from it. Two literals for one fact drift (the kø-(p) rule), and a drifted
|
||||
#: floor is a guard that stops guarding without a local diff.
|
||||
_MIN_MAJOR = 1
|
||||
_MIN_MINOR = 16
|
||||
_MIN_VERSION = f"{_MIN_MAJOR}.{_MIN_MINOR}.0"
|
||||
|
||||
|
||||
def assert_supported_maf_version(version_str: str) -> None:
|
||||
"""Raise ``ValueError`` when ``version_str`` is outside the supported ``>=1.9.0,<2`` range, naming
|
||||
the private-API premises to re-verify before a bump. Pure string parse — no import side effects,
|
||||
so a fake version can be passed directly (the RED-proof) without touching the real install."""
|
||||
"""Raise ``ValueError`` when ``version_str`` is outside the supported ``>=1.16.0,<2`` range,
|
||||
naming the private-API premises to re-verify before a bump. Pure string parse — no import side
|
||||
effects, so a fake version can be passed directly (the RED-proof) without touching the real
|
||||
install."""
|
||||
parts = version_str.split(".")
|
||||
major = int(parts[0])
|
||||
minor = int(parts[1]) if len(parts) > 1 else 0
|
||||
if not (major == 1 and minor >= 9):
|
||||
if not (major == _MIN_MAJOR and minor >= _MIN_MINOR):
|
||||
raise ValueError(
|
||||
f"{_DIST} {version_str} is outside the supported range >=1.9.0,<2. Before bumping, "
|
||||
"re-verify the private-API premises the offline sim relies on: the _inner_get_response "
|
||||
"keyword-only signature (messages/options/stream) and the _build_response_stream "
|
||||
"construction. Update the pin in pyproject.toml once confirmed."
|
||||
f"{_DIST} {version_str} is outside the supported range >={_MIN_VERSION},<2. Before "
|
||||
"bumping, re-verify the private-API premises the offline sim relies on: the "
|
||||
"_inner_get_response keyword-only signature (messages/options/stream) and the "
|
||||
"_build_response_stream construction. Update the pin in pyproject.toml once confirmed."
|
||||
)
|
||||
|
||||
|
||||
def test_installed_maf_version_is_supported() -> None:
|
||||
"""T-2.5d: the real installed distribution (verified 1.9.0) passes the guard — read from
|
||||
"""T-2.5d: the real installed distribution (verified 1.16.0) passes the guard — read from
|
||||
``importlib.metadata.version``, NOT ``agent_framework.__version__`` (a 0.0.0 placeholder)."""
|
||||
assert_supported_maf_version(importlib.metadata.version(_DIST))
|
||||
|
||||
|
|
@ -53,13 +61,18 @@ def test_guard_rejects_future_major() -> None:
|
|||
|
||||
|
||||
def test_guard_rejects_too_old_minor() -> None:
|
||||
"""T-2.5d: a pre-1.9 minor (``1.8.0``) also trips the guard (the pin is two-sided)."""
|
||||
with pytest.raises(ValueError, match="private-API premises"):
|
||||
assert_supported_maf_version("1.8.0")
|
||||
"""T-2.5d / F15: the PREVIOUS floor (``1.9.0``) now trips the guard — the pin is two-sided, and
|
||||
this is the arm that makes the F15 lift measurable rather than asserted. ``1.15.0`` is rejected
|
||||
too: ``agent-framework-orchestrations`` 1.1.1 requires ``core>=1.15.0``, but 1.16.0 is the
|
||||
version whose private-API premises were actually re-verified."""
|
||||
for stale in ("1.8.0", "1.9.0", "1.15.0"):
|
||||
with pytest.raises(ValueError, match="private-API premises"):
|
||||
assert_supported_maf_version(stale)
|
||||
|
||||
|
||||
def test_pyproject_pins_agent_framework_core_below_2() -> None:
|
||||
"""T-2.5d: ``pyproject.toml`` pins ``agent-framework-core>=1.9.0,<2`` — the install-time half of
|
||||
the guard (the test above is the test-time half)."""
|
||||
"""T-2.5d: ``pyproject.toml`` pins ``agent-framework-core>=1.16.0,<2`` — the install-time half of
|
||||
the guard (the test above is the test-time half). The expected string is DERIVED from
|
||||
``_MIN_VERSION`` so the two halves cannot drift apart."""
|
||||
pyproject = (Path(__file__).resolve().parents[1] / "pyproject.toml").read_text(encoding="utf-8")
|
||||
assert "agent-framework-core>=1.9.0,<2" in pyproject
|
||||
assert f"agent-framework-core>={_MIN_VERSION},<2" in pyproject
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ def test_notice_is_omitted_when_tracing_is_off() -> None:
|
|||
"""T8a: no tracing → no line at all (``mandate.announce``'s rule).
|
||||
|
||||
The same rule ``cost_baseline_notice`` and ``skipped_links_notice`` follow, and it is
|
||||
load-bearing beyond style here: the pinned demo stderr is four lines, and a "tracing: off" row
|
||||
load-bearing beyond style here: the pinned demo stderr is two lines, and a "tracing: off" row
|
||||
would have made it five.
|
||||
"""
|
||||
assert tracing.tracing_notice(tracing.TracingSetup(mode=None, endpoints=())) is None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue