From 68298d81b3c12e3d1b439967019375d334029474 Mon Sep 17 00:00:00 2001 From: cloudinit-bot Date: Tue, 18 Aug 2026 11:54:06 +0000 Subject: [PATCH 1/9] =?UTF-8?q?docs(init):=20validate=20specification=20?= =?UTF-8?q?=E2=80=94=20v0.6=20Nomad=20Web=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ---ci--- project: oy phase: 0 milestone: v0.6 status: specify ---/ci--- --- .ciagent/CHECKPOINT.json | 17 ++++++-------- .ciagent/config.json | 4 ++-- .ciagent/oy/PROJECT.md | 48 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/.ciagent/CHECKPOINT.json b/.ciagent/CHECKPOINT.json index b04b690..63a6d56 100644 --- a/.ciagent/CHECKPOINT.json +++ b/.ciagent/CHECKPOINT.json @@ -1,15 +1,12 @@ { - "phase": 8, - "stage": "complete", - "milestone": "v0.5", + "phase": 0, + "stage": "specify", + "milestone": "v0.6", "milestone_type": "feature", - "tag_base": "v0.4.x", - "phase_role": "final", + "tag_base": "v0.5.x", + "phase_role": "pre_execution", "project": "oy", "attempts": 0, - "updated_at": "2026-08-18T02:00:00Z", - "milestone_complete": true, - "milestone_release_tag": "v0.4.8", - "release_id": 763, - "requirements_covered": ["REQ-033", "REQ-034", "REQ-035", "REQ-036", "REQ-037", "REQ-038", "REQ-039"] + "updated_at": "2026-08-18T11:30:00Z", + "milestone_complete": false } \ No newline at end of file diff --git a/.ciagent/config.json b/.ciagent/config.json index 4c406e6..52f310c 100644 --- a/.ciagent/config.json +++ b/.ciagent/config.json @@ -6,9 +6,9 @@ } ], "active_project": "oy", - "milestone": "v0.5", + "milestone": "v0.6", "milestone_type": "feature", - "tag_base": "v0.4.x", + "tag_base": "v0.5.x", "autonomy": { "level": "full", "escalation_hooks": ["deploy", "delete_data", "merge_to_main"], diff --git a/.ciagent/oy/PROJECT.md b/.ciagent/oy/PROJECT.md index f8f67e9..2494fa0 100644 --- a/.ciagent/oy/PROJECT.md +++ b/.ciagent/oy/PROJECT.md @@ -61,6 +61,54 @@ OpenYield (OY) is a durable, anti-greed, jurisdiction-light financial layer — - D-009: Rebased history to fix v1.0 → v0.1 in ---ci--- blocks ## Milestone +v0.6 — Nomad Web UI (in progress; feature type; tags run on the v0.5.x patch line) + +### v0.6 Scope (Nomad Web UI MVP — generated test data, no real chain) + +v0.6 is the project's first UI milestone. It delivers a working prototype Web +UI where a person can sign up to be a Nomad (create a Reach + open a Stash) +and exercise basic functionality around the (Reach, Stash) components, plus +Window authorization, Standing progress, and Bloom accrual views. All data is +generated as test fixtures — there is no real blockchain interaction, no live +chain launch, no real bearer transports (D-020 continues to govern network +deployment). The UI is a greenfield Go `html/template` + HTMX layer served by a +Go mock HTTP server that instantiates the real `x/*/types` structs (Reach, +Stash, Window, FreeholderSignals, BloomRecord) populated from in-memory +fixtures. No keeper, no Cosmos runtime, no `app.go` (none exists in the repo). + +This milestone is the prerequisite for real-world MVP testing: it makes the +Nomad path visible and exercisable in a browser. Wiring the UI to a real `oyd` +daemon (once one exists) is deferred to v0.7+ (no `app.go`, `cmd/`, or `main.go` +exists in the repo today). + +- **REQ-040** Nomad Reach signup Web UI — Go HTTP mock server (`web/`) + "Create a Reach" form + Reach list/detail; grounds the UI in `x/identity/types.Reach`. "Sign up" maps to "Create a Reach" (the word "account" is banned per REQ-012). +- **REQ-041** Stash dashboard Web UI — balance in Grain + Bread-scale conversion (using `x/bread/types.BreadScaleAll()`) + 90-day maturity progress bar (`x/stash/types.StashActivity.IsMature`). +- **REQ-042** Window authorization Web UI — form to open a Window (scope + duration + rate-limit), lifecycle view (Open→Active→Revoked/Expired via `x/window/types.Window.Activate/Revoke/Expire`), audit log. +- **REQ-043** Standing + Freeholder signals progress Web UI — computed from mock `Rating`/`Vouch`/`Slash` records using the locked constants + `GetStandingBucket`/`ComputeDiversityBonus`/`GetVoucherWeight`; 4-signal progress (`FreeholderSignals.IsFreeholderEligible`). +- **REQ-044** Bloom accrual Web UI — per-Stash `BloomRecord` view (`AccruedGrain`, `RateBasisPoints`), computed from mock data; shows the 4.5% target rate. +- **REQ-045** Extend REQ-012 lexicon firewall to scan `web/templates/**` + `web/static/**` (new `lexicon_meta_web_test.go`). Firewall-first: lands in P1 before content. + +### Milestone Type +Feature (all execution phases are `feat` except REQ-045 which is `test`). Phase 0 → `v0.5.0`; execution phases `v0.5.1..v0.5.5`; final phase patch `v0.5.6` IS the v0.6 milestone release. No separate minor tag. The final-phase audit enforces the feature purity gate (no breaking schema changes; G-003 production firewall intact; G-006 go.mod unchanged unless a runtime dep is GRILL-approved — HTMX is a vendored static asset, not a Go dep). + +### Out of Scope (v0.6) +- Real blockchain interaction / mainnet / IBC / real bearer transports (D-020 continues) +- A real `oyd` daemon / `app.go` / `cmd/oyd` (no chain runtime exists; deferred to v0.7+) +- Real Anchors onboarding / Hub API B2B / real custody (simtest/mock only) +- Authentication / sessions / real key management (mock; a Reach is created by form submission, stored in-memory) +- Persistence (mock store is in-memory; resets on restart) +- i18n / multi-language UI +- Real Standing oracle / real Bloom accrual engine (computed from fixtures using locked constants) +- The 5 P1+ mainnet-readiness items deferred from v0.5 (governance spam deposit, CLOB front-running, real IBC simtest, CLOB perf, emitMatchEventHook testability) — those are v0.7+ mainnet-readiness, not UI work + +### Prior Milestones +- v0.1 — OpenYield Foundation Init (COMPLETE; pre-MVP foundation skeleton; released as v0.0.9) +- v0.2 — The Mesh (COMPLETE; skeleton + tests; released as v0.1.5) +- v0.3 — Bearers & Documentation (COMPLETE; feature; released as v0.2.6) +- v0.4 — Refinement (COMPLETE; NFR; released as v0.3.4) +- v0.5 — Bearers Runtime (COMPLETE; feature; released as v0.4.8) + +## Prior Milestone v0.5 — Bearers Runtime (complete; feature type; tags ran on the v0.4.x patch line) ### v0.5 Scope (Live-runtime promotions of the v0.3 Bearers skeletons) From 4876c49aa0cb22c558479165bbbd3aff089565fd Mon Sep 17 00:00:00 2001 From: cloudinit-bot Date: Tue, 18 Aug 2026 11:54:59 +0000 Subject: [PATCH 2/9] =?UTF-8?q?docs(P00):=20clarify=20=E2=80=94=20v0.6=20d?= =?UTF-8?q?ecisions=20D-066..D-073?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-validated stack: Go html/template + HTMX, Go mock API server, new web/ dir, all 5 screens. Lexicon firewall extended to web/. Bread-scale source of truth = x/bread/types code constants. ---ci--- project: oy phase: 0 milestone: v0.6 status: clarify ---/ci--- --- .ciagent/CHECKPOINT.json | 4 ++-- .ciagent/oy/PROJECT.md | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.ciagent/CHECKPOINT.json b/.ciagent/CHECKPOINT.json index 63a6d56..c73cb5f 100644 --- a/.ciagent/CHECKPOINT.json +++ b/.ciagent/CHECKPOINT.json @@ -1,12 +1,12 @@ { "phase": 0, - "stage": "specify", + "stage": "clarify", "milestone": "v0.6", "milestone_type": "feature", "tag_base": "v0.5.x", "phase_role": "pre_execution", "project": "oy", "attempts": 0, - "updated_at": "2026-08-18T11:30:00Z", + "updated_at": "2026-08-18T11:35:00Z", "milestone_complete": false } \ No newline at end of file diff --git a/.ciagent/oy/PROJECT.md b/.ciagent/oy/PROJECT.md index 2494fa0..b040c9b 100644 --- a/.ciagent/oy/PROJECT.md +++ b/.ciagent/oy/PROJECT.md @@ -291,4 +291,19 @@ Auto-decided defaults logged per clarify workflow Step 4 (full autonomy → acce | D-058 | **Hub custody model = key-share abstraction (MPC-via-interface, not a concrete HSM/MPC vendor).** `x/hub` custody handlers expose a `CustodyKeyring` interface with `Sign`/`Derive` methods; v0.5 ships an in-memory test-only implementation. Real MPC/HSM backing is deferred (operational, Year 3+). This keeps v0.5 dep-neutral w.r.t. custody vendors while landing the handler surface. | Custody key management is operational, not protocol-level. An interface + test impl lets runtime handlers be exercised in simtest without committing to a vendor. GRILL reviews the interface boundary. | 0.78 | [commit to a specific MPC vendor (premature); hand-roll shamir (out of scope)] | | D-059 | **IBC packet scope = the 5 L2 chains already in the v0.2 skeleton** (Polygon, Base, Arbitrum, Optimism, Solana per REQ-009/`x/satellite`). v0.5 `x/bridge` handlers implement IBC packet recv/ack for these 5 chains' `BridgeStatus` transitions. No new L2 chains in v0.5. Solana IBC uses the wormhole-style bridge adapter (already stubbed in `x/bridge` per D-021). | The 5 L2 chains are the locked-const set (REQ-009). Adding new chains is a Year-4 concern. Solana IBC was a v0.1 deferred item (D-021) now promoted. | 0.82 | [add 3+ new L2 chains (Year 4); defer Solana IBC again (stalls)] | | D-060 | **Council governance shape (AUDIT §193 P1-1)**: add `Proposal` and `VoteOption` enum types to `x/council/types` (currently absent per AUDIT). `ProposalKind` enum = {Stand, Guild, Mesh, MissionLockAmendment-Rejected} (Mission Lock non-amendable → the enum value exists but the handler rejects it; documents the non-amendability in code). `VoteOption` enum = {Yes, No, Abstain, Veto} (Veto = Watcher-only, quorum rule). SignalKind stays at 4 sources (P1-2 defensible per AUDIT; expansion deferred to v0.6+ governance vote). Mission Lock const firewall (G-003) intact. | AUDIT P1-1 flagged the absence as a divergence. Adding the enums is `feat:` (deferred from v0.4 by D-001). P1-2 (SignalKind 4→5) is a locked-const change rejected by the audit rationale, so it stays at 4. | 0.82 | [add SignalKind 5th source (locked-const change, rejected); defer Proposal/VoteOption again (stalls)] | -| D-061 | **No IDEATE stage in v0.5** (no `--ideate` flag this run). The feature scope was pre-seeded from PROJECT.md v0.4 out-of-scope + AUDIT §193 P1-1 + D-050 and ratified at CLARIFY. The D-001 refinement-only filter does NOT apply (v0.5 is a feature milestone, not NFR). | run.md §IDEATE is conditional on `--ideate`. This invocation has no `--ideate`. | 1.00 | [run IDEATE anyway] | \ No newline at end of file +| D-061 | **No IDEATE stage in v0.5** (no `--ideate` flag this run). The feature scope was pre-seeded from PROJECT.md v0.4 out-of-scope + AUDIT §193 P1-1 + D-050 and ratified at CLARIFY. The D-001 refinement-only filter does NOT apply (v0.5 is a feature milestone, not NFR). | run.md §IDEATE is conditional on `--ideate`. This invocation has no `--ideate`. | 1.00 | [run IDEATE anyway] | + +## Clarification Decisions (Phase 0 v0.6 — CLARIFY, autonomy=full) + +Auto-decided defaults logged per clarify workflow Step 4 (full autonomy → accept defaults, log decisions). `--ideate` flag IS present this run; v0.6 is the project's first UI milestone. The D-001 refinement-only filter does NOT apply (v0.6 is a feature milestone). User-validated stack choices recorded via interactive questions: Go `html/template` + HTMX (frontend stack), Go mock API server (mock data layer), all 5 screens (Reach signup, Stash dashboard, Window authorization, Standing + Freeholder signals, Bloom accrual), new top-level `web/` dir (UI code location). + +| ID | Decision | Rationale | Confidence | Alternatives | +|----|----------|-----------|------------|--------------| +| D-066 | **Frontend stack = Go `html/template` + HTMX.** HTMX is a single vendored JS file served as a static asset — no node toolchain, no `package.json`, no build step. Go `html/template` is stdlib. **G-006 (zero-dep) is preserved** — this is the decisive factor vs. a React/Svelte SPA. Sufficient for Reach/Stash/Window/Standing/Bloom screens (progressive enhancement over server-rendered HTML). Weakest for rich dashboards, but adequate for an MVP prototype. | User-validated. Project has a strong zero-dep ethos (G-006); v0.5 took a controlled G-006 exception for cosmos-sdk only after GRILL ratification. A node toolchain + `package.json` would be a far larger exception for a UI MVP that can be served by stdlib + one vendored JS file. | 0.88 | [React/Vite SPA (adds node toolchain, breaks Go-only convention); SvelteKit (same tradeoff); pure static HTML/CSS/vanilla JS (most fragile)] | +| D-067 | **Mock data layer = Go HTTP server in `web/` instantiating real `x/*/types` structs.** New top-level `web/` dir holds `main.go`, HTTP handlers, an in-memory mock store seeded from fixtures, and `static/` + `templates/`. The mock store imports `x/identity/types`, `x/stash/types`, `x/window/types`, `x/standing/types`, `x/bread/types`, `x/bloom/types` and populates them with test values. **No keeper, no Cosmos runtime, no `app.go`** (none exists in the repo). This grounds the UI in the actual locked data shapes (Reach, Stash, Window, FreeholderSignals, BloomRecord) — the UI does not exercise a chain but does exercise the real Go type definitions. | User-validated. The four modules the Nomad UI primarily surfaces (identity, stash, window, standing) are types-only skeletons with no keeper/MsgServer. A Go mock server reuses the type definitions as the source of truth, so the UI is grounded in the locked constants (GrainsPerBread=10000, MaturityThresholdDays=90, standing formula) rather than mirroring them in TS/JSON. | 0.85 | [frontend-only TS/JSON fixtures (UI would not exercise any Go code path); Go mock API + in-memory keepers (more code, premature)] | +| D-068 | **UI code location = new top-level `web/` dir.** Clean separation from `x/` protocol modules; does not touch the `go.mod` module path; does not pretend to be a Cosmos module. `web/` contains `main.go` (or `cmd/oyd-ui/main.go`), handlers, mock store, fixtures, `static/`, `templates/`. | User-validated. The Mesh Experience component is ROADMAP Phase 2, not a v0.6 deliverable; coupling the UI to Cosmos module conventions (a new `x/meshexperience`) is premature. A top-level `web/` dir matches the project's existing convention of non-`x/` top-level dirs (`docs/`, `lexicon/`, `lexicon_meta_docs/`). | 0.90 | [new `x/meshexperience` Cosmos module (couples UI to Cosmos conventions prematurely); `cmd/oyd-ui` + `web/` split (more files, clearer build)] | +| D-069 | **Lexicon firewall extension to `web/`.** REQ-012 currently scans `x/` + `docs/`. A new sibling meta-test `lexicon_meta_web_test.go` (package `lexicon_meta_web`) scans `web/templates/**/*.html` + `web/static/**/*.js` for the 10 banned terms, using the same `lexicon.FindBannedTerm` + word-boundary regex. Self-exclusion + fragment pattern preserved. **"Sign up" maps to "Create a Reach"** — the word "account" is banned (REQ-012). Firewall-first: lands in P1 before content (P2..P5) so UI strings are lexicon-clean by construction. | REQ-012 is `All` phases and UI strings are user-facing; the firewall must cover the UI to be durable. Extending the existing meta-test pattern (not modifying it) preserves v0.2/v0.3 coverage. Firewall-first (D-044 pattern) ensures UI content is lexicon-clean by construction, not by retrofit. | 0.88 | [skip (REQ-012 is All phases); single combined meta-test scanning x/ + docs/ + web/ (loses isolation)] | +| D-070 | **G-003 firewall scope: `web/` importing `x/*/types` is app-layer consumption, not a cross-`x/` production import.** G-003 (production import firewall) prohibits production struct imports across `x//types` packages. `web/` is not an `x/` module — it is the application layer that consumes protocol types, exactly as a future `cmd/oyd` would. The G-003 firewall stays intact: no `x/` module gains a production import of another `x/` module's types via `web/`. GRILL reviews this boundary. | G-003's intent is to prevent cross-module coupling inside the protocol layer. The application layer consuming types is the intended consumption direction. `web/` importing `x/identity/types` is no different from `cmd/oyd` importing it (when one exists). | 0.85 | [treat `web/` as an `x/` module (wrong — it is not protocol); forbid `web/` from importing `x/*/types` (would force TS/JSON fixtures, losing the grounding in locked constants)] | +| D-071 | **"Sign up" = create a Reach + open a Stash atomically.** The Nomad entry path per `docs/nomads/reach.md` is "a Nomad starts with a Reach and a Stash". The signup form creates both atomically: a `Reach` with `IsNomad=true` + a `Stash` with `HolderID` matching the Reach's `HolderID` and `BalanceGrain` seeded to a test value (e.g., 500,000 Grain = 50 Bread). No KYC, no custodian (REQ-001 self-service principle). The UI labels this "Create a Reach" (lexicon-clean; "account" is banned). | The docs define the Nomad starting state as Reach + Stash. Creating only a Reach would leave the Nomad unable to view a Stash dashboard (P2) — the atomic creation matches the docs and makes the happy path contiguous. | 0.82 | [create Reach only, defer Stash creation to a separate flow (fractures the happy path); create Reach + Stash + Window all at signup (over-scope for an MVP)] | +| D-072 | **Phase ordering** (provisional, planner finalizes): P1 Web foundation + Reach signup + lexicon firewall extension (REQ-040 + REQ-045 — same `web/` territory, vertical slice, firewall-first) → P2 Stash dashboard (REQ-041, depends on Reach existing) → P3 Window authorization (REQ-042, depends on Stash existing) → P4 Standing + Freeholder signals (REQ-043, depends on Reach existing) → P5 Bloom accrual (REQ-044, depends on Stash existing) → P6 final review + audit + milestone ship. Each phase independently shippable; P1 lands the foundation + firewall first (lexicon-clean by construction). | P1 bundles the web foundation + Reach signup + the firewall extension (same `web/` territory, vertical slice). P2..P5 each add one screen, ordered by the Nomad happy path (Reach → Stash → Window → Standing → Bloom). Vertical slices, each phase shippable. | 0.82 | [different wave ordering; bundle Stash + Window in one phase] | +| D-073 | **Bread-scale source of truth = `x/bread/types` code constants, NOT `docs/shared/bread-scale.md`.** The code constants (`GrainsPerBread=10000`, `BreadScaleAll()` table) are the locked, tested values; the docs table is aspirational/outdated (states 1,000× ratios that do not match the code). The UI uses the code constants for all Bread-scale conversions. A doc-fix for `docs/shared/bread-scale.md` is flagged as a P1+ follow-up (not a v0.6 deliverable — docs were a v0.3 deliverable; this is a doc-drift fix, not a UI feature). | The code constants are tested (`x/bread/types/types_test.go` asserts them); the docs are not. Using the code as the source of truth keeps the UI consistent with the protocol layer. | 0.90 | [use the docs table (wrong — not tested, disagrees with code); fix the docs in v0.6 (out of scope — doc-drift fix, not a UI feature)] | \ No newline at end of file From 6597cbebd8bd73dbeba411ff680177028517619e Mon Sep 17 00:00:00 2001 From: cloudinit-bot Date: Tue, 18 Aug 2026 11:57:23 +0000 Subject: [PATCH 3/9] =?UTF-8?q?docs(P00):=20research=20=E2=80=94=20v0.6=20?= =?UTF-8?q?Nomad=20Web=20UI=20MVP=20findings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ---ci--- phase: 0 milestone: v0.6 status: research decisions: - id: D-074 decision: HTMX 2.0.10 vendored as web/static/htmx.min.js (single JS file, no build step, no go get — G-006 preserved) rationale: htmx.org docs confirm dependency-free single-file install; 2.0.10 is current stable (v4 in beta, Summer 26 target) confidence: 0.95 alternatives: [htmx 1.x (IE support, unnecessary), pin a newer beta (instability risk)] - id: D-075 decision: lexicon_meta_web_test.go scans web/**/*.{html,js,go} as a new sibling firewall (package lexicon_meta_web, subdir lexicon_meta_web/) rationale: web/ is a new top-level dir NOT under x/ — the existing lexicon_meta_test.go (x/**/*.go) does not cover it; mirror the lexicon_meta_docs/ subdir pattern with G-013 walk-coverage + G-009 self-test + G-014 shared SyntheticBannedStrings() confidence: 0.85 alternatives: [extend lexicon_meta_test.go to also walk web/ (mixes x/ and web/ concerns), separate .go and .html/.js tests (more files)] - id: D-076 decision: Go 1.22 net/http.ServeMux is the sole router for web/ (method+path patterns, r.PathValue); gorilla/mux NOT used by web/ despite being a transitive cosmos-sdk dep rationale: go.mod:3 confirms go 1.22; enhanced ServeMux covers GET/POST + path params for all 5 screens; G-006 zero-dep preserved (no third-party router) confidence: 0.95 alternatives: [gorilla/mux (breaks G-006 for web/, unnecessary), chi/router (new dep)] - id: D-077 decision: frontend-engineer activated for v0.6 with territory web/** (templates, static, handlers, store, main.go, lexicon_meta_web_test.go); backend-engineer co-owns the mock store x/*/types integration rationale: first UI milestone — frontend-engineer was deactivated since v0.3 (no UI work); Go html/template + HTMX stack (no node/React) aligns with frameworks; constraints bind G-006 (vendored HTMX), G-003 (app-layer type import), REQ-012 (lexicon), D-073 (bread-scale code constants) confidence: 0.90 alternatives: [keep frontend-engineer deactivated and have backend-engineer own templates (wrong skill fit), activate docs-writer instead (no docs-content work in v0.6)] ---ci--- v0.6 §1: Go html/template + HTMX architecture — server layout (web/main.go, handlers/, store/, templates/, static/), base template pattern, HTMX 2.0.10 vendoring (single JS file, no build step, G-006 preserved), progressive enhancement via HX-Request header (fragment vs full-page dispatch), html/template contextual auto-escaping (XSS prevention). v0.6 §2: Mock server data model — exact struct shapes verified from source for all 6 modules (identity Reach, stash Stash+StashActivity+IsMature, window Window+Scope+RateLimit+Activate/Revoke/Expire, standing Rating/Vouch/Slash/ FreeholderSignals+helpers, bread GrainsPerBread=10000+BreadScaleAll 11 tiers, bloom BloomRecord+TargetBloomRateBasisPoints=450). Import paths use module github.com/oy/openyield. Bread-scale code constants are the source of truth (D-073) — docs/shared/bread-scale.md is outdated (claims 1000x ratios; code uses 100x). v0.6 §3: Lexicon firewall extension — pattern to mirror from lexicon_meta_test.go (x/**/*.go) and lexicon_meta_docs/ (docs/**/*.md); new lexicon_meta_web/ subdir + package lexicon_meta_web scanning web/**/*.{html,js,go}; 10 banned terms verified from lexicon.go:30-41 (bank, deposit, interest, yield, currency, dollar, euro, account, savings, depositor); G-013 walk-coverage + G-009 self-test + G-014 shared helper. v0.6 §4: HTTP routing — Go 1.22 net/http.ServeMux method+path patterns confirmed (go.mod:3); r.PathValue() for path params; gorilla/mux (go.mod:75 transitive) NOT used by web/ per G-006. v0.6 §5: PERSONAS.md update — frontend-engineer activation (YAML frontmatter format documented); territory web/**, frameworks Go 1.22+html/template+HTMX+ ServeMux (NO node/React), constraints G-006/G-003/REQ-012/D-073; backend-engineer co-owns mock store type integration; security/cosmos/mesh/data-engineers deactivate for v0.6 (UI-only, no runtime). v0.6 §6: ARCHITECTURE.md update — proposed section outline appended after line 514 (v0.5 section end); 7 subsections mirroring v0.5 density. --- .ciagent/oy/RESEARCH.md | 531 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 530 insertions(+), 1 deletion(-) diff --git a/.ciagent/oy/RESEARCH.md b/.ciagent/oy/RESEARCH.md index c519736..996e08e 100644 --- a/.ciagent/oy/RESEARCH.md +++ b/.ciagent/oy/RESEARCH.md @@ -2194,4 +2194,533 @@ flow per the researcher role — NOT flagged `[ASSUMED]`): rejection is proposed. Confidence 0.80. 4. **A-574** (Watcher Veto quorum value): default 6 proposed (matches REQ-004 6-of-9); the exact param value is a planner decision. - Confidence 0.75. \ No newline at end of file + Confidence 0.75. + +--- + +## v0.6 Research (Nomad Web UI MVP) + +> v0.6 is the project's first UI milestone (D-066..D-073, CLARIFY). Stack is +> Go `html/template` + HTMX (vendored single JS file, no node toolchain — +> G-006 zero-dep preserved). Mock data layer = Go HTTP server in new +> top-level `web/` dir instantiating real `x/*/types` structs from in-memory +> fixtures (no keeper, no Cosmos runtime, no `app.go`). 5 screens: Reach +> signup, Stash dashboard, Window authorization, Standing + Freeholder +> signals, Bloom accrual. This research grounds the UI in the live codebase +> (read-only — no files modified). + +### v0.6 §1. Go `html/template` + HTMX Architecture + +**Server structure** — A Go `html/template` server for the mock UI follows +the standard stdlib-only layout (matches D-068's `web/` dir decision): + +``` +web/ + main.go # entrypoint: registers routes, serves static + templates + handlers/ # one file per screen (reach.go, stash.go, window.go, ...) + store/ # in-memory mock store (imports x/*/types, seeded from fixtures) + templates/ + base.html # layout: ...` (served by `http.FileServer` or +`http.ServeFile` from `web/static/`). + +**HTMX vendoring (G-006-compliant)** — HTMX is a dependency-free, browser- +oriented JS library: a single `htmx.min.js` file loaded via `