openapi.yaml yaml
4,472 lines 140.2 KB
Raw
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 9 days ago
1 openapi: 3.0.3
2 info:
3 title: Knowtation Hub API
4 description: REST API for the Knowtation Hub (vault read/write, proposals, capture). Same contract as CLI/MCP where applicable.
5 version: 1.0.0
6 links:
7 - description: API contract (human-readable)
8 url: ./HUB-API.md
9
10 servers:
11 - url: /api/v1
12 description: Relative to Hub base URL (e.g. https://hub.example.com)
13
14 tags:
15 - name: Health
16 - name: Auth
17 - name: Notes
18 - name: Search
19 - name: Proposals
20 - name: Capture
21 - name: Flows
22 - name: Tasks
23 - name: LearningPaths
24 - name: Attachments
25 - name: DocsConnectors
26 - name: Automation
27
28 security:
29 - BearerAuth: []
30
31 paths:
32 /health:
33 get:
34 tags: [Health]
35 summary: Health check
36 security: []
37 responses:
38 '200':
39 description: Hub is up
40 content:
41 application/json:
42 schema: { type: object, properties: { ok: { type: boolean } }, required: [ok] }
43
44 /automation/ingest:
45 post:
46 tags: [Automation]
47 summary: AIP — preferred cron ingest
48 description: |
49 Routes a robot write by first-match per-account rules.
50 Requires agent_access with ingest:automation, or a session editor/admin/member.
51 Does not require vault:write. REST-only (no MCP).
52 parameters:
53 - name: X-Vault-Id
54 in: header
55 schema: { type: string }
56 - name: X-Ingest-Idempotency-Key
57 in: header
58 schema: { type: string }
59 requestBody:
60 required: true
61 content:
62 application/json:
63 schema:
64 type: object
65 required: [path, body, source_fingerprint]
66 properties:
67 path: { type: string }
68 body: { type: string }
69 frontmatter: { type: object }
70 intent: { type: string }
71 labels: { type: array, items: { type: string } }
72 source: { type: string }
73 source_fingerprint: { type: string }
74 content_class: { type: string, enum: [research, ops, general] }
75 ingest: { type: boolean }
76 responses:
77 '201':
78 description: First apply
79 '200':
80 description: Idempotent replay
81 '400':
82 description: Validation
83 '401':
84 description: Unauthorized
85 '403':
86 description: Vault forbidden
87 '409':
88 description: Path or idempotency conflict
89
90 /automation/ingest-rules:
91 get:
92 tags: [Automation]
93 summary: List ingest rules and disabled pack templates (session only)
94 responses:
95 '200':
96 description: '{ rules, templates }'
97 '401':
98 description: Unauthorized
99 put:
100 tags: [Automation]
101 summary: Replace ingest rules (session only)
102 responses:
103 '200':
104 description: Replaced
105 '400':
106 description: Validation or cap
107 '401':
108 description: Unauthorized
109 post:
110 tags: [Automation]
111 summary: Append one ingest rule (session only)
112 responses:
113 '201':
114 description: Created
115 '401':
116 description: Unauthorized
117
118 /automation/ingest-rules/from-template:
119 post:
120 tags: [Automation]
121 summary: Copy a pack template into user rules (stays disabled unless enable=true)
122 responses:
123 '201':
124 description: Copied
125 '401':
126 description: Unauthorized
127
128 /automation/ingest-rules/{rule_id}:
129 delete:
130 tags: [Automation]
131 summary: Delete one user ingest rule (session only)
132 parameters:
133 - name: rule_id
134 in: path
135 required: true
136 schema: { type: string }
137 responses:
138 '200':
139 description: Remaining rules
140 '401':
141 description: Unauthorized
142
143 /auth/agent/credentials:
144 post:
145 tags: [Auth]
146 summary: Phase C — mint scoped REST agent credential (secret once)
147 description: |
148 Requires a human session JWT. Returns opaque `kt_agent_<id>.<secret>` once.
149 Default scopes: propose + vault:read. No admin scopes.
150 responses:
151 '201':
152 description: Credential minted
153 '401':
154 description: Unauthorized
155 '409':
156 description: Credential limit
157 get:
158 tags: [Auth]
159 summary: Phase C — list agent credentials (metadata only)
160 responses:
161 '200':
162 description: Credential list without secrets; includes health fields and store banner flags
163 content:
164 application/json:
165 schema:
166 type: object
167 required: [credentials, store]
168 properties:
169 credentials:
170 type: array
171 items:
172 type: object
173 properties:
174 id: { type: string }
175 name: { type: string }
176 vault_ids: { type: array, items: { type: string } }
177 scopes: { type: array, items: { type: string } }
178 created_at: { type: number, nullable: true }
179 last_used_at: { type: number, nullable: true }
180 last_failure_code: { type: string, nullable: true, enum: [invalid, revoked, expired] }
181 last_failure_at: { type: number, nullable: true }
182 expires_at: { type: number, nullable: true }
183 revoked: { type: boolean }
184 revoked_at: { type: number, nullable: true }
185 store:
186 type: object
187 required: [wipe_required, inconsistent]
188 properties:
189 wipe_required: { type: boolean }
190 inconsistent: { type: boolean }
191 '503':
192 description: Agent credential store unavailable or inconsistent
193 content:
194 application/json:
195 schema:
196 type: object
197 properties:
198 code:
199 type: string
200 enum: [AGENT_CREDENTIAL_STORE_UNAVAILABLE, AGENT_CREDENTIAL_STORE_INCONSISTENT]
201 store:
202 type: object
203 properties:
204 inconsistent: { type: boolean }
205 /auth/agent/credentials/{id}:
206 delete:
207 tags: [Auth]
208 summary: Phase C — revoke agent credential
209 parameters:
210 - name: id
211 in: path
212 required: true
213 schema: { type: string }
214 responses:
215 '200':
216 description: Revoked (idempotent)
217 /auth/agent/credentials/{id}/rotate:
218 post:
219 tags: [Auth]
220 summary: Phase C — rotate agent credential secret (shown once)
221 parameters:
222 - name: id
223 in: path
224 required: true
225 schema: { type: string }
226 responses:
227 '200':
228 description: New secret issued
229 /auth/agent/token:
230 post:
231 tags: [Auth]
232 summary: Phase C — exchange kt_agent_ credential for agent_access JWT
233 security: []
234 responses:
235 '200':
236 description: Access token issued
237 '401':
238 description: Invalid credential
239 '503':
240 description: Agent credential store unavailable or inconsistent
241 content:
242 application/json:
243 schema:
244 type: object
245 properties:
246 code:
247 type: string
248 enum: [AGENT_CREDENTIAL_STORE_UNAVAILABLE, AGENT_CREDENTIAL_STORE_INCONSISTENT]
249
250 /api/v1/auth/session:
251 get:
252 tags: [Auth]
253 summary: C7 Session introspection — current identity and scopes
254 description: |
255 Returns the verified identity and derived API scopes for the caller. Accepts only a
256 `Bearer` JWT in the `Authorization` header — no cookie required, making it safe to call
257 cross-origin from Scooling or any other consumer.
258
259 The response is derived entirely from the signed token — no database call is made.
260 Scopes are role-derived today (C4 will replace this with per-user explicit grants without
261 changing the response shape).
262 security:
263 - bearerAuth: []
264 responses:
265 '200':
266 description: Verified session
267 content:
268 application/json:
269 schema:
270 type: object
271 required: [sub, provider, id, name, role, iat, exp, scopes]
272 properties:
273 sub:
274 type: string
275 description: Canonical user ID (`provider:id`)
276 example: google:104164334692309763642
277 provider:
278 type: string
279 enum: [google, github, apple]
280 id:
281 type: string
282 description: Provider-specific user ID
283 name:
284 type: string
285 description: Display name (empty for refresh-path tokens)
286 role:
287 type: string
288 enum: [admin, member]
289 iat:
290 type: integer
291 description: Token issued-at (Unix seconds)
292 exp:
293 type: integer
294 description: Token expires-at (Unix seconds)
295 scopes:
296 type: array
297 items: { type: string }
298 description: Derived API scopes. `admin` role → `[vault:read, vault:write, admin]`; `member` → `[vault:read, vault:write]`
299 example: [vault:read, vault:write]
300 '401':
301 description: Missing, expired, or tampered token
302 content:
303 application/json:
304 schema:
305 type: object
306 properties:
307 error: { type: string }
308 code: { type: string, enum: [UNAUTHORIZED] }
309
310 /auth/providers:
311 get:
312 tags: [Auth]
313 summary: OAuth providers configured
314 security: []
315 responses:
316 '200':
317 content:
318 application/json:
319 schema:
320 type: object
321 properties:
322 google: { type: boolean }
323 github: { type: boolean }
324 apple: { type: boolean }
325 local: { type: boolean }
326
327 /api/v1/auth/native-apple-exchange:
328 post:
329 tags: [Auth]
330 summary: Sign in with Apple identity-assertion exchange (native)
331 description: |
332 Verifies an Apple `identity_token` (JWKS) and mints a hosted session JWT
333 (`provider: apple`, `type: session`). Not Passport Google/GitHub and not
334 `api/v1/auth/native` PKCE. Does not return `scooling_uid`.
335 security: []
336 requestBody:
337 required: true
338 content:
339 application/json:
340 schema:
341 type: object
342 required: [identity_token]
343 additionalProperties: false
344 properties:
345 identity_token: { type: string }
346 nonce: { type: string }
347 full_name: { type: string, maxLength: 128 }
348 responses:
349 '200':
350 description: Hosted session minted
351 content:
352 application/json:
353 schema:
354 type: object
355 required: [schema_version, token_type, access_token, expires_in]
356 properties:
357 schema_version: { type: integer, enum: [1] }
358 token_type: { type: string, enum: [Bearer] }
359 access_token: { type: string }
360 expires_in: { type: integer }
361 '400':
362 description: Bad request
363 '401':
364 description: Apple assertion invalid
365 '403':
366 description: Offline-locked OAuth disabled
367 '503':
368 description: Not configured or Apple JWKS unavailable
369
370 /notes/facets:
371 get:
372 tags: [Notes]
373 summary: Projects, tags, folders for filter dropdowns
374 responses:
375 '200':
376 content:
377 application/json:
378 schema:
379 type: object
380 properties:
381 projects: { type: array, items: { type: string } }
382 tags: { type: array, items: { type: string } }
383 folders: { type: array, items: { type: string } }
384
385 /notes:
386 get:
387 tags: [Notes]
388 summary: List notes
389 parameters:
390 - name: folder
391 in: query
392 schema: { type: string }
393 - name: project
394 in: query
395 schema: { type: string }
396 - name: tag
397 in: query
398 schema: { type: string }
399 - name: since
400 in: query
401 schema: { type: string }
402 - name: until
403 in: query
404 schema: { type: string }
405 - name: limit
406 in: query
407 schema: { type: integer, minimum: 0, maximum: 100 }
408 - name: offset
409 in: query
410 schema: { type: integer, minimum: 0 }
411 - name: order
412 in: query
413 schema: { type: string, enum: [date, date-asc] }
414 - name: fields
415 in: query
416 schema: { type: string, enum: [path, path+metadata, full] }
417 - name: count_only
418 in: query
419 schema: { type: boolean }
420 - name: content_class
421 in: query
422 schema: { type: string, enum: [research, ops, general] }
423 responses:
424 '200':
425 content:
426 application/json:
427 schema:
428 oneOf:
429 - type: object
430 properties:
431 notes: { type: array, items: { $ref: '#/components/schemas/NoteListItem' } }
432 total: { type: integer }
433 - type: object
434 properties:
435 total: { type: integer }
436 post:
437 tags: [Notes]
438 summary: Write or update a note
439 requestBody:
440 required: true
441 content:
442 application/json:
443 schema:
444 type: object
445 required: [path]
446 properties:
447 path: { type: string }
448 body: { type: string }
449 frontmatter: { type: object }
450 append: { type: boolean }
451 responses:
452 '200':
453 content:
454 application/json:
455 schema: { type: object, properties: { path: { type: string }, written: { type: boolean } } }
456 '400':
457 '500':
458 content:
459 application/json:
460 schema: { $ref: '#/components/schemas/Error' }
461
462 /notes/{path}:
463 get:
464 tags: [Notes]
465 summary: Get one note by path
466 parameters:
467 - name: path
468 in: path
469 required: true
470 schema: { type: string }
471 responses:
472 '200':
473 content:
474 application/json:
475 schema: { $ref: '#/components/schemas/NoteFull' }
476 '404':
477 content:
478 application/json:
479 schema: { $ref: '#/components/schemas/Error' }
480
481 /note-outline:
482 get:
483 tags: [Notes]
484 summary: Body-free NoteOutline headings for one note
485 description: >
486 Returns knowtation.note_outline/v1 metadata for one authorized vault-relative note.
487 The response excludes note body text, snippets, full frontmatter, absolute paths,
488 provider payloads, MCP resource URIs, summaries, vectors, OCR, PageIndex output,
489 persistence records, and write-back state.
490 parameters:
491 - name: path
492 in: query
493 required: true
494 schema: { type: string }
495 description: Vault-relative Markdown note path.
496 responses:
497 '200':
498 content:
499 application/json:
500 schema: { $ref: '#/components/schemas/NoteOutline' }
501 '400':
502 content:
503 application/json:
504 schema: { $ref: '#/components/schemas/Error' }
505 '401':
506 content:
507 application/json:
508 schema: { $ref: '#/components/schemas/Error' }
509 '403':
510 content:
511 application/json:
512 schema: { $ref: '#/components/schemas/Error' }
513 '404':
514 content:
515 application/json:
516 schema: { $ref: '#/components/schemas/Error' }
517 '502':
518 content:
519 application/json:
520 schema: { $ref: '#/components/schemas/Error' }
521
522 /document-tree:
523 get:
524 tags: [Notes]
525 summary: Body-free DocumentTree heading hierarchy for one note
526 description: >
527 Returns knowtation.document_tree/v0 metadata for one authorized vault-relative note.
528 The response excludes note body text, snippets, full frontmatter, absolute paths,
529 provider payloads, MCP resource URIs, summaries, vectors, OCR, PageIndex output,
530 persistence records, sidecars, LLM calls, and write-back state.
531 parameters:
532 - name: path
533 in: query
534 required: true
535 schema: { type: string }
536 description: Vault-relative Markdown note path.
537 responses:
538 '200':
539 content:
540 application/json:
541 schema: { $ref: '#/components/schemas/DocumentTree' }
542 '400':
543 content:
544 application/json:
545 schema: { $ref: '#/components/schemas/Error' }
546 '401':
547 content:
548 application/json:
549 schema: { $ref: '#/components/schemas/Error' }
550 '403':
551 content:
552 application/json:
553 schema: { $ref: '#/components/schemas/Error' }
554 '404':
555 content:
556 application/json:
557 schema: { $ref: '#/components/schemas/Error' }
558 '502':
559 content:
560 application/json:
561 schema: { $ref: '#/components/schemas/Error' }
562
563 /calendar/timeline:
564 get:
565 tags: [Calendar]
566 summary: Merged note-date and external-event timeline (self-hosted)
567 description: >
568 Returns knowtation.calendar_timeline/v0 items for an authorized vault.
569 Merges note-date buckets and stored calendar events. No OAuth tokens or connector secrets.
570 parameters:
571 - name: from
572 in: query
573 required: true
574 schema: { type: string }
575 description: Range start (YYYY-MM-DD or ISO8601).
576 - name: to
577 in: query
578 required: true
579 schema: { type: string }
580 description: Range end (YYYY-MM-DD or ISO8601).
581 - name: layers
582 in: query
583 required: false
584 schema: { type: string }
585 description: Comma-separated layers (`notes`, `events`). Default both.
586 - name: source_calendar_ids
587 in: query
588 required: false
589 schema: { type: string }
590 description: Comma-separated source calendar ids to include for the events layer.
591 responses:
592 '200':
593 content:
594 application/json:
595 schema: { $ref: '#/components/schemas/CalendarTimeline' }
596 '400':
597 content:
598 application/json:
599 schema: { $ref: '#/components/schemas/Error' }
600 '401':
601 content:
602 application/json:
603 schema: { $ref: '#/components/schemas/Error' }
604 '403':
605 content:
606 application/json:
607 schema: { $ref: '#/components/schemas/Error' }
608
609 /calendar/agent-context:
610 get:
611 tags: [Calendar]
612 summary: Tier-enforced calendar context for agents (self-hosted)
613 description: >
614 Returns knowtation.calendar_agent_context/v0 — redacted calendar events an agent
615 may see. Enforced server-side: calendars with enabled_for_agents=false contribute
616 nothing; per-calendar agent_context_tier_max and the org policy cap clamp the tier;
617 the v0 retrieval ceiling is tier 2. Agent visibility is independent of
618 enabled_for_display. Tier 1 omits the event summary; tier 0 returns no events.
619 Calendar text is untrusted prompt content.
620 parameters:
621 - name: from
622 in: query
623 required: true
624 schema: { type: string }
625 description: Range start (YYYY-MM-DD or ISO8601).
626 - name: to
627 in: query
628 required: true
629 schema: { type: string }
630 description: Range end (YYYY-MM-DD or ISO8601).
631 - name: agent_context_tier
632 in: query
633 required: true
634 schema: { type: integer, minimum: 0, maximum: 2 }
635 description: Requested agent tier (0 none, 1 busy blocks, 2 titles + label). Clamped by caps.
636 - name: source_calendar_ids
637 in: query
638 required: false
639 schema: { type: string }
640 description: Comma-separated source calendar ids to restrict the agent scope.
641 responses:
642 '200':
643 content:
644 application/json:
645 schema: { $ref: '#/components/schemas/CalendarAgentContext' }
646 '400':
647 content:
648 application/json:
649 schema: { $ref: '#/components/schemas/Error' }
650 '401':
651 content:
652 application/json:
653 schema: { $ref: '#/components/schemas/Error' }
654 '403':
655 content:
656 application/json:
657 schema: { $ref: '#/components/schemas/Error' }
658
659 /calendar/source-calendars:
660 get:
661 tags: [Calendar]
662 summary: List source calendars and display/agent toggles (self-hosted)
663 responses:
664 '200':
665 content:
666 application/json:
667 schema: { $ref: '#/components/schemas/SourceCalendarList' }
668 '401':
669 content:
670 application/json:
671 schema: { $ref: '#/components/schemas/Error' }
672 '403':
673 content:
674 application/json:
675 schema: { $ref: '#/components/schemas/Error' }
676
677 /calendar/source-calendars/{id}:
678 patch:
679 tags: [Calendar]
680 summary: Update source calendar display/agent toggles (self-hosted)
681 description: >
682 Partial update for enabled_for_display, enabled_for_agents, agent_context_tier_max (0–4),
683 and optional user_group. Org policy may cap agent_context_tier_max via
684 KNOWTATION_CALENDAR_AGENT_TIER_MAX_CAP or data/hub_calendar_policy.json.
685 parameters:
686 - name: id
687 in: path
688 required: true
689 schema: { type: string }
690 description: Source calendar id.
691 requestBody:
692 required: true
693 content:
694 application/json:
695 schema: { $ref: '#/components/schemas/SourceCalendarPatchRequest' }
696 responses:
697 '200':
698 content:
699 application/json:
700 schema: { $ref: '#/components/schemas/SourceCalendarPatchResult' }
701 '400':
702 content:
703 application/json:
704 schema: { $ref: '#/components/schemas/Error' }
705 '401':
706 content:
707 application/json:
708 schema: { $ref: '#/components/schemas/Error' }
709 '403':
710 content:
711 application/json:
712 schema: { $ref: '#/components/schemas/Error' }
713 '404':
714 content:
715 application/json:
716 schema: { $ref: '#/components/schemas/Error' }
717
718 /calendar/events/import:
719 post:
720 tags: [Calendar]
721 summary: Import ICS text into the local event store (read-only, self-hosted)
722 requestBody:
723 required: true
724 content:
725 application/json:
726 schema: { $ref: '#/components/schemas/CalendarIcsImportRequest' }
727 responses:
728 '200':
729 content:
730 application/json:
731 schema: { $ref: '#/components/schemas/CalendarIcsImportResult' }
732 '400':
733 content:
734 application/json:
735 schema: { $ref: '#/components/schemas/Error' }
736 '401':
737 content:
738 application/json:
739 schema: { $ref: '#/components/schemas/Error' }
740 '403':
741 content:
742 application/json:
743 schema: { $ref: '#/components/schemas/Error' }
744
745 /flows:
746 get:
747 tags: [Flows]
748 summary: List scope-visible flows (content-minimized)
749 description: >
750 Returns knowtation.flow_list/v0 summaries for flows visible in the caller's
751 authorized workspace scope. Scope query param narrows only — never widens.
752 Step bodies are never included in list responses.
753 parameters:
754 - name: scope
755 in: query
756 schema: { type: string, enum: [personal, project, org] }
757 description: Narrow within authorized scopes only.
758 - name: tag
759 in: query
760 schema: { type: string }
761 description: Filter by single tag membership.
762 - name: limit
763 in: query
764 schema: { type: integer, minimum: 1, maximum: 200 }
765 description: Max summaries (default 200).
766 responses:
767 '200':
768 content:
769 application/json:
770 schema: { $ref: '#/components/schemas/FlowListResponse' }
771 '400':
772 content:
773 application/json:
774 schema: { $ref: '#/components/schemas/Error' }
775 '401':
776 content:
777 application/json:
778 schema: { $ref: '#/components/schemas/Error' }
779 '403':
780 content:
781 application/json:
782 schema: { $ref: '#/components/schemas/Error' }
783 post:
784 tags: [Flows]
785 summary: Propose a new Flow (review-before-write)
786 description: >
787 Validates a knowtation.flow/v0 + flow_step/v0 bundle, resolves write
788 authority server-side (scope × role, deny-by-default), and creates a
789 standard proposal targeting the Flow's mirror note (SD-4). Returns a
790 knowtation.flow_proposal/v0 envelope (pointers/labels only). Gated by
791 FLOW_AUTHORING_WRITES — when off returns 403 FLOW_AUTHORING_DISABLED.
792 No Flow index write happens here; the index changes only at approve→apply.
793 requestBody:
794 required: true
795 content:
796 application/json:
797 schema: { $ref: '#/components/schemas/FlowProposeRequest' }
798 responses:
799 '201':
800 content:
801 application/json:
802 schema: { $ref: '#/components/schemas/FlowProposalResponse' }
803 '400':
804 content:
805 application/json:
806 schema: { $ref: '#/components/schemas/Error' }
807 '401':
808 content:
809 application/json:
810 schema: { $ref: '#/components/schemas/Error' }
811 '403':
812 content:
813 application/json:
814 schema: { $ref: '#/components/schemas/Error' }
815 '409':
816 content:
817 application/json:
818 schema: { $ref: '#/components/schemas/Error' }
819
820 /flows/import:
821 post:
822 tags: [Flows]
823 summary: Import a portable Flow bundle as a scope-checked proposal
824 description: >
825 Routes a portable { flow, steps } bundle through the same propose path.
826 The bundle scope is validated against the actor's write tier; unwritable
827 ⇒ 403 FLOW_IMPORT_SCOPE_DENIED, malformed ⇒ 400 FLOW_IMPORT_BUNDLE_MALFORMED.
828 Lineage pointers (external_ref / source_vault_hint) are preserved. Never
829 auto-applied — creates a proposed proposal. Gated by FLOW_AUTHORING_WRITES.
830 requestBody:
831 required: true
832 content:
833 application/json:
834 schema: { $ref: '#/components/schemas/FlowImportRequest' }
835 responses:
836 '201':
837 content:
838 application/json:
839 schema: { $ref: '#/components/schemas/FlowProposalResponse' }
840 '400':
841 content:
842 application/json:
843 schema: { $ref: '#/components/schemas/Error' }
844 '401':
845 content:
846 application/json:
847 schema: { $ref: '#/components/schemas/Error' }
848 '403':
849 content:
850 application/json:
851 schema: { $ref: '#/components/schemas/Error' }
852 '409':
853 content:
854 application/json:
855 schema: { $ref: '#/components/schemas/Error' }
856
857 /flows/capture/observe:
858 post:
859 tags: [Flows]
860 summary: Observe content-minimized session signals (capture detection)
861 description: >
862 Runs bounded structural detectors when FLOW_CAPTURE_DETECTION_ENABLED is on.
863 Creates/updates flow_candidate/v0 records; returns content-minimized summaries.
864 When detection is off, returns detection_authorized=false with no store mutation.
865 requestBody:
866 required: true
867 content:
868 application/json:
869 schema:
870 type: object
871 required: [session_id, step_sequence_refs, observed_counts]
872 responses:
873 '200':
874 description: Observe envelope
875 '400':
876 content:
877 application/json:
878 schema: { $ref: '#/components/schemas/Error' }
879 '403':
880 content:
881 application/json:
882 schema: { $ref: '#/components/schemas/Error' }
883
884 /flows/candidates:
885 get:
886 tags: [Flows]
887 summary: List flow capture candidates (read store)
888 description: Returns pending_review candidate summaries; read path does not require detection sub-gate.
889 parameters:
890 - name: scope
891 in: query
892 schema: { type: string, enum: [personal, project, org] }
893 - name: include_low_confidence
894 in: query
895 schema: { type: boolean }
896 - name: limit
897 in: query
898 schema: { type: integer, minimum: 1, maximum: 50 }
899 responses:
900 '200':
901 description: Candidate list envelope
902 '400':
903 content:
904 application/json:
905 schema: { $ref: '#/components/schemas/Error' }
906
907 /flows/candidates/{candidate_id}/propose:
908 post:
909 tags: [Flows]
910 summary: Propose candidate promotion (review-before-write)
911 description: >
912 Creates a flow_candidate_promote or flow_candidate_merge proposal.
913 Gated by FLOW_CAPTURE_WRITES_ENABLED (default off).
914 parameters:
915 - name: candidate_id
916 in: path
917 required: true
918 schema: { type: string }
919 requestBody:
920 required: true
921 content:
922 application/json:
923 schema:
924 type: object
925 required: [confirmed_scope, intent]
926 responses:
927 '201':
928 description: Capture proposal envelope
929 '403':
930 content:
931 application/json:
932 schema: { $ref: '#/components/schemas/Error' }
933 '404':
934 content:
935 application/json:
936 schema: { $ref: '#/components/schemas/Error' }
937 '409':
938 content:
939 application/json:
940 schema: { $ref: '#/components/schemas/Error' }
941
942 /flows/candidates/{candidate_id}/dismiss:
943 post:
944 tags: [Flows]
945 summary: Propose candidate dismissal
946 description: >
947 Creates a flow_candidate_dismiss proposal; on approve candidate status becomes rejected.
948 Gated by FLOW_CAPTURE_WRITES_ENABLED (default off).
949 parameters:
950 - name: candidate_id
951 in: path
952 required: true
953 schema: { type: string }
954 requestBody:
955 required: true
956 content:
957 application/json:
958 schema:
959 type: object
960 required: [intent]
961 responses:
962 '201':
963 description: Capture proposal envelope
964 '403':
965 content:
966 application/json:
967 schema: { $ref: '#/components/schemas/Error' }
968 '404':
969 content:
970 application/json:
971 schema: { $ref: '#/components/schemas/Error' }
972
973 /flows/{id}/proposals:
974 post:
975 tags: [Flows]
976 summary: Propose an edit to an existing Flow (review-before-write)
977 description: >
978 Like POST /flows but for an edit. Requires base_version + base_state_id
979 (the flowst1_ optimistic-concurrency token); a mismatch at propose or
980 approve time ⇒ 409 FLOW_LINEAGE_CONFLICT. flow.version must be strictly
981 greater than base_version. Editing a flow the actor cannot read ⇒ 404
982 unknown_flow (no existence leak). Gated by FLOW_AUTHORING_WRITES.
983 parameters:
984 - name: id
985 in: path
986 required: true
987 schema: { type: string }
988 description: Flow id (flow_<slug>); must match the bundle's flow_id.
989 requestBody:
990 required: true
991 content:
992 application/json:
993 schema: { $ref: '#/components/schemas/FlowProposeEditRequest' }
994 responses:
995 '201':
996 content:
997 application/json:
998 schema: { $ref: '#/components/schemas/FlowProposalResponse' }
999 '400':
1000 content:
1001 application/json:
1002 schema: { $ref: '#/components/schemas/Error' }
1003 '401':
1004 content:
1005 application/json:
1006 schema: { $ref: '#/components/schemas/Error' }
1007 '403':
1008 content:
1009 application/json:
1010 schema: { $ref: '#/components/schemas/Error' }
1011 '404':
1012 content:
1013 application/json:
1014 schema: { $ref: '#/components/schemas/Error' }
1015 '409':
1016 content:
1017 application/json:
1018 schema: { $ref: '#/components/schemas/Error' }
1019
1020 /flows/{id}/projection:
1021 get:
1022 tags: [Flows]
1023 summary: Derive a read-only harness projection of a canonical flow
1024 description: >
1025 Renders the canonical flow (latest visible, or pinned ?version) into the requested
1026 harness as knowtation.flow_project/v0. Derived and read-only — generated_from_canonical
1027 is always true and editable is always false. No secrets appear in rendered text.
1028 parameters:
1029 - name: id
1030 in: path
1031 required: true
1032 schema: { type: string }
1033 - name: harness
1034 in: query
1035 required: true
1036 schema:
1037 type: string
1038 enum: [cursor_rule, cursor_skill, mcp_prompt, cli_runbook, agent_bundle]
1039 - name: version
1040 in: query
1041 schema: { type: string }
1042 responses:
1043 '200':
1044 content:
1045 application/json:
1046 schema: { $ref: '#/components/schemas/FlowProjectResponse' }
1047 '400':
1048 content:
1049 application/json:
1050 schema: { $ref: '#/components/schemas/Error' }
1051 '401':
1052 content:
1053 application/json:
1054 schema: { $ref: '#/components/schemas/Error' }
1055 '403':
1056 content:
1057 application/json:
1058 schema: { $ref: '#/components/schemas/Error' }
1059 '404':
1060 content:
1061 application/json:
1062 schema: { $ref: '#/components/schemas/Error' }
1063
1064 /flows/{id}/external-grants:
1065 post:
1066 tags: [Flows]
1067 summary: Mint a short-lived external-agent grant (gated; default off)
1068 description: >
1069 Mints knowtation.flow_external_grant/v0 for a pinned flow version and requested tools.
1070 Returns a one-time bearer at mint only. Requires FLOW_EXTERNAL_AGENT_ENABLED.
1071 parameters:
1072 - name: id
1073 in: path
1074 required: true
1075 schema: { type: string }
1076 requestBody:
1077 required: true
1078 content:
1079 application/json:
1080 schema: { $ref: '#/components/schemas/FlowExternalGrantMintRequest' }
1081 responses:
1082 '201':
1083 content:
1084 application/json:
1085 schema: { $ref: '#/components/schemas/FlowExternalGrantMintResponse' }
1086 '400':
1087 content:
1088 application/json:
1089 schema: { $ref: '#/components/schemas/Error' }
1090 '403':
1091 content:
1092 application/json:
1093 schema: { $ref: '#/components/schemas/Error' }
1094 '404':
1095 content:
1096 application/json:
1097 schema: { $ref: '#/components/schemas/Error' }
1098
1099 /flows/external-grants:
1100 get:
1101 tags: [Flows]
1102 summary: List external-agent grant metadata (no bearer)
1103 parameters:
1104 - name: flow_id
1105 in: query
1106 schema: { type: string }
1107 responses:
1108 '200':
1109 content:
1110 application/json:
1111 schema: { $ref: '#/components/schemas/FlowExternalGrantListResponse' }
1112 '403':
1113 content:
1114 application/json:
1115 schema: { $ref: '#/components/schemas/Error' }
1116
1117 /flows/external-grants/{grant_id}:
1118 delete:
1119 tags: [Flows]
1120 summary: Revoke an external-agent grant
1121 parameters:
1122 - name: grant_id
1123 in: path
1124 required: true
1125 schema: { type: string }
1126 responses:
1127 '200':
1128 content:
1129 application/json:
1130 schema: { $ref: '#/components/schemas/FlowExternalGrant' }
1131 '403':
1132 content:
1133 application/json:
1134 schema: { $ref: '#/components/schemas/Error' }
1135 '404':
1136 content:
1137 application/json:
1138 schema: { $ref: '#/components/schemas/Error' }
1139
1140 /tasks:
1141 get:
1142 tags: [Tasks]
1143 summary: List scope-visible tasks (content-minimized)
1144 description: >
1145 Returns knowtation.task_list/v0 summaries for tasks visible in the caller's
1146 authorized workspace scope. Scope query param narrows only — never widens.
1147 List responses never include assignee refs or artifact_links.
1148 parameters:
1149 - name: scope
1150 in: query
1151 schema: { type: string, enum: [personal, project, org] }
1152 description: Narrow within authorized scopes only.
1153 - name: workspace_id
1154 in: query
1155 schema: { type: string }
1156 description: Filter by workspace_id equality.
1157 - name: status
1158 in: query
1159 schema:
1160 type: string
1161 enum: [pending, in_progress, blocked, done, cancelled]
1162 - name: kind
1163 in: query
1164 schema:
1165 type: string
1166 enum: [personal, assignment, mentor_checkin, org_work_job]
1167 - name: limit
1168 in: query
1169 schema: { type: integer, minimum: 1, maximum: 500 }
1170 description: Max summaries (default 500).
1171 responses:
1172 '200':
1173 content:
1174 application/json:
1175 schema: { $ref: '#/components/schemas/TaskListResponse' }
1176 '400':
1177 content:
1178 application/json:
1179 schema: { $ref: '#/components/schemas/Error' }
1180 '401':
1181 content:
1182 application/json:
1183 schema: { $ref: '#/components/schemas/Error' }
1184 '403':
1185 content:
1186 application/json:
1187 schema: { $ref: '#/components/schemas/Error' }
1188
1189 /tasks/{id}:
1190 get:
1191 tags: [Tasks]
1192 summary: Get one authorized task
1193 description: >
1194 Returns knowtation.task_get/v0 with the full task record when the caller
1195 is authorized for the task scope. Missing or invisible tasks return 404
1196 unknown_task (no existence leak).
1197 parameters:
1198 - name: id
1199 in: path
1200 required: true
1201 schema: { type: string }
1202 responses:
1203 '200':
1204 content:
1205 application/json:
1206 schema: { $ref: '#/components/schemas/TaskGetResponse' }
1207 '400':
1208 content:
1209 application/json:
1210 schema: { $ref: '#/components/schemas/Error' }
1211 '401':
1212 content:
1213 application/json:
1214 schema: { $ref: '#/components/schemas/Error' }
1215 '403':
1216 content:
1217 application/json:
1218 schema: { $ref: '#/components/schemas/Error' }
1219 '404':
1220 content:
1221 application/json:
1222 schema: { $ref: '#/components/schemas/Error' }
1223
1224 /learning-paths:
1225 get:
1226 tags: [LearningPaths]
1227 summary: List scope-visible learning paths (content-minimized)
1228 description: >
1229 Returns knowtation.learning_path_list/v0 summaries. JWT + vault; no write gate.
1230 Default omits archived. Empty list is paths: [] (never a fabricated sample).
1231 PATH_WRITES_ENABLED does not affect this read.
1232 parameters:
1233 - name: scope
1234 in: query
1235 schema: { type: string, enum: [personal, project, org] }
1236 - name: workspace_id
1237 in: query
1238 schema: { type: string }
1239 - name: status
1240 in: query
1241 schema: { type: string, enum: [active, paused, archived] }
1242 - name: limit
1243 in: query
1244 schema: { type: integer, minimum: 1, maximum: 200 }
1245 description: Max summaries (default 200; invalid treated as 200).
1246 responses:
1247 '200':
1248 content:
1249 application/json:
1250 schema: { $ref: '#/components/schemas/LearningPathListResponse' }
1251 '400':
1252 content:
1253 application/json:
1254 schema: { $ref: '#/components/schemas/Error' }
1255 '401':
1256 content:
1257 application/json:
1258 schema: { $ref: '#/components/schemas/Error' }
1259 '403':
1260 content:
1261 application/json:
1262 schema: { $ref: '#/components/schemas/Error' }
1263
1264 /learning-paths/{path_id}:
1265 get:
1266 tags: [LearningPaths]
1267 summary: Get one authorized learning path
1268 description: >
1269 Missing, invalid path_id, or out-of-scope returns 404 PATH_NOT_FOUND (no existence leak).
1270 Archived paths still return when authorized.
1271 parameters:
1272 - name: path_id
1273 in: path
1274 required: true
1275 schema: { type: string }
1276 responses:
1277 '200':
1278 content:
1279 application/json:
1280 schema: { $ref: '#/components/schemas/LearningPathGetResponse' }
1281 '401':
1282 content:
1283 application/json:
1284 schema: { $ref: '#/components/schemas/Error' }
1285 '403':
1286 content:
1287 application/json:
1288 schema: { $ref: '#/components/schemas/Error' }
1289 '404':
1290 content:
1291 application/json:
1292 schema: { $ref: '#/components/schemas/Error' }
1293
1294 /learning-paths/proposals:
1295 post:
1296 tags: [LearningPaths]
1297 summary: Propose a learning-path write (SD-4; gated; default off)
1298 description: >
1299 path_create, path_update, or path_archive. Missing kind defaults to path_create.
1300 Requires PATH_WRITES_ENABLED (default off). Propose only — apply stays after approve.
1301 Path kinds are not admitted to personal self-apply (T5).
1302 requestBody:
1303 required: true
1304 content:
1305 application/json:
1306 schema: { $ref: '#/components/schemas/LearningPathProposalRequest' }
1307 responses:
1308 '201':
1309 content:
1310 application/json:
1311 schema: { $ref: '#/components/schemas/LearningPathProposalResponse' }
1312 '400':
1313 content:
1314 application/json:
1315 schema: { $ref: '#/components/schemas/Error' }
1316 '403':
1317 content:
1318 application/json:
1319 schema: { $ref: '#/components/schemas/Error' }
1320 '404':
1321 content:
1322 application/json:
1323 schema: { $ref: '#/components/schemas/Error' }
1324
1325 /attachments:
1326 get:
1327 tags: [Attachments]
1328 summary: List scope-visible attachments (content-minimized)
1329 description: >
1330 Returns knowtation.attachment_list/v0 summaries for attachments visible in
1331 the caller's authorized workspace scope. Scope query param narrows only — never widens.
1332 List responses never include linked_note_refs, byte_size, mime_type, or agent_visible.
1333 On hosted gateway→bridge (SEC-SEAM-MEDIA), connector_ref rows from
1334 hub_attachment_external_refs.json are included after media external-link apply.
1335 parameters:
1336 - name: scope
1337 in: query
1338 schema: { type: string, enum: [personal, project, org] }
1339 description: Narrow within authorized scopes only.
1340 - name: note_ref
1341 in: query
1342 schema: { type: string }
1343 description: Filter attachments linked to a specific note (note:path).
1344 - name: source
1345 in: query
1346 schema:
1347 type: string
1348 enum: [vault_file, mist_blob, embedded_url, connector_ref]
1349 - name: mime_class
1350 in: query
1351 schema:
1352 type: string
1353 enum: [image, video, audio, document, unknown]
1354 - name: storage_kind
1355 in: query
1356 schema:
1357 type: string
1358 enum: [vault_blob, external_link]
1359 - name: agent_visible
1360 in: query
1361 schema: { type: boolean }
1362 description: When true, return only attachments with agent_visible consent.
1363 - name: limit
1364 in: query
1365 schema: { type: integer, minimum: 1, maximum: 500 }
1366 description: Max summaries (default 500).
1367 responses:
1368 '200':
1369 content:
1370 application/json:
1371 schema: { $ref: '#/components/schemas/AttachmentListResponse' }
1372 '400':
1373 content:
1374 application/json:
1375 schema: { $ref: '#/components/schemas/Error' }
1376 '401':
1377 content:
1378 application/json:
1379 schema: { $ref: '#/components/schemas/Error' }
1380 '403':
1381 content:
1382 application/json:
1383 schema: { $ref: '#/components/schemas/Error' }
1384
1385 '404':
1386 content:
1387 application/json:
1388 schema: { $ref: '#/components/schemas/Error' }
1389
1390 /attachments/link-proposals:
1391 post:
1392 tags: [Attachments]
1393 summary: Propose an external media link (review-before-write)
1394 description: >
1395 Creates a media_external_link proposal. Gated by MEDIA_EXTERNAL_LINK_ENABLED (default off).
1396 Requires an active import consent and allowlisted connector. Never fetches opaque_ref.
1397 Available on self-hosted Hub and on hosted gateway→bridge (SEC-SEAM-MEDIA) when the
1398 same gate is enabled; hosted creates the proposal on the canister proposal store.
1399 requestBody:
1400 required: true
1401 content:
1402 application/json:
1403 schema:
1404 type: object
1405 required: [intent, scope, connector_id, opaque_ref, consent_id]
1406 properties:
1407 intent: { type: string }
1408 scope: { type: string, enum: [personal, project, org] }
1409 connector_id: { type: string }
1410 opaque_ref: { type: string }
1411 consent_id: { type: string }
1412 display_label: { type: string }
1413 responses:
1414 '201':
1415 content:
1416 application/json:
1417 schema: { $ref: '#/components/schemas/MediaProposalResponse' }
1418 '403':
1419 content:
1420 application/json:
1421 schema: { $ref: '#/components/schemas/Error' }
1422
1423 /attachments/attach-proposals:
1424 post:
1425 tags: [Attachments]
1426 summary: Propose attaching media to a note (review-before-write)
1427 description: >
1428 Creates a media_attach proposal. Gated by MEDIA_ATTACH_ENABLED (default off).
1429 Available on self-hosted Hub and on hosted gateway→bridge (SEC-SEAM-MEDIA) when the
1430 same gate is enabled. Hosted propose stamps media_pointer onto the canister row so
1431 apply does not require a vault-wide mist walk on the bridge.
1432 requestBody:
1433 required: true
1434 content:
1435 application/json:
1436 schema:
1437 type: object
1438 required: [intent, scope, attachment_id, note_ref, base_state_id]
1439 properties:
1440 intent: { type: string }
1441 scope: { type: string, enum: [personal, project, org] }
1442 attachment_id: { type: string }
1443 note_ref: { type: string }
1444 base_state_id: { type: string }
1445 responses:
1446 '201':
1447 content:
1448 application/json:
1449 schema: { $ref: '#/components/schemas/MediaProposalResponse' }
1450 '403':
1451 content:
1452 application/json:
1453 schema: { $ref: '#/components/schemas/Error' }
1454
1455 /attachments/import-consents:
1456 get:
1457 tags: [Attachments]
1458 summary: List import consents (read-only)
1459 parameters:
1460 - name: scope
1461 in: query
1462 schema: { type: string, enum: [personal, project, org] }
1463 responses:
1464 '200':
1465 content:
1466 application/json:
1467 schema:
1468 type: object
1469 required: [schema, vault_id, consents]
1470 properties:
1471 schema:
1472 type: string
1473 enum: [knowtation.media_import_consent_list/v0]
1474 vault_id: { type: string }
1475 consents:
1476 type: array
1477 items:
1478 type: object
1479 post:
1480 tags: [Attachments]
1481 summary: Grant import consent for external linking
1482 description: Requires MEDIA_EXTERNAL_LINK_ENABLED. Not exposed as MCP write tool.
1483 requestBody:
1484 required: true
1485 content:
1486 application/json:
1487 schema:
1488 type: object
1489 required: [connector_id, scope]
1490 properties:
1491 connector_id: { type: string }
1492 scope: { type: string, enum: [personal, project, org] }
1493 expires_at: { type: [string, 'null'] }
1494 responses:
1495 '201':
1496 content:
1497 application/json:
1498 schema:
1499 type: object
1500 delete:
1501 tags: [Attachments]
1502 summary: Revoke import consent (not supported at collection path)
1503 responses:
1504 '405':
1505 content:
1506 application/json:
1507 schema: { $ref: '#/components/schemas/Error' }
1508
1509 /attachments/import-consents/{id}:
1510 delete:
1511 tags: [Attachments]
1512 summary: Revoke an import consent by id
1513 parameters:
1514 - name: id
1515 in: path
1516 required: true
1517 schema: { type: string }
1518 responses:
1519 '200':
1520 content:
1521 application/json:
1522 schema:
1523 type: object
1524 '404':
1525 content:
1526 application/json:
1527 schema: { $ref: '#/components/schemas/Error' }
1528
1529 /attachments/proposals/{proposal_id}/apply-approved:
1530 post:
1531 tags: [Attachments]
1532 summary: Apply an approved media proposal (hosted Hub-complete / ops recovery)
1533 description: >
1534 Runs the shared media precheck + reconcile against bridge dataDir stores
1535 (and canister note RMW for media_attach). Requires proposal status approved
1536 (409 CONFLICT otherwise). The mandatory client path is the gateway post-approve
1537 hook (maybeApplyHostedMediaAfterApprove); this route is the ops recovery surface
1538 and the hook's bridge target (SEC-SEAM-MEDIA SM-C4 / SM-C12). Self-hosted Hub
1539 applies on approve without this route.
1540 parameters:
1541 - name: proposal_id
1542 in: path
1543 required: true
1544 schema: { type: string }
1545 responses:
1546 '200':
1547 content:
1548 application/json:
1549 schema:
1550 type: object
1551 required: [applied, proposal_id, vault_id, proposal_kind]
1552 properties:
1553 applied: { type: boolean, enum: [true] }
1554 proposal_id: { type: string }
1555 vault_id: { type: string }
1556 proposal_kind:
1557 type: string
1558 enum: [media_external_link, media_attach]
1559 attachment_id: { type: string }
1560 connector_id: { type: ['string', 'null'] }
1561 note_ref: { type: string }
1562 '400':
1563 content:
1564 application/json:
1565 schema: { $ref: '#/components/schemas/Error' }
1566 '403':
1567 content:
1568 application/json:
1569 schema: { $ref: '#/components/schemas/Error' }
1570 '404':
1571 content:
1572 application/json:
1573 schema: { $ref: '#/components/schemas/Error' }
1574 '409':
1575 content:
1576 application/json:
1577 schema: { $ref: '#/components/schemas/Error' }
1578
1579 /attachments/{id}:
1580 get:
1581 tags: [Attachments]
1582 summary: Get one authorized attachment
1583 description: >
1584 Returns knowtation.attachment_get/v0 with the full attachment record when
1585 the caller is authorized. Missing or invisible attachments return 404
1586 unknown_attachment (no existence leak). On hosted gateway→bridge, connector_ref
1587 rows derived from hub_attachment_external_refs.json are visible after media
1588 external-link apply (blob-backed stores).
1589 parameters:
1590 - name: id
1591 in: path
1592 required: true
1593 schema: { type: string }
1594 responses:
1595 '200':
1596 content:
1597 application/json:
1598 schema: { $ref: '#/components/schemas/AttachmentGetResponse' }
1599 '400':
1600 content:
1601 application/json:
1602 schema: { $ref: '#/components/schemas/Error' }
1603 '401':
1604 content:
1605 application/json:
1606 schema: { $ref: '#/components/schemas/Error' }
1607 '403':
1608 content:
1609 application/json:
1610 schema: { $ref: '#/components/schemas/Error' }
1611 '404':
1612 content:
1613 application/json:
1614 schema: { $ref: '#/components/schemas/Error' }
1615
1616 /tasks/proposals:
1617 post:
1618 tags: [Tasks]
1619 summary: Propose a one-time task write (SD-4; gated; default off)
1620 description: >
1621 Typed facade over /proposals for task_create, task_status_update, task_assign,
1622 and task_artifact_link. Requires TASK_WRITES_ENABLED (default off).
1623 requestBody:
1624 required: true
1625 content:
1626 application/json:
1627 schema: { $ref: '#/components/schemas/TaskWriteProposalRequest' }
1628 responses:
1629 '201':
1630 content:
1631 application/json:
1632 schema: { $ref: '#/components/schemas/TaskProposalResponse' }
1633 '403':
1634 content:
1635 application/json:
1636 schema: { $ref: '#/components/schemas/Error' }
1637 '409':
1638 content:
1639 application/json:
1640 schema: { $ref: '#/components/schemas/Error' }
1641
1642 /task-loops/proposals:
1643 post:
1644 tags: [Tasks]
1645 summary: Propose a task loop series write (SD-4; gated; default off)
1646 description: >
1647 task_loop_create, task_loop_pause, or task_loop_cancel proposal. Requires TASK_WRITES_ENABLED.
1648 requestBody:
1649 required: true
1650 content:
1651 application/json:
1652 schema: { $ref: '#/components/schemas/TaskLoopWriteProposalRequest' }
1653 responses:
1654 '201':
1655 content:
1656 application/json:
1657 schema: { $ref: '#/components/schemas/TaskProposalResponse' }
1658 '403':
1659 content:
1660 application/json:
1661 schema: { $ref: '#/components/schemas/Error' }
1662
1663 /task-loops/{loop_id}/instances/proposals:
1664 post:
1665 tags: [Tasks]
1666 summary: Propose materializing one loop occurrence task (SD-4; gated; default off)
1667 parameters:
1668 - name: loop_id
1669 in: path
1670 required: true
1671 schema: { type: string }
1672 requestBody:
1673 required: true
1674 content:
1675 application/json:
1676 schema: { $ref: '#/components/schemas/TaskInstanceMaterializeRequest' }
1677 responses:
1678 '201':
1679 content:
1680 application/json:
1681 schema: { $ref: '#/components/schemas/TaskInstanceProposalResponse' }
1682 '403':
1683 content:
1684 application/json:
1685 schema: { $ref: '#/components/schemas/Error' }
1686 '409':
1687 content:
1688 application/json:
1689 schema: { $ref: '#/components/schemas/Error' }
1690
1691 /agents/identities:
1692 post:
1693 tags: [Delegation]
1694 summary: Propose agent identity registration (SD-4; gated; default off)
1695 description: >
1696 Creates an SD-4 proposal with intent agent_identity_register. Requires DELEGATION_ENABLED.
1697 requestBody:
1698 required: true
1699 content:
1700 application/json:
1701 schema: { $ref: '#/components/schemas/AgentIdentityRegisterRequest' }
1702 responses:
1703 '201':
1704 content:
1705 application/json:
1706 schema: { $ref: '#/components/schemas/DelegationProposalResponse' }
1707 '403':
1708 content:
1709 application/json:
1710 schema: { $ref: '#/components/schemas/Error' }
1711 get:
1712 tags: [Delegation]
1713 summary: List agent identities (gated; default off)
1714 parameters:
1715 - name: kind
1716 in: query
1717 schema:
1718 type: string
1719 enum: [user_owned, org_owned, delegate]
1720 - name: status
1721 in: query
1722 schema:
1723 type: string
1724 enum: [active, suspended, revoked]
1725 responses:
1726 '200':
1727 content:
1728 application/json:
1729 schema: { $ref: '#/components/schemas/AgentIdentityListResponse' }
1730 '403':
1731 content:
1732 application/json:
1733 schema: { $ref: '#/components/schemas/Error' }
1734
1735 /delegation/consents:
1736 post:
1737 tags: [Delegation]
1738 summary: Propose delegation consent (SD-4; gated; default off)
1739 requestBody:
1740 required: true
1741 content:
1742 application/json:
1743 schema: { $ref: '#/components/schemas/DelegationConsentProposeRequest' }
1744 responses:
1745 '201':
1746 content:
1747 application/json:
1748 schema: { $ref: '#/components/schemas/DelegationConsentProposeResponse' }
1749 '403':
1750 content:
1751 application/json:
1752 schema: { $ref: '#/components/schemas/Error' }
1753
1754 /delegation/consents/{consent_id}:
1755 delete:
1756 tags: [Delegation]
1757 summary: Revoke delegation consent
1758 parameters:
1759 - name: consent_id
1760 in: path
1761 required: true
1762 schema: { type: string }
1763 responses:
1764 '200':
1765 content:
1766 application/json:
1767 schema: { $ref: '#/components/schemas/DelegationConsent' }
1768 '403':
1769 content:
1770 application/json:
1771 schema: { $ref: '#/components/schemas/Error' }
1772 '404':
1773 content:
1774 application/json:
1775 schema: { $ref: '#/components/schemas/Error' }
1776
1777 /delegation/grants:
1778 post:
1779 tags: [Delegation]
1780 summary: Mint short-lived delegation grant (gated; default off)
1781 requestBody:
1782 required: true
1783 content:
1784 application/json:
1785 schema: { $ref: '#/components/schemas/DelegationGrantMintRequest' }
1786 responses:
1787 '201':
1788 content:
1789 application/json:
1790 schema: { $ref: '#/components/schemas/DelegationGrantMintResponse' }
1791 '403':
1792 content:
1793 application/json:
1794 schema: { $ref: '#/components/schemas/Error' }
1795 '404':
1796 content:
1797 application/json:
1798 schema: { $ref: '#/components/schemas/Error' }
1799 get:
1800 tags: [Delegation]
1801 summary: List delegation grant metadata (no bearer)
1802 parameters:
1803 - name: actor_agent_id
1804 in: query
1805 schema: { type: string }
1806 responses:
1807 '200':
1808 content:
1809 application/json:
1810 schema: { $ref: '#/components/schemas/DelegationGrantListResponse' }
1811 '403':
1812 content:
1813 application/json:
1814 schema: { $ref: '#/components/schemas/Error' }
1815
1816 /delegation/grants/{grant_id}:
1817 delete:
1818 tags: [Delegation]
1819 summary: Revoke delegation grant
1820 parameters:
1821 - name: grant_id
1822 in: path
1823 required: true
1824 schema: { type: string }
1825 responses:
1826 '200':
1827 content:
1828 application/json:
1829 schema: { $ref: '#/components/schemas/DelegationGrant' }
1830 '403':
1831 content:
1832 application/json:
1833 schema: { $ref: '#/components/schemas/Error' }
1834 '404':
1835 content:
1836 application/json:
1837 schema: { $ref: '#/components/schemas/Error' }
1838
1839 /delegation/audit:
1840 post:
1841 tags: [Delegation]
1842 summary: Append delegation audit entry (pointer-safe)
1843 requestBody:
1844 required: true
1845 content:
1846 application/json:
1847 schema: { $ref: '#/components/schemas/DelegationAuditAppendRequest' }
1848 responses:
1849 '201':
1850 content:
1851 application/json:
1852 schema: { $ref: '#/components/schemas/DelegationAudit' }
1853 '403':
1854 content:
1855 application/json:
1856 schema: { $ref: '#/components/schemas/Error' }
1857
1858 /flows/{id}:
1859 get:
1860 tags: [Flows]
1861 summary: Get one flow definition + ordered steps
1862 description: >
1863 Returns knowtation.flow_get/v0 with full flow definition and steps in ascending
1864 ordinal order. Missing and scope-invisible flows both return 404 unknown_flow.
1865 Step text is untrusted input — returned verbatim as data.
1866 parameters:
1867 - name: id
1868 in: path
1869 required: true
1870 schema: { type: string }
1871 description: Flow id (flow_<slug>).
1872 - name: version
1873 in: query
1874 schema: { type: string }
1875 description: Pin semver version; default latest visible.
1876 responses:
1877 '200':
1878 content:
1879 application/json:
1880 schema: { $ref: '#/components/schemas/FlowGetResponse' }
1881 '400':
1882 content:
1883 application/json:
1884 schema: { $ref: '#/components/schemas/Error' }
1885 '401':
1886 content:
1887 application/json:
1888 schema: { $ref: '#/components/schemas/Error' }
1889 '403':
1890 content:
1891 application/json:
1892 schema: { $ref: '#/components/schemas/Error' }
1893 '404':
1894 content:
1895 application/json:
1896 schema: { $ref: '#/components/schemas/Error' }
1897
1898 /flow-runs/{run_id}:
1899 get:
1900 tags: [Flows]
1901 summary: Get one flow run by run id or portable run_ref
1902 description: >
1903 Returns knowtation.flow_run/v0 for a scope-visible run. Accepts canonical
1904 run_id (run_…) or portable run_ref (flow_run:…). Missing and
1905 scope-invisible runs both return 404 unknown_run.
1906 parameters:
1907 - name: run_id
1908 in: path
1909 required: true
1910 schema: { type: string }
1911 responses:
1912 '200':
1913 content:
1914 application/json:
1915 schema: { $ref: '#/components/schemas/FlowRunResponse' }
1916 '404':
1917 content:
1918 application/json:
1919 schema: { $ref: '#/components/schemas/Error' }
1920
1921 /flows/{id}/runs:
1922 get:
1923 tags: [Flows]
1924 summary: List runs for a flow
1925 parameters:
1926 - name: id
1927 in: path
1928 required: true
1929 schema: { type: string }
1930 responses:
1931 '200':
1932 content:
1933 application/json:
1934 schema: { $ref: '#/components/schemas/FlowRunListResponse' }
1935 post:
1936 tags: [Flows]
1937 summary: Start a flow run
1938 description: >
1939 Gated by FLOW_RUN_WRITES_ENABLED (default off). Pins flow_version for the run life.
1940 parameters:
1941 - name: id
1942 in: path
1943 required: true
1944 schema: { type: string }
1945 requestBody:
1946 required: true
1947 content:
1948 application/json:
1949 schema:
1950 type: object
1951 required: [flow_version]
1952 properties:
1953 flow_version: { type: string }
1954 task_ref: { type: string }
1955 external_ref: { type: string }
1956 responses:
1957 '201':
1958 content:
1959 application/json:
1960 schema: { $ref: '#/components/schemas/FlowRunStartResponse' }
1961 '403':
1962 content:
1963 application/json:
1964 schema: { $ref: '#/components/schemas/Error' }
1965
1966 /flows/{id}/runs/{run_id}:
1967 get:
1968 tags: [Flows]
1969 summary: Get one flow run
1970 parameters:
1971 - name: id
1972 in: path
1973 required: true
1974 schema: { type: string }
1975 - name: run_id
1976 in: path
1977 required: true
1978 schema: { type: string }
1979 responses:
1980 '200':
1981 content:
1982 application/json:
1983 schema: { $ref: '#/components/schemas/FlowRunResponse' }
1984 post:
1985 tags: [Flows]
1986 summary: Advance, record evidence, execute automatable, or submit review
1987 description: >
1988 Use dedicated sub-paths (/advance, /evidence, /execute-automatable, /submit-review).
1989 Run writes gated by FLOW_RUN_WRITES_ENABLED; automatable by FLOW_AUTOMATABLE_EXECUTION_ENABLED.
1990
1991 /flows/{id}/runs/{run_id}/advance:
1992 post:
1993 tags: [Flows]
1994 summary: Advance a step manually
1995 parameters:
1996 - name: id
1997 in: path
1998 required: true
1999 schema: { type: string }
2000 - name: run_id
2001 in: path
2002 required: true
2003 schema: { type: string }
2004 requestBody:
2005 required: true
2006 content:
2007 application/json:
2008 schema:
2009 type: object
2010 required: [step_id, to_status]
2011 properties:
2012 step_id: { type: string }
2013 to_status: { type: string }
2014 skip_reason: { type: string }
2015 responses:
2016 '200':
2017 content:
2018 application/json:
2019 schema: { $ref: '#/components/schemas/FlowRunResponse' }
2020
2021 /flows/{id}/runs/{run_id}/evidence:
2022 post:
2023 tags: [Flows]
2024 summary: Record evidence pointer on a step
2025 parameters:
2026 - name: id
2027 in: path
2028 required: true
2029 schema: { type: string }
2030 - name: run_id
2031 in: path
2032 required: true
2033 schema: { type: string }
2034 requestBody:
2035 required: true
2036 content:
2037 application/json:
2038 schema:
2039 type: object
2040 required: [step_id, evidence_ref, pointer_kind]
2041 properties:
2042 step_id: { type: string }
2043 evidence_ref: { type: string }
2044 pointer_kind: { type: string }
2045 responses:
2046 '200':
2047 content:
2048 application/json:
2049 schema: { $ref: '#/components/schemas/FlowRunResponse' }
2050
2051 /flows/{id}/runs/{run_id}/execute-automatable:
2052 post:
2053 tags: [Flows]
2054 summary: Execute an automatable step (server orchestration stub)
2055 description: Requires valid knowtation.flow_execution_consent/v0. Gated by FLOW_AUTOMATABLE_EXECUTION_ENABLED.
2056 parameters:
2057 - name: id
2058 in: path
2059 required: true
2060 schema: { type: string }
2061 - name: run_id
2062 in: path
2063 required: true
2064 schema: { type: string }
2065 requestBody:
2066 required: true
2067 content:
2068 application/json:
2069 schema:
2070 type: object
2071 required: [step_id, consent_id]
2072 properties:
2073 step_id: { type: string }
2074 consent_id: { type: string }
2075 model_lane: { type: string }
2076 dry_run: { type: boolean }
2077 responses:
2078 '200':
2079 content:
2080 application/json:
2081 schema: { $ref: '#/components/schemas/FlowExecuteAutomatableResponse' }
2082
2083 /flows/{id}/runs/{run_id}/submit-review:
2084 post:
2085 tags: [Flows]
2086 summary: Submit run outcome to review tray
2087 parameters:
2088 - name: id
2089 in: path
2090 required: true
2091 schema: { type: string }
2092 - name: run_id
2093 in: path
2094 required: true
2095 schema: { type: string }
2096 requestBody:
2097 required: true
2098 content:
2099 application/json:
2100 schema:
2101 type: object
2102 required: [intent]
2103 properties:
2104 intent: { type: string }
2105 responses:
2106 '200':
2107 content:
2108 application/json:
2109 schema: { $ref: '#/components/schemas/FlowRunSubmitReviewResponse' }
2110
2111 /flows/{id}/runs/{run_id}/consent:
2112 post:
2113 tags: [Flows]
2114 summary: Mint execution consent for automatable steps
2115 parameters:
2116 - name: id
2117 in: path
2118 required: true
2119 schema: { type: string }
2120 - name: run_id
2121 in: path
2122 required: true
2123 schema: { type: string }
2124 requestBody:
2125 required: true
2126 content:
2127 application/json:
2128 schema:
2129 type: object
2130 required: [allowed_lanes, cost_cap_units]
2131 properties:
2132 allowed_lanes: { type: array, items: { type: string } }
2133 cost_cap_units: { type: integer }
2134 ttl_seconds: { type: integer }
2135 responses:
2136 '201':
2137 content:
2138 application/json:
2139 schema: { $ref: '#/components/schemas/FlowExecutionConsentMintResponse' }
2140
2141 /metadata-facets:
2142 get:
2143 tags: [Notes]
2144 summary: Body-free MetadataFacets hints for one note
2145 description: >
2146 Returns knowtation.metadata_facets/v0 metadata for one authorized vault-relative note.
2147 The response excludes note body text, snippets, full frontmatter, absolute paths,
2148 provider payloads, MCP resource URIs, summaries, labels, vectors, OCR, PageIndex output,
2149 media metadata, memory events, persistence records, sidecars, LLM calls, and write-back state.
2150 parameters:
2151 - name: path
2152 in: query
2153 required: true
2154 schema: { type: string }
2155 description: Vault-relative Markdown note path.
2156 responses:
2157 '200':
2158 content:
2159 application/json:
2160 schema: { $ref: '#/components/schemas/MetadataFacets' }
2161 '400':
2162 content:
2163 application/json:
2164 schema: { $ref: '#/components/schemas/Error' }
2165 '401':
2166 content:
2167 application/json:
2168 schema: { $ref: '#/components/schemas/Error' }
2169 '403':
2170 content:
2171 application/json:
2172 schema: { $ref: '#/components/schemas/Error' }
2173 '404':
2174 content:
2175 application/json:
2176 schema: { $ref: '#/components/schemas/Error' }
2177 '502':
2178 content:
2179 application/json:
2180 schema: { $ref: '#/components/schemas/Error' }
2181
2182 /section-source:
2183 get:
2184 tags: [Notes]
2185 summary: Body-free SectionSource metadata for one note
2186 description: >
2187 Returns knowtation.section_source/v0 metadata for one authorized vault-relative note.
2188 The response excludes note body text, section body text, snippets, full frontmatter,
2189 line ranges, byte offsets, section body lengths, absolute paths, raw canister payloads,
2190 provider payloads, and MCP resource URIs.
2191 parameters:
2192 - name: path
2193 in: query
2194 required: true
2195 schema: { type: string }
2196 description: Vault-relative Markdown note path.
2197 responses:
2198 '200':
2199 content:
2200 application/json:
2201 schema: { $ref: '#/components/schemas/SectionSource' }
2202 '400':
2203 content:
2204 application/json:
2205 schema: { $ref: '#/components/schemas/Error' }
2206 '401':
2207 content:
2208 application/json:
2209 schema: { $ref: '#/components/schemas/Error' }
2210 '403':
2211 content:
2212 application/json:
2213 schema: { $ref: '#/components/schemas/Error' }
2214 '404':
2215 content:
2216 application/json:
2217 schema: { $ref: '#/components/schemas/Error' }
2218 '502':
2219 content:
2220 application/json:
2221 schema: { $ref: '#/components/schemas/Error' }
2222
2223 /index:
2224 post:
2225 tags: [Notes]
2226 summary: Re-run indexer (vault to vector store)
2227 responses:
2228 '200':
2229 content:
2230 application/json:
2231 schema:
2232 type: object
2233 properties:
2234 ok: { type: boolean }
2235 notesProcessed: { type: integer }
2236 chunksIndexed: { type: integer }
2237 vectors_deleted: { type: integer, description: Rows removed for this vault before upsert (hosted sqlite-vec) }
2238 '500':
2239 content:
2240 application/json:
2241 schema: { $ref: '#/components/schemas/Error' }
2242
2243 /export:
2244 post:
2245 tags: [Notes]
2246 summary: Export one note to content (returns body + filename for client download)
2247 requestBody:
2248 required: true
2249 content:
2250 application/json:
2251 schema:
2252 type: object
2253 required: [path]
2254 properties:
2255 path: { type: string }
2256 format: { type: string, enum: [md, html] }
2257 responses:
2258 '200':
2259 content:
2260 application/json:
2261 schema:
2262 type: object
2263 properties:
2264 content: { type: string }
2265 filename: { type: string }
2266 '400':
2267 content:
2268 application/json:
2269 schema: { $ref: '#/components/schemas/Error' }
2270 '404':
2271 content:
2272 application/json:
2273 schema: { $ref: '#/components/schemas/Error' }
2274
2275 /import:
2276 post:
2277 tags: [Notes]
2278 summary: Import from uploaded file or ZIP (multipart: source_type; file except for google-sheets; optional project, tags, spreadsheet_id for google-sheets)
2279 requestBody:
2280 required: true
2281 content:
2282 multipart/form-data:
2283 schema:
2284 type: object
2285 required: [source_type]
2286 properties:
2287 source_type:
2288 type: string
2289 description: Importer id. For google-sheets, omit file and set spreadsheet_id; optional sheets_range (A1 notation). See lib/import-source-types.mjs.
2290 file: { type: string, format: binary, description: Required for all importers except google-sheets. }
2291 spreadsheet_id:
2292 type: string
2293 description: Required when source_type is google-sheets (id from the Google Sheets URL).
2294 sheets_range:
2295 type: string
2296 description: Optional for google-sheets; A1 range. Omit to read the first sheet from A1.
2297 project: { type: string }
2298 output_dir: { type: string }
2299 tags: { type: string }
2300 responses:
2301 '200':
2302 content:
2303 application/json:
2304 schema:
2305 type: object
2306 properties:
2307 imported: { type: array, items: { type: object } }
2308 count: { type: integer }
2309 '400':
2310 content:
2311 application/json:
2312 schema: { $ref: '#/components/schemas/Error' }
2313 '500':
2314 content:
2315 application/json:
2316 schema: { $ref: '#/components/schemas/Error' }
2317
2318 /import-url:
2319 post:
2320 tags: [Notes]
2321 summary: Import from a public https URL (JSON body; editor/admin)
2322 requestBody:
2323 required: true
2324 content:
2325 application/json:
2326 schema:
2327 type: object
2328 required: [url]
2329 properties:
2330 url: { type: string, description: 'Full https URL' }
2331 mode: { type: string, enum: [auto, bookmark, extract], description: 'Capture mode (default auto)' }
2332 project: { type: string }
2333 output_dir: { type: string }
2334 tags: { oneOf: [{ type: string }, { type: array, items: { type: string } }] }
2335 responses:
2336 '200':
2337 content:
2338 application/json:
2339 schema:
2340 type: object
2341 properties:
2342 imported: { type: array, items: { type: object } }
2343 count: { type: integer }
2344 '400':
2345 content:
2346 application/json:
2347 schema: { $ref: '#/components/schemas/Error' }
2348 '500':
2349 content:
2350 application/json:
2351 schema: { $ref: '#/components/schemas/Error' }
2352
2353 /docs/connectors:
2354 get:
2355 tags: [DocsConnectors]
2356 summary: List docs connectors (Drive + Notion). Gate off → 501 NOT_AUTHORIZED. No secrets.
2357 responses:
2358 '200':
2359 content:
2360 application/json:
2361 schema:
2362 type: object
2363 required: [schema, connectors]
2364 properties:
2365 schema: { type: string, enum: [knowtation.docs_connectors/v0] }
2366 connectors:
2367 type: array
2368 items:
2369 type: object
2370 properties:
2371 connector_id: { type: string }
2372 provider: { type: string, enum: [google-drive, notion] }
2373 display_name: { type: string }
2374 status: { type: string, enum: [pending, connected, needs_reauth, revoked] }
2375 last_sync_at: { type: string, nullable: true }
2376 last_sync_error: { type: string }
2377 file_count: { type: integer }
2378 revoked_at: { type: string, nullable: true }
2379 '501':
2380 description: Gate not authorized
2381 post:
2382 tags: [DocsConnectors]
2383 summary: Begin Drive OAuth or Notion Hub-key connector (editor/admin). Gates hard-coded false.
2384 requestBody:
2385 required: true
2386 content:
2387 application/json:
2388 schema:
2389 type: object
2390 required: [provider]
2391 properties:
2392 provider: { type: string, enum: [google-drive, notion] }
2393 display_name: { type: string, maxLength: 128 }
2394 return_url: { type: string, description: Required for google-drive; exact-allowlisted }
2395 responses:
2396 '200':
2397 description: Drive returns authorization_url; Notion returns status
2398 '400':
2399 description: BAD_REQUEST / PROVIDER_DENIED / RETURN_URL_DENIED
2400 '501':
2401 description: NOT_AUTHORIZED
2402
2403 /docs/connectors/callback:
2404 get:
2405 tags: [DocsConnectors]
2406 summary: Google Drive OAuth callback (state-authenticated; no JWT)
2407 security: []
2408 parameters:
2409 - name: code
2410 in: query
2411 schema: { type: string }
2412 - name: state
2413 in: query
2414 schema: { type: string }
2415 responses:
2416 '302':
2417 description: Redirect to allowlisted return_url
2418
2419 /docs/connectors/{id}/files:
2420 get:
2421 tags: [DocsConnectors]
2422 summary: List importable file metadata (no bodies)
2423 parameters:
2424 - name: id
2425 in: path
2426 required: true
2427 schema: { type: string }
2428 - name: page_token
2429 in: query
2430 schema: { type: string }
2431 - name: q
2432 in: query
2433 schema: { type: string, pattern: '^[A-Za-z0-9 ._-]{1,128}$' }
2434 responses:
2435 '200':
2436 description: files + optional next_page_token
2437 '400':
2438 description: BAD_REQUEST (invalid q or ids)
2439 '501':
2440 description: NOT_AUTHORIZED
2441
2442 /docs/connectors/{id}/import:
2443 post:
2444 tags: [DocsConnectors]
2445 summary: Create docs-sync Review proposals for 1–20 file ids (never writeNote)
2446 parameters:
2447 - name: id
2448 in: path
2449 required: true
2450 schema: { type: string }
2451 requestBody:
2452 required: true
2453 content:
2454 application/json:
2455 schema:
2456 type: object
2457 required: [file_ids]
2458 properties:
2459 file_ids:
2460 type: array
2461 minItems: 1
2462 maxItems: 20
2463 items: { type: string }
2464 responses:
2465 '200':
2466 description: '{ proposed, skipped, proposal_ids }'
2467 '501':
2468 description: NOT_AUTHORIZED
2469
2470 /docs/connectors/{id}/sync:
2471 post:
2472 tags: [DocsConnectors]
2473 summary: Optional cursor sync; rate-limited ≥60s; creates proposals only
2474 parameters:
2475 - name: id
2476 in: path
2477 required: true
2478 schema: { type: string }
2479 responses:
2480 '200':
2481 description: '{ proposed, skipped, last_sync_at }'
2482 '429':
2483 description: RATE_LIMITED
2484 '501':
2485 description: NOT_AUTHORIZED
2486
2487 /docs/connectors/{id}:
2488 delete:
2489 tags: [DocsConnectors]
2490 summary: Revoke connector; imported vault notes stay
2491 parameters:
2492 - name: id
2493 in: path
2494 required: true
2495 schema: { type: string }
2496 responses:
2497 '200':
2498 description: '{ revoked: true }'
2499 '501':
2500 description: NOT_AUTHORIZED
2501
2502 /settings:
2503 get:
2504 tags: [Notes]
2505 summary: Config status for Settings UI (no secrets)
2506 responses:
2507 '200':
2508 content:
2509 application/json:
2510 schema:
2511 type: object
2512 properties:
2513 vault_path_display: { type: string }
2514 vault_git:
2515 type: object
2516 properties:
2517 enabled: { type: boolean }
2518 has_remote: { type: boolean }
2519 auto_commit: { type: boolean }
2520 auto_push: { type: boolean }
2521
2522 /vault/sync:
2523 post:
2524 tags: [Notes]
2525 summary: Manual vault backup (git add, commit, push)
2526 description: Self-hosted runs local git. Hosted (bridge) pushes notes as Markdown plus `.knowtation/backup/v1/snapshot.json` with full proposals.
2527 responses:
2528 '200':
2529 content:
2530 application/json:
2531 schema:
2532 type: object
2533 properties:
2534 ok: { type: boolean }
2535 message: { type: string }
2536 notesCount: { type: integer, description: Hosted bridge only }
2537 proposalsCount: { type: integer, description: Hosted bridge only }
2538 '400':
2539 content:
2540 application/json:
2541 schema: { $ref: '#/components/schemas/Error' }
2542 '500':
2543 content:
2544 application/json:
2545 schema: { $ref: '#/components/schemas/Error' }
2546
2547 /search:
2548 post:
2549 tags: [Search]
2550 summary: Vault search (semantic or keyword)
2551 requestBody:
2552 required: true
2553 content:
2554 application/json:
2555 schema:
2556 type: object
2557 required: [query]
2558 properties:
2559 query: { type: string }
2560 mode: { type: string, enum: [semantic, keyword], description: Omitted or semantic = vector search; keyword = substring/token match on note text }
2561 match: { type: string, enum: [phrase, all_terms], description: Keyword only; phrase = full query substring; all_terms = every token must appear }
2562 folder: { type: string }
2563 project: { type: string }
2564 tag: { type: string }
2565 since: { type: string }
2566 until: { type: string }
2567 chain: { type: string }
2568 entity: { type: string }
2569 episode: { type: string }
2570 limit: { type: integer }
2571 order: { type: string }
2572 fields: { type: string }
2573 content_scope: { type: string, enum: [notes, approval_logs], description: Narrow to normal notes vs approvals/ logs }
2574 snippetChars: { type: integer }
2575 count_only: { type: boolean }
2576 countOnly: { type: boolean }
2577 responses:
2578 '200':
2579 content:
2580 application/json:
2581 schema:
2582 type: object
2583 properties:
2584 results: { type: array, items: { $ref: '#/components/schemas/SearchResult' } }
2585 query: { type: string }
2586 mode: { type: string, enum: [semantic, keyword] }
2587 count: { type: integer, description: Present when count_only keyword search }
2588 '400':
2589 content:
2590 application/json:
2591 schema: { $ref: '#/components/schemas/Error' }
2592
2593 /proposals:
2594 get:
2595 tags: [Proposals]
2596 summary: List proposals
2597 parameters:
2598 - name: status
2599 in: query
2600 schema: { type: string }
2601 - name: limit
2602 in: query
2603 schema: { type: integer }
2604 - name: offset
2605 in: query
2606 schema: { type: integer }
2607 - name: label
2608 in: query
2609 description: Match if proposal labels include this string (case-insensitive)
2610 schema: { type: string }
2611 - name: source
2612 in: query
2613 schema: { type: string }
2614 - name: path_prefix
2615 in: query
2616 schema: { type: string }
2617 - name: evaluation_status
2618 in: query
2619 description: Filter by evaluation_status (none, pending, passed, failed, needs_changes)
2620 schema: { type: string }
2621 - name: review_queue
2622 in: query
2623 description: Exact match on proposal review_queue
2624 schema: { type: string }
2625 - name: review_severity
2626 in: query
2627 description: standard or elevated
2628 schema: { type: string }
2629 responses:
2630 '200':
2631 content:
2632 application/json:
2633 schema:
2634 type: object
2635 properties:
2636 proposals: { type: array, items: { $ref: '#/components/schemas/Proposal' } }
2637 total: { type: integer }
2638 post:
2639 tags: [Proposals]
2640 summary: Create proposal
2641 requestBody:
2642 content:
2643 application/json:
2644 schema:
2645 type: object
2646 properties:
2647 path: { type: string }
2648 body: { type: string }
2649 frontmatter: { type: object }
2650 intent: { type: string }
2651 base_state_id: { type: string }
2652 external_ref: { type: string }
2653 labels: { type: array, items: { type: string } }
2654 source: { type: string }
2655 responses:
2656 '201':
2657 content:
2658 application/json:
2659 schema:
2660 type: object
2661 properties:
2662 proposal_id: { type: string }
2663 path: { type: string }
2664 status: { type: string, enum: [proposed] }
2665 '400':
2666
2667 /proposals/{id}:
2668 get:
2669 tags: [Proposals]
2670 summary: Get one proposal
2671 parameters:
2672 - name: id
2673 in: path
2674 required: true
2675 schema: { type: string }
2676 responses:
2677 '200':
2678 content:
2679 application/json:
2680 schema: { $ref: '#/components/schemas/ProposalDetail' }
2681 '404':
2682
2683 /proposals/{id}/review-hints:
2684 post:
2685 tags: [Proposals]
2686 summary: Store async LLM review hints (canister; not a merge gate)
2687 parameters:
2688 - name: id
2689 in: path
2690 required: true
2691 schema: { type: string }
2692 requestBody:
2693 content:
2694 application/json:
2695 schema:
2696 type: object
2697 properties:
2698 review_hints: { type: string }
2699 review_hints_model: { type: string }
2700 responses:
2701 '200':
2702 content:
2703 application/json:
2704 schema:
2705 type: object
2706 properties:
2707 proposal_id: { type: string }
2708 ok: { type: boolean }
2709
2710 /proposals/{id}/evaluation:
2711 post:
2712 tags: [Proposals]
2713 summary: Submit human evaluation (admin or evaluator)
2714 parameters:
2715 - name: id
2716 in: path
2717 required: true
2718 schema: { type: string }
2719 requestBody:
2720 content:
2721 application/json:
2722 schema:
2723 type: object
2724 required: [outcome]
2725 properties:
2726 outcome:
2727 type: string
2728 enum: [pass, fail, needs_changes]
2729 checklist:
2730 type: array
2731 items:
2732 type: object
2733 properties:
2734 id: { type: string }
2735 passed: { type: boolean }
2736 grade: { type: string }
2737 comment: { type: string }
2738 responses:
2739 '200':
2740 content:
2741 application/json:
2742 schema: { $ref: '#/components/schemas/ProposalDetail' }
2743 '400':
2744 '404':
2745
2746 /proposals/{id}/approve:
2747 post:
2748 tags: [Proposals]
2749 summary: Apply proposal to vault
2750 parameters:
2751 - name: id
2752 in: path
2753 required: true
2754 schema: { type: string }
2755 requestBody:
2756 content:
2757 application/json:
2758 schema:
2759 type: object
2760 properties:
2761 base_state_id: { type: string }
2762 waiver_reason:
2763 type: string
2764 description: Admin override when evaluation is not passed (min length 3 after trim)
2765 external_ref:
2766 type: string
2767 description: Optional cross-system lineage id (e.g. Muse); server may resolve via MUSE_URL when omitted
2768 responses:
2769 '200':
2770 content:
2771 application/json:
2772 schema:
2773 type: object
2774 properties:
2775 proposal_id: { type: string }
2776 status: { type: string, enum: [approved] }
2777 external_ref: { type: string }
2778 '403':
2779 description: EVALUATION_REQUIRED — pass evaluation or provide waiver_reason
2780 '409':
2781 description: base_state_id mismatch (CONFLICT)
2782
2783 /proposals/{id}/enrich:
2784 post:
2785 tags: [Proposals]
2786 summary: Optional LLM summary and suggested labels (KNOWTATION_HUB_PROPOSAL_ENRICH=1)
2787 parameters:
2788 - name: id
2789 in: path
2790 required: true
2791 schema: { type: string }
2792 responses:
2793 '200':
2794 content:
2795 application/json:
2796 schema: { $ref: '#/components/schemas/ProposalDetail' }
2797 '400':
2798 description: >-
2799 ICP canister — suggested_labels_json or assistant_suggested_frontmatter_json is valid JSON
2800 but exceeds max length (4000 / 14000 characters) after validation.
2801 '404':
2802
2803 /proposals/{id}/discard:
2804 post:
2805 tags: [Proposals]
2806 summary: Discard proposal
2807 parameters:
2808 - name: id
2809 in: path
2810 required: true
2811 schema: { type: string }
2812 responses:
2813 '200':
2814 content:
2815 application/json:
2816 schema:
2817 type: object
2818 properties:
2819 proposal_id: { type: string }
2820 status: { type: string, enum: [discarded] }
2821
2822 /capture:
2823 post:
2824 tags: [Capture]
2825 summary: Ingest message into vault inbox (webhook-style)
2826 description: Same contract as capture-webhook. If CAPTURE_WEBHOOK_SECRET is set, require X-Webhook-Secret header.
2827 security: []
2828 requestBody:
2829 content:
2830 application/json:
2831 schema:
2832 type: object
2833 required: [body]
2834 properties:
2835 body: { type: string }
2836 source_id: { type: string }
2837 source: { type: string }
2838 project: { type: string }
2839 tags: { type: array, items: { type: string } }
2840 responses:
2841 '200':
2842 content:
2843 application/json:
2844 schema: { type: object, properties: { ok: { type: boolean }, path: { type: string } } }
2845 '400':
2846
2847 components:
2848 securitySchemes:
2849 BearerAuth:
2850 type: http
2851 scheme: bearer
2852 bearerFormat: JWT
2853
2854 schemas:
2855 Error:
2856 type: object
2857 properties:
2858 error: { type: string }
2859 code: { type: string }
2860
2861 NoteListItem:
2862 type: object
2863 properties:
2864 path: { type: string }
2865 title: { type: string, nullable: true }
2866 project: { type: string, nullable: true }
2867 tags: { type: array, items: { type: string } }
2868 date: { type: string, nullable: true }
2869
2870 NoteFull:
2871 type: object
2872 properties:
2873 path: { type: string }
2874 frontmatter: { type: object }
2875 body: { type: string }
2876
2877 SearchResult:
2878 type: object
2879 properties:
2880 path: { type: string }
2881 snippet: { type: string }
2882 score: { type: number }
2883 project: { type: string }
2884 tags: { type: array, items: { type: string } }
2885
2886 NoteOutline:
2887 type: object
2888 required: [schema, path, headings, truncated]
2889 properties:
2890 schema:
2891 type: string
2892 enum: [knowtation.note_outline/v1]
2893 path: { type: string }
2894 title: { type: string, nullable: true }
2895 headings:
2896 type: array
2897 maxItems: 500
2898 items: { $ref: '#/components/schemas/NoteOutlineHeading' }
2899 truncated: { type: boolean }
2900
2901 NoteOutlineHeading:
2902 type: object
2903 required: [level, text, id]
2904 properties:
2905 level: { type: integer, minimum: 1, maximum: 6 }
2906 text: { type: string }
2907 id: { type: string }
2908
2909 DocumentTree:
2910 type: object
2911 required: [schema, path, root, truncated]
2912 properties:
2913 schema:
2914 type: string
2915 enum: [knowtation.document_tree/v0]
2916 path: { type: string }
2917 title: { type: string, nullable: true }
2918 root:
2919 type: object
2920 required: [children]
2921 properties:
2922 children:
2923 type: array
2924 maxItems: 500
2925 items: { $ref: '#/components/schemas/DocumentTreeNode' }
2926 truncated: { type: boolean }
2927
2928 DocumentTreeNode:
2929 type: object
2930 required: [id, level, text, children]
2931 properties:
2932 id: { type: string }
2933 level: { type: integer, minimum: 1, maximum: 6 }
2934 text: { type: string }
2935 children:
2936 type: array
2937 items: { $ref: '#/components/schemas/DocumentTreeNode' }
2938
2939 MetadataFacets:
2940 type: object
2941 required: [schema, path, facets, inferred, truncated]
2942 properties:
2943 schema:
2944 type: string
2945 enum: [knowtation.metadata_facets/v0]
2946 path: { type: string }
2947 facets:
2948 type: object
2949 required: [project, tags, date, updated, causal_chain_id, entity, episode_id]
2950 properties:
2951 project: { type: string, nullable: true }
2952 tags:
2953 type: array
2954 maxItems: 100
2955 items: { type: string }
2956 date: { type: string, nullable: true }
2957 updated: { type: string, nullable: true }
2958 causal_chain_id: { type: string, nullable: true }
2959 entity:
2960 type: array
2961 maxItems: 100
2962 items: { type: string }
2963 episode_id: { type: string, nullable: true }
2964 inferred:
2965 type: object
2966 required: [folder, source_type]
2967 properties:
2968 folder: { type: string, nullable: true }
2969 source_type: { nullable: true, enum: [null] }
2970 truncated: { type: boolean }
2971
2972 SectionSource:
2973 type: object
2974 required: [schema, path, sections, truncated]
2975 properties:
2976 schema:
2977 type: string
2978 enum: [knowtation.section_source/v0]
2979 path: { type: string }
2980 title: { type: string, nullable: true }
2981 sections:
2982 type: array
2983 items: { $ref: '#/components/schemas/SectionSourceSection' }
2984 truncated: { type: boolean }
2985
2986 SectionSourceSection:
2987 type: object
2988 required:
2989 - section_id
2990 - heading_id
2991 - level
2992 - heading_path
2993 - heading_text
2994 - child_section_ids
2995 - body_available
2996 - body_returned
2997 - snippet_returned
2998 properties:
2999 section_id: { type: string }
3000 heading_id: { type: string }
3001 level: { type: integer, minimum: 1, maximum: 6 }
3002 heading_path: { type: array, items: { type: string } }
3003 heading_text: { type: string }
3004 child_section_ids: { type: array, items: { type: string } }
3005 body_available: { type: boolean }
3006 body_returned: { type: boolean, enum: [false] }
3007 snippet_returned: { type: boolean, enum: [false] }
3008
3009 Proposal:
3010 type: object
3011 properties:
3012 proposal_id: { type: string }
3013 path: { type: string }
3014 status: { type: string }
3015 intent: { type: string }
3016 base_state_id: { type: string }
3017 external_ref: { type: string }
3018 vault_id: { type: string }
3019 proposed_by: { type: string }
3020 labels: { type: array, items: { type: string } }
3021 source: { type: string }
3022 suggested_labels: { type: array, items: { type: string } }
3023 assistant_notes: { type: string }
3024 assistant_model: { type: string }
3025 assistant_at: { type: string }
3026 created_at: { type: string }
3027 updated_at: { type: string }
3028 evaluation_status:
3029 type: string
3030 enum: [none, pending, passed, failed, needs_changes]
3031 evaluation_grade: { type: string }
3032 evaluation_comment: { type: string }
3033 evaluated_by: { type: string }
3034 evaluated_at: { type: string }
3035 evaluation_waiver:
3036 type: object
3037 nullable: true
3038 properties:
3039 by: { type: string }
3040 at: { type: string }
3041 reason: { type: string }
3042 review_queue: { type: string }
3043 review_severity: { type: string, enum: [standard, elevated] }
3044 auto_flag_reasons:
3045 type: array
3046 items: { type: string }
3047 auto_flag_reasons_json: { type: string, description: JSON array string on canister }
3048 review_hints: { type: string }
3049 review_hints_at: { type: string }
3050 review_hints_model: { type: string }
3051 assistant_suggested_frontmatter:
3052 type: object
3053 description: Normalized SPEC-aligned suggested note metadata from Enrich (object on GET); omitted or empty on older proposals
3054 additionalProperties: true
3055
3056 ProposalDetail:
3057 allOf:
3058 - { $ref: '#/components/schemas/Proposal' }
3059 - type: object
3060 properties:
3061 body: { type: string }
3062 frontmatter: { type: object }
3063 evaluation_checklist:
3064 type: array
3065 items:
3066 type: object
3067 properties:
3068 id: { type: string }
3069 label: { type: string }
3070 passed: { type: boolean }
3071
3072 CalendarTimeline:
3073 type: object
3074 required: [schema, vault_id, from, to, layers, items]
3075 properties:
3076 schema:
3077 type: string
3078 enum: [knowtation.calendar_timeline/v0]
3079 vault_id: { type: string }
3080 from: { type: string }
3081 to: { type: string }
3082 layers:
3083 type: array
3084 items:
3085 type: string
3086 enum: [notes, events]
3087 items:
3088 type: array
3089 items:
3090 oneOf:
3091 - { $ref: '#/components/schemas/CalendarTimelineNoteItem' }
3092 - { $ref: '#/components/schemas/CalendarTimelineEventItem' }
3093
3094 CalendarTimelineNoteItem:
3095 type: object
3096 required: [kind, date, path, title, project, tags, sort_at]
3097 properties:
3098 kind:
3099 type: string
3100 enum: [note]
3101 date: { type: string }
3102 path: { type: string }
3103 title: { type: string, nullable: true }
3104 project: { type: string, nullable: true }
3105 tags:
3106 type: array
3107 items: { type: string }
3108 sort_at: { type: string }
3109
3110 CalendarTimelineEventItem:
3111 type: object
3112 required: [kind, event_id, source_calendar_id, start, end, timezone, summary, busy, status, calendar_label, sort_at]
3113 properties:
3114 kind:
3115 type: string
3116 enum: [event]
3117 event_id: { type: string }
3118 source_calendar_id: { type: string }
3119 start: { type: string }
3120 end: { type: string }
3121 timezone: { type: string }
3122 summary: { type: string, nullable: true }
3123 busy: { type: boolean }
3124 status:
3125 type: string
3126 enum: [confirmed, cancelled, tentative]
3127 calendar_label: { type: string, nullable: true }
3128 sort_at: { type: string }
3129
3130 CalendarAgentContext:
3131 type: object
3132 required: [schema, vault_id, from, to, requested_tier, effective_tier, policy_agent_context_tier_max_cap, source_calendars, items]
3133 properties:
3134 schema:
3135 type: string
3136 enum: [knowtation.calendar_agent_context/v0]
3137 vault_id: { type: string }
3138 from: { type: string }
3139 to: { type: string }
3140 requested_tier:
3141 type: integer
3142 minimum: 0
3143 maximum: 2
3144 effective_tier:
3145 type: integer
3146 minimum: 0
3147 maximum: 2
3148 description: Requested tier after the org policy cap is applied.
3149 policy_agent_context_tier_max_cap:
3150 type: integer
3151 minimum: 0
3152 maximum: 4
3153 source_calendars:
3154 type: array
3155 items: { $ref: '#/components/schemas/AgentContextCalendarSummary' }
3156 items:
3157 type: array
3158 items: { $ref: '#/components/schemas/CalendarAgentContextEventItem' }
3159
3160 AgentContextCalendarSummary:
3161 type: object
3162 required: [source_calendar_id, display_name, user_group, enabled_for_agents, agent_context_tier_max, effective_tier, event_count]
3163 properties:
3164 source_calendar_id: { type: string }
3165 display_name: { type: string }
3166 user_group:
3167 type: string
3168 nullable: true
3169 enum: [personal, work, school, other, null]
3170 enabled_for_agents: { type: boolean }
3171 agent_context_tier_max:
3172 type: integer
3173 minimum: 0
3174 maximum: 4
3175 effective_tier:
3176 type: integer
3177 minimum: 0
3178 maximum: 2
3179 event_count: { type: integer }
3180
3181 CalendarAgentContextEventItem:
3182 type: object
3183 required: [event_id, source_calendar_id, external_uid, start, end, timezone, busy, status, agent_tier]
3184 description: >
3185 Redacted event. `summary` and `calendar_label` are present only at tier 2;
3186 tier 1 omits the event title entirely.
3187 properties:
3188 event_id: { type: string }
3189 source_calendar_id: { type: string }
3190 external_uid: { type: string }
3191 start: { type: string }
3192 end: { type: string }
3193 timezone: { type: string }
3194 busy: { type: boolean }
3195 status:
3196 type: string
3197 enum: [confirmed, cancelled, tentative]
3198 agent_tier:
3199 type: integer
3200 minimum: 1
3201 maximum: 2
3202 summary: { type: string, nullable: true }
3203 calendar_label: { type: string, nullable: true }
3204
3205 SourceCalendarList:
3206 type: object
3207 required: [schema, vault_id, source_calendars]
3208 properties:
3209 schema:
3210 type: string
3211 enum: [knowtation.source_calendars/v0]
3212 vault_id: { type: string }
3213 source_calendars:
3214 type: array
3215 items: { $ref: '#/components/schemas/SourceCalendar' }
3216
3217 SourceCalendar:
3218 type: object
3219 required: [source_calendar_id, connector_id, display_name, enabled_for_sync, enabled_for_display, enabled_for_agents, agent_context_tier_max]
3220 properties:
3221 source_calendar_id: { type: string }
3222 connector_id: { type: string }
3223 display_name: { type: string }
3224 color: { type: string, nullable: true }
3225 user_group:
3226 type: string
3227 nullable: true
3228 enum: [personal, work, school, other, null]
3229 enabled_for_sync: { type: boolean }
3230 enabled_for_display: { type: boolean }
3231 enabled_for_agents: { type: boolean }
3232 agent_context_tier_max:
3233 type: integer
3234 minimum: 0
3235 maximum: 4
3236 provider: { type: string }
3237
3238 CalendarIcsImportRequest:
3239 type: object
3240 required: [ics_text]
3241 properties:
3242 ics_text: { type: string }
3243 display_name: { type: string }
3244 source_calendar_id: { type: string }
3245 connector_id: { type: string }
3246 default_timezone: { type: string }
3247
3248 CalendarIcsImportResult:
3249 type: object
3250 required: [schema, vault_id, source_calendar_id, connector_id, imported, updated]
3251 properties:
3252 schema:
3253 type: string
3254 enum: [knowtation.calendar_import/v0]
3255 vault_id: { type: string }
3256 source_calendar_id: { type: string }
3257 connector_id: { type: string }
3258 imported: { type: integer }
3259 updated: { type: integer }
3260
3261 SourceCalendarPatchRequest:
3262 type: object
3263 minProperties: 1
3264 properties:
3265 enabled_for_display: { type: boolean }
3266 enabled_for_agents: { type: boolean }
3267 agent_context_tier_max:
3268 type: integer
3269 minimum: 0
3270 maximum: 4
3271 user_group:
3272 type: string
3273 nullable: true
3274 enum: [personal, work, school, other, null]
3275
3276 SourceCalendarPatchResult:
3277 type: object
3278 required: [schema, vault_id, policy_agent_context_tier_max_cap, source_calendar]
3279 properties:
3280 schema:
3281 type: string
3282 enum: [knowtation.source_calendar_patch/v0]
3283 vault_id: { type: string }
3284 policy_agent_context_tier_max_cap:
3285 type: integer
3286 minimum: 0
3287 maximum: 4
3288 source_calendar: { $ref: '#/components/schemas/SourceCalendar' }
3289
3290 FlowListResponse:
3291 type: object
3292 required: [schema, vault_id, effective_scope, flows, truncated]
3293 properties:
3294 schema:
3295 type: string
3296 enum: [knowtation.flow_list/v0]
3297 vault_id: { type: string }
3298 effective_scope:
3299 type: string
3300 enum: [personal, project, org]
3301 flows:
3302 type: array
3303 maxItems: 200
3304 items: { $ref: '#/components/schemas/FlowSummary' }
3305 truncated: { type: boolean }
3306
3307 TaskListResponse:
3308 type: object
3309 required: [schema, vault_id, effective_scope, tasks, truncated]
3310 properties:
3311 schema:
3312 type: string
3313 enum: [knowtation.task_list/v0]
3314 vault_id: { type: string }
3315 effective_scope:
3316 type: string
3317 enum: [personal, project, org]
3318 tasks:
3319 type: array
3320 maxItems: 500
3321 items: { $ref: '#/components/schemas/TaskSummary' }
3322 truncated: { type: boolean }
3323
3324 LearningPathListResponse:
3325 type: object
3326 required: [schema, vault_id, effective_scope, paths, truncated]
3327 properties:
3328 schema:
3329 type: string
3330 enum: [knowtation.learning_path_list/v0]
3331 vault_id: { type: string }
3332 effective_scope:
3333 type: string
3334 enum: [personal, project, org]
3335 paths:
3336 type: array
3337 maxItems: 200
3338 items: { $ref: '#/components/schemas/LearningPathSummary' }
3339 truncated: { type: boolean }
3340
3341 LearningPathSummary:
3342 type: object
3343 required: [schema, path_id, scope, status, title, goal, current_step_index, step_count, next_step_title, active_decisions, workspace_id, updated]
3344 properties:
3345 schema:
3346 type: string
3347 enum: [knowtation.learning_path/v0]
3348 path_id: { type: string }
3349 scope:
3350 type: string
3351 enum: [personal, project, org]
3352 status:
3353 type: string
3354 enum: [active, paused, archived]
3355 title: { type: string }
3356 goal: { type: string }
3357 current_step_index: { type: integer }
3358 step_count: { type: integer }
3359 next_step_title: { type: string }
3360 active_decisions: { type: string }
3361 workspace_id: { type: string }
3362 updated: { type: string, format: date-time }
3363
3364 LearningPathGetResponse:
3365 type: object
3366 required: [schema, vault_id, effective_scope, path]
3367 properties:
3368 schema:
3369 type: string
3370 enum: [knowtation.learning_path_get/v0]
3371 vault_id: { type: string }
3372 effective_scope:
3373 type: string
3374 enum: [personal, project, org]
3375 path: { $ref: '#/components/schemas/LearningPathRecord' }
3376
3377 LearningPathRecord:
3378 type: object
3379 required: [schema, path_id, scope, status, title, summary, goal, steps, current_step_index, step_count, next_step_title, active_decisions, workspace_id, note_path, created, updated]
3380 properties:
3381 schema:
3382 type: string
3383 enum: [knowtation.learning_path/v0]
3384 path_id: { type: string }
3385 scope:
3386 type: string
3387 enum: [personal, project, org]
3388 status:
3389 type: string
3390 enum: [active, paused, archived]
3391 title: { type: string }
3392 summary: { type: string }
3393 goal: { type: string }
3394 steps:
3395 type: array
3396 minItems: 1
3397 maxItems: 20
3398 items:
3399 type: object
3400 required: [title, objective, source_document_ids]
3401 properties:
3402 title: { type: string }
3403 objective: { type: string }
3404 source_document_ids:
3405 type: array
3406 items: { type: string }
3407 current_step_index: { type: integer }
3408 step_count: { type: integer }
3409 next_step_title: { type: string }
3410 active_decisions: { type: string }
3411 workspace_id: { type: string }
3412 note_path:
3413 type: string
3414 nullable: true
3415 created: { type: string, format: date-time }
3416 updated: { type: string, format: date-time }
3417
3418 LearningPathProposalRequest:
3419 type: object
3420 properties:
3421 proposal_kind:
3422 type: string
3423 enum: [path_create, path_update, path_archive]
3424 title: { type: string }
3425 summary: { type: string }
3426 goal: { type: string }
3427 steps: { type: array, items: { type: object } }
3428 path_id: { type: string }
3429 intent: { type: string }
3430
3431 LearningPathProposalResponse:
3432 type: object
3433 required: [schema, proposal_id, proposal_kind, path_id, status, review_queue]
3434 properties:
3435 schema:
3436 type: string
3437 enum: [knowtation.learning_path_proposal/v0]
3438 proposal_id: { type: string }
3439 proposal_kind:
3440 type: string
3441 enum: [path_create, path_update, path_archive]
3442 path_id: { type: string }
3443 scope:
3444 type: string
3445 enum: [personal, project, org]
3446 auto_approvable: { type: boolean }
3447 status: { type: string }
3448 review_queue:
3449 type: string
3450 enum: [learning-path]
3451
3452 TaskSummary:
3453 type: object
3454 required: [schema, task_id, kind, scope, status, title, workspace_id, due_at, run_ref, truncated]
3455 properties:
3456 schema:
3457 type: string
3458 enum: [knowtation.task/v0]
3459 task_id: { type: string }
3460 kind:
3461 type: string
3462 enum: [personal, assignment, mentor_checkin, org_work_job]
3463 scope:
3464 type: string
3465 enum: [personal, project, org]
3466 status:
3467 type: string
3468 enum: [pending, in_progress, blocked, done, cancelled]
3469 title: { type: string }
3470 workspace_id: { type: string }
3471 due_at:
3472 type: string
3473 nullable: true
3474 run_ref:
3475 type: string
3476 nullable: true
3477 truncated: { type: boolean }
3478
3479 TaskGetResponse:
3480 type: object
3481 required: [schema, vault_id, effective_scope, task]
3482 properties:
3483 schema:
3484 type: string
3485 enum: [knowtation.task_get/v0]
3486 vault_id: { type: string }
3487 effective_scope:
3488 type: string
3489 enum: [personal, project, org]
3490 task: { $ref: '#/components/schemas/TaskRecord' }
3491
3492 TaskRecord:
3493 type: object
3494 required:
3495 - schema
3496 - task_id
3497 - kind
3498 - scope
3499 - status
3500 - title
3501 - workspace_id
3502 - due_at
3503 - artifact_links
3504 - created
3505 - updated
3506 - truncated
3507 properties:
3508 schema:
3509 type: string
3510 enum: [knowtation.task/v0]
3511 task_id: { type: string }
3512 kind:
3513 type: string
3514 enum: [personal, assignment, mentor_checkin, org_work_job]
3515 scope:
3516 type: string
3517 enum: [personal, project, org]
3518 status:
3519 type: string
3520 enum: [pending, in_progress, blocked, done, cancelled]
3521 title: { type: string }
3522 workspace_id: { type: string }
3523 due_at:
3524 type: string
3525 nullable: true
3526 assignee_ref:
3527 type: string
3528 nullable: true
3529 assigner_ref:
3530 type: string
3531 nullable: true
3532 run_ref:
3533 type: string
3534 nullable: true
3535 artifact_links:
3536 type: array
3537 maxItems: 32
3538 items:
3539 type: object
3540 required: [kind, ref]
3541 properties:
3542 kind:
3543 type: string
3544 enum: [note, media, review_item]
3545 ref: { type: string }
3546 created: { type: string }
3547 updated: { type: string }
3548 truncated: { type: boolean }
3549
3550 AttachmentListResponse:
3551 type: object
3552 required: [schema, vault_id, effective_scope, attachments, truncated]
3553 properties:
3554 schema:
3555 type: string
3556 enum: [knowtation.attachment_list/v0]
3557 vault_id: { type: string }
3558 effective_scope:
3559 type: string
3560 enum: [personal, project, org]
3561 attachments:
3562 type: array
3563 maxItems: 500
3564 items: { $ref: '#/components/schemas/AttachmentSummary' }
3565 truncated: { type: boolean }
3566
3567 AttachmentSummary:
3568 type: object
3569 required:
3570 - schema
3571 - attachment_id
3572 - source
3573 - storage_kind
3574 - mime_class
3575 - scope
3576 - display_label
3577 - created
3578 - truncated
3579 properties:
3580 schema:
3581 type: string
3582 enum: [knowtation.attachment/v0]
3583 attachment_id: { type: string }
3584 source:
3585 type: string
3586 enum: [vault_file, mist_blob, embedded_url]
3587 storage_kind:
3588 type: string
3589 enum: [vault_blob, external_link]
3590 mime_class:
3591 type: string
3592 enum: [image, video, audio, document, unknown]
3593 scope:
3594 type: string
3595 enum: [personal, project, org]
3596 display_label: { type: string }
3597 created: { type: string }
3598 truncated: { type: boolean }
3599
3600 AttachmentGetResponse:
3601 type: object
3602 required: [schema, vault_id, effective_scope, attachment]
3603 properties:
3604 schema:
3605 type: string
3606 enum: [knowtation.attachment_get/v0]
3607 vault_id: { type: string }
3608 effective_scope:
3609 type: string
3610 enum: [personal, project, org]
3611 attachment: { $ref: '#/components/schemas/AttachmentRecord' }
3612
3613 MediaProposalResponse:
3614 type: object
3615 required: [schema, proposal_id, proposal_kind, attachment_id, scope, auto_approvable, status]
3616 properties:
3617 schema:
3618 type: string
3619 enum: [knowtation.media_proposal/v0]
3620 proposal_id: { type: string }
3621 proposal_kind:
3622 type: string
3623 enum: [media_external_link, media_attach]
3624 attachment_id:
3625 type: string
3626 pattern: '^att_(file|mist|url|link)_[a-f0-9]{32}$'
3627 note_ref: { type: [string, 'null'] }
3628 connector_id: { type: [string, 'null'] }
3629 scope:
3630 type: string
3631 enum: [personal, project, org]
3632 base_state_id: { type: string }
3633 external_ref: { type: [string, 'null'] }
3634 auto_approvable:
3635 type: boolean
3636 enum: [false]
3637 status:
3638 type: string
3639 enum: [proposed]
3640 review_queue:
3641 type: string
3642 enum: [media-writes]
3643
3644 AttachmentRecord:
3645 type: object
3646 required:
3647 - schema
3648 - attachment_id
3649 - source
3650 - storage_kind
3651 - mime_class
3652 - mime_type
3653 - scope
3654 - display_label
3655 - byte_size
3656 - linked_note_refs
3657 - agent_visible
3658 - created
3659 - updated
3660 - truncated
3661 properties:
3662 schema:
3663 type: string
3664 enum: [knowtation.attachment/v0]
3665 attachment_id: { type: string }
3666 source:
3667 type: string
3668 enum: [vault_file, mist_blob, embedded_url]
3669 storage_kind:
3670 type: string
3671 enum: [vault_blob, external_link]
3672 mime_class:
3673 type: string
3674 enum: [image, video, audio, document, unknown]
3675 mime_type:
3676 type: string
3677 nullable: true
3678 scope:
3679 type: string
3680 enum: [personal, project, org]
3681 display_label: { type: string }
3682 byte_size:
3683 type: integer
3684 nullable: true
3685 linked_note_refs:
3686 type: array
3687 items: { type: string }
3688 agent_visible: { type: boolean }
3689 created: { type: string }
3690 updated: { type: string }
3691 truncated: { type: boolean }
3692
3693 TaskWriteProposalRequest:
3694 type: object
3695 required: [intent]
3696 properties:
3697 proposal_kind:
3698 type: string
3699 enum: [task_create, task_status_update, task_assign, task_artifact_link]
3700 intent: { type: string, minLength: 1 }
3701 task: { $ref: '#/components/schemas/TaskRecord' }
3702 task_id: { type: string }
3703 base_state_id: { type: string }
3704 status:
3705 type: string
3706 enum: [pending, in_progress, blocked, done, cancelled]
3707 assignee_ref: { type: string, nullable: true }
3708 assigner_ref: { type: string, nullable: true }
3709 artifact_link:
3710 type: object
3711 required: [kind, ref]
3712 properties:
3713 kind: { type: string }
3714 ref: { type: string }
3715
3716 TaskLoopWriteProposalRequest:
3717 type: object
3718 required: [intent]
3719 properties:
3720 proposal_kind:
3721 type: string
3722 enum: [task_loop_create, task_loop_pause, task_loop_cancel]
3723 intent: { type: string, minLength: 1 }
3724 loop: { type: object }
3725 loop_id: { type: string }
3726 base_state_id: { type: string }
3727
3728 TaskInstanceMaterializeRequest:
3729 type: object
3730 required: [intent]
3731 properties:
3732 intent: { type: string, minLength: 1 }
3733 occurrence_key: { type: string }
3734 occurrence_at: { type: string }
3735 due_at: { type: string }
3736 title_override: { type: string }
3737 base_state_id: { type: string }
3738
3739 TaskProposalResponse:
3740 type: object
3741 required:
3742 - schema
3743 - proposal_id
3744 - proposal_kind
3745 - auto_approvable
3746 - status
3747 - review_queue
3748 properties:
3749 schema:
3750 type: string
3751 enum: [knowtation.task_proposal/v0]
3752 proposal_id: { type: string }
3753 proposal_kind: { type: string }
3754 task_id: { type: string, nullable: true }
3755 loop_id: { type: string, nullable: true }
3756 base_state_id: { type: string, nullable: true }
3757 scope:
3758 type: string
3759 enum: [personal, project, org]
3760 auto_approvable: { type: boolean }
3761 status: { type: string }
3762 review_queue: { type: string }
3763
3764 TaskInstanceProposalResponse:
3765 allOf:
3766 - $ref: '#/components/schemas/TaskProposalResponse'
3767 - type: object
3768 required: [occurrence_key]
3769 properties:
3770 schema:
3771 type: string
3772 enum: [knowtation.task_instance_proposal/v0]
3773 occurrence_key: { type: string }
3774
3775 FlowSummary:
3776 type: object
3777 required: [schema, flow_id, title, version, scope, summary, tags, step_count, updated, truncated]
3778 properties:
3779 schema:
3780 type: string
3781 enum: [knowtation.flow/v0]
3782 flow_id: { type: string }
3783 title: { type: string }
3784 version: { type: string }
3785 scope:
3786 type: string
3787 enum: [personal, project, org]
3788 summary: { type: string }
3789 tags:
3790 type: array
3791 maxItems: 32
3792 items: { type: string }
3793 step_count: { type: integer, minimum: 0 }
3794 updated: { type: string }
3795 truncated: { type: boolean }
3796
3797 FlowGetResponse:
3798 type: object
3799 required: [schema, vault_id, flow, steps]
3800 properties:
3801 schema:
3802 type: string
3803 enum: [knowtation.flow_get/v0]
3804 vault_id: { type: string }
3805 flow: { $ref: '#/components/schemas/Flow' }
3806 steps:
3807 type: array
3808 maxItems: 100
3809 items: { $ref: '#/components/schemas/FlowStep' }
3810
3811 FlowRun:
3812 type: object
3813 required:
3814 [schema, run_id, run_ref, flow_id, flow_version, scope, status, step_states, started, provenance]
3815 description: knowtation.flow_run/v0 — canonical run state (pointer-only).
3816 properties:
3817 schema:
3818 type: string
3819 enum: [knowtation.flow_run/v0]
3820 run_id: { type: string }
3821 run_ref:
3822 type: string
3823 description: Portable cross-system pointer (flow_run:…); resolves get/list lookups.
3824 flow_id: { type: string }
3825 flow_version: { type: string }
3826 scope:
3827 type: string
3828 enum: [personal, project, org]
3829 status:
3830 type: string
3831 enum: [pending, in_progress, blocked, done, abandoned]
3832 step_states:
3833 type: array
3834 maxItems: 200
3835 items:
3836 type: object
3837 required: [step_id, status, verified]
3838 properties:
3839 step_id: { type: string }
3840 status:
3841 type: string
3842 enum: [pending, in_progress, blocked, done, skipped]
3843 evidence_ref: { type: string, nullable: true }
3844 verified: { type: boolean }
3845 started: { type: string, format: date-time }
3846 provenance:
3847 type: object
3848 required: [actor, harness]
3849 properties:
3850 actor: { type: string, description: Hashed actor id only }
3851 harness: { type: string }
3852 task_ref: { type: string, nullable: true }
3853 external_ref: { type: string, nullable: true }
3854
3855 FlowRunGetResponse:
3856 type: object
3857 required: [schema, vault_id, run]
3858 properties:
3859 schema:
3860 type: string
3861 enum: [knowtation.flow_run_get/v0]
3862 vault_id: { type: string }
3863 run: { $ref: '#/components/schemas/FlowRun' }
3864
3865 FlowRunResponse:
3866 allOf:
3867 - $ref: '#/components/schemas/FlowRunGetResponse'
3868
3869 FlowRunListResponse:
3870 type: object
3871 required: [schema, vault_id, effective_scope, runs, truncated]
3872 properties:
3873 schema:
3874 type: string
3875 enum: [knowtation.flow_run_list/v0]
3876 vault_id: { type: string }
3877 effective_scope:
3878 type: string
3879 enum: [personal, project, org]
3880 runs:
3881 type: array
3882 maxItems: 200
3883 items: { $ref: '#/components/schemas/FlowRun' }
3884 truncated: { type: boolean }
3885
3886 FlowRunStartResponse:
3887 type: object
3888 required: [schema, run]
3889 properties:
3890 schema:
3891 type: string
3892 enum: [knowtation.flow_run_start/v0]
3893 run: { $ref: '#/components/schemas/FlowRun' }
3894
3895 FlowRunSubmitReviewResponse:
3896 type: object
3897 required: [schema, run, proposal_id]
3898 properties:
3899 schema:
3900 type: string
3901 enum: [knowtation.flow_run_submit_review/v0]
3902 run: { $ref: '#/components/schemas/FlowRun' }
3903 proposal_id: { type: string }
3904
3905 FlowProposeRequest:
3906 type: object
3907 required: [flow, steps, intent]
3908 description: Propose a new Flow. intent is untrusted and recorded verbatim.
3909 properties:
3910 flow: { $ref: '#/components/schemas/Flow' }
3911 steps:
3912 type: array
3913 maxItems: 100
3914 items: { $ref: '#/components/schemas/FlowStep' }
3915 intent: { type: string, minLength: 1 }
3916
3917 FlowProposeEditRequest:
3918 type: object
3919 required: [flow, steps, intent, base_version, base_state_id]
3920 description: >
3921 Propose an edit. base_version + base_state_id (flowst1_ token) gate
3922 optimistic concurrency; flow.version must exceed base_version.
3923 properties:
3924 flow: { $ref: '#/components/schemas/Flow' }
3925 steps:
3926 type: array
3927 maxItems: 100
3928 items: { $ref: '#/components/schemas/FlowStep' }
3929 intent: { type: string, minLength: 1 }
3930 base_version: { type: string }
3931 base_state_id: { type: string }
3932
3933 FlowImportRequest:
3934 type: object
3935 required: [bundle, intent]
3936 description: Import a portable bundle through the same scope-checked propose path.
3937 properties:
3938 bundle:
3939 type: object
3940 required: [flow, steps]
3941 properties:
3942 flow: { $ref: '#/components/schemas/Flow' }
3943 steps:
3944 type: array
3945 maxItems: 100
3946 items: { $ref: '#/components/schemas/FlowStep' }
3947 intent: { type: string, minLength: 1 }
3948 external_ref: { type: string }
3949 source_vault_hint: { type: string }
3950
3951 FlowProposalResponse:
3952 type: object
3953 required: [schema, proposal_id, flow_id, scope, auto_approvable, status, review_queue]
3954 description: >
3955 knowtation.flow_proposal/v0 envelope — pointers/labels only, never a
3956 rendered Flow body or secret. base_version/base_state_id are null for new.
3957 properties:
3958 schema:
3959 type: string
3960 enum: [knowtation.flow_proposal/v0]
3961 proposal_id: { type: string }
3962 flow_id: { type: string }
3963 base_version: { type: string, nullable: true }
3964 base_state_id: { type: string, nullable: true }
3965 scope:
3966 type: string
3967 enum: [personal, project, org]
3968 auto_approvable: { type: boolean }
3969 status:
3970 type: string
3971 enum: [proposed]
3972 review_queue: { type: string }
3973
3974 FlowExternalGrantMintRequest:
3975 type: object
3976 required: [flow_version, requested_tools]
3977 properties:
3978 flow_version: { type: string }
3979 requested_tools:
3980 type: array
3981 minItems: 1
3982 items: { type: string }
3983 ttl_seconds: { type: integer, minimum: 1 }
3984 actor_label: { type: string }
3985
3986 FlowExternalGrant:
3987 type: object
3988 required:
3989 - schema
3990 - grant_id
3991 - vault_id
3992 - scope
3993 - flow_id
3994 - flow_version
3995 - allowed_tools
3996 - allowed_harnesses
3997 - expires_at
3998 - issued_at
3999 - revoked_at
4000 - actor_hash
4001 - invocation_count
4002 properties:
4003 schema:
4004 type: string
4005 enum: [knowtation.flow_external_grant/v0]
4006 grant_id: { type: string }
4007 vault_id: { type: string }
4008 scope:
4009 type: string
4010 enum: [personal, project, org]
4011 flow_id: { type: string }
4012 flow_version: { type: string }
4013 allowed_tools:
4014 type: array
4015 items: { type: string }
4016 allowed_harnesses:
4017 type: array
4018 items: { type: string }
4019 expires_at: { type: string, format: date-time }
4020 issued_at: { type: string, format: date-time }
4021 revoked_at: { type: string, format: date-time, nullable: true }
4022 actor_hash: { type: string }
4023 max_invocations: { type: integer }
4024 invocation_count: { type: integer }
4025
4026 FlowExternalGrantMintResponse:
4027 type: object
4028 required: [schema, grant, bearer, expires_at]
4029 properties:
4030 schema:
4031 type: string
4032 enum: [knowtation.flow_external_grant_mint/v0]
4033 grant: { $ref: '#/components/schemas/FlowExternalGrant' }
4034 bearer: { type: string }
4035 expires_at: { type: string, format: date-time }
4036
4037 FlowExternalGrantListResponse:
4038 type: object
4039 required: [schema, vault_id, grants]
4040 properties:
4041 schema:
4042 type: string
4043 enum: [knowtation.flow_external_grant_list/v0]
4044 vault_id: { type: string }
4045 grants:
4046 type: array
4047 items: { $ref: '#/components/schemas/FlowExternalGrant' }
4048
4049 AgentIdentityRegisterRequest:
4050 type: object
4051 required: [kind]
4052 properties:
4053 kind:
4054 type: string
4055 enum: [user_owned, org_owned, delegate]
4056 agent_id: { type: string }
4057 label: { type: string }
4058 scope_ceiling:
4059 type: string
4060 enum: [personal, project, org]
4061
4062 DelegationProposalResponse:
4063 type: object
4064 required: [schema, proposal_id, intent]
4065 properties:
4066 schema:
4067 type: string
4068 enum: [knowtation.delegation_proposal/v0]
4069 proposal_id: { type: string }
4070 intent: { type: string }
4071 agent_id: { type: string }
4072 consent_id: { type: string }
4073
4074 AgentIdentity:
4075 type: object
4076 required:
4077 - schema
4078 - agent_id
4079 - kind
4080 - owner_ref
4081 - vault_id
4082 - scope_ceiling
4083 - status
4084 - created
4085 - updated
4086 properties:
4087 schema:
4088 type: string
4089 enum: [knowtation.agent_identity/v0]
4090 agent_id: { type: string }
4091 kind:
4092 type: string
4093 enum: [user_owned, org_owned, delegate]
4094 owner_ref: { type: string }
4095 vault_id: { type: string }
4096 scope_ceiling:
4097 type: string
4098 enum: [personal, project, org]
4099 label: { type: string }
4100 status:
4101 type: string
4102 enum: [active, suspended, revoked]
4103 created: { type: string, format: date-time }
4104 updated: { type: string, format: date-time }
4105
4106 AgentIdentityListResponse:
4107 type: object
4108 required: [schema, vault_id, identities]
4109 properties:
4110 schema:
4111 type: string
4112 enum: [knowtation.agent_identity_list/v0]
4113 vault_id: { type: string }
4114 identities:
4115 type: array
4116 items: { $ref: '#/components/schemas/AgentIdentity' }
4117
4118 DelegationConsentProposeRequest:
4119 type: object
4120 required: [delegate_agent_id, scope]
4121 properties:
4122 delegate_agent_id: { type: string }
4123 scope:
4124 type: string
4125 enum: [personal, project, org]
4126 workspace_id: { type: string }
4127 allowed_flow_ids:
4128 type: array
4129 items: { type: string }
4130 allowed_task_kinds:
4131 type: array
4132 items: { type: string }
4133 allowed_task_ids:
4134 type: array
4135 items: { type: string }
4136 expires_at: { type: string, format: date-time }
4137
4138 DelegationConsentProposeResponse:
4139 type: object
4140 required: [schema, proposal_id, intent, consent_id]
4141 properties:
4142 schema:
4143 type: string
4144 enum: [knowtation.delegation_proposal/v0]
4145 proposal_id: { type: string }
4146 intent: { type: string }
4147 consent_id: { type: string }
4148 consent_preview: { $ref: '#/components/schemas/DelegationConsent' }
4149
4150 DelegationConsent:
4151 type: object
4152 required:
4153 - schema
4154 - consent_id
4155 - principal_ref
4156 - delegate_agent_id
4157 - scope
4158 - revoked_at
4159 - evidence_ref
4160 - created
4161 properties:
4162 schema:
4163 type: string
4164 enum: [knowtation.delegation_consent/v0]
4165 consent_id: { type: string }
4166 principal_ref: { type: string }
4167 delegate_agent_id: { type: string }
4168 scope:
4169 type: string
4170 enum: [personal, project, org]
4171 workspace_id: { type: string }
4172 allowed_flow_ids:
4173 type: array
4174 items: { type: string }
4175 allowed_task_kinds:
4176 type: array
4177 items: { type: string }
4178 allowed_task_ids:
4179 type: array
4180 items: { type: string }
4181 expires_at: { type: string, format: date-time }
4182 revoked_at: { type: string, format: date-time, nullable: true }
4183 evidence_ref: { type: string }
4184 created: { type: string, format: date-time }
4185
4186 DelegationGrantMintRequest:
4187 type: object
4188 required: [consent_id, actor_agent_id]
4189 properties:
4190 consent_id: { type: string }
4191 actor_agent_id: { type: string }
4192 task_ref: { type: string }
4193 run_ref: { type: string }
4194 flow_id: { type: string }
4195 flow_version: { type: string }
4196 ttl_seconds: { type: integer, minimum: 1 }
4197
4198 DelegationGrant:
4199 type: object
4200 required:
4201 - schema
4202 - grant_id
4203 - consent_id
4204 - actor_agent_id
4205 - principal_ref
4206 - scope
4207 - expires_at
4208 - revoked_at
4209 - action_count
4210 - issued_at
4211 properties:
4212 schema:
4213 type: string
4214 enum: [knowtation.delegation_grant/v0]
4215 grant_id: { type: string }
4216 consent_id: { type: string }
4217 actor_agent_id: { type: string }
4218 principal_ref: { type: string }
4219 scope:
4220 type: string
4221 enum: [personal, project, org]
4222 workspace_id: { type: string }
4223 task_ref: { type: string }
4224 run_ref: { type: string }
4225 flow_id: { type: string }
4226 flow_version: { type: string }
4227 expires_at: { type: string, format: date-time }
4228 revoked_at: { type: string, format: date-time, nullable: true }
4229 max_actions: { type: integer }
4230 action_count: { type: integer }
4231 issued_at: { type: string, format: date-time }
4232
4233 DelegationGrantMintResponse:
4234 type: object
4235 required: [schema, grant, bearer, expires_at]
4236 properties:
4237 schema:
4238 type: string
4239 enum: [knowtation.delegation_grant_mint/v0]
4240 grant: { $ref: '#/components/schemas/DelegationGrant' }
4241 bearer: { type: string }
4242 expires_at: { type: string, format: date-time }
4243
4244 DelegationGrantListResponse:
4245 type: object
4246 required: [schema, vault_id, grants]
4247 properties:
4248 schema:
4249 type: string
4250 enum: [knowtation.delegation_grant_list/v0]
4251 vault_id: { type: string }
4252 grants:
4253 type: array
4254 items: { $ref: '#/components/schemas/DelegationGrant' }
4255
4256 DelegationAuditAppendRequest:
4257 type: object
4258 required: [grant_id, actor_agent_id, action, evidence_refs]
4259 properties:
4260 grant_id: { type: string }
4261 actor_agent_id: { type: string }
4262 principal_ref: { type: string }
4263 action:
4264 type: string
4265 enum: [advance_step, complete_task, propose_outcome, invoke_tool, mint_subgrant]
4266 evidence_refs:
4267 type: array
4268 minItems: 1
4269 items: { type: string }
4270 task_ref: { type: string }
4271 run_ref: { type: string }
4272 flow_id: { type: string }
4273 flow_version: { type: string }
4274 step_id: { type: string }
4275 execution_location:
4276 type: string
4277 enum: [local, hosted, hybrid]
4278
4279 DelegationAudit:
4280 type: object
4281 required:
4282 - schema
4283 - audit_id
4284 - grant_id
4285 - actor_agent_id
4286 - principal_ref
4287 - action
4288 - evidence_refs
4289 - occurred_at
4290 properties:
4291 schema:
4292 type: string
4293 enum: [knowtation.delegation_audit/v0]
4294 audit_id: { type: string }
4295 grant_id: { type: string }
4296 actor_agent_id: { type: string }
4297 principal_ref: { type: string }
4298 task_ref: { type: string }
4299 run_ref: { type: string }
4300 flow_id: { type: string }
4301 flow_version: { type: string }
4302 step_id: { type: string }
4303 action:
4304 type: string
4305 enum: [advance_step, complete_task, propose_outcome, invoke_tool, mint_subgrant]
4306 evidence_refs:
4307 type: array
4308 items: { type: string }
4309 occurred_at: { type: string, format: date-time }
4310 execution_location:
4311 type: string
4312 enum: [local, hosted, hybrid]
4313
4314 FlowProjectResponse:
4315 type: object
4316 required: [schema, vault_id, projection, staleness, generator]
4317 properties:
4318 schema:
4319 type: string
4320 enum: [knowtation.flow_project/v0]
4321 vault_id: { type: string }
4322 projection: { $ref: '#/components/schemas/FlowProjection' }
4323 staleness: { $ref: '#/components/schemas/FlowProjectionStaleness' }
4324 generator: { $ref: '#/components/schemas/FlowProjectionGenerator' }
4325
4326 FlowProjection:
4327 type: object
4328 required: [schema, flow_id, flow_version, harness, rendered, generated_from_canonical, editable]
4329 properties:
4330 schema:
4331 type: string
4332 enum: [knowtation.flow_projection/v0]
4333 flow_id: { type: string }
4334 flow_version: { type: string }
4335 harness:
4336 type: string
4337 enum: [cursor_rule, cursor_skill, mcp_prompt, cli_runbook, agent_bundle]
4338 rendered:
4339 type: string
4340 maxLength: 65536
4341 generated_from_canonical:
4342 type: boolean
4343 enum: [true]
4344 editable:
4345 type: boolean
4346 enum: [false]
4347 fidelity:
4348 type: object
4349 required: [dropped_fields]
4350 properties:
4351 dropped_fields:
4352 type: array
4353 items: { type: string }
4354 notes: { type: string }
4355
4356 FlowProjectionStaleness:
4357 type: object
4358 required: [stale, projection_version, latest_version]
4359 properties:
4360 stale: { type: boolean }
4361 projection_version: { type: string }
4362 latest_version: { type: string }
4363
4364 FlowProjectionGenerator:
4365 type: object
4366 required: [generator_version, content_hash, generated_at]
4367 properties:
4368 generator_version: { type: string }
4369 content_hash: { type: string }
4370 generated_at: { type: string }
4371
4372 Flow:
4373 type: object
4374 required: [schema, flow_id, title, version, scope, summary, steps, updated, truncated]
4375 properties:
4376 schema:
4377 type: string
4378 enum: [knowtation.flow/v0]
4379 flow_id: { type: string }
4380 title: { type: string }
4381 version: { type: string }
4382 scope:
4383 type: string
4384 enum: [personal, project, org]
4385 summary: { type: string }
4386 tags:
4387 type: array
4388 maxItems: 32
4389 items: { type: string }
4390 steps:
4391 type: array
4392 maxItems: 100
4393 items: { type: string }
4394 inputs:
4395 type: array
4396 items:
4397 type: object
4398 required: [name, type, required]
4399 properties:
4400 name: { type: string }
4401 type: { type: string }
4402 required: { type: boolean }
4403 vault_mirror_path: { type: string, nullable: true }
4404 updated: { type: string }
4405 truncated: { type: boolean }
4406
4407 FlowStep:
4408 type: object
4409 required: [schema, step_id, flow_id, ordinal, owned_job, instruction, trigger, when_not_to_run, boundaries, output_shape, verification, automatable]
4410 properties:
4411 schema:
4412 type: string
4413 enum: [knowtation.flow_step/v0]
4414 step_id: { type: string }
4415 flow_id: { type: string }
4416 ordinal: { type: integer, minimum: 1 }
4417 owned_job: { type: string }
4418 instruction: { type: string }
4419 trigger: { type: string }
4420 when_not_to_run: { type: string }
4421 requires:
4422 type: array
4423 items:
4424 type: object
4425 required: [kind, id]
4426 properties:
4427 kind:
4428 type: string
4429 enum: [vault_scope, tool, file, artifact]
4430 id: { type: string }
4431 boundaries:
4432 type: array
4433 items: { type: string }
4434 skill_refs:
4435 type: array
4436 items:
4437 type: object
4438 required: [kind, id]
4439 properties:
4440 kind:
4441 type: string
4442 enum: [mcp_prompt, skill_pack, cli, external_tool]
4443 id: { type: string }
4444 inputs:
4445 type: array
4446 items:
4447 type: object
4448 required: [name, from]
4449 properties:
4450 name: { type: string }
4451 from: { type: string }
4452 outputs:
4453 type: array
4454 items:
4455 type: object
4456 required: [name, type]
4457 properties:
4458 name: { type: string }
4459 type: { type: string }
4460 output_shape: { type: string }
4461 verification:
4462 type: object
4463 required: [kind, evidence_required, description]
4464 properties:
4465 kind:
4466 type: string
4467 enum: [human_review, artifact_exists, value_match, test_pass, agent_check]
4468 evidence_required: { type: boolean }
4469 description: { type: string }
4470 automatable:
4471 type: string
4472 enum: [manual, agent_assisted, automatable]
File History 1 commit
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 9 days ago