howone 0.1.30 → 0.1.32

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.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/templates/vite/.howone/skills/howone/01-architect/01-app-generation.md +138 -176
  3. package/templates/vite/.howone/skills/howone/01-architect/02-manifest-codegen.md +2 -2
  4. package/templates/vite/.howone/skills/howone/{02-database → 02-entity-schema}/01-schema-design.md +12 -30
  5. package/templates/vite/.howone/skills/howone/02-entity-schema/02-schema-operations.md +329 -0
  6. package/templates/vite/.howone/skills/howone/02-entity-schema/03-access-models.md +151 -0
  7. package/templates/vite/.howone/skills/howone/02-entity-schema/04-query-contracts.md +123 -0
  8. package/templates/vite/.howone/skills/howone/02-entity-schema/05-ai-persistence-patterns.md +255 -0
  9. package/templates/vite/.howone/skills/howone/{04-ai → 03-ai-capabilities}/01-ai-capability-architecture.md +42 -36
  10. package/templates/vite/.howone/skills/howone/{04-ai → 03-ai-capabilities}/02-workflow-contract-rules.md +5 -4
  11. package/templates/vite/.howone/skills/howone/{04-ai/04-service-capability-catalog.md → 03-ai-capabilities/03-service-capability-catalog.md} +15 -11
  12. package/templates/vite/.howone/skills/howone/03-ai-capabilities/04-workflow-operations.md +141 -0
  13. package/templates/vite/.howone/skills/howone/{04-ai/06-ai-feature-playbooks.md → 03-ai-capabilities/05-ai-feature-playbooks.md} +8 -29
  14. package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/01-client-setup.md +7 -6
  15. package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/07-ai-action-calls.md +5 -5
  16. package/templates/vite/.howone/skills/howone/{04-ai/03-ai-sdk-handoff.md → 04-app-sdk/08-ai-manifest-handoff.md} +8 -7
  17. package/templates/vite/.howone/skills/howone/{03-sdk/08-extension-boundaries.md → 04-app-sdk/09-extension-boundaries.md} +1 -1
  18. package/templates/vite/.howone/skills/howone/{02-database/03-data-access-patterns.md → 04-app-sdk/11-entity-data-access-patterns.md} +4 -4
  19. package/templates/vite/.howone/skills/howone/{02-database/04-query-dsl-and-responses.md → 04-app-sdk/12-query-dsl-and-responses.md} +1 -1
  20. package/templates/vite/.howone/skills/howone/SKILL.md +137 -133
  21. package/templates/vite/.howone/skills/howone/agents/openai.yaml +3 -3
  22. package/templates/vite/AGENTS.md +2 -2
  23. package/templates/vite/.howone/skills/howone/02-database/02-schema-operations.md +0 -398
  24. package/templates/vite/.howone/skills/howone/02-database/05-ai-persistence-patterns.md +0 -372
  25. package/templates/vite/.howone/skills/howone/04-ai/05-workflow-operations.md +0 -256
  26. /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/02-entity-operations.md +0 -0
  27. /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/03-auth.md +0 -0
  28. /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/04-react-integration.md +0 -0
  29. /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/05-file-upload.md +0 -0
  30. /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/06-raw-http.md +0 -0
  31. /package/templates/vite/.howone/skills/howone/{03-sdk/09-workflow-execute-sse.md → 04-app-sdk/10-workflow-execute-sse.md} +0 -0
@@ -0,0 +1,255 @@
1
+ # AI Persistence Entity Patterns
2
+
3
+ Use this reference after the AI output schema is known and the product needs durable data:
4
+ generation history, saved results, reports, retryable jobs, share pages, or user libraries.
5
+
6
+ This is a backend entity design reference. It does not define SDK calls. App-side execution and
7
+ persistence code belongs in `04-app-sdk/07-ai-action-calls.md` and
8
+ `04-app-sdk/08-ai-manifest-handoff.md`.
9
+
10
+ ## Core Boundary
11
+
12
+ ```text
13
+ AI capability outputSchema != database entity schema
14
+ ```
15
+
16
+ The AI output schema is the workflow return contract. The database entity schema is the product
17
+ record contract. Persist only fields the product needs after refresh, across sessions, in lists, or
18
+ on public pages.
19
+
20
+ For every AI output field, decide:
21
+
22
+ | Question | Persist? | Entity design |
23
+ |---|---:|---|
24
+ | User must see it after refresh | yes | explicit field |
25
+ | It appears in history/library/search | yes | field + index if queried |
26
+ | It is needed for retry/resume | yes | input/options/status fields |
27
+ | It is only a streaming/intermediate chunk | no | runtime/UI state |
28
+ | It is provider debug metadata | usually no | logs, not product records |
29
+ | It is sensitive internal/provider data | usually no | omit or keep private-only |
30
+
31
+ ## Pending-First Record Model
32
+
33
+ For long-running or user-visible AI jobs, design an entity that can represent pending, completed,
34
+ and failed states. The app may create a pending record before workflow execution, then update it
35
+ after completion or failure.
36
+
37
+ Required contract pieces:
38
+
39
+ - original user input or durable input reference;
40
+ - `status`;
41
+ - output fields for completed display;
42
+ - failure fields for history/retry;
43
+ - timestamps for list ordering and stale-job handling.
44
+
45
+ Status field:
46
+
47
+ ```json
48
+ {
49
+ "status": {
50
+ "type": "string",
51
+ "description": "pending | running | completed | failed | canceled",
52
+ "default": "pending"
53
+ }
54
+ }
55
+ ```
56
+
57
+ Rules:
58
+
59
+ - Do not infer completion only from `resultUrl`, `summary`, or another output field.
60
+ - Keep failed records when the product has history or retry UX.
61
+ - If pending/running records are shown from persisted data, define how stale records are recovered.
62
+ - Do not store raw event streams unless the entity explicitly needs them.
63
+
64
+ ## Minimal Generation History Entity
65
+
66
+ Use for image, text, report, music, video, or similar generation history.
67
+
68
+ ```json
69
+ {
70
+ "name": "Generation",
71
+ "type": "object",
72
+ "properties": {
73
+ "prompt": { "type": "string" },
74
+ "status": { "type": "string", "default": "pending" },
75
+ "resultUrl": { "type": ["string", "null"], "default": null },
76
+ "resultText": { "type": ["string", "null"], "default": null },
77
+ "errorMessage": { "type": ["string", "null"], "default": null },
78
+ "requestedAt": { "type": "date" },
79
+ "completedAt": { "type": ["date", "null"], "default": null }
80
+ },
81
+ "required": ["prompt", "status", "requestedAt"],
82
+ "access": {
83
+ "authenticated": { "read": "own", "create": "own", "update": "own", "delete": "own" },
84
+ "public": { "read": "none", "create": "none", "update": "none", "delete": "none" }
85
+ },
86
+ "indexes": [
87
+ { "name": "owner_updated", "fields": ["updatedDate"], "scope": "owner" },
88
+ { "name": "owner_status_updated", "fields": ["status", "updatedDate"], "scope": "owner" }
89
+ ],
90
+ "performance": {
91
+ "defaultLimit": 20,
92
+ "maxLimit": 100,
93
+ "allowedSorts": ["updatedDate", "requestedAt"]
94
+ },
95
+ "presentation": {
96
+ "titleField": "prompt",
97
+ "subtitleField": "status"
98
+ }
99
+ }
100
+ ```
101
+
102
+ Prefer separate product fields over one opaque `result` object when the UI lists, filters, previews,
103
+ or shares the output. Use an object field only for genuinely nested product-level structured data.
104
+
105
+ ## Structured Analysis Report Entity
106
+
107
+ Use when AI returns a report users browse later.
108
+
109
+ ```json
110
+ {
111
+ "name": "AnalysisReport",
112
+ "type": "object",
113
+ "properties": {
114
+ "sourceTitle": { "type": "string" },
115
+ "sourceUrl": { "type": ["string", "null"], "default": null },
116
+ "status": { "type": "string", "default": "pending" },
117
+ "summary": { "type": ["string", "null"], "default": null },
118
+ "insights": { "type": "array", "default": [] },
119
+ "score": { "type": ["number", "null"], "default": null },
120
+ "errorMessage": { "type": ["string", "null"], "default": null },
121
+ "requestedAt": { "type": "date" },
122
+ "completedAt": { "type": ["date", "null"], "default": null }
123
+ },
124
+ "required": ["sourceTitle", "status", "requestedAt"],
125
+ "access": {
126
+ "authenticated": { "read": "own", "create": "own", "update": "own", "delete": "own" },
127
+ "public": { "read": "none", "create": "none", "update": "none", "delete": "none" }
128
+ },
129
+ "indexes": [
130
+ { "name": "owner_updated", "fields": ["updatedDate"], "scope": "owner" },
131
+ { "name": "owner_score_updated", "fields": ["score", "updatedDate"], "scope": "owner" }
132
+ ]
133
+ }
134
+ ```
135
+
136
+ Mapping rule:
137
+
138
+ ```text
139
+ workflow input.sourceTitle -> AnalysisReport.sourceTitle
140
+ workflow input.sourceUrl -> AnalysisReport.sourceUrl
141
+ workflow output.summary -> AnalysisReport.summary
142
+ workflow output.insights -> AnalysisReport.insights
143
+ workflow output.score -> AnalysisReport.score
144
+ runtime failure -> AnalysisReport.errorMessage
145
+ runtime completed -> AnalysisReport.completedAt
146
+ ```
147
+
148
+ Do not save the whole workflow envelope unless the product explicitly needs a private object field
149
+ for audit/debug.
150
+
151
+ ## Public Share Split
152
+
153
+ For public AI result pages, split private history from public share data:
154
+
155
+ - private `Generation` stores prompts, failures, drafts, internal metadata, and user history;
156
+ - public/scoped `SharedGeneration` stores only curated fields for anonymous viewing.
157
+
158
+ Scoped public share entity:
159
+
160
+ ```json
161
+ {
162
+ "name": "SharedGeneration",
163
+ "type": "object",
164
+ "properties": {
165
+ "shareId": {
166
+ "type": "string",
167
+ "autoGenerate": { "strategy": "uuid" }
168
+ },
169
+ "title": { "type": "string" },
170
+ "resultUrl": { "type": "string" },
171
+ "active": { "type": "boolean", "default": true },
172
+ "sourceGenerationId": { "type": "string" }
173
+ },
174
+ "required": ["shareId", "title", "resultUrl", "active", "sourceGenerationId"],
175
+ "access": {
176
+ "authenticated": { "read": "own", "create": "own", "update": "own", "delete": "own" },
177
+ "public": {
178
+ "read": "scoped",
179
+ "create": "none",
180
+ "update": "none",
181
+ "delete": "none",
182
+ "requiredScopes": ["shareId"],
183
+ "allowedFilters": ["shareId", "active"],
184
+ "allowedSorts": ["updatedDate"],
185
+ "defaultLimit": 1,
186
+ "maxLimit": 1
187
+ }
188
+ },
189
+ "indexes": [
190
+ { "name": "share_id_unique", "fields": ["shareId"], "unique": true },
191
+ { "name": "owner_updated", "fields": ["updatedDate"], "scope": "owner" }
192
+ ]
193
+ }
194
+ ```
195
+
196
+ Never make the main private generation history public just to support share pages.
197
+
198
+ ## Retry And Resume Fields
199
+
200
+ If retry is part of the product, persist enough input fields to rebuild the workflow request:
201
+
202
+ - prompt/source content reference;
203
+ - selected style/mode/options;
204
+ - uploaded file URLs or file IDs;
205
+ - status and error message;
206
+ - requested/completed timestamps.
207
+
208
+ Do not persist:
209
+
210
+ - auth/session/token values;
211
+ - raw uploaded browser bytes;
212
+ - temporary component state;
213
+ - raw streaming chunks;
214
+ - provider secrets;
215
+ - hidden system prompts or internal prompts.
216
+
217
+ Prefer a new retry record for history-oriented products. Prefer updating the same record only when
218
+ retry semantically replaces the original attempt.
219
+
220
+ ## Field Mapping Checklist
221
+
222
+ Before app implementation, write the mapping explicitly:
223
+
224
+ ```text
225
+ workflow input.prompt -> Generation.prompt
226
+ workflow input.style -> Generation.style
227
+ workflow output.imageUrl -> Generation.resultUrl
228
+ workflow output.caption -> Generation.resultText
229
+ workflow error.message -> Generation.errorMessage
230
+ runtime request started -> Generation.requestedAt
231
+ runtime request completed -> Generation.completedAt
232
+ ```
233
+
234
+ If a workflow output has no mapping, decide whether it is intentionally transient or the entity
235
+ schema is missing a product field.
236
+
237
+ ## Access Checklist
238
+
239
+ | Product behavior | Entity access |
240
+ |---|---|
241
+ | User-only private generation history | authenticated own, public none |
242
+ | Shared authenticated library | authenticated all, public none |
243
+ | Anonymous public gallery | public list with safe fields only |
244
+ | One public share link | public scoped with share id |
245
+ | Public submission to AI queue | public create only with anti-abuse constraints |
246
+
247
+ ## Persistence Checklist
248
+
249
+ - AI output schema is fixed before persistence schema design.
250
+ - Entity stores product fields, not workflow internals.
251
+ - Status and failure fields exist for long-running jobs.
252
+ - Retry/resume input fields are durable.
253
+ - Public share data is split from private history.
254
+ - Indexes match history/share/list query patterns.
255
+ - SDK implementation begins only after database and AI manifests are synced.
@@ -1,11 +1,12 @@
1
1
  # AI Capability Architecture
2
2
 
3
- Use this reference when a HowOne app needs AI generation, editing, analysis, research, media
4
- creation, file generation, or any workflow-backed behavior.
3
+ **Track:** `03-ai-capabilities/` capability/workflow **design** only; SDK calls live in `04-app-sdk/`.
4
+
5
+ Use this reference when the user needs HowOne platform AI (verify `03-service-capability-catalog.md` first).
5
6
 
6
7
  This file answers: **what AI layer should be designed, in what order, and where each responsibility
7
8
  belongs?** For schema details read `02-workflow-contract-rules.md`. For workflow service calls read
8
- `05-workflow-operations.md`.
9
+ `04-workflow-operations.md`.
9
10
 
10
11
  ## Platform Mental Model
11
12
 
@@ -15,9 +16,9 @@ HowOne AI has five distinct layers:
15
16
  |---|---|---|
16
17
  | Product feature | User-facing goal, UX states, persistence decision | workflow internals |
17
18
  | AI capability contract | `name`, `description`, `inputSchema`, `outputSchema`, `outputEntityName`, versions, manifest | database CRUD, UI, auth |
18
- | External workflow implementation | generated/edited workflow graph behind a `workflowId` | app schema, frontend state |
19
- | Status/background layer | `request_id` polling, completed/failed state, `workflowConfigID` capture | SDK binding source |
20
- | SDK binding/app code | `defineAiAction`, Zod schemas, `howone.ai.*`, persistence through entities | workflow generation |
19
+ | External workflow implementation | generated/edited workflow graph behind a manifest `workflowId`/EAX `config_id` | app schema, frontend state |
20
+ | Status/background layer | job/task polling, completed/failed state, submitted config mapping | SDK binding source |
21
+ | SDK handoff | synced manifest action names, workflow IDs, input/output schemas | workflow generation |
21
22
 
22
23
  Do not collapse these layers. The common mistakes are:
23
24
 
@@ -33,10 +34,9 @@ Do not collapse these layers. The common mistakes are:
33
34
  user request = intent
34
35
  agent AI contract proposal = draft
35
36
  applied AI capability version = validated contract
36
- .howone/ai/manifest.json = local synced source for SDK codegen
37
- workflow service completed status = source for workflowConfigID
38
- src/lib/sdk.ts = generated app binding
39
- frontend UI = SDK consumer
37
+ .howone/ai/manifest.json = local synced source for workflow submit and later SDK codegen
38
+ external-ai-capability result = job/task/config mapping and possible manifest workflowId update
39
+ SDK/UI implementation = separate app-sdk track after AI design is complete
40
40
  entity schema = persistence contract, separate from AI contract
41
41
  ```
42
42
 
@@ -46,19 +46,18 @@ Never generate SDK bindings from the user prompt or from an unsynced draft.
46
46
 
47
47
  Use this flow for new AI features:
48
48
 
49
- 1. Classify the feature using `04-ai/04-service-capability-catalog.md`.
49
+ 1. Classify the feature using `03-ai-capabilities/03-service-capability-catalog.md`.
50
50
  2. Decide whether the feature is supported. If not supported, stop and explain the missing capability.
51
51
  3. Decide one workflow per user-facing feature. Use two workflows only for RAG.
52
52
  4. Design `inputSchema` and `outputSchema` using `02-workflow-contract-rules.md`.
53
- 5. Preview/apply the AI capability patch through the capability tool.
53
+ 5. Apply the AI capability patch through the capability tool.
54
54
  6. Sync `.howone/ai/manifest.json`.
55
- 7. Submit workflow create through `external-ai-capability` / workflow operate from the synced manifest.
56
- 8. Store returned `request_id` values for polling.
55
+ 7. Submit workflow create/update through `external-ai-capability` from the synced manifest.
56
+ 8. Store returned job/task IDs and submitted config IDs for polling/debugging.
57
57
  9. Poll status until `completed` or `failed`.
58
- 10. On completed + `payload.success === true`, store `payload.workflow_details.new_workflow_config_id`.
59
- 11. Generate/update `src/lib/sdk.ts` using `03-ai-sdk-handoff.md` and `01-architect/02-manifest-codegen.md`.
60
- 12. Implement UI calls through `howone.ai.<action>.run()`, `.stream()`, or `.events()`.
61
- 13. If output must persist, design entity schema and use `runAiActionAndPersist()` when appropriate.
58
+ 10. Re-read `.howone/ai/manifest.json`; update operations may have written fresh `workflowId` values.
59
+ 11. Leave AI design. If app code must call the workflow, read the SDK track and generate bindings.
60
+ 12. If output must persist, design entity schema after the output contract is fixed.
62
61
 
63
62
  Do not submit external workflow create/update from a hand-written schema. It should come from the
64
63
  synced manifest.
@@ -70,7 +69,7 @@ synced manifest.
70
69
  | New AI feature, no manifest entry | create AI capability, sync manifest, submit workflow create |
71
70
  | Manifest entry exists but no workflow created yet | submit workflow create from manifest |
72
71
  | User asks to change input/output contract | update capability contract first, sync, then submit workflow update |
73
- | User asks to improve behavior only | submit workflow update with `workflowConfigID` and `updatePrompt` |
72
+ | User asks to improve behavior only | submit workflow update with `updates[]` and `updatePrompt` |
74
73
  | User asks to save outputs/history | design/update database entity after AI output contract is known |
75
74
  | User asks for public share of AI result | private history entity + public scoped share entity |
76
75
 
@@ -80,23 +79,30 @@ Create external workflow when:
80
79
 
81
80
  - capability has a `workflowId`;
82
81
  - no confirmed external implementation exists;
83
- - no `workflowConfigID` has been captured.
82
+ - the manifest `workflowId` has not already been submitted as an implementation config.
84
83
 
85
84
  Update external workflow when:
86
85
 
87
86
  - an external implementation exists;
88
- - the status layer previously returned `payload.workflow_details.new_workflow_config_id`;
89
87
  - you have a concrete `updatePrompt`.
88
+ - `external-ai-capability` can read the current manifest `workflowId`.
90
89
 
91
- `workflowConfigID` is not the same as `workflowId`.
90
+ Current `external-ai-capability` semantics:
92
91
 
93
92
  ```text
94
- workflowId = stable workflow UUID from manifest, used by SDK execution
95
- workflowConfigID = implementation config ID from completed workflow generation/edit status
96
- request_id = async operation ID returned by workflow operate endpoint
93
+ create:
94
+ config_id = manifest capability.workflowId
95
+ mode = create
96
+
97
+ update:
98
+ previous config = current manifest capability.workflowId
99
+ new config = freshly generated UUID
100
+ manifest = rewritten so capability.workflowId is the fresh UUID
97
101
  ```
98
102
 
99
- Do not invent any of these IDs.
103
+ The SDK execution binding uses the manifest `workflowId`, which is the EAX config id. After update,
104
+ the new manifest `workflowId` is the only value that should be copied into `src/lib/sdk.ts`.
105
+ Do not invent IDs; let the AI design/sync/external workflow tools generate and persist them.
100
106
 
101
107
  ## Workflow Count Rule
102
108
 
@@ -136,18 +142,18 @@ Workflow must not do:
136
142
  - owner assignment or permissions;
137
143
  - app navigation, UI state, toast, or modal logic.
138
144
 
139
- If the product needs durable history, use entity persistence outside the workflow:
145
+ If the product needs durable history, design entity persistence outside the workflow:
140
146
 
141
- ```ts
142
- await runAiActionAndPersist({
143
- entity: howone.entities.Generation,
144
- input,
145
- createPending: (input) => ({ prompt: input.prompt, status: 'pending' }),
146
- run: (input) => howone.ai.generateImage.run(input),
147
- mapCompleted: ({ output }) => ({ status: 'completed', resultUrl: output.generated_image_url }),
148
- })
147
+ ```text
148
+ workflow input.prompt -> Generation.prompt
149
+ workflow output.imageUrl -> Generation.resultUrl
150
+ runtime failure -> Generation.errorMessage
151
+ runtime status -> Generation.status
149
152
  ```
150
153
 
154
+ After AI and database manifests are synced, app implementation can read the SDK track to wire the
155
+ runtime calls.
156
+
151
157
  ## Unsupported AI Behavior
152
158
 
153
159
  If a user explicitly requires behavior not available in the workflow service, stop that AI path.
@@ -201,5 +207,5 @@ Before editing files:
201
207
  - Input and output property names do not overlap.
202
208
  - Text output descriptions specify language behavior.
203
209
  - Persistence is modeled as entity schema, not workflow CRUD.
204
- - `workflowId`, `request_id`, and `workflowConfigID` are not guessed.
210
+ - `workflowId` / EAX `config_id` values are generated by tools and not guessed.
205
211
  - SDK binding will be generated only after manifest sync.
@@ -4,7 +4,7 @@ Use this reference when designing `capability.description`, `inputSchema`, `outp
4
4
  `outputEntityName` for HowOne AI workflows.
5
5
 
6
6
  These rules come from `docs/ai-worlfow-guide-schema.md`. Violating them can make the workflow
7
- service reject the request or produce a workflow that the SDK cannot call reliably.
7
+ service reject the request or produce a workflow the runtime cannot execute reliably.
8
8
 
9
9
  ## Contract Shape
10
10
 
@@ -122,7 +122,8 @@ Forbidden:
122
122
  - inline PDF/image/audio bytes;
123
123
  - browser upload logic in workflow.
124
124
 
125
- The app uploads first through `howone.upload.*`, then passes the URL to the workflow.
125
+ The app uploads first, then passes the resulting URL to the workflow. File upload helpers belong to
126
+ the SDK track.
126
127
 
127
128
  ## Output Minimalism
128
129
 
@@ -227,8 +228,8 @@ Forbidden in capability descriptions and schemas:
227
228
  Instead:
228
229
 
229
230
  1. workflow returns output fields;
230
- 2. frontend/server code calls SDK entity methods;
231
- 3. persistence helper maps durable fields.
231
+ 2. app code persists through the entity runtime after SDK handoff;
232
+ 3. durable fields map to the entity contract.
232
233
 
233
234
  ## External Data Assumptions
234
235
 
@@ -1,7 +1,11 @@
1
1
  # Service Capability Catalog
2
2
 
3
- Use this reference before designing an AI workflow. It tells the agent what the current workflow
4
- service can actually do and what input/output shapes are expected.
3
+ Use this reference **only** for HowOne **workflow-service AI** feasibility. It lists what the current
4
+ workflow service supports—not everything a full product may use.
5
+
6
+ Infrastructure or products the user operates themselves (clusters, custom servers, third-party
7
+ APIs, etc.) are **app-owned** per `01-architect/01-app-generation.md`. They are out of scope for
8
+ this catalog and must not be rejected as "AI not supported" when the user only needs to connect to them in app code.
5
9
 
6
10
  Source: `docs/ai-capability.md`.
7
11
 
@@ -268,14 +272,14 @@ Rules:
268
272
  | Video -> Image edit -> Video | extract frame, edit frame, use as next reference |
269
273
  | RAG document chat | indexing workflow + query workflow |
270
274
 
271
- ## Capability Rejection Checklist
275
+ ## Platform AI stop (catalog boundary)
276
+
277
+ Stop **platform AI design** (do not invent capabilities) when the requirement:
272
278
 
273
- Stop or narrow scope if user requires:
279
+ - has no matching capability family in this catalog or detailed sections below;
280
+ - needs behavior the workflow service cannot perform per contract rules in `02-workflow-contract-rules.md`;
281
+ - violates workflow input/output constraints (e.g. persistence or app CRUD inside the workflow contract);
282
+ - exceeds documented service limits after you read the relevant section.
274
283
 
275
- - real-time streaming market data;
276
- - arbitrary external API calls not listed;
277
- - raw file bytes/base64 in workflow;
278
- - database CRUD inside workflow;
279
- - unsupported provider-specific model guarantees;
280
- - content disallowed by moderation;
281
- - long video generation in one call beyond service limits.
284
+ Explain the gap by **missing catalog/contract support**, not by naming the user's stack. Offer the
285
+ closest listed capability or ask to narrow the product ask. App-owned integrations remain allowed in parallel.
@@ -0,0 +1,141 @@
1
+ # Workflow Operations
2
+
3
+ Use this reference when submitting HowOne external AI workflow create/update operations through
4
+ `external-ai-capability`. This is an AI workflow design reference, not an app SDK guide.
5
+
6
+ ## Current Tool Contract
7
+
8
+ Do not hand-build raw workflow HTTP requests in generated app work. Use `external-ai-capability`
9
+ after `.howone/ai/manifest.json` has been synced.
10
+
11
+ The tool performs:
12
+
13
+ ```text
14
+ POST /workflows
15
+ GET /jobs/{job_id}
16
+ ```
17
+
18
+ The tool reads the synced manifest and submits operations for selected capabilities.
19
+
20
+ ## Create
21
+
22
+ Use create when the capability has a synced manifest entry and no external implementation has been
23
+ submitted for its current `workflowId`.
24
+
25
+ Tool input:
26
+
27
+ ```json
28
+ {
29
+ "cwd": "<app-root>",
30
+ "capabilityNames": ["summarizeDocument"]
31
+ }
32
+ ```
33
+
34
+ Tool behavior:
35
+
36
+ ```text
37
+ config_id = manifest.capabilities[].workflowId
38
+ mode = create
39
+ capability = synced manifest capability contract
40
+ ```
41
+
42
+ Do not generate a second UUID for create. The AI capability design/sync path already produced the
43
+ manifest `workflowId`.
44
+
45
+ ## Update
46
+
47
+ Use update when the external implementation exists and the user asks to change workflow behavior or
48
+ to regenerate implementation for a changed contract.
49
+
50
+ Tool input:
51
+
52
+ ```json
53
+ {
54
+ "cwd": "<app-root>",
55
+ "updates": [
56
+ {
57
+ "capabilityName": "summarizeDocument",
58
+ "updatePrompt": "Support concise bullet-point summaries when the user asks for bullet format."
59
+ }
60
+ ]
61
+ }
62
+ ```
63
+
64
+ Tool behavior:
65
+
66
+ ```text
67
+ previous config = current manifest capability.workflowId
68
+ new config = freshly generated UUID
69
+ mode = update
70
+ manifest = rewritten so capability.workflowId is the fresh UUID
71
+ ```
72
+
73
+ After update, re-read `.howone/ai/manifest.json`. The new manifest `workflowId` is the value used by
74
+ SDK bindings and future execution.
75
+
76
+ Do not pass stale `workflowConfigID` values from old docs or older status payloads. The current
77
+ tool owns config rotation and manifest write-back.
78
+
79
+ ## Selection Rules
80
+
81
+ - `capabilityNames` limits create operations.
82
+ - `updates[]` limits update operations.
83
+ - If `updates[]` is provided without `capabilityNames`, only those update capabilities are selected.
84
+ - Do not submit every capability when the user asked to update one behavior.
85
+
86
+ ## Status And Results
87
+
88
+ The tool may return immediately when a host poller is available. Preserve:
89
+
90
+ - `jobId`;
91
+ - `taskId` / `requestId` when present;
92
+ - `submittedConfigId`;
93
+ - `previousConfigId` for updates;
94
+ - `manifestUpdates` mapping old workflow IDs to new workflow IDs.
95
+
96
+ Terminal result meaning:
97
+
98
+ | Status | Meaning |
99
+ |---|---|
100
+ | `submitted` | background poller will continue |
101
+ | `running` / `queued` | not terminal |
102
+ | `completed` | workflow operation completed |
103
+ | `failed` / `canceled` / `timed_out` | report error and do not pretend workflow is ready |
104
+
105
+ ## Standard Flow
106
+
107
+ New AI feature:
108
+
109
+ ```text
110
+ ai-capability-design apply_capability_patch
111
+ sync_ai_artifacts
112
+ external-ai-capability { cwd, capabilityNames }
113
+ read .howone/ai/manifest.json
114
+ ```
115
+
116
+ Schema-changing AI update:
117
+
118
+ ```text
119
+ ai-capability-design apply_capability_patch
120
+ sync_ai_artifacts
121
+ external-ai-capability { cwd, updates: [{ capabilityName, updatePrompt }] }
122
+ read .howone/ai/manifest.json
123
+ ```
124
+
125
+ Behavior-only update:
126
+
127
+ ```text
128
+ external-ai-capability { cwd, updates: [{ capabilityName, updatePrompt }] }
129
+ read .howone/ai/manifest.json
130
+ ```
131
+
132
+ SDK/code work happens after these steps and belongs to the SDK track.
133
+
134
+ ## Checklist
135
+
136
+ - Manifest is synced before submit.
137
+ - Create uses the existing manifest `workflowId`.
138
+ - Update lets the tool generate a fresh config UUID.
139
+ - Update has a concrete `updatePrompt`.
140
+ - The manifest is re-read after update.
141
+ - SDK bindings are copied from manifest, not from memory or old status IDs.