Skip to content

M6: commands — pause/resume/delete end to end - #3

Merged
Denisergocmen924 merged 5 commits into
masterfrom
feat/m6-commands
Aug 26, 2026
Merged

M6: commands — pause/resume/delete end to end #3
Denisergocmen924 merged 5 commits into
masterfrom
feat/m6-commands

Conversation

@Denisergocmen924

Copy link
Copy Markdown
Owner

No description provided.

Denisergocmen924 and others added 5 commits August 26, 2026 16:37
`pending_delete`, silme akışının ara durumunu ("emir verildi, cihaz henüz
duymadı") işaretlemek için tasarlanmıştı. Ama yazacak kimse yoktu:

  * dashboard yazamaz — db/rls.sql `devices` üzerindeki UPDATE yetkisini tek
    sütuna daraltıyor: grant update (device_name). Bu kilit bilinçliydi;
    key_hash / last_seen / logging_enabled'ın yazarı collector'dır.
  * collector yazmıyor — supabase_client.py'deki DEVICE_WRITABLE_COLUMNS
    listesinin dışındaydı ve yanındaki not "kimin yazacağı M6'da karara
    bağlanacak" diyordu.

Yazan olmayınca sütun her satırda `false` kaldı: kimsenin dolduramadığı bir
bayrak hiçbir şey işaretlemiyordu. Aynı bilgi `commands` tablosunda zaten
duruyor — bekleyen silme = (type='delete' and status='pending'). Kopyayı
yaşatmak için ya kilidi gevşetmek ya yeni bir mekanizma (trigger / ayrı
endpoint) eklemek gerekiyordu; kaldırmak üçünün de bedelini sıfırlıyor.

Değişiklikler:
  * db/migrations/0003_drop_pending_delete.sql — yeni migration, doğrulama
    sorgusu ve geri alma notuyla birlikte
  * db/schema.sql — sütun çıkarıldı (her DB değişikliğinde iki dosya kuralı)
  * db/rls.sql — kolon-yetki yorumundaki atıf temizlendi
  * collector/auth.py — DeviceIdentity.pending_delete alanı ve satır eşlemesi
  * collector/supabase_client.py — find_device_by_key_hash select listesi

ÇALIŞTIRMA SIRASI: migration, `pending_delete`'i artık SELECT etmeyen collector
Fly'a deploy EDİLDİKTEN SONRA çalıştırılır. Ters sırada canlı collector olmayan
bir sütunu istemeye devam eder ve device key ile gelen her istek hata alır.

Veri kaybı yok: sütun hiç yazılmadı. Testler: 226 passed.
Komut kuyruğunun sunucu tarafı: dashboard `commands` tablosuna pending satır
ekler, agent poll ile alır, uygular ve id'sini `POST /ingest` gövdesinde geri
yollar.

- endpoints_commands.py: GET /commands (device key) + process_acks()
- db_access.py: server_now() ve call_or_503() — iki uç noktanın paylaştığı
  yardımcılar; ingest'in içindeki yereller buraya taşındı
- supabase_client: delete_device / list_pending_commands /
  mark_commands_applied; `logging_enabled` allowlist'e eklendi

Kilitli kararlar (md/memory/decisions.md → "Komutlar (M6)"):
- #6 GET /commands de `last_seen` tazeler — pause'daki agent offline görünmesin
- #7 `devices.logging_enabled` komut VERİLDİĞİNDE değil, agent UYGULADIĞINI
  bildirdiğinde yazılır; değer gövdeden değil DB'deki `type` alanından türer
- ack, satır yazımından SONRA işlenir: delete cihaz satırını siler (CASCADE),
  ters sırada aynı gövdedeki son ölçümler foreign key'e takılırdı
- mark_commands_applied'da `status=eq.pending` filtresi bilerek YOK: yarıda
  kalmış bir delete, tekrarlanan ack ile tamamlanabilsin

collector 0.3.0 → 0.4.0

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Buradaki hataların hepsi sessiz: komut teslim edilmezse agent hiç duraklamaz,
ack işlenmezse aynı komut sonsuza kadar tekrar gelir, delete yanlış sırada
işlenirse cihaz kaydı öksüz kalır. Hiçbiri istisna fırlatmaz.

Kapsanan: poll'ün last_seen tazelemesi, yanıtın yalnızca id+type taşıması,
sorgunun doğrulanmış cihaza kilitli olması, ack'in device_id ile sınırlanması,
pause/resume sunucu kopyası, "son komut kazanır", delete'in her şeyin önüne
geçmesi, silinmiş satıra yazmama, 503 yolları ve satırların delete'ten önce
yazılması.

Suite 226 → 248. 25 sabotaj denendi, hepsi yakalandı (md/memory/decisions.md →
"Her test, koruduğu kod bozularak doğrulanır").

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Agent artık `GET /commands` ile bekleyen komutları çekiyor, uyguluyor ve
`applied_command_ids` ile ack'liyor. Poll'ün kendi HTTP istemcisi var: pause
sırasında ve backoff altında da sorulmaya devam eder, yoksa `resume` cihaza
hiç ulaşamazdı.

Spec'ten iki bilinçli sapma:

1. Ack, telemetriye bağlanmadı. CLAUDE.md §7 yalnızca `delete` ack'ini pause
   istisnası sayıyor — ama pause ack'i de gitmezse sunucu komutu her poll'da
   yeniden verir ve `devices.logging_enabled` kopyası hiç güncellenmez.
   `send_acks` bu yüzden ölçüm taşımayan küçük bir kontrol mesajı: pause
   telemetriyi durdurur, agent'ın "uyguladım" demesini değil.

2. Self-uninstall doğrudan yapılamıyor. Agent yetkisiz kullanıcıyla,
   NoNewPrivileges=yes ve ProtectSystem=strict altında çalışır; uninstall.sh'i
   kendi içinden çağırsa hem yetkisi yetmez hem de `systemctl disable --now`
   betiği kendi cgroup'uyla öldürürdü. Bunun yerine agent state dizinine bir
   işaret dosyası bırakıyor; yeni tracebox-uninstall.path onu görüp kaldırmayı
   root tarafında çalıştırıyor. Yalıtım ayarlarının hiçbiri gevşetilmedi.

delete sırası (§11 Boşluk E) korundu: ack → 200 → yerel wipe → işaret. Ack
gitmezse hiçbir şey silinmez, komut `pending` kalır ve tekrar denenir.

install.sh iki yeni birimi kurup izleyiciyi başlatıyor; başlatmadan önce eski
kurulumdan kalan işareti siliyor (yoksa yeni kurulum ilk saniyede kendini
kaldırırdı). uninstall.sh her iki birimi de temizliyor ama kendisini çalıştıran
servisi durdurmuyor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Yeni dosyalar: test_commands.py (poll ayrıştırma, idempotent uygulama, delete
sırası), test_loop_commands.py (ack'lerin state'e girip çıkışı),
test_entrypoint.py (silinmiş cihaz bir daha açılmaz). test_shipper.py,
test_spool.py ve test_install_scripts.py genişletildi.

En kritik üçü:
  - tekrar gelen komut yeniden ack'lenir — edilmezse duraklatılmış agent
    sonsuza kadar öyle kalır ve dashboard onu "çalışıyor" gösterir
  - delete, yerel veriye dokunmadan ÖNCE ack atar — tersi anahtarı silip
    cihaz satırını sunucuda ölümsüz bırakırdı
  - path unit'in izlediği yol ile agent'ın yazdığı yol aynı sabitten gelir —
    ayrılırlarsa kaldırma sessizce hiç başlamaz

41 kasıtlı bozmanın 41'i ilgili testi kırmızıya çevirdi.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Denisergocmen924
Denisergocmen924 merged commit 44091f1 into master Aug 26, 2026
1 check passed
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