feat(3): flaten sier sant om seg selv, og to gater måler at den fortsetter å gjøre det
Fase 3 (AAA+ på publisert flate). Tre av planens premisser falt på måling og er rettet FØR handling, ikke etterpå: * GOVERNANCE-raden hadde feil tiltak. Planen sa «skriv den»; org-ops D11 sier én kanonisk fil som hvert repo LENKER, og filen er nå publisert (målt: HTTP 200 på open/repo-standard). Å skrive vår egen ville gjort oss til kopi nr. 12 av en fil D11-bølgen holder på å rydde vekk. README lenker den, i samme form som repo-mailbox bruker, og bus-faktor 1 står uttalt i den kanoniske teksten. * Release-objektet for v1.0.0 FINNES allerede på open/ (id 155, CHANGELOG-kropp, siden rendrer) — det som mangler er vedlegg, ikke objektet. * WARN RELEASE-STALE fyrer ikke, og kan ikke: regelen sammenligner utgivelse mot tagg og er strukturelt blind for repo med null utgivelser (org-ops hovedbok #18). Gaten var OK/20 sjekker FØR arbeidet startet, så den kan ikke tjene som verifikasjon for denne fasen. Bevisene er Forgejo-APIet, filinnholdet og ren-klon-kjøringen. A5-defekten rettet: env.template:21 sa at credential resolves via DefaultAzureCredential. Den har aldri gjort det — backends.py:149 konstruerer ManagedIdentityCredential eller AzureCliCredential, og Learns MAF-veiledning navngir den spesifikke credentialen NETTOPP for å unngå probing. En operatør som kopierte templaten ble fortalt at feil identitet ville bli brukt. To load-bearing gater (Iron Law: begge røde før fiksen, 2 failed / 7 passed): 1. env.template navngir de credentials backends.py faktisk konstruerer, og ingen linje utgir DefaultAzureCredential for å være mekanismen. LINJEFORANKRET, ikke delstreng: backends.py NAVNGIR klassen fire ganger i kommentarene som begrunner hvorfor den ikke brukes, så en fil-bred substring-gate ville vært rød på nøyaktig den prosaen den beskytter (repoets 08-09-klasse, fjerde gang). 2. README-ens wheel-filnavn bærer versjonen bygget stempler på fila. Uten den ville en versjonsbump stille etterlatt en publisert install-kommando som peker på en fil som ikke finnes. Hver positiv assert er paret med en KONTROLL på at det søkes etter noe som finnes — en ekstraktor som stille finner null lager en gate som bare kan bli grønn. MUTASJONER MÅLT MOT HELE SUITEN, begge røde på riktig test og på INGEN annen: gjeninnfør den usanne credential-påstanden (2 røde, 844 grønne) · la wheel-filnavnet drifte til 1.0.0 (1 rød, 845 grønne). Restaurert fra scratchpad + shasum -c mellom hver. Bumpen selv var den andre mutasjonen: pyproject 1.0.0 → 1.1.0 gjorde README-gaten rød alene, før README ble rettet. SECURITY.md: varslingsfrist (minst én minor-release og aldri under 30 dager mellom kunngjøring og fjerning, med sikkerhetskritisk fjerning som uttalt unntak). Støttetabellen er bevisst VERSJONSFRI — et release-nummer skrevet der ville drevet ved neste tagg, altså samme defektklasse som gate 2 fanger. CLAUDE.md beholdt på flaten med en engelsk innramming øverst (operatørvalg): den sier hva fila er for en fremmed. Innholdet er repoets sterkeste bevis på at hver beslutning er målt; å fjerne det ville fjernet bevis, ikke friksjon. Versjon 1.1.0 — synket i pyproject, __init__, test_smoke og README-kommandoen. 1.0.0-treet kan ikke produsere en kjørbar wheel (force-include kom etter taggen, målt: git show v1.0.0:pyproject.toml har den ikke), så en wheel hengt på den utgivelsen ville vært nøyaktig den usanne påstanden denne fasen finnes for å fjerne. Operatøren valgte bumpen framfor et vedlegg som ikke virker. 846 passed / 4 skipped (fra 837). ruff + format + mypy rene. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011ckyg3Pc6k7FRuR6fDGQLJ
This commit is contained in:
parent
9a869baf8a
commit
28a420ab97
10 changed files with 246 additions and 10 deletions
50
CHANGELOG.md
50
CHANGELOG.md
|
|
@ -5,6 +5,56 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.1.0] - 2026-08-14
|
||||
|
||||
The release that makes the distribution stand on its own. `1.0.0` shipped a framework that could
|
||||
only run from a checkout; this one runs from an installed wheel and inside a Foundry-hosted
|
||||
container, and it is the first release whose artefacts are published alongside it.
|
||||
|
||||
### Added
|
||||
- `shared/` now travels **as packaged data**. The wheel carries a byte-identical mirror of the tree
|
||||
under `portfolio_optimiser/_shared/`, and `shared_root()` resolves at call time in a fixed order:
|
||||
`PORTFOLIO_SHARED_ROOT`, then the working tree's `shared/` when one exists, then the packaged
|
||||
copy. The working tree stays authoritative in a checkout — that is what keeps the pull-only
|
||||
subtree contract and the byte-exact goldens untouched. Measured before and after: the `1.0.0`
|
||||
wheel carried 58 files and none under `shared/`; this one carries 122, of which 64 are the mirror.
|
||||
- A **hosted entry point**: `main.py` wraps `run_project` on a single asyncio loop and serves the
|
||||
Foundry hosting contract (`GET /readiness`, `POST /invocations`, SIGTERM → exit 0), with a
|
||||
`Dockerfile` and `azure.yaml` beside it. The invocation payload is whitelisted against
|
||||
`run_project`'s own signature — an unknown field is refused by name with a 400 rather than
|
||||
silently dropped — and a rejected proposal is a successful run (200), because the negative outcome
|
||||
belongs to the payload and never to the transport.
|
||||
- Wheel-install instructions in the README. A wheel is not installable on its own: two dependencies
|
||||
are pinned to git tags, and `[tool.uv.sources]` does not travel with wheel metadata, so both must
|
||||
be supplied as requirements alongside the wheel. The published command is the one that was
|
||||
measured (65 packages, exit 0), not one composed afterwards.
|
||||
- Two gates on claims the **published surface** makes about itself: that `env.template` names the
|
||||
credentials `backends.py` actually constructs, and that the README's wheel-install command spells
|
||||
the version the build stamps on the file. Both read raw text and are line-anchored, because prose
|
||||
is the only place these claims live.
|
||||
|
||||
### Changed
|
||||
- The AZURE profile now reads **its own environment** rather than the operator's laptop. The
|
||||
endpoint resolves to the first non-empty of `PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT` and Foundry's
|
||||
injected `FOUNDRY_PROJECT_ENDPOINT`; precedence applies to *values*, so an exported-but-empty name
|
||||
falls through instead of masking a real one. The credential follows the same environment:
|
||||
`AzureCliCredential` on a developer host, `ManagedIdentityCredential` when
|
||||
`FOUNDRY_HOSTING_ENVIRONMENT` holds a non-empty value — never `DefaultAzureCredential`, whose
|
||||
probing would walk a credential chain that cannot succeed in a container and turn a config error
|
||||
into a slow one.
|
||||
- `SECURITY.md` states a **deprecation notice period**: at least one minor release and no fewer than
|
||||
30 days between announcement and removal, with security-critical removals named as the explicit
|
||||
exception. The supported-versions table is deliberately version-free, since a release number
|
||||
written there would drift at the next tag.
|
||||
- The README links the organisation's single canonical `GOVERNANCE.md` instead of vendoring a copy,
|
||||
and states the maintenance model (solo-maintained, no SLA, fork-and-own) on the first screen.
|
||||
- `CLAUDE.md` opens with an English note explaining what the file is for a visitor: the working
|
||||
agreement with the AI agent that builds this repository, doubling as its invariant ledger.
|
||||
|
||||
### Fixed
|
||||
- `env.template` claimed the AZURE profile resolved its credential through `DefaultAzureCredential`.
|
||||
It never has. An operator copying the template was told the wrong identity would be used.
|
||||
|
||||
## [1.0.0] - 2026-08-12
|
||||
|
||||
### Added
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue