docs(deck): Del 1-3a rebuilt on verified seams — MAF-free guard named exactly, backends chain, five startup contracts, three debate stops
The MAF-free rule is a family of guards, not one list: _MAF_FREE_MODULES holds nine modules (tests/test_okf.py:22-32), ingest/ingest_mcp carry their own, hitl/notify add a transitive import-graph guard. The repo map says so instead of claiming one AST guard over eight modules. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
8988719545
commit
6e7c9c6d5d
1 changed files with 148 additions and 143 deletions
|
|
@ -582,74 +582,56 @@
|
|||
<section class="slide">
|
||||
<div class="inner">
|
||||
<p class="kicker"><span class="num">09</span><span class="part">Del 2 · Arkitekturen overordnet</span></p>
|
||||
<h2>Repo-kartet: 39 moduler i sju lag, og 26 av dem kjenner ikke MAF.</h2>
|
||||
<h2>Repo-kartet har seks lag, men bare én av grensene er håndhevet av koden.</h2>
|
||||
<figure class="fig">
|
||||
<svg viewBox="0 0 1200 520" role="img" aria-label="Sju grupper av Python-moduler, med MAF-importerende moduler markert i blaatt inni hver gruppe">
|
||||
<rect class="box" x="30" y="40" width="270" height="200"/>
|
||||
<text class="lbl" x="48" y="70">Kunnskap og ingest · 8</text>
|
||||
<text class="mono" x="48" y="100">okf ingest ingest_mcp</text>
|
||||
<text class="mono" x="48" y="122">retrieval semretrieval</text>
|
||||
<text class="mono" x="48" y="144">prepass frozen_bundles</text>
|
||||
<rect class="box accent" x="42" y="164" width="246" height="30"/>
|
||||
<text class="mono" x="54" y="184">datasource</text>
|
||||
<svg viewBox="0 0 1200 600" role="img" aria-label="Seks lag av moduler stablet, med MAF-importerende moduler markert i blaatt i hvert lag">
|
||||
<text class="tiny" x="1170" y="24" text-anchor="end">Blå = importerer agent_framework · 13 av 39 moduler</text>
|
||||
|
||||
<rect class="box" x="320" y="40" width="270" height="200"/>
|
||||
<text class="lbl" x="338" y="70">Kontrakter og IR · 5</text>
|
||||
<text class="mono" x="338" y="100">ir contracts mandate</text>
|
||||
<text class="mono" x="338" y="122">dimension</text>
|
||||
<rect class="box accent" x="332" y="164" width="246" height="30"/>
|
||||
<text class="mono" x="344" y="184">provenance</text>
|
||||
<rect class="band" x="30" y="36" width="1140" height="84"/>
|
||||
<text class="lbl" x="48" y="70">Kjøreflater og ops</text>
|
||||
<text class="tiny" x="48" y="94">7 moduler</text>
|
||||
<rect class="box accent" x="250" y="58" width="180" height="30"/>
|
||||
<text class="mono" x="262" y="79">run simulation</text>
|
||||
<text class="mono" x="446" y="79">hosting preflight hitl costsim evals/v1_gate</text>
|
||||
|
||||
<rect class="box" x="610" y="40" width="270" height="200"/>
|
||||
<text class="lbl" x="628" y="70">Orkestrering · 7</text>
|
||||
<rect class="box accent" x="622" y="86" width="246" height="102"/>
|
||||
<text class="mono" x="634" y="110">workflow generate</text>
|
||||
<text class="mono" x="634" y="132">explore backends tools</text>
|
||||
<text class="mono" x="634" y="154">mcp_tools budget</text>
|
||||
<text class="tiny" x="628" y="214">Alle sju importerer agent_framework.</text>
|
||||
<rect class="band" x="30" y="130" width="1140" height="84"/>
|
||||
<text class="lbl" x="48" y="164">Orkestrering</text>
|
||||
<text class="tiny" x="48" y="188">7 moduler, alle MAF-bundne</text>
|
||||
<rect class="box accent" x="250" y="152" width="620" height="30"/>
|
||||
<text class="mono" x="262" y="173">workflow explore generate budget mcp_tools tracing backends</text>
|
||||
|
||||
<rect class="box" x="900" y="40" width="270" height="200"/>
|
||||
<text class="lbl" x="918" y="70">Validering · 3</text>
|
||||
<text class="mono" x="918" y="100">validator costsim</text>
|
||||
<text class="mono" x="918" y="122">reference_domain</text>
|
||||
<text class="tiny" x="918" y="160">Porten som avgjør verdien</text>
|
||||
<text class="tiny" x="918" y="180">har ingen MAF-import.</text>
|
||||
<rect class="band" x="30" y="224" width="1140" height="84"/>
|
||||
<text class="lbl" x="48" y="258">Validering</text>
|
||||
<text class="tiny" x="48" y="282">2 moduler</text>
|
||||
<text class="mono" x="250" y="267">validator stress</text>
|
||||
<text class="sub" x="446" y="267">Porten som avgjør verdien har ingen MAF-import i det hele tatt.</text>
|
||||
|
||||
<rect class="box" x="30" y="264" width="270" height="200"/>
|
||||
<text class="lbl" x="48" y="294">Læring og HITL · 8</text>
|
||||
<text class="mono" x="48" y="324">persona hitl notify</text>
|
||||
<text class="mono" x="48" y="346">outbox proposal_review</text>
|
||||
<text class="mono" x="48" y="368">ledger value_report</text>
|
||||
<rect class="box accent" x="42" y="388" width="246" height="30"/>
|
||||
<text class="mono" x="54" y="408">verdicts</text>
|
||||
<rect class="band" x="30" y="318" width="1140" height="84"/>
|
||||
<text class="lbl" x="48" y="352">Læring og HITL</text>
|
||||
<text class="tiny" x="48" y="376">7 moduler</text>
|
||||
<rect class="box accent" x="250" y="340" width="110" height="30"/>
|
||||
<text class="mono" x="262" y="361">verdicts</text>
|
||||
<text class="mono" x="376" y="361">proposal_review outbox notify persona ledger value_report</text>
|
||||
|
||||
<rect class="box" x="320" y="264" width="270" height="200"/>
|
||||
<text class="lbl" x="338" y="294">Kjøring og drift · 6</text>
|
||||
<text class="mono" x="338" y="324">hosting preflight</text>
|
||||
<text class="mono" x="338" y="346">shared_root</text>
|
||||
<rect class="box accent" x="332" y="366" width="246" height="52"/>
|
||||
<text class="mono" x="344" y="388">run simulation</text>
|
||||
<text class="mono" x="344" y="410">tracing</text>
|
||||
<rect class="band" x="30" y="412" width="1140" height="84"/>
|
||||
<text class="lbl" x="48" y="446">Kunnskap og ingest</text>
|
||||
<text class="tiny" x="48" y="470">10 moduler</text>
|
||||
<rect class="box accent" x="250" y="428" width="180" height="30"/>
|
||||
<text class="mono" x="262" y="449">datasource tools</text>
|
||||
<text class="mono" x="446" y="449">okf retrieval semretrieval prepass frozen_bundles</text>
|
||||
<text class="mono" x="446" y="482">ingest ingest_mcp shared_root</text>
|
||||
|
||||
<rect class="box" x="610" y="264" width="270" height="200"/>
|
||||
<text class="lbl" x="628" y="294">Evals · 2</text>
|
||||
<text class="mono" x="628" y="324">stress</text>
|
||||
<text class="mono" x="628" y="346">evals/v1_gate</text>
|
||||
<text class="tiny" x="628" y="384">Måleinstrumentene, utenfor</text>
|
||||
<text class="tiny" x="628" y="404">kjørestien.</text>
|
||||
|
||||
<rect class="box accent" x="900" y="264" width="270" height="86"/>
|
||||
<text class="lbl" x="918" y="294">Blå = importerer MAF</text>
|
||||
<text class="tiny" x="918" y="318">13 av 39 moduler gjør det.</text>
|
||||
<text class="tiny" x="918" y="338">De 26 andre gjør det ikke.</text>
|
||||
<text class="sub" x="900" y="386">Det er dét som lar en søsken-</text>
|
||||
<text class="sub" x="900" y="408">implementasjon på Claude Agent SDK</text>
|
||||
<text class="sub" x="900" y="430">gjenbruke dem uendret.</text>
|
||||
<rect class="band" x="30" y="506" width="1140" height="84"/>
|
||||
<text class="lbl" x="48" y="540">Kontrakter og IR</text>
|
||||
<text class="tiny" x="48" y="564">6 moduler</text>
|
||||
<rect class="box accent" x="250" y="522" width="130" height="30"/>
|
||||
<text class="mono" x="262" y="543">provenance</text>
|
||||
<text class="mono" x="396" y="543">ir dimension contracts mandate reference_domain</text>
|
||||
</svg>
|
||||
<figcaption>Målt 18.09.2026: 41 <code>.py</code>-filer under <code>src/portfolio_optimiser/</code>, hvorav 2 er <code>__init__.py</code>. 13 av de 39 modulene har en <code>agent_framework</code>-import. Grupperingen i sju lag er framstillerens lesning, ikke en struktur i koden.</figcaption>
|
||||
<figcaption>Målt 18.09.2026: 41 <code>.py</code>-filer og 22 019 linjer under <code>src/</code>. To av filene er <code>__init__.py</code>, så 39 er moduler, og 13 av dem importerer <code>agent_framework</code>. Lagdelingen er framstillerens lesning; modulene ligger flatt, og bare <code>evals/</code> er en pakke.</figcaption>
|
||||
</figure>
|
||||
<p class="callout"><b>MAF-frihet er en regel, ikke en tilfeldighet.</b> Den håndheves av <code>tests/test_okf.py::test_okf_is_maf_free</code>, som går rødt hvis kontekst-sømmen begynner å importere rammeverket.</p>
|
||||
<p class="src">Kilde: <code>ls src/portfolio_optimiser/*.py src/portfolio_optimiser/evals/*.py | wc -l</code> · <code>grep -lE '^\s*(from|import)\s+agent_framework'</code> · <code>tests/test_okf.py:477</code></p>
|
||||
<p class="callout"><b>Den ene grensen koden håndhever.</b> <code>tests/test_okf.py</code> holder en liste, <code>_MAF_FREE_MODULES</code>, med ni moduler — <code>okf</code>, <code>dimension</code>, <code>mandate</code>, <code>outbox</code>, <code>costsim</code>, <code>hitl</code>, <code>notify</code>, <code>semretrieval</code>, <code>proposal_review</code> — og en AST-sjekk går rødt hvis noen av dem importerer <code>agent_framework</code> eller <code>mcp</code>. AST, ikke tekstsøk, så en docstring som <i>omtaler</i> rammeverket ikke utløser den. <code>ingest</code> og <code>ingest_mcp</code> har egne vakter, og <code>hitl</code> og <code>notify</code> har i tillegg en <i>transitiv</i> importgraf-vakt. Det er dette som lar en søsken-implementasjon på Claude Agent SDK gjenbruke lagene nederst uendret.</p>
|
||||
<p class="src">Kilde: <code>tests/test_okf.py:22-32</code> · <code>tests/test_okf.py:476-500</code> · <code>tests/test_hitl_loadbearing.py:273</code> · <code>find src -name "*.py" | xargs wc -l</code></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -708,43 +690,54 @@
|
|||
<p class="kicker"><span class="num">11</span><span class="part">Del 2 · Arkitekturen overordnet</span></p>
|
||||
<h2>To backend-profiler: local på loopback uten egress, azure mot Foundry.</h2>
|
||||
<figure class="fig">
|
||||
<svg viewBox="0 0 1200 400" role="img" aria-label="Kjede fra profil og rolle gjennom modell-oppslag til backend-valg og videre til to konkrete MAF-chat-klienter">
|
||||
<rect class="box" x="30" y="150" width="200" height="110"/>
|
||||
<text class="lbl" x="48" y="182">profil + rolle</text>
|
||||
<text class="sub" x="48" y="208">local | azure</text>
|
||||
<text class="tiny" x="48" y="234">proposer, checker, …</text>
|
||||
<path class="edge" d="M232 205 H274"/>
|
||||
<svg viewBox="0 0 1200 460" role="img" aria-label="Dataflyt fra profil og rolle gjennom modell-oppslaget til backend-valget og de to konkrete chat-klientene">
|
||||
<rect class="box" x="30" y="140" width="190" height="120"/>
|
||||
<text class="lbl" x="48" y="172">profil + rolle</text>
|
||||
<text class="sub" x="48" y="198">local | azure</text>
|
||||
<text class="tiny" x="48" y="224">proposer · checker</text>
|
||||
<path class="edge" d="M222 200 H262"/>
|
||||
|
||||
<rect class="box" x="278" y="150" width="250" height="110"/>
|
||||
<text class="lbl" x="296" y="182">resolve_model()</text>
|
||||
<text class="sub" x="296" y="206">rolle → deployment-id</text>
|
||||
<text class="tiny" x="296" y="230">REPLACE-WITH-* feiler fail-fast</text>
|
||||
<text class="tiny" x="296" y="250">PORTFOLIO_MODEL_MAP vinner</text>
|
||||
<path class="edge" d="M530 205 H572"/>
|
||||
<rect class="box" x="266" y="118" width="260" height="164"/>
|
||||
<text class="lbl" x="284" y="150">resolve_model()</text>
|
||||
<text class="tiny" x="284" y="176">1 · ukjent profil → ValueError</text>
|
||||
<text class="tiny" x="284" y="198">2 · map[profil][rolle]</text>
|
||||
<text class="tiny" x="284" y="220">3 · ellers map[profil][default]</text>
|
||||
<text class="tiny" x="284" y="242">4 · REPLACE-WITH-* → ValueError</text>
|
||||
<text class="tiny" x="284" y="268">PORTFOLIO_MODEL_MAP slår den pakkede</text>
|
||||
<path class="edge" d="M528 200 H568"/>
|
||||
|
||||
<rect class="box" x="576" y="150" width="244" height="110"/>
|
||||
<text class="lbl" x="594" y="182">get_backend(profile)</text>
|
||||
<text class="sub" x="594" y="208">ChatBackend-protokoll</text>
|
||||
<text class="tiny" x="594" y="234">ukjent profil: fail-fast</text>
|
||||
<rect class="box" x="572" y="140" width="230" height="120"/>
|
||||
<text class="lbl" x="590" y="172">get_backend(profile)</text>
|
||||
<text class="sub" x="590" y="198">ChatBackend-protokoll</text>
|
||||
<text class="tiny" x="590" y="224">returnerer én av to</text>
|
||||
|
||||
<path class="edge noarrow" d="M822 205 H852"/>
|
||||
<path class="edge" d="M852 205 V115 H864"/>
|
||||
<path class="edge" d="M852 205 V295 H864"/>
|
||||
<path class="edge noarrow" d="M804 200 H834"/>
|
||||
<path class="edge" d="M834 200 V110 H846"/>
|
||||
<path class="edge" d="M834 200 V300 H846"/>
|
||||
|
||||
<rect class="box accent" x="868" y="60" width="302" height="110"/>
|
||||
<text class="lbl" x="886" y="92">LocalBackend</text>
|
||||
<text class="mono" x="886" y="118">OpenAIChatCompletionClient</text>
|
||||
<text class="sub" x="886" y="144">127.0.0.1:11434/v1 — ingen egress</text>
|
||||
<rect class="box accent" x="850" y="52" width="320" height="116"/>
|
||||
<text class="lbl" x="868" y="84">LocalBackend — utviklingsdefault</text>
|
||||
<text class="mono" x="868" y="110">OpenAIChatCompletionClient</text>
|
||||
<text class="tiny" x="868" y="134">127.0.0.1:11434/v1 — loopback, aldri en fjernvert</text>
|
||||
<text class="tiny" x="868" y="156">Chat Completions, ikke Responses: usage uten None</text>
|
||||
|
||||
<rect class="box accent" x="868" y="240" width="302" height="110"/>
|
||||
<text class="lbl" x="886" y="272">AzureFoundryBackend</text>
|
||||
<text class="mono" x="886" y="298">FoundryChatClient</text>
|
||||
<text class="sub" x="886" y="324">Foundry-prosjekt + eksplisitt cred.</text>
|
||||
<rect class="box accent" x="850" y="240" width="320" height="130"/>
|
||||
<text class="lbl" x="868" y="272">AzureFoundryBackend</text>
|
||||
<text class="mono" x="868" y="298">FoundryChatClient</text>
|
||||
<text class="tiny" x="868" y="322">credential er PÅKREVD — ingen lazy default</text>
|
||||
<text class="tiny" x="868" y="342">AzureCliCredential på en utviklermaskin</text>
|
||||
<text class="tiny" x="868" y="362">ManagedIdentityCredential i hostet container</text>
|
||||
|
||||
<rect class="box soft" x="30" y="310" width="790" height="130"/>
|
||||
<text class="lbl" x="48" y="342">Det som faktisk ligger i data/model_map.json</text>
|
||||
<text class="mono" x="48" y="374">local: default / proposer / checker = qwen3:4b</text>
|
||||
<text class="mono" x="48" y="398">azure: default / proposer / checker = REPLACE-WITH-FOUNDRY-DEPLOYMENT</text>
|
||||
<text class="tiny" x="48" y="426">Azure-profilen feiler altså fail-fast ut av boksen, helt til operatøren bytter dem ut.</text>
|
||||
</svg>
|
||||
<figcaption>Deployment-navn committes aldri: modell-mappet sendes med <code>REPLACE-WITH-*</code>-plassholdere som feiler fail-fast, og <code>PORTFOLIO_MODEL_MAP</code> peker på et map utenfor repoet.</figcaption>
|
||||
<figcaption>Endepunktet leses ved kall, og vårt eget navn vinner: <code>PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT</code> først, så det plattform-injiserte <code>FOUNDRY_PROJECT_ENDPOINT</code>. Presedensen gjelder verdier, ikke erklæringer, så et eksportert-men-tomt navn faller gjennom i stedet for å skygge for et ekte.</figcaption>
|
||||
</figure>
|
||||
<p class="callout"><b>Kostnadsdisiplin.</b> Utvikling skjer på <code>local</code>, som er gratis. Foundry brukes bare til målrettet, minimal verifisering. Credential-figuren og hele leverandørsømmen tas i Del 5.</p>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/backends.py:88-172</code> · <code>README.md:390-405</code></p>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/backends.py:87-91</code> · <code>backends.py:105-122</code> · <code>backends.py:125-172</code> · <code>src/portfolio_optimiser/data/model_map.json</code></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -753,7 +746,7 @@
|
|||
<div class="inner">
|
||||
<p class="kicker"><span class="num">12</span><span class="part">Del 2 · Arkitekturen overordnet</span></p>
|
||||
<h2>Kjørestien har fire moduser, og de er en dokumentert partisjon.</h2>
|
||||
<p class="lede">Ett kall kan ikke utøve hvert flagg. Derfor er modusene skrevet ned som en partisjon, og kombinasjoner som ville vært tvetydige nektes i stedet for å bli tolket.</p>
|
||||
<p class="lede">CLI-en har 36 distinkte flagg. Ett kall kan ikke utøve dem alle, så modusene er skrevet ned som en partisjon, og kombinasjoner som ville vært tvetydige nektes i stedet for å bli tolket.</p>
|
||||
<table class="compact">
|
||||
<thead><tr><th>Modus</th><th>Påkrevd</th><th>Hva den gjør</th></tr></thead>
|
||||
<tbody>
|
||||
|
|
@ -764,7 +757,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<p class="callout warn"><b>Nektet, aldri stilltiende ignorert.</b> <code>--live-dry-run</code> og <code>--scripted-replies</code> er begge offline-moduser og nektes sammen. <code>--json</code> uten <code>--report</code> nektes. <code>--report</code> tåler bare <code>--ledger</code> og <code>--json</code> ved siden av seg. <code>--across-bundle</code> nekter <code>--bundle-dir</code>, <code>--portfolio</code>, <code>--explore</code> og <code>--prepass-payload</code>, fordi hver av dem løser opp én base.</p>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/run.py:2826-3145</code> · <code>run.py:3185</code> · <code>run.py:3265-3271</code> · <code>run.py:3434</code> · <code>run.py:4051</code></p>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/run.py:2826-3145</code> (37 <code>add_argument</code>, hvorav én er posisjonsargumentet <code>project_id</code>) · <code>run.py:3185</code> · <code>run.py:3265-3271</code> · <code>run.py:3434</code> · <code>run.py:4051</code></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -961,36 +954,38 @@
|
|||
<section class="slide">
|
||||
<div class="inner">
|
||||
<p class="kicker"><span class="num">16</span><span class="part">Del 3 · Elementene</span></p>
|
||||
<h2>Kontraktene er Pydantic, og de feiler ved oppstart.</h2>
|
||||
<h2>Kontraktene er Pydantic, og de feiler før det første modellkallet.</h2>
|
||||
<figure class="fig">
|
||||
<svg viewBox="0 0 1200 500" role="img" aria-label="Tre kolonner: kontrakter validert ved oppstart, typene som flyter gjennom kjoeringen, og provenance-stempelet paa hvert utfall">
|
||||
<svg viewBox="0 0 1200 560" role="img" aria-label="Tre kolonner: kontrakter validert ved oppstart, typene som flyter gjennom kjoeringen, og provenance-stempelet paa hvert utfall">
|
||||
<text class="band-lbl" x="30" y="30">Validert ved oppstart</text>
|
||||
<rect class="band" x="30" y="40" width="360" height="440"/>
|
||||
<rect class="box" x="48" y="58" width="324" height="82"/>
|
||||
<text class="lbl" x="66" y="88">contracts.py</text>
|
||||
<text class="tiny" x="66" y="112">ModelMapContract · TerminationContract</text>
|
||||
<text class="tiny" x="66" y="132">DataSourceContract · FeedbackContract</text>
|
||||
<rect class="band" x="30" y="40" width="360" height="490"/>
|
||||
<rect class="box" x="48" y="58" width="324" height="88"/>
|
||||
<text class="lbl" x="66" y="88">contracts.py — fire kontrakter</text>
|
||||
<text class="tiny" x="66" y="112">DataSourceContract · ModelMapContract</text>
|
||||
<text class="tiny" x="66" y="134">TerminationContract · FeedbackContract</text>
|
||||
|
||||
<rect class="box" x="48" y="156" width="324" height="82"/>
|
||||
<text class="lbl" x="66" y="186">mandate.Mandate</text>
|
||||
<text class="tiny" x="66" y="210">objective + approaches[] med id, label,</text>
|
||||
<text class="tiny" x="66" y="230">bundle_id og en bindende requirement</text>
|
||||
<rect class="box" x="48" y="158" width="324" height="88"/>
|
||||
<text class="lbl" x="66" y="188">mandate.Mandate</text>
|
||||
<text class="tiny" x="66" y="212">objective + approaches[] med id, label,</text>
|
||||
<text class="tiny" x="66" y="234">bundle_id og en bindende requirement</text>
|
||||
|
||||
<rect class="box" x="48" y="254" width="324" height="70"/>
|
||||
<text class="lbl" x="66" y="284">dimension.Dimension</text>
|
||||
<text class="tiny" x="66" y="308">allowed_measure_types er påkrevd</text>
|
||||
<rect class="box" x="48" y="258" width="324" height="68"/>
|
||||
<text class="lbl" x="66" y="288">dimension.Dimension</text>
|
||||
<text class="tiny" x="66" y="312">allowed_measure_types er påkrevd</text>
|
||||
|
||||
<rect class="box" x="48" y="340" width="324" height="70"/>
|
||||
<text class="lbl" x="66" y="370">explore.ExplorationContract</text>
|
||||
<text class="tiny" x="66" y="394">seks felt, alle påkrevd, ingen default</text>
|
||||
<rect class="box" x="48" y="338" width="324" height="88"/>
|
||||
<text class="lbl" x="66" y="368">budget.Budget</text>
|
||||
<text class="tiny" x="66" y="392">max_tokens og max_rounds, begge over 0</text>
|
||||
<text class="tiny" x="66" y="414">nekter konstruksjon ellers — aldri ubegrenset</text>
|
||||
|
||||
<rect class="box" x="48" y="426" width="324" height="40"/>
|
||||
<text class="lbl" x="66" y="452">mcp_tools.McpConfig — extra=forbid</text>
|
||||
<rect class="box" x="48" y="438" width="324" height="74"/>
|
||||
<text class="lbl" x="66" y="468">explore.ExplorationContract</text>
|
||||
<text class="tiny" x="66" y="492">seks felt, alle påkrevd, ingen default</text>
|
||||
|
||||
<path class="edge" d="M392 260 H424"/>
|
||||
<path class="edge" d="M392 280 H424"/>
|
||||
|
||||
<text class="band-lbl" x="430" y="30">Gjennom kjøringen</text>
|
||||
<rect class="band accent" x="430" y="40" width="340" height="440"/>
|
||||
<rect class="band accent" x="430" y="40" width="340" height="490"/>
|
||||
<rect class="box" x="448" y="70" width="304" height="140"/>
|
||||
<text class="lbl" x="466" y="100">ir.SavingsProposal</text>
|
||||
<text class="tiny" x="466" y="126">project_id · measure</text>
|
||||
|
|
@ -1004,16 +999,16 @@
|
|||
<text class="tiny" x="466" y="310">unit_cost over 0 · total</text>
|
||||
<text class="tiny" x="466" y="332">summen begrenser claimed</text>
|
||||
|
||||
<rect class="box" x="448" y="364" width="304" height="102"/>
|
||||
<rect class="box" x="448" y="364" width="304" height="126"/>
|
||||
<text class="lbl" x="466" y="394">ir.CostBaseline</text>
|
||||
<text class="tiny" x="466" y="420">project_id · items: kode → linje</text>
|
||||
<text class="tiny" x="466" y="442">prosjektets faktiske kostnadslinjer —</text>
|
||||
<text class="tiny" x="466" y="460">det validatoren forankrer mot</text>
|
||||
<text class="tiny" x="466" y="464">det validatoren forankrer mot</text>
|
||||
|
||||
<path class="edge" d="M772 260 H804"/>
|
||||
<path class="edge" d="M772 280 H804"/>
|
||||
|
||||
<text class="band-lbl" x="810" y="30">På hvert utfall</text>
|
||||
<rect class="band" x="810" y="40" width="360" height="440"/>
|
||||
<rect class="band" x="810" y="40" width="360" height="490"/>
|
||||
<rect class="box" x="828" y="70" width="324" height="242"/>
|
||||
<text class="lbl" x="846" y="100">provenance.ProvenanceStamp</text>
|
||||
<text class="tiny" x="846" y="128">citations — minst én, alltid</text>
|
||||
|
|
@ -1025,16 +1020,18 @@
|
|||
<text class="tiny" x="846" y="268">external_calls — tom liste er en PÅSTAND</text>
|
||||
<text class="tiny" x="846" y="292">om at ingenting utenfor prosessen ble kontaktet</text>
|
||||
|
||||
<rect class="box soft" x="828" y="340" width="324" height="126"/>
|
||||
<rect class="box soft" x="828" y="340" width="324" height="150"/>
|
||||
<text class="lbl" x="846" y="370">Fail-fast, ikke tolerant</text>
|
||||
<text class="tiny" x="846" y="396">En malformert konfig reiser ValidationError</text>
|
||||
<text class="tiny" x="846" y="416">FØR den første chat-klienten bygges.</text>
|
||||
<text class="tiny" x="846" y="440">Ingen degradering til noe som «virker likevel»:</text>
|
||||
<text class="tiny" x="846" y="460">en tolerant baseline løsner porten i stillhet.</text>
|
||||
<text class="tiny" x="846" y="396">load_contracts bygger de fire i rekkefølge og</text>
|
||||
<text class="tiny" x="846" y="416">reiser på den FØRSTE som er malformert,</text>
|
||||
<text class="tiny" x="846" y="436">før noen chat-klient finnes.</text>
|
||||
<text class="tiny" x="846" y="462">Ingen degradering til noe som «virker likevel»:</text>
|
||||
<text class="tiny" x="846" y="482">en tolerant baseline løsner porten i stillhet.</text>
|
||||
</svg>
|
||||
<figcaption>Typene er små og få. Poenget er ikke modelleringen, men at hvert felt som kan lyve enten er påkrevd uten default, eller har en begrensning Pydantic håndhever ved konstruksjon.</figcaption>
|
||||
<figcaption>Feltene som kan lyve er enten påkrevde uten default, eller har en begrensning Pydantic håndhever ved konstruksjon. <code>BindingRequirement</code> bærer stien og kravets eget nummer som frontmatteren skriver det, aldri en parafrase — målt bakgrunn: 0 av 26 fasit-konsepter ble noen gang åpnet, i begge runder, mens hver kjøring likevel produserte forslag.</figcaption>
|
||||
</figure>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/ir.py:15-63</code> · <code>contracts.py:31-63</code> · <code>mandate.py:71-134</code> · <code>provenance.py:53-104</code> · <code>explore.py:65-99</code> · <code>mcp_tools.py:50-104</code></p>
|
||||
<p class="callout"><b>To ting som IKKE er det samme.</b> <code>TerminationContract</code> og <code>Budget</code> er ressurstak; <code>GoalContract</code> er et domenemål — en besparelse i øre eller prosent — og det målet bor ett sted, ikke i mandatet. <code>McpConfig</code> er <code>extra=forbid</code>, så en forvillet <code>"credential": "sk-…"</code> blir en nekt i stedet for en ignorert nøkkel.</p>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/contracts.py:31-101</code> · <code>ir.py:15-63</code> · <code>mandate.py:46-156</code> · <code>budget.py:67-81</code> · <code>provenance.py:53-104</code> · <code>explore.py:65-99</code> · <code>mcp_tools.py:50-58</code></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -1044,7 +1041,7 @@
|
|||
<p class="kicker"><span class="num">17</span><span class="part">Del 3 · Elementene</span></p>
|
||||
<h2>Debatten er maker–checker i en GroupChat, med rundetak og en VERDICT-linje.</h2>
|
||||
<figure class="fig">
|
||||
<svg viewBox="0 0 1200 520" role="img" aria-label="Sekvensdiagram mellom proposer, checker og den deterministiske validatoren">
|
||||
<svg viewBox="0 0 1200 540" role="img" aria-label="Sekvensdiagram mellom proposer, checker og den deterministiske validatoren, med stoppene under">
|
||||
<rect class="box accent" x="60" y="20" width="260" height="64"/>
|
||||
<text class="lbl" x="82" y="58">proposer</text>
|
||||
<rect class="box accent" x="440" y="20" width="260" height="64"/>
|
||||
|
|
@ -1071,18 +1068,26 @@
|
|||
<text class="tiny" x="230" y="374">5 · ved nekt: KUN Rejection.reason inn i neste forsøks prompt, aldri forrige JSON</text>
|
||||
<path class="edge warn" d="M970 384 H196"/>
|
||||
|
||||
<rect class="box soft" x="60" y="420" width="520" height="80"/>
|
||||
<text class="lbl" x="80" y="450">Ferske agenter og ferske klienter per kjøring</text>
|
||||
<text class="tiny" x="80" y="476">Ingen tilstand overlever mellom kjøringer.</text>
|
||||
<rect class="box soft" x="60" y="420" width="520" height="100"/>
|
||||
<text class="lbl" x="80" y="450">Ferske agenter, ferske klienter, per kjøring</text>
|
||||
<text class="tiny" x="80" y="476">Målt: en gjenbrukt bygget workflow er ENGANGS — klientkall-serien</text>
|
||||
<text class="tiny" x="80" y="496">[2, 0, 0] over tre .run() på ett objekt. Gjenbruk gir TOMME kjøringer,</text>
|
||||
<text class="tiny" x="80" y="514">ikke bare forurensede. Derfor en fabrikk, ikke et delt objekt.</text>
|
||||
|
||||
<rect class="box warn" x="620" y="420" width="500" height="80"/>
|
||||
<text class="lbl" x="640" y="450">Tre uavhengige stopp — mer i Del 5</text>
|
||||
<text class="tiny" x="640" y="476">with_max_rounds · turn-count-nettet · token-taket i middlewaren</text>
|
||||
<rect class="box warn" x="620" y="420" width="500" height="100"/>
|
||||
<text class="lbl" x="640" y="450">Tre uavhengige stopp</text>
|
||||
<text class="tiny" x="640" y="476">with_max_rounds(max_rounds) er det bindende taket</text>
|
||||
<text class="tiny" x="640" y="496">make_termination(max_rounds × 2 + 1) er sikkerhetsnettet over det</text>
|
||||
<text class="tiny" x="640" y="514">BudgetMiddleware nekter NESTE kall før det gjøres. Mer i Del 5.</text>
|
||||
</svg>
|
||||
<figcaption>På grenen uten pre-pass-payload har debatten de samme fire navigasjonsverktøyene som utforskningen bruker — samme policy, gjenbrukt, aldri en andre kopi.</figcaption>
|
||||
<figcaption><code>output_from=agents</code> er load-bearing: uten den gir <code>get_outputs()</code> bare orkestratorens «reached max rounds»-melding, og både proposerens forslag og checkerens dom går tapt. <code>run.py</code> skiller dem på <code>author_name</code>. På grenen uten pre-pass-payload har debatten de samme fire navigasjonsverktøyene som utforskningen.</figcaption>
|
||||
</figure>
|
||||
<p class="point">Slik ser en falsifisering ut når den reiser tilbake til modellen — hele blokken, ordrett:</p>
|
||||
<pre><code>Your previous proposal was REJECTED by the deterministic validator.
|
||||
Reason: {prior_rejection.reason}
|
||||
Produce a REVISED SavingsProposal that resolves this.</code></pre>
|
||||
<p class="callout"><b>Checker-porten er fail-open.</b> Bare en eksplisitt <code>VERDICT: REJECT</code> blokkerer. Mangler markøren, eller er den uleselig, står den deterministiske validatoren alene som port. Stadiene i den porten er Del 3b; MAF-objektene rundt debatten er Del 5.</p>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/workflow.py:24-117</code> · <code>run.py:673-687</code> · <code>run.py:1331-1346</code> · <code>generate.py:219-235</code></p>
|
||||
<p class="src">Kilde: <code>src/portfolio_optimiser/workflow.py:26-117</code> · <code>generate.py:362-367</code> · <code>generate.py:701-793</code> · <code>run.py:673-687</code> · <code>run.py:1331-1346</code></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue