|
| 1 | +# The AssertValues Manifesto |
| 2 | + |
| 3 | +**A method for solo developers and small teams building with AI: declare what matters, let the machine derive the rest.** |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## We Assert |
| 8 | + |
| 9 | +1. **Values before specifications.** A system built on "we never surprise the user" produces better code than one built on "validate all inputs on fields 1–47." Specs describe the *what*. Values describe the *why*. The why survives contact with reality. The what doesn't. This isn't either/or — specs still matter when precision matters. But values come first, because they shape which specs you need. |
| 10 | + |
| 11 | +2. **Philosophy is an input, not a decoration.** Values aren't something you frame on the wall after the code ships. They are the primary artifact you hand to the AI. They come first. They are the source code. |
| 12 | + |
| 13 | +3. **Propagation over enforcement.** Rules are brittle. A value, properly declared, shapes decisions no linter can reach—architecture, error handling, naming, defaults. You don't enforce "security-first." You assert it, and it flows into every layer without a checklist. |
| 14 | + |
| 15 | +4. **Humans declare, machines derive.** The human's job is to know what matters. The machine's job is to turn that into working software. This is the correct division of labor for the age we're entering. |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## What This Replaces |
| 20 | + |
| 21 | +The current loop: you prompt, you get code, you eyeball it, you prompt again. The feedback is structural—*move this here, rename that, add error handling.* You're iterating on *what the code should do* when you should be declaring *what the code should care about*. AssertValues breaks that loop. Be clear about what matters, and the implementation follows. |
| 22 | + |
| 23 | +There's a deeper problem this solves: **framework drift**. When you build fast with AI, the AI doesn't just write what you asked for — it writes what it thinks you'll need next. Service layers, adapter patterns, event buses, generic components. Each one is defensible in isolation. Together, they turn a weekend project into an enterprise scaffold that nobody asked for. Without values, there's no force pushing back. The complexity ratchet only turns one way. Values are the counter-force — they give the AI a reason to say *no* to its own instincts. |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## How Values Propagate Into Code |
| 28 | + |
| 29 | +A spec is pushing a single brick—it moves that brick and nothing else. A value is a lever at the top of the wall—one pull rearranges everything below it. |
| 30 | + |
| 31 | +**You declare a value** → the AI treats it as a constraint that applies everywhere, not a rule that applies once. When you assert "we value transparency," it chooses inspectable data structures. It writes errors that explain *why*. It avoids abstractions that obscure behavior. One value, dozens of coherent decisions. |
| 32 | + |
| 33 | +A spec is a point. A value is a vector—it has direction, and it applies force across the entire codebase. |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## Writing Values That Propagate |
| 38 | + |
| 39 | +Not all values are equal. A platitude biases nothing. A sharp value kills ten bad ideas before they start. |
| 40 | + |
| 41 | +| Platitude | Sharp Value | |
| 42 | +|---|---| |
| 43 | +| "We value quality" | "We never ship what we haven't tested" | |
| 44 | +| "Keep it simple" | "Three similar lines beat a premature abstraction" | |
| 45 | +| "Be user-friendly" | "Never surprise the user" | |
| 46 | +| "We care about performance" | "Every page loads in under 2 seconds on 3G" | |
| 47 | +| "Security matters" | "Assume every input is hostile" | |
| 48 | + |
| 49 | +**What makes a value propagate:** |
| 50 | +- **It constrains.** If it doesn't make you say no to something, it's not a value—it's a wish. |
| 51 | +- **It's specific enough to decide with.** "Never surprise the user" tells you what to do at a fork in the road. "Be user-friendly" doesn't. |
| 52 | +- **It's general enough to apply everywhere.** If it only matters in one file, it's a spec, not a value. |
| 53 | +- **Few beat many.** Three sharp values outperform fifteen that conflict. If your values need a priority matrix, you have too many. |
| 54 | + |
| 55 | +Writing sharp values is a skill. It requires knowing what trade-offs exist before you can choose a side. If you're not sure where to start, you're not alone — we're building something to help with that. |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +## A Worked Example |
| 60 | + |
| 61 | +You're building a marketplace. Sellers list products, buyers browse and purchase, reviews, payments, search, admin dashboard. Give a capable AI this prompt: |
| 62 | + |
| 63 | +``` |
| 64 | +Build a marketplace app. Sellers list products, buyers browse |
| 65 | +and purchase, with reviews. Next.js, TypeScript, Stripe, |
| 66 | +PostgreSQL with Drizzle ORM, Tailwind. Include auth, search, |
| 67 | +and an admin dashboard. |
| 68 | +``` |
| 69 | + |
| 70 | +A good AI will scaffold the full picture: `ProductService`, `OrderService`, `ReviewSystem` with moderation queue. A generic `DataTable` with sorting, filtering, and pagination abstracted upfront. An event bus for order-placed → send-email → update-inventory. Repository patterns wrapping Drizzle behind another layer. Auth middleware chains. A component library with 30 primitives. 60+ files before a single user flow works end-to-end. The skeleton looks impressive. The gap between scaffolded and shipped is where the real work lives. |
| 71 | + |
| 72 | +Now the same prompt, with five values loaded: |
| 73 | + |
| 74 | +``` |
| 75 | +VALUES.md |
| 76 | +
|
| 77 | +- "The best code is no code at all." — Jeff Atwood |
| 78 | + Every line you write is a line you must maintain, debug, |
| 79 | + and explain. Delete what you can. |
| 80 | +- "Make each program do one thing well." — Doug McIlroy |
| 81 | + Small, focused tools composed together are more powerful |
| 82 | + than monoliths. |
| 83 | +- "Duplication is far cheaper than the wrong abstraction." |
| 84 | + — Sandi Metz |
| 85 | + Tolerate repetition until the pattern is clear. |
| 86 | +- "Perfect is the enemy of good." — Voltaire |
| 87 | + Ship the working version. Improve it with real feedback. |
| 88 | +- "Never surprise the user." |
| 89 | + Every interaction should behave exactly as the user expects. |
| 90 | +``` |
| 91 | + |
| 92 | +~15 files. Deployable in one session. Stripe Checkout redirect instead of a custom payment flow — because "never surprise the user" means using the flow buyers already trust. SQL `ILIKE` for search instead of Elasticsearch — because Voltaire says ship it, upgrade when someone complains. Reviews inline on the product page, not a `ReviewAggregator` with sentiment analysis — because Atwood says every file must earn its existence. No repository layer wrapping Drizzle — because Metz says don't abstract until the pattern is clear. No generic `DataTable` — duplicate the table markup in admin and product list until a real shared shape emerges. |
| 93 | + |
| 94 | +Each value kills specific decisions. "Ship the working version" kills the analytics dashboard. "Every line is a line you must maintain" kills the event bus. "Tolerate repetition" kills the generic component. "Never surprise the user" picks Stripe's hosted checkout over a custom one that could break in unexpected ways. |
| 95 | + |
| 96 | +60 files vs. 15. Both handle the same prompt. One scaffolds for a future that may never arrive. The other ships for the present and evolves with real feedback. |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## Where This Breaks |
| 101 | + |
| 102 | +Levers trade precision for reach. AssertValues is not universal. It breaks in specific, predictable ways: |
| 103 | + |
| 104 | +**Regulatory compliance.** You can assert "patient safety" but the FDA needs field-level audit trails, specific error codes, and exact data retention windows. When a regulator is the audience—not an AI—specs aren't optional. They're the deliverable. |
| 105 | + |
| 106 | +**Protocol and integration work.** Implementing OAuth2, matching an API contract, parsing a wire format. The spec *is* the product. The bytes either match or they don't. There's nothing to philosophize about. |
| 107 | + |
| 108 | +**Performance-critical systems.** "We value responsiveness" won't produce a specific cache invalidation strategy or memory allocation pattern. When the problem is microseconds, you need specs, not values. |
| 109 | + |
| 110 | +**Debugging.** "The value propagated incorrectly" is harder to trace than "line 47 doesn't match the spec." Values make the causal chain longer and more opaque. This is a real cost, not a solvable problem. |
| 111 | + |
| 112 | +**Value conflicts at scale.** With three values, it's elegant. With fifteen across a large team, conflicts multiply. Kindness and transparency collide — the kind thing is to hide a scary error, the transparent thing is to show it. Resolving those collisions is the human's real job in this model, and it's hard. |
| 113 | + |
| 114 | +AssertValues is sharpest in small teams with high autonomy — solo developers, early-stage products, weekend projects that need to ship. The method may have a natural ceiling. Finding that ceiling is part of why we need engineers to test it. |
| 115 | + |
| 116 | +--- |
| 117 | + |
| 118 | +## Try It |
| 119 | + |
| 120 | +AssertValues needs proof, not persuasion. Build something real this way — declare values first, write zero specs, and see what the AI produces. |
| 121 | + |
| 122 | +If AI-assisted development feels powerful but aimless, this is the missing piece: *aim*. |
| 123 | + |
| 124 | +Assert your values. Let the code follow. |
0 commit comments