TiculateTiculateOn track/nick/ticulateJSONGive feedback
Nick

Ticulate

architecture
Claude Code · 11 Aug

How it is built

One Next.js application serving three surfaces — the marketing site, the authenticated workspace, and published project pages — over a single Postgres database, with an MCP endpoint as the front door for agents. Published pages are server components only, so they render with JavaScript disabled.

ServiceWhat it doesLanguageRepoRuns on
ticulate-webMarketing, workspace, published pages and the MCP endpointTypeScript · Next.js 16this repolocal only, not yet deployed
ticulate-dbProjects, features, feedback, updates, people, audit trailPostgres 16src/db/schema.tsNeon · us-east-2
Where to start reading
Start here
src/server/agent-api.ts
Every capability an agent has. MCP and REST are both thin wrappers over it, so the two doors cannot drift.
The schema
src/db/schema.ts
14 tables. Document-shaped blocks are jsonb; list-shaped data is rows.
Write pipeline
src/server/writes.ts
recordWrite: snapshot the block, bump the revision, log the audit event. Human and agent writes both go through it.
Published page
src/sections/public-page/
Server components only. No "use client" belongs anywhere under here.
CSS sanitiser
src/server/theme-css.ts
Why agent-authored CSS is safe to serve. 33 adversarial tests in scripts/test-css-sanitizer.mjs.
The skill
skills/ticulate/SKILL.md
What an agent reads before touching a project.
Conventions an agent must follow
  • Every write — human or agent — goes through recordWrite, so the audit trail reads the same either way
  • Nothing under src/sections/public-page may be a client component; a published page must work with JavaScript off
  • Agent CSS is parsed with PostCSS and rewritten, never pattern-matched, and every selector is scoped to the page
  • Enum validation lives in agent-api rather than the tool schemas, because the REST dispatcher takes raw JSON
  • Grid and flex children get min-width:0 — an unbreakable string once pushed a whole column past the viewport
  • Block-replacing writes accept ifRevision so two agents cannot silently overwrite each other
Environments
localhttp://localhost:3000mainThe only environment so far — deploying is the next step
Open questions
Where does this deploy, and what is the migration story once the schema stops churning?
Blocked on a hosting decision
Answer this →
Votes are deduplicated by cookie, not identity — what does a stakeholder account look like?
Blocked on unassigned
Answer this →
Is the tagline "projects that articulate themselves" or "projects that speak for themselves"?
Blocked on a naming decision
Answer this →
NeonBetter AuthModel Context ProtocolDrizzle ORMLucidePostCSS