The product direction is Go-first full web app compilation: GOWDK is the
.gwdk component/page compiler, and GOWDK Runtime is the app/runtime layer.
Build-time page output is the default, actions/APIs/fragments are first-class
request-time endpoint behavior, and server {} / go server {} select the
integrated non-default request-time page-rendering lane per page.
Current user-facing documentation now separates implemented behavior from planned behavior across the README, CLI/config/routing/deployment references, language references, compiler docs, and examples.
- Implemented: available in the current codebase, documented, and covered by tests or an explicit verification command.
- Partial: available for a narrower slice than the full requirement, with remaining limits called out in the notes.
- Experimental: available to try, but the public contract may still change.
- Planned: accepted product direction with no stable implementation yet.
- Intentionally out of scope: rejected for the current product direction.
| ID | Requirement | Priority | Status | Notes |
|---|---|---|---|---|
| PRD-001 | Compile portable package-peer .gwdk files that declare package, optional page, route, guard, layout, blocks, and endpoints. |
High | Partial | Discovery, package parsing, metadata parsing, parser syntax validation, filename-derived page IDs, default build discovery, route shape/conflict validation, required page-view and page-guard validation, explicit component-file build input, typed GOWDK AST, AST analyzer, versioned compiler IR, endpoint comment discovery, endpoint conflict diagnostics, and mandatory typed view {} IR nodes for supported view bodies are implemented; full downstream migration to typed IR for every semantic block remains planned. |
| PRD-002 | Default render mode must be spa. |
High | Implemented | Root RenderConfig.DefaultMode() defaults to gowdk.SPA. |
| PRD-003 | Support render modes spa, hybrid, and ssr. |
High | Implemented | Root RenderMode constants exist. Actions are endpoint capability, not a render mode. |
| PRD-004 | Reject request-time page behavior unless the SSR feature is enabled in config or CLI options. | High | Implemented | internal/compiler.ValidatePage emits missing_ssr_addon. |
| PRD-005 | Require paths {} for dynamic SPA routes. |
High | Implemented | Dynamic SPA routes without paths are rejected; action endpoints on those pages inherit generated concrete page paths. Malformed routes, duplicate route params, duplicate page route patterns, and route-method conflicts are rejected; the first literal string paths {} subset can prerender dynamic SPA routes. |
| PRD-006 | Keep typed actions available without SSR. | High | Partial | SPA pages with exported act Name POST "/path" endpoint declarations validate without SSR. Generated apps can serve POST action handlers with generated typed decoders, unexpected-field rejection, generated validation for direct literal required, minlength, maxlength, and supported anchored pattern form controls, bounded multipart action forms with explicit file count/size/MIME policy, generated validation fragments for partial requests, partial fragment responses, same-package action handlers using no-input, typed value, typed pointer, form.Values, or form.Data signatures returning response.Response, and generated CSRF token injection/validation by default unless Build.CSRF.Disabled is set. Upload storage/scanning/persistence and user-defined domain validation patterns remain in normal Go handlers. |
| PRD-007 | Treat server {} as request-time behavior requiring the SSR addon. |
High | Implemented | Pages with server {} infer request-time SSR and fail unless SSR is enabled. |
| PRD-008 | Keep runtime render core reusable across build-time pages, backend fragments, and request-time pages. | High | Implemented | runtime/render exists independently from addons/ssr; SSR is integrated through compiler/runtime hooks and enabled by feature registration. |
| PRD-009 | Generate build-output/prerender output for v0.1. | High | Partial | gowdk build --out emits app-shell HTML, gowdk-routes.json, gowdk-assets.json, and gowdk-build-report.json for simple build-time pages, the first literal dynamic path subset, literal build data, imported and same-package Go build data functions returning T or (T, error) with optional gowdk.BuildParams route params, scalar build fields, earlier-field references, string concatenation, numeric arithmetic, boolean logic, comparisons, bounded build-time iteration/transform (list and object literals, seq ranges, comprehensions with map/filter, list reductions such as count/sum/join, and field/index access) over deterministic build data, slice/struct fields returned by Go build functions, and explicit or discovered components. Build.ObfuscateAssets / gowdk build --obfuscate-assets provide deterministic production obfuscation for compiler-owned generated browser JavaScript and record transformed assets in the asset manifest and build report. Generated app handlers exist for the supported action/API/fragment/SSR slices; arbitrary build-time statements beyond the expression/iteration subset, feeding build-time lists into g:for prerender regions, and full component semantics remain planned. |
| PRD-010 | Provide CSS processor addon extension points without adding Tailwind to the compiler core or runtime core. | High | Partial | FeatureCSS, addons/css, configured stylesheet links, compile-time CSS processors, discovered CSS inputs, extracted literal classes, css page selection, generated page CSS output, CSS asset manifest entries, page-aware processor stylesheet selections, component CSS AST/IR scope and hash metadata, emitted scoped component CSS linked only from pages that use the component, emitted component asset files, scoped selector/keyframe rewriting, deterministic CSS ordering, native config-helper execution for importable addon values, an experimental Tailwind v4 standalone-CLI wrapper, and generated CSS/component asset content-hashed emitted filenames are implemented; richer CSS processor addon capabilities remain planned. |
| PRD-011 | Support embedded assets and one-binary serving. | High | Partial | addons/embed and runtime/asset boundaries exist; gowdk serve can serve generated build output locally; gowdk build --app can generate an embedded app, --bin can compile it into one binary, --docker can emit a minimal non-root Dockerfile and .dockerignore beside that binary, --deploy-recipe can emit optional static/systemd/Caddy/Nginx/split frontend-backend starter files, and --wasm can compile a Go js/wasm artifact for SPA pages, feature-bound action/API handlers, action redirects, action fragments, standalone concrete or dynamic fragments, concrete or dynamic SSR pages with declared server {} identifier or dotted paths, and concrete or dynamic hybrid request-time pages with or without declared server {} data. CI now starts the generated one-binary embed example and verifies both /_gowdk/health and the embedded page response. |
| PRD-012 | Support server fragments for partial updates without full-page SSR. | Medium | Partial | addons/partial, generated client runtime emission, generated action fragment responses for partial POSTs, standalone concrete and dynamic fragment routes with raw and typed route params for request-time hooks, generated required-field validation fragments for partial POSTs, generated CSRF validation when enabled, and first-slice generated JavaScript islands for local component state are implemented. Richer fragment rendering and broader local client-side reactivity remain planned. |
| PRD-013 | Complete request-time page rendering with server {}, guards, layouts, and error handling. |
Medium | Partial | addons/ssr registers the SSR feature. runtime/ssr provides load context, route registration, request-aware layout composition, safe local redirect errors, default error-handler contracts, and declared load path resolution. runtime/guard provides shared guard context/registry/execution plus no-store redirect/custom-response helpers for generated SSR/action/API/fragment routes, and runtime/auth provides thin native RBAC principal/provider helpers for defense-in-depth generated route access gates, and addons/auth exposes an app-owned revocable session-store contract with authorization-version checks while generated auth-addon startup remains signed-cookie; backend authorization remains normal Go code and is never replaced by guard metadata. Generated embedded apps can serve concrete and dynamic request-time SSR pages rendered from view {} and literal or imported build {} data, generated SSR/action/API/fragment routes use auth.Addon defaults for auth.required and native role:/permission: session guards when configured; otherwise they require GOWDKGuardRegistry for custom guard IDs and GOWDKAuthProvider for native RBAC guard IDs, fail Go compilation when required backing hooks are missing, run declared guards before user logic, and have generated-binary coverage for registered guard success and redirect paths, server { => { field, user.name } } execution calls same-package Go load functions through ssr.LoadContext, optional generated 404.html/500.html pages are used by runtime app error responses, SSR routes can declare error "/errors/page.html" for route-local generated load/render failure and route panic pages, action/API declarations can declare endpoint-local error pages for generated panic boundaries, and generated SSR/action/API lanes have no-store panic boundaries. |
| PRD-014 | Add optional WASM islands after the core compiler and action flow are stable. | Low | Partial | Component-level wasm declarations make normal calls to that component emit WASM and loader assets under assets/gowdk/islands/; explicit g:island="wasm" remains supported as a call-site override. Declared wasm browser-side Go packages and page-level go client {} mounts are compiled with GOOS=js GOARCH=wasm, checked for browser-unsafe imports, ship the Go wasm_exec.js runtime asset, instantiate through Go runtime imports when needed, and validate required GOWDK ABI exports. Browser-runtime integration coverage exercises the generated host loader mount, event, patch, emit, cleanup, invalid-patch rejection, shared page-store participation, and persistence contract; runtime/wasm exposes payload/result helpers for Go exports. Fuller user-code runtime validation remains planned. |
| PRD-015 | Provide language tools for .gwdk token inspection, formatting, validation, manifest output, and LSP editor integration. |
High | Implemented | internal/lang, internal/lsp, internal/inspectreport, and CLI commands exist, including source-linked inspect tree, endpoint graph output, and Go binding inspection. |
| PRD-016 | Define the current hybrid request-time page contract without adding separate page syntax. | High | Implemented | Hybrid Lifecycle Contract is the source of truth. Pages default to SPA; config-selected hybrid pages and request-time pages with effective hybrid mode use the integrated request-time lane, require the SSR feature, skip build-time prerender output with request_time_page_skipped, expose hybrid in route reports, and keep streaming, browser-owned server-data refresh, non-HTTP revalidation, and implicit action invalidation unsupported until a future source contract exists. |
| PRD-017 | Define cache and revalidation behavior for static files, SPA routes, backend endpoints, partial responses, SSR routes, and hybrid pages. | Medium | Implemented | Generated binaries apply asset-manifest cache policies for generated assets, default SPA HTML to no-cache, default request-time handlers to no-store, and apply explicit page cache policies to successful generated static SPA, SSR, and hybrid HTML responses. revalidate accepts positive second or duration values, requires cache, and compiles into a stale-while-revalidate=<seconds> Cache-Control directive for successful generated static SPA, SSR, and hybrid HTML. Safety responses for actions, APIs, fragments, guard failures, load redirects, generated errors, and CSRF-mutated HTML remain no-store. |
| PRD-018 | Escape generated HTML by default and require any raw HTML escape hatch to be explicit. | High | Implemented | Rendering escapes text and attributes by default. g:unsafe-html={Expr} is the single explicit raw HTML escape hatch: attributes stay escaped, markup children are rejected, and it is refused on void elements, in stateful/island/loop contexts, and for route-param-tainted values. Foreign raw HTML syntax such as {@html} fails loudly and points at g:unsafe-html. URL-bearing attributes reject active-content schemes, protocol-relative URLs, and control characters; raw on* handlers, srcdoc, and literal <script> tags are rejected in view {}. See docs/language/markup.md. |
| PRD-019 | Provide optional rate limiting for request-time handlers without making it core. | Medium | Implemented | FeatureRateLimit and addons/ratelimit enable generated rate-limit hooks; runtime/ratelimit exposes HTTP middleware, fixed-window decisions, an in-memory store, and a Redis-backed store adapter. Generated action, API, fragment, SSR, and split-backend proxy handlers expose RegisterRateLimiter(*ratelimit.Limiter) when the addon is enabled and call the registered limiter before guards and user logic. Docs include an in-memory registration example and a concrete go-redis adapter. |
| PRD-020 | Allow generated apps and binaries to package selected configured modules. | High | Implemented | Build.Targets statically declares module sets, output dirs, generated app dirs, and binaries. gowdk build runs all configured targets, --target selects named targets, and ad hoc repeated or comma-separated --module flags remain supported. Generated frontend/backend apps under .gowdk/ build as packages inside the application module, while explicit legacy app dirs and worker/cron role apps keep nested generated modules. |
| PRD-021 | Provide a dependency-free fast local development loop. | High | Implemented | gowdk dev polls discovered inputs without production dependencies, compares content hashes, caches watched input snapshots between ticks, rebuilds only on real input changes, incrementally renders page/component/layout affected SPA output when possible, falls back to full builds for config/CSS/source-set/app/binary/WASM changes, serves the generated output, live reloads browsers after successful rebuilds, keeps the last successful output after failed rebuilds, and can build/restart generated app targets. SPA/app generation skips identical file writes. |
| PRD-022 | Allow generated app output to compile to a WASM deploy artifact. | Medium | Partial | gowdk build --wasm <file> and Build.Targets[].WASM compile the generated app with GOOS=js GOARCH=wasm. CI verifies the emitted artifact is a real WASM module by checking the WebAssembly magic header. This remains separate from component-level browser island assets emitted for wasm components; host runtime/loader integration is deploy-platform owned. |
| PRD-023 | Keep current documentation aligned with implemented CLI, config, compiler, language, routing, deployment, and examples. | High | Implemented | README.md, docs/getting-started.md, docs/cookbook/README.md, reference docs, language docs, compiler docs, and examples/README.md describe current support, link to the right source of truth, and call out planned behavior. |
| PRD-024 | Require project config before compiling or validating .gwdk code. |
High | Implemented | check, audit, manifest, sitemap, routes, build, and dev require gowdk.config.go discovered upward from the current directory or explicit source paths, --project-root <dir>, or an explicit --config <file>, even when explicit .gwdk file paths are provided. Project-aware build, check, and dev execute importable configs through a cached native helper instead of serializing gowdk.Config. |
| PRD-025 | Keep framework integrations optional and outside compiler/runtime core. | Medium | Implemented | Generated apps expose standard net/http handlers and framework-neutral code by default. Optional runtime/adapters/chi, runtime/adapters/echo, runtime/adapters/gin, and runtime/adapters/fiber nested modules wrap the same generated http.Handler; route-aware Chi/Echo/Gin mounting can consume generated OpenAPI metadata, and docs cover middleware overlap and Fiber adaptor caveats. |
| PRD-026 | Provide declarative security posture and baseline audit gating. | High | Partial | internal/securitymanifest projects validated IR into a route/endpoint/contract/frontend posture, internal/auditspec evaluates the built-in baseline plus declared *.audit.gwdk policies, gowdk audit reports human/JSON findings with registry-backed severities and exits non-zero on error findings, and gowdk build evaluates the same baseline before writing output plus scans final emitted artifact files after generation. Production builds fail on error-severity findings unless --allow-insecure is set; non-production builds print a warning summary. The baseline covers action/command/state-changing API CSRF, guardless action/fragment/command/query endpoints, public-by-omission APIs, roleless contracts, bundle secret leaks, client-visible guardless routes, and raw-HTML sinks, and auth-addon session mode posture; policy rules can require headers. gowdk audit --emit-tests writes readable standalone _test.go posture tests without overwriting user-owned files unless --force is passed, and --run builds a temporary generated app and executes its generated app audit test through runtime/testkit without auto-authorizing app-owned custom guards. Richer role fixture injection and deeper browser/data-flow analysis remain planned; authentication, sessions, RBAC storage, and backend resource authorization stay app-owned by design. |
| PRD-027 | Provide opt-in browser presentation-event fanout without adding WebSocket dependencies to the root module. | Medium | Implemented | FeatureRealtime and addons/realtime provide config and gowdk add realtime wiring for presentation-event fanout. Dependency-free SSE fanout remains in the root module through runtime/contracts/sse and realtime.NewSSE; WebSocket fanout remains isolated in the nested runtime/contracts/websocketfanout module. Docs cover SSE versus WebSocket setup, deployment caveats, and the M14 boundary for live DOM reactivity. |
| PRD-028 | Provide compiler-validated realtime UI subscription metadata. | Medium | Partial | ADR 0012 defines g:subscribe on query-owned elements. The compiler parses the directive, lowers it to Program.RealtimeSubscriptions, requires realtime.Addon(), validates referenced Go contracts as presentation events available to the web role, emits exact-span diagnostics, renders data-gowdk-subscribe and validated data-gowdk-subscribe-type markers, records build-report metadata, generated apps mount subscription-filtered SSE fanout at /_gowdk/realtime/events for bound subscriptions, generated stream handlers run inherited guards before opening SSE responses, the SSE adapter declares configurable browser retry timing, keeps an optional bounded replay window keyed by SSE event IDs, can revoke connected clients by server-owned audience label, exposes process-local stats, and drops events for full per-client buffers instead of blocking command execution. Generated gowdk.js applies explicit version-1 replaceHTML realtime patches to subscribed query regions, and examples/contracts demonstrates the live flow. The compiler also scans explicit Go RegisterInvalidation[event, query] edges, lowers validated bound edges to Program.QueryInvalidations, rejects unknown queries/events or events no scanned command emits, records query_invalidation build-report events, prints invalidates graph edges, renders data-gowdk-query-type markers, emits generated gowdk.query.invalidate presentation events after command event dispatch, and uses a generated route/query refresh endpoint before falling back to current-document refetch for matching non-subscribed query regions. Fragment/API-specific query execution is defined as fallback-only until explicit renderer metadata exists. Richer patch shapes, richer fragment/API renderers, durable replay, and production telemetry export remain planned hardening work. |
| PRD-029 | Provide optional SEO build output for sitemap, robots, and structured page metadata without making crawler policy core. | Medium | Partial | addons/seo registers FeatureSEO and gowdk.SEOProvider; gowdk build emits sitemap.xml and robots.txt only when the addon supplies a valid BaseURL. The sitemap includes public static and paths {}-expanded SPA routes plus configured extra URLs, while request-time, noindex, and guardless default-denied pages are excluded and listed in gowdk-build-report.json. Pages can declare supported jsonld kinds for generated JSON-LD, and generated apps can serve /sitemap.xml with an app-owned dynamic provider. Broader schema kinds and crawler operations remain planned or app-owned. |
| PRD-030 | Provide dependency-free runtime trace primitives and opt-in generated app instrumentation. | Medium | Partial | ADR 0013 defines runtime/trace as the root-module observability core. It provides W3C-compatible trace/span IDs, traceparent/tracestate propagation with bounded header parsing, context spans, GOWDK surface/lane/source metadata, attributes/events/status, always-on/off and ratio sampling, console/JSONL/ring/multi/exporter sinks, a bounded JSON/SSE collector, hardened browser span ingest, and a self-contained local viewer with dropped/rejected counters. addons/observability gates debug-only generated route/guard/handler/SSR-load/browser/island tracing, runtime/contracts propagates trace context through events/jobs/workers/outbox records, and the nested runtime/trace/otel module provides optional OTLP HTTP export without root OpenTelemetry dependencies. Durable production storage, hosted analysis, and production sampling/access policy remain app-owned. |
| PRD-031 | Provide a config-owned localization contract for generated page routes and typed message catalogs. | Medium | Partial | Config.I18N declares locale codes, optional path prefixes, default locale, and default-prefix omission. Build-time SPA routes, dynamic paths {} output, request-time SSR/hybrid page routes, route metadata, site-map JSON, route manifests, and SEO sitemap output expand per locale. Build helpers receive gowdk.BuildParams.Locale, generated HTML receives lang, SSR handlers attach runtime/app.Locale(ctx), and runtime/i18n provides typed Go catalog/bundle helpers, deterministic catalog completeness reports/templates, and bounded plural, number, date, and time formatting helpers. Compiler-owned .gwdk message extraction, ICU/CLDR completeness, translated diagnostics, and generated per-endpoint locale policies remain planned or app-owned. |
This backlog records product decisions without treating deferred work as implemented.
| Area | Requirement Direction | Status |
|---|---|---|
| Markup language | Expand view {} only through GOWDK-owned AST nodes and directives; support bounded client-island await blocks and CSS-driven motion hooks while deferring async placeholder directives, DOM/document targets, and DOM actions until separate contracts exist. |
Partial — the directive contract is closed: unknown g:* directives and deferred families (DOM/document/window targets, g:await/g:async, DOM actions) fail at parse time with family-specific guidance under unsupported_markup_directive/unsupported_markup_syntax; {#await fetchJSON[T](urlExpr)} is supported inside JS islands, g:transition/g:animate provide CSS class/state hooks for client g:if and keyed g:for, and raw HTML has its explicit contract via g:unsafe-html={Expr} (PRD-018). |
| Snippets and slots | Keep slots as the stable reusable markup primitive; defer first-class snippet/render values. | Partial — default, named, and scoped slots are implemented and documented as the reusable-markup contract; first-class snippet/render values remain deferred. |
| Component props | Keep imported Go structs as the primary typed prop path; inline scalar string/int/float/bool props, scalar defaults, same-named {...props} forwarding, target:source prop renaming, and component g:bind:<ExportedState> for exported child state are supported; recursive rendering and dynamic component selection remain explicit rejections. |
Partial |
| Client reactivity | Keep bounded compiler-owned client {}; generated JS must not own routing, auth, business rules, database access, server validation, action behavior, global app state, or page loading policy. |
Partial — component-local state, computed values, dependency ordering and cycle diagnostics, handlers, events, effects, lifecycle cleanup, refs, bindings, conditionals, lists, typed exports, and bounded async helpers are implemented; broader browser-owned app behavior remains out of scope. |
| Shared state | Keep stores page/island scoped until cross-package or app-global stores have explicit ownership, serialization, subscription, and teardown contracts. | Partial — page-scoped stores, explicit component use, optional local/session persistence, shape invalidation, and SPA-navigation hydration are implemented; app-global stores remain deferred. |
| Load/data lifecycle | Keep build {} build-time, server {} request-time, and actions/APIs/fragments as endpoint lanes; defer universal/browser-owned load policy. |
Partial |
| Hybrid | Keep hybrid request-time page behavior explicit through config-selected effective render mode and the integrated SSR-gated request-time lane; keep streaming, browser-owned server-data refresh, non-HTTP revalidation, and implicit action invalidation unsupported until a future source contract exists. | Implemented for the current bounded contract — see Hybrid Lifecycle Contract. |
| Hooks | Compose app-wide hooks as net/http middleware plus explicit generated registration points and generated-binary lifecycle services; defer route rewriting and fetch interception. |
Partial — generated embedded and backend-only apps expose RegisterMiddleware(runtime/app.Middleware) for ordered app-wide middleware, gowdkapp.App() for generated-binary startup, and runtime/app.Service lifecycle hooks for app-owned workers or extra servers. Route rewriting, response transformation, fetch/navigation interception, and protocol-specific built-ins such as MCP remain out of core. |
| Errors | Keep error for route-local SSR and action/API boundaries; define expected error types and layout boundaries without leaking internals. |
Partial — typed expected errors map to 404, 403, 422, and 500 for generated boundaries, SSR load errors honor response.HandlerStatus instead of forcing 500, and layout-level error pages compose with SSR route boundaries for HTTP 500 handling. Templated error regions and component/fragment-specific boundaries remain planned. |
| Dev server | Keep dependency-free live reload as baseline; add browser error overlay before component-aware HMR. | Partial — gowdk dev polls without production dependencies, skips no-op rebuilds, supports incremental SPA rebuilds, runs generated app targets, prints stable change/rebuild/runtime-proxy log lines, shows browser overlays for SPA/static serving, generated-app rebuild failures, and generic generated-app runtime 5xx failures through a dev-only proxy bridge, skips live-reload/initial-overlay injection for proxied HTML over the documented dev-only size limit without full buffering, sends successful rebuilds through versioned dev-update v1 payloads, route-scopes layout-only reloads to affected pages, hot-swaps changed JS island component roots when the dependency graph maps the change to the current page, and preserves island state only when deterministic state-shape markers match. Page/source-set/runtime changes, unmatched component roots, incompatible state shapes, WASM islands, unsupported dev-update protocol versions, and broader page/layout DOM patching fall back to full reload or remain deferred to #424. |
| Playground | Own playground onboarding in website/docs first with local preview commands and static examples; keep hosted code execution optional, sandboxed, and exportable as a normal GOWDK app. | Partial — playground.md defines the onboarding path, sandbox rules, export contract, and non-goals. gowdk playground policy/export/run implements local policy inspection, normal source archive export, and an opt-in staged build bridge for future hosted runners; production hosted execution remains app-owned infrastructure. |
| Routing | Add rest params and trailing-slash policy first while keeping explicit route declarations; defer optional params, route groups, and same-path page/API negotiation. | Partial — rest params {name...} are supported as the final segment of SSR page routes (string-only, one or more segments joined with /) with duplicate/ambiguity validation, and the trailing-slash policy is explicit (canonical declarations; GET/HEAD trailing-slash requests 308-redirect to the canonical path). Optional params, route groups, and same-path negotiation remain deferred with explicit diagnostics; see docs/reference/routing.md. |
| Typed generated APIs | Generate typed route-param accessors first; add typed SSR load data before broader action result contracts. | Partial — generated SSR and fragment request-time handlers attach raw route params through app.Params(ctx) and decoded typed params through app.TypedParams(ctx); SSR load handlers can return exported typed result structs whose declared server {} fields are compiler-checked and lowered into generated adapter glue. Per-route param structs and typed action-result accessors remain planned. |
| Inline Go authoring | Allow optional Go code blocks inside .gwdk only when they extract to normal importable, formatted, testable package Go. Separate .go files remain supported and generated adapters remain glue. Saved default go {} blocks are type-checked with sibling Go files during validation, default go {} blocks can provide build-time functions for build { => LocalFunc() } with optional gowdk.BuildParams route params and same-page action/API/fragment handlers, page-level go client {} blocks can opt into client-side Go by exporting GOWDKMount<PageID> for generated WASM page mounts, generated app source materializes default go {} and go server {} blocks under gowdk_go/, go server {} can provide generated SSR load handlers, and configured addons implementing gowdk.GoBlockConsumer can validate go addon.<name> {} blocks and emit generated app Go files through native config-helper execution. Source-adjacent extraction remains planned. |
Partial |
| Forms | Keep progressive-enhancement-first form behavior; full POST and enhanced POST share action result semantics; domain validation stays in user Go. | Partial |
| APIs | Broaden APIs through public request/response helpers and typed body/query helpers, not framework-specific adapters. | Partial — runtime/api provides strict JSON body decoding, typed query helpers, typed result status selection, JSON/error/no-content response helpers for raw func(context.Context, *http.Request) (response.Response, error) handlers; addons/api enables generated API support. Generated typed API handler signatures, strict generated query/JSON input decoding, typed JSON result adapters, OpenAPI request/response schemas from the same metadata, config-level CORS policy for generated API/command/query routes, and endpoint-local .gwdk API CORS clauses that inherit/override config defaults with credentialed wildcard safety validation are implemented. Route-param/header input contracts, custom typed content negotiation, and richer examples remain planned. |
| Contract runtime | Add typed Go queries, commands, backend-owned domain/integration events, presentation events, and jobs after endpoint/adapter IR is stable. Frontend UI events trigger commands or queries, commands have one owner, domain events are emitted after backend state changes succeed, local in-process dispatch is default, and broker/outbox/worker roles are optional. Runtime registry, role filtering, event capture/replay, outbox/broker/fanout/EventSource/seen-store interfaces, worker ack/nack/backoff, file/in-memory/Redis/NATS adapters, SSE/WebSocket fanout, presentation-event audience labels, audience-scoped dependency-free SSE delivery, generated command event sinks, generated registries, generated worker replay helpers, generated standalone worker/cron role binaries, Go AST scanning, go/types diagnostics, duplicate-owner and emitted-event diagnostics, contract/list/graph/trace CLI, g:command/g:query metadata, query-bounded g:subscribe, explicit RegisterInvalidation[event, query] metadata, import-path-aware reference/subscription/invalidation linking, g:event rejection, IR binding status, app adapter IR, generated web command/query adapters, page-route query JSON negotiation, stable JSON success/error response shape, formatted generated adapter source, page-guard propagation, rate-limit/guard/CSRF ordering, report metadata, enforced scan diagnostics, generated subscription-filtered guarded SSE fanout, generated client replaceHTML patches, generated gowdk.query.invalidate events, configurable SSE retry/replay/revocation, and route/query refresh endpoint fallback for matching non-subscribed invalidated query regions are implemented. Fragment/API-specific query execution currently has fallback-only behavior; richer fragment/API renderers, remaining exact diagnostic spans, richer scheduler policies, richer realtime patch shapes, durable retry operations, and editor-first visualizations remain planned outside the milestone-14 runtime contract. |
Implemented |
| Observability | Keep root tracing dependency-free while making generated instrumentation opt-in and debug-gated. | Partial — runtime/trace provides W3C-compatible IDs, bounded traceparent/tracestate propagation, context spans, GOWDK surface/lane/source metadata, span attributes/events/status, always-on/off and ratio sampling, console/JSONL/ring/multi/exporter sinks, OTLP-shaped snapshots, slog trace/span helpers, tracer export health, bounded JSON/SSE local collection, collector health, hardened browser ingest, and a self-contained viewer. runtime/app.Metrics records dependency-free request counters, active requests, errors, latency, and generated backend route metrics keyed by route templates and endpoint IDs. addons/observability enables debug-only generated backend, SSR/load, frontend, and island tracing; contracts/outbox records carry optional trace context; runtime/trace/otel isolates OTLP HTTP export in a nested module. Durable storage, hosted analysis, production metrics/log backends, alerting, retention, and production sampling/access policy remain app-owned or future work. |
| Cache | Keep cache and revalidate as HTTP cache policy; keep action-driven data refresh explicit through redirects, fragments, JSON, or reload responses. |
Implemented for current generated responses — route reports include route/endpoint cache metadata, build reports summarize generated cache policies, generated binaries apply immutable asset cache, SPA no-cache, request-time no-store, and page cache/revalidate for successful SPA, SSR, and hybrid HTML. |
| Guards | Extend guards with safe local redirects and response helpers before richer request-local state. | Partial — guards keep the func(runtime/guard.Context) error signature. Ordinary errors fail closed with 403, while runtime/guard.RedirectTo, runtime/guard.Redirect, and runtime/guard.Respond intentionally write no-store redirects or custom responses. Richer request-local state is still deferred. |
| Component CSS | Make component CSS explicit, compiler-scoped, and documented; Tailwind and processors remain optional. | Partial |
| Accessibility | Add accessibility diagnostics as compiler warnings with stable codes and spans. | Partial — missing_img_alt, missing_form_label, empty_link_text, missing_button_type, and heading_order_skip warn on literal view markup in pages, components, and layouts. Broader ARIA and full WCAG rule coverage remain outside the current compiler slice. |
| Diagnostics and LSP | Expand diagnostic catalogue before broad parser recovery; prioritize hover, semantic tokens, go-to-definition, and route/type navigation. | Partial — the diagnostic registry, gowdk explain, JSON check output, safe fix metadata, exact ranges for high-value parser/IR-backed diagnostics, LSP diagnostics/formatting/completions/hover/definitions/references/code actions/semantic tokens, dirty-buffer g:command/g:query binding diagnostics, CLI route/sitemap/inspect reports, and diagnostics/navigation contract exist; parser recovery, remaining aggregate/addon exact-span gaps, direct markup-family emitted codes, and workspace route/type navigation remain planned. |
| Testing and scaffolding | Add optional Go handler tests, generated app smoke tests, template/addon selection, and editable generated examples. | Partial — gowdk init --tests writes a starter go.mod and non-skipping generated app smoke test, gowdk test builds temporary generated output/app/binary artifacts and runs ordinary Go tests with GOWDK_TEST_* context, runtime/testkit provides HTTP scenario helpers, cookie-preserving clients, response assertions, and in-memory contract registry/event assertions, examples/contracts/patients/contracts_test.go demonstrates command event capture, gowdk audit --run builds a temporary generated app and runs generated runtime audit tests, and explicit repository scripts cover parser fuzz smoke, generated-app integration, generated-output/report determinism, and focused runtime race detection. Broader IR-generated endpoint test files and first-class browser/E2E scaffolds remain planned. |
| Deployment and operations | Prefer docs and optional generators for static hosts, Docker, systemd, reverse proxies, CDN policy, health checks, metrics, logging, binary deploy, rollback, and CSRF secret rotation. | Partial — deployment.md documents static output, one-binary, generated Docker contexts, split frontend/backend, backend-only, Docker, systemd, reverse proxy, CDN/cache, health, metrics, logging, readiness, graceful shutdown, artifact layout, rollback, CSRF secret rotation, backup ownership, and incident boundaries. gowdk build --docker emits a minimal non-root Dockerfile and .dockerignore beside a compiled one-binary artifact. gowdk build --deploy-recipe and Build.Targets[].DeployRecipes emit optional static-host, systemd, Caddy, Nginx, and split frontend/backend starting points without owning secrets, domains, TLS, CDN policy, storage, backups, incident response, or rollout logic. Release workflows pin third-party action SHAs, extension publishing uses locked local vsce, govulncheck is pinned through tools/govulncheck, and docs distinguish convenience and high-assurance install paths. |
| Full-page hydration | Keep full-page hydration out of the repository core; use static pages, progressive enhancement, server fragments, and explicit islands. | Intentionally out of scope |
| Island ergonomics | Improve compiler-owned island syntax, lifecycle cleanup, focus helpers, local batching, and diagnostics without exposing arbitrary JavaScript as the app contract. | Partial — generated JS islands support idempotent mount/remount, cleanup, lifecycle/effect blocks, bounded refs such as focus/blur/scroll, local batching, and diagnostics; broader HMR-style ergonomics remain deferred. |
| Client builtins | Add deterministic formatting, collection, async-safe UI, focus, and selection helpers only with generated-output tests. | Partial — scalar expression helpers, list mutation built-ins, fetchJSON, and safe DOM ref methods are implemented in the bounded client language; broader formatting, selection, and date/time helpers remain deferred. |
| WASM islands | Keep browser-side Go explicit and separate from backend handlers; improve ABI docs, validation, and examples. | Partial — component-level WASM islands have a versioned gowdk-wasm-island-v1 ABI, required export and signature validation, browser-unsafe import diagnostics, loader/browser tests for mount/event/patch/emit/destroy/store participation, wasm_exec.js size/version reporting, runtime/wasm payload/result helpers, and a runnable component WASM ABI example under examples/components/wasm/; richer user-code runtime validation remains deferred. |
| PWA/offline | Keep service workers and PWA behavior optional and documentation-first; no hidden offline/cache defaults. | Documented — GOWDK emits no service worker, manifest, offline shell, or install prompt by default. docs/reference/pwa-offline.md documents user-owned registration, deploy-owned static files, conservative cache rules, and the current lack of root-scope service-worker embedding for one-binary deploys. |
| Images | Document image optimization patterns first; optional integrations may emit assets or metadata without turning core into an image pipeline. | Documented — docs/reference/images.md covers pre-build/CDN optimization, responsive literal markup, missing_img_alt, social images, component asset packaging, and the current non-goal of automatic variant generation or URL rewriting. |
| Addon discovery | Start with repository/website docs or registry metadata; add CLI discovery only after addon versioning, trust, and compatibility rules exist. | Partial — the addon discovery policy limits default gowdk add --list to addable built-ins, keeps external addons explicit through Go imports, and defines checked-in registry metadata for kind, lifecycle, compatibility, ownership, trust, public interfaces, process/network behavior, external tools, and security notes. gowdk add --list --registry and --json expose the local registry for docs/website rendering without installing or executing addon code. Remote registry sync and automatic compatibility enforcement remain planned hardening work. |
| Performance profiling | Document measurement for build time, output size, generated JS size, SSR/action latency, binary size, and cache behavior before adding automation. | Partial |
| Migration guides | Core docs avoid migration-guide positioning during 0.x hardening. Native GOWDK concepts, examples, and diagnostics come first. | Intentionally out of scope |
- Performance: SPA pages should be generated at build time and served directly from disk or embedded assets.
- Reliability: compiler diagnostics must fail fast for invalid render modes, SSR used without the feature enabled, and dynamic SPA routes without paths.
- Security: state-changing generated endpoints need CSRF, typed input decoding, validation, and safe redirects before production use; audit posture reports must not be served as public build output.
- Privacy: generated logs and diagnostics must not expose secrets or sensitive form data.
- Packaging: generated binaries and WASM artifacts must embed only the selected module output for that build.
- Developer loop: failed rebuilds must not stop the last successful served output, no-op generated writes should not retrigger dev loops, and page-local build-output edits should not force full output rendering.
- Accessibility: generated components should preserve semantic HTML and support focus restoration for partial updates.
- Localization: route and content generation should not assume one locale.
- Supportability: manifest output should include route, render mode, layouts, paths presence, and guards for debugging.
- Project shape: project-level compiler commands must fail fast when no config file is loaded.
- Full SPA runtime as the default experience.
- Mandatory full-page SSR.
- User-written JavaScript for normal forms, actions, and partial update flows.
- WASM islands as the default component runtime.
- Which remaining diagnostics, reports, and LSP metadata need exact source spans first?
- Should hybrid pages ever get additional cache policy syntax beyond page-level
cacheandrevalidate, or should that remain application-owned? - Should processor-emitted CSS become selectable named
cssinputs through a future page-aware processor contract? - Should build targets eventually support per-target addon and render-mode overrides?
- What generated adapter shape should execute
g:commandandg:querycontracts without replacing existing endpoint declarations prematurely?