Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions devlog/_plan/261111_link_child_updates/000_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ file or symbol; later phases MODIFY it.
| file | `child-ops-types.ts`: `ChildJob`, `ChildJobItem`, `ChildItemState`, `ChildOpsEnv`, `ItemRunner`, `ItemOutcome` | `src/link/child-ops-types.ts` | 030 (moves the job types out of 020's engine) |
| file | `child-ops-engine.ts`: `createChildOpsEngine`, `sharedChildOpsEngine`, `resetSharedChildOpsEngineForTests` (030); methods `submit(request, env)` (030; 020 shipped `submit(request)`), `job` (`ChildJob \| undefined`), `activeJob`, `whenDone` (050), `settled` | `src/link/child-ops-engine.ts` | 020 (030, 050 extend) |
| file | `child-ops-runners.ts`: `runSyncItem`, `runRestartCodexItem`, `runUpdateItem`, `pinnedSync` | `src/link/child-ops-runners.ts` | 030 |
| file | `sync-then-restart.ts`: `syncThenRestart`, `pinnedSyncRanNothing`, `RESTART_RESULT_UNKNOWN` (moved from `child-ops-runners.ts`, which re-exports the constant); the one "sync then guarded restart" sequence for the runners and `ocx sync --restart-children` | `src/link/sync-then-restart.ts` | 040 (extracted from 030's `syncWithRestart`) |
| file | `child-ops-scheduler.ts`: `createChildOpsScheduler`, `createLinkBackoff` (shared by 050 and 070) | `src/link/child-ops-scheduler.ts` | 050 |
| file | `child-policy.ts`, `child-ops-host.ts` (`startChildOpsHost`) | `src/link/` | 050 |
| file | `child-update-sweep.ts` | `src/link/child-update-sweep.ts` | 070 |
Expand Down
471 changes: 371 additions & 100 deletions devlog/_plan/261111_link_child_updates/040_sync_loosening.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions devlog/_plan/261111_link_child_updates/060_dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,9 @@ that it shows the `desktop-app` owner action.
GUI parity test's regex is widened for 030's `refusal()` switch, which uses `fail(code, …)`.
3. **Restart scope** is chosen per click in a dialog; the policy panel's `childCodexRestart` only governs the
automatic restart (050), so there is no "remember scope" setting.

## Carried from wp3 review (#8513)

- Remote Link guide (English + 7 translations): the restart protection paragraph must say to wait for active Codex
turns to finish before a restart, not only pause new requests, because a turn running a tool has no relayed request in
flight (CodeRabbit 4533270262).
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/fr/guides/remote-link.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Sur le Home, `ocx link check (--link-id <id> | --all)` lit pour chaque enfant la

### Opérer les enfants depuis le Home

`ocx link sync`, `ocx link restart-codex` et `ocx link update` s’exécutent sur les enfants lancés par le Home via la connexion SSH du lien et affichent la tâche en JSON. `sync` exécute le `ocx sync --expect-link` épinglé (enfant 2.93.0 ou plus récent). `restart-codex` synchronise, puis redémarre les app-servers Codex de l’enfant pour qu’un Codex en cours charge le catalogue actuel ; `--scope codex` relance aussi l’application de bureau. Un redémarrage vise un seul lien ; `restart-codex` et `--restart-codex` exigent `--yes`, tandis que `ocx link sync --link-id <id> --restart-app-server-only` redémarre les app-servers sans confirmation. Le redémarrage est ignoré (`restart-skipped:link-active`) tant que le Home relaie une requête de modèle pour cet enfant. Pour un enfant antérieur à 2.69, une requête non diffusée en flux n’est visible qu’au début de sa réponse. `update --yes` met l’OpenCodex de l’enfant à la version de ce Home, jamais à une autre, avec le propre outil de mise à jour de l’enfant (enfant 2.97.0 ou plus récent ; npm et pnpm passent par leur lanceur Node, si bien que `ocx link check` y exécute aussi `node --version` en lecture seule), un enfant à la fois, puis resynchronise après une application réussie, échouée ou annulée ; une application au résultat inconnu n’est ni relancée ni resynchronisée, vérifiez-la avec `ocx link check`. La mise à jour interrompt les requêtes relayées pour cet enfant. Les enfants Windows ne prennent en charge que `sync`, et les enfants `ocx-child` signalent redémarrages et mises à jour comme non pris en charge. La CLI exige un Home lié à loopback ; sur tout autre Home, ces opérations ne sont pas disponibles, et le tableau de bord ne les propose pas. Détails et codes de sortie : [Operating Children from the Home](/guides/remote-link/#operating-children-from-the-home) (en anglais). Cette protection est au mieux : une requête qui démarre entre la vérification et le redémarrage peut encore être interrompue ; suspendez les nouvelles requêtes sur cet enfant si ses tours doivent être préservés.
`ocx link sync`, `ocx link restart-codex` et `ocx link update` s’exécutent sur les enfants lancés par le Home via la connexion SSH du lien et affichent la tâche en JSON. `sync` exécute le `ocx sync --expect-link` épinglé (enfant 2.93.0 ou plus récent). `restart-codex` synchronise, puis redémarre les app-servers Codex de l’enfant pour qu’un Codex en cours charge le catalogue actuel ; `--scope codex` relance aussi l’application de bureau. Un redémarrage vise un seul lien ; `restart-codex` et `--restart-codex` exigent `--yes`, tandis que `ocx link sync --link-id <id> --restart-app-server-only` redémarre les app-servers sans confirmation. Le redémarrage est ignoré (`restart-skipped:link-active`) tant que le Home relaie une requête de modèle pour cet enfant. Pour un enfant antérieur à 2.69, une requête non diffusée en flux n’est visible qu’au début de sa réponse. `update --yes` met l’OpenCodex de l’enfant à la version de ce Home, jamais à une autre, avec le propre outil de mise à jour de l’enfant (enfant 2.97.0 ou plus récent ; npm et pnpm passent par leur lanceur Node, si bien que `ocx link check` y exécute aussi `node --version` en lecture seule), un enfant à la fois, puis resynchronise après une application réussie, échouée ou annulée ; une application au résultat inconnu n’est ni relancée ni resynchronisée, vérifiez-la avec `ocx link check`. La mise à jour interrompt les requêtes relayées pour cet enfant. Les enfants Windows ne prennent en charge que `sync`, et les enfants `ocx-child` signalent redémarrages et mises à jour comme non pris en charge. La CLI exige un Home lié à loopback ; sur tout autre Home, ces opérations ne sont pas disponibles, et le tableau de bord ne les propose pas. Détails et codes de sortie : [Operating Children from the Home](/guides/remote-link/#operating-children-from-the-home) (en anglais). Cette protection est au mieux : une requête qui démarre entre la vérification et le redémarrage peut encore être interrompue ; suspendez les nouvelles requêtes sur cet enfant si ses tours doivent être préservés. `ocx sync --restart-children` (ou `--restart-children=codex --yes`) applique la même règle lors de la propagation d’une synchronisation du Home, à tous les enfants ou à ceux désignés par `--child <linkId>` : chaque enfant est synchronisé, et seul son redémarrage est sauté (`restart-skipped:link-active`) tant qu’une requête relayée est en cours.

Ne liez pas une machine qui ne vous appartient pas : le Home y exécute des commandes avec votre clé SSH.

Expand Down
6 changes: 3 additions & 3 deletions docs-site/src/content/docs/fr/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,11 @@ La section **OAuth reliability** indique si le stockage des identifiants est acc

## Synchronisation du catalogue

### `ocx sync [--expect-link <linkId> | --expect-hub-key <apiKeyId>] [--local-only] [--json] [--restart-codex] [--restart-app-server-only]` <span id="ocx-sync---restart-codex---restart-app-server-only"></span>
### `ocx sync [--expect-link <linkId> | --expect-hub-key <apiKeyId>] [--local-only] [--json] [--restart-codex] [--restart-app-server-only] [--child <linkId>]... [--restart-children[=app-server] | --restart-children=codex --yes]` <span id="ocx-sync---restart-codex---restart-app-server-only"></span>

Sur un Home Remote Link, après la validation et l’enregistrement d’un catalogue à jour, `ocx sync` synchronise aussi les Enfants liés admissibles. `--local-only` désactive cette propagation. `--json` produit un seul document `ocx.sync.fanout/1` contenant le résultat du Home et l’état de chaque Enfant ; un Enfant ignoré indique la raison. Le code de sortie non nul du Home est renvoyé sans modification. Si le Home réussit, un Enfant connecté ignoré pendant la propagation, en échec ou en délai dépassé, ou un registre de liens illisible, entraîne le code de sortie 6. Les exclusions intentionnelles, comme les liens initiés par le client et `--local-only`, conservent leur comportement ; les Enfants connectés ignorés reçoivent une indication `hint`. En mode texte, le registre illisible produit un message sans chemin. Le code 7 est réservé à une mise à jour en cours. Si la synchronisation du Home lève une erreur en mode JSON, stdout conserve un seul document et stderr fournit un diagnostic assaini.
Sur un Home Remote Link, après la validation et l’enregistrement d’un catalogue à jour, `ocx sync` synchronise aussi les Enfants liés admissibles. `--local-only` désactive cette propagation. `--json` produit un seul document `ocx.sync.fanout/1` contenant le résultat du Home et l’état de chaque Enfant ; un Enfant ignoré indique la raison. Le code de sortie non nul du Home est renvoyé sans modification. Si le Home réussit, un Enfant connecté ignoré pendant la propagation, en échec ou en délai dépassé, ou un registre de liens illisible, entraîne le code de sortie 6. Les exclusions intentionnelles, comme les liens initiés par le client et `--local-only`, conservent leur comportement ; les Enfants connectés ignorés reçoivent une indication `hint`. En mode texte, le registre illisible produit un message sans chemin. Le code 7 est réservé à une mise à jour en cours. Si la synchronisation du Home lève une erreur en mode JSON, stdout conserve un seul document et stderr fournit un diagnostic assaini. Les liens exclus par `--child` (`not-selected`) et les Enfants occupés par une opération d’Enfant (`child-busy`) sont aussi des exclusions intentionnelles sans code 6 ; un redémarrage d’Enfant demandé qui n’a pas eu lieu avec certitude produit le code 6.

La propagation ne demande jamais le redémarrage de l’application Codex ni d’un app-server sur un Enfant. Pour cela, utilisez GOAT, exécutez `ocx sync --restart-codex` sur un Enfant `ocx` complet, ou relancez séparément Codex Desktop et les processus `app-server` sur un hôte léger `ocx-child`. La synchronisation épinglée de l’Enfant peut néanmoins redémarrer son propre runtime client OpenCodex après l’application de réglages Home modifiés. Si le Home interrompt son processus SSH local après un délai dépassé, une synchronisation distante déjà lancée peut continuer sur l’Enfant.
La propagation ne demande aucun redémarrage de Codex sur un Enfant, sauf si vous passez `--restart-children` (les app-servers) ou `--restart-children=codex --yes` (l’application Codex Desktop, ce qui met fin aux conversations en cours et nécessite une session de bureau ouverte sur cette machine). Le Home synchronise d’abord chaque Enfant sélectionné, relit l’activité de cet Enfant, puis envoie le redémarrage dans une seconde synchronisation épinglée. Il saute le redémarrage, jamais la synchronisation, pour un Enfant qui relaie une requête de modèle à ce moment (`restart-skipped:link-active`) ou dont il ne peut pas lire l’activité (`restart-skipped:activity-unknown`), pour les Enfants Windows (`restart-skipped:windows`) et pour `ocx-child` (`restart-unsupported:ocx-child`), puis quitte avec le code 6. Un lien dont le type d’Enfant n’est pas enregistré reçoit tout de même l’option de redémarrage lors de cette seconde synchronisation ; c’est ainsi que le Home apprend qu’il exécute `ocx-child`, qui ignore l’option. Si le redémarrage n’a pas pu être envoyé, ou a été envoyé sans résultat connu, la ligne de l’Enfant indique `restart-not-run` ou `restart-result-unknown` et le code de sortie est aussi 6. Comme pour `ocx link restart-codex`, cette protection est au mieux : une requête qui démarre entre cette lecture et le redémarrage peut encore être interrompue. `--child <linkId>` (répétable) limite la propagation à ces liens ; les autres sont signalés `not-selected`. Un Enfant occupé par une opération d’Enfant, comme `ocx link update`, est ignoré avec `child-busy`. La synchronisation épinglée de l’Enfant peut néanmoins redémarrer son propre runtime client OpenCodex après l’application de réglages Home modifiés. Si le Home interrompt son processus SSH local après un délai dépassé, une synchronisation distante déjà lancée peut continuer sur l’Enfant.

> **Enfant Remote Link :** sur un enfant `ocx` complet, `ocx sync` applique aussi les réglages Codex du Home et redémarre le runtime client s'il a démarré avant cette application ; si ce redémarrage échoue, l'ancien runtime continue de servir et la commande quitte avec un code non nul. Sur un hôte léger `ocx-child`, `ocx-child sync` démarre `ocx-child serve` s'il est absent, le relance lorsque `runtimeStartedAt < lastApplyAt` et publie la parité au mieux hors mode `stale` (un échec de relance arrête l'ancien relais et quitte avec un code non nul sans redémarrer Codex Desktop ni `app-server`, qu'il faut relancer séparément). Les champs de `ocx status --json` (ou `ocx-child status --json`) sur l'enfant et `ocx link status --json` sur le Home sont décrits dans [Remote Link apply parity](/reference/cli/lifecycle/#remote-link-apply-parity) (en anglais). Sur le Home, `ocx link check (--link-id <id> | --all)` lit la version installée et la voie de mise à jour de chaque enfant lancé par le Home via `ocx update --plan` par SSH (60 secondes par enfant, sans rien installer), et `ocx link status --json` ajoute un bloc `child` à chaque ligne ; voir [Child install, catalog and activity](/guides/remote-link/#child-install-catalog-and-activity) (en anglais). `ocx link sync`, `ocx link restart-codex --yes` et `ocx link update --yes` lancent sur ces enfants des tâches de synchronisation, de redémarrage de Codex et de mise à jour, et affichent le document `ocx.link.child-job/1` ; voir [Operating Children from the Home](/guides/remote-link/#operating-children-from-the-home) (en anglais).

Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/guides/remote-link.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ From the Home you can also sync a Home-initiated Child, restart Codex on it, and
- `ocx link restart-codex --link-id <id> --yes` syncs first and then restarts the Child's Codex app-servers, so a running Codex loads the current catalog. `--scope codex` also quits and relaunches the Codex desktop app, which needs a signed-in desktop session on the Child. `ocx link sync --link-id <id>` with `--restart-app-server-only` or `--restart-codex --yes` does the same. A restart ends the Codex turns running on that Child, so it names exactly one link. It needs 2.93.0 or later.
- `ocx link update (--link-id <id> | --all) --yes` brings the Child's OpenCodex to this Home's version, never to another one, through the Child's own updater. The Home first confirms that the Child still belongs to this link, then asks the Child for an update plan, applies it with a deadline counted on the Child's own clock, and syncs again after a successful, failed or rolled-back apply. An apply whose result is unknown is neither retried nor resynced; check that Child with `ocx link check`. npm and pnpm installs are updated through their Node launcher and Bun installs through Bun; `ocx link check` on an npm or pnpm Child therefore also runs `node --version` there, read-only. Updates need 2.97.0 or later on the Child; an older Child receives no update command and reports `owner-action` (`legacy-ocx`). Updates run one Child at a time and restart the Child's OpenCodex, which ends the requests the Home is relaying for it, so `--yes` is required.

The Home does not restart Codex on a Child while it is relaying a model request for that Child. If a request is already in flight when `ocx link restart-codex` starts, nothing is sent and the item is `busy` (`restart-skipped:link-active`). If one starts during the sync that precedes the restart, or the restart was requested with `ocx link sync`, the sync still runs and only the restart is skipped (`restart-skipped:link-active`). This protection is best-effort: a request that starts between that check and the restart can still be ended, so pause new requests on that Child when its turns must survive. A Child older than 2.69 is seen as busy only once its response starts for a non-streaming request, so a restart can still end such a request. Windows Children support `sync`; restarts and updates from the Home are refused there (`windows-restart`, `windows-apply`). `ocx-child` Children report restarts and updates as unsupported. One operation runs on a link at a time. Removing a link while an operation runs on it is refused with `409 link_operation_in_progress`; remove it once the operation has finished. While a link is being removed, a new operation that names only that link is refused with the same 409, and a job that names several links reports that link's item as `busy` (`link-operation-in-progress`) while its other links still run.
The Home does not restart Codex on a Child while it is relaying a model request for that Child. `ocx sync --restart-children` (or `--restart-children=codex --yes`) applies the same rule when a Home sync fans out, to every Child or to those named with `--child <linkId>`: each Child is synced, and only its restart is skipped (`restart-skipped:link-active`) while a relayed request is in flight. If a request is already in flight when `ocx link restart-codex` starts, nothing is sent and the item is `busy` (`restart-skipped:link-active`). If one starts during the sync that precedes the restart, or the restart was requested with `ocx link sync`, the sync still runs and only the restart is skipped (`restart-skipped:link-active`). This protection is best-effort: a request that starts between that check and the restart can still be ended, so pause new requests on that Child when its turns must survive. A Child older than 2.69 is seen as busy only once its response starts for a non-streaming request, so a restart can still end such a request. Windows Children support `sync`; restarts and updates from the Home are refused there (`windows-restart`, `windows-apply`). `ocx-child` Children report restarts and updates as unsupported. One operation runs on a link at a time. Removing a link while an operation runs on it is refused with `409 link_operation_in_progress`; remove it once the operation has finished. While a link is being removed, a new operation that names only that link is refused with the same 409, and a job that names several links reports that link's item as `busy` (`link-operation-in-progress`) while its other links still run.

The commands exit 0 when every Child succeeded or was already up to date (with `--no-wait`, 0 only means the job was accepted; it may still be running. The printed job carries a `jobId`; read the result with `GET /api/link/children/jobs/<jobId>` on the Home, using the admin token on loopback. Finished jobs stay readable for one hour, at most 32 of them, and are lost when the Home restarts, so read the result promptly), 6 when a Child needs attention (busy, offline, refused, an owner action, unsupported, a skipped restart, or an update that was kept but whose follow-up sync failed; run `ocx link sync` for that link), 1 on a failure or an unconfirmed result (check the Child again with `ocx link check` before retrying), 4 for an unknown link or a Home without these commands, and 5 when another operation is running on that link, the only link named was started from the Child, the Home has no links, or the command ran on a Child; the error message names which. The CLI needs a Home bound to loopback; on any other Home these commands are refused (exit 1), and the dashboard has no controls for them.

Expand Down
Loading
Loading