Skip to content

Serve roadmap static site on srv1 (stateless-frontend milestone A) - #6128

Merged
briansrls merged 10 commits into
mainfrom
session/wise-newt-294
Jul 2, 2026
Merged

briansrls merged 10 commits into
mainfrom
session/wise-newt-294

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jul 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the first non-CI fabric consumer: a stateless roadmap HTTP site deployed on srv1 via the existing live_deploy path (target-host preflight + gated apply unchanged).

  • Models SiteArtifact, WebServiceShape, DomainRoute, and StaticSiteAllocation in dsl/gunbc/roadmap_static_site.dag
  • Serves emitted authority content at /ROADMAP.md, /target/roadmap-dispatch.json, and /healthz (JSON with artifact digests)
  • Keeps the HTML index at / (ready/upcoming/done) and /roadmap
  • Consolidates roadmap_dispatch_file_content() into roadmap_spawner (single authority; tools/roadmap_dispatch now imports it)
  • Post-deploy read-back in the apply script: healthz 200, fnv1a digest match for both artifacts, dispatch JSON parse, and a roadmap-site-receipt line (host · URL · digests · model hash · timestamp)

Test plan

  • target/release/gunbc run --source-root dsl --source-root src/v2 --entry dsl/test/claim/roadmap_static_site_witness_test.dag --function roadmap_static_site_witnesses --claim-run → true
  • target/release/gunbc run --source-root dsl --source-root src/v2 --entry dsl/test/claim/roadmap_dashboard_emit_witness_test.dag --function roadmap_dashboard_emit_witnesses --claim-run → true
  • target/release/gunbc run --source-root dsl --source-root src/v2 --entry dsl/test/claim/live_deploy/emit_test.dag --function live_deploy_emit_holds --claim-run → true
  • CI floor (auto on ready)

@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review July 2, 2026 04:20
@gunbai-bot gunbai-bot Bot changed the title roadmap-frontend-deploy (2-stateless-frontend milestone A) — serve ROADMAP.md + target/roadmap-dispatch.json (+ optional HTML index of ready/upcoming/done) as the first non-CI fabric consumer on srv1. Acceptance: independent read-back (HTTP 200, digest==committed source, JSON parses, healthz); deplo Serve roadmap static site on srv1 (stateless-frontend milestone A) Jul 2, 2026
briansrls and others added 2 commits July 2, 2026 04:31
…pe units.

Add dissolution trigger + Scaffold bind to live_deploy_emit_shell_dissolution_trigger,
roster entry for roadmap_static_site.dag, and std.measure carriers (CpuMillicoreBudget,
Mebibyte, Port) replacing bare Int unit field names.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Addressed both REQUEST_CHANGES findings in 15bf45e follow-up:

1. Readback shell scaffold discipline — Valid. Added roadmap_site_readback_script_scaffold (Scaffold → live_deploy_emit_shell_dissolution_trigger), roadmap_site_readback_shell_dissolution_trigger with roster retirement language, and dsl/gunbc/roadmap_static_site.dag to medium_structure_exception_roster. Witness witness_readback_shell_marked_scaffold locks the marker.

2. WebServiceShape unit modeling — Valid. Replaced cpu_millicores: Int / memory_mib: Int with CpuMillicoreBudget = Measure<Count, Milli, Nat> and Mebibyte = Measure<Memory, Mebi, Nat>; port now uses branded Port.

Local witnesses green: roadmap_static_site_witnesses, live_deploy_emit_holds, roadmap_dashboard_emit_witnesses.

— sent from wise-newt-294

Move parallel Measure aliases out of roadmap_static_site into std/measure.dag
with constructor roundtrip witnesses; WebServiceShape imports the std authority.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Verified blocking finding on current HEAD — valid. Mebibyte and CpuMillicoreBudget were parallel aliases in roadmap_static_site.dag.

Fix (931de62 follow-up): Added Mebibyte + mebibyte/mebibyte_count and Millicore + millicore/millicore_count to std/measure.dag (alongside existing Kibibyte/Gibibyte). WebServiceShape now imports and consumes those std carriers; local type aliases removed. Roundtrip locked in measure_magnitude_carrier_test.

Non-blocking note on readback shell: Acknowledged — the marked-shell surface grew but remains honestly scaffolded (roadmap_site_readback_shell_dissolution_trigger → live_deploy_emit_shell_dissolution_trigger, roster entry at medium_structure_containment.dag:153); dissolution rides #5828 bash-emit like sibling deploy modules.

— sent from wise-newt-294

@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Verified blocking finding on current HEAD (df40a89) — valid.

Root cause: roadmap_site_healthz_body() nested concats closed artifacts and the outer object inside the inner literal ("}}"), then the outer concat appended another "}", yielding …}}} — invalid JSON for ApplicationJsonUtf8.

Fix:

  1. Refactored body construction: build artifacts as {path:digest,…} first, then wrap {"status", "service", "artifacts":…} with a single closing brace.
  2. Hardened witnesses: witness_healthz_body_json_well_formed (starts {, ends }}, not }}}) + perturb control witness_healthz_body_extra_brace_perturb_red; folded into witness_healthz_route_json_ok.
  3. Readback script: /healthz now uses JSON.parse (same fail-closed pattern as dispatch), not grep '"status":"ok"'.

Local witnesses green: roadmap_static_site_witnesses, live_deploy_emit_holds.

— sent from wise-newt-294

@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Verified APPROVE on HEAD df40a89 — findings match current code; no blocking items.

Soft note (site_artifact_digest → NonEmptyStr cast): Acknowledged and intentional for milestone A. Both served artifacts (expected_roadmap_md(), roadmap_dispatch_file_content()) are authority-backed non-empty strings today; the cast makes empty-body a compile/type-boundary error at digest time rather than a silent bogus hash. If a future artifact can legitimately be empty, the right move is a named variant on SiteArtifact (e.g. optional body + absent digest) rather than weakening content_hash_atom's NonEmptyStr precondition here — out of scope for this PR.

— sent from wise-newt-294

@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Verified APPROVE (composer-2.5) on HEAD df40a89 — no findings; assessment matches current code.

Scope checks: roadmap_static_site.dag authority + dashboard route-table splice + live-deploy readback integration; roadmap_dispatch_file_content single authority; std.measure Mebibyte/Millicore consumed by WebServiceShape; scaffold bind + dissolve-on trigger + medium_structure_exception_roster entry; witnesses include healthz JSON shape + RED perturb + readback gates. No new hand-Rust.

— sent from wise-newt-294

briansrls and others added 2 commits July 2, 2026 06:12
…parse.

Retract leg (option B): live_deploy retract owns the single gunbc-roadmap server process (rm server.js, disable unit, tailscale reset); new witnesses tie static-site routes to the dashboard route table and prove retract removes that process without a readback shell. Healthz: add Node JSON.parse witness via roadmap_site_healthz_validate plus wet ProcessExit discriminant.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Operator REQUEST_CHANGES addressed in fa7bcd0:

1. Retract leg (option B) — live_deploy retract owns the entire gunbc-roadmap server process (rm /opt/gunbc/server.js, systemctl disable --now gunbc-roadmap.service, tailscale serve reset). Static-site routes are only served from that single emitted createServer; retract removes the process, so routes/artifacts are gone without a separate per-route retract script. Witnesses lock this: retract script targets the owned server + no readback shell on retract; every roadmap_site_text_static_routes() row must appear in roadmap_dashboard_served_static_route_table() (body/path/content-type match); authority path list locked to [/ROADMAP.md, /target/roadmap-dispatch.json, /healthz] so new routes can't silently escape table coverage.

2. Healthz JSON.parse — roadmap_site_healthz_validate.dag writes body to scratch and runs Node JSON.parse (witness_healthz_body_json_parses); string-shape checks remain as hermetic shadow + RED perturb. Wet roadmap_site_healthz_json_parse_witness (ProcessExit) discriminates invalid trailing-brace body.

— sent from wise-newt-294

JSON.parse via Filesystem.Write lives only in roadmap_site_healthz_json_parse_witness (ProcessExit, outside floor test-fn discovery). Hermetic *_test.dag aggregate stays pure string-shape + RED perturb.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Verified APPROVE (composer-2.5) on HEAD 10a934bfad — no findings; assessment matches current code.

Scope checks: roadmap_static_site.dag single authority; roadmap_dispatch_file_content dedup via roadmap_spawner; std.measure Millicore/Mebibyte; scaffold bind + dissolve-on + roster entry; witnesses lock routes/digests/retract/table coverage; hermetic healthz in roadmap_static_site_witness_test.dag, wet JSON.parse in roadmap_site_healthz_json_parse_witness.dag (ci_yaml_parse pattern). Operator review items closed on prior push.

— sent from wise-newt-294

@gunbai-bot

gunbai-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Verified APPROVE (opus-4-7) on HEAD 10a934bfad — no blocking findings.

fnv1a readback (non-blocking): Acknowledged. Milestone A readback compares curl body → client-side fnv1a against emit-time ContentHash from the same site_artifact_digest authority; content-type/status are the HTTP-layer cross-checks. One-source at this tier is intentional — full independent digest transport is a dissolve-on item with live_deploy_emit_shell_dissolution_trigger.

Shared /tmp/gunbc_roadmap_site_healthz.json (non-blocking): Acknowledged hygiene nit. Path is only touched by the wet ProcessExit witness (roadmap_site_healthz_json_parse_witness.dag), outside hermetic floor auto-enroll; sequential ok/perturbed calls in one witness run. If concurrent wet runs become a thing, we'll PID-suffix the scratch path.

— sent from wise-newt-294

@briansrls
briansrls merged commit 4f902de into main Jul 2, 2026
1 of 2 checks passed
@briansrls
briansrls deleted the session/wise-newt-294 branch July 2, 2026 06:56
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.

1 participant