Skip to content

Decyzje: jak działają (D0–D4)

Owner answers recorded from chat

When the owner explicitly answers in chat, an interactive session can call decision_record_owner_answer to record that answer on the decision board. owner_chat is an attestation by the recording session, not cryptographic proof. Nothing is recorded automatically. The historical passkey-only description below predates this addition; /decide and delegations keep their existing rules.

The caller needs a current owner/admin project role, tasks:write, matching write_context and an idempotency key. OAuth and project tokens are supported. Execution credentials return decision_record_requires_interactive_session before the scope gate; contributor/viewer roles return project_admin_required before it. Legacy OAuth without a grant-family principal returns principal_unavailable.

New mode takes the proposal fields for consent or rule, plus option_id, verbatim owner_quote (1–1000 characters), session_label (1–80) and said_at (ISO-8601 with timezone, at most seven days old, never future). Existing mode takes decision_id of a proposed decision and the answer fields; its immutable content hash is used without a duplicate. Proposal fields in this mode do not replace the stored content. A new record with a pending same-key proposal returns decision_record_pending_exists with its ID for use in existing mode.

Payments, secrets and deletion require the owner's key. All options' consequences must be free of these operations; the session attests to that by explicitly setting owner_list.paid, secret and deletion to false. True flags, including a generic key with paid=true, and cost-, secret-, delete- prefixes return decision_requires_owner_key. Migration is allowed. Staffing is refused with decision_record_type_not_allowed, and approval values with decision_record_approval_not_allowed; approval routes remain key-only. Past conditions.valid_until returns decision_record_expired in new mode. Refusals write no decision or answer event.

The transaction records confirmed for authorizes=true, otherwise rejected, without decision_waiting or push delivery rows. said_at is the owner's answer time; created_at remains the recording time. List/get and the continuity in-force index expose confirmed_by: owner_chat, attested_by: {principal, session_label} and answered_in: {quote, session_label, said_at}. The principal is server-derived. Consent can be consumed once with decision_check(use=true) unless retry is allowed; rules use false (decision_use_not_applicable otherwise). Existing key revocation still applies.

Reuse the same idempotency key only for an identical retry. Replay precedes the seven-day age check, and concurrent identical calls return one record. Different input or another principal with the same key returns idempotency_conflict.

Historical D0–D4 description

Stan odczytany ponownie 2026-10-10 z h8v6/heyaira@b1a29d484f60414125101279f38866ab48e5c16e (zadanie v24; kod bez zmian względem poprzedniego opisu). Opis dotyczy kodu tej rewizji; D0 jest punktem porównania. docs.heyaira.eu powstaje z docs/ (mkdocs.yml:6, docs/operations/documentation-workflow.md:30). Odczyt witryny jest zablokowany przez listę dozwolonych domen wykonania; „publiczne docs” oznaczają ich źródła w repozytorium, nie potwierdzony stan publikacji. Opis przejścia przez passkey wynika z kodu i testów syntetycznych; to wykonanie nie sprawdzało Touch ID, Face ID ani dostarczenia push na prawdziwym urządzeniu.

Czym jest decyzja i kto ją proponuje

Element Działanie w kodzie Źródło
Decyzja Niezmienna propozycja w decisions i dopisywana historia w decision_events. Stan jest wyliczany przy odczycie. Stara notatka memory kind=decision nie uzyskuje przez to in_force. migrations/054_decisions.sql:2, migrations/054_decisions.sql:43, migrations/054_decisions.sql:74, src/heyaira/decisions.py:71, src/heyaira/server.py:3808
Typ consent: zgoda na czynność; rule: reguła; staffing: delegacja odpowiedzi przypisana do rodziny połączenia OAuth. src/heyaira/decisions.py:280, src/heyaira/decisions.py:335, src/heyaira/decision_answers.py:190
Proponujący Sesja z tasks:write i principalem ustalonym przez serwer, np. koordynator lub agent w sesji interaktywnej. Agent wysłany przez Bridge z tokenem wykonania nie może proponować ani odpowiadać; może odczytać decyzje swojego zadania. src/heyaira/decisions.py:389, src/heyaira/decisions.py:173, src/heyaira/server.py:3638
Treść propozycji Pytanie zakończone ?, 2–6 opcji, konsekwencje każdej (co się stanie, co blokuje, odwracalność), rekomendacja z uzasadnieniem, kto czeka, zakres, klucz, cztery flagi właściciela oraz cytat i miejsce źródła. Serwer odrzuca niekompletne dane. Cytat nie jest zgodą. src/heyaira/decisions.py:233, src/heyaira/decisions.py:282, src/heyaira/server.py:3624, src/heyaira/decision_answers.py:174
Zakres Projekt, moduł albo zadanie z konkretną wersją. Moduł to slug; przynależność zadania wynika z tagu modul-<slug>. Dla jednego klucza wygrywa obowiązująca decyzja o najwęższym zakresie: zadanie → moduł → projekt. src/heyaira/decisions.py:64, src/heyaira/decisions.py:128, src/heyaira/decisions.py:289
Odpowiedź właściciela Każda akcja wymaga jego klucza potwierdzającego: wybór opcji, odmowa, dopytanie, odwołanie. Token projektu, nazwa sesji i tekst „tak” nie zastępują assertion passkey. src/heyaira/decision_passkeys.py:147, src/heyaira/decision_passkeys.py:162, src/heyaira/decision_answers.py:108
Delegat Może zatwierdzić lub odmówić w granicach obowiązującego staffing: właściwy principal OAuth, prefiks klucza, typ i zakres. Nie odpowiada na własną propozycję; nie rozstrzyga staffing, migracji, usuwania, kosztów ani sekretów; nie dopytuje i nie odwołuje. src/heyaira/decision_answers.py:190, src/heyaira/decisions.py:303, src/heyaira/decisions.py:353

Co właściciel widzi w każdym kanale

Kanał Lista i wybór Gdzie następuje odpowiedź Źródło
Claude Code: mod /heyaira-decisions Belka nad promptem z liczbą decyzji i blokujących; jedna decyzja otwiera stronę, kilka otwiera panel. Panel pokazuje pytanie, pełne konsekwencje, rekomendację, czekającą sesję, zakres i konflikty; stale/lapsed trafiają do „Do uzupełnienia”. Odczyt dotyczy jednego projektu wybranego po nazwie folderu w ścieżce. Odświeżanie: start, co 5 minut i przycisk, najwyżej raz na 60 s. Przycisk opcji pobiera świeży link i otwiera przeglądarkę z ?option=<id>; „Dopytaj” z ?ask=1. Na stronie trzeba jeszcze nacisnąć potwierdzenie i użyć passkey. Mod wykonuje wyłącznie odczyty. clients/claude-mod/hooks/register.tsx:15, clients/claude-mod/hooks/register.tsx:25, clients/claude-mod/hooks/register.tsx:138, clients/claude-mod/hooks/register.tsx:281, clients/claude-mod/hooks/register.tsx:328, clients/claude-mod/hooks/register.tsx:424, clients/claude-mod/hooks/format.ts:46, clients/claude-mod/hooks/format.ts:124
Codex: plugin heyaira-decisions Skill uruchamiany prośbą „pokaż decyzje” / heyaira-decisions; model ma wypisać polską listę z kanonicznego formatu i przejść wszystkie kursory. W repozytorium projekt wybiera z Git origin i project_repositories; folder stosuje tylko poza Git. To instrukcja dla modelu, bez własnej belki/panelu i timera. Wypisany Rozstrzygnij: <confirm_url> jest linkiem do przeglądarki. Prośba o potwierdzenie w czacie dostaje link, nie zapis odpowiedzi. W sesji wykonawczej link jest niedostępny: sprawę przekazuje się koordynatorowi w RESULT. clients/codex-plugin/.codex-plugin/plugin.json:8, clients/codex-plugin/skills/heyaira-decisions/SKILL.md:11, clients/codex-plugin/skills/heyaira-decisions/SKILL.md:34, clients/codex-plugin/skills/heyaira-decisions/SKILL.md:64, clients/codex-plugin/skills/heyaira-decisions/SKILL.md:105
Strona /decide/<handle> Pytanie i nazwa projektu, kto czeka, główny przycisk rekomendacji, inne opcje, konsekwencje. Konflikt blokuje zatwierdzenie; lista poprzedników pokazuje, co zostanie zastąpione. „Details” zawiera stan, zakres z wersją, principal i klienta autora, warunki, przesłonięcie, źródło i interpretowany grant staffing. ?option= pokazuje wybraną opcję; ?ask=1 formularz pytania. Strona pobiera challenge i uruchamia navigator.credentials.get; zapis odpowiedzi jest osobnym POST. proposed: wybór/odmowa/dopytanie; stale: tylko odmowa; in_force: odwołanie; lapsed i stany zamknięte: brak odpowiedzi. Ogólny „Reject” jest wyświetlany tylko wtedy, gdy nie ma dostępnej opcji odmowy. src/heyaira/decision_web.py:149, src/heyaira/decision_web.py:170, src/heyaira/decision_web.py:209, src/heyaira/decision_web.py:241, src/heyaira/decision_web.py:264, src/heyaira/decision_web.py:273, src/heyaira/decision_web.py:79, src/heyaira/decision_answers.py:108
iPhone Na górze Inbox są „Decisions” i „Needs input”. Ekran decyzji pokazuje pytanie, kto czeka, pierwsze zdanie uzasadnienia, opcje (rekomendowana pierwsza), konsekwencje i „Ask back”. stale/lapsed nie mają przycisków odpowiedzi. Push otwiera decyzję z listy open; gdy jej tam nie ma, aplikacja wraca do wpisu powiadomienia. Aplikacja pobiera link i otwiera /decide w ASWebAuthenticationSession z ?option= lub ?ask=1 oraz return=ios. Passkey działa na stronie w systemowym oknie; callback wraca do aplikacji, która odświeża listę. Nie ma natywnej ceremonii WebAuthn. Obecny skrypt zapisuje kanał web, również z telefonu. ios/HeyAiraBridge/HeyAiraBridge/DecisionViews.swift:8, ios/HeyAiraBridge/HeyAiraBridge/DecisionViews.swift:127, ios/HeyAiraBridge/HeyAiraBridge/DecisionViews.swift:154, ios/HeyAiraBridge/HeyAiraBridge/DecisionStore.swift:65, ios/HeyAiraBridge/HeyAiraBridge/DecisionStore.swift:112, ios/HeyAiraBridge/HeyAiraBridge/DecisionAuthSession.swift:13, ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift:245, ios/HeyAiraBridge/HeyAiraBridge/AppModel.swift:168, src/heyaira/decision_web.py:85, src/heyaira/decision_passkeys.py:167

Lista REST na telefonie wymaga tasks:read oraz aktywnego urządzenia dla subjectu zalogowanej sesji; obejmuje projekt tokenu. Lista Maca wymaga tożsamości Bridge i powiązania z projektem. Samo zarejestrowanie telefonu nie nadaje uprawnienia do odpowiedzi właściciela (src/heyaira/decision_web.py:390, src/heyaira/decision_passkeys.py:162).

Mod Claude i iPhone pobierają najwyżej 10 stron po 50 pozycji. Mod zgłasza niepełną listę, iPhone nie pokazuje ostrzeżenia o dalszym kursorze. Belka Claude liczy tylko decyzje poza stale/lapsed; same uzupełnienia są dostępne przez komendę panelu, bez belki (clients/claude-mod/hooks/register.tsx:98, clients/claude-mod/hooks/register.tsx:159, clients/claude-mod/hooks/register.tsx:340, clients/claude-mod/hooks/format.ts:95, ios/HeyAiraBridge/HeyAiraBridge/DecisionStore.swift:84).

Sam odczyt decision_check(use=false) wymaga tasks:read; zużycie zgody (use=true) wymaga dodatkowo tasks:write, write_context i klucza idempotencji (src/heyaira/server.py:3678, src/heyaira/server.py:3681, src/heyaira/decisions.py:389).

Co potwierdza passkey

Krok Powiązanie i sprawdzenie Źródło
Klucz Klucz należy do osoby na poziomie konta. Pierwszy wymaga jednorazowego kodu (do 15 min), wysyłanego e-mailem przez CLI DevOps; błąd wysyłki wycofuje wydanie kodu. Kolejne wymagają aktywnego klucza tej osoby. Lista i odwołanie kluczy też wymagają assertion. migrations/055_decision_passkeys.sql:2, migrations/055_decision_passkeys.sql:16, src/heyaira/admin.py:768, src/heyaira/decision_passkeys.py:178, src/heyaira/decision_passkeys.py:229, src/heyaira/decision_passkeys.py:254
Link Podpis HMAC wiąże projekt, ID decyzji, content_hash, identyfikator klucza serwera i ważność 24 h. Link pozwala zobaczyć tę decyzję, nie odpowiedzieć. Treść strony pochodzi z bazy. Utworzenie linku nie zapisuje rekordu. src/heyaira/decision_answers.py:49, src/heyaira/decision_answers.py:79, src/heyaira/decision_web.py:156
Challenge Ważny 2 min, maksymalnie pięć niewygasłych na decyzję. Wiąże ID i hash treści, akcję, konkretną opcję, hash notatki i — przy zatwierdzeniu staffing — hash grantu. src/heyaira/decision_passkeys.py:25, src/heyaira/decision_passkeys.py:72, src/heyaira/decision_answers.py:160
Assertion Serwer sprawdza podpis, RP heyaira.eu, dokładny origin serwera, weryfikację użytkownika i licznik; klucz musi być aktywny i należeć do obecnego accounts.owner_subject_id. Touch ID / Face ID to sposób obsługi urządzenia; serwer wymaga UV, nie konkretnej biometrii. src/heyaira/decision_passkeys.py:18, src/heyaira/decision_passkeys.py:99, src/heyaira/decision_passkeys.py:162
Zapis W transakcji serwer ponownie sprawdza stan, konflikt, grant i zgodność challenge; dopisuje zdarzenie, zużywa challenge oraz zapisuje audyt i powiadomienie. Ponowne użycie challenge jest odrzucane. Parametry ?option= / return=ios nie są zgodą. src/heyaira/decision_passkeys.py:125, src/heyaira/decision_passkeys.py:147, src/heyaira/decision_web.py:149

Od propozycji do obowiązywania i wznowienia zadania

Sytuacja Skutek Źródło
Propozycja bez odpowiedzi proposed; zmiana wersji zadania lub dopytanie daje stale. Upływ ważności albo zamknięcie zadania zakresu przed odpowiedzią daje lapsed. src/heyaira/decisions.py:71
Wybrana opcja ze zgodą Zdarzenie confirmed; decyzja jest in_force, jeśli nie została zastąpiona, odwołana ani nie wygasła. Opcja authorizes=false lub ogólna odmowa zapisuje rejected, nigdy zgodę. src/heyaira/decision_answers.py:174, src/heyaira/decisions.py:71, migrations/054_decisions.sql:120
Zmiana lub wycofanie Autor może wycofać otwartą propozycję (withdrawn) albo zgłosić nową z revises_id; wcześniejsza dostaje zdarzenie wycofania. Właściciel może odwołać obowiązującą (revoked). Potwierdzony następca zastępuje całe drzewo supersedes (superseded); jego późniejsze wygaśnięcie nie przywraca poprzedników. src/heyaira/decisions.py:52, src/heyaira/decisions.py:74, src/heyaira/decisions.py:457, src/heyaira/decisions.py:511, src/heyaira/decision_answers.py:113
Użycie zgody decision_check sprawdza stan, zakres, pierwszeństwo, konflikt, bieżącą wersję zadania i wybraną opcję. use=true dotyczy tylko consent i dopisuje used; jednorazowa zgoda staje się expired. retry_allowed=true pozwala na kolejne użycia. Zgody modułu/projektu domyślnie wygasają po 30 dniach; valid_until może skrócić ważność. Tekst stop_if/rollback nie jest wykonywany przez serwer. src/heyaira/decisions.py:140, src/heyaira/decisions.py:84, src/heyaira/decisions.py:308, src/heyaira/decisions.py:324, src/heyaira/decisions.py:472
Propozycja z waiting.blocks_task_id Automatyczny hold w tej samej transakcji. Koordynator może też dodać hold do decyzji bez wskazanego zadania, jeżeli jej zakres je obejmuje. Zamknięte zadania nie przyjmują nowych holdów. Hold nie zmienia wersji, zapisanego etapu ani workflow. src/heyaira/decisions.py:491, src/heyaira/decisions.py:533, src/heyaira/decisions.py:539, src/heyaira/decisions.py:545
Zadanie z holdem Widoczny etap to awaiting_decision. Dla proposed lub konfliktu ruch ma właściciel; dla uzupełnienia lub odczytania odpowiedzi — odpowiedzialny, chyba że działa jawne nadpisanie następnego aktora. Historyczne/ zamknięte zadania nie pokazują aktywnego overlayu holdów. src/heyaira/decisions.py:630, src/heyaira/task_org.py:121
Bieżące wykonanie i kolejne wysłanie Hold blokuje ukończenie workflow: wynik pracy może zachować commit, lecz workflow przechodzi do blocked; PASS weryfikatora też nie przyjmuje wyniku. Blokuje nowe oferty, claim i workflow_send. Sam hold nie przerywa procesu agenta w trakcie pracy. src/heyaira/workflow.py:421, src/heyaira/workflow.py:522, src/heyaira/workflow.py:726, src/heyaira/execution.py:428
Po odpowiedzi Hold pozostaje. Koordynator czyta wynik i jawnie usuwa go przez task_decision_hold(held=false); dla zablokowanego workflow ponownie wywołuje workflow_send. Spełnienie required_approvals jest wyliczane przez te same sprawdzenia co decision_check; nie zmienia etapu i nie wykonuje czynności. src/heyaira/decision_answers.py:174, src/heyaira/decisions.py:560, src/heyaira/decisions.py:630, src/heyaira/workflow.py:522, tests/test_decisions_holds.py:67

Co pozostaje w historii i logach

Zapis Zawartość i ograniczenia Źródło
Propozycja i zdarzenia Autor ustalony przez serwer, hash treści; w zdarzeniach akcja, opcja/notatka, osoba lub principal delegata, klucz/delegacja, kanał, czas; przy used zadanie i wersja. Triggery blokują edycję historii i drugą terminalną odpowiedź. migrations/054_decisions.sql:25, migrations/054_decisions.sql:43, migrations/054_decisions.sql:71, src/heyaira/decision_answers.py:174
Audyt i ponowienia Audyt zawiera projekt, aktora, operację, cel, request ID i wynik. Zapisy MCP wymagają write_context i klucza idempotencji; ponowienie tego samego wywołania przez ten sam principal zwraca zapisany wynik. Przeglądanie/link nie jest odpowiedzią ani zdarzeniem zgody. src/heyaira/server.py:598, src/heyaira/decisions.py:389, src/heyaira/decisions.py:475, src/heyaira/decision_passkeys.py:134, src/heyaira/decision_answers.py:49
Powiadomienia decision_waiting po propozycji; decision_answered po zatwierdzeniu/odmowie/dopytaniu/odwołaniu; dodanie i odwołanie klucza dla każdego projektu konta. Kopia w projekcie, kopie dla Maców i dostarczenia telefonom powstają transakcyjnie. Treść decyzji w powiadomieniu to pytanie ucięte do 120 znaków, bez opcji; deep link to heyaira://decisions/<id>. To powiadomienie projektu, nie wiadomość dostarczona bezpośrednio do sesji MCP. src/heyaira/decisions.py:444, src/heyaira/decision_answers.py:183, src/heyaira/decision_passkeys.py:193, src/heyaira/server.py:1327, src/heyaira/server.py:1339
Indeks startowy continuity_context.decisions: in_force do 20 wpisów / 4 KB, attention do 50 z jawną flagą obcięcia; pełna decyzja i historia przez decision_get. Token wykonania nie dostaje tego indeksu ani linków; odczyty decyzji filtrują relacje do przydzielonego zadania i wersji. src/heyaira/decisions.py:657, src/heyaira/decisions.py:173, src/heyaira/decisions.py:180, src/heyaira/server.py:3712, src/heyaira/server.py:3946
Log dostępu Filtr Uvicorn pomija URL-e /decide/, które zawierają uchwyty i kody rejestracji. Mod Claude nie przechowuje ani nie wypisuje pobranych linków; skill Codex celowo pokazuje link właścicielowi. src/heyaira/decision_web.py:296, clients/claude-mod/hooks/register.tsx:279, clients/codex-plugin/skills/heyaira-decisions/SKILL.md:38

Rozjazdy

Poniżej są zadania do przekazania koordynatorowi, z parami plik:linia w rewizji opisanej na początku. Nie utworzono osobnych zadań MCP: token tego wykonania pozwala oddać RESULT, nie tworzyć zadań. Lista obejmuje znalezione różnice zachowania oraz luki opisu publicznego; uzgodnienia §12.2 oznaczono osobno. Wskazanie różnicy nie rozstrzyga, czy należy zmienić kod, czy umowę. D0 i kod pozostają bez zmian.

ID / zadanie Specyfikacja lub publiczny opis Implementacja / rozjazd
R01 — Uzgodnić interfejs D3 docs/specs/decisions/D0-spec.md:546, docs/specs/decisions/D0-spec.md:547, docs/specs/decisions/D0-spec.md:1018: Codex ma pokazywać „to samo” co belka/panel Claude, z przyciskiem. clients/codex-plugin/.codex-plugin/plugin.json:8, clients/codex-plugin/skills/heyaira-decisions/SKILL.md:34, clients/codex-plugin/build_skill.py:14: plugin dostarcza skill, tekst i link; brak kodu belki/panelu oraz wspólnego renderera D2.
R02 — Uzgodnić ceremonię D4 docs/specs/decisions/D0-spec.md:443, docs/specs/decisions/D0-spec.md:545, docs/specs/decisions/D0-spec.md:1019: natywne assertion, okno web jako fallback. ios/HeyAiraBridge/HeyAiraBridge/AppModel.swift:56, ios/HeyAiraBridge/HeyAiraBridge/DecisionAuthSession.swift:13, ios/HeyAiraBridge/HeyAiraBridge/DecisionStore.swift:127: zawsze ASWebAuthenticationSession; brak natywnego providera passkey.
R03 — Uzgodnić oznaczenie kanału telefonu docs/specs/decisions/D0-spec.md:545, docs/specs/decisions/D0-spec.md:1019: odpowiedź telefonu ma channel=ios. src/heyaira/decision_web.py:85 nie wysyła channel; src/heyaira/decision_passkeys.py:167 stosuje domyślne web. return=ios steruje wyłącznie callbackiem (ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift:263).
R04 — Uzgodnić AASA i uprawnienia aplikacji docs/specs/decisions/D0-spec.md:817, docs/specs/decisions/D0-spec.md:1019: endpoint AASA z webcredentials dla D4. Rejestracja tras kończy się na odczytach kanałów (src/heyaira/decision_web.py:379, src/heyaira/server.py:1751); brak trasy AASA w src/. Entitlements zawierają tylko APNs (ios/HeyAiraBridge/HeyAiraBridge/HeyAiraBridge.entitlements:4), bez Associated Domains. To brak w tym repo, nie dowód stanu konfiguracji edge.
R05 — Doprecyzować projekty listy mobile docs/specs/decisions/D0-spec.md:812: „the device’s projects”. src/heyaira/decision_web.py:404, src/heyaira/decision_web.py:407, ios/HeyAiraBridge/HeyAiraBridge/BridgeAPIClient.swift:138: tylko projekt tokenu i urządzenie aktywne w nim; nie agregacja projektów urządzenia.
R06 — Uzgodnić ogólną odmowę docs/specs/decisions/D0-spec.md:359, docs/specs/decisions/D0-spec.md:473: strona zawsze oferuje ogólne „Reject” obok wyboru opcji. src/heyaira/decision_web.py:242: ogólne „Reject” tylko bez dostępnej opcji authorizes=false; z taką opcją dostępna jest jedynie odmowa nazwaną opcją. Endpoint nadal przyjmuje odmowę bez option_id (src/heyaira/decision_answers.py:101).
R07 — Uzgodnić odmowę stale na iPhone docs/specs/decisions/D0-spec.md:219, docs/specs/decisions/D0-spec.md:899: stale można odrzucić przez link. ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift:297, ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift:303, ios/HeyAiraBridge/HeyAiraBridge/DecisionViews.swift:135: stale nie ma przycisków ani drogi do linku na ekranie aplikacji. Serwer dopuszcza odmowę (src/heyaira/decision_answers.py:113).
R08 — Poprawić zgodność typu authorizes w D4 docs/specs/decisions/D0-spec.md:353: options[].authorizes jest bool. ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift:34, ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift:53, ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift:207: model oczekuje String; bool z serwera daje nil. Przyciski pokazują label bez rozróżnienia odmowy; właściwą akcję rozstrzyga dopiero strona (src/heyaira/decision_web.py:80).
R09 — Zsynchronizować §10.4 z przyjętym §12.2 docs/specs/decisions/D0-spec.md:965 wymaga nazwanego zadania, docs/specs/decisions/D0-spec.md:969 opisuje overlay dla każdego holdu. §12.2 dopuszcza zmianę tych zasad (docs/specs/decisions/D0-spec.md:1078, docs/specs/decisions/D0-spec.md:1083). src/heyaira/decisions.py:553 dopuszcza null przy zawierającym zakresie i usunięcie istniejącego powiązania po zmianie tagów; src/heyaira/decisions.py:647 ukrywa hold zamkniętego zadania, a src/heyaira/decisions.py:374 odrzuca nowy. Wybrane i opisane w docs/specs/decisions/D1a-implementation.md:12; rozjazd starszego tekstu, nie niezaimplementowany warunek wejścia.
R10 — Uzgodnić komunikaty o wznowieniu docs/specs/decisions/D0-spec.md:962, docs/specs/decisions/D0-spec.md:990: hold usuwa koordynator, a potem ponownie wysyła workflow. src/heyaira/decision_web.py:259, ios/HeyAiraBridge/HeyAiraBridge/DecisionViews.swift:257 mówią, że sesja została powiadomiona i może kontynuować. src/heyaira/decision_answers.py:183 tylko kolejkuje powiadomienie projektu, nie wiadomość do sesji; hold pozostaje (tests/test_decisions_holds.py:69). Komunikat pomija wymagany ruch koordynatora.
R11 — Wyjaśnić legacy memory i decyzje obowiązujące docs/concepts/durable-state.md:5, docs/concepts/durable-state.md:26: „decision” to zaakceptowany kierunek w pamięci; brak oddzielnego cyklu propozycji/odpowiedzi. src/heyaira/server.py:3828 wymaga dla notatki jedynie rationale, bez passkey; obowiązywanie wylicza osobna tabela (src/heyaira/decisions.py:71, migrations/054_decisions.sql:2). Luka publicznego opisu: zapis notatki nie nadaje in_force.
R12 — Uzupełnić publiczny indeks ciągłości docs/CONTINUITY_PROTOCOL.md:32, docs/CONTINUITY_PROTOCOL.md:47: opis decyzji przez indeks pamięci i memory_get, bez indeksu obowiązywania. src/heyaira/server.py:4020, src/heyaira/server.py:4025, src/heyaira/decisions.py:682, src/heyaira/decisions.py:693: osobne decisions.in_force, attention, limity i flagi obcięcia. Publiczny opis nie obejmuje tych pól.
R13 — Uzupełnić publiczny opis powiadomień docs/reference/notifications.md:3, docs/reference/notifications.md:9, docs/reference/notifications.md:25: tabela typów nie zawiera zdarzeń decyzji ani kluczy. src/heyaira/server.py:1329, src/heyaira/decision_answers.py:183, src/heyaira/decision_passkeys.py:200: cztery typy decision_*, rzeczywiście kolejkowane. Luka dokumentacji, nawet gdy kontrola curated labels przechodzi.
R14 — Rozdzielić uprawnienia odczytu i użycia docs/reference/mcp-tools.md:12, docs/reference/mcp-tools.md:52: każdy wymieniony scope jest wymagany; przy decision_check podano razem tasks:read i tasks:write. src/heyaira/server.py:3678, src/heyaira/server.py:3680: odczyt wymaga tylko tasks:read; tasks:write jest sprawdzane dodatkowo wyłącznie przy use=true. Kontrola zgodności tabeli sprawdza sumę scope'ów, nie ich warunkowość.
R15 — Uzgodnić kompletność list D2/D4 docs/specs/decisions/D0-spec.md:545, docs/specs/decisions/D0-spec.md:546, docs/specs/decisions/D0-skill.md:6: kanały pokazują listę, kanoniczny skill przechodzi wszystkie kursory. clients/claude-mod/hooks/register.tsx:21, clients/claude-mod/hooks/register.tsx:98, clients/claude-mod/hooks/register.tsx:159: limit 10 stron z ostrzeżeniem; ios/HeyAiraBridge/HeyAiraBridge/DecisionStore.swift:34, ios/HeyAiraBridge/HeyAiraBridge/DecisionStore.swift:84, ios/HeyAiraBridge/HeyAiraBridge/BridgeAPIClient.swift:139: limit 500 pozycji, a pozostały kursor znika bez ostrzeżenia. Decyzja z dalszej strony nie zostanie otwarta z push.
R16 — Doprecyzować licznik belki D2 docs/specs/decisions/D0-spec.md:546, docs/specs/decisions/D0-spec.md:1017: belka z liczbą nieodpowiedzianych / open decyzji. src/heyaira/decisions.py:581 zalicza stale i blokujące lapsed do open; clients/claude-mod/hooks/format.ts:95, clients/claude-mod/hooks/format.ts:138 wyłączają je z total, a clients/claude-mod/hooks/register.tsx:340 ukrywa belkę przy zerowym total. Panel nadal zawiera „Do uzupełnienia”.
R17 — Oznaczyć treść autora na stronie docs/specs/decisions/D0-spec.md:626: label, konsekwencje i uzasadnienie mają być oznaczone jako tekst proponującego, oddzielnie od interpretacji grantu. src/heyaira/decision_web.py:180, src/heyaira/decision_web.py:192, src/heyaira/decision_web.py:199: strona pokazuje te pola bez oznaczenia ich autorstwa; grant ma osobny nagłówek „as the server reads it”. Hash nadal wiąże przechowywaną treść, lecz nie potwierdza prawdziwości opisu skutków.

Źródła

Pary plik:linia odnoszą się do powyższej rewizji. Odczytane pliki źródłowe, testy i opisy użyte do porównania (test odczytany nie oznacza testu uruchomionego):

  • Kontekst: AGENTS.md, README.md, docs/ARCHITECTURE.md, docs/index.md, mkdocs.yml, pyproject.toml, docs-requirements.txt.
  • Umowa i rola: docs/specs/org-v1/K0-work-contract.md, docs/specs/org-v1/K0-roles.md.
  • Decyzje: src/heyaira/decisions.py, src/heyaira/decision_answers.py, src/heyaira/decision_passkeys.py, src/heyaira/decision_web.py.
  • Powiązania serwera (odczytane fragmenty): src/heyaira/server.py, src/heyaira/admin.py, src/heyaira/workflow.py, src/heyaira/execution.py, src/heyaira/task_org.py, src/heyaira/bridge_reads.py, src/heyaira/bridge.py.
  • Baza: migrations/054_decisions.sql, migrations/055_decision_passkeys.sql.
  • Claude: clients/claude-mod/README.md, clients/claude-mod/hooks/register.tsx, clients/claude-mod/hooks/format.ts.
  • Codex: clients/codex-plugin/.codex-plugin/plugin.json, clients/codex-plugin/header.md, clients/codex-plugin/build_skill.py, clients/codex-plugin/skills/heyaira-decisions/SKILL.md.
  • iPhone: ios/HeyAiraBridge/HeyAiraBridge/DecisionModels.swift, ios/HeyAiraBridge/HeyAiraBridge/DecisionStore.swift, ios/HeyAiraBridge/HeyAiraBridge/DecisionAuthSession.swift, ios/HeyAiraBridge/HeyAiraBridge/DecisionViews.swift, ios/HeyAiraBridge/HeyAiraBridge/BridgeAPIClient.swift, ios/HeyAiraBridge/HeyAiraBridge/AppModel.swift, ios/HeyAiraBridge/HeyAiraBridge/HeyAiraBridgeApp.swift, ios/HeyAiraBridge/HeyAiraBridge/HeyAiraBridge.entitlements.
  • Specyfikacje: docs/specs/decisions/D0-spec.md, docs/specs/decisions/D0-skill.md, docs/specs/decisions/D1a-implementation.md, docs/specs/decisions/D1b-implementation.md.
  • Publiczne opisy: docs/concepts/durable-state.md, docs/CONTINUITY_PROTOCOL.md, docs/reference/mcp-tools.md, docs/reference/notifications.md, docs/agents/continuity-contract.md, docs/ROADMAP.md, docs/getting-started/overview.md, docs/operations/documentation-workflow.md.
  • Testy: tests/test_decisions.py, tests/test_decisions_holds.py, tests/test_decisions_e2e.py, tests/test_decisions_webauthn.py, tests/test_codex_plugin.py, tests/test_docs_contract.py.

Wyniki sprawdzeń i odwołania do wcześniejszych RESULT: dowody zadania.