Skip to content

Habit Tracker

The Habit Tracker fixture is the canonical end-to-end example. It exercises every Layer-2-carrying kind, every provenance pattern, and the full SenLang lowering.

Source: atomprd/examples/habit-tracker/.

  • 1 vision
  • 1 persona (Self-improver)
  • 1 module (Habits)
  • 1 entity (Habit) + 3 field atoms
  • 6 feature atoms
  • 1 ui_view (multi-screen: list / add / detail)
  • 1 rule (habit_name_not_empty)
  • 1 integration (Habits REST API)
  • 2 criterion atoms (initial-load empty state, streak increments on check-in)
  • 2 fixture atoms (empty state, streak-at-4)

Total: 21 atoms, ~12 relations.

out/
├── app.sen.json # 1 SenLang Document v0.3
├── app.sen.map.json # RFC-0009 source map
└── scenarios/
├── cri_initial_load_h31a.json
└── cri_streak_increments_b2c2.json

The .sen.json runs in @senlang/renderer-react with no build step. See it live at the cloud’s /demos/from-atomprd page (or run the fixture locally).

Terminal window
cd atomprd/examples/habit-tracker
bun install
bun run gen
# → writes out/
# Inspect
cat out/app.sen.json | jq .views.ui_habits_screen_a1b2
# Render in a browser
cd ../../packages/renderer-react/example
bun run dev
# Open http://localhost:5173 and import out/app.sen.json

The fixture is intentionally crafted to exercise all four provenance patterns:

AtomBehavior fieldsPatterns demonstrated
feat_create_habit_h14a4 stepsA on validate, C on call + setState
feat_load_habits_e5f61 stepB (empty Layer 2 → bridge default) at first; C after Pattern C run
ui_habits_screen_a1b23 screensC from rendered_by entity + viewType template
rul_name_not_empty_a1b22 enforced_atC from uses_rule reverse edges
cri_initial_load_h31a1 api_call, state_diffA — hand-authored
cri_streak_increments_b2c21 api_call, state_diffC from feature.behavior.steps
fix_empty_state_a1b2empty before/afterA
fix_streak_at_4_z9z9full before/afterD — LLM suggested, accepted

The full step-by-step authoring walkthrough lives at atomprd/docs/tutorial-habit-tracker.md. It covers:

  1. Creating the project in the cloud authoring UI.
  2. Adding vision + persona + module + entity + 3 fields.
  3. Adding 6 features. Filling Layer 1 first.
  4. Adding 1 multi-screen ui_view. Setting viewType=list and wiring rendered_by.
  5. Adding 1 rule with two enforcement sites.
  6. Adding 1 integration (HTTP REST).
  7. Adding 2 criteria with verifies edges.
  8. Adding 2 fixtures with linked_criteria.
  9. Running Pattern C on each Layer-2 kind. Reviewing the diff. Locking trusted fields.
  10. Filling the gaps with Pattern D for the one feature without a linked criterion.
  11. Generating the SenLang Document. Rendering it.

Total time: ~15 minutes end-to-end.

The reverse bridge @senlang/to-atomprd extracts a draft AtomPRD manifest from a working Sen Document. Useful if you start in SenLang and want to formalise the PRD shape after:

import { toAtomPrd } from "@senlang/to-atomprd";
import senDoc from "./my-app.sen.json";
const { manifest, warnings } = toAtomPrd(senDoc, { projectId: "imported" });
console.log(JSON.stringify(manifest, null, 2));

Atoms come back tagged provenance: C, source: "from-sen:...". vision, persona, module, criterion, fixture, runtime atoms are NOT inferred — they require human intent that doesn’t exist in the Sen Document.