Product

Product Requirements

Current Status

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.

Status Legend

  • 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.

Requirements

IDRequirementPriorityStatusNotes
PRD-001Compile portable package-peer .gwdk files that declare package, optional page, route, guard, layout, blocks, and endpoints.HighPartialDiscovery, 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, and endpoint conflict diagnostics are implemented; full downstream migration to the IR remains planned.
PRD-002Default render mode must be spa.HighImplementedRoot RenderConfig.DefaultMode() defaults to gowdk.SPA.
PRD-003Support render modes spa, action, hybrid, and ssr.HighImplementedRoot RenderMode constants exist.
PRD-004Reject request-time page behavior unless the SSR feature is enabled in config or CLI options.HighImplementedinternal/compiler.ValidatePage emits missing_ssr_addon.
PRD-005Require paths {} for dynamic SPA routes.HighImplementedDynamic 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-006Keep typed actions available without SSR.HighPartialSPA 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, generated validation fragments for partial requests, partial fragment responses, same-package action handlers using no-input, typed value, typed pointer, or form.Values signatures returning response.Response, and generated CSRF token injection/validation by default unless Build.CSRF.Disabled is set. Direct file inputs and multipart generated action forms are rejected because uploads belong in user-owned API/server handlers. User-defined domain validation patterns remain in normal Go handlers.
PRD-007Treat server {} as request-time behavior requiring the SSR addon.HighImplementedPages with load infer request-time SSR and fail unless SSR is enabled.
PRD-008Keep runtime render core reusable across build-time pages, backend fragments, and request-time pages.HighImplementedruntime/render exists independently from addons/ssr; SSR is integrated through compiler/runtime hooks and enabled by feature registration.
PRD-009Generate build-output/prerender output for v0.1.HighPartialgowdk 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, 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 expression records and full component semantics remain planned.
PRD-010Provide CSS processor addon extension points without adding Tailwind to the compiler core or runtime core.HighPartialFeatureCSS, 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, AST-only config loading for built-in addons, executable config loading for external importable addons, 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-011Support embedded assets and one-binary serving.HighPartialaddons/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-012Support server fragments for partial updates without full-page SSR.MediumPartialaddons/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-013Complete request-time page rendering with server {}, guards, layouts, and error handling.MediumPartialaddons/ssr registers the SSR feature and provides load context aliases, 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; 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-014Add optional WASM islands after the core compiler and action flow are stable.LowPartialComponent-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-015Provide language tools for .gwdk token inspection, formatting, validation, manifest output, and LSP editor integration.HighImplementedinternal/lang, internal/lsp, internal/inspectreport, and CLI commands exist, including source-linked inspect tree, endpoint graph output, and Go binding inspection.
PRD-016Keep hybrid route behavior internal until a source contract is chosen.HighPartialHybrid route metadata exists internally; .gwdk source selects request-time rendering with server {} or go server {}.
PRD-017Define cache and revalidation behavior for static files, SPA routes, backend endpoints, partial responses, SSR routes, and hybrid pages.MediumPartialGenerated 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 HTML and SSR HTML responses. revalidate accepts positive second or duration values, requires cache, and compiles into a stale-while-revalidate=<seconds> Cache-Control directive for generated static SPA HTML and SSR HTML. Richer hybrid cache policy syntax remains planned.
PRD-018Escape generated HTML by default and require any raw HTML escape hatch to be explicit.HighImplementedRendering 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-019Provide optional rate limiting for request-time handlers without making it core.MediumImplementedFeatureRateLimit and addons/ratelimit expose 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-020Allow generated apps and binaries to package selected configured modules.HighImplementedBuild.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.
PRD-021Provide a dependency-free fast local development loop.HighImplementedgowdk 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-022Allow generated app output to compile to a WASM deploy artifact.MediumPartialgowdk 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-023Keep current documentation aligned with implemented CLI, config, compiler, language, routing, deployment, and examples.HighImplementedREADME.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-024Require project config before compiling or validating .gwdk code.HighImplementedcheck, audit, manifest, sitemap, routes, build, and dev require gowdk.config.go in the current directory or an explicit --config <file>, even when explicit .gwdk file paths are provided.
PRD-025Keep framework integrations optional and outside compiler/runtime core.MediumImplementedGenerated 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-026Provide declarative security posture and baseline audit gating.HighPartialinternal/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. 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; policy rules can require headers. gowdk audit --emit-tests writes readable standalone _test.go posture tests, and --run builds a temporary generated app and executes its generated app audit test through runtime/testkit; broader auth/session ownership, role fixture injection, and deeper browser/data-flow analysis remain planned or app-owned.
PRD-027Provide opt-in browser presentation-event fanout without adding WebSocket dependencies to the root module.MediumImplementedFeatureRealtime 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-028Provide compiler-validated realtime UI subscription metadata.MediumPartialADR 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 browser retry timing and drops events for full per-client buffers instead of blocking command execution, generated gowdk.js applies explicit 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 refetches the current document to replace matching non-subscribed query regions. Custom retry/backoff/replay, active session-change stream revocation, richer patch shapes, fragment/API-specific query execution, and route-specific refresh endpoints remain planned hardening work.
PRD-029Provide optional SEO build output for sitemap and robots files without making crawler policy core.MediumPartialaddons/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 and guardless default-denied pages are excluded and listed in gowdk-build-report.json. JSON-LD and request-time sitemap serving remain planned/out of scope for this slice.
PRD-030Provide dependency-free runtime trace primitives and opt-in generated app instrumentation.MediumPartialADR 0013 defines runtime/trace as the root-module observability core. It provides W3C-compatible trace/span IDs, traceparent propagation, 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, browser span ingest, and a self-contained local viewer. 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.

P0/P1/P2 Decision Backlog

This backlog records product decisions without treating deferred work as implemented.

AreaRequirement DirectionStatus
Markup languageExpand 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 slotsKeep 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 propsKeep 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 reactivityKeep 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 stateKeep 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 lifecycleKeep build {} build-time, server {} request-time, and actions/APIs/fragments as endpoint lanes; defer universal/browser-owned load policy.Partial
HybridKeep hybrid route metadata internal until the source contract is stable; defer streaming, data refresh, and non-HTTP revalidation.Partial
HooksCompose 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.
ErrorsKeep error for route-local SSR and action/API boundaries; define expected error types and layout boundaries later.Partial
Dev serverKeep 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, and hot-swaps changed JS island component roots when the dependency graph maps the change to the current page. Page/layout/source-set/runtime changes, unmatched component roots, WASM islands, and broader state-preserving HMR fall back to full reload or remain deferred to #424.
PlaygroundOwn 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.
RoutingAdd 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 APIsGenerate typed route-param accessors first; defer typed load/action data accessors until result contracts are stable.Partial — generated SSR and fragment request-time handlers attach raw route params through app.Params(ctx) and decoded typed params through app.TypedParams(ctx); per-route param structs and typed load/action result accessors remain planned.
Inline Go authoringAllow 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 both literal and executable config loading. Source-adjacent extraction remains planned.Partial
FormsKeep progressive-enhancement-first form behavior; full POST and enhanced POST share action result semantics; domain validation stays in user Go.Partial
APIsBroaden APIs through public request/response helpers and typed body/query helpers, not framework-specific adapters.Partial — addons/api provides strict JSON body decoding, typed query helpers, and JSON/error/no-content response helpers for current func(context.Context, *http.Request) (response.Response, error) handlers. Generated typed handler signatures, per-route result contracts, CORS policy, and richer examples remain planned.
Contract runtimeAdd 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, generated command event sinks, generated registries, generated worker replay helpers, 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, and current-document refresh for matching non-subscribed invalidated query regions are implemented. Separate worker/cron binary generators, fragment/API-specific query execution, remaining exact diagnostic spans, richer realtime patch shapes, durable retry operations, and editor-first visualizations remain planned outside the milestone-14 runtime contract.Implemented
ObservabilityKeep root tracing dependency-free while making generated instrumentation opt-in and debug-gated.Partial — runtime/trace provides W3C-compatible IDs, traceparent 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, bounded JSON/SSE local collection, browser ingest, and a self-contained viewer. 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, and production sampling/access policy remain app-owned.
CacheKeep cache and revalidate as HTTP cache policy; keep action-driven data refresh explicit through redirects, fragments, JSON, or reload responses.Partial — 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 HTML.
GuardsExtend 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 CSSMake component CSS explicit, compiler-scoped, and documented; Tailwind and processors remain optional.Partial
AccessibilityAdd 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 LSPExpand 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 scaffoldingAdd optional Go handler tests, generated app smoke tests, template/addon selection, and editable generated examples.Partial — gowdk init --tests writes an optional build smoke test, runtime/testkit provides HTTP scenario helpers for generated-handler tests plus 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, and generated-output/report determinism. Broader IR-generated endpoint test files and browser/E2E scaffolds remain planned.
Deployment and operationsPrefer 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.
Full-page hydrationKeep full-page hydration out of the repository core; use static pages, progressive enhancement, server fragments, and explicit islands.Intentionally out of scope
Island ergonomicsImprove 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 builtinsAdd 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 islandsKeep 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/offlineKeep 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.
ImagesDocument 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 discoveryStart 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 profilingDocument measurement for build time, output size, generated JS size, SSR/action latency, binary size, and cache behavior before adding automation.Partial
Migration guidesCore docs avoid migration-guide positioning during 0.x hardening. Native GOWDK concepts, examples, and diagnostics come first.Intentionally out of scope

Non-Functional Requirements

  • 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.

Out Of Scope

  • 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.

Open Questions

  • Which remaining diagnostics, reports, and LSP metadata need exact source spans first?
  • Should hybrid pages get additional cache policy syntax beyond page-level cache and revalidate?
  • Should processor-emitted CSS become selectable named css inputs 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:command and g:query contracts without replacing existing endpoint declarations prematurely?