Skip to content

Roadmap phases 1–2: correctness/trust fixes + Tier 1 quick wins + Tier 2/3 quality foundation#234

Open
Marve10s wants to merge 28 commits into
mainfrom
roadmap-phase-1
Open

Roadmap phases 1–2: correctness/trust fixes + Tier 1 quick wins + Tier 2/3 quality foundation#234
Marve10s wants to merge 28 commits into
mainfrom
roadmap-phase-1

Conversation

@Marve10s

@Marve10s Marve10s commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Summary

Roadmap phases 1–2 from the multi-agent codebase analysis (docs/next-updates-roadmap.md). Large but cohesive: correctness/trust fixes, Tier‑1 quick wins, and the Tier‑2 quality foundation + contained Tier‑3 items. Every change is validated locally (suites + builds) and the Tier‑2/3 work was additionally put through an adversarial verification pass that caught two HIGH issues before merge.

Phase 1 — correctness/trust + Tier 1

🔴 Bugs

  1. Accurate scaffold status — install/db/build steps no longer swallow errors; the CLI reports "created with N unfinished setup step(s)" instead of false "success".
  2. Rollback of half-written projects on fatal error (BTS_KEEP_FAILED_OUTPUT=1 to keep).
  3. CI smoke gate now fails on any real step failure (was: only regex-matched "template" failures).
  4. check-types added to 17 generated packages + a coverage meta-test (closes the silent type-drift hole).

Tier 1
5. .NET ecosystem stat fixed (7→8), derived from the schema. 6. AGENTS.md generated by default (standard uppercase) + label/parity sync. 7. /showcase route shipped. 8. /analytics popular-stacks dashboard (new aggregation transform) + nav + sitemap. Plus react-native added to the per-PR smoke matrix (pr-core).

Phase 2 — Tier 2 quality foundation + Tier 3

  1. Property tests over the compatibility engine (fast-check). The design agent empirically disproved idempotence/convergence/constraint-satisfaction on the real engine and tested the invariants that actually hold (determinism, changes⟺adjusted, key-set preservation, well-formed issues, YOLO bypass).
  2. dotnet combo generator case (only generatable .NET values) + enabled in SUPPORTED_SMOKE_ECOSYSTEMS.
  3. Schema↔template coverage guard — every non-none enum value must be generatable or explicitly allowlisted; surfaces the real .NET selectable-but-not-generated gaps. Matching is scoped per-ecosystem so it has genuine teeth.
  4. API-literal drift guard — stripe apiVersion vs the pinned stripe major (fails closed on a major bump).
  5. bfs doctor — diagnoses a scaffolded project (bts.jsonc, deps, env vars, build/type checks); exits non-zero on failure so it works as a CI gate.
  6. MCP create-fields — exposes astroIntegration (fixes a latent bug where MCP-built Astro projects could never pick an integration), aiDocs, analytics, effect, versionChannel, and an optional targetDir.

Adversarial verification fixes (found by the verify workflow, not the green suites)

  • bfs doctor always exited 0 — trpc-cli's process.exit(0) overrode process.exitCode; now exits synchronously on failure (verified: EXIT:1).
  • Coverage guard lacked teeth — global substring matching false-positived aspnet-mvc/aspnet-blazor (via the display-name map) and dotnetDeploy:aws (via the SST template); dotnet matching is now scoped and the genuine gaps are allowlisted.
  • AGENTS.md default was incompletecreateVirtual + MCP_COMPATIBILITY_DEFAULTS still shipped only CLAUDE.md; completed (snapshots regenerated).
  • A types-suite regression from the AGENTS.md default (a hard-coded default in the stack-translation test) — fixed.

Validation

  • CLI suite 3287 pass / 0 fail · packages/types 92/0 · packages/template-generator 127/0 · web parity 27/0 · web build ✓ · testing/ tsc 0 errors · CLI/types builds + publint + lint clean.
  • Real installs: check-types passes on TS + react-native stacks; bfs doctor exit-code verified on real failing projects; MCP end-to-end smoke confirmed the Astro integration fix flows through; the dotnet combo generation verified SDK-free (CI runs the .NET build).

Notes / follow-ups

  • templates.generated.ts + dist are gitignored (built in CI); only sources are in the diff.
  • /showcase + /analytics build/typecheck and degrade gracefully, but their live data needs the Convex deployment populated + VITE_CONVEX_URL.
  • Bigger Tier‑3/4 features (full bfs add, bfs upgrade, vector DB category, golden-path SaaS templates, MCP structured outputs / recommend_stack) are deferred to their own design+validation cycles.

Marve10s added 8 commits June 18, 2026 15:22
…t on failure

Install, database-setup and native-build steps no longer swallow errors:
they return structured SetupStepResult values that createProject collects,
so the CLI reports 'created with N unfinished setup step(s)' plus a recovery
hint instead of a false 'created successfully'. A fatal scaffolding error now
removes the half-written directory it created (never a pre-existing/merge dir);
set BTS_KEEP_FAILED_OUTPUT=1 to keep partial output for debugging.
Previously only 'template'-classified failures set a non-zero exit, so genuine
compile/build/typecheck errors whose output did not match a curated
TEMPLATE_PATTERN were classified 'unknown' and silently passed CI. The smoke
runner now fails on any non-skipped, non-advisory step failure; transient
'environment' failures stay non-gating but are surfaced.
Adds a check-types script to 17 previously-unchecked generated packages
(db, auth server, all api servers, native, and react frontends) so the root
'turbo/bun check-types' actually type-checks them, closing the silent type-drift
hole that let heroui-native and stripe apiVersion regressions ship. A new
meta-test (check-types-coverage.test.ts) enforces that every generated package
either defines check-types or is explicitly allowlisted with a reason. Validated
via real install + check-types on TypeScript and react-native stacks.
ECOSYSTEM_COUNT was hardcoded to 7 and ECOSYSTEM_NAMES omitted .NET, so the
marketing/SEO surface (compare page, llms.txt, SoftwareApplication JSON-LD)
under-reported the product as 7 ecosystems. Now derived from the canonical
EcosystemSchema via a typed display-name Record, so the count and names can
never drift from the schema again.
…ase filename

Adds agents-md to the default aiDocs selection (alongside claude-md) so every
scaffold ships both CLAUDE.md and AGENTS.md by default — matching create-next-app
and the cross-tool AGENTS.md standard read by Codex/Cursor/Copilot/etc. Also
fixes the generated filename from non-standard 'Agents.md' to 'AGENTS.md'
(matters on case-sensitive filesystems), and syncs the display labels plus the
web builder default (DEFAULT_STACK_SELECTION) so CLI/web --yes parity holds.
Wires up the built-but-unrouted ShowcasePage (components/showcase). A server-side
loader fetches projects via Convex's lightweight HTTP client so the reactive
Convex React SDK stays out of the client entry chunk, and degrades to an empty
gallery when Convex is unconfigured/unreachable. Adds /showcase to the sitemap.
Adds a public /analytics route that aggregates the Convex telemetry (getStats +
getDailyStats) into the dashboard's data shape and renders the existing
prop-driven chart sections (metrics, timeline, stack-configuration, dev-tools).
Uses a server-side loader via Convex's HTTP client (no reactive Convex SDK in the
client bundle) and degrades to an empty dashboard when Convex is unconfigured;
the live event feed is intentionally left for a follow-up. Adds Showcase +
Analytics entries to the nav and /analytics to the sitemap.
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
better-fullstack-web Ready Ready Preview, Comment Jun 20, 2026 11:45am

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). labels Jun 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8e9ef19ce3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

() => ({
total: data.totalProjects,
avgPerDay: data.avgProjectsPerDay,
lastUpdatedIso: data.lastUpdated ?? "",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Provide a valid fallback before rendering empty analytics

When VITE_CONVEX_URL is unset, getStats returns null, or the Convex request is caught, loadAnalytics() returns EMPTY_ANALYTICS_DATA with lastUpdated: null; this line then passes "" as legacy.lastUpdatedIso. AnalyticsHeader formats that value unconditionally with format(new Date(legacy.lastUpdatedIso), ...), which throws on an invalid date, so /analytics crashes instead of degrading to the intended empty dashboard. Use a null-aware legacy date or omit the legacy timestamp when no analytics data exists.

Useful? React with 👍 / 👎.

The smoke preset suite had no react-native preset, so Expo was never
install+typechecked by the per-PR strict-smoke matrix (e2e-test.yaml's
smoke-strict-core runs --preset pr-core on every PR) — only occasionally via
nightly random generation — despite heroui-native drift being a recurring RN
bug. Adds a native-uniwind-trpc preset to pr-core; combined with the native
check-types added in this branch, every PR now type-checks an Expo frontend.
Validated end-to-end through the smoke harness (1/1 pass).
@Marve10s Marve10s changed the title Roadmap phase 1: correctness/trust fixes + Tier 1 quick wins Roadmap phase 1: correctness/trust fixes + Tier 1 quick wins + RN CI coverage Jun 18, 2026
Marve10s added 8 commits June 18, 2026 17:27
DEFAULT_STACK_SELECTION.aiDocs became ["claude-md","agents-md"] (AGENTS.md
default), so the stack-translation default test must compare against that.
Uses reversed order to also exercise the array-insensitive comparison.
…teral drift guards (Tier-2)

- compatibility-properties.test.ts: fast-check invariants (determinism, changes⟺adjusted, key-set preservation, well-formed issues, YOLO bypass) over the compatibility engine. Deliberately omits idempotence/convergence/constraint-satisfaction (empirically false on the real engine).
- schema-template-coverage.test.ts: asserts every non-none enum value is generatable (template dir / hbs conditional / processor ref), with a documented allowlist of the real selectable-but-not-generated gaps (mostly .NET stubs).
- api-literal-drift.test.ts: guards the stripe apiVersion literal against the pinned stripe major (fails closed on a major bump).
Diagnoses a scaffolded project: parses bts.jsonc, checks lockfile/node_modules,
required env vars (from .env.example), and runs the ecosystem build/type checks
(reusing runGeneratedChecks). Supports --skip-checks and --json.
bfs_create_project/bfs_plan_project now accept astroIntegration (fixes a latent
bug where MCP-built Astro projects could never pick an integration), aiDocs
(agents can request AGENTS.md/cursorrules, defaulting to the canonical
["claude-md","agents-md"]), analytics, effect, and versionChannel; and
bfs_create_project takes an optional targetDir parent directory.
createDraft had no dotnet case (returned undefined -> dotnet combos silently
skipped) and DEFAULT_ECOSYSTEM_WEIGHTS lacked a dotnet entry. Adds makeDotnetDraft
(only generatable .NET values: aspnet-minimal + minimal-api/graphql-hotchocolate/
grpc-dotnet, ef-core, xunit), the switch case, the weight, and dotnet to
SUPPORTED_SMOKE_ECOSYSTEMS so nightly random generation covers .NET.
trpc-cli calls process.exit(0) after a handler resolves, which silently
overrode doctor's process.exitCode=1 — so `bfs doctor && deploy` proceeded even
when the diagnosis failed. Exit synchronously with process.exit(1) on the
failure paths instead. Also report `signal X` when check-types is killed by a
signal (exitCode null).
…defaults)

The AGENTS.md default change missed two spots that still used ["claude-md"]:
the programmatic createVirtual API (index.ts) and MCP_COMPATIBILITY_DEFAULTS
(mcp.ts). Aligning createVirtual means every scaffold (incl. the snapshot
fixtures) now ships AGENTS.md by default — snapshots regenerated accordingly.
The global quoted-substring corpus false-positived dotnet values via the
graph-backend display-name map (aspnet-mvc/aspnet-blazor) and a cross-ecosystem
SST template (dotnetDeploy:aws), masking the exact selectable-but-not-generated
class the guard targets. dotnet categories now match only against dotnet-relevant
files; the genuinely-unimplemented .NET values are explicitly allowlisted.
@Marve10s Marve10s changed the title Roadmap phase 1: correctness/trust fixes + Tier 1 quick wins + RN CI coverage Roadmap phases 1–2: correctness/trust fixes + Tier 1 quick wins + Tier 2/3 quality foundation Jun 18, 2026
Marve10s added 3 commits June 18, 2026 20:09
New `github-actions` addon emits .github/workflows/ci.yml — install + lint
(when biome/oxlint is selected) + check-types + build — parameterized by package
manager (bun/pnpm/npm/yarn) and ecosystem (TS/rust/go/python, with a degrade
branch for the rest). Pure file emission via the addon handler's catch-all; no
new deps. Wired through schema/option-metadata/compatibility/stack-graph/
stack-translation + the CLI prompt + web option metadata (cli-builder-sync parity).
…stack tools

All tools now declare outputSchema/structuredContent (typed results) and
annotations (readOnlyHint on the read tools, non-read on create/add) so clients
can auto-approve reads and gate writes; bfs_check_compatibility also surfaces
evaluateCompatibility issues (code/optionId/suggestions). Adds bfs_list_presets
(mern/pern/t3/uniwind with stack summaries) and bfs_recommend_stack (deterministic
NL-brief -> compatibility-validated config + rationale + reproducible command;
e.g. 'SaaS with payments and auth' -> better-auth + stripe + postgres, matched to pern).
…, and CI for all ecosystems

Adversarial-verification fixes for the roadmap work:

- bfs_check_compatibility: filter evaluation.issues to the target
  ecosystem so a clean TS stack no longer reports cross-ecosystem
  false positives (hasIssues now reflects only relevant categories).
- bfs_recommend_stack: gate TS-web fields (frontend/backend/runtime/api)
  out of the summary for native-backend ecosystems, and add an explicit
  rationale note that brief keyword analysis is TypeScript-only.
- recommendStackFromBrief: treat admin/dashboard/portal/members/rbac/
  permissions/roles as auth signals (better-auth).
- config-prompts: allow the github-actions addon for non-TS ecosystems
  (was silently dropped alongside docker-compose).
- ci.yml addon: route react-native through the JS package-manager flow
  instead of the degrade echo; make pnpm/yarn install non-strict to match
  bun/npm; add real CI jobs for elixir, java (maven+gradle), and dotnet so
  the addon is useful across all 8 ecosystems.
…necone)

New TypeScript-ecosystem option category for AI embeddings / semantic search,
modeled on the existing backend-service categories (search/cms/fileStorage).

- types: VectorDbSchema + VECTOR_DB_VALUES; wired through option-metadata
  (TYPESCRIPT_CATEGORY_ORDER only), stack-translation (defaults, url keys,
  part-role maps, reproducible command), compatibility (convex/firebase/
  react-native force-none, standalone-backend requirement, TS-only gate),
  defaults, stack-graph (legacy single categories + defineTools), and the
  VectorDb type.
- template-generator: server-side lib templates for all four providers under
  templates/vector-db/<provider>/server/base/src/lib/vector.ts; handler +
  generator wiring, dependency processor, version pins, preflight rule.
- cli: --vector-db flag, interactive prompt (TS + standalone backend only),
  config-prompts resolver, MCP input schema + field docs, default-config
  and bts.jsonc round-trip, reproducible-command emission.
- web: TECH_OPTIONS + tech-icons + resource links + stack-builder category
  wiring so the builder exposes the category at parity with the CLI.

Each provider is a standalone service (pgvector connects to a dedicated
Postgres+pgvector instance via PGVECTOR_DATABASE_URL), so there is no coupling
to the project's primary database. Verified: all four generated projects
install + type-check clean against their real client SDKs.
- chroma/pinecone aren't on simpleicons (CDN 404 failed validate:tech-icons);
  ship local /icon/chroma.svg + /icon/pinecone.svg and point the registry +
  TECH_OPTIONS at them (qdrant/pgvector keep their valid simpleicons slugs).
- smoke/e2e presets hung on the new interactive vectorDb prompt because the
  command builder never emitted the flag; render buildCommand now emits
  --vector-db (withExplicitScalar → 'none' default) for the TypeScript flag
  set, mirroring --search.
Inline compatibility fixtures (and any caller) that predate the vectorDb
category omit the field entirely. The no-backend service override then saw
`undefined !== "none"` and reported defaulting it as a spurious adjustment,
breaking 'no change expected' assertions (e.g. Go better-auth stacks).
Default a missing vectorDb to 'none' up front so it is never mistaken for
an adjustment.
…lers import

Smoke-gating template bugs surfaced by the strict smoke gate:

- stripe: env server schema never declared STRIPE_SECRET_KEY/STRIPE_WEBHOOK_SECRET
  (only a polar block existed), and stripe.ts pinned apiVersion '2024-12-18'
  while stripe@^22 now types it as '2026-05-27.dahlia'. Add the stripe env
  block, bump the literal, and update the api-literal-drift guard's expected
  value for major 22.
- api package: graphql-yoga/ts-rest/garph contexts import better-auth types
  directly for any backend, but the dep was only added for express/fastify ->
  'Cannot find module better-auth' on e.g. adonisjs. Broaden the condition.
- go: cmd/server/main.go imported internal/handlers whenever an ORM was set,
  but handlers is only generated for gin/echo/fiber/chi web frameworks ->
  'package .../internal/handlers is not in std' for web-framework=none. Gate
  the handlers import on the web framework, decoupled from the database import.

Verified: stripe combo (solid+adonisjs+graphql-yoga+better-auth+stripe) and go
combo (sqlc+gqlgen+none) both install/tidy + type-check/build clean; gin still
imports handlers and builds.
…edis/celery

More smoke/e2e gating template bugs:

- vinext mode-toggle still used the radix `asChild` API while its dropdown-menu
  is @base-ui (render prop) like the other react frontends -> web typecheck
  failure. Switch to render={<Button .../>} to match next/react-vite/etc.
- better-auth index.ts always passed `database: env.DATABASE_URL`, but with
  database=none there is no DATABASE_URL in the env schema (auth typecheck
  failure, e.g. tanstack-start-fullstack). Gate the database field on
  database != none so better-auth falls back to its in-memory default.
- python pyproject pinned redis>=7.0.0, which is unsatisfiable with
  celery[redis] (kombu caps redis<6.5) -> uv sync failure. Lower the floor to
  redis>=5.0.1 so uv resolves 7.x normally and 6.4.x alongside celery.

Verified: vinext + tanstack-start type-check clean; python uv sync --all-extras
resolves; t3 builds + type-checks clean (its dev-check flake is not a template
bug).
Follow-up to the redis/celery pin fix — the RQ task-queue test hard-coded the
old redis>=7.0.0 floor.
…auth redis, go handlers import, dev-check timeout

Smoke / strict-smoke gating failures on PR #234:

- db/redis/base: ioredis zscore returns string|null but zset.score() was
  declared number|null -> db typecheck failure on *-redis combos. Await
  and coerce with Number().
- api/garph routers: createResolvers(ctx) only reads ctx when
  auth=better-auth -> TS6133 unused param when auth=none. Emit _ctx when
  not better-auth.
- api/garph context: context.ts only branched on
  hono/elysia/express/fastify/fets/adonisjs/self(next|tanstack|astro);
  nestjs (and self+other frontends) produced an empty file the generator
  skips -> "Cannot find module '../context'". Add a generic session-only
  fallback for uncovered backends/frontends.
- auth/better-auth: database=redis is a KV store, not a SQL adapter, but
  the orm=none / kysely / mikroorm blocks still passed
  `database: env.DATABASE_URL` (string) -> server typecheck failure
  ('string' not assignable to better-auth database). Exclude redis so
  better-auth falls back to its in-memory default.
- go cmd/server/main.go: internal/handlers was imported for any
  gin/echo/fiber/chi web framework, but handlers are only referenced when
  goOrm is gorm/sqlc/ent -> "imported and not used" for orm=none (e.g.
  echo+grpc-go). Gate the import on web framework AND orm.
- testing/dev-check: bump URL-detection (60s->120s) and total (90s->150s)
  timeouts so heavy Next presets (preset-t3) reliably print their dev URL
  under CI load.

Verified: the four failing TS/Go combos scaffold + install + type-check /
build clean; full apps/cli suite (./test/*.test.ts) 3290 pass / 0 fail.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant