@claudetools/tools 0.8.10 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codedna/generators/astro.d.ts +18 -0
- package/dist/codedna/generators/astro.js +91 -0
- package/dist/codedna/generators/authjs.d.ts +18 -0
- package/dist/codedna/generators/authjs.js +68 -0
- package/dist/codedna/generators/better-auth.d.ts +18 -0
- package/dist/codedna/generators/better-auth.js +62 -0
- package/dist/codedna/generators/drizzle-orm.d.ts +18 -0
- package/dist/codedna/generators/drizzle-orm.js +65 -0
- package/dist/codedna/generators/elysia-api.d.ts +12 -0
- package/dist/codedna/generators/elysia-api.js +64 -0
- package/dist/codedna/generators/hono-api.d.ts +12 -0
- package/dist/codedna/generators/hono-api.js +64 -0
- package/dist/codedna/generators/lucia-auth.d.ts +18 -0
- package/dist/codedna/generators/lucia-auth.js +69 -0
- package/dist/codedna/generators/prisma.d.ts +18 -0
- package/dist/codedna/generators/prisma.js +64 -0
- package/dist/codedna/generators/react-router-v7.d.ts +18 -0
- package/dist/codedna/generators/react-router-v7.js +77 -0
- package/dist/codedna/generators/react19-shadcn.d.ts +21 -0
- package/dist/codedna/generators/react19-shadcn.js +367 -0
- package/dist/codedna/generators/sveltekit.d.ts +18 -0
- package/dist/codedna/generators/sveltekit.js +73 -0
- package/dist/codedna/generators/tanstack-start-drizzle.d.ts +92 -0
- package/dist/codedna/generators/tanstack-start-drizzle.js +824 -0
- package/dist/codedna/generators/trpc-api.d.ts +12 -0
- package/dist/codedna/generators/trpc-api.js +64 -0
- package/dist/codedna/index.d.ts +31 -0
- package/dist/codedna/index.js +39 -0
- package/dist/codedna/kappa-api-generator.d.ts +89 -0
- package/dist/codedna/kappa-api-generator.js +493 -0
- package/dist/codedna/kappa-ast.d.ts +552 -0
- package/dist/codedna/kappa-ast.js +141 -0
- package/dist/codedna/kappa-cli.d.ts +2 -0
- package/dist/codedna/kappa-cli.js +302 -0
- package/dist/codedna/kappa-component-generator.d.ts +47 -0
- package/dist/codedna/kappa-component-generator.js +295 -0
- package/dist/codedna/kappa-design-generator.d.ts +52 -0
- package/dist/codedna/kappa-design-generator.js +365 -0
- package/dist/codedna/kappa-drizzle-generator.d.ts +45 -0
- package/dist/codedna/kappa-drizzle-generator.js +355 -0
- package/dist/codedna/kappa-form-generator.d.ts +51 -0
- package/dist/codedna/kappa-form-generator.js +319 -0
- package/dist/codedna/kappa-lexer.d.ts +268 -0
- package/dist/codedna/kappa-lexer.js +757 -0
- package/dist/codedna/kappa-page-generator.d.ts +57 -0
- package/dist/codedna/kappa-page-generator.js +338 -0
- package/dist/codedna/kappa-parser.d.ts +261 -0
- package/dist/codedna/kappa-parser.js +2547 -0
- package/dist/codedna/kappa-provenance.d.ts +101 -0
- package/dist/codedna/kappa-provenance.js +199 -0
- package/dist/codedna/kappa-types-generator.d.ts +37 -0
- package/dist/codedna/kappa-types-generator.js +159 -0
- package/dist/codedna/kappa-validator.d.ts +86 -0
- package/dist/codedna/kappa-validator.js +638 -0
- package/dist/codedna/kappa-zod-generator.d.ts +32 -0
- package/dist/codedna/kappa-zod-generator.js +216 -0
- package/dist/handlers/codedna-handlers.d.ts +1 -1
- package/dist/handlers/kappa-handlers.d.ts +116 -0
- package/dist/handlers/kappa-handlers.js +465 -0
- package/dist/handlers/tool-handlers.js +121 -0
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.js +166 -9
- package/dist/tools.js +199 -0
- package/docs/research/2026-01-02-codedna-il-specification.md +639 -0
- package/docs/research/2026-01-02-codedna-v2-research.md +943 -0
- package/docs/research/2026-01-02-computation-foundations.md +564 -0
- package/docs/research/2026-01-02-hardware-description.md +814 -0
- package/docs/research/2026-01-02-kappa-specification.md +697 -0
- package/docs/research/2026-01-02-kappa-tanstack-example.md +527 -0
- package/docs/research/2026-01-02-kappa-v2-synthesis.md +406 -0
- package/docs/research/2026-01-02-kappa-v2.5-specification.md +1218 -0
- package/docs/research/2026-01-02-kappa-v3-specification.md +1864 -0
- package/docs/research/2026-01-02-kappa-whitepaper.md +662 -0
- package/docs/research/2026-01-02-logic-constraint.md +731 -0
- package/docs/research/2026-01-02-quantum-computation.md +635 -0
- package/package.json +4 -2
|
@@ -0,0 +1,1864 @@
|
|
|
1
|
+
# Kappa v3: Outcome-Oriented Programming
|
|
2
|
+
|
|
3
|
+
**Version:** 3.0.0-alpha
|
|
4
|
+
**Date:** 2026-01-02
|
|
5
|
+
**Status:** Paradigm Definition
|
|
6
|
+
**Authors:** Owen Innes, Claude (Anthropic)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Abstract
|
|
11
|
+
|
|
12
|
+
Kappa v3 introduces **Outcome-Oriented Programming (OOP2)** — a paradigm where developers specify desired outcomes, constraints, and design intent rather than implementation details. A constraint solver synthesises optimal implementations that satisfy all requirements. This document specifies the complete language, constraint system, design intent model, and synthesis engine.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Part I: The Paradigm
|
|
17
|
+
|
|
18
|
+
### 1.1 The Evolution
|
|
19
|
+
|
|
20
|
+
| Generation | You Specify | System Does |
|
|
21
|
+
|------------|-------------|-------------|
|
|
22
|
+
| **Imperative** (C, Python) | How to do it step by step | Execute instructions |
|
|
23
|
+
| **Declarative** (SQL, React) | What result you want | Figure out how |
|
|
24
|
+
| **Specification** (Kappa v1-v2) | What code structure you want | Generate boilerplate |
|
|
25
|
+
| **Outcome-Oriented** (Kappa v3) | What success looks like | Synthesise everything |
|
|
26
|
+
|
|
27
|
+
### 1.2 The Core Insight
|
|
28
|
+
|
|
29
|
+
Traditional programming:
|
|
30
|
+
```
|
|
31
|
+
Developer → Code → Compiler → Binary → Outcome
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Outcome-Oriented:
|
|
35
|
+
```
|
|
36
|
+
Developer → Outcomes + Constraints → Solver → Code → Compiler → Binary
|
|
37
|
+
↑
|
|
38
|
+
Verify outcomes met
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
You define the destination. The system finds the path.
|
|
42
|
+
|
|
43
|
+
### 1.3 The Five Pillars
|
|
44
|
+
|
|
45
|
+
1. **Goals** — What you want to achieve (business outcomes)
|
|
46
|
+
2. **Constraints** — What must be true (non-negotiable requirements)
|
|
47
|
+
3. **Entities** — What exists in your domain (data model + behavior)
|
|
48
|
+
4. **Journeys** — How users accomplish tasks (interaction flows)
|
|
49
|
+
5. **Design Intent** — How it should feel (aesthetic + UX goals)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Part II: Language Specification
|
|
54
|
+
|
|
55
|
+
### 2.1 Goals
|
|
56
|
+
|
|
57
|
+
Goals express desired business outcomes, not technical implementation.
|
|
58
|
+
|
|
59
|
+
```kappa
|
|
60
|
+
goal <Name> {
|
|
61
|
+
# What should be possible
|
|
62
|
+
enable: <capability>, <capability>, ...
|
|
63
|
+
|
|
64
|
+
# What must be true
|
|
65
|
+
ensure: <invariant>, <invariant>, ...
|
|
66
|
+
|
|
67
|
+
# Compliance requirements
|
|
68
|
+
comply: <standard>, <standard>, ...
|
|
69
|
+
|
|
70
|
+
# Audit requirements
|
|
71
|
+
audit: <event_pattern>
|
|
72
|
+
|
|
73
|
+
# Performance requirements
|
|
74
|
+
perform: <metric> <comparator> <value>
|
|
75
|
+
|
|
76
|
+
# Success metrics
|
|
77
|
+
measure: <metric> -> <target>
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Example:**
|
|
82
|
+
|
|
83
|
+
```kappa
|
|
84
|
+
goal UserAuthentication {
|
|
85
|
+
enable:
|
|
86
|
+
users can sign_up with email and password,
|
|
87
|
+
users can log_in with credentials,
|
|
88
|
+
users can reset_password via email,
|
|
89
|
+
users can enable two_factor_auth,
|
|
90
|
+
admins can impersonate users (with audit)
|
|
91
|
+
|
|
92
|
+
ensure:
|
|
93
|
+
no duplicate accounts (by email),
|
|
94
|
+
passwords are never stored plaintext,
|
|
95
|
+
sessions expire after inactivity,
|
|
96
|
+
failed attempts trigger lockout (5 attempts, 15 min)
|
|
97
|
+
|
|
98
|
+
comply: GDPR, SOC2, OWASP_Top_10
|
|
99
|
+
|
|
100
|
+
audit: all authentication events with ip, user_agent, outcome
|
|
101
|
+
|
|
102
|
+
perform:
|
|
103
|
+
login p99 < 200ms,
|
|
104
|
+
signup p99 < 500ms
|
|
105
|
+
|
|
106
|
+
measure:
|
|
107
|
+
signup_completion_rate -> > 80%,
|
|
108
|
+
login_success_rate -> > 95%
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
goal RealtimeCollaboration {
|
|
112
|
+
enable:
|
|
113
|
+
multiple users can edit same document simultaneously,
|
|
114
|
+
users see each other's cursors and selections,
|
|
115
|
+
changes sync within 100ms,
|
|
116
|
+
offline edits merge on reconnect
|
|
117
|
+
|
|
118
|
+
ensure:
|
|
119
|
+
no data loss on conflict (CRDT),
|
|
120
|
+
eventual consistency,
|
|
121
|
+
causal ordering preserved
|
|
122
|
+
|
|
123
|
+
perform:
|
|
124
|
+
sync_latency p99 < 100ms,
|
|
125
|
+
merge_time < 50ms
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 2.2 Constraints
|
|
130
|
+
|
|
131
|
+
Constraints are non-negotiable requirements that ALL generated code must satisfy.
|
|
132
|
+
|
|
133
|
+
```kappa
|
|
134
|
+
constraints <Category> {
|
|
135
|
+
<aspect>: <requirement>
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Built-in constraint categories:**
|
|
140
|
+
|
|
141
|
+
```kappa
|
|
142
|
+
constraints Security {
|
|
143
|
+
# Authentication
|
|
144
|
+
passwords: hashed(<algorithm>), min_length(<n>), require(<complexity>), breach_check
|
|
145
|
+
sessions: <type>, expires(<duration>), refresh(<strategy>), revokable
|
|
146
|
+
tokens: <type>, signed(<algorithm>), expires(<duration>)
|
|
147
|
+
|
|
148
|
+
# Input handling
|
|
149
|
+
inputs: sanitized, validated, parameterized # SQL injection prevention
|
|
150
|
+
uploads: scanned, size_limit(<n>), type_whitelist([...])
|
|
151
|
+
|
|
152
|
+
# Rate limiting
|
|
153
|
+
rate_limit: <n> per <duration> per <scope>
|
|
154
|
+
|
|
155
|
+
# Encryption
|
|
156
|
+
data_at_rest: encrypted(<algorithm>)
|
|
157
|
+
data_in_transit: tls(<min_version>)
|
|
158
|
+
|
|
159
|
+
# Headers
|
|
160
|
+
headers: csp(<policy>), hsts, x_frame_options(<value>)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
constraints Privacy {
|
|
164
|
+
pii_fields: [<field_patterns>]
|
|
165
|
+
retention: <duration> then <action>
|
|
166
|
+
consent: required_for([<purposes>])
|
|
167
|
+
export: available_within(<duration>) # GDPR right to portability
|
|
168
|
+
deletion: complete_within(<duration>) # GDPR right to erasure
|
|
169
|
+
anonymization: <strategy> for analytics
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
constraints Accessibility {
|
|
173
|
+
level: WCAG_A | WCAG_AA | WCAG_AAA
|
|
174
|
+
contrast: min(<ratio>)
|
|
175
|
+
motion: respect_prefers_reduced
|
|
176
|
+
keyboard: full_navigation
|
|
177
|
+
screen_reader: aria_complete
|
|
178
|
+
focus: visible_always
|
|
179
|
+
text: resizable_to(<percentage>)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
constraints Performance {
|
|
183
|
+
# Core Web Vitals
|
|
184
|
+
lcp: < <duration> # Largest Contentful Paint
|
|
185
|
+
fid: < <duration> # First Input Delay
|
|
186
|
+
cls: < <value> # Cumulative Layout Shift
|
|
187
|
+
|
|
188
|
+
# Bundle
|
|
189
|
+
initial_bundle: < <size>
|
|
190
|
+
lazy_threshold: > <size> # Code-split if larger
|
|
191
|
+
|
|
192
|
+
# API
|
|
193
|
+
api_p50: < <duration>
|
|
194
|
+
api_p99: < <duration>
|
|
195
|
+
|
|
196
|
+
# Database
|
|
197
|
+
query_limit: < <duration>
|
|
198
|
+
n_plus_one: forbidden
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
constraints Reliability {
|
|
202
|
+
availability: <percentage> # e.g., 99.9%
|
|
203
|
+
rto: < <duration> # Recovery Time Objective
|
|
204
|
+
rpo: < <duration> # Recovery Point Objective
|
|
205
|
+
backup: every(<duration>), retain(<duration>)
|
|
206
|
+
failover: automatic within(<duration>)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
constraints Cost {
|
|
210
|
+
infrastructure: < <amount> per <period>
|
|
211
|
+
per_user: < <amount> per <period>
|
|
212
|
+
scale_strategy: <horizontal | vertical | serverless>
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 2.3 Entities
|
|
217
|
+
|
|
218
|
+
Entities define your domain model with behavior, not just data.
|
|
219
|
+
|
|
220
|
+
```kappa
|
|
221
|
+
entity <Name> {
|
|
222
|
+
# Identity
|
|
223
|
+
identify_by: <field> | composite(<fields>)
|
|
224
|
+
|
|
225
|
+
# Attributes
|
|
226
|
+
<name>: <type> [= <default>] [<modifiers>]
|
|
227
|
+
|
|
228
|
+
# Relationships
|
|
229
|
+
belongs_to: <Entity> [(as <role>)]
|
|
230
|
+
has_one: <Entity> [(as <role>)]
|
|
231
|
+
has_many: <Entity> [(as <role>)] [limit(<n>)]
|
|
232
|
+
|
|
233
|
+
# Capabilities (who can do what)
|
|
234
|
+
can: <action> [when <condition>]
|
|
235
|
+
cannot: <action> [unless <condition>]
|
|
236
|
+
|
|
237
|
+
# Visibility
|
|
238
|
+
visible_to: <roles | conditions>
|
|
239
|
+
<field>.visible_to: <roles | conditions>
|
|
240
|
+
|
|
241
|
+
# Editability
|
|
242
|
+
editable_by: <roles | conditions>
|
|
243
|
+
<field>.editable_by: <roles | conditions>
|
|
244
|
+
|
|
245
|
+
# State machine
|
|
246
|
+
states: <state> -> <state> [-> <state>]*
|
|
247
|
+
transitions:
|
|
248
|
+
<from> -> <to>: when <condition>, by <roles>
|
|
249
|
+
|
|
250
|
+
# Lifecycle hooks
|
|
251
|
+
on_create: <action>, <action>, ...
|
|
252
|
+
on_update: <action>, <action>, ...
|
|
253
|
+
on_delete: <action>, <action>, ...
|
|
254
|
+
on_<transition>: <action>, <action>, ...
|
|
255
|
+
|
|
256
|
+
# Computeds
|
|
257
|
+
compute <name>: <expression>
|
|
258
|
+
|
|
259
|
+
# Validations
|
|
260
|
+
validate: <expression> else <error>
|
|
261
|
+
|
|
262
|
+
# Indexes
|
|
263
|
+
index: <fields> [unique] [where <condition>]
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Example:**
|
|
268
|
+
|
|
269
|
+
```kappa
|
|
270
|
+
entity User {
|
|
271
|
+
identify_by: email
|
|
272
|
+
|
|
273
|
+
# Attributes
|
|
274
|
+
email: email, unique, immutable
|
|
275
|
+
name: string(2..100)
|
|
276
|
+
avatar: image?, max_size(5mb)
|
|
277
|
+
role: Role = member
|
|
278
|
+
status: active | suspended | deleted = active
|
|
279
|
+
last_login: timestamp?
|
|
280
|
+
mfa_enabled: bool = false
|
|
281
|
+
mfa_secret: string?, encrypted, internal # never exposed to API
|
|
282
|
+
|
|
283
|
+
# Relationships
|
|
284
|
+
has_many: Project (as owner), limit(100)
|
|
285
|
+
has_many: Membership
|
|
286
|
+
has_many: Project through Membership (as member)
|
|
287
|
+
has_many: AuditLog
|
|
288
|
+
|
|
289
|
+
# Capabilities
|
|
290
|
+
can: create Project
|
|
291
|
+
can: read Project when member_of(Project) or owner_of(Project)
|
|
292
|
+
can: update Project when owner_of(Project) or role_in(Project, editor)
|
|
293
|
+
can: delete Project when owner_of(Project)
|
|
294
|
+
can: invite_to Project when owner_of(Project)
|
|
295
|
+
cannot: delete self when has_owned_projects # must transfer first
|
|
296
|
+
|
|
297
|
+
# Visibility
|
|
298
|
+
visible_to: self, admin
|
|
299
|
+
email.visible_to: self, admin, members_of_shared_projects
|
|
300
|
+
mfa_secret.visible_to: none # internal only
|
|
301
|
+
|
|
302
|
+
# State
|
|
303
|
+
states: active -> suspended -> deleted
|
|
304
|
+
transitions:
|
|
305
|
+
active -> suspended: by admin, on_transition notify(user, "account_suspended")
|
|
306
|
+
suspended -> active: by admin
|
|
307
|
+
suspended -> deleted: by admin, after(30 days)
|
|
308
|
+
active -> deleted: by self, requires confirmation
|
|
309
|
+
|
|
310
|
+
# Lifecycle
|
|
311
|
+
on_create:
|
|
312
|
+
send_email(welcome_template),
|
|
313
|
+
log_audit(user_created),
|
|
314
|
+
enqueue(onboarding_sequence)
|
|
315
|
+
|
|
316
|
+
on_delete:
|
|
317
|
+
anonymize(email -> "deleted_{id}@anon.local"),
|
|
318
|
+
anonymize(name -> "Deleted User"),
|
|
319
|
+
delete(avatar),
|
|
320
|
+
transfer_or_delete(owned_projects),
|
|
321
|
+
log_audit(user_deleted, retain: 7 years) # legal requirement
|
|
322
|
+
|
|
323
|
+
# Computed
|
|
324
|
+
compute display_name: name or email.local_part
|
|
325
|
+
compute is_admin: role == admin
|
|
326
|
+
compute project_count: projects.count
|
|
327
|
+
|
|
328
|
+
# Validations
|
|
329
|
+
validate: email.domain not in disposable_domains else "Please use a permanent email"
|
|
330
|
+
validate: name !~ /<script>/i else "Invalid characters in name"
|
|
331
|
+
|
|
332
|
+
# Indexes
|
|
333
|
+
index: email, unique
|
|
334
|
+
index: [status, last_login] where status == active # for cleanup queries
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
entity Project {
|
|
338
|
+
identify_by: slug (scoped_to owner)
|
|
339
|
+
|
|
340
|
+
name: string(1..100)
|
|
341
|
+
slug: slug, auto_from(name)
|
|
342
|
+
description: markdown?, max_length(10000)
|
|
343
|
+
visibility: public | private | team = private
|
|
344
|
+
status: draft | active | archived = draft
|
|
345
|
+
|
|
346
|
+
belongs_to: User (as owner)
|
|
347
|
+
has_many: Membership
|
|
348
|
+
has_many: User through Membership (as members)
|
|
349
|
+
has_many: Task, ordered_by(position)
|
|
350
|
+
|
|
351
|
+
# Capabilities contextual to relationship
|
|
352
|
+
owner can: read, update, delete, archive, transfer_ownership, manage_members
|
|
353
|
+
member(editor) can: read, update, create_task, update_task
|
|
354
|
+
member(viewer) can: read
|
|
355
|
+
public: anyone can read when visibility == public
|
|
356
|
+
|
|
357
|
+
states: draft -> active -> archived
|
|
358
|
+
transitions:
|
|
359
|
+
draft -> active: by owner
|
|
360
|
+
active -> archived: by owner, on_transition notify_members("project_archived")
|
|
361
|
+
archived -> active: by owner, within(30 days) # after 30 days, cannot restore
|
|
362
|
+
|
|
363
|
+
on_delete:
|
|
364
|
+
require: no active_tasks or force_confirmed,
|
|
365
|
+
delete: all tasks (cascade),
|
|
366
|
+
notify: all members,
|
|
367
|
+
log_audit: project_deleted
|
|
368
|
+
|
|
369
|
+
compute member_count: memberships.count
|
|
370
|
+
compute task_count: tasks.count
|
|
371
|
+
compute completion_rate: tasks.where(done).count / tasks.count
|
|
372
|
+
|
|
373
|
+
index: [owner_id, slug], unique
|
|
374
|
+
index: [visibility, status] where visibility == public
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
entity Membership {
|
|
378
|
+
identify_by: composite(user, project)
|
|
379
|
+
|
|
380
|
+
belongs_to: User
|
|
381
|
+
belongs_to: Project
|
|
382
|
+
|
|
383
|
+
role: owner | editor | viewer
|
|
384
|
+
invited_by: User?
|
|
385
|
+
invited_at: timestamp = now
|
|
386
|
+
accepted_at: timestamp?
|
|
387
|
+
|
|
388
|
+
states: pending -> accepted -> revoked
|
|
389
|
+
transitions:
|
|
390
|
+
pending -> accepted: by self (the invited user)
|
|
391
|
+
pending -> revoked: by inviter or project_owner
|
|
392
|
+
accepted -> revoked: by project_owner or self
|
|
393
|
+
|
|
394
|
+
validate: user != project.owner else "Owner cannot have membership"
|
|
395
|
+
validate: role != owner else "Only one owner allowed, use transfer"
|
|
396
|
+
|
|
397
|
+
on_create: send_email(invitation_template) when state == pending
|
|
398
|
+
on_transition(accepted): log_audit(member_joined)
|
|
399
|
+
on_transition(revoked): log_audit(member_removed)
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### 2.4 Journeys
|
|
404
|
+
|
|
405
|
+
Journeys define how users accomplish goals, not routes or pages.
|
|
406
|
+
|
|
407
|
+
```kappa
|
|
408
|
+
journey <Name> {
|
|
409
|
+
# Who takes this journey
|
|
410
|
+
actor: <role | condition>
|
|
411
|
+
|
|
412
|
+
# What triggers entry
|
|
413
|
+
entry: <trigger>
|
|
414
|
+
|
|
415
|
+
# Steps (not pages - semantic steps)
|
|
416
|
+
steps: <step> -> <step> [-> <step>]*
|
|
417
|
+
|
|
418
|
+
# Step definitions
|
|
419
|
+
step <name> {
|
|
420
|
+
goal: <what user accomplishes>
|
|
421
|
+
show: <information needed>
|
|
422
|
+
collect: <input needed>
|
|
423
|
+
validate: <constraints on input>
|
|
424
|
+
on_complete: <actions>
|
|
425
|
+
next: <step> [when <condition>] | done
|
|
426
|
+
alternatives: <step> [when <condition>]
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
# Optimization targets
|
|
430
|
+
optimize_for: <metric>
|
|
431
|
+
|
|
432
|
+
# Failure handling
|
|
433
|
+
on_drop_off(<step>): <action>
|
|
434
|
+
on_error: <action>
|
|
435
|
+
|
|
436
|
+
# Testing
|
|
437
|
+
test: <scenario> -> <expected_outcome>
|
|
438
|
+
|
|
439
|
+
# Experimentation
|
|
440
|
+
experiment(<name>) {
|
|
441
|
+
control: <variant>
|
|
442
|
+
variants: <variant>, <variant>
|
|
443
|
+
measure: <metric>
|
|
444
|
+
significance: <threshold>
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
**Example:**
|
|
450
|
+
|
|
451
|
+
```kappa
|
|
452
|
+
journey Onboarding {
|
|
453
|
+
actor: unauthenticated user
|
|
454
|
+
entry: visit(landing_page) or referral_link or direct(signup_url)
|
|
455
|
+
|
|
456
|
+
steps: land -> signup -> verify_email -> create_workspace -> invite_team -> done
|
|
457
|
+
|
|
458
|
+
step land {
|
|
459
|
+
goal: understand value proposition
|
|
460
|
+
show: hero, features, social_proof, pricing_preview
|
|
461
|
+
collect: nothing # awareness only
|
|
462
|
+
next: signup when cta_clicked
|
|
463
|
+
track: time_on_page, scroll_depth, cta_hover
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
step signup {
|
|
467
|
+
goal: create account
|
|
468
|
+
show: signup_form, oauth_options, terms_link
|
|
469
|
+
collect: {
|
|
470
|
+
email: email, required
|
|
471
|
+
password: password, required, strength_meter
|
|
472
|
+
name: string, required
|
|
473
|
+
}
|
|
474
|
+
validate:
|
|
475
|
+
email not in existing_users else "Already have an account? [Log in]",
|
|
476
|
+
password.strength >= medium else "Please choose a stronger password"
|
|
477
|
+
on_complete:
|
|
478
|
+
create(User),
|
|
479
|
+
send_verification_email,
|
|
480
|
+
set_cookie(session),
|
|
481
|
+
track(signup_completed)
|
|
482
|
+
next: verify_email
|
|
483
|
+
alternatives: oauth_flow when oauth_clicked
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
step verify_email {
|
|
487
|
+
goal: confirm email ownership
|
|
488
|
+
show: check_email_message, resend_option, change_email_option
|
|
489
|
+
collect: verification_code(6 digits) or magic_link_click
|
|
490
|
+
validate: code matches sent_code and not expired(10 min)
|
|
491
|
+
on_complete:
|
|
492
|
+
mark_verified,
|
|
493
|
+
track(email_verified)
|
|
494
|
+
next: create_workspace
|
|
495
|
+
timeout: 24 hours -> send_reminder, 72 hours -> expire_account
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
step create_workspace {
|
|
499
|
+
goal: set up first project space
|
|
500
|
+
show: workspace_form, template_options, skip_option
|
|
501
|
+
collect: {
|
|
502
|
+
workspace_name: string, required, suggested(from user.name + "'s Workspace")
|
|
503
|
+
template: template_id?, recommended(blank)
|
|
504
|
+
}
|
|
505
|
+
on_complete:
|
|
506
|
+
create(Project, from: template),
|
|
507
|
+
assign_owner(current_user),
|
|
508
|
+
track(workspace_created, template: selected_template)
|
|
509
|
+
next: invite_team
|
|
510
|
+
alternatives: done when skip_clicked # allow skipping
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
step invite_team {
|
|
514
|
+
goal: add collaborators (activation metric)
|
|
515
|
+
show: invite_form, skip_option, benefits_of_collaboration
|
|
516
|
+
collect: {
|
|
517
|
+
emails: [email], min(0), max(10)
|
|
518
|
+
message: string?, default(standard_invite_message)
|
|
519
|
+
}
|
|
520
|
+
on_complete:
|
|
521
|
+
send_invitations(emails),
|
|
522
|
+
track(invitations_sent, count: emails.length)
|
|
523
|
+
next: done
|
|
524
|
+
skip_allowed: true # but track it
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
step done {
|
|
528
|
+
goal: start using product
|
|
529
|
+
show: success_message, quick_start_guide, first_action_prompt
|
|
530
|
+
on_complete:
|
|
531
|
+
track(onboarding_completed, duration: journey_time),
|
|
532
|
+
trigger(product_tour) when first_visit
|
|
533
|
+
next: dashboard
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
optimize_for: completion_rate, time_to_value
|
|
537
|
+
|
|
538
|
+
on_drop_off(signup):
|
|
539
|
+
track(signup_abandoned),
|
|
540
|
+
cookie(intent),
|
|
541
|
+
retarget_after(24 hours) when email_collected
|
|
542
|
+
|
|
543
|
+
on_drop_off(verify_email):
|
|
544
|
+
send_reminder(after: 1 hour),
|
|
545
|
+
send_reminder(after: 24 hours),
|
|
546
|
+
send_final_notice(after: 48 hours)
|
|
547
|
+
|
|
548
|
+
on_drop_off(invite_team):
|
|
549
|
+
track(skipped_invites),
|
|
550
|
+
prompt_later(after: 3 days) in_app
|
|
551
|
+
|
|
552
|
+
experiment(signup_flow) {
|
|
553
|
+
control: email_first
|
|
554
|
+
variants:
|
|
555
|
+
oauth_prominent: show oauth buttons first, email below
|
|
556
|
+
social_proof: add testimonial next to form
|
|
557
|
+
minimal: remove all but essential fields
|
|
558
|
+
measure: signup_completion_rate, time_to_complete
|
|
559
|
+
significance: 95%
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
test: complete_flow -> user.verified and project.exists
|
|
563
|
+
test: oauth_google -> user.verified(immediate) and provider(google)
|
|
564
|
+
test: drop_at_verify -> reminder_sent(after: 1 hour)
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
journey TaskCompletion {
|
|
568
|
+
actor: authenticated project_member
|
|
569
|
+
entry: view_task or notification_click or search_result
|
|
570
|
+
|
|
571
|
+
steps: view -> work -> complete -> celebrate
|
|
572
|
+
|
|
573
|
+
step view {
|
|
574
|
+
goal: understand what needs to be done
|
|
575
|
+
show: task_details, attachments, comments, related_tasks, assignee, due_date
|
|
576
|
+
collect: nothing
|
|
577
|
+
next: work when start_clicked or comment_added or file_uploaded
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
step work {
|
|
581
|
+
goal: make progress on task
|
|
582
|
+
show: task_details, timer_option, progress_updates, collaboration_tools
|
|
583
|
+
collect: {
|
|
584
|
+
progress_note: string?,
|
|
585
|
+
time_logged: duration?,
|
|
586
|
+
blockers: [blocker]?
|
|
587
|
+
}
|
|
588
|
+
on_progress:
|
|
589
|
+
notify(watchers, throttled: 5 min),
|
|
590
|
+
update(last_activity)
|
|
591
|
+
next: complete when mark_done_clicked
|
|
592
|
+
alternatives: blocked when blocker_added
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
step complete {
|
|
596
|
+
goal: mark task as finished
|
|
597
|
+
show: completion_form, summary
|
|
598
|
+
collect: {
|
|
599
|
+
completion_note: string?
|
|
600
|
+
actual_time: duration?, suggested(tracked_time)
|
|
601
|
+
}
|
|
602
|
+
validate: all subtasks.completed when has_subtasks
|
|
603
|
+
on_complete:
|
|
604
|
+
mark_done,
|
|
605
|
+
notify(stakeholders),
|
|
606
|
+
track(task_completed, time: actual_time),
|
|
607
|
+
update_project_progress
|
|
608
|
+
next: celebrate
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
step celebrate {
|
|
612
|
+
goal: positive reinforcement
|
|
613
|
+
show: success_animation, streak_count, next_task_suggestion
|
|
614
|
+
duration: 2 seconds
|
|
615
|
+
next: view(next_task) or dashboard
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
optimize_for: completion_rate, time_to_complete
|
|
619
|
+
|
|
620
|
+
test: complete_task -> task.status == done and audit_logged
|
|
621
|
+
test: blocked_task -> blocker.assigned and notifications_sent
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### 2.5 Design Intent
|
|
626
|
+
|
|
627
|
+
Design intent expresses how the product should *feel*, not just how it looks.
|
|
628
|
+
|
|
629
|
+
```kappa
|
|
630
|
+
design {
|
|
631
|
+
# === MOOD & PERSONALITY ===
|
|
632
|
+
|
|
633
|
+
mood: <mood_descriptors>
|
|
634
|
+
# Moods: professional, playful, serious, friendly, luxurious, minimal,
|
|
635
|
+
# energetic, calm, bold, subtle, warm, cool, technical, approachable
|
|
636
|
+
|
|
637
|
+
personality {
|
|
638
|
+
voice: "<brand voice description>"
|
|
639
|
+
tone: <tone_descriptors> # confident, humble, casual, formal, witty, direct
|
|
640
|
+
|
|
641
|
+
# Microcopy patterns
|
|
642
|
+
empty_states: <encouraging | minimal | instructive>
|
|
643
|
+
errors: <apologetic | direct | helpful>
|
|
644
|
+
success: <celebratory | subtle | informative>
|
|
645
|
+
loading: <patient | progress | skeleton>
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
# === VISUAL FOUNDATION ===
|
|
649
|
+
|
|
650
|
+
foundation {
|
|
651
|
+
# Can derive from assets
|
|
652
|
+
primary: <color> | from_logo(<path>) | from_brand(<url>)
|
|
653
|
+
|
|
654
|
+
# Or specify mood-based derivation
|
|
655
|
+
palette: derive(mood, base: <color>)
|
|
656
|
+
|
|
657
|
+
# Explicit overrides
|
|
658
|
+
colors {
|
|
659
|
+
background: <color>
|
|
660
|
+
surface: <color>
|
|
661
|
+
text: <color>
|
|
662
|
+
# ... etc
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
# Typography
|
|
666
|
+
typography {
|
|
667
|
+
heading: <font> | derive(mood)
|
|
668
|
+
body: <font> | derive(mood, readable: true)
|
|
669
|
+
mono: <font>
|
|
670
|
+
scale: <ratio> # e.g., 1.25 (major third), 1.333 (perfect fourth)
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
# Spacing & Layout
|
|
674
|
+
density: compact | comfortable | spacious
|
|
675
|
+
spacing_unit: <size> # base unit, e.g., 4px
|
|
676
|
+
radius: none | subtle | medium | full
|
|
677
|
+
|
|
678
|
+
# Effects
|
|
679
|
+
shadows: none | subtle | medium | dramatic
|
|
680
|
+
borders: none | subtle | prominent
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
# === MOTION & INTERACTION ===
|
|
684
|
+
|
|
685
|
+
motion {
|
|
686
|
+
level: none | reduced | standard | expressive
|
|
687
|
+
|
|
688
|
+
# Semantic animations (what they mean, not how they move)
|
|
689
|
+
enter: <style> # elements appearing
|
|
690
|
+
exit: <style> # elements disappearing
|
|
691
|
+
move: <style> # elements relocating
|
|
692
|
+
feedback: <style> # response to interaction
|
|
693
|
+
|
|
694
|
+
# Derived from mood
|
|
695
|
+
style: derive(mood) # playful = bouncy, professional = smooth, etc.
|
|
696
|
+
|
|
697
|
+
duration {
|
|
698
|
+
instant: <ms> # micro-interactions
|
|
699
|
+
fast: <ms> # standard transitions
|
|
700
|
+
slow: <ms> # emphasis transitions
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
# === RESPONSIVE BEHAVIOR ===
|
|
705
|
+
|
|
706
|
+
responsive {
|
|
707
|
+
strategy: mobile_first | desktop_first
|
|
708
|
+
|
|
709
|
+
breakpoints {
|
|
710
|
+
mobile: < <width>
|
|
711
|
+
tablet: <width> to <width>
|
|
712
|
+
desktop: > <width>
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
# Layout adaptations (semantic, not CSS)
|
|
716
|
+
mobile {
|
|
717
|
+
navigation: bottom_tabs | hamburger | minimal
|
|
718
|
+
layout: stack | full_width
|
|
719
|
+
interactions: touch_optimized, larger_targets
|
|
720
|
+
content: prioritized, progressive_disclosure
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
tablet {
|
|
724
|
+
navigation: sidebar_collapsible | top
|
|
725
|
+
layout: adaptive_grid
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
desktop {
|
|
729
|
+
navigation: sidebar_fixed | top_full
|
|
730
|
+
layout: multi_column, max_width(<width>)
|
|
731
|
+
interactions: hover_states, keyboard_shortcuts
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
# === COMPONENT PATTERNS ===
|
|
736
|
+
|
|
737
|
+
patterns {
|
|
738
|
+
# Form style
|
|
739
|
+
forms {
|
|
740
|
+
layout: stacked | inline | floating_label
|
|
741
|
+
validation: instant | on_blur | on_submit
|
|
742
|
+
errors: inline | tooltip | summary
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
# Data display
|
|
746
|
+
data {
|
|
747
|
+
tables: full | cards_on_mobile
|
|
748
|
+
lists: separated | bordered | minimal
|
|
749
|
+
empty: illustration | message | cta
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
# Feedback
|
|
753
|
+
feedback {
|
|
754
|
+
success: toast | inline | modal
|
|
755
|
+
error: toast | inline | modal
|
|
756
|
+
confirm: modal | inline | popover
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
# Navigation
|
|
760
|
+
navigation {
|
|
761
|
+
breadcrumbs: always | deep_only | never
|
|
762
|
+
back_button: always | when_nested | never
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
# === DARK MODE ===
|
|
767
|
+
|
|
768
|
+
dark_mode {
|
|
769
|
+
enabled: true | false | system_only
|
|
770
|
+
strategy: invert_lightness | separate_palette | auto_derive
|
|
771
|
+
|
|
772
|
+
# If separate palette
|
|
773
|
+
overrides {
|
|
774
|
+
background: <color>
|
|
775
|
+
surface: <color>
|
|
776
|
+
# ...
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
# === ACCESSIBILITY OVERRIDES ===
|
|
781
|
+
|
|
782
|
+
accessibility {
|
|
783
|
+
# Beyond constraints (which are requirements), these are enhancements
|
|
784
|
+
focus_visible: always | keyboard_only
|
|
785
|
+
link_underlines: always | hover | never(with_color_only)
|
|
786
|
+
reduced_motion_alternative: true
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
**Example:**
|
|
792
|
+
|
|
793
|
+
```kappa
|
|
794
|
+
design {
|
|
795
|
+
mood: professional + approachable + minimal
|
|
796
|
+
|
|
797
|
+
personality {
|
|
798
|
+
voice: "We help teams ship faster without the chaos"
|
|
799
|
+
tone: confident, helpful, occasionally witty
|
|
800
|
+
|
|
801
|
+
empty_states: encouraging # "No projects yet. Let's create your first one!"
|
|
802
|
+
errors: helpful # "That email's already taken. Did you mean to log in?"
|
|
803
|
+
success: celebratory # Subtle confetti on milestones
|
|
804
|
+
loading: skeleton # Content-shaped placeholders
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
foundation {
|
|
808
|
+
primary: from_logo("./assets/logo.svg") # Extract dominant color
|
|
809
|
+
palette: derive(mood, base: primary) # Generate full palette
|
|
810
|
+
|
|
811
|
+
typography {
|
|
812
|
+
heading: "Inter"
|
|
813
|
+
body: "Inter"
|
|
814
|
+
mono: "JetBrains Mono"
|
|
815
|
+
scale: 1.25
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
density: comfortable
|
|
819
|
+
spacing_unit: 4px
|
|
820
|
+
radius: medium # ~8px, friendly but not childish
|
|
821
|
+
shadows: subtle
|
|
822
|
+
borders: subtle
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
motion {
|
|
826
|
+
level: standard
|
|
827
|
+
style: derive(mood) # smooth, purposeful (from professional + approachable)
|
|
828
|
+
|
|
829
|
+
enter: fade_up # elements rise into view
|
|
830
|
+
exit: fade # elements fade out (don't distract)
|
|
831
|
+
feedback: scale # buttons subtly press
|
|
832
|
+
|
|
833
|
+
duration {
|
|
834
|
+
instant: 100ms
|
|
835
|
+
fast: 200ms
|
|
836
|
+
slow: 400ms
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
responsive {
|
|
841
|
+
strategy: mobile_first
|
|
842
|
+
|
|
843
|
+
breakpoints {
|
|
844
|
+
mobile: < 640px
|
|
845
|
+
tablet: 640px to 1024px
|
|
846
|
+
desktop: > 1024px
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
mobile {
|
|
850
|
+
navigation: bottom_tabs
|
|
851
|
+
layout: stack
|
|
852
|
+
content: prioritized # Show key info first, details on tap
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
desktop {
|
|
856
|
+
navigation: sidebar_fixed
|
|
857
|
+
layout: multi_column, max_width(1280px)
|
|
858
|
+
interactions: hover_states, keyboard_shortcuts
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
patterns {
|
|
863
|
+
forms {
|
|
864
|
+
layout: stacked
|
|
865
|
+
validation: on_blur
|
|
866
|
+
errors: inline
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
data {
|
|
870
|
+
tables: cards_on_mobile # Convert tables to cards on small screens
|
|
871
|
+
empty: illustration # Friendly illustrations for empty states
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
feedback {
|
|
875
|
+
success: toast
|
|
876
|
+
error: inline
|
|
877
|
+
confirm: modal
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
dark_mode {
|
|
882
|
+
enabled: true
|
|
883
|
+
strategy: auto_derive # Automatically create dark versions
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
---
|
|
889
|
+
|
|
890
|
+
## Part III: The Constraint Solver
|
|
891
|
+
|
|
892
|
+
### 3.1 Architecture
|
|
893
|
+
|
|
894
|
+
```
|
|
895
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
896
|
+
│ Kappa Specification │
|
|
897
|
+
│ (Goals, Constraints, Entities, Journeys, Design Intent) │
|
|
898
|
+
└─────────────────────────────────────────────────────────────┘
|
|
899
|
+
│
|
|
900
|
+
▼
|
|
901
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
902
|
+
│ PARSER & ANALYZER │
|
|
903
|
+
│ - Parse Kappa syntax │
|
|
904
|
+
│ - Build dependency graph │
|
|
905
|
+
│ - Identify constraint interactions │
|
|
906
|
+
└─────────────────────────────────────────────────────────────┘
|
|
907
|
+
│
|
|
908
|
+
▼
|
|
909
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
910
|
+
│ CONSTRAINT COMPILER │
|
|
911
|
+
│ - Convert goals to formal constraints │
|
|
912
|
+
│ - Convert design intent to design tokens │
|
|
913
|
+
│ - Compile to SAT/SMT representation │
|
|
914
|
+
└─────────────────────────────────────────────────────────────┘
|
|
915
|
+
│
|
|
916
|
+
▼
|
|
917
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
918
|
+
│ SYNTHESIS ENGINE │
|
|
919
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
920
|
+
│ │ Schema │ │ API │ │ UI │ │
|
|
921
|
+
│ │ Generator │ │ Generator │ │ Generator │ │
|
|
922
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
923
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
924
|
+
│ │ Auth │ │ Journey │ │ Design │ │
|
|
925
|
+
│ │ Generator │ │ Generator │ │ Generator │ │
|
|
926
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
927
|
+
└─────────────────────────────────────────────────────────────┘
|
|
928
|
+
│
|
|
929
|
+
▼
|
|
930
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
931
|
+
│ CONSTRAINT SOLVER │
|
|
932
|
+
│ - Find implementation satisfying all constraints │
|
|
933
|
+
│ - Optimize for specified metrics │
|
|
934
|
+
│ - Report conflicts for human resolution │
|
|
935
|
+
└─────────────────────────────────────────────────────────────┘
|
|
936
|
+
│
|
|
937
|
+
▼
|
|
938
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
939
|
+
│ VERIFIER │
|
|
940
|
+
│ - Prove constraints are satisfied │
|
|
941
|
+
│ - Generate test cases │
|
|
942
|
+
│ - Add runtime checks where static proof impossible │
|
|
943
|
+
└─────────────────────────────────────────────────────────────┘
|
|
944
|
+
│
|
|
945
|
+
▼
|
|
946
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
947
|
+
│ GENERATED OUTPUT │
|
|
948
|
+
│ - Database schema with migrations │
|
|
949
|
+
│ - API routes with middleware │
|
|
950
|
+
│ - UI components with design tokens │
|
|
951
|
+
│ - Journey flows with analytics │
|
|
952
|
+
│ - Tests covering all constraints │
|
|
953
|
+
│ - Provenance comments linking to specs │
|
|
954
|
+
└─────────────────────────────────────────────────────────────┘
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
### 3.2 Constraint Resolution
|
|
958
|
+
|
|
959
|
+
When constraints interact or conflict:
|
|
960
|
+
|
|
961
|
+
```kappa
|
|
962
|
+
# Example conflict
|
|
963
|
+
constraints Performance {
|
|
964
|
+
lcp: < 1.5s
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
entity Project {
|
|
968
|
+
has_many: Task, limit(10000) # Could have many tasks
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
journey Dashboard {
|
|
972
|
+
step overview {
|
|
973
|
+
show: all project tasks with status # Potentially slow
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
**Solver detects:**
|
|
979
|
+
```
|
|
980
|
+
⚠️ Potential Constraint Conflict
|
|
981
|
+
|
|
982
|
+
Performance.lcp < 1.5s may conflict with:
|
|
983
|
+
- Project.has_many Task (up to 10,000)
|
|
984
|
+
- Dashboard.overview.show all tasks
|
|
985
|
+
|
|
986
|
+
Analysis:
|
|
987
|
+
- Fetching 10,000 tasks: ~800ms DB + ~400ms render = 1.2s (OK)
|
|
988
|
+
- Fetching 10,000 tasks with details: ~2.5s (EXCEEDS)
|
|
989
|
+
|
|
990
|
+
Solutions:
|
|
991
|
+
┌─────────────────────────────────────────────────────────┐
|
|
992
|
+
│ (a) Add pagination [RECOMMENDED] │
|
|
993
|
+
│ Fetch 50 tasks per page │
|
|
994
|
+
│ Impact: UX change (pagination controls) │
|
|
995
|
+
│ Satisfies: All constraints │
|
|
996
|
+
├─────────────────────────────────────────────────────────┤
|
|
997
|
+
│ (b) Add virtualization │
|
|
998
|
+
│ Render only visible rows │
|
|
999
|
+
│ Impact: Complexity +2, bundle +15kb │
|
|
1000
|
+
│ Satisfies: All constraints │
|
|
1001
|
+
├─────────────────────────────────────────────────────────┤
|
|
1002
|
+
│ (c) Relax LCP constraint for large projects │
|
|
1003
|
+
│ Change: lcp < 1.5s when tasks < 1000 │
|
|
1004
|
+
│ lcp < 3.0s when tasks >= 1000 │
|
|
1005
|
+
│ Impact: Degraded experience for power users │
|
|
1006
|
+
├─────────────────────────────────────────────────────────┤
|
|
1007
|
+
│ (d) Add caching layer │
|
|
1008
|
+
│ Cache task summaries, invalidate on change │
|
|
1009
|
+
│ Impact: Cost +$20/mo, eventual consistency │
|
|
1010
|
+
└─────────────────────────────────────────────────────────┘
|
|
1011
|
+
|
|
1012
|
+
> Select solution: [a] / b / c / d / custom
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
### 3.3 Design Intent Resolution
|
|
1016
|
+
|
|
1017
|
+
```kappa
|
|
1018
|
+
design {
|
|
1019
|
+
mood: professional + playful # Slight tension
|
|
1020
|
+
}
|
|
1021
|
+
```
|
|
1022
|
+
|
|
1023
|
+
**Solver interprets:**
|
|
1024
|
+
```
|
|
1025
|
+
Mood Analysis: professional + playful
|
|
1026
|
+
|
|
1027
|
+
These moods have tension points:
|
|
1028
|
+
- professional suggests: muted colors, clean lines, formal typography
|
|
1029
|
+
- playful suggests: bright colors, rounded shapes, casual typography
|
|
1030
|
+
|
|
1031
|
+
Resolution strategy: Professional foundation, playful accents
|
|
1032
|
+
|
|
1033
|
+
Generated tokens:
|
|
1034
|
+
colors:
|
|
1035
|
+
background: #FAFAFA (professional: neutral)
|
|
1036
|
+
text: #1A1A1A (professional: high contrast)
|
|
1037
|
+
primary: #6366F1 (playful: vibrant purple)
|
|
1038
|
+
accent: #F59E0B (playful: warm amber)
|
|
1039
|
+
|
|
1040
|
+
typography:
|
|
1041
|
+
heading: "Inter" (professional: clean sans-serif)
|
|
1042
|
+
body: "Inter" (professional: readable)
|
|
1043
|
+
weight: medium (professional: substantial)
|
|
1044
|
+
|
|
1045
|
+
radius: 12px (playful: rounded but not bubbly)
|
|
1046
|
+
|
|
1047
|
+
motion:
|
|
1048
|
+
style: smooth (professional: controlled)
|
|
1049
|
+
feedback: bounce(subtle) (playful: responsive)
|
|
1050
|
+
|
|
1051
|
+
personality:
|
|
1052
|
+
microcopy: friendly but concise
|
|
1053
|
+
empty_states: illustrated (playful) with direct CTA (professional)
|
|
1054
|
+
|
|
1055
|
+
Confidence: 87% this interpretation matches intent
|
|
1056
|
+
> Accept / Adjust toward professional / Adjust toward playful / Custom
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
---
|
|
1060
|
+
|
|
1061
|
+
## Part IV: Provenance & Debugging
|
|
1062
|
+
|
|
1063
|
+
### 4.1 Provenance Comments
|
|
1064
|
+
|
|
1065
|
+
Every generated line traces to its source:
|
|
1066
|
+
|
|
1067
|
+
```typescript
|
|
1068
|
+
// FILE: app/api/projects/[id]/route.ts
|
|
1069
|
+
// GENERATED: 2026-01-02T14:30:00Z
|
|
1070
|
+
// KAPPA: entities.Project, goals.ProjectCollaboration
|
|
1071
|
+
|
|
1072
|
+
import { db } from "@/lib/db";
|
|
1073
|
+
import { requireAuth, requireRole } from "@/lib/auth";
|
|
1074
|
+
|
|
1075
|
+
// [GOAL: ProjectCollaboration.ensure.only_owners_can_delete]
|
|
1076
|
+
// [ENTITY: Project.owner can delete]
|
|
1077
|
+
export async function DELETE(req: Request, { params }: { params: { id: string } }) {
|
|
1078
|
+
// [CONSTRAINT: Security.sessions.jwt]
|
|
1079
|
+
const user = await requireAuth(req);
|
|
1080
|
+
|
|
1081
|
+
// [ENTITY: Project.owner can delete]
|
|
1082
|
+
// [GOAL: ProjectCollaboration.ensure.only_owners_can_delete]
|
|
1083
|
+
const project = await db.project.findUnique({
|
|
1084
|
+
where: { id: params.id },
|
|
1085
|
+
include: { owner: true }
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
if (!project) {
|
|
1089
|
+
// [CONSTRAINT: Security.inputs.validated]
|
|
1090
|
+
return Response.json({ error: "Project not found" }, { status: 404 });
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
if (project.ownerId !== user.id) {
|
|
1094
|
+
// [GOAL: ProjectCollaboration.ensure.only_owners_can_delete]
|
|
1095
|
+
return Response.json({ error: "Only owners can delete projects" }, { status: 403 });
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
// [ENTITY: Project.on_delete.require no active_tasks]
|
|
1099
|
+
const activeTasks = await db.task.count({
|
|
1100
|
+
where: { projectId: params.id, status: { not: "done" } }
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
if (activeTasks > 0 && !req.headers.get("X-Force-Delete")) {
|
|
1104
|
+
return Response.json({
|
|
1105
|
+
error: "Project has active tasks",
|
|
1106
|
+
active_count: activeTasks,
|
|
1107
|
+
hint: "Complete or delete tasks first, or send X-Force-Delete header"
|
|
1108
|
+
}, { status: 409 });
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
// [ENTITY: Project.on_delete.delete all tasks (cascade)]
|
|
1112
|
+
await db.task.deleteMany({ where: { projectId: params.id } });
|
|
1113
|
+
|
|
1114
|
+
// [ENTITY: Project.on_delete.notify all members]
|
|
1115
|
+
// [JOURNEY: implicit notification on significant events]
|
|
1116
|
+
await notifyProjectMembers(params.id, "project_deleted", {
|
|
1117
|
+
project_name: project.name,
|
|
1118
|
+
deleted_by: user.name
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
// [ENTITY: Project.on_delete.log_audit]
|
|
1122
|
+
// [GOAL: ProjectCollaboration.audit]
|
|
1123
|
+
await auditLog("project.deleted", {
|
|
1124
|
+
projectId: params.id,
|
|
1125
|
+
userId: user.id,
|
|
1126
|
+
projectName: project.name,
|
|
1127
|
+
taskCount: activeTasks,
|
|
1128
|
+
forced: !!req.headers.get("X-Force-Delete")
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
// [ENTITY: Project primary delete action]
|
|
1132
|
+
await db.project.delete({ where: { id: params.id } });
|
|
1133
|
+
|
|
1134
|
+
return Response.json({ success: true });
|
|
1135
|
+
}
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
### 4.2 Constraint Violation Detection
|
|
1139
|
+
|
|
1140
|
+
Runtime monitoring for constraints that can't be statically verified:
|
|
1141
|
+
|
|
1142
|
+
```typescript
|
|
1143
|
+
// [CONSTRAINT: Performance.api_p99 < 200ms]
|
|
1144
|
+
// [MONITORING: runtime_check]
|
|
1145
|
+
export const withPerformanceConstraint = (handler: Handler) => async (req, res) => {
|
|
1146
|
+
const start = performance.now();
|
|
1147
|
+
|
|
1148
|
+
try {
|
|
1149
|
+
const result = await handler(req, res);
|
|
1150
|
+
return result;
|
|
1151
|
+
} finally {
|
|
1152
|
+
const duration = performance.now() - start;
|
|
1153
|
+
|
|
1154
|
+
// Track for p99 calculation
|
|
1155
|
+
metrics.recordApiLatency(req.path, duration);
|
|
1156
|
+
|
|
1157
|
+
// [CONSTRAINT: Performance.api_p99 < 200ms]
|
|
1158
|
+
if (duration > 200) {
|
|
1159
|
+
constraintViolation({
|
|
1160
|
+
constraint: "Performance.api_p99",
|
|
1161
|
+
expected: "< 200ms",
|
|
1162
|
+
actual: `${duration.toFixed(0)}ms`,
|
|
1163
|
+
endpoint: req.path,
|
|
1164
|
+
severity: duration > 500 ? "critical" : "warning"
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
### 4.3 Bidirectional Sync
|
|
1172
|
+
|
|
1173
|
+
When you edit generated code:
|
|
1174
|
+
|
|
1175
|
+
```typescript
|
|
1176
|
+
// Developer adds this line:
|
|
1177
|
+
if (user.role === "admin") {
|
|
1178
|
+
// Skip ownership check for admins
|
|
1179
|
+
// TODO: Is this intentional?
|
|
1180
|
+
}
|
|
1181
|
+
```
|
|
1182
|
+
|
|
1183
|
+
**Kappa detects the drift:**
|
|
1184
|
+
```
|
|
1185
|
+
⚠️ Generated Code Modified
|
|
1186
|
+
|
|
1187
|
+
File: app/api/projects/[id]/route.ts
|
|
1188
|
+
Line: 23-26 (new code)
|
|
1189
|
+
|
|
1190
|
+
Change analysis:
|
|
1191
|
+
- Allows admins to bypass ownership check
|
|
1192
|
+
- Affects: GOAL ProjectCollaboration.ensure.only_owners_can_delete
|
|
1193
|
+
|
|
1194
|
+
This change implies a new capability. Update spec?
|
|
1195
|
+
|
|
1196
|
+
Options:
|
|
1197
|
+
┌─────────────────────────────────────────────────────────┐
|
|
1198
|
+
│ (a) Update spec to match code [RECOMMENDED] │
|
|
1199
|
+
│ Add: admin can: delete any Project │
|
|
1200
|
+
│ Regenerates other affected code consistently │
|
|
1201
|
+
├─────────────────────────────────────────────────────────┤
|
|
1202
|
+
│ (b) Revert code to match spec │
|
|
1203
|
+
│ Removes admin bypass │
|
|
1204
|
+
├─────────────────────────────────────────────────────────┤
|
|
1205
|
+
│ (c) Mark as intentional deviation │
|
|
1206
|
+
│ Adds @override annotation, preserves on regenerate │
|
|
1207
|
+
└─────────────────────────────────────────────────────────┘
|
|
1208
|
+
|
|
1209
|
+
> Select: [a] / b / c
|
|
1210
|
+
```
|
|
1211
|
+
|
|
1212
|
+
If (a) selected, spec updates automatically:
|
|
1213
|
+
|
|
1214
|
+
```kappa
|
|
1215
|
+
entity Project {
|
|
1216
|
+
# ... existing ...
|
|
1217
|
+
|
|
1218
|
+
# Auto-added from code sync
|
|
1219
|
+
owner can: delete
|
|
1220
|
+
admin can: delete any # [SYNCED: app/api/projects/[id]/route.ts:23-26]
|
|
1221
|
+
}
|
|
1222
|
+
```
|
|
1223
|
+
|
|
1224
|
+
---
|
|
1225
|
+
|
|
1226
|
+
## Part V: Learning & Evolution
|
|
1227
|
+
|
|
1228
|
+
### 5.1 Escape Hatch with Learning
|
|
1229
|
+
|
|
1230
|
+
When Kappa can't express something:
|
|
1231
|
+
|
|
1232
|
+
```kappa
|
|
1233
|
+
entity Payment {
|
|
1234
|
+
amount: money
|
|
1235
|
+
currency: currency_code
|
|
1236
|
+
status: pending | processing | completed | failed
|
|
1237
|
+
|
|
1238
|
+
# Complex tax calculation - hard to specify declaratively
|
|
1239
|
+
custom {
|
|
1240
|
+
@target(typescript)
|
|
1241
|
+
@learn("external_tax_integration")
|
|
1242
|
+
|
|
1243
|
+
calculateTax: (amount: number, shipping: Address, items: LineItem[]) => {
|
|
1244
|
+
// Tax jurisdiction logic is complex and varies
|
|
1245
|
+
// Delegate to TaxJar API
|
|
1246
|
+
const taxjar = new TaxJar({ apiKey: env.TAXJAR_KEY });
|
|
1247
|
+
return taxjar.taxForOrder({
|
|
1248
|
+
from_country: 'US',
|
|
1249
|
+
from_zip: warehouse.zip,
|
|
1250
|
+
to_country: shipping.country,
|
|
1251
|
+
to_zip: shipping.zip,
|
|
1252
|
+
amount: amount,
|
|
1253
|
+
shipping: shipping.cost,
|
|
1254
|
+
line_items: items.map(i => ({
|
|
1255
|
+
quantity: i.quantity,
|
|
1256
|
+
unit_price: i.price,
|
|
1257
|
+
product_tax_code: i.taxCode
|
|
1258
|
+
}))
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
**After seeing similar patterns across projects:**
|
|
1266
|
+
|
|
1267
|
+
```
|
|
1268
|
+
📚 Pattern Learned: external_tax_integration
|
|
1269
|
+
|
|
1270
|
+
Observed in: 12 projects
|
|
1271
|
+
Common structure:
|
|
1272
|
+
- Third-party tax service (TaxJar, Avalara, TaxCloud)
|
|
1273
|
+
- Inputs: amount, addresses, line items
|
|
1274
|
+
- Outputs: tax breakdown by jurisdiction
|
|
1275
|
+
|
|
1276
|
+
Proposing first-class primitive:
|
|
1277
|
+
|
|
1278
|
+
tax_calculation {
|
|
1279
|
+
provider: taxjar | avalara | taxcloud | stripe_tax
|
|
1280
|
+
from: <address_field>
|
|
1281
|
+
to: <address_field>
|
|
1282
|
+
items: <line_items_field>
|
|
1283
|
+
cache: <duration>
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
Add to Kappa standard library? [Y/n]
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
### 5.2 Community Pattern Library
|
|
1290
|
+
|
|
1291
|
+
```kappa
|
|
1292
|
+
# Import community patterns
|
|
1293
|
+
import patterns/saas_billing from kappa-hub
|
|
1294
|
+
import patterns/team_permissions from kappa-hub
|
|
1295
|
+
import patterns/audit_logging from kappa-hub
|
|
1296
|
+
|
|
1297
|
+
# Use them
|
|
1298
|
+
entity Subscription {
|
|
1299
|
+
uses: saas_billing(
|
|
1300
|
+
provider: stripe,
|
|
1301
|
+
plans: [free, pro, enterprise],
|
|
1302
|
+
billing_cycle: monthly | yearly,
|
|
1303
|
+
trial: 14 days
|
|
1304
|
+
)
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
entity Organization {
|
|
1308
|
+
uses: team_permissions(
|
|
1309
|
+
roles: [owner, admin, member, viewer],
|
|
1310
|
+
invitations: email_based,
|
|
1311
|
+
sso: optional(saml, oidc)
|
|
1312
|
+
)
|
|
1313
|
+
}
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
### 5.3 Spec Evolution
|
|
1317
|
+
|
|
1318
|
+
As requirements change:
|
|
1319
|
+
|
|
1320
|
+
```kappa
|
|
1321
|
+
# Version 1
|
|
1322
|
+
entity User {
|
|
1323
|
+
email: email
|
|
1324
|
+
name: string
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
# Version 2 - add teams
|
|
1328
|
+
entity User {
|
|
1329
|
+
email: email
|
|
1330
|
+
name: string
|
|
1331
|
+
belongs_to: Team? # NEW
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
entity Team { # NEW
|
|
1335
|
+
name: string
|
|
1336
|
+
has_many: User
|
|
1337
|
+
}
|
|
1338
|
+
```
|
|
1339
|
+
|
|
1340
|
+
**Solver generates migration:**
|
|
1341
|
+
```
|
|
1342
|
+
Migration Analysis: v1 → v2
|
|
1343
|
+
|
|
1344
|
+
Changes detected:
|
|
1345
|
+
1. New entity: Team
|
|
1346
|
+
2. New relationship: User.belongs_to Team (optional)
|
|
1347
|
+
|
|
1348
|
+
Generated migrations:
|
|
1349
|
+
|
|
1350
|
+
1. Create teams table
|
|
1351
|
+
- Safe: Yes (new table)
|
|
1352
|
+
|
|
1353
|
+
2. Add team_id to users
|
|
1354
|
+
- Safe: Yes (nullable)
|
|
1355
|
+
|
|
1356
|
+
3. Data migration needed: No
|
|
1357
|
+
- Existing users have team_id = null (valid for optional)
|
|
1358
|
+
|
|
1359
|
+
Rollback plan:
|
|
1360
|
+
1. Drop team_id from users
|
|
1361
|
+
2. Drop teams table
|
|
1362
|
+
|
|
1363
|
+
> Apply migration? [Y/n]
|
|
1364
|
+
```
|
|
1365
|
+
|
|
1366
|
+
---
|
|
1367
|
+
|
|
1368
|
+
## Part VI: Complete Example
|
|
1369
|
+
|
|
1370
|
+
### 6.1 Full Specification
|
|
1371
|
+
|
|
1372
|
+
```kappa
|
|
1373
|
+
# ============================================
|
|
1374
|
+
# PROJECT: TaskFlow - Team Task Management
|
|
1375
|
+
# ============================================
|
|
1376
|
+
|
|
1377
|
+
# === GOALS ===
|
|
1378
|
+
|
|
1379
|
+
goal Authentication {
|
|
1380
|
+
enable:
|
|
1381
|
+
users sign up with email,
|
|
1382
|
+
users log in securely,
|
|
1383
|
+
users recover forgotten passwords,
|
|
1384
|
+
users enable two-factor auth
|
|
1385
|
+
|
|
1386
|
+
ensure:
|
|
1387
|
+
no duplicate accounts,
|
|
1388
|
+
sessions expire after inactivity,
|
|
1389
|
+
passwords meet security standards
|
|
1390
|
+
|
|
1391
|
+
comply: OWASP_Top_10
|
|
1392
|
+
audit: all auth events
|
|
1393
|
+
|
|
1394
|
+
perform:
|
|
1395
|
+
login p99 < 200ms,
|
|
1396
|
+
signup p99 < 500ms
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
goal TaskManagement {
|
|
1400
|
+
enable:
|
|
1401
|
+
users create and organize tasks,
|
|
1402
|
+
users assign tasks to team members,
|
|
1403
|
+
users set due dates and priorities,
|
|
1404
|
+
users track task progress,
|
|
1405
|
+
users collaborate with comments
|
|
1406
|
+
|
|
1407
|
+
ensure:
|
|
1408
|
+
only team members see team tasks,
|
|
1409
|
+
completed tasks are never lost,
|
|
1410
|
+
task history is preserved
|
|
1411
|
+
|
|
1412
|
+
audit: task status changes, assignments
|
|
1413
|
+
|
|
1414
|
+
measure:
|
|
1415
|
+
tasks_completed_per_user_per_week -> track,
|
|
1416
|
+
overdue_task_rate -> < 20%
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
goal TeamCollaboration {
|
|
1420
|
+
enable:
|
|
1421
|
+
users create teams,
|
|
1422
|
+
team owners invite members,
|
|
1423
|
+
members have roles (admin, member, viewer),
|
|
1424
|
+
teams share projects
|
|
1425
|
+
|
|
1426
|
+
ensure:
|
|
1427
|
+
only owners can delete teams,
|
|
1428
|
+
removing member preserves their task history,
|
|
1429
|
+
transferring ownership is atomic
|
|
1430
|
+
|
|
1431
|
+
audit: membership changes, role changes
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
# === CONSTRAINTS ===
|
|
1435
|
+
|
|
1436
|
+
constraints Security {
|
|
1437
|
+
passwords: hashed(argon2id), min(12), breach_check
|
|
1438
|
+
sessions: jwt, expires(7d), refresh(sliding), revokable
|
|
1439
|
+
inputs: sanitized, validated, rate_limited(100/min/ip)
|
|
1440
|
+
uploads: scanned, max_size(10mb), type_whitelist([image/*, .pdf, .doc, .docx])
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
constraints Privacy {
|
|
1444
|
+
pii_fields: [email, name, avatar]
|
|
1445
|
+
retention: 3 years then anonymize
|
|
1446
|
+
deletion: complete within 30 days
|
|
1447
|
+
export: available within 48 hours
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
constraints Accessibility {
|
|
1451
|
+
level: WCAG_AA
|
|
1452
|
+
contrast: min(4.5)
|
|
1453
|
+
keyboard: full_navigation
|
|
1454
|
+
motion: respect_prefers_reduced
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
constraints Performance {
|
|
1458
|
+
lcp: < 2s
|
|
1459
|
+
fid: < 100ms
|
|
1460
|
+
cls: < 0.1
|
|
1461
|
+
api_p99: < 300ms
|
|
1462
|
+
initial_bundle: < 150kb
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
# === ENTITIES ===
|
|
1466
|
+
|
|
1467
|
+
entity User {
|
|
1468
|
+
identify_by: email
|
|
1469
|
+
|
|
1470
|
+
email: email, unique, immutable
|
|
1471
|
+
name: string(2..100)
|
|
1472
|
+
avatar: image?, max_size(5mb)
|
|
1473
|
+
role: Role = member
|
|
1474
|
+
|
|
1475
|
+
has_many: Team (as owner), limit(10)
|
|
1476
|
+
has_many: Membership
|
|
1477
|
+
has_many: Team through Membership
|
|
1478
|
+
has_many: Task (as assignee)
|
|
1479
|
+
has_many: Comment
|
|
1480
|
+
|
|
1481
|
+
can: create Team, create Task (in own teams)
|
|
1482
|
+
visible_to: self, team_members, admin
|
|
1483
|
+
|
|
1484
|
+
on_create: send_email(welcome), log_audit
|
|
1485
|
+
on_delete: anonymize, transfer_ownership, log_audit
|
|
1486
|
+
|
|
1487
|
+
compute display_name: name or email.local_part
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
entity Team {
|
|
1491
|
+
identify_by: slug
|
|
1492
|
+
|
|
1493
|
+
name: string(2..50)
|
|
1494
|
+
slug: slug, auto_from(name), unique
|
|
1495
|
+
description: string?, max(500)
|
|
1496
|
+
|
|
1497
|
+
belongs_to: User (as owner)
|
|
1498
|
+
has_many: Membership
|
|
1499
|
+
has_many: User through Membership (as members)
|
|
1500
|
+
has_many: Project
|
|
1501
|
+
|
|
1502
|
+
owner can: update, delete, manage_members, transfer_ownership
|
|
1503
|
+
admin can: update, manage_members, create_project
|
|
1504
|
+
member can: read, create_task, comment
|
|
1505
|
+
viewer can: read
|
|
1506
|
+
|
|
1507
|
+
on_delete: require(no_projects or confirmed), notify_members
|
|
1508
|
+
|
|
1509
|
+
compute member_count: memberships.count
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
entity Membership {
|
|
1513
|
+
identify_by: composite(user, team)
|
|
1514
|
+
|
|
1515
|
+
belongs_to: User
|
|
1516
|
+
belongs_to: Team
|
|
1517
|
+
role: owner | admin | member | viewer = member
|
|
1518
|
+
|
|
1519
|
+
states: invited -> active -> removed
|
|
1520
|
+
|
|
1521
|
+
on_create: send_email(invitation) when invited
|
|
1522
|
+
on_transition(active): log_audit(member_joined)
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
entity Project {
|
|
1526
|
+
identify_by: slug (scoped_to team)
|
|
1527
|
+
|
|
1528
|
+
name: string(1..100)
|
|
1529
|
+
slug: slug, auto_from(name)
|
|
1530
|
+
description: markdown?, max(10000)
|
|
1531
|
+
status: active | archived = active
|
|
1532
|
+
|
|
1533
|
+
belongs_to: Team
|
|
1534
|
+
has_many: Task, ordered_by(position)
|
|
1535
|
+
|
|
1536
|
+
visible_to: team.members
|
|
1537
|
+
editable_by: team.owner, team.admin, team.member
|
|
1538
|
+
|
|
1539
|
+
states: active -> archived
|
|
1540
|
+
|
|
1541
|
+
compute task_count: tasks.count
|
|
1542
|
+
compute completion_rate: tasks.done.count / tasks.count
|
|
1543
|
+
|
|
1544
|
+
index: [team_id, slug], unique
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
entity Task {
|
|
1548
|
+
identify_by: number (scoped_to project, auto_increment)
|
|
1549
|
+
|
|
1550
|
+
title: string(1..200)
|
|
1551
|
+
description: markdown?, max(50000)
|
|
1552
|
+
status: todo | in_progress | in_review | done = todo
|
|
1553
|
+
priority: low | medium | high | urgent = medium
|
|
1554
|
+
due_date: date?
|
|
1555
|
+
position: integer, auto
|
|
1556
|
+
|
|
1557
|
+
belongs_to: Project
|
|
1558
|
+
belongs_to: User? (as assignee)
|
|
1559
|
+
belongs_to: User (as creator)
|
|
1560
|
+
has_many: Comment, ordered_by(created_at)
|
|
1561
|
+
has_many: Task (as subtasks)
|
|
1562
|
+
belongs_to: Task? (as parent)
|
|
1563
|
+
|
|
1564
|
+
visible_to: project.team.members
|
|
1565
|
+
editable_by: creator, assignee, project.team.admin, project.team.owner
|
|
1566
|
+
|
|
1567
|
+
states: todo -> in_progress -> in_review -> done
|
|
1568
|
+
transitions:
|
|
1569
|
+
any -> done: log_audit(task_completed)
|
|
1570
|
+
done -> any: log_audit(task_reopened)
|
|
1571
|
+
|
|
1572
|
+
on_assign: notify(assignee), log_audit
|
|
1573
|
+
on_due_soon(1 day): notify(assignee, creator)
|
|
1574
|
+
on_overdue: notify(assignee, creator, project.team.owner)
|
|
1575
|
+
|
|
1576
|
+
compute is_overdue: due_date < today and status != done
|
|
1577
|
+
compute subtask_progress: subtasks.done.count / subtasks.count
|
|
1578
|
+
|
|
1579
|
+
index: [project_id, number], unique
|
|
1580
|
+
index: [assignee_id, status] where assignee_id != null
|
|
1581
|
+
index: [due_date] where status != done
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
entity Comment {
|
|
1585
|
+
identify_by: auto
|
|
1586
|
+
|
|
1587
|
+
body: markdown(1..10000)
|
|
1588
|
+
|
|
1589
|
+
belongs_to: Task
|
|
1590
|
+
belongs_to: User (as author)
|
|
1591
|
+
|
|
1592
|
+
visible_to: task.project.team.members
|
|
1593
|
+
editable_by: author (within 15 minutes)
|
|
1594
|
+
deletable_by: author, task.project.team.admin
|
|
1595
|
+
|
|
1596
|
+
on_create: notify(task.participants except author)
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
# === JOURNEYS ===
|
|
1600
|
+
|
|
1601
|
+
journey Onboarding {
|
|
1602
|
+
actor: new_user
|
|
1603
|
+
entry: signup or invitation_accept
|
|
1604
|
+
|
|
1605
|
+
steps: signup -> verify -> create_team -> invite -> ready
|
|
1606
|
+
|
|
1607
|
+
step signup {
|
|
1608
|
+
goal: create account
|
|
1609
|
+
collect: { email: email, password: password, name: string }
|
|
1610
|
+
on_complete: create(User), send_verification
|
|
1611
|
+
next: verify
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
step verify {
|
|
1615
|
+
goal: confirm email
|
|
1616
|
+
show: check_email_prompt, resend_option
|
|
1617
|
+
collect: verification_code or magic_link
|
|
1618
|
+
timeout: 24h -> reminder, 72h -> expire
|
|
1619
|
+
next: create_team
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
step create_team {
|
|
1623
|
+
goal: set up workspace
|
|
1624
|
+
show: team_form, templates
|
|
1625
|
+
collect: { name: string, template?: template_id }
|
|
1626
|
+
on_complete: create(Team), assign_owner
|
|
1627
|
+
next: invite
|
|
1628
|
+
skip_to: ready when invited_to_existing_team
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
step invite {
|
|
1632
|
+
goal: bring in collaborators
|
|
1633
|
+
show: invite_form, skip_option, benefits
|
|
1634
|
+
collect: { emails: [email], message?: string }
|
|
1635
|
+
on_complete: send_invitations
|
|
1636
|
+
next: ready
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
step ready {
|
|
1640
|
+
goal: start using product
|
|
1641
|
+
show: success, quick_tour_offer, first_task_prompt
|
|
1642
|
+
next: dashboard
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
optimize_for: completion_rate, time_to_first_task
|
|
1646
|
+
|
|
1647
|
+
on_drop_off(signup): retarget(24h) when email_collected
|
|
1648
|
+
on_drop_off(verify): send_reminder(1h), send_reminder(24h)
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
journey DailyTaskWork {
|
|
1652
|
+
actor: team_member
|
|
1653
|
+
entry: app_open or notification
|
|
1654
|
+
|
|
1655
|
+
steps: review -> select -> work -> complete
|
|
1656
|
+
|
|
1657
|
+
step review {
|
|
1658
|
+
goal: understand priorities
|
|
1659
|
+
show: my_tasks, due_today, overdue, recent_activity
|
|
1660
|
+
next: select when task_clicked
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
step select {
|
|
1664
|
+
goal: choose what to work on
|
|
1665
|
+
show: task_detail, subtasks, comments, attachments
|
|
1666
|
+
next: work when start_clicked
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
step work {
|
|
1670
|
+
goal: make progress
|
|
1671
|
+
show: task_in_focus, timer_option, quick_add_subtask
|
|
1672
|
+
collect: progress_updates, time_logged
|
|
1673
|
+
next: complete when mark_done
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
step complete {
|
|
1677
|
+
goal: finish task
|
|
1678
|
+
show: completion_form, next_suggestion
|
|
1679
|
+
on_complete: update_status, notify_stakeholders, celebrate
|
|
1680
|
+
next: review
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
optimize_for: tasks_completed, time_in_flow
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
# === DESIGN ===
|
|
1687
|
+
|
|
1688
|
+
design {
|
|
1689
|
+
mood: focused + friendly
|
|
1690
|
+
|
|
1691
|
+
personality {
|
|
1692
|
+
voice: "Your calm, capable task companion"
|
|
1693
|
+
tone: encouraging, not pushy
|
|
1694
|
+
empty_states: motivating
|
|
1695
|
+
success: celebratory (subtle)
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
foundation {
|
|
1699
|
+
primary: "#6366F1" # Indigo - focused, professional
|
|
1700
|
+
palette: derive(mood)
|
|
1701
|
+
|
|
1702
|
+
typography {
|
|
1703
|
+
heading: "Inter"
|
|
1704
|
+
body: "Inter"
|
|
1705
|
+
scale: 1.25
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
density: comfortable
|
|
1709
|
+
radius: medium
|
|
1710
|
+
shadows: subtle
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
motion {
|
|
1714
|
+
level: standard
|
|
1715
|
+
enter: fade_up
|
|
1716
|
+
feedback: scale
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
responsive {
|
|
1720
|
+
strategy: mobile_first
|
|
1721
|
+
|
|
1722
|
+
mobile {
|
|
1723
|
+
navigation: bottom_tabs
|
|
1724
|
+
layout: stack
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
desktop {
|
|
1728
|
+
navigation: sidebar_fixed
|
|
1729
|
+
layout: multi_column
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
dark_mode {
|
|
1734
|
+
enabled: true
|
|
1735
|
+
strategy: auto_derive
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
```
|
|
1739
|
+
|
|
1740
|
+
### 6.2 What Gets Generated
|
|
1741
|
+
|
|
1742
|
+
From this ~400 line spec, the solver generates:
|
|
1743
|
+
|
|
1744
|
+
```
|
|
1745
|
+
Generated Output Structure:
|
|
1746
|
+
├── db/
|
|
1747
|
+
│ ├── schema.ts # Drizzle schema (all entities)
|
|
1748
|
+
│ ├── migrations/ # Migration files
|
|
1749
|
+
│ └── seed.ts # Test data seeder
|
|
1750
|
+
├── lib/
|
|
1751
|
+
│ ├── auth.ts # Auth utilities
|
|
1752
|
+
│ ├── permissions.ts # RBAC logic
|
|
1753
|
+
│ ├── audit.ts # Audit logging
|
|
1754
|
+
│ └── notifications.ts # Notification dispatch
|
|
1755
|
+
├── app/
|
|
1756
|
+
│ ├── api/
|
|
1757
|
+
│ │ ├── auth/ # Auth endpoints
|
|
1758
|
+
│ │ ├── users/ # User CRUD
|
|
1759
|
+
│ │ ├── teams/ # Team CRUD
|
|
1760
|
+
│ │ ├── projects/ # Project CRUD
|
|
1761
|
+
│ │ └── tasks/ # Task CRUD
|
|
1762
|
+
│ ├── routes/
|
|
1763
|
+
│ │ ├── _layout.tsx # Root layout
|
|
1764
|
+
│ │ ├── index.tsx # Landing/redirect
|
|
1765
|
+
│ │ ├── login.tsx # Login page
|
|
1766
|
+
│ │ ├── signup.tsx # Signup flow
|
|
1767
|
+
│ │ ├── dashboard.tsx # Main dashboard
|
|
1768
|
+
│ │ ├── teams/
|
|
1769
|
+
│ │ │ ├── $teamSlug.tsx
|
|
1770
|
+
│ │ │ └── $teamSlug.settings.tsx
|
|
1771
|
+
│ │ └── projects/
|
|
1772
|
+
│ │ ├── $projectSlug.tsx
|
|
1773
|
+
│ │ └── $projectSlug.task.$taskNumber.tsx
|
|
1774
|
+
│ └── components/
|
|
1775
|
+
│ ├── ui/ # Design system components
|
|
1776
|
+
│ ├── forms/ # Form components
|
|
1777
|
+
│ └── features/ # Feature components
|
|
1778
|
+
├── styles/
|
|
1779
|
+
│ └── tokens.css # Generated design tokens
|
|
1780
|
+
├── tests/
|
|
1781
|
+
│ ├── constraints/ # Constraint verification tests
|
|
1782
|
+
│ ├── journeys/ # Journey flow tests
|
|
1783
|
+
│ └── e2e/ # End-to-end tests
|
|
1784
|
+
└── docs/
|
|
1785
|
+
├── provenance.json # Spec → code mapping
|
|
1786
|
+
└── constraints.md # Constraint documentation
|
|
1787
|
+
|
|
1788
|
+
Total: ~15,000 lines of production code
|
|
1789
|
+
From: ~400 lines of Kappa spec
|
|
1790
|
+
Expansion: 37.5x
|
|
1791
|
+
```
|
|
1792
|
+
|
|
1793
|
+
---
|
|
1794
|
+
|
|
1795
|
+
## Part VII: Why This Is Novel
|
|
1796
|
+
|
|
1797
|
+
### 7.1 Comparison to Existing Approaches
|
|
1798
|
+
|
|
1799
|
+
| Approach | Input | Output | Intelligence |
|
|
1800
|
+
|----------|-------|--------|--------------|
|
|
1801
|
+
| **Traditional Coding** | Implementation | Executable | None |
|
|
1802
|
+
| **Code Generation (Copilot)** | Context + partial code | More code | Pattern matching |
|
|
1803
|
+
| **Low-Code (Retool)** | Visual config | App | Template filling |
|
|
1804
|
+
| **DSLs (Terraform)** | Declarative config | Infrastructure | Provider mapping |
|
|
1805
|
+
| **Kappa v1-v2** | Code specification | Expanded code | Boilerplate expansion |
|
|
1806
|
+
| **Kappa v3** | Outcomes + Constraints | Optimal implementation | Constraint solving + synthesis |
|
|
1807
|
+
|
|
1808
|
+
### 7.2 Key Innovations
|
|
1809
|
+
|
|
1810
|
+
1. **Outcome Specification** — You specify what success looks like, not how to achieve it
|
|
1811
|
+
2. **Constraint Satisfaction** — System finds implementation meeting ALL constraints
|
|
1812
|
+
3. **Design Intent** — Mood and personality derive actual design, not just config
|
|
1813
|
+
4. **Journey-Centric** — User flows are first-class, not derived from routes
|
|
1814
|
+
5. **Bidirectional Sync** — Edit generated code, spec updates; edit spec, code regenerates
|
|
1815
|
+
6. **Provenance Tracking** — Every line traces to constraints, debuggable
|
|
1816
|
+
7. **Learning System** — Escape hatches teach new patterns, system evolves
|
|
1817
|
+
|
|
1818
|
+
### 7.3 Why It Works
|
|
1819
|
+
|
|
1820
|
+
The insight: **There's a finite, solvable design space.**
|
|
1821
|
+
|
|
1822
|
+
For any given set of:
|
|
1823
|
+
- Business goals
|
|
1824
|
+
- Security constraints
|
|
1825
|
+
- Performance constraints
|
|
1826
|
+
- Accessibility constraints
|
|
1827
|
+
- Design intent
|
|
1828
|
+
|
|
1829
|
+
There are only so many valid implementations. The space is large but bounded. A constraint solver can explore it.
|
|
1830
|
+
|
|
1831
|
+
Traditional programming makes humans explore this space manually. Kappa v3 makes the computer explore it systematically.
|
|
1832
|
+
|
|
1833
|
+
---
|
|
1834
|
+
|
|
1835
|
+
## Part VIII: Implementation Roadmap
|
|
1836
|
+
|
|
1837
|
+
### Phase 1: Core Language
|
|
1838
|
+
- Parser and analyzer
|
|
1839
|
+
- Constraint compiler
|
|
1840
|
+
- Basic generators (schema, API, pages)
|
|
1841
|
+
|
|
1842
|
+
### Phase 2: Constraint Solver
|
|
1843
|
+
- SAT/SMT integration
|
|
1844
|
+
- Conflict detection and resolution
|
|
1845
|
+
- Performance optimization
|
|
1846
|
+
|
|
1847
|
+
### Phase 3: Design System
|
|
1848
|
+
- Mood interpretation model
|
|
1849
|
+
- Design token generation
|
|
1850
|
+
- Component library integration
|
|
1851
|
+
|
|
1852
|
+
### Phase 4: Intelligence
|
|
1853
|
+
- Provenance tracking
|
|
1854
|
+
- Bidirectional sync
|
|
1855
|
+
- Pattern learning
|
|
1856
|
+
|
|
1857
|
+
### Phase 5: Ecosystem
|
|
1858
|
+
- Community pattern library
|
|
1859
|
+
- IDE integration
|
|
1860
|
+
- CI/CD integration
|
|
1861
|
+
|
|
1862
|
+
---
|
|
1863
|
+
|
|
1864
|
+
*Kappa v3: Tell the machine what success looks like. Let it figure out the rest.*
|