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
30 lines
2.2 KiB
Text
30 lines
2.2 KiB
Text
# portfolio-optimiser — environment template. Copy to `.env` and fill in. NEVER commit `.env`.
|
|
#
|
|
# Two backend profiles (D2): LOCAL (OpenAI-compatible local endpoint, dev default — D6) and
|
|
# AZURE (Foundry, for targeted minimal verification against the private tenant).
|
|
#
|
|
# Named `env.template` (no leading dot) on purpose: a leading-dot `.env.template` is blocked by
|
|
# the llm-security pre-write pathguard. Copy to `.env` locally (`.env` is gitignored).
|
|
|
|
# --- LOCAL profile (dev default) — OpenAI-compatible local endpoint (Ollama / LM Studio) ---
|
|
# No-egress notes (research 03): the endpoint MUST be loopback; a model pull is the ONLY
|
|
# legitimate egress and is explicit. Harden Ollama: bind to 127.0.0.1, pin >= 0.17.1, and
|
|
# leave OLLAMA_DEBUG unset.
|
|
PORTFOLIO_LOCAL_BASE_URL=http://127.0.0.1:11434/v1 # loopback only — never a remote host
|
|
PORTFOLIO_LOCAL_API_KEY=ollama # local servers accept any non-empty key
|
|
# Recommended Ollama hardening (set in the Ollama service environment, not here):
|
|
# OLLAMA_HOST=127.0.0.1:11434 # bind loopback only
|
|
# (pin Ollama >= 0.17.1; leave OLLAMA_DEBUG unset)
|
|
|
|
# --- AZURE / Foundry profile (targeted verification only — D6) ---
|
|
# Deployment (model) names are tenant-specific and live in data/model_map.json (azure.*).
|
|
# The credential is chosen by the ENVIRONMENT and is not configured here:
|
|
# * developer host -> AzureCliCredential; constructing it acquires no token, so `az login`
|
|
# stays your own manual step (docs/2026-07-15-foundry-auth-recipe.md).
|
|
# * Foundry hosted agent -> ManagedIdentityCredential, selected when FOUNDRY_HOSTING_ENVIRONMENT
|
|
# holds a non-empty value. A container has no Azure CLI; the platform
|
|
# mints the agent a dedicated Entra identity at deploy time instead.
|
|
PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT= # tenant-specific Foundry project endpoint (operator supplies)
|
|
# Hosted only: Foundry injects FOUNDRY_PROJECT_ENDPOINT itself, and the framework reads it as a
|
|
# fallback. The name above wins whenever it holds a non-empty value, so an explicit export is never
|
|
# shadowed by a platform default — and an exported-but-empty name falls through rather than masking.
|