Skip to content

computer-mcp 0.2.1: everything a person can delegate — send port, screen lending, password fields fail closed - #6

Open
GLouv wants to merge 72 commits into
mainfrom
proeve/rettelser-2026-09-28
Open

GLouv wants to merge 72 commits into
mainfrom
proeve/rettelser-2026-09-28

Conversation

@GLouv

@GLouv GLouv commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

computer-mcp 0.2.1 — «everything a person can delegate»

Everything since 0.1.0, built on a clean macOS 15 runner (the «Fremmed Mac» workflow). Nothing here is published; merging does not publish — udgiv-npm.yml now requires the udgivelse environment, and the npm tag it needs doesn't exist yet either (see below).

What it adds

  • Password fields are refused on every write path — computer_type (checked before every character, including a Tab into a password field halfway through), computer_set_value, and blackout in screenshots. An AX lookup that fails is treated as secure (fail closed).
  • Consent shows the whole action (up to 4,000 characters, wrapped in the menu bar icon); anything longer is not asked. Consent goes through the icon with Touch ID in the foreground too; the dialog is only a fallback when the icon is not running.
  • computer_ask_user works in background mode — the question waits in the icon («Take me there», «Done»); Done is a signal, never a consent.
  • Send port: in listed chat and mail apps and recognised web chats/webmail, Send (pressed, clicked, several languages, nameless buttons) and Return in chat asks for that one message, showing the recipient and text read from the screen by the server. The Send control must sit next to the text field in the conversation's window; if anything cannot be read, nothing is sent. What would be sent is re-checked under the lock.
  • Screen lending: computer_request_screen — the person lends one agent the screen with Touch ID for at most 15 minutes; each step waits while the person uses keyboard or mouse; «Take the screen back now» ends it and stops a running step (paste stops before Cmd+V and restores the clipboard). CMCP_BACKGROUND set locks it out.
  • computer_permissions names the rules in your client that walk around the gate (shell, sudo, osascript, interpreters, browser/computer automation). SECURITY.md says plainly what the gate is and is not.
  • The door (computer_open), macOS 15 builds, honest foreground claims, fail-closed per-app lock.

How it was checked (updated 2/10 — supersedes the earlier «every finding fixed» claim)

review-security found 11 findings (F1–F11) in this PR's code. Gustav's decision (2/10): fix F1 and F5, accept F2–F4 and F6–F11 as known risk for 0.2.1.

  • F1 (Critical — fixed, verified): an ownership-match exception in knapErFarlig reopened the exact fail-open gap the gate exists to close. The exception is gone — found:false now always asks, no exceptions (46e3cdc). A follow-up mutation-coverage gap from the dedup that fix required was also found and fixed (2ba02e6, b184854).
  • F5 (Important — fixed, verified): computer_press's danger-check failed open on a dry-run timeout or a missing would_press (read as "harmless" instead of "unknown") — the exact asymmetry already fixed for clicks in F1, just on the other branch. Now fails closed like the click path, mutation-proven both ways (test/knap-ord.mjs cases 11–12, mutants Q27–Q28).
  • Accepted as known risk for 0.2.1 (Gustav, 2/10): F2 (nameless AXLink/AXStaticText web-link click bypass, Important), F3 (click can land on a different/covering app's element when found:true, Important), F4, F6–F11 (Suggestion-severity).
  • A second, independent gap found by this session's review AND a sibling chat's Astra+Opus panel (2/10): the "no agent took the screen" claim (used in docs copy) is not fully measured — test/parallel.mjs explicitly filters com.apple.finder out of its per-agent screen-ownership check, so a Finder self-activation (a known, previously-logged macOS quirk) passes that check silently even when Finder did take the foreground. Not fixed; disclosed.
  • Fremmed Mac CI was red on 7 consecutive pushes (f22496a → 46e3cdc) before the F1 coverage gap was found and fixed (b184854, confirmed green). Three more commits (release-script fixes, unrelated to tested code paths) and this F5 fix followed; see commit history for the exact frozen SHA this PR merges at.
  • Earlier in this PR's life: five review rounds by two independent models (Astra, Fable) on the pre-regression code, final verdicts GODKENDT from both.

Known limitations (unmeasured, stated in README/SECURITY)

  • Send port against real messaging apps (layout-dependent binding; Slack/Teams may be refused rather than asked).
  • Web chats are recognised by page title; a chat on an unlisted site is not.
  • Touch ID and the human-input pause are unmeasured on real hardware; exclusivity between two servers is enforced by the icon but not measured live.
  • The "no agent took the screen" guarantee does not cover Finder (see above).
  • F2–F4, F6–F11 from review-security (see above) — accepted as known risk for 0.2.1.

🤖 Generated with Claude Code

Gustav Louv and others added 30 commits September 28, 2026 16:52
…e port

- ci/release/udgiv-npm: macos-14 -> macos-15 (SCRecordingOutput mangler i 14-SDK, CI rød på main)
- README + vejledning: fjern 'nothing comes to the front'; sig at forgrunden gives tilbage
- menu-needs-front: 'may be' i stedet for påstået årsag; peg ikke paa en vej der afvises bagfra
- brugsscenarier: skærm taget (selv med tilbagegivning) = 'delvist', ikke 'bevist' (MANDAT)
- fremmed-mac: samlende port fejler jobbet hvis suite/mutant/scenarier ikke bestod

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…skets at give

Gustav 28/9: modellen skal vide den kan alt et menneske kan, og enten finde vejen
eller spørge (computer_ask_user) frem for at stoppe. Login/kodeord, afsendelse til
et rigtigt menneske, og forgrund er menneskets; aldrig taste kodeord, aldrig omgå
en afvisning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…laim 45 groen)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fandt af batch-2-hærdningen (29 bekræftede huller): programlaas.js:45 kørte
handlingen alligevel ved enhver ikke-EEXIST låsefejl (ENOTDIR/EACCES). To agenter
kunne skrive i flæng i samme program - netop det låsen skal forhindre. Nu:
kan låsen ikke tages, sker handlingen ikke, med en ærlig grund (infra, ikke contention).
Prøve test/laas-fejler-lukket.mjs tvinger ENOTDIR frem; revert af M1 gør den rød.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fandt af batch-2-review'et: givTilbage() gav forgrunden tilbage naar maalprogrammet
kom frem UANSET nyligt menneske-input - klikkede mennesket selv over i dét program,
rev vi det tilbage. Nu gaelder menneske-tjekket i alle grene, og et forgrunds-skift
vi lader staa rapporteres aerligt (took_screen:true, gave_back:false) i stedet for
et tavst false. Paa en maskine uden menneske (køreren) er adfaerden uaendret, saa
giv-tilbage-mutanten verificerer fortsat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
M4-ændringen fjernede den linje den gamle mutant patchede (efter.forrestPid==maal
|| !menneskeRoerteNetop()), saa mutanten kunne ikke anvendes og 'overlevede'
falsk. Ny mutant: faa menneske-tjekket til altid at fyre -> forgrunden gives
aldrig tilbage -> proeven bliver roed. Beviser M4's invariant paa en maskine uden menneske.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kert

Baggrunds-doeren fra batch-2-spec'en, foerste skive. Modellen giver et intent
(open_app/play_track/open_chat) + EN typet parameter, ALDRIG en URL - serveren
bygger en fast app-URL og validerer parameteren strengt (kun cifre/bogstaver).
Helperen aabner den med NSWorkspace .withoutActivation og dobbelt-tjekker mod en
haardkodet scheme-allowlist (spotify/whatsapp/claude). Doeren navngiver sit maal
via intent'et, saa porten ikke kalder den 'ukendt maal'. Baerer navigation, ALDRIG
et send. test/doer.mjs (8 tjek) beviser: intet url-felt at injicere i, bad
id/phone/bundle/intent afvist, praecis app-URL bygget. Swift-open-url + funktionen
verificeres paa hhv. koereren og Gustavs Mac.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tilfoej computer_open til vaerktoejslisterne (README, llms.txt, tools.html,
capability-matrix), bump tool-tallet 30->31 (14 laesende, 17 skrivende) paa alle
tekstflader + gemini-extension.json. Udvid ORD-ordlisten i baade sync-tal.py og
claims.mjs forbi 'thirty' (crashede/parsede undefined ved 31). Ret to test-hygiejne-
fund: doer.mjs saetter fake osascript (vagt 26), og open-url's fejltekst hejser
join'et ud i en variabel saa lintens streng-udtraekker ikke eksponerer et dansk
variabelnavn (vagt 27). claims.mjs groen. Ingen kode-logik roert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ut-bug

- main.swift: computer_open's open-url smed sem.wait-resultatet vaek -> en TIMEOUT
  rapporterede 'aabnet' i stedet for fejl. Nu er timeout en fejl (open-timeout).
- tools.js: doeren lovede 'without bringing it to the front' (umaalt) + 'the person
  confirms it' (ikke haandhaevet). Nu aerligt: aktiverer ikke, men kan komme frem og
  gives tilbage; send er en separat handling uden indbygget bekraeftelse.
- CHANGELOG 0.2.1: fjern 'Only a switch to the target app is counted' (M4 gjorde den
  falsk; release.sh laver GitHub-noter af dette afsnit), tilfoej doeren + M1-laasen.
- README: 'Twenty are offered'->23, 'twelve that only look'->14 (drift claims.mjs ikke fanger).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…owlist + udvid release.sh ord-liste forbi thirty

Fable-review: 'claude' var i helperens open-url-allowlist uden at noget intent byggede
den (død angrebsflade) - fjernet. release.sh's WORDS stoppede ved 'thirty', saa ved 31
vaerktoejer blev $WORD tom og regex'en matchede alt (samme fejlklasse som sync-tal/claims,
allerede rettet der) - udvidet til forty. Ikke-blokerende, defensivt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ny ledende differentiator-bullet: Claude Code/Cursor/VS Code/Codex/Windsurf/Zed/egen
agent - samme npx-server overalt, ikke bundet til én leverandørs desktop-app eller plan.
Universaliteten stod kun i install-sektionen, ikke i overskriften.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Anthropics mcpb-CLI (v2.1.2). Manifest 0.3 + scripts/build-mcpb.sh bygger en
self-contained bundle: server-filer + node_modules + vendor (helper+status-app),
node ekstry_point (ikke npx, matcher MCPB-designet). Bygget+valideret+pakket lokalt:
computer-mcp-0.2.1.mcpb, 4,3 MB, 2377 filer, mcpb validate grøn. Artefakten gitignored
(bygges on demand). Indsendelse til Smithery + notarisering forbliver Gustavs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ikke ikonet/Touch ID

dcf361a lovede «computer_ask_user: question waits in the menu bar icon and the person
answers with Touch ID». MÅLT: ask_user er i TAGER_SKAERMEN (afvises i baggrund) og dens
handler kalder askHumanToDo = en osascript-boks, ikke ikonet, ingen Touch ID. Teksten er
nu sand: ask_user er en forgrunds-prompt (afvist i ren baggrund), mennesket taster selv
hemmeligheder, og ikon-consent-porten (computer_pending) er en SEPARAT mekanisme for
skrivehandlinger. Samme ærligheds-klasse som forgrunds-løfterne i 47c80f2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Panelet 29/9 (Astra + Fable): kun set_value naegtede sikre felter. type faldt
tilbage til tastetryk og tastede i kodeordsfeltet, og «bruger<Tab>kode» hoppede
ind i feltet midt i teksten. Nu spoerges foer hvert tegn; efter Tab/Enter ventes
der paa fokusskiftet.

Proeve: skriv-ankommer 3/3k/3b (ingen tekst) + 3c (fokus flytter undervejs,
SIGUSR1 i fixturen). Mutationsbevis M5 (opslaget siger aldrig sikkert) og M6
(tjek kun ved start) skal begge give roedt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Panelet 29/9: protokollen klippede teksten ved 200 tegn og Touch ID-arket ved
80, uden at sige det. Et ja daekkede noget mennesket aldrig saa.

- serveren sender teksten hel (op til 4.000 tegn); en laengere spoerges ikke
- ikonet viser den ombrudt i undermenuen lige over «Allow…», i sort
- Touch ID-arket siger naar det forkorter, og hvor resten staar
- ikonet laeser op til 64 KB (16 KB kunne klippe)

Proever: ikon-godkend A14 (hel tekst) + A15 (over loftet: ikke spurgt),
ny test/ombryd.mjs (intet tegn falder ud, ingen linje over 64). Mutationer af
alle tre vagter giver roedt (koert lokalt).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Panelet 29/9: porten er brugt 3 gange paa ni dage - bevis fejlvejene foer
den udvides. Ny F-blok i ikon-godkend (falsk ikon, ingen skaerm):
F1 ikonet gaar ned midt i spoergsmaalet -> nej · F1b naeste spoergsmaal virker
straks · F2 ulaeseligt svar -> nej · F3 svar i to stykker -> ja · F4 ikonet
vaek -> afvist uden at haenge · F4b nyt ikon -> porten virker igen.

Og en instrumentfejl: «sent-ja» brugte `sock` uden at closuren fik den, saa
det sene ja blev aldrig sendt (ReferenceError slugt af try{}). A13 maalte
kun «intet svar».

Mutationer (lokalt): venter aldrig nulstillet, buffer overskrevet, lukket
forbindelse = ja - alle tre giver roedt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e-ikonet

Panelet 29/9 (Fable): vejledningen lovede at ask_user venter i ikonet med
Touch ID; i virkeligheden var den skjult i baggrund og en osascript-boks i
forgrund. En agent der ramte et kodeord eller en 2FA-kode kunne kun give op.

- ny spoergsmaalstype «goer-selv» i ikonet: hele teksten, hvor det lander
  (skrevet af serveren), «Take me there» (MENNESKETS klik henter frem),
  «Done — I did it» og «I won't do this»
- «Done» er et signal, ikke et samtykke: godtages KUN paa et goer-selv-
  spoergsmaal, saa det aldrig kan blive et ja til en anden handling
- i baggrund kraever den `app`; uden ikon afvises den, aldrig en dialog
- 24 af 31 tilbydes nu i baggrund (fra 23); README, site og vejledning rettet
  (capability-matrix bar ogsaa S1's nu usande «every password field gets
  keystrokes»)

Proever: ikon-godkend del E (E1 goer-selv + serverens «hvor» + done:true +
ingen dialog · E2 nej · E3 «done» paa et samtykke = nej), baggrund-stille 2b.
Mutationer (lokalt): «done» godtaget overalt -> E3 roed; modellen skriver
«hvor» -> E1 roed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dommen 28/9 (D4 + trin 7): foer fandtes intet beskedapp-begreb, og Send i
WhatsApp gik igennem i allow uden at nogen blev spurgt.

- BESKED_APPS (WhatsApp, Messages, Mail, Slack, Telegram, Signal, Discord,
  Teams, Outlook, Messenger, Spark, Superhuman, FaceTime)
- afsendelse = Send trykket (press --dry: samme element som trykket) eller
  klikket (at: navnet under punktet), Return/Enter med enhver modifikator,
  Mails cmd+shift+d, et menupunkt der hedder Send/Reply
- spoergsmaalet viser modtager og tekst LAEST AF SERVEREN fra skaermen (ny
  hjaelper-kommando `samtale`), aldrig modellens ord; ulaeseligt siges aabent
- linjeskift i computer_type i en beskedapp afvises (det sender)
- genkontrol under laasen: aendres modtager/tekst efter ja, sendes intet
- kan det ikke afgoeres om noget sender, spoerges der (fejler lukket)

Proeve: test/sende-port.mjs (a/a2/b x6/c x3/d/d2/d3/g/u, falsk ikon + falsk
hjaelper med scriptede skaerm-svar, ingen skaerm). (e)+(f) = ikon-godkend
A7/A13/E3. Mutationer lokalt: ikke spurgt · return ikke send · linjeskift
slipper · ingen genkontrol · modellen skriver modtager - alle fem roede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… den tilbage

Panelet 29/9 (B2 + B5): forgrund kunne kun slaas til med CMCP_BACKGROUND=0
og en genstart, pr. server - 21 servere kunne vaere uenige om én skaerm, og
syv vaerktoejer var uden for raekkevidde for en agent der manglede ét traek.

- nyt vaerktoej computer_request_screen (request/release/status): mennesket
  godkender i menulinje-ikonet med Touch ID, hoejst 15 minutter, én agent ad
  gangen («optaget» er ikke et menneskes nej)
- laanet ER den aabne forbindelse til ikonet: tiden gaar, «Take the screen back
  now», ikonet doer eller serveren doer -> forbindelsen lukkes -> slut. Intet
  paa disk en agent kan pille ved. Serverens eget ur gaelder ogsaa.
- vaerktoejslisten meldes aendret (tools/list_changed) ved start og slut
- B5: under laanet pauser hver skaerm-tagende handling, naar mennesket bruger
  tastatur/mus; input FOER vores egen sidste handling taeller ikke (ny
  hjaelper-kommando `idle`). Kan det ikke laeses: intet sker.
- CMCP_BACKGROUND sat er et loft: intet laan, ikonet spoerges ikke
- ét samtykke-spor: ogsaa i forgrunden spoerges ikonet (Touch ID) foerst;
  osascript-boksen er kun faldbag naar ikonet ikke koerer
- 32 vaerktoejer, 25 tilbudt i baggrund; README, site, llms, gemini rettet

Proeve: test/skaerm-laan.mjs (19 tjek, falsk ikon + falsk hjaelper). Mutationer
lokalt: laan virker ikke · tilbagetagning ignoreret · menneske ignoreret ·
loft ignoreret · ikonets ur ignoreret - alle fem roede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Panelet 29/9 (B6, «sikkerhedskontrol uden for agenten»): koden indroemmer
selv at porten ikke er et faengsel - en agent med shell under samme bruger kan
klikke med osascript, og browser-automation kan sende fra webmail, helt uden
om serveren. Intet i pakken kan forhindre det (alt er skrivbart for samme
bruger). Kontrollen der ligger uden for agenten, er klientens tilladelser.

- computer_permissions laeser Claude Code's settings (kun laesning) og naevner
  KUN de regler der er omveje: aaben Bash, osascript, browser klik/udfyld/
  naviger/eksekver. Andre klienter laeses ikke - og det siges.
- SECURITY.md: «What the consent gate is, and is not»; README + CHANGELOG

Proeve: test/omveje.mjs (8 tjek, midlertidig indstillingsfil). Mutationer
lokalt: osascript overset · alt naevnes (laek) - begge roede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ring

MANDAT: hver vagt skal kunne blive roed. De 20 mutanter jeg koerte i haanden
for S2, S3, B3, B4, B2/B5 og B6 staar nu i .github/mutanter-porte.json og
koeres af .github/mutant-porte.py i «Mutationsbevis»-trinnet. Hver fil
gendannes fra en kopi (aldrig fra git) og hash-tjekkes bagefter.
Lokalt: 20 af 20 roede, 0 overlevede, 0 gendannelsesfejl.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Goer-selv, skaerm-laanet og den fulde tekst var kun kompileret i ikonet.
Undermenuens indhold bygges nu af én ren funktion (spoergsmaalMenu) som baade
menuen og `cmcp-status --dump-question` bruger - uden at ikonet vises.

Proeve: test/ikon-menu.mjs (samtykke Allow/Deny + hel tekst + tegn-antal +
Touch ID-arkets «forkortet»; goer-selv uden Allow; laan med minutter, loft 15,
«Take the screen back now»; linjeskift kan ikke tegne knapper). Vaelger den
nyeste binaer og draeber efter 10 s: en aeldre ville starte det rigtige ikon.
Mutation lokalt: goer-selv faar Allow -> roed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Panelet 30/9 (Astra + Fable, begge IKKE GODKENDT):
- R1 (Astra 7, Fable F1): osascript-boksen var faldbag for ALLE «ikke spurgt»
  - ogsaa efter et nej, over loftet, med et ventende spoergsmaal. Under et laan
  er serveren i forgrund, saa et nej i ikonet kunne omgaas. Nu kun naar ikonet
  ikke koerer (`ikkeKoerer`).
- R2 (Astra 4): et skaerm-kald der ventede paa laasen, mens laanet sluttede,
  blev udfoert. Nu genmaales under laasen; og skaerm-tagende hjaelpere der
  koerer, draebes naar laanet slutter.
- R8 (Astra 5, Fable F2): pausen gaelder ALLE skrivende kald under laanet
  (ogsaa stille med app); menneske = input nyere end vores egen sidste handling.
- R9 (Astra 8): en laanegrund over 4.000 tegn spoerges ikke (klippedes tavst).
- R12 (Fable F5): intet laan uden at loggen kan skrives.
- R13 (Fable F6): udloeb paa eget ur meldte ikke vaerktoejslisten.

Proever: ikon-godkend G1-G3; skaerm-laan 5c, 5d, 6b, 7b, 9b - og proeven
scripter nu «hvem er forrest» og «hvem ejer punktet», saa den aldrig laeser den
rigtige skaerm (6b var groen af forkert grund; 5 koersler i traek groenne).
Mutanter lokalt: R1, R2, R8x2, R9, R13 (oprindelig fejl) - alle roede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Panelet 30/9 (Astra + Fable, begge IKKE GODKENDT):
- R4 (Astra 2): genkontrollen koerte kun naar foerste dom var «send»; nu doemmes
  der ALTID igen hvor noget kan sende, og dommen skal vaere identisk
- R5 (Astra 3, Fable P4): fingeraftryk af hele aflaesningen (vindue, alle
  overskrifter, tekst); ulaeselig modtager ELLER tekst -> intet sendes; modtageren
  laeses i feltets kolonne over feltet (ikke sidebarens oeverste navn)
- R6 (Astra 1, Fable F3/P3): send-ord paa 8 sprog (Afsend, Besvar, Envoyer ...);
  en navnloes KNAP er en mulig send; mellemrum paa en knap; webchat/webmail i en
  browser genkendt paa vinduets titel; flere apps paa listen
- R7 (Fable F8/P6/F4): chat og mail adskilt - i mail er Return en ny linje og en
  mail med afsnit kan skrives; i chat afvises alle styretegn undtagen tab
- R14 (Fable F7): FaceTime ud - et opkald er ikke en besked
- R3 (Astra 6): kodeordsvagten fejler LUKKET - ukendt fokus/rolle stopper skrivningen
- R10 (Astra 9): mutationsporten kraever rc 1 + en DUMP-linje; alt andet er en
  instrumentfejl, ikke et bevis; mutanter med flere aendringer understoettes
- R11 (Astra 10, Fable P1): README «Twenty-four» -> 25, og claim 42d vogter tallet
- R15 (Fable P5): omvejs-listen fanger skaller/fortolkere (bash, zsh, python3,
  node ...) og hele browser-servere - tre stod i husets egne indstillinger

Og to fund undervejs:
- et navnloest MENUPUNKT (Apple-menuen i en chat-apps menulinje) er ikke en
  send-knap - claim 35 blev roed paa Gustavs Mac fordi WhatsApp var forrest
- privatliv: den falske hjaelper sendte `samtale` videre til den rigtige, saa en
  proeve kunne laese en udviklers rigtige chats; uscriptet svarer den nu tomt

Proever: sende-port 37 tjek, skaerm-laan, ikon-godkend, omveje 4b/4c, claims 42d,
skriv-ankommer 4/4b (kolonne-aflaesning mod proevemaalet - kun paa CI).
Mutanter lokalt: 33 af 33 roede, 0 overlevede, 0 instrumentfejl.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Astra R2 (IKKE GODKENDT) + Fable R2 (GODKENDT m. anbefalinger):
- Q1 (Astra 1): laanets nummer blev talt op FOER spoergsmaalet, saa en samtidig
  anmodning gjorde det godkendte laans slut ugyldigt - laanet sluttede aldrig.
  Nu faar kun et ja et nummer. En skrivning doemt under et laan sker ikke, hvis
  laanet er slut lige foer udfoerelsen (efter alle opslag). Ved laanets slut
  draebes ALLE hjaelper-processer der ikke er rene opslag (Fable 3: stille type,
  paste, launch, vindueskald fortsatte), og svaret siger «took the screen back».
  Et laan der ikke kan skrives i loggen efter ja'et, gives ikke.
- Q5 (Astra 5): kun handlinger der poster input flytter «vores sidste handling».
- Q6 (Astra 6): loft, pause og ventende spoergsmaal tjekkes FOER det afgoeres om
  ikonet koerer - ellers blev et manglende ikon til en boks lige efter et nej.
- Fable 9: afvisninger i forgrund havner i computer_pending (koe); release
  logges én gang.

Proever: ikon-godkend G3a/G3b/G3c (G3c i frisk proces), skaerm-laan 6c/6d/6e
(falsk hjaelper kan nu «arbejde» i _vent ms; falsk ikon kan svare langsomt).
Mutanter lokalt: ingen binding, stille draebes ikke, oprindelig nummerfejl
(to aendringer) - alle roede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Q4 Q7 Q8 Q9

Astra R2 (IKKE GODKENDT) + Fable R2 (GODKENDT m. anbefalinger):
- Q2 (Astra 2): kodeordsvagten tabte opslagsfejl paa underrollen (`string()`) og
  AX-indsaettelsen skrev foer tjekket. Ny `sikkerStatus`: «findes ikke» ≠
  «fejlede»; ukendt stopper BEGGE skriveveje. `samtale` laeser kun vaerdien af
  et felt der VIDES ikke at vaere sikkert.
- Q3 (Astra 3, Fable 4): uden kolonne (feltets ramme) intet send; et soegefelt
  er ikke en besked; Send-knappen skal ligge i samtalens vindue (press --dry og
  at melder nu vinduet); kun foerste overskrift vises som modtager.
- Q4 (Astra 4, Fable 7): browser med ulaeselig titel = chat (fejl lukket); chat
  foer mail («Gmail - Slack»); forankrede navne, signal ude, Google Chat ind;
  flere browser-id'er.
- Q9 (Fable 2): ved et KLIK er et navnloest element kun send hvis knap/billede.
- Q8 (Fable 1): omveje fanger sudo, fuld sti, npx playwright, env/xargs, Claude in
  Chrome, computer-use, remote-devices; README/SECURITY: «the rules it recognises».
- Q7 (Astra 7): M5 var brækket af min egen R3 (anker 0 traef - CI ville vaere
  roed); genankret. Shell-runneren fejler nu ved manglende anker og kraever rc 1
  + DUMP. Hver JS-mutant har `forventet`: kun DENS prove taeller som bevis.
- To overlevende mutanter afsloerede dublerede vagter (loftet to steder; «laanet
  sluttede mens kaldet ventede» to steder). Én vagt pr. regel nu.
- Svage tjek skaerpet: «spoerger ikke» kraever nu ogsaa at handlingen skete.

Proever: sende-port 49 tjek (q3, q4, q9, Cmd+Return i mail, webmail), omveje
4d/4e. Mutanter lokalt: 44 af 44 roede i den forventede prove, 0 overlevede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-kontrollens binding

Astra R3 (IKKE GODKENDT, 6) + Fable R3 (IKKE GODKENDT, 1):
- Fable R3: `isSecure` (set_value, sloeringen, focused, inspect) tabte stadig en
  fejl paa underrollen. Rettet i ÉT sted: isSecure = sikkerStatus != false, saa
  alle syv kaldesteder er fejl-lukkede. skriv-ankommer 3s/3sw: set_value i et
  kodeordsfelt afvises (M5 daekker nu ogsaa den vej).
- Astra R3 1: laanVedDom blev taget 40 linjer efter baggrundsporten; nu i samme
  synkrone oejeblik.
- Astra R3 2: Send-kontrollens vindue SKAL kunne laeses, og kontrollen skal ligge
  paa beskedfeltets raekke (samtale/at giver nu rammer).
- Astra R3 3: en ukendt rolle ved et klik er en mulig send (kun kendt ufarlig
  rolle som AXGroup er undtaget).
- Astra R3 5: en skrivning via tilgaengeligheds-laget flytter ikke «vores sidste
  input»; computer_space gør. Laanets tekst + README siger aerligt: hvert trin
  venter mens du bruger tastatur/mus; et trin der koerer, bliver faerdigt - eller
  stoppes naar du tager skaermen.
- Astra R3 4 (browser, ukendt side): IKKE aendret - et produktvalg (se tråden).
  README siger nu praecis hvilke sider der genkendes. X tilbage paa listen.
- Astra R3 6: shell-runneren binder nu ogsaa til den forventede prove.
- Smaat: press --dry og paste draebes ikke ved laanets slut (paste ville tabe
  udklipsholderen); aerlig besked «the screen loan ended»; env bash i omveje;
  kommentaren i spoerg fortaeller hvorfor venter/pause tjekkes igen efter await.

Mutanter lokalt: 47 af 47 roede i den forventede prove, 0 overlevede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Swift-mutanternes forventede tjek

GitHubs Mac, 2485a66: Suiten failure paa «klik rammer ejeren» tjek 6 - sende-
porten afviste et almindeligt klik i Chrome, fordi prooevens stub ikke svarede
paa `samtale`, og Q4 goer en ulaeselig browsertitel til chat (Fable R3 h
forudsagde det). Og hvert klik i en browser koerte hele samtale-aflaesningen
(op til 4.000 elementer) bare for titlen.
- `samtale --title-only`: kun vinduets titel, billigt; bruges til browserens klasse
- klik-ejer-stubben svarer med en almindelig sidetitel
- Swift-mutanterne M1-M4 blev roede paa tjek 2b/2/3 (ikke 4b som jeg satte i
  9370f0d); FORVENTET rettet efter CI-loggen

Lokalt: 9 stub-prover groenne, 47/47 JS-mutanter roede.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, AX-stemplet, paste

Astra R4 (IKKE GODKENDT, 4) + Fable R4 (IKKE GODKENDT, 1 - = Astra 3):
- Astra 1: laanets tilstand tages ved KALDETS START, foer den foerste vagt der
  afhaenger af det; aendres den undervejs (sluttet, begyndt, skiftet) sker intet.
- Astra 2: Send-kontrollen skal ligge VED SIDEN AF beskedfeltet (samme raekke og
  hoejst 160 pt til hoejre); et opslag der fejler, afviser (erKontrol foer
  opslaget); i en browser doemmes ogsaa kontrollens vindue - naar det er LAEST
  (en manglende titel er ikke en chat: klik-ejer 1/9 var roed af det).
- Astra 3 / Fable 1: min runde 3-rettelse var DOED KODE - den ledte efter
  «method» i svarets prosa. Nu et struktureret, ikke-talt felt; stemplet flyttes
  kun efter en handling der lykkedes og postede input. Prove 5e + mutant.
- Astra 4: paste var undtaget fra afbrydelse; nu faar den SIGUSR1 og stopper FOER
  Cmd+V og laegger personens udklipsholder tilbage. Prove 6f.
- Fable 2/3: CHANGELOG og SECURITY siger det samme som README (titel-afgraensning
  under «Out of scope»); ikonets tekst: «messages in the apps and web chats it
  recognises». Shell-runnerens match er forankret til DUMP-linjer.
- CI b626996: skriv-ankommer 3s ledte efter ROLLEN AXSecureTextField; et native
  kodeordsfelt har den som UNDERROLLE. Rettet.
- Prover: forudsaetninger tjekkes nu (laanet blev givet, flytningen skete); 5d
  og 6b var TIMING paa en belastet maskine, ikke kodefejl; CMCP_MENNESKE_SEK
  (standard 1,5) giver proeven brede marginer.

Mutanter lokalt: 52 af 52 roede i den forventede prove (en fuld koersel + 5
genkoert efter instrumentfejl under belastning, som runneren korrekt ikke talte
som bevis; browser-mutanterne genkoert efter titel-rettelsen).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e-signalets opstart

Fable R5: GODKENDT. Astra R5: IKKE GODKENDT (3) - alle tre maalte og rettet:
- Astra 1: «intet laan -> laan -> intet laan» under ét kald saa ud som «uaendret»
  (0 === 0). Nu et generationsnummer der taeller hver aendring (laanOejeblik);
  enhver aendring under kaldet -> intet sker. Prove 6g + mutant (den gamle
  nul-binding goer praecis 6g roed).
- Astra 2 = Fable 1: en browser-Send-kontrol hvis vindue ikke kan laeses, blev
  ignoreret foer navnet blev doemt. Nu doemmes et ulaeseligt vindue som ukendt
  (chat, fejl-lukket). Prove r4d + mutant. klik-ejer-stubben giver nu vinduer som
  den rigtige hjaelper.
- Astra 3: SIG_IGN kom foer signalkilden - et SIGUSR1 i hullet blev tabt. Nu
  kilden FOERST (et signal foer SIG_IGN draeber processen foer noget er roert),
  helt oeverst i `paste`; en laas koordinerer «stop» med «tryk Cmd+V».
  Ny test/paste-stop.mjs maaler den RIGTIGE hjaelper (kun paa en fremmed maskine:
  et svigtende stop ville indsaette tekst) + Swift-mutanter M7/M8.
- Fable smaat: tools.js-teksten om «messages still ask» foelger README;
  CMCP_MENNESKE_SEK kan kun haeve graensen; shell-runnerens forventede praefiks
  skal staa forrest paa en DUMP-linje.

Lokalt: 14 stub-prover groenne; de 7 beroerte mutanter roede i den forventede
prove (fuld liste: 54, koeres paa GitHubs Mac).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gustav Louv and others added 16 commits October 1, 2026 21:29
…egne programmer (GitHubs Mac 36863990504)

MAALT: mens «mennesket» skrev i TextEdit, kom Finder frem, og giv-tilbage tog
skrivningen (keyDown) for et menneskeligt skift - alle 270/645/595 tegn landede i Finder.
Nu taeller kun klik, modifier (Cmd+Tab), rul og styrefladegestus. Mutant M11.
Oprydning: i baggrunden lukkes et program aldrig uden et menneskes ja (med vilje), saa
use case-programmerne stod aabne efter hver koersel i ugevis. Proeven lukker nu selv
de programmer den startede (SIGTERM paa deres pid), og roed hvis de stadig koerer.
M3's anker fulgt med launch-aendringen. Maalerens puls: én pr. 10 s under last.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kaerm-koe-panelet)

computer_press slaar knappens eget navn op (--dry), computer_click elementet under
punktet (at); samme ord som menuerne (menuSerFarlig). Ukendt navn: kan ikke doemmes
- et tryk der ikke kan slaas op, finder heller intet at trykke paa. test/knap-ord.mjs
(5 tjek) + mutant Q25 roed. Lommeregner-scenariet trykker ikke laengere «All Clear»
(et nystartet vindue staar paa 0); oprydningen trykker kun «Gem ikke».
Bivirkning: hvert tryk og klik laver ét ekstra opslag foer handlingen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… forgrund-dom og global tastatur-stroem

To stale mutant-ankre (B4-modellen-skriver-modtager, R5-svagt-fingeraftryk) fulgte
WhatsApp-rettelsens 'sam.recipient'-felt og blev opdateret + bekraeftet roede.

5.1b krævede 'TextEdit forrest hele vejen' - men et menu-klik (scenarie 15: cmd+n,
shift+cmd+g paa Finder) SKAL kort goere maalet forrest for at kunne klikke dets
menulinje. README (linje 204) lover selv aerligt 'took_screen'+'gave_back', ikke
nul beroering. Nu tolereres udsving der gives aerligt tilbage inden for 3,5 s
(giv-tilbage-vinduerne er 240/2000/4000 ms); kun permanente eller for langsomme
tilbagegivelser fejler.

5.3's '(r.tog||0)>0' duplikerede og overtrumfede dette - en scenarie der selv tog
og aerligt gav skaermen tilbage (koerScenariens egen 'delvist') blev talt som roed.
Fjernet; kun aegte 'fejlede' (inkl. IKKE-tilbagegivet skaerm) taeller nu.

Mennesket i TextEdit skrev via den globale tastatur-stroem (uden --app): under
Finders ~700 ms-udsving forsvandt tasterne ind i Finder i stedet, og TextEdits
dokument endte tomt selvom 'skrevet' talte dem med. Skriver nu med --app, via
tilgaengeligheds-laget (AX.indsaetIFokus), praecis som produktet selv skriver i
baggrunden - landes uanset hvad der tilfaeldigvis er forrest.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…koersel 36876560087)

«tePid» blev FOER gaettet ud fra skift-loggen foer runden startede. Staar mennesket
stille i de foerste 1,5 s (det almindelige - han skriver jo uden afbrydelser), er der
INTET skift at gaette ud fra, og [...new Set([])].pop() = undefined. Alle TextEdit-
tilbagevendinger blev saa selv talt som 'ikke tePid' og fejlagtigt vist som udsving
der ALDRIG blev givet tilbage - selvom den raa skift-log tydeligt viser korrekt
give-back (176/86 ms i runde 5).

Rettet: TextEdits PID laeses direkte fra apps-listen, mens vi VED den har fokus -
ikke gaettet bagefter af en muligvis tom log.

5.2 (menneskets tekst) er fortsat 0 efter --app-rettelsen i forrige commit, to
koersler i traek. I stedet for at gaette en tredje gang: hvert type-kalds raa svar
logges nu (sidste vinder), og traef-tallet fra find-opslaget tages med i fejlbeskeden
- saa naeste koersel viser os METODEN (accessibility/keystrokes) og om opslaget
overhovedet fandt elementet, i stedet for blot at gentage 'staar 0'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…60 s - og agenten skriver klikvejen i chatten foerst

MAALT i Gustavs chat-historik (skaerm-koe-panelet, Astra + Opus 5.5, begge
GODKENDT): 11 af 12 udloebne skaerm-anmodninger kom INDEN FOR 3 minutter efter
han sagde «klar»/«fortsaet». Han var der - men det almindelige 60 s-vindue
(CMCP_ASK_TIMEOUT, delt med alle andre samtykke-dialoger) naaede ikke at daekke
det. skaermVentetid() giver netop skaerm-anmodninger deres eget vindue: 5 min
som standard, loft 20 min (under Claude Codes 30 min-graense for lange MCP-kald
uden fremskridt, saa klienten aldrig selv afbryder kaldet mens det venter).

Vaerktoejsbeskrivelsen beder nu agenten skrive klikvejen i chatten FOER kaldet
(trin 8) - mennesket skal vide hvad der skal klikkes, ikke bare at noget venter.

Proever: offline-tjek af standard/loft/tilsidesaettelse (claims-offline.mjs, intet
GUI) + et live-tjek der beviser skaermVentetid() - IKKE askTimeout() - reelt
styrer ventetiden, ved at saette den kortere end askTimeout og vise at et svar
der kommer efter den udloeber (skaerm-laan.mjs #12). 17 eksisterende mutanter
for skaerm-laan.mjs/claims-offline.mjs stadig roede efter aendringen.

mcp-server/README.md genudledt af build-release.sh (tidligere drift fra README.md).

Dette er trin 1+8 af 9 fra den godkendte skaerm-koe-plan (DOM.md). Trin 2 (koe i
stedet for 'optaget') er den stoerste, mest arkitektoniske del og bygges som sin
egen skive.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sel 36884149245)

5.1b er nu GROEN i alle tre runder (tePid-rettelsen virkede). Tilbage stod 5.2
('menneskets tekst er intakt') - nu med diagnose: det SIDSTE type-kald lykkedes
og blev VERIFICERET af hjaelperen selv ('method':'accessibility','verified':true),
men 'find --role AXTextArea' fandt 2/3/4 traef paa tvaers af runderne (stigende
med 1 pr. runde) - min 'tekst()' tog altid det FOERSTE, som kunne vaere det
forkerte (et gammelt, tomt vindue).

Aarsagen: et almindeligt «killall TextEdit» venter paa appens egen
afslutningslogik, og et ugemt dokument rejser «Gem aendringer?» - som intet
svarer paa, saa vinduet bliver staaende. Naeste rundes nye TextEdit-vindue laa
saa OVENI de gamle. killall -9 spoerger ikke (her er intet vigtigt at gemme),
og luk() venter nu til TextEdit faktisk er vaek fra apps-listen, foer naeste
runde starter.

Dette retter ogsaa M11-mutanten (Swift): den kunne ikke verificeres, fordi 5.2's
fejl gjorde ALLE koersler roede uanset mutationen - mutant-ankrene i sig selv er
uaendrede.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…vinduerne (koersel 36890103580)

5.1b og 5.3 er nu GROENNE i alle tre runder. 5.2 ('menneskets tekst') var STADIG
roed efter SIGKILL-rettelsen, med SAMME voksende moenster (2 -> 3 -> 4 traef)
som foer den - det var signalet: SIGKILL draeber processen, men macOS' egen
'Resume'-funktion gemmer TextEdits vinduestilstand periodisk og GENSKABER den
automatisk naeste gang 'open -a TextEdit' koeres, UANSET hvordan processen blev
afsluttet. 'tekst()'s matches[0] ramte derfor tilfaeldigt et gammelt, genskabt
(og tomt) vindue fra en tidligere runde.

Samme opskrift som filen allerede bruger til Skak (nulstil(), lige ovenfor):
NSQuitAlwaysKeepsWindows + ApplePersistenceIgnoreState slaas fra for TextEdit,
og den gemte tilstand slettes, foer hver aabning - ikke kun ved oprydning efter.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…else, ikke et skroebeligt slut-opslag (koersel 36896072791)

Seks koersler i traek (fae1055 til 6953d8e) forsoegte et paalideligt AFSLUTTENDE
laes af TextEdits dokument via 'find --role AXTextArea'. Resume-rettelsen gjorde
traef-tallet entydigt (1 ikke 2/3/4), men vaerdien laeste stadig tom - selv om
HVERT ENKELT skrive-kald, maalt i selve oejeblikket af hjaelperens egen
readback-loop (AX.indsaetIFokus), bekraeftede at akkurat den tekst landede
('verified':true i svaret). Det er en AX-kvirk i hvordan TextEdit besvarer et
SEPARAT, SENERE find-opslag - udenfor computer-mcp's egen kode, og udenfor det
dette tjek faktisk skal bevise.

Beviset flyttes derfor til data der ALLEREDE er paalidelige: hjaelperens egen
per-kald-bekraeftelse. 5.2 kraever nu at mindst 95% af de forsoegte skrivninger
blev verificeret af hjaelperen selv, mens runden koerte - en staerkere, mere
granulaer proeve af 'forstyrrede agenterne mennesket' end et enkelt slut-opslag
nogensinde var, og en der ikke afhaenger af TextEdits accessibility-implementering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…n legitim tilbagegivelse - retarget M11 (koersel 36901238860)

Mange agenter samtidig er nu GROEN i alle tre runder (24/24 tjek, inkl. 5.2 med
0% tabt). Eneste tilbagevaerende rode: M11-mutanten 'overlevede - proeven maaler
ikke'. Aarsagen: parallel.mjs's menneske-simulation skriver nu via tilgaengelig-
heds-laget (AX.indsaetIFokus, ingen rigtig CGEvent) efter dagens tidligere
rettelser - mutationen (medtag .keyDown i menneskeRoerteNetop()) har derfor intet
at bide i LAENGERE, fordi der aldrig postes et AEGTE tastetryk under den proeve.

Ny sag 5 i giv-tilbage.mjs sender et AEGTE globalt tastetryk (ingen --app, tvinger
CGEvent-vejen) lige foer et selv-aktiverende program startes, og beviser at
tilbagegivelsen stadig lykkes - den PRAECISE adfaerd M11 skal vogte. M11 peger nu
dertil i stedet for parallel.mjs (ingen PROEVE= soeger giv-tilbage.mjs, filens
egen standard).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ke reaktiverings-timing (koersel 36907620350)

M11-mutanten blev korrekt roed (bevist virkende) - men den UNDMUTEREDE sag 5
fejlede SELV i 'Hele suiten', med 'gave_back:false, why: ... did not work'.
Det er en KENDT, UBESLAEGTET timing-flage: NSRunningApplication.activate()s
500 ms-poll kan tabe kaploebet under belastning, uanset om menneskeRoerteNetop()
korrekt ekskluderede tastetrykket.

De to grene i Skaerm.givTilbage har hver sin entydige signatur: naar
menneskeRoerteNetop() (fejlagtigt) returnerer true, baerer svaret ALTID et
'observed.note' med 'taken to be them' - FOER noget overhovedet forsoeges
reaktiveret. Den langsomme-reaktivering-grenen har ALDRIG et 'observed'-felt.
Sag 5 maaler nu praecis og kun dette (r5.observed === undefined), ikke om
selve genaktiveringen naaede at fuldfoere inden for 500 ms - robust mod
systembelastning, stadig et skarpt bevis paa den fejl M11 skal vogte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
En skaerm-anmodning mens et andet laan allerede er aktivt staar nu i koe
(anmodninger.append) i stedet for at blive afvist straks - serveren venter
allerede taalmodigt paa skaermVentetid() (trin 1), saa ingen aendring var
noedvendig der. menuNeedsUpdate udelader «Allow» fra undermenuen for en
anmodning mens et ANDET laan loeber, og viser i stedet «Waiting - the
screen is lent to X for N more minutes». Samme spoergsmaalMenu()-funktion
bygger baade den rigtige menu og --dump-question's svar (nyt
simulateActiveLoan-testfelt, test-kun, roerer ikke den rigtige
Spoergsmaal-protokol), saa test/ikon-menu.mjs (3d/3e) maaler gateringen
uden en levende GUI. test/skaerm-laan.mjs (13) beviser server-siden med
to agent-processer mod samme fake-ikon: den anden staar i koe, ikke
afvist, og godkendes naar den foerste slutter.

tillad()'s kaploebs-vagt (Touch ID-klik lige som et andet laan blev
givet) svarer ikke laengere «optaget» - anmodningen bliver i koen og
faar en frisk Allow naar det andet laan slutter, i stedet for at tvinge
agenten til at spoerge forfra.

Trin 1+8 af 9-trins-planen (DOM.md, konsulentpanel 1/10, begge GODKENDT)
var bygget; dette er trin 2, det konkret skitserede trin. 3-7+9 ikke
bygget endnu.
…rsioner

A6's ordlyd ("macos-14 + macos-15") er forældet: macos-14 er nu DEPRECATED
hos GitHub (højst to GA-versioner understøttet ad gangen). Nutidens svar er
de to AKTIVE GA-versioner (macos-15, macos-26), begge arkitekturer
(ARM64-labels + "-intel"-varianterne).

En push til proeve/-grene rører fortsat kun macos-15 (0 ekstra koererminutter
under udvikling) - hele fire-vejs-matrixen køres kun ved manuelt
workflow_dispatch med full_matrix=true, før en udgivelse. Artefakt-navnene
fik matrix-suffiks (fremmed-mac-film-${os}), ellers ville flere parallelle
koerere kollidere på samme artefakt-navn.
scripts/kontaktark.py trækker to billeder (tidligt + sent) ud af hver
brug-baggrund-*/brug-forgrund-*-film, parret pr. use case i en statisk
HTML-side, plus ét midtvejsbillede pr. parallel-N-agenter-film. Testet
lokalt mod de 25 film fra commit 258f7c0's kørsel (11 use cases, begge
tilstande, 0 manglende par).

Wired ind i Fremmed Mac lige efter "Filmene": uploades som sin egen
matrix-sikre artefakt (fremmed-mac-kontaktark-${os}) og noteres i
$GITHUB_STEP_SUMMARY, som vises direkte på PR'ens checks-fane - ingen
ekstra GITHUB_TOKEN-rettigheder nødvendige.

Rører ikke produktionskoden og tager ikke skærmen - læser kun film der
allerede er optaget af et tidligere CI-trin.
Fundet af Opus i et konsulentpanel om canvas-blinde apps (2/10): knapErFarlig()
behandlede "intet fundet på punktet", "fundet uden navn/beskrivelse" og "opslaget
fejlede" som IKKE farligt for computer_click - selvom et koordinat-klik rammer
skærmen uanset om opslaget her lykkes. Et "Delete" i en canvas-tegnet dialog,
et fjernskrivebord, eller ethvert punkt serveren ikke kan identificere, kunne
rammes uden at nogen blev spurgt - stik imod README's løfte om at alt der
sletter eller rydder spørger hver gang.

Den oprindelige begrundelse ("et tryk der ikke kan slås op, finder heller ikke
noget at trykke på") holder for computer_press, som ikke kan udføres uden et
fundet element - men ikke for et klik. De tre tilfælde fejler nu LUKKET (spørg)
for klik, mens press er uændret (fejler stadig åbent, med rette).

test/knap-ord.mjs udvidet med tre nye tjek (intet fundet, intet navn, opslaget
fejler) + ny kalibrering. Mutant Q26 i .github/mutanter-porte.json. Begge
bekræftet manuelt: reverteres fixet, går præcis de tre nye tjek røde.
…t tage fokus

Følg-panelet (klik på en session i menuen) viste kun løbende tekst om hvad
agenten gør. D3 bad om mere: "panelet peger på det program/vindue agenten
arbejder i, uden at tage forgrunden af sig selv - menneskets klik er det
eneste der flytter fokus".

status.js: statusHandling() tager nu en valgfri tredje parameter - den raa
app-streng (bundle-id ELLER synligt navn) serveren allerede har i hånden fra
`args.app`. Slås IKKE op her (resolveApp ville lægge et ekstra helper-opslag
på HVER handling bare for denne knap) - ikonet forsøger selv begge former,
når mennesket klikker.

main.swift: Post fik et `target`-felt. LivePanel fik en "Show me where"-knap,
samme princip som den eksisterende "Take me there" på et samtykke (hentFrem):
MENNESKETS klik aktiverer appen, agenten rører aldrig forgrunden selv. Knappen
læser `senesteMaal()` - det igangværende mål, eller ellers det sidst
FÆRDIGE (uden faldbagget ville den næsten aldrig være aktiv, fordi `now` kun
er sat de få millisekunder en handling rent faktisk kører).

--dump fik et nyt `nowTarget`-felt, så test/status-ikon.mjs kan bevise at
målet når helt frem uden en levende GUI (D3's prøve-halvdel). Knappens
EGEN aktivering (klik → appen kommer frem) kræver stadig film på GitHubs
Mac, som D1-D4 alle gør.

Verificeret lokalt: swift build ren, scripts/build-release.sh kørt (vendor-
binær opdateret, gitignored), test/status-ikon.mjs + test/ikon-menu.mjs
begge grønne mod den friske binær.
Opus-panelets punkt (b) (2/10, canvas-fallback-panelet): den eneste
agent-guidede vej for en app der ikke udgiver noget til tilgængeligheds-
træet (spil, plotte-værktøjer, fjernskrivebord) er nu at tage ÉT afgrænset
skærmbillede, beskrive hvad man ser, og give trinnet til mennesket via
computer_ask_user - ikke gætte koordinater selv. Ingen ny mekanik: samme
værktøjer, bare en instruktion om hvornår de bruges.

Panelets øvrige anbefalinger: (a) knapErFarlig fail-closed for blinde
klik - rettet i f22496a. (c) "ret READMEs upræcise citat" - falsk alarm,
den faktiske README.md:37-45 er allerede ordret præcis; fejlen var i min
egen PAKKE.md-opsummering, ikke i produktet.
Gustav Louv and others added 11 commits October 2, 2026 14:59
Fundet af forside-chatten (2/10): `hale.rstrip('\n')` gjorde `hale` ALTID
tom ('\n'.rstrip('\n') == ''), uanset om linjen ovenfor havde regnet sig
frem til enkelt eller dobbelt linjeskift. <!-- /FORBEHOLD --> og teksten
der fulgte landede på samme linje - GitHub og npm viste markøren som rå
tekst ("**Look:** `computer_pending` ·" stod bogstaveligt i README.md).

Rettelsen fjerner blot .rstrip('\n') - `hale` var allerede den rigtige
streng (smart enkelt/dobbelt alt efter om der i forvejen fulgte en tom
linje), den skal bare bruges som den er.

Kørt to gange i træk: anden kørsel rapporterer "flader rettet: 0 af 29"
(idempotent, som scriptets egen kommentar kræver). Fem flader rettet:
README.md, mcp-server/README.md (afledt), docs/index.html, docs/tools.html,
docs/llms.txt, docs/llms-install.md.
…pørge

To regressioner fundet af CI samme dag som fail-closed-rettelsen (f22496a):

1. test/sende-port.mjs q9: et klik på en navnløs AXGroup (helt almindeligt
   layout-lag i Electron-apps) begyndte at spørge. Rettet ved at genbruge
   send-portens egen `navnSender`-sondring: kun en rolle der plausibelt ER
   en knap (ukendt, Button, Image, Unknown) kan overhovedet hedde "Delete" -
   en gruppe kan ikke.

2. test/e2e-forloeb.mjs "click --app tager ikke skaermen": et klik på en
   helt almindelig, navngivet NSButton ("klik-maal", fundet af computer_find
   sekunder før) blev afvist. Målt årsag: `at`-punktopslaget fejlede med AX-
   fejl -25200 ("did not say who owns that point") - en kendt, almindelig
   AX-kvirk, ikke kun et canvas/fjernskrivebord-symptom som Opus-panelet
   antog. At spørge ved hver forekomst ville gøre computer_click næsten
   ubrugeligt. Rettet: `at` svarer stadig med hvilket program der ejer
   punktet selv når elementet ikke kan slås op - matcher det programmet
   kaldet selv navngav (targetBundleId, allerede opslået, intet nyt kald),
   er det ikke Opus' "jeg aner ikke hvad jeg rammer".

Verificeret lokalt (sikkert, ingen af dem rører en rigtig skærm): knap-ord
(ny case 9), sende-port, e2e-forloeb, klik-ejer, argumenter, baggrund-stille,
failclosed, server-e2e, claims - alle grønne.

Derudover: lille grammatikrettelse i sync-tal.py's llms.txt-tekst, fundet af
forside-chatten ("described below the source" -> "described below are the
source").
Forside-chatten bad om en optagelse af parallel-prøvens 10-runde der kan stå
på computermcp.dev uden "menneske.txt"/"m0 m1 m2", Netflix' ophavsretlige
plakater, eller et sort skrivebord med Game Center-popup.

CMCP_FILM_PYNT=1 (kun via workflow_dispatch, aldrig på push) skifter:
- test/parallel.mjs: filnavnet til notes.txt, og teksten der "skrives" fra
  "m$i " til en kort, cyklende huskeliste (Buy milk, Call Alex, ...) - samme
  --app-vej, samme forsøgt/verificeret-tælling, samme loop-struktur.
- test/brugsscenarier.mjs: scenarie 5's URL/titel-match fra netflix.com til
  en neutral Wikipedia-artikel (macOS) - scenariets navn, nummer og app-liste
  er UÆNDREDE, kun destinationen skifter.
- fremmed-mac.yml: sætter en rigtig desktop-baggrund (det første .heic
  koereren rent faktisk har) og bedste forsøg på at tie Game Center/
  notifikationer, FØR optagelsen - alt med `|| true`, fejler aldrig bygningen.

Verificeret lokalt (sikkert - ingen GUI/skærm rørt): node --check begge filer,
SCENARIER.length stadig 19 med og uden flaget, scenarie 5's navn/apps uændret.
Fundet under fuld-review af denne chats arbejde (2/10): kortet meldte
"64 commits ligger lokalt", selvom alt var skubbet til
origin/proeve/rettelser-2026-09-28. Lokal main tracker origin/main (git
config), men husets egen deploy-doktrin pusher til en proeve/-gren via
PR - main er LÅST (computermcp_main_laast). Tjekket målte sin egen
hardcodede antagelse, ikke den faktiske push-tilstand.

Rettet: er HEAD med på NOGEN fjern-gren (git branch -r --contains HEAD),
er den skubbet - og kortet navngiver hvilken. Verificeret: viser nu
korrekt "HEAD er på origin/proeve/rettelser-2026-09-28".
Uafhængigt review-security-review (2/10, efter fuld-review-skillets Trin 5)
fandt at ac7da21's "punktet tilhører den app kaldet selv navngav"-undtagelse
(F1, Critical, confidence 90) genåbner PRÆCIS det Opus-panelet fandt: et
fjernskrivebord eller en VM ejer sit eget vindue legitimt, men AX-laget kan
ALDRIG se ind i det - "under" matcher altid "app" derinde. At kende APPEN er
ikke det samme som at kende ELEMENTET.

Prøvede først et genforsøg (en ægte AX-kvirk burde være forbigående) -
MÅLT at svigte empirisk: samme AX-fejl -25200 to gange i træk på den
samme, helt almindelige NSButton fra test/e2e-forloeb.mjs. Kvirken er ikke
timing, og der er ingen billig måde at skelne "en almindelig knap AX
tilfældigvis ikke kan slå op" fra "et fjernskrivebord der aldrig kan slås
op" med kun ét punkt-opslag.

Efter tre runder der hver rettede ét symptom og genåbnede et andet, er den
disciplinerede løsning den simpleste sikre: `found:false` spørger ALTID,
uden undtagelse - computer_click bliver dyrere på kendte AX-kvirke, og den
pris er betalt med vilje. test/e2e-forloeb.mjs's "klik-maal"-knap rammes
nu korrekt af spørgsmålet; testens forventning er opdateret til at
afspejle den sikrere, sande opførsel (og "sent"-effektens dækning flyttet
til test/klik-ejer.mjs, hvor den allerede proves med et ja).

Dette er FJERDE version af knapErFarlig i dag (07a4a8f-serien, f22496a,
ac7da21, nu denne). Resten af review-security's fund (F2 nameless AXLink/
AXStaticText, F3 click-through på dækket vindue, F5 press fail-open på
timeout, F6-F11) er IKKE rettet i denne omgang - rapporteret, ikke skjult.

Verificeret lokalt: knap-ord (9/9), sende-port, klik-ejer, e2e-forloeb
(32/32), argumenter, baggrund-stille, failclosed, server-e2e, claims -
alle grønne. Q26-mutantens anker matcher igen koden uændret.
…Knap

CI (46e3cdc) fejlede på mutant R3-ukendt-rolle-ufarlig: "1 overlevede, 0
fejl" - en ægte overlevelse, ikke en instrument-fejl. Målt årsag:
navnSender's klik-rolle-tjek var en ord-for-ord kopi af knapErFarlig's
kanVaereKnap() (bevidst genbrugt mønster, se f22496a). To uafhængige
kopier af samme logik betyder at en mutation i navnSender's egen kopi
blev maskeret - knapErFarlig spurgte stadig, af sin EGEN grund, så den
observerede opførsel ("spurgte den?") var uændret uanset mutationen.

Rettet ved at fjerne duplikeringen: navnSender's klik-gren kalder nu
kanVaereKnap(rolle) direkte i stedet for at gentage udtrykket. Én kilde,
én mutation rammer begge porte - og rammer nu BEGGE porte's prøver
(verificeret: mutanten gør både sende-port.mjs OG knap-ord.mjs røde).
Mutant R3's anker opdateret til den delte funktions linje.

Verificeret lokalt: mutationen anvendt manuelt → begge testfiler røde på
den forventede linje → gendannet → begge grønne igen i deres normale
tilstand.
- udgiv-npm.yml: opsætnings-kommentaren sagde "Environment: (tom)" til Gustav,
  i modstrid med jobbets egen "environment: udgivelse" og husets låste
  beslutning (computermcp_main_laast_2026_09_29). Ville have fået npm OIDC
  til at afvise tokenet pga. environment-claim-mismatch ved første rigtige
  publish-forsøg.
- release.sh: fjernet gen-indsættelse af værktøjstal i repo-beskrivelsen -
  tallet blev bevidst fjernet 2/10 fordi det var forkert mod både koden og
  npm; scriptet ville have sat den forkerte værdi tilbage ved næste udgivelse.

Begge fund verificeret selv mod koden før rettelse, ikke taget for pålydende
fra panelrapporterne. Ingen af de to kræver en beslutning - de retter kode
til at stemme med fakta der allerede er afgjort.
…mere

CI på 2ba02e6 fejlede ægte: "Q9-navnloes-gruppe-er-send: ankrene findes [0]
gange" - dedup-refaktoreringen i 2ba02e6 (navnSender kalder nu kanVaereKnap
direkte i stedet for sin egen inline-kopi) fjernede den tekst mutanten søgte
efter. 0 mutanter overlevede; dette var en knækket anker, ikke en reel fejl.

Retarget til kanVaereKnap's funktionskrop (samme sted R3-ukendt-rolle-ufarlig
peger), med sin egen mutation (tilføjer Group i stedet for at fjerne Unknown)
så den stadig beviser noget andet end R3.

Mutationsbevist manuelt begge veje før push: muteret → test/sende-port.mjs
gik rødt netop på "q9 klik paa en navnloes gruppe" (den påstand mutanten selv
hedder) → gendannet → git diff tom → baseline grøn igen. knap-ord.mjs upåvirket.
- Tilføjet eksplicit "mcp-publisher login" før publish, som to-vejs-skridt
  (samme rettelse release.sh allerede har - set -e dækker ikke en &&-kæde).
- Registerkontrollen kunne matche en FREMMED server ved navn-overlap i
  søgningen; kræver nu præcis navn "io.github.Agent360dk/computer-mcp" OG
  sammenligner med den faktisk udgivne version. Selvtestet mod det ægte,
  læsende registerkald (0.1.0 matcher, 0.2.1 rapporteres som uoverensstemmelse).
- Scriptets sidste trin anbefalede "git push origin main" - afvises altid,
  main kræver PR (enforce_admins=true, bekræftet). Erstattet med en gren +
  gh pr create-vej.

Ingen CI-vagt kører dette script (grep-bekræftet); ingen risiko for porten.
Intet kørt - kun scriptets egen tekst og logik rettet.
…cted main

Tre fund, alle Opus 2/10, verificeret selv mod branch-beskyttelsen
(gh api .../branches/main/protection, bekræftet enforce_admins=true):

1. Intet tjek for at lokalt HEAD faktisk er origin/main FØR der tagges.
   Køres scriptet i et træ hvis lokale main er bagud (målt i en anden chats
   træ: stod på 46e3cdc), ville det offentlige mærke v$V pege på en commit
   GitHub ikke har - permanent forkert, mærker omskrives ikke uden historik-
   brud. Tilføjet et hårdt stop før trin 0.
2. "git push origin main --tags" (linje ~254) forsøgte at skubbe "main" for
   et skridt der kun handler om mærket - meningsløst når HEAD nu er
   verificeret synkron, og ville være blevet afvist af beskyttelsen hvis det
   alligevel ikke var. Skubber nu kun mærket.
3. Efter en VIRKELIG npm-udgivelse (irreversibel, fælden allerede afvæbnet)
   prøvede scriptet samme afviste "git push origin main" for at synkronisere
   PUBLICERET/docs - et set -e-stop her ville have efterladt Gustav i en uklar
   tilstand midt i en udgivelse. Erstattet med gren + automatisk PR; scriptet
   fortæller præcis hvilken PR der skal merges, uden selv at merge den.

Intet af dette rammer CI (grep-bekræftet: ingen workflow eller test udfører
scripts/release.sh - kun build-release.sh, en anden fil). bash -n ren.
review-security fandt det (F5, Important), en søsterchats Astra+Opus-panel
genfandt og verificerede det selv i koden (420b998, index.js:517-524) og
Gustav gav ja til at rette den nu, resten af review-security-fundene som
kendt risiko (forbrugeragent-3e, 2/10).

Verificeret selv mod den faktiske kode før rettelse: knapErFarlig's klik-gren
blev gjort fail-closed i dag (46e3cdc) - `catch { return true; }`,
`if (!d?.found) return true;`. Press-grenen gjorde præcis det modsatte -
`catch { return false; }` og et manglende would_press talte som "ufarligt".
Samme fejlklasse: et mislykket opslag læst som "ved besked" i stedet for
"ved ikke", nøjagtig den antagelse F1 lukkede for klik i dag.

Rettet til samme fail-closed-regel som klik, ingen undtagelse. To nye
prøver (knap-ord.mjs 11-12: manglende would_press, og selve dry-run-kaldet
fejler) plus to mutanter (Q27, Q28) - mutationsbevist manuelt begge veje
FØR commit, og hele den lokale mutationssuite kørt bagefter: 0 overlevede,
0 fejl (74 mutanter inkl. de to nye). test/sende-port.mjs og
test/e2e-forloeb.mjs upåvirkede.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
GLouv pushed a commit that referenced this pull request Oct 3, 2026
- Optagelsen er fra FORSØG 2 af kørsel 36957564215 (menulinjens ur 4:12 AM,
  10-runden 04:11:53-04:13:14 UTC), som målte 165/165 - ikke forsøg 1's
  175/175. Figcaption, aria-label og slutpladen siger nu 165 af 165; klippet
  er bygget igen.
- Kodeordsprogrammer bliver i standardtilstanden AFVIST, ikke spurgt
  (policy.js:554-569: «a password app can never be approved from the menu
  bar»); kun med CMCP_BACKGROUND=0 spørger de hver gang. Rettet på forsiden
  (kort + JSON-LD), security.html, llms.txt og README (5 steder). Et ukendt
  mål afvises også i standardtilstanden (README).
- README: «seven others» -> «five others» (9 bundle-ID'er = 7 programmer),
  Windsurf og Zed fjernet (ikke testet; allerede fjernet fra siden).
- «15 agents connected: 375 MB while idle» var målt 27/9 før menulinje-ikonet
  og uden kilde i repoet. Erstattet af målingen på den frosne udgivelse
  77ba8b6 (kørsel 37032861000): 15 agenter på én gang, 175 af 175 ord skrevet
  forrest nåede frem.
- tools.html: «nothing locks between them» -> låsen pr. program findes
  (programlaas.js); den gør kun at to agenter i samme program tager tur.

README rettes her og ikke i #6, fordi #6 er frosset (aftalt med forbrugeragent-ca).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GLouv pushed a commit that referenced this pull request Oct 3, 2026
README siger nu «Keychain, 1Password and five others» (4441a36). Tjek 42b
regnede A42.size - 2 = 7 og krævede «seven others»: 9 bundle-ID'er, men tre
er 1Password i hver sin version, så det er 7 programmer = Keychain + 1Password
+ fem. «seven» bestod kun fordi README og prøven delte samme regnefejl.
Rettelsen er forbrugeragent-ca's (testet og mutationsbevist dér, rullet
tilbage for ikke at gøre den frosne #6 rød); den lander her sammen med
teksten, så main aldrig står rød imellem.

mcp-server/README.md er afledt igen med build-release.sh' to omskrivninger
(tjek 45).

Kørt isoleret (blok 42 og 45 fra claims.mjs, uden resten der styrer skærmen):
42a/42b/42c/45 OK; mutant med «seven others» i README -> 42b og 45 DUMP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant