Record the verified frontend and ingress preparation commit in the lifecycle board while preserving Stage 2 as TODO.
Constraint: Stage completion is milestone-based and cannot be inferred from visible files or a running demo.
Confidence: high
Scope-risk: narrow
Directive: Keep S2-C open until Worker recovery and the complete product topology are verified.
Tested: make verify; staged Secret scan; Markdown links and diff checks.
Not-tested: Rotated-key Bailian live smoke remains pending.
Expose the verified synthetic retrieval path through a typed React client and a non-root Nginx edge while keeping database credentials and data-network reachability out of the browser tier. A fixed-origin gateway preserves request boundaries and now closes upstream streams even when downstream disconnects before body iteration. The deployment ADR and runbooks record the four-network topology and its accepted Web edge-egress risk.
Constraint: The previously exposed Bailian key must be revoked and no live provider credential may enter Git, images, logs, or the browser.
Rejected: Connect Web directly to the data network | expands lateral reach to PostgreSQL.
Rejected: Publish the database-aware API on the edge network | gives a credential-bearing process a public default route.
Rejected: Buffer streaming responses in either proxy | prevents incremental chat delivery in the future.
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Do not mark Stage 1 or Stage 2 complete until the rotated-key live smoke and remaining stage gates pass.
Tested: make verify; 65 backend tests; 14 frontend tests; Docker image build; container health and isolation probes; real HTTP demo/status/search/docs/OpenAPI checks.
Not-tested: Live Bailian models, real document ingestion, business chat SSE generation, and final browser screenshot automation because the browser skill runtime was unavailable.
The lifecycle tracker now points to the pushed API and gateway implementation while preserving Stage 1 as in progress until live provider evidence exists.
Constraint: Live model validation still requires a newly rotated Bailian key
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep S1-B open until all three live probes and real-mode synthetic seed pass
Tested: make verify; 63 pytest tests; strict mypy; Ruff; Secret scan; Compose config
Not-tested: Live Bailian model calls
The backend can now be inspected through a loopback-only gateway while the database-aware API remains on the internal data network. A governed synthetic demo proves readiness, pgvector retrieval, reranking, and citation output through real HTTP without invoking cloud models.
Constraint: The previously exposed Bailian key is compromised and cannot be used for live validation
Constraint: The API must be locally reachable while retaining no internet egress
Rejected: Attach the API directly to the ingress network | a real socket test proved that configuration still had egress
Rejected: Publish a port from the internal-only network | Docker Desktop did not expose the host port
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep model and database credentials out of the gateway; do not relax the fixed demo identity/profile filters
Tested: make verify; 63 pytest tests; strict mypy; Ruff; Secret scan; Compose config; three backend image builds; API/DB/gateway healthy; migration exit 0; Swagger browser check; live/ready/meta/status/search HTTP; 20/20/20 index; API egress ENETUNREACH; empty gateway mounts and business environment
Not-tested: Live Bailian calls require a newly rotated key; full generated-answer flow and React UI are not implemented
The lifecycle tracker now records the pushed offline Stage 1 slices while leaving the live provider node open. This prevents mock and local database success from being mistaken for full Bailian validation.
Constraint: A newly rotated Bailian key is required before live smoke can be accepted
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Do not mark Stage 1 DONE until all three live model probes and real-mode synthetic seed pass
Tested: make verify; Markdown link check; secret scan; 41 pytest tests; strict mypy; Ruff; Compose config
Not-tested: Live Bailian provider calls
The Stage 1 foundation now proves provider contracts with mocks and validates PostgreSQL/pgvector ingestion, approval binding, retrieval, reranking, and idempotency using only synthetic data. Live Bailian validation remains gated on rotating the exposed key.
Constraint: The key shown in chat is compromised and cannot be used or committed
Rejected: Mark Stage 1 complete from mock and offline results | real three-model smoke is still required
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Do not enable real-data ingestion until Stage 3 cloud approval and outbound manifest controls are enforced end to end
Tested: make verify; 41 pytest tests; strict mypy; Ruff; Compose config; pinned image build; empty-volume migration; role denial; two idempotent 20-vector seeds; database restart persistence
Not-tested: Live Bailian calls require a newly rotated key; React product UI is not implemented