Skip to content

fix: web preview reachable through the host port forward - #198

Merged
kaaloo merged 12 commits into
mainfrom
fix/p153-preview-reachability
Oct 19, 2026
Merged

kaaloo merged 12 commits into
mainfrom
fix/p153-preview-reachability

Conversation

@kaaloo

@kaaloo kaaloo commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Problème

Dans la VM, l'agent lance les serveurs de développement sur 127.0.0.1 : le port forwardé depuis l'hôte ne répond jamais, la prévisualisation web est inaccessible. En plus, quand l'utilisateur demande un bind 0.0.0.0, l'agent le refuse en invoquant une fausse exposition réseau — alors que côté hôte le forward n'écoute que sur 127.0.0.1 et n'expose rien sur le réseau local.

Closes #153

Changements

Instructions gérées toujours présentes (fix(skills)) :

  • la zone gérée de AGENTS.md porte désormais un texte permanent qui énonce les faits : bind 0.0.0.0 requis dans l'invité pour être joignable via le forward, forward hôte limité à 127.0.0.1, une requête lancée depuis l'invité ne prouve rien, just-code check vérifie depuis l'hôte ;
  • la zone existe même sans skill épinglé ; un passage en skills host-local la retire entièrement ;
  • le préflight de démarrage local-only ne bloque plus sur la seule présence de la zone : seules des épingles de skills résiduelles bloquent ;
  • init possède toujours la zone, ce qui rend un import Albert Code sans skills idempotent (le second import re-rend une zone identique au lieu de signaler une réparation).

Sonde de ports dans check (feat(check)) :

  • just-code check interroge chaque port explicitement configuré par le projet, depuis l'hôte, dans les deux modes d'isolation ;
  • toute réponse HTTP = joignable ; aucune réponse = message avec le correctif côté invité (bind 0.0.0.0), sans le faux avertissement d'exposition réseau ;
  • la sonde est informative : elle ne fait jamais échouer check, et s'exécute même si le backend OpenCode est en panne ;
  • la plage implicite 3000-3010 n'est pas sondée : ce sont des défauts, pas des choix de projet.

Tests

  • internal/justcode : zone permanente sans épingles (init vide, clearing, import idempotent), préflight sensible aux épingles réelles, sonde joignable / non joignable / plage legacy silencieuse ;
  • suite complète go test ./... verte.

👾 Generated with Letta Code

kaaloo and others added 2 commits October 16, 2026 16:06
…oject

The managed AGENTS.md zone now carries standing web-preview guidance in
every versioned project, even with no pinned skills: a dev server must
bind 0.0.0.0 inside the guest to be reachable through the host port
forward, and the host side of the forward binds 127.0.0.1 only, so the
guest-side bind exposes nothing on the network. Local-only selections
strip the zone entirely instead of leaving a pin-less remnant.

The local-only startup preflight now blocks only when the guest zone
still lists pinned skills; the standing guidance alone is not evidence
that versioned skills survived the switch. Init always owns the zone,
which also makes a skills-less Albert Code import idempotent: the
second import re-renders an identical zone instead of reporting a
repair.

Part of #153.

👾 Generated with [Letta Code](https://letta.com)

Model: lc-qwencloud/deepseek-v4.1-flash

Co-Authored-By: Letta Code <noreply@letta.com>
`just-code check` now probes every port the project explicitly mapped,
from the host side of the forward, in both isolation modes. Any HTTP
answer counts as reachable; no answer prints the guest-side fix (bind
0.0.0.0 inside the guest) instead of the wrong LAN-exposure warning the
agent used to give. The probe is print-only and runs even when the
OpenCode health endpoint is down, because preview reachability does not
depend on backend health. The legacy implicit 3000-3010 range stays
unprobed: those are defaults, not project choices.

Part of #153.

👾 Generated with [Letta Code](https://letta.com)

Model: lc-qwencloud/deepseek-v4.1-flash

Co-Authored-By: Letta Code <noreply@letta.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T09:54:41.683338Z 56cae38 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

The managed AGENTS.md zone now exists even without selected skills and
carries the guest-side 0.0.0.0 binding guidance; the local-only refusal
now depends on leftover skill pins, not the zone itself. `just-code
check` reports reachability of explicitly configured ports in both
isolation modes.

Part of #153.

👾 Generated with [Letta Code](https://letta.com)

Model: lc-qwencloud/deepseek-v4.1-flash

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — head 6e8fe67 adds the docs companion commit on top of 9357fc3 (standing managed zone + check port probes). Please review the final head.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e8fe67eeb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/dispatcher.go Outdated
Comment thread internal/justcode/initwizard.go Outdated
Comment thread internal/justcode/dispatcher.go
Address the Codex review findings on the standing managed zone and the
check port probes:

- The standing web-preview guidance describes the Microsandbox host
  port forward. On tart and agent-vm it gave agents an ineffective
  verification command and an incorrect exposure assurance, so
  MergeManagedInstructions now renders it for Microsandbox only; other
  runtimes get the pinned-skill list alone and no managed section at
  all without pins.
- The configured-port probes in `check` hit 127.0.0.1 on the host, which
  only means something on Microsandbox: tart connects to the VM IP
  directly and agent-vm forwards dynamically, so a probe there could
  report an unrelated local service as a preview forward. The probe now
  runs only on Microsandbox.
- The probe client no longer follows redirects: a redirect answer is
  reachability, while following it could send a diagnostic request
  outside loopback or misreport a dead redirect target as a dead
  forward.

Docs updated to state the Microsandbox scope of both behaviors.

👾 Generated with [Letta Code](https://letta.com)

Model: lc-qwencloud/deepseek-v4.1-flash

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — head d238885 addresses the three findings: standing managed guidance and configured-port probes are now scoped to the Microsandbox runtime, and the probe client no longer follows redirects. Please review the new head.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d23888513a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/skills.go Outdated
Comment thread internal/justcode/initwizard.go Outdated
managedInstructionRuntime parsed the stored manifest runtime with the
host-OS-gated parseRuntimeName, so a tart or agent-vm manifest read on
Windows rendered as Microsandbox and skill update, rollback, and
recovery rewrote its managed section with the port-forward guidance the
scoping excludes. Stored names now resolve without host compatibility
checks; those checks belong to runtime execution, not instruction
rendering.

The wizard validated AGENTS.md even for a pin-less tart or agent-vm init
whose merge changes nothing, so a symlinked AGENTS.md blocked an init
that touches nothing. The plan now claims and validates AGENTS.md only
when pins, the Microsandbox standing guidance, a local-only strip, or a
stale managed zone require changing it.

Also platform-gate the two tart tests that failed the Windows CI legs:
the dispatcher test points the platform-gated sweep at darwin to keep
the tart path under test everywhere, and the wizard test skips where
tart is not selectable, matching the existing mounting test.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head 18c559d addresses both findings (host-independent stored runtime parsing; AGENTS.md claimed only when the plan can change it) and platform-gates the two tart tests that failed the Windows CI legs; please re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 18c559dbd0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/dispatcher.go Outdated
Port mappings changed in the manifest only apply when the Microsandbox is
recreated, so probing the desired values could report an unrelated
service on a newly configured host port as a reachable preview, stay
silent about a removed mapping the sandbox still forwards, and diagnose
a missing guest bind for a forward that does not exist yet.

The probe now reads the running instance persisted network port list
(the same authority ServerPortForwarded uses) and reports three states:
mappings both configured and applied are probed as before, configured
mappings the sandbox does not forward are reported as pending recreate
instead of being probed, and applied mappings no longer configured are
reported as still forwarded until recreation. The OpenCode backend
server forward is excluded: ValidatePortMappings keeps DefaultPort out
of user mappings entirely. When the applied list cannot be read the
probes are skipped rather than falling back to the manifest view.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head d61f498 addresses the applied-mappings finding: probes now use the running instance's persisted port list, pending mappings are reported instead of probed, stale forwards are reported as still active, and unreadable applied state skips the probes. Please re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d61f498b0d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/dispatcher.go Outdated
Comment thread internal/justcode/initwizard.go Outdated
Two review findings on the previous round, both edge states of the new
conditional behavior:

`ports remove` of the final entry persists portsConfigured with an empty
list, and the probe returned before reading the applied mappings, so the
sandbox kept forwarding the removed mapping until recreate while check
printed nothing. The early return now keys on portsConfigured alone: an
explicitly emptied mapping list still counts as configured, and the
stale-forward report covers it.

A local-only init on a pin-less tart or agent-vm project forced the
AGENTS.md claim even when the file has no managed zone, so a symlinked
AGENTS.md still blocked an init whose strip would change nothing. The
local-only flag no longer forces the claim by itself: the zone-presence
check decides, so a zone-less file is left untouched while a stale zone
is still stripped.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head a365020 addresses both findings: the probe now runs for an explicitly emptied mapping list and reports the stale forward, and the local-only flag no longer forces the AGENTS.md claim when no zone exists. Please re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a365020c6a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/initwizard.go Outdated
A local-only plan never merges managed instructions, so pins and the
Microsandbox runtime must not force the AGENTS.md claim on their own:
with no managed zone the strip changes nothing, and a symlinked AGENTS.md
was still rejected for a local-only Microsandbox init or one carrying a
local skill selection. The claim predicate now requires a non-local-only
plan for those forcing conditions; local-only plans claim only when the
zone-presence check finds a stale managed zone to strip.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head f5d0655: local-only plans now base AGENTS.md ownership solely on actual zone presence (pins and the Microsandbox runtime no longer force the claim for them). Please re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f5d06556a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/initwizard.go Outdated
…ning

A plan leaves AGENTS.md unclaimed when it would change nothing, so a
managed zone appearing between the interactive Plan and Apply steps was
never re-read: the manifest committed as local-only while the newly
added versioned pins survived in AGENTS.md. Apply now rechecks the
unclaimed path and, when a zone has appeared, claims it and strips or
refreshes the zone on current content — the same drift adaptation the
claimed path already performs. A non-regular AGENTS.md holding the
appeared zone aborts the apply rather than writing through it.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head 51665d2: Apply rechecks an unclaimed AGENTS.md and strips or refreshes a zone that appeared after planning, refusing a non-regular file instead of writing through it. Please re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51665d259e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/initwizard.go Outdated
Both zone-presence checks read AGENTS.md before inspecting its type, so
a FIFO or a symlink to an unbounded device such as /dev/zero could block
indefinitely or exhaust memory instead of being refused. The new
managedZoneAt helper resolves the entry on the real filesystem first —
following symlinks so a link to a regular zone-less file stays untouched
— and reads only a regular target. A missing or dangling path still
reads as no zone; a non-regular or unreadable entry fails closed into
the existing refusal. Covered for both the planning probe and the
apply-time recheck by unix-only tests.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head f8aa563: zone-presence checks resolve the AGENTS.md entry type before reading, refusing FIFOs and symlinks to unbounded devices. Please re-review.

@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — re-requesting for head f8aa563: the previous run has been in "running" state for over an hour with no findings posted. Please review the current head.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f8aa5630dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/skills.go Outdated
Comment thread internal/justcode/dispatcher.go
managedZoneAt validated one filesystem object and then re-opened the
path, so an entry swapped in between the Stat and the read could still
be a FIFO or a symlink to /dev/zero and block or balloon the probe. It
now opens the path once with O_NONBLOCK, inspects the opened handle, and
reads only a bounded regular file; a larger file fails closed into a
claim instead of being decided from a truncated read.

Port probing ran one 2s-timeout probe per mapping with no total bound,
so a manifest with many dead forwards could stall just-code check for
minutes. The probe loop now runs under a shared 10s budget: each probe
keeps its own shorter timeout, and mappings beyond the budget are
reported as not probed rather than silently skipped.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head e85152c: managedZoneAt opens once with O_NONBLOCK and reads a bounded regular file from the opened handle; port probing runs under a shared 10s budget with not-probed reporting. Please re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e85152c5e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/justcode/skills.go Outdated
The oversize fail-closed from the previous round re-broke the
zone-less-symlink property (a symlink to a large regular file was
refused instead of left untouched) and only moved the full read one
step later, into Plan and Apply. The probe now scans the opened file
line by line for the begin or end marker — either marker claims the
file, matching hasManagedSkillZone, where a balanced pair is a zone and
any other combination fails closed — in bounded chunks. A line longer
than the buffer cannot be a marker and is skipped whole, so file size
no longer bounds memory, and an oversized zone-less file is not claimed
at all.

👾 Generated with [Letta Code](https://letta.com)

Model: letta/auto

Co-Authored-By: Letta Code <noreply@letta.com>
@kaaloo

kaaloo commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@codex review — new head 56cae38: the probe scans for zone markers in bounded memory instead of failing closed on oversize, so oversized zone-less files (and symlinks to them) are not claimed. Please re-review.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 56cae38b45

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@kaaloo
kaaloo merged commit 1ff037e into main Oct 19, 2026
10 checks passed
@kaaloo
kaaloo deleted the fix/p153-preview-reachability branch October 19, 2026 10:21
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.

Preview : serveur de l'agent injoignable depuis l'hôte (écoute 127.0.0.1 dans l'invité)

1 participant