I0904 — The listen address is one fact with two projections
Make the deployment bind an externally reachable interface on the port the canonical object declares, without changing the loopback default that local use depends on, and without the port existing as a literal in more than one place.
BLOCKED wave 2 · p0 · implementation profile · parallel safe
Blocked. This issue cannot start until I0902 is done. The status is derived from that, not declared.
Objective
Make the deployment bind an externally reachable interface on the port the canonical object declares, without changing the loopback default that local use depends on, and without the port existing as a literal in more than one place.
Why
A server bound to 127.0.0.1 inside a Machine is unreachable, and the usual repair is to hardcode 0.0.0.0:8080 in three files. The port is a fact of the deployment object; the container, the provider configuration and the process must all read the same one.
Current state
bind() defaults to loopback and warns when the bound address is not loopback, because a non-loopback bind exposes this repository's layer to every host that can reach the interface. The default port is a constant in cli.rs.
Desired state
Local invocation is unchanged. A hosted process binds the declared address deliberately, the warning stays for the accidental case, and the port appears once as canonical data.
Scope
- apps/majordomus-cli/src/http/server.rs
- apps/majordomus-cli/src/commands/serve.rs
- apps/majordomus-cli/src/cli.rs
Out of scope
- Graceful shutdown, which is I0906
- Any change to what the server serves
Dependencies
What waits on this
- I0906BLOCKED Termination is graceful and proved against the real container
- I0909BLOCKED The production image is a generated projection of the build specification
Acceptance criteria
- The deployment port is stated once in the canonical object and consumed by the process, the container projection and the provider configuration
- The local default remains loopback and the existing warning still fires for an unintended non-loopback bind
- A hosted bind is expressed as intent rather than by suppressing the warning
- A test proves the hosted configuration binds a reachable address and the local default does not
Validation
- cargo test --workspace --all-features
- bash test/run.sh
Evidence required
- single_port_source
- hosted_bind
- local_default_unchanged
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Risk
Weakening the loopback default for everyone would expose local repositories on shared networks. The hosted path must be an explicit mode, not a lowered default.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I0904.yaml. Read it back with majordomus plan show I0904.