chore(ideai): carnet de #69 — validation live partielle et réserve du lot 3
État `.ideai/` du chantier client téléphone, séparé du code applicatif conformément aux précédents `5ee25d1` / `8e481ae`. - Carnet #69 : périmètre exact de la validation live utilisateur sur téléphone réel (lots 1 et 2 validés en réel via l'appairage puis le workspace ; lot 3 — `TerminalKeyBar` et invariant de focus — NON exercé), arbitrage Main autorisant le merge avec réserve écrite, et report de l'écart Playwright vers #63 plutôt que vers un ticket neuf. - Faits de topologie mis à jour après rebase sur `develop@fe0e53e` : les SHA cités (`e22ea5b`/`8f15ad6`/`6ed0087`) n'existaient plus sur aucune branche. - Journal des tâches de fond : complétions enregistrées. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -7007,10 +7007,36 @@
|
|||||||
"ticket_id": "36f9d4e8-fdb1-4e8d-9b35-56d36e7d20ee",
|
"ticket_id": "36f9d4e8-fdb1-4e8d-9b35-56d36e7d20ee",
|
||||||
"conversation_id": "6bc594e8-a37c-0dbd-1de6-6e3b73002cb4"
|
"conversation_id": "6bc594e8-a37c-0dbd-1de6-6e3b73002cb4"
|
||||||
},
|
},
|
||||||
"state": "running",
|
"state": "completed",
|
||||||
"wakePolicy": "recordOnly",
|
"wakePolicy": "recordOnly",
|
||||||
"createdAtMs": 1784206763128,
|
"createdAtMs": 1784206763128,
|
||||||
"updatedAtMs": 1784206763128,
|
"updatedAtMs": 1784206996360,
|
||||||
|
"deadlineMs": null,
|
||||||
|
"result": {
|
||||||
|
"outcome": "success",
|
||||||
|
"finished_at_ms": 1784206996360,
|
||||||
|
"exit_code": null,
|
||||||
|
"summary": "Headless rendezvous completed with Final",
|
||||||
|
"stdout_tail": "Merge terminé, sans conflit, strictement en local. `develop` est maintenant sur **`fe0e53e`**, working tree propre.\n\n## Pas de passe QA supplémentaire — et voici pourquoi\n\nTu m'as laissé le déclenchement à disposition ; je ne l'ai pas demandé, mais je ne me suis pas contenté de tes constats live non plus. Le carnet de #65 contenait déjà une vérif QA à exécution réelle, et **je l'ai ré-exécutée moi-même avant de merger**, puis une seconde fois sur `develop` après merge :\n\n```\ncargo test -p backend → 41 passed, 0 failed\ncargo test -p web-server → 55 passed, 0 failed\ncargo test -p app-tauri → 35 passed, 0 failed\n```\n\nChiffres identiques au carnet, 0 échec. Tes constats live (démarrage, SPA servi, contrôle d'origine, reverse proxy) couvrent le chemin d'exécution que les tests ne touchent pas ; l'ensemble satisfait la règle d'or. Deux réserves que je te remonte sans les avoir traitées : les 10 échecs `openai_compat` de `cargo test --workspace` sont **préexistants sur `506d589`** (bind réseau interdit par la sandbox), donc hors périmètre ; et le carnet signale qu'aucun test ne couvre `run_embedded().stop()` — à prendre dans #68, qui consommera ce handle.\n\n## Les trois arbitrages\n\n**1. Squash, oui.** `82e8e77` était un commit de sûreté disant explicitement « ne fige aucun contrat », et `ddbea7b` comblait précisément l'écart qu'il annonçait. Les deux n'ont de sens qu'ensemble : laisser « état intermédiaire non figé » dans `develop` y aurait inscrit durablement une affirmation devenue fausse. La branche n'avait jamais été poussée et n'était contenue par aucune autre — réécriture sans risque. J'ai vérifié que l'arbre du commit squashé est **identique bit pour bit** à `ddbea7b` (`git diff --cached ddbea7b` vide), et j'ai gardé l'historique d'origine sur `backup/ticket65-pre-squash-ddbea7b` — à toi de me dire quand le supprimer.\n\n**2. `dist-web`, d'accord avec toi.** Règle d'ignore ajoutée à côté de `frontend/dist/`, même classe : sortie de build rebuildable. Rien de ce dossier n'est entré dans l'historique.\n\n**3. L'état `.ideai/` est durable, je l'ai committé** dans un `chore(ideai)` séparé du code, comme le précédent `8e481ae`. Les tickets et `.ideai/memory/` sont le store versionné assumé (le `.gitignore` le dit noir sur blanc). Scan de secrets passé, rien trouvé.\n\nLes commits, sur `feature/ticket65-idea-serve-headless` puis mergés en `--no-ff` (pas de rebase : `develop` n'avait pas bougé, merge-base = son sommet exact) :\n\n| Commit | Contenu |\n|---|---|\n| `0e15482` | `feat(web-server)` — extraction `idea-serve` (squash) |\n| `4f57e5a` | `chore(gitignore)` — ignore `frontend/dist-web/` |\n| `5ee25d1` | `chore(ideai)` — tickets #13/#65 + #68-#70, note mémoire |\n| `fe0e53e` | merge `--no-ff` dans `develop` |\n\nBranche de feature supprimée après confirmation qu'elle était bien intégrée.\n\n**Un point que je te laisse arbitrer** : `.ideai/background-tasks/*.json` est suivi et je l'ai committé par cohérence avec le précédent, mais c'est un journal d'exécution machine-local (7000+ lignes, avec des `stdout_tail` entiers) qui ressemble plus à `.ideai/conversations/` — déjà ignoré — qu'à de l'état durable. Le désuivre changerait ce qui est versionné : c'est une décision d'architecture, pas de topologie git, donc elle revient à Architect. Ça vaut un ticket.\n\n`develop` est en avance de 4 commits sur `origin/develop`. Aucune action sortante : pas de push, pas de PR.",
|
||||||
|
"stderr_tail": null
|
||||||
|
},
|
||||||
|
"completionDelivered": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "176eb370-fbe9-4fab-96e4-0d0a813ec2c9",
|
||||||
|
"projectId": "97b49ac2-8376-4aa3-8ea9-bf3ac81d0023",
|
||||||
|
"ownerAgentId": "cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5",
|
||||||
|
"kind": {
|
||||||
|
"kind": "headlessRendezvous",
|
||||||
|
"requester_agent_id": "a6ced819-b893-4213-b003-9e9dc79b9641",
|
||||||
|
"target_agent_id": "cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5",
|
||||||
|
"ticket_id": "54fd5f2e-35d2-465f-b224-a918ec99189a",
|
||||||
|
"conversation_id": "6bc594e8-a37c-0dbd-1de6-6e3b73002cb4"
|
||||||
|
},
|
||||||
|
"state": "running",
|
||||||
|
"wakePolicy": "recordOnly",
|
||||||
|
"createdAtMs": 1784207556306,
|
||||||
|
"updatedAtMs": 1784207556306,
|
||||||
"deadlineMs": null,
|
"deadlineMs": null,
|
||||||
"result": null,
|
"result": null,
|
||||||
"completionDelivered": false
|
"completionDelivered": false
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
issueRef: "#69"
|
issueRef: "#69"
|
||||||
version: 9
|
version: 11
|
||||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||||
updatedAt: 1784202783353
|
updatedAt: 1784207736267
|
||||||
---
|
---
|
||||||
# Ticket #69 — Adaptibilité client téléphone (carnet de chantier)
|
# Ticket #69 — Adaptibilité client téléphone (carnet de chantier)
|
||||||
|
|
||||||
Statut : **QA — en attente de validation live utilisateur sur un VRAI téléphone**.
|
Statut : **validation live utilisateur PARTIELLE effectuée — mergé dans `develop` avec réserve explicite sur le lot 3**.
|
||||||
Branche : `feature/ticket69-mobile-responsive-client` (base `develop` @ `506d589`). Commits : `e22ea5b` (shell), `8f15ad6` (terminal + tests), `6ed0087` (fix typecheck). Frontend uniquement — vérifié.
|
Branche : `feature/ticket69-mobile-responsive-client`, **rebasée sur `develop` @ `fe0e53e`** (base d'origine `506d589`). Commits après rebase : `48b8853` (shell), `62ecefe` (terminal + tests), `f0f2f3b` (fix typecheck) — anciennement `e22ea5b`/`8f15ad6`/`6ed0087`. Arbre `frontend/` identique bit pour bit avant/après rebase (`git diff 6ed0087 HEAD -- frontend` vide) ; historique d'origine conservé sur `backup/ticket69-pre-rebase-6ed0087`. Frontend uniquement — vérifié.
|
||||||
|
|
||||||
## Cadrage Architect
|
## Cadrage Architect
|
||||||
Ticket **frontend-pur** : aucun changement DTO, use case, ni modèle `LayoutTree`. Contrats HTTP/WS et layout/terminal inchangés. Mais PAS du « CSS pur ».
|
Ticket **frontend-pur** : aucun changement DTO, use case, ni modèle `LayoutTree`. Contrats HTTP/WS et layout/terminal inchangés. Mais PAS du « CSS pur ».
|
||||||
@ -29,13 +29,28 @@ Le clavier virtuel n'a ni Esc, ni Tab, ni Ctrl, ni flèches : on pouvait taper u
|
|||||||
- **CSS mobile confirmé DANS le bundle** (les valeurs arbitraires Tailwind avec `env()` no-opent en silence) : `100dvh`, `60dvh`, les 4 `safe-area-inset-*`, `viewport-fit=cover`, `.h-\[60dvh\]{height:60dvh}`.
|
- **CSS mobile confirmé DANS le bundle** (les valeurs arbitraires Tailwind avec `env()` no-opent en silence) : `100dvh`, `60dvh`, les 4 `safe-area-inset-*`, `viewport-fit=cover`, `.h-\[60dvh\]{height:60dvh}`.
|
||||||
- Non-régression desktop : `LayoutGrid` ne passe pas `onReady` ; chemin desktop inchangé.
|
- Non-régression desktop : `LayoutGrid` ne passe pas `onReady` ; chemin desktop inchangé.
|
||||||
- Rendu réel Chrome headless 360×780 : pairing tient sans débordement horizontal.
|
- Rendu réel Chrome headless 360×780 : pairing tient sans débordement horizontal.
|
||||||
|
- **Ré-exécutée par Git sur la base rebasée `fe0e53e` avant merge** (les chiffres du carnet ne valaient que sur `506d589`) : `npm run typecheck` exit 0 · `npx vitest run` → 85 files / **774 passed**, 0 échec · `VITE_TRANSPORT=http npx vite build` exit 0. Identique — le rebase n'a rien cassé.
|
||||||
|
|
||||||
## Réserve ASSUMÉE — trou de couverture réel
|
## Réserve ASSUMÉE — trou de couverture réel
|
||||||
**jsdom n'évalue PAS les media queries** : les tests sont structurels, pas visuels. Ils ne prouvent NI le rendu aux breakpoints, NI l'effet réel de `dvh`, NI les safe areas, NI le clavier virtuel/focus sur navigateur mobile. QA : « acceptable pour merger avec réserve explicite », pas rouge. **C'est exactement ce que la validation utilisateur doit couvrir.**
|
**jsdom n'évalue PAS les media queries** : les tests sont structurels, pas visuels. Ils ne prouvent NI le rendu aux breakpoints, NI l'effet réel de `dvh`, NI les safe areas, NI le clavier virtuel/focus sur navigateur mobile. QA : « acceptable pour merger avec réserve explicite », pas rouge. **C'est exactement ce que la validation utilisateur doit couvrir.**
|
||||||
Workspace + keybar non vérifiés visuellement à 360px (demande un serveur appairé + PTY vivant = territoire #65) — angle mort restant.
|
|
||||||
|
|
||||||
## Écart de périmètre à arbitrer (Playwright)
|
## Validation live utilisateur — PÉRIMÈTRE EXACT (2026-07-16)
|
||||||
Lot 4 demandait « Playwright ou équivalent ». DevFrontend a livré l'équivalent (vitest/jsdom) et REFUSÉ d'installer Playwright unilatéralement (binaires navigateur + surface CI = décision de dépendance qui remonte à Architect/Main). Avis QA : non bloquant pour ce lot, mais vitest/jsdom **n'est pas un équivalent complet** pour un ticket dont le risque principal est visuel mobile. ⇒ **Follow-up à décider** : ticket « tests de rendu réel aux breakpoints » si le projet accepte une dépendance navigateur/CI.
|
|
||||||
|
Effectuée par l'utilisateur sur un **vrai téléphone**, contre le serveur `idea-serve` exposé via le reverse proxy `https://idea.anthonybouteiller.ovh`.
|
||||||
|
|
||||||
|
**Couvert — verdict utilisateur : OK.** « Le terminal s'ouvre correctement pour le téléphone. » Atteindre le terminal implique d'avoir traversé l'appairage **puis** le workspace : cela valide en réel le shell (lot 1) et la mise en page à taille de téléphone (lot 2), y compris le `100dvh` et le `60dvh` de la cellule terminal, que jsdom ne pouvait pas prouver.
|
||||||
|
|
||||||
|
**NON couvert — angle mort qui subsiste.** Le **lot 3 n'a pas été exercé** : la `TerminalKeyBar` (Esc/Tab/Ctrl-C/Ctrl-D/flèches) n'a pas été utilisée, et le comportement de focus au tap — l'invariant « chaque tap annule le déplacement de focus puis refocalise xterm », sans lequel le clavier virtuel se referme à chaque touche — n'a **pas** été observé sur un navigateur mobile réel. Or c'est le cœur du ticket : le carnet identifie le terminal, pas le layout, comme le vrai blocage.
|
||||||
|
|
||||||
|
Le test qui fermerait ce trou tient en 30 s : lancer une commande longue, taper **Ctrl-C** dans la barre de touches, vérifier (a) que la commande s'interrompt et (b) que le clavier virtuel reste ouvert.
|
||||||
|
|
||||||
|
**Arbitrage Main : merge autorisé avec cette réserve écrite, pas effacée.** Le risque résiduel est borné (surface frontend-pure, desktop non atteint, non-régression prouvée) et ne justifie pas de bloquer le sprint. Mais tant que le test Ctrl-C n'est pas fait, **le lot 3 est livré et non prouvé en conditions réelles** — à ne pas présenter comme validé.
|
||||||
|
|
||||||
|
**Report de la réserve dans l'historique git (Git, 2026-07-16)** : la réserve est recopiée dans le corps du commit de merge de `develop`. Un carnet peut être réécrit ; un message de commit mergé, non. Le fait « lot 3 non prouvé en réel au moment du merge » est donc daté et infalsifiable, indépendamment de ce fichier.
|
||||||
|
|
||||||
|
## Écart de périmètre — Playwright : TRANCHÉ, reporté vers #63
|
||||||
|
Lot 4 demandait « Playwright ou équivalent ». DevFrontend a livré l'équivalent (vitest/jsdom) et REFUSÉ d'installer Playwright unilatéralement (binaires navigateur + surface CI = décision de dépendance qui remonte à Architect/Main) — refus fondé. QA : non bloquant pour ce lot.
|
||||||
|
**Décision Main (2026-07-16) : ne bloque pas #69 et ne donne PAS lieu à un ticket neuf.** La décision de dépendance appartient à **#63 « Système de test de l'UI »**, déjà ouvert, où elle sera tranchée avec la stratégie de test UI dans son ensemble plutôt qu'au coin d'un sprint serveur/client. Rationnel conservé : Playwright rend un vrai navigateur (media queries, `dvh`, safe areas évalués pour de vrai) et aurait attrapé automatiquement les deux bugs de classe « CSS silencieusement absent du bundle » corrigés ici ; il **n'émule** cependant qu'un téléphone et ne remplace pas la validation manuelle du clavier virtuel — sa valeur est d'empêcher la régression silencieuse entre deux validations manuelles.
|
||||||
|
|
||||||
## Prochaine étape
|
## Prochaine étape
|
||||||
Validation live utilisateur sur un vrai téléphone (build `VITE_TRANSPORT=http`, servi par `idea --serve`/`idea-serve`, accès LAN). Si OK → Git merge dans develop (Git passera #69 avant #65 si les deux sont prêts : petit, frontend-pur, faible risque).
|
Merge fait par Git (rebase + `--no-ff` dans `develop`, sans conflit). **Le test Ctrl-C sur téléphone réel reste ouvert** : s'il échoue, il ouvre un bug, il ne réverte pas le ticket. Le passage du ticket à un statut terminal appartient à Main : tant que le lot 3 n'est pas prouvé en réel, « mergé » ≠ « validé ».
|
||||||
|
|||||||
@ -8,9 +8,9 @@ sprint: "028179b1-eaf4-41e9-9c1f-7c37125117e6"
|
|||||||
links: []
|
links: []
|
||||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||||
createdBy: {"kind":"user"}
|
createdBy: {"kind":"user"}
|
||||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||||
createdAt: 1784193391258
|
createdAt: 1784193391258
|
||||||
updatedAt: 1784202783353
|
updatedAt: 1784207736267
|
||||||
version: 9
|
version: 11
|
||||||
---
|
---
|
||||||
J'aimerais un format vertical qui rende l'app client compatible téléphone
|
J'aimerais un format vertical qui rende l'app client compatible téléphone
|
||||||
@ -725,7 +725,7 @@
|
|||||||
"assignedAgentIds": [
|
"assignedAgentIds": [
|
||||||
"a6ced819-b893-4213-b003-9e9dc79b9641"
|
"a6ced819-b893-4213-b003-9e9dc79b9641"
|
||||||
],
|
],
|
||||||
"updatedAt": 1784202783353
|
"updatedAt": 1784207736267
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"issueRef": "#70",
|
"issueRef": "#70",
|
||||||
|
|||||||
Reference in New Issue
Block a user