Voordat een voorgestelde wijziging je repository of je releaseproces bereikt, valideert FixControl haar — en legt precies vast wat die validatie bewees. Deze pagina is het gedetailleerde beheerdersoverzicht: welke omgevingen er zijn, hoe de keuze ertussen wordt gemaakt, welk bewijs een run achterlaat, en welke onderdelen een pilot zijn. Hoe je als gebruiker een uitslag leest, staat in Verificatie en resultaten.
| Onderdeel | Beschikbaarheid |
|---|---|
| Validatie in FixControls eigen afgeschermde omgeving, automatische omgevingsontdekking, de controle of de applicatie start, tests die de wijziging meebrengt | Beschikbaar, standaard aan |
| Voorbeelden (previews) | Beschikbaar, standaard aan; een workspace kan ze uitzetten |
| Een mislukte run onderzoeken in zijn container | Beschikbaar, uit tot je het aanzet |
| Validatie met meerdere containers uit je Compose-bestand | Pilot, standaard uit, per organisatie aangezet |
| Validatie binnen je eigen Kubernetes-omgeving (FC Agent-runner) | Pilot, standaard uit, per organisatie aangezet |
| .NET Framework (net48) en WinDev | Vandaag niet geverifieerd — zie hieronder |
Je kunt hier ook gewoon om vragen. Command Center beantwoordt "hoe wordt dit project geverifieerd?", "waarom faalde het?" (in gewone taal, inclusief wat de agent in de gefaalde container vond), "start hij nog?" en "waarom kan deze wijziging niet toegepast worden?" — en hij kan een verificatie starten of de applicatie als voorbeeld opbrengen, en wijzigen hoe een project geverifieerd wordt: aan of uit, waar het draait, en wat je weet over het starten van de applicatie. Alleen wat je noemt verandert; de kaart toont waar hij vandaan én naartoe verandert.
Wijziging (voorgesteld door een developer of door FixControls AI)
↓
geïsoleerde validatie in de omgeving van FixControl
↓
optionele validatie in je eigen cluster (beleidsgedreven, via de FC Agent)
↓
bewijs bevroren in de goedkeuring
↓
je bestaande CI/CD-, Kubernetes- en Argo-controlesGeïsoleerde Docker-validatie
Elke run krijgt een eigen, tijdelijke en afgeschermde container op de infrastructuur van FixControl, die na afloop wordt opgeruimd. Waar multi-container-validatie is geconfigureerd (pilot: een instelling per organisatie, standaard uit), draait FixControl de wijziging daarnaast naast de services die de applicatie werkelijk nodig heeft:
- Het Compose-bestand van de repository wordt gelezen als configuratie — nooit uitgevoerd. Elke service, image en optie passeert een strikt beleid: niet-ondersteunde of gevaarlijke constructies (host-mounts, privileged containers, poortpublicatie, build-instructies en meer) worden geweigerd, niet stilletjes overgeslagen. De regels in klanttaal staan onder Projecten → Omgevingen met meerdere containers.
- Services starten in één geïsoleerd netwerk per run, zonder internettoegang. Alleen de container die je tests draait krijgt de checkout — bij de ondersteunende services wordt de repository nooit gemount. De run wordt na afloop opgeruimd, en een sweeper verwijdert wat een gecrashte run achterlaat.
- Image-referenties worden vóór de run opgelost naar digests, zodat het bewijs de exacte softwareversies noemt waartegen de wijziging slaagde.
Deze lane beantwoordt: bouwt de wijziging, slagen de tests, en gedraagt ze zich naast haar database, cache en achtergrondservices? Ze is snel, reproduceerbaar en wegwerpbaar.
Validatie in je eigen omgeving (pilot)
Waar geconfigureerd — een instelling per organisatie, standaard uit — gaat de validatie verder binnen je eigen Kubernetes-cluster, uitgevoerd door een validatie-runner die het installatiepakket van de FC Agent meelevert (dat pakket installeer je zelf; het is een ondertekende openbare release):
- De opdracht om te draaien arriveert als een getekende, aflopende, single-use operatie die de agent uitgaand ophaalt; standaard reist de workspace over datzelfde kanaal. Je cluster wordt nooit blootgesteld aan FixControl.
- De runner maakt een kortlevende testnamespace aan, start dezelfde gedeclareerde services, draait hetzelfde plan, en ruimt op. Hij is een aparte identiteit naast de agent, kan rollouts niet aanraken, en een admission-policy blokkeert zijn schrijfacties buiten de eigen testnamespaces.
- Secret-waarden verschijnen nooit in FixControls opslag, operatie-payloads, logs of bewijs. Sterker nog: FixControl geeft vandaag helemaal geen secret door aan een validatierun — een run die er een nodig heeft steunt op wat de namespace van de runner zelf al biedt, ingericht aan jouw kant tijdens de onboarding. (Een koppelmodel per project — een secret bij naam noemen, runner-zijde opgelost — bestaat in het schema, maar geen enkele executor leest het al; reken er dus niet op.)
Deze lane beantwoordt een andere vraag: gedraagt de wijziging zich in de omgeving waarin ze werkelijk gaat draaien — de runtime, policies en afhankelijkheden van jouw cluster. Het is niet de Docker-run in tweevoud.
Wat FixControl echt kan verifiëren
Een oordeel betekent alleen iets als er een echte toolchain heeft gedraaid. Dit is wat er meekomt, per stack — inclusief de plekken waar het eerlijke antwoord "hier niet" is.
| Stack | Wat er draait | Waar het oordeel vandaan komt |
|---|---|---|
| Node / TypeScript | dependency-install, Prisma- of Drizzle-migraties, tsc --noEmit, de gedetecteerde testrunner (Jest, Vitest, Mocha, node --test) | typecheck en tests; lint en build zijn adviserend |
| Angular | install, migraties, ng build, ng test in een headless browser die de image meelevert | build en tests — de build is hier vereist omdat die de templates typecheckt |
| Python | Poetry-, Pipenv- of pip-install, Django- of Alembic-migraties, mypy, pytest of unittest | typecheck en tests |
| dbt | install, een gesynthetiseerd offline profiel, dbt deps, dbt parse | dbt parse. dbt compile draait als advies, want dat heeft een bereikbare warehouse nodig; dbt run / dbt test worden helemaal niet gepland |
| PHP | Composer-install, Laravel- of Doctrine-migraties, Psalm of PHPStan, Pest / PHPUnit / artisan test | analyser en tests; op een legacy-tree zonder beide een recursieve php -l-syntaxcontrole |
| Go | go mod download, go build ./..., go test ./... | build en tests |
| Rust | cargo fetch, cargo build, cargo test | build en tests |
| Java | Maven of Gradle, compileren en dan testen (Maven warmt zijn repository één keer op en draait daarna offline) | build en tests |
| C# / .NET | dotnet restore, EF Core-migraties, dotnet build, dotnet test | build en tests; dotnet format is adviserend en alleen met een ingecheckte .editorconfig |
| C / C++ | CMake of Meson configureren, bouwen, ctest / meson test | build en tests |
| Ruby | bundle install, rails db:migrate, RSpec of Minitest | tests |
.NET Framework (net48) | gepland als NuGet-restore → MSBuild → VSTest, en gerouteerd naar een Windows-omgeving | Vandaag verifieert niets dit. Zie hieronder. |
| WINDEV | gedetecteerd, en gerouteerd naar een WINDEV-runner | Vandaag verifieert niets dit. Zie hieronder. |
Een component zonder testrunner, typechecker of build levert een unsupported plan op en zegt dat ook — "No verification steps could be derived" — in plaats van een groene run die niets bewees. Migratiestappen vervallen wanneer het project geen database heeft, zodat een vereiste migratiestap de poort nooit permanent kan blokkeren.
Windows-toolchains: wat er eerlijk gezegd meekomt
Een net48-project wordt niet als onbekend geweigerd. FixControl detecteert het, plant de echte commando's (NuGet-restore, MSBuild, VSTest) en routeert de hele solution naar een Windows-omgeving. Een gehoste Windows-omgeving daarvoor, op de cloudinfrastructuur van FixControl, is gebouwd — maar staat nog niet aan en is nog niet bewezen: het image is nog niet in gebruik genomen en er heeft nog geen Windows-run plaatsgevonden. Tot die tijd stopt de run met een weigering die precies benoemt wat ontbreekt (MSBuild of VS Build Tools, nuget.exe en vstest.console). Ook als die Windows-omgeving aan staat, start ze de applicatie niet (de startcontrole meldt dan hier niet geverifieerd) en kan ze geen ondersteunende diensten zoals een database draaien; een net48-repository die er een declareert, wordt geweigerd met de naam van die dienst.
WinDev wordt ook gedetecteerd en gepland, maar compileren en testen vraagt een gelicentieerde installatie van PC SOFT, die FixControl niet levert en niet mag verkrijgen. Een WinDev-run stopt altijd met een weigering.
Dat is een bewuste keuze. Het alternatief — een net48-solution stilzwijgend verifiëren met een Linux-.NET-SDK — zou een groene run opleveren die niets bewijst over de software die daadwerkelijk draait. Een weigering die de ontbrekende capability benoemt is het eerlijke antwoord, en dat is wat je krijgt.
Welke validatie draait
De keuze is beleidsgedreven en expliciet, nooit afgeleid uit de repository. Je zet hem per project onder Omgevingen → Hoe wijzigingen worden gevalideerd; nieuwe projecten gebruiken Geïsoleerde Docker. Validatie in je eigen omgeving vraagt daarnaast dat de FC Agent voor je workspace aan staat, een runner die aangeeft tests te kunnen draaien, en dat validatie op afstand is toegestaan — de standaard voor de workspace stelt je FixControl-beheerder in, en de projectinstelling Remote validatie voor dit project (Instelling van de werkruimte overnemen, Toegestaan voor dit project, Niet toegestaan voor dit project) kan daarvan afwijken.
| Op het scherm | Wat het doet |
|---|---|
| Geïsoleerde Docker | Snelle, geïsoleerde validatie op infrastructuur die FixControl beheert. |
| Je eigen Kubernetes-omgeving | Valideer tegen de omgeving waar de wijziging daadwerkelijk naartoe gaat. |
| Eerst Docker, dan je eigen omgeving | De geïsoleerde run gaat voorop; pas als die slaagt start de run in je eigen omgeving. De poort vereist dan beide. |
In runlijsten heten de twee lanes local (Docker) en remote (cluster), en op de detailpagina van een run staat Waar het draaide naast Validatie.
Twee eerlijkheidsregels gelden overal:
- Een vereiste in-cluster-validatie wordt alleen vervuld door in-cluster-bewijs — een Docker-only groen wordt er nooit voor in de plaats gesteld.
- Is een vereiste lane niet beschikbaar (bijvoorbeeld: de agent staat uit), dan faalt de run gesloten met een duidelijke reden. Er wordt niet zonder melding teruggevallen op een zwakkere validatie.
FixControl detecteert ook wanneer een repository duidelijk op Kubernetes mikt (Helm-charts, Kustomize, manifests) en legt dat signaal bij de run vast, zodat een Docker-only-validatie van een cluster-zware applicatie zichtbaar is voor wat ze is. Het signaal informeert; het wijzigt nooit stilzwijgend de geconfigureerde strategie.
Automatische omgevingsontdekking
Validatie werkt alleen als FixControl weet hoe je applicatie gebouwd en gestart wordt. Voor repositories met een herkenbare vorm leidt FixControl dat af uit de repository zelf. Waar dat niet genoeg is, kan FixControl het uitzoeken — en het vervolgens bewijzen (een instelling per organisatie, standaard aan; zet het uit om elke run op deterministische detectie te houden):
- Feiten worden uit de repository gelezen, zonder AI: manifests en hun versie-eisen, lockfiles, runtime-versiebestanden, Dockerfile-instructies, Compose-services, CI-runtimeconfiguratie, build- en startscripts, opgegeven health-endpoints. Uit omgevingssjablonen komen alleen namen, nooit waarden.
- AI stelt een omgeving voor op basis van die feiten, in een vast schema. Het voorstel kan alleen runtimes, services, install-/build-/validatiestappen, startcommando's en omgevingsverwijzingen uitdrukken. Een Docker-vlag, een mount, een gepubliceerde poort, privileged mode of een geheime waarde kan het niet uitdrukken — die velden bestaan niet.
- Beleid controleert het voorstel voordat er iets draait: dezelfde commandoregels, dezelfde image-regels en dezelfde resourcebudgetten als bij elke andere validatie. Een voorstel dat een expliciet feit uit de repository tegenspreekt (bijvoorbeeld een vereiste runtimeversie) wordt geweigerd, niet afgerond.
- De sandbox bewijst het door het echt te draaien. Alleen een geslaagde run levert een geverifieerde omgeving op — een genummerde, niet-wijzigbare vastlegging van de runtimes, services, images, stappen en startcommando's die werkten, samen met welke ontdekkingsrun en welke sandboxrun het bewees.
Pogingen zijn begrensd: een vast maximum aantal pogingen, een tijdslimiet en een tokenbudget, alle vastgelegd bij de ontdekking naast wat er werkelijk verbruikt is. Raken de pogingen op, dan is het resultaat geen vage rode run: FixControl stopt met wat het aantrof, wat het probeerde, de laatste fout, en de ene vraag die een mens moet beantwoorden om het vlot te trekken.
Latere wijzigingen hergebruiken de geverifieerde omgeving zoals ze is. Een fingerprint over de configuratierelevante bestanden (manifests, lockfiles, Dockerfiles, Compose, CI, omgevingssjablonen, Kubernetes-manifests) bepaalt wanneer dat niet langer klopt: een wijziging in je code laat hem ongemoeid, een wijziging in de configuratie maakt de geverifieerde omgeving ongeldig en er is een nieuwe verificatie nodig. Datzelfde geldt voor de runtime-pins van het project zelf onder Residency & validatie: wijzig een vastgezette versie of image en de geverifieerde omgeving wordt ingetrokken, zodat de volgende run onder de nieuwe pin bewezen wordt in plaats van een image te hergebruiken dat de pin niet meer noemt. Een geverifieerde omgeving wordt nooit ter plekke aangepast — een nieuw bewijs is een nieuwe versie — en ze kan alleen worden ingetrokken, nooit opnieuw geldig verklaard zonder een nieuwe geslaagde run.
Wat je zelf kunt vertellen
Ontdekking leest de repository. Sommige dingen staan niet in de repository: hoe de applicatie in jouw deployment wordt gestart, op welke poort hij luistert, welk readiness-pad antwoordt, een omgevingsvariabele die geen geheim is, een systeempakket, een extra installatiestap.
Onder Omgevingsinstellingen, op dezelfde kaart als de geverifieerde omgeving, kan een projectbeheerder dat opschrijven. De hint op het scherm formuleert het contract precies: "Wat ontdekking niet uit de repository kan lezen: hoe de applicatie start, de poort en het readiness-pad, extra omgeving, systeempakketten en installatiestappen. Toegepast op elke verificatie, beoordeeld door hetzelfde beleid als de commando's van de planner zelf, en nog steeds bewezen door de run."
Drie eigenschappen maken dit veilig genoeg om aan een beheerder te geven in plaats van aan een engineer:
- Hetzelfde beleid beoordeelt jouw commando's en die van de AI. Een commando dat jij typt gaat door dezelfde allowlist; een systeempakket dat je noemt wordt in dezelfde receptenallowlist opgezocht. Er is geen beheerdersbypass.
- Het wordt nog steeds bewezen. Instellingen zijn invoer voor de verificatie, nooit een vervanging ervan. Opslaan en verifiëren draait de ontdekking opnieuw met de instellingen erin; de omgeving is pas geverifieerd als die run slaagt.
- Het is begrensd. Maximaal vier startcommando's, tweeëndertig omgevingsregels, acht extra installatiestappen, en een vrije notitie voor de planner. Credentials horen hier niet — dat staat ook op het scherm.
Staat er niets, dan zegt de kaart "Geen omgevingsinstellingen — ontdekking leidt alles af uit de repository." Staat er wel iets, dan "Omgevingsinstellingen gelden voor elke verificatie."
De meeste projecten hoeven dit nooit in te vullen. De eerste, modelloze verificatiepoging leidt het startcommando nu uit de repository zelf af waar die het met zoveel woorden zegt — het markeringsbestand van het framework, zijn dependency, zijn eigen vastgelegde poort en healthpad. Bewijs wint van conventie, en conventie wint nooit van stilte: een repository die niets zegt krijgt geen startcommando in plaats van een gok, en een foute afleiding kost één poging in plaats van een fout contract op te leveren, want een omgeving waarvan het startdoel niet antwoordde wordt niet geaccepteerd.
Een geverifieerde omgeving zonder startcommando is dus een normale, eerlijke uitkomst — de tests draaiden, er werd niets gestart. De kaart zegt dat, en biedt Zoek een startcommando aan, waarmee de planner er zelf een uitzoekt in plaats van jou te laten gokken.
Waar de ontdekking draait. Standaard op FixControls eigen geïsoleerde Docker-lane. Voor een project waarvan het residency-beleid uitvoering aan klantzijde vereist, valt het lokale Docker-doel volledig uit de selectie en draait de ontdekking op je eigen runner; het bewijs vermeldt waar hij draaide. Dat is geen terugval met een schouderophalen: staat externe validatie voor het project uit, of adverteert geen bereikbare runner de capabilities die de ontdekking nodig heeft, dan wordt het verzoek met precies die reden geweigerd — inclusief het middel: registreer een container-capabele runner, of zet externe validatie aan voor het project.
Omgevingsfouten worden als omgevingsfouten behandeld. Een runtime die niet op te lossen is, een service die niet start of een dependency die niet installeert, wordt nooit een door AI voorgestelde wijziging aan je applicatiecode.
Start de applicatie nog?
Een groene testsuite is geen groene wijziging. Een patch kan elke test laten slagen en toch de start slopen: een ontbrekende omgevingsvariabele, een routetabel die niet meer compileert, een service die de applicatie bij het starten opent.
Dus wanneer de geverifieerde omgeving van het project vastlegt hoe de applicatie start, start elke run op de eigen Linux-infrastructuur van FixControl die applicatie ook echt op en wacht tot hij antwoordt op zijn readiness-pad — in de geïsoleerde Docker-omgeving en in de beheerde cloudomgeving van FixControl, waar de applicatie wordt gestart, gepeild en gestopt binnen dezelfde kortlevende taak die de tests draaide. Dat resultaat is een eigen regel op de run:
| Op het scherm | Betekent |
|---|---|
| Gestart en antwoordde | De applicatie startte en antwoordde binnen het readiness-budget. |
| Startte niet | Hij startte en viel om, of antwoordde nooit. |
| Niet gestart | Er is niets geprobeerd. |
| Hier niet geverifieerd | Deze omgeving legt niets vast om te starten, dus er viel niets te controleren. De tests zeggen niets over of de applicatie draait. |
De detailpagina van de run zegt het onomwonden: "De tests kunnen slagen terwijl de applicatie niet meer opstart. Dit is de controle die die twee uit elkaar houdt."
Het blokkeert het toepassen. Claimt de geverifieerde omgeving een startcommando en heeft geen run dat bewezen, dan weigert de patchpoort met: "De tests slaagden, maar niets bewees dat de applicatie nog start; draai de verificatie opnieuw zodat het startdoel wordt uitgevoerd." Een reeds gegeven goedkeuring blijft staan — de patch toont Goedgekeurd — start van de applicatie onbewezen in plaats van stilzwijgend toe te passen.
Twee grenzen zijn het waard te kennen. Een start die faalt omdat het contract fout is (geen startdoel, het commando geweigerd door beleid) is een omgevingsfout en stuurt de omgeving terug voor herverificatie. Een start die faalt omdat de applicatie crashte of een time-out kreeg is een applicatiefout en voedt de revisielus.
Het bewijs is vereist, waar de run ook draaide. Een runner in je eigen omgeving kan de applicatie niet starten en zien opkomen (het operatiekanaal kent geen start- of peilstap). Daar wordt de controle vastgelegd als hier niet geverifieerd en weigert de toepassingspoort nog steeds. Een project dat alleen in je eigen omgeving wordt gevalideerd, heeft daarom een van twee dingen nodig: de strategie Eerst Docker, dan je eigen omgeving, waarbij de geïsoleerde run het bewijs levert, of de vrijstelling hieronder.
Vrijstelling, met naam en datum
Sommige projecten kunnen het echt niet beantwoorden. Een project dat op je eigen runner gevalideerd wordt, heeft misschien geen manier om de applicatie te starten en te zien opkomen. Daarvoor kan een projectbeheerder Bewijs dat de applicatie nog start op niet vereist zetten, in de validatie-instellingen van het project onder Geavanceerd.
Het scherm benoemt de afweging voluit voordat je bevestigt: "Je accepteert dat een wijziging toegepast kan worden terwijl niemand heeft bevestigd dat de applicatie nog opkomt. Je naam en de datum van vandaag worden vastgelegd naast elke goedkeuring die erop leunt."
Een vrijstelling is dus geen stilte in de code — het is een beheerder die een risico accepteerde, op een datum, in een regel die een auditor kan lezen. De projectinstellingen zeggen dan Niet vereist — wijzigingen worden op de testresultaten alleen toegepast, met Geaccepteerd door {wie} op {datum} eronder. Alleen admins en managers kunnen dit zetten, en een ongerelateerde opslag verleent of trekt er nooit een in.
Op de goedkeuringskaart
De goedkeurder ziet dit als een eigen controle, Start van de applicatie, naast QA-verificatie, securityreview, sandboxvalidatie en CI op de geleverde commit. Hij heeft drie standen en de middelste heeft een eigen woord:
- geslaagd — de applicatie kwam op en antwoordde, met deze wijziging erin;
- vrijgesteld — niemand bewees het, en iemand accepteerde dat; de controle noemt wie en wanneer;
- gefaald — FixControl kon de applicatie met deze wijziging niet starten.
Vrijgesteld is bewust niet geslaagd. Wie de statuskolom scant kan de twee nooit verwarren, en bewijs wint altijd waar het bestaat: een project dat het kón bewijzen en dat deed, toont nooit alleen maar vrijgesteld.
Tests die de wijziging zelf meebrengt
Een patch brengt vaak eigen tests mee. Twee soorten werden geschreven en daarna nooit gedraaid; beide draaien nu:
- Tests die de runner van je framework nooit oppakt. Een Odoo-module verzamelt alleen Odoo's eigen testklassen, dus een gewoon Python-
unittest-bestand in een patch werd geladen en draaide niets. FixControl leest zo'n bestand nu (zonder het te importeren) en draait de testklassen ervan rechtstreeks, naast de stap van het framework zelf. Een Node-testbestand voornode --testin een Jest-, Vitest- of Mocha-project draait metnode --testin plaats van de projectrunner te laten falen. - UI-tests, in een headless browser. Een Odoo-QUnit-suite die de patch registreert (alleen de eigen QUnit-modules van de patch), een Odoo-tour die vanuit een Python-test start, een Playwright- of Cypress-spec in een project dat die tool al gebruikt, of een zelfstandig Node-testscript. De developer-agent wordt gevraagd doelen over de interface precies in zulke tests om te zetten, per stack.
Deze stappen bewijzen de patch; ze vervangen de verplichte stappen van het project niet. Ze falen gesloten: kan de testomgeving geen browser draaien, dan zegt de run "UI-tests konden in deze testomgeving niet draaien" in plaats van stilletjes te slagen, en een UI-stap die niets uitvoerde wordt gemeld als niet gedraaid. Een doel over de interface telt alleen als geverifieerd door een geslaagde browsertest van deze versie van de patch die het dekt — een Node-script verifieert nooit een UI-doel. Een falende UI-test is een oordeel over de wijziging en voedt de revisielus zoals elke andere falende test.
Faalt een run, dan gaat de agent terug de container in
Een gefaalde run gaf de volgende poging vroeger een stukje log mee. Nu krijgt de developer-agent, waar dit aan staat, een begrensde shell in precies de container waarin de run faalde — dezelfde image, dezelfde services, dezelfde working tree — draait een paar commando's en schrijft op wat hij zag.
- Hij heeft exact twee werkwoorden: één commando draaien, en concluderen. Hij heeft geen enkele manier om een bestand te bewerken; hij kan daarbinnen niets "repareren".
- Hij is begrensd door een aantal commando's en een tijdsbudget (standaard twaalf commando's, twee minuten), allebei ingesteld door je FixControl-beheerder en door de agent niet te verhogen.
- De container wordt direct vernietigd zodra de sessie eindigt. Niets overleeft zijn run; er is geen lease en geen keep-alive.
- De conclusie bevat een samenvatting, een waarschijnlijke oorzaak, het bewijs dat hij zag, een voorgestelde richting en een zekerheid. "Niet gereproduceerd, lage zekerheid" is een toegestaan en bruikbaar antwoord; een zelfverzekerde gok niet.
Op de run zie je dit als Wat de agent vond in de gefaalde container, met de commando's die hij draaide. De bevinding staat bovenaan de briefing van de volgende revisie, boven de logsamenvatting — zodat de volgende patch geschreven wordt tegen iets dat is waargenomen in plaats van afgeleid.
Hij staat uit tot je hem aanzet. Dat is bewust, en de reden is het benoemen waard: wat hij mogelijk maakt is een model dat commando's van eigen keuze draait binnen de sandbox — een geharde, internetloze wegwerpbak op een toch al gefaalde run, maar nog steeds een capability waarvan jij de reikwijdte weegt, niet wij namens jou. Een gefaalde run biedt hem aan op de plek waar je het gat tegenkomt dat hij vult, met wat hij kost: "Het kost een minuutje extra op een run die toch al faalde, en niets op een run die slaagde."
Je zet hem zelf aan. De schakelaar wordt op drie plekken aangeboden, allemaal schrijvend naar dezelfde workspace-instelling: op de gefaalde run zelf (Zet dit aan), op de kaart Code & omgevingen van het project, en in Instellingen → Overzicht onder Instellingen voor deze workspace. Je kunt het ook gewoon vragen — "laat FixControl mislukte runs onderzoeken" — en Command Center stelt het voor op een kaart die het gevolg benoemt voordat je bevestigt. Alleen admins en managers, achter de tweefactormuur, en elke wijziging gaat met waarde vóór en ná het auditspoor in.
Eenmaal aan treedt hij alleen in werking als de run een patch heeft, in de eigen omgeving van FixControl draaide (de geïsoleerde Docker-omgeving of de beheerde cloudomgeving), en de developer-agent de bijbehorende capability bezit.
Voorbeelden van de draaiende applicatie
Live voorbeelden staan standaard aan; een admin of manager kan ze voor de workspace uitzetten onder Instellingen → Overzicht & voortgang → Instellingen van deze workspace (Mensen een draaiend voorbeeld laten openen). Ze vragen daarnaast dat automatische omgevingsontdekking aan staat — een voorbeeld kan alleen bovenop een geverifieerde omgeving worden geopend, en die geverifieerde omgeving is precies wat ontdekking oplevert. Een voorbeeld houdt een sandboxomgeving in leven nadat de run al klaar is; daarom draaien er per workspace maximaal drie tegelijk, stopt elk na 30 minuten zonder gebruik of na 4 uur, en moet het binnen 20 minuten klaarstaan.
Iemand met projectbeheerrechten kan een voorbeeld openen: FixControl start de applicatie in de sandbox, wacht tot ze haar eigen health-check beantwoordt, en stelt die ene applicatie een beperkte tijd beschikbaar aan ingelogde mensen in je organisatie.
Een voorbeeld starten duurt een paar minuten, dus je hoeft de pagina niet open te houden: wie het startte, krijgt een melding zodra het klaar is — of dat het niet is gestart, met de reden — met een link terug naar waar het werd gestart.
Wat dat wel en niet opent:
- Er wordt geen poort gepubliceerd. Het sandboxnetwerk blijft gesloten en FixControl bereikt de draaiende applicatie over het interne netwerk van die ene run. Databases, caches en andere services in de omgeving zijn via een voorbeeld niet bereikbaar; precies één applicatiedoel wel.
- Een voorbeeld is geen deelbare link. Kijkers moeten ingelogd zijn, in de juiste organisatie, met settings-leesrechten op het project (een voorbeeld aanmaken en een oordeel vastleggen vragen beide settings-beheerrechten). Er is geen publieke deellink. Waar elk voorbeeld een eigen hostnaam heeft, draagt het eerste request een eenmalige overdracht die zestig seconden geldig is, aan dat ene voorbeeld gebonden is en meteen wordt ingewisseld voor een gewone sessiecookie die alleen op die host bestaat — doorsturen of hergebruiken kan niet.
- Het stopt vanzelf. Elk voorbeeld heeft een tijdslimiet en er geldt een maximum aantal voorbeelden per organisatie; verlopen, handmatig stoppen of een gecrashte applicatie beëindigen het, en de omgeving wordt daarna opgeruimd. Aanmaken, bekijken, stoppen en beoordelen worden alle als auditgebeurtenis vastgelegd.
- Je kunt de applicatie gebruiken, niet alleen bekijken. De gateway stuurt
GETenHEADoveral door, en stuurt formulierinzendingen en andere schrijfacties (POST,PUT,PATCH,DELETE) door zodra het voorbeeld op een eigen hostnaam draait — je kunt dus inloggen en een flow doorlopen. WebSocket-upgrades worden nog niet doorgestuurd; een pagina die een live socket nodig heeft, valt terug op wat ze zonder die socket doet. - Voorbeelden draaien in de geïsoleerde omgeving van FixControl zelf, ook in de beheerde cloudomgeving. Een voorbeeld binnen je eigen Kubernetes-cluster hoort hier niet bij — dat zou een pad naar je cluster openen dat vandaag niet bestaat. Om dezelfde reden krijgt een project waarvan het residency-beleid uitvoering aan klantzijde vereist helemaal geen voorbeeld: het verzoek wordt met die reden geweigerd, in plaats van stilletjes terug te vallen op een run aan FixControl-zijde.
- Hostnamen per voorbeeld zijn een voorwaarde voor de beheerder, geen standaard. Zolang de FixControl-beheerder geen origin-sjabloon voor voorbeelden heeft ingesteld (waarvoor wildcard-DNS en een wildcard-certificaat op de FixControl-deployment nodig zijn), worden voorbeelden onder een gedeeld pad geserveerd en renderen ze alleen goed voor applicaties die hun assets relatief adresseren. Een applicatie die root-absolute assetpaden uitstuurt — de meeste PHP- en Rails-applicaties doen dat — heeft die eigen hostnaam nodig voordat stylesheets en scripts laden. Diezelfde hostnaam is wat formulierinzendingen in het punt hierboven mogelijk maakt.
Na het bekijken kan een beoordelaar een oordeel vastleggen: dit ziet er goed uit of dit ziet er niet goed uit. Dat oordeel is menselijk bewijs en wordt naast de automatische validatie vastgelegd, met naam en moment. Het vervangt nooit een testresultaat, het opent op zichzelf nooit een goedkeuringspoort, en het telt niet langer als bewijs zodra de geverifieerde omgeving waarop het gevormd is, vervangen wordt.
Wie er een mag draaien
Drie aparte rechten, want het zijn drie verschillende bevoegdheden:
- Lezen van een run, het detail, de live stream en de CI-status van een wijziging — admins, managers en operators.
- Starten en annuleren van een run — ook admins, managers en operators. Een rapport lezen en een container uitgeven zijn verschillende dingen, maar een operator die werk voorbij ziet komen moet een controle opnieuw kunnen draaien zonder het aan iemand anders te vragen.
- Het verificatieoordeel bewerken — alleen admins en managers. Dat is de poort die lezen nooit mag kunnen openen.
Een run archiveren en terugzetten valt onder het algemene archiefrecht: dat is alleen zichtbaarheid, en omkeerbaar.
De runlijst beheren
Sandbox-runs stapelen zich op. De pagina Sandbox runs filtert ze op uitkomst — geslaagd, gefaald, fout gelopen (error of timeout, samengenomen omdat het mentale model "niet geslaagd, niet netjes gefaald" is), geannuleerd, draaiend — en laat je de lijst opruimen zonder iets kwijt te raken:
- Archiveer een afgeronde run, vanaf de rij of in bulk. Archiveren is puur zichtbaarheid: het verdict, de logs, het bewijs en elke poort die naar die run verwees blijven onaangeroerd, en de run blijft op zijn id te openen. Wie hem archiveerde en wanneer staan op de run zelf, zodat het spoor beide vragen nog beantwoordt nadat de auditgebeurtenis is verlopen.
- Gearchiveerd is een eigen weergave, van waaruit dezelfde runs in bulk of één voor één teruggezet kunnen worden.
- Een run die nog draait kan niet gearchiveerd worden — de server weigert dat, dus de actie wordt verborgen in plaats van aangeboden en daarna afgewezen.
Bewijs
Elke groene run legt vast:
- de genormaliseerde omgevingsconfiguratie (een hash van de gevalideerde topologie),
- de exacte image-digests waarmee de services draaiden,
- het uitgevoerde plan (welke stappen liepen),
- voor in-cluster-runs: waar hij draaide — agent, cluster, namespace, operatie.
Samen vormen deze de validatie-fingerprint van de run. Een gewijzigde patch, image, configuratie of plan levert een andere fingerprint op, zodat verouderd bewijs nooit meelift. Het resultaat — inclusief de fingerprint en, waar van toepassing, de resultaten per lane — wordt bevroren in de goedkeuring die erop steunt, en verschijnt in het deployment-provenance-spoor naast de goedkeuring en de rollout waartoe ze leidde.
Waar je governance-beleid het vereist, weigert de patch-poort een wijziging toe te passen waarvan de huidige versie geen passend groen bewijs heeft (zie Governance & beleid, verificatiebeleid).
Als validatie faalt
Een falen levert gestructureerd bewijs op, geclassificeerd naar soort:
- Applicatiefouten — een rode test, een crash bij het opstarten, een service die nooit ready werd. Deze kunnen een nieuwe, door AI voorbereide revisie van de wijziging voeden, die van voren af aan door validatie en goedkeuring gaat.
- Infrastructuurfouten — een image die niet binnengehaald kon worden, een onbereikbare runner, een verlopen operatie. Deze verschijnen als health-bevindingen voor een beheerder en veroorzaken bewust geen codewijziging: een kapotte omgeving is geen bug in je applicatie.
In beide gevallen blijft governance tussen analyse en uitvoering staan: een falen betekent nooit dat een niet-beoordeelde wijziging je systemen bereikt.
Zie ook: FC Agent · DevOps & CI/CD · Governance & beleid.