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
59 lines
1.3 KiB
Python
59 lines
1.3 KiB
Python
"""portfolio-optimiser — generic MAF framework for per-project cost-savings optimization."""
|
|
|
|
from portfolio_optimiser.contracts import GoalConfig, GoalContract, load_goal_config
|
|
from portfolio_optimiser.dimension import Dimension, admits, load_dimension
|
|
from portfolio_optimiser.ledger import (
|
|
LedgerEntry,
|
|
RealizationRefused,
|
|
SavingsLedger,
|
|
realize,
|
|
)
|
|
from portfolio_optimiser.notify import (
|
|
ConsoleNotifier,
|
|
FileNotifier,
|
|
Notifier,
|
|
NotifierConfig,
|
|
NotifyError,
|
|
NotifyRefused,
|
|
WebhookNotifier,
|
|
build_notifier,
|
|
)
|
|
from portfolio_optimiser.run import (
|
|
GoalReached,
|
|
PortfolioResult,
|
|
RunResult,
|
|
run_portfolio,
|
|
run_project,
|
|
)
|
|
|
|
__version__ = "1.1.0"
|
|
|
|
__all__ = [
|
|
# Portfolio orchestration
|
|
"PortfolioResult",
|
|
"RunResult",
|
|
"run_portfolio",
|
|
"run_project",
|
|
# Fase 1 domain model
|
|
"Dimension",
|
|
"admits",
|
|
"load_dimension",
|
|
"SavingsLedger",
|
|
"LedgerEntry",
|
|
"realize",
|
|
"RealizationRefused",
|
|
"GoalContract",
|
|
"GoalConfig",
|
|
"load_goal_config",
|
|
"GoalReached",
|
|
# S5.2 varsling (B11): the declared Notifier contract + deliverable implementations
|
|
"Notifier",
|
|
"ConsoleNotifier",
|
|
"FileNotifier",
|
|
"WebhookNotifier",
|
|
"build_notifier",
|
|
"NotifierConfig",
|
|
"NotifyError",
|
|
"NotifyRefused",
|
|
"__version__",
|
|
]
|