chore(release): 1.0.0 version sync + the six undocumented feat commits, tag deliberately withheld
Version 1.0.0 across the four sites that carry it — pyproject.toml, __init__.py, uv.lock, test_smoke.py. Measured that these are the only four: README carries no version badge, and CHANGELOG's `## [0.1.0]` is history rather than a bump site. The heading stays `[Unreleased]`. STATE authorises the CHANGELOG CONTENT now and holds the TAG until after Wednesday's freeze, so stamping `## [1.0.0] - <date>` today would be a future-dated claim about an event that has not happened — and one to rewrite if the dress rehearsal fails or the freeze slips. `pyproject` at 1.0.0 with `[Unreleased]` populated is the release-prep state, not an inconsistency; nothing machine-reads the CHANGELOG (measured). The global versjonssync rule is read as CONTENT, not heading. Tag day is then one atomic move: rename the heading, stamp the date, tag. The re-lock was the hazard, and it was gated rather than assumed. Bumping the version stales `uv.lock`, and the next `uv run` would have re-locked it invisibly against a RANGE dependency (`agent-framework-core>=1.9.0,<2`) — while the two ExperimentalWarning lines are pinned byte-for-byte in the stderr golden, and STATE's own okf note records that a bare sync is enough for a guard to stop guarding with no local diff. So: bump, then `uv lock` EXPLICITLY, then diff before any test ran. The diff is the single `portfolio-optimiser` version line; agent-framework-core, llm-ingestion-okf (v0.3.2) and llm-ingestion-guard (v0.3.4) are untouched, and uv.lock was re-checked AFTER the suite to confirm no silent re-lock. CHANGELOG prose for the six feat commits `[Unreleased]` did not cover — it carried only Step 5 and the scripted registry. Console entry points and the golden transcript are Added; the Step-7 inbox, the anchored walkthrough, the stderr damping and the derived provenance sentence are Changed, scoped as the OFFLINE SIMULATION rather than framework runtime, since they change what the walkthrough exercises and not the library's behaviour. The content gate is Security, and carries its opt-in qualifier: `materialize` stays ungated by design and `materialize_gated` is asked for by name — an entry claiming "ingest now scans content before writing" without that clause would overclaim, and it sits next to the sentence read on stage Thursday. A Notes line names the two open boundaries (ingest stamp spec divergence, D7 mirroring) so 1.0.0 reads as a stable surface rather than a finished programme. Measured, not asserted: 810 passed / 4 skipped unchanged · ruff + mypy clean (31 source files) · no `0.1.0` remaining outside .venv/shared · and the demo RUN, not just tested — stdout byte-identical to tests/golden/demo-transcript.stdout, exit 0, 61 stdout / 4 stderr lines, matching dress rehearsal nr. 0. The version string appears nowhere in either golden (0 hits), so the bump could not move the fasit. Two STATE premises corrected by measurement: 24 commits since v0.1.0, not 23; and eight feat commits exist since the tag, of which six were undocumented. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ue1AnPZYsC9Tk7e5Tyv8Fv
This commit is contained in:
parent
887a8be677
commit
a41272def5
5 changed files with 69 additions and 4 deletions
65
CHANGELOG.md
65
CHANGELOG.md
|
|
@ -12,6 +12,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
falsifications that informed a later attempt, surfaced on `RunResult.refinements`. The offline
|
||||
simulation exercises it — the scripted proposer overclaims, the deterministic validator falsifies
|
||||
the number, and the refined proposal validates.
|
||||
- Two console entry points ship with `uv sync`: `portfolio-optimiser` (the CLI) and
|
||||
`portfolio-optimiser-demo` (the offline walkthrough). Deliberately two of the package's five
|
||||
`main()` functions — `costsim`, `hitl` and `preflight` stay operator tools invoked as modules, and
|
||||
every name here is one a release has to carry. Both invocation forms write byte-identical stdout.
|
||||
The entry points are tested against the INSTALLED distribution's metadata rather than the TOML: a
|
||||
`[project.scripts]` line that has never been synced is a claim, not a command.
|
||||
- The offline walkthrough's transcript is checked in as a golden fixture
|
||||
(`tests/golden/demo-transcript.stdout` and `.stderr`). Self-identity across two runs cannot detect
|
||||
a regression — two runs of a regressed walkthrough agree exactly as well as two runs of a correct
|
||||
one — so the fixture leaves the process. stdout is pinned verbatim; stderr is normalised on exactly
|
||||
two measured environment spans, the `site-packages` prefix and the temporary directory, leaving the
|
||||
`po-sim-` prefix visible because that belongs to the program rather than the environment. A
|
||||
companion control forbids the mask from widening: a normaliser that dropped whole lines, with the
|
||||
fixture regenerated beneath it, would keep both equality tests green.
|
||||
|
||||
### Changed
|
||||
- **Breaking (library API):** `generate_via_llm` returns `GenerationResult` instead of
|
||||
|
|
@ -25,6 +39,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
`simulate_learning_loop` takes `project_id` alongside `bundle_dir`. Adding a project to the
|
||||
walkthrough is a data entry. A prompt matching no entry — or more than one — raises
|
||||
`ScriptedCandidateError` rather than answering with another project's numbers.
|
||||
- The offline simulation now EXERCISES the Step-7 file inbox it narrates. The verdict previously
|
||||
arrived as a function argument — the short, in-run capture — while the trace line described the
|
||||
long file loop. An expert now writes a real verdict file into an inbox between the two runs, and
|
||||
the second run is given `verdict_dir=`, so `run_project` merges it before the Step-1 fold. The
|
||||
inbox sits beside the bundle copy and never inside it: a verdict file within the bundle would reach
|
||||
the next run as navigable context, which is a different mechanism wearing this one's clothes. The
|
||||
two time-scales carry SEPARATE markers by construction, since one marker on both paths would let
|
||||
either seam alone satisfy the assertion and leave the other free to rot; `simulate_learning_loop`
|
||||
refuses equal markers.
|
||||
- The offline walkthrough runs ANCHORED. Its deterministic gate reconciles each proposal against the
|
||||
project's real cost lines, which activates only when the knowledge base ships a `cost-baseline.json`;
|
||||
without one the gate reasoned solely about numbers the proposal supplied itself. The walkthrough now
|
||||
reads that file through exactly the seam a delivered knowledge base would use. For the synthetic
|
||||
fallback bundle, which cannot receive the file inside the pull-only `shared/` subtree, the baseline
|
||||
is DERIVED IN CODE from the scripted register rather than typed beside it — two sources of the same
|
||||
numbers drift, and drift is precisely what the walkthrough's own 10 % probe models. The declared
|
||||
baseline is printed, because an anchoring nobody can see is one nobody can check.
|
||||
- The walkthrough's stderr is quieter. The expected round-cap notice is dropped by a filter on the
|
||||
emitting logger, keyed on the message and installed by `main()` — never at import, so a library
|
||||
consumer keeps its own logging configuration. The two `ExperimentalWarning` lines are deliberately
|
||||
NOT damped: they fire while the package `__init__` imports the agent framework, always before the
|
||||
simulation's own imports and under both invocation forms, so silencing them would mean filtering
|
||||
warnings inside the library on every consumer's behalf. They are pinned in the golden fixture
|
||||
instead. stderr went from six lines to four.
|
||||
- The walkthrough DERIVES its provenance sentence for prior verdicts instead of stating it. The line
|
||||
above already computes the count, so a hand-written split would be a second copy of the same fact,
|
||||
free to drift the moment a knowledge base ships another seeded verdict.
|
||||
|
||||
### Security
|
||||
- Door A — the ingest path that materialises externally sourced documents into a knowledge base — can
|
||||
now scan generated content before it is published, through `ingest.materialize_gated`. The gate is
|
||||
**opt-in and requested by name**: `materialize` itself stays ungated by design, because golden
|
||||
suites pin its bytes and a caller that wants the gate asks for it.
|
||||
The seam sits *around* materialisation rather than inside it. The pinned upstream stages in memory
|
||||
and then performs its own disk phase, with no callback between the two, so a gate placed "at the
|
||||
write point" could only have run after the bytes had landed — a cleanup, not a gate. Instead the
|
||||
bundle is COPIED, materialised into the copy, scanned, and then published or discarded as a whole.
|
||||
The copy is load-bearing rather than convenient: the upstream's ownership scan, its collision gate
|
||||
against curated content, and its index merge all read the EXISTING bundle, so staging into an empty
|
||||
directory would publish a bundle stripped of its curated neighbours and their index links — data
|
||||
loss dressed as a security fix.
|
||||
Trust follows ORIGIN, never channel. The outcome is per BUNDLE, since partial publication would
|
||||
leave a bundle and index answering to no manifest, while diagnostics are per DOCUMENT so a single
|
||||
run reports every finding rather than only the first. Findings are written to the bundle's `log.md`
|
||||
and never to concept frontmatter, where four golden suites pin the bytes.
|
||||
|
||||
### Notes
|
||||
- The `1.0.0` version signals a stable public surface, not a finished research programme. Two
|
||||
boundaries are open and named rather than implied: the ingest stamp predicate has diverged from the
|
||||
upstream specification (a value literal here, a structured field upstream) and does not touch the
|
||||
run path, and the mirroring of several seams to the sibling implementation is outstanding.
|
||||
|
||||
## [0.1.0] - 2026-08-06
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[project]
|
||||
name = "portfolio-optimiser"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
description = "Generic framework on Microsoft Agent Framework for per-project cost-savings optimization"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ from portfolio_optimiser.run import (
|
|||
run_project,
|
||||
)
|
||||
|
||||
__version__ = "0.1.0"
|
||||
__version__ = "1.0.0"
|
||||
|
||||
__all__ = [
|
||||
# Portfolio orchestration
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ from portfolio_optimiser import __version__
|
|||
|
||||
|
||||
def test_version():
|
||||
assert __version__ == "0.1.0"
|
||||
assert __version__ == "1.0.0"
|
||||
|
|
|
|||
2
uv.lock
generated
2
uv.lock
generated
|
|
@ -1487,7 +1487,7 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "portfolio-optimiser"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core" },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue