@anchrd/intel-contract 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contract/audit.d.ts +41 -0
- package/dist/contract/audit.js +56 -0
- package/dist/contract/board.d.ts +94 -0
- package/dist/contract/board.js +143 -0
- package/dist/contract/bundle.d.ts +43 -0
- package/dist/contract/bundle.js +42 -6
- package/dist/contract/contract.d.ts +36 -0
- package/dist/contract/contract.js +32 -0
- package/dist/contract/flow-run.d.ts +3 -3
- package/dist/contract/flow.d.ts +6 -0
- package/dist/contract/flow.js +8 -1
- package/dist/contract/node.d.ts +22 -6
- package/dist/contract/node.js +25 -9
- package/dist/contract/share.d.ts +8 -0
- package/dist/contract/share.js +21 -5
- package/dist/contract/table.d.ts +6 -0
- package/package.json +9 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const AuditResourceType: z.ZodEnum<{
|
|
3
|
+
node: "node";
|
|
4
|
+
}>;
|
|
5
|
+
export type AuditResourceType = z.infer<typeof AuditResourceType>;
|
|
6
|
+
export declare const AuditEvent: z.ZodObject<{
|
|
7
|
+
id: z.ZodString;
|
|
8
|
+
actorId: z.ZodString;
|
|
9
|
+
action: z.ZodString;
|
|
10
|
+
resourceType: z.ZodEnum<{
|
|
11
|
+
node: "node";
|
|
12
|
+
}>;
|
|
13
|
+
resourceId: z.ZodString;
|
|
14
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
15
|
+
occurredAt: z.ZodISODateTime;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
export type AuditEvent = z.infer<typeof AuditEvent>;
|
|
18
|
+
export declare const AuditCursor: z.ZodString;
|
|
19
|
+
export declare const AuditListRequest: z.ZodObject<{
|
|
20
|
+
resourceType: z.ZodEnum<{
|
|
21
|
+
node: "node";
|
|
22
|
+
}>;
|
|
23
|
+
after: z.ZodOptional<z.ZodString>;
|
|
24
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
25
|
+
}, z.core.$strict>;
|
|
26
|
+
export type AuditListRequest = z.infer<typeof AuditListRequest>;
|
|
27
|
+
export declare const AuditListResponse: z.ZodObject<{
|
|
28
|
+
events: z.ZodArray<z.ZodObject<{
|
|
29
|
+
id: z.ZodString;
|
|
30
|
+
actorId: z.ZodString;
|
|
31
|
+
action: z.ZodString;
|
|
32
|
+
resourceType: z.ZodEnum<{
|
|
33
|
+
node: "node";
|
|
34
|
+
}>;
|
|
35
|
+
resourceId: z.ZodString;
|
|
36
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
37
|
+
occurredAt: z.ZodISODateTime;
|
|
38
|
+
}, z.core.$strict>>;
|
|
39
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
export type AuditListResponse = z.infer<typeof AuditListResponse>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { IntelId, IsoDateTime } from "./contract.js";
|
|
3
|
+
// Which kind of resource an event is about. The column already carries three values — `node`,
|
|
4
|
+
// `flow` and `flow-run` — but each needs a DIFFERENT visibility check, and only the node one
|
|
5
|
+
// exists as a reusable walk today (`subtreeCte`).
|
|
6
|
+
//
|
|
7
|
+
// ⚠️ This enum is deliberately narrower than the column (#620). It is the boundary of what the
|
|
8
|
+
// reader is allowed to ask for, not a mirror of what is stored. Asking for `flow` is REFUSED
|
|
9
|
+
// rather than answered with an empty list: an empty list reads as "nothing happened", and a
|
|
10
|
+
// consumer building on that would miss every flow event without ever learning they exist. Widening
|
|
11
|
+
// this enum later is an extension; answering silently would have been a change of meaning.
|
|
12
|
+
export const AuditResourceType = z.enum(["node"]);
|
|
13
|
+
// One line of the change journal. `resourceId` is the node the event is about; `actorId` is who
|
|
14
|
+
// caused it. `metadata` is whatever the write site recorded — its shape belongs to `action` and is
|
|
15
|
+
// deliberately not typed here, because a schema per action would have to be kept in step with 11
|
|
16
|
+
// write sites and would go stale in silence.
|
|
17
|
+
export const AuditEvent = z.strictObject({
|
|
18
|
+
id: IntelId,
|
|
19
|
+
actorId: z.string().min(1),
|
|
20
|
+
action: z.string().min(1),
|
|
21
|
+
resourceType: AuditResourceType,
|
|
22
|
+
resourceId: IntelId,
|
|
23
|
+
metadata: z.record(z.string(), z.unknown()),
|
|
24
|
+
occurredAt: IsoDateTime,
|
|
25
|
+
});
|
|
26
|
+
// ⚠️ Opaque BY CONTRACT, not merely by encoding. The reader gets a string back and hands the same
|
|
27
|
+
// string in again; it must not take it apart, and it must not build one.
|
|
28
|
+
//
|
|
29
|
+
// The reason is that the cursor is a PAIR — `(occurredAt, id)` — and the pair is the whole point.
|
|
30
|
+
// A timestamp alone cannot separate two events written in the same millisecond, which for a batch
|
|
31
|
+
// is the normal case rather than the exception; a reader continuing on `occurredAt > X` skips the
|
|
32
|
+
// second one silently. If the cursor were two fields, a caller would eventually send only the
|
|
33
|
+
// timestamp, and the loss would look like nothing at all: no error, no log, just an event that
|
|
34
|
+
// never arrived.
|
|
35
|
+
export const AuditCursor = z.string().min(1).max(400);
|
|
36
|
+
export const AuditListRequest = z.strictObject({
|
|
37
|
+
resourceType: AuditResourceType.describe("Which kind of resource to read events about. Only `node` can be listed today; asking for anything else is refused rather than answered with an empty list."),
|
|
38
|
+
after: AuditCursor.optional().describe("Where to continue: the `nextCursor` of a previous answer, passed back unchanged. Omit it to start at the oldest event you may see. Do not build one — it is opaque on purpose."),
|
|
39
|
+
limit: z
|
|
40
|
+
.number()
|
|
41
|
+
.int()
|
|
42
|
+
.min(1)
|
|
43
|
+
.max(200)
|
|
44
|
+
.default(50)
|
|
45
|
+
.describe("How many events to return at most. The answer may be shorter."),
|
|
46
|
+
});
|
|
47
|
+
// `nextCursor` is present exactly when another page may exist, and it is the cursor of the LAST
|
|
48
|
+
// returned row — not a page number. A reader stores it and sends it back as `after`.
|
|
49
|
+
//
|
|
50
|
+
// ⚠️ `nextCursor` being present does not promise the next page is non-empty. The journal is a live
|
|
51
|
+
// table and the rows a reader may see can shrink between calls; treating "cursor present" as
|
|
52
|
+
// "more data" is a fair reading, treating an empty answer as "the feed ended" is not.
|
|
53
|
+
export const AuditListResponse = z.strictObject({
|
|
54
|
+
events: z.array(AuditEvent),
|
|
55
|
+
nextCursor: AuditCursor.nullable(),
|
|
56
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const BoardColumn: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
title: z.ZodString;
|
|
5
|
+
terminal: z.ZodDefault<z.ZodBoolean>;
|
|
6
|
+
}, z.core.$strict>;
|
|
7
|
+
export type BoardColumn = z.infer<typeof BoardColumn>;
|
|
8
|
+
export declare const BoardTask: z.ZodObject<{
|
|
9
|
+
id: z.ZodString;
|
|
10
|
+
title: z.ZodString;
|
|
11
|
+
status: z.ZodString;
|
|
12
|
+
assigneeId: z.ZodNullable<z.ZodString>;
|
|
13
|
+
labels: z.ZodArray<z.ZodString>;
|
|
14
|
+
startDate: z.ZodNullable<z.ZodISODateTime>;
|
|
15
|
+
dueDate: z.ZodNullable<z.ZodISODateTime>;
|
|
16
|
+
dependsOn: z.ZodNullable<z.ZodString>;
|
|
17
|
+
position: z.ZodNumber;
|
|
18
|
+
archivedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
19
|
+
}, z.core.$strict>;
|
|
20
|
+
export type BoardTask = z.infer<typeof BoardTask>;
|
|
21
|
+
export declare const BoardTaskFilter: z.ZodObject<{
|
|
22
|
+
status: z.ZodOptional<z.ZodString>;
|
|
23
|
+
assigneeId: z.ZodOptional<z.ZodString>;
|
|
24
|
+
dueBefore: z.ZodOptional<z.ZodISODateTime>;
|
|
25
|
+
dependsOn: z.ZodOptional<z.ZodString>;
|
|
26
|
+
includeArchived: z.ZodDefault<z.ZodBoolean>;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
export type BoardTaskFilter = z.infer<typeof BoardTaskFilter>;
|
|
29
|
+
export declare const BoardGetInput: z.ZodObject<{
|
|
30
|
+
status: z.ZodOptional<z.ZodString>;
|
|
31
|
+
assigneeId: z.ZodOptional<z.ZodString>;
|
|
32
|
+
dueBefore: z.ZodOptional<z.ZodISODateTime>;
|
|
33
|
+
dependsOn: z.ZodOptional<z.ZodString>;
|
|
34
|
+
includeArchived: z.ZodDefault<z.ZodBoolean>;
|
|
35
|
+
boardId: z.ZodString;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
export type BoardGetInput = z.infer<typeof BoardGetInput>;
|
|
38
|
+
export declare const BoardView: z.ZodObject<{
|
|
39
|
+
boardId: z.ZodString;
|
|
40
|
+
title: z.ZodString;
|
|
41
|
+
columns: z.ZodArray<z.ZodObject<{
|
|
42
|
+
id: z.ZodString;
|
|
43
|
+
title: z.ZodString;
|
|
44
|
+
terminal: z.ZodDefault<z.ZodBoolean>;
|
|
45
|
+
}, z.core.$strict>>;
|
|
46
|
+
tasks: z.ZodArray<z.ZodObject<{
|
|
47
|
+
id: z.ZodString;
|
|
48
|
+
title: z.ZodString;
|
|
49
|
+
status: z.ZodString;
|
|
50
|
+
assigneeId: z.ZodNullable<z.ZodString>;
|
|
51
|
+
labels: z.ZodArray<z.ZodString>;
|
|
52
|
+
startDate: z.ZodNullable<z.ZodISODateTime>;
|
|
53
|
+
dueDate: z.ZodNullable<z.ZodISODateTime>;
|
|
54
|
+
dependsOn: z.ZodNullable<z.ZodString>;
|
|
55
|
+
position: z.ZodNumber;
|
|
56
|
+
archivedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
57
|
+
}, z.core.$strict>>;
|
|
58
|
+
}, z.core.$strict>;
|
|
59
|
+
export type BoardView = z.infer<typeof BoardView>;
|
|
60
|
+
export declare const BoardUpdateInput: z.ZodObject<{
|
|
61
|
+
boardId: z.ZodString;
|
|
62
|
+
columns: z.ZodArray<z.ZodObject<{
|
|
63
|
+
id: z.ZodString;
|
|
64
|
+
title: z.ZodString;
|
|
65
|
+
terminal: z.ZodDefault<z.ZodBoolean>;
|
|
66
|
+
}, z.core.$strict>>;
|
|
67
|
+
idempotencyKey: z.ZodString;
|
|
68
|
+
}, z.core.$strict>;
|
|
69
|
+
export type BoardUpdateInput = z.infer<typeof BoardUpdateInput>;
|
|
70
|
+
export declare const BoardTaskCreateInput: z.ZodObject<{
|
|
71
|
+
boardId: z.ZodString;
|
|
72
|
+
title: z.ZodString;
|
|
73
|
+
status: z.ZodOptional<z.ZodString>;
|
|
74
|
+
assigneeId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
75
|
+
labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
76
|
+
startDate: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
77
|
+
dueDate: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
78
|
+
dependsOn: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
79
|
+
idempotencyKey: z.ZodString;
|
|
80
|
+
}, z.core.$strict>;
|
|
81
|
+
export type BoardTaskCreateInput = z.infer<typeof BoardTaskCreateInput>;
|
|
82
|
+
export declare const BoardTaskUpdateInput: z.ZodObject<{
|
|
83
|
+
taskId: z.ZodString;
|
|
84
|
+
title: z.ZodOptional<z.ZodString>;
|
|
85
|
+
status: z.ZodOptional<z.ZodString>;
|
|
86
|
+
position: z.ZodOptional<z.ZodNumber>;
|
|
87
|
+
assigneeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
88
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
89
|
+
startDate: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
|
|
90
|
+
dueDate: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
|
|
91
|
+
dependsOn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
92
|
+
idempotencyKey: z.ZodString;
|
|
93
|
+
}, z.core.$strict>;
|
|
94
|
+
export type BoardTaskUpdateInput = z.infer<typeof BoardTaskUpdateInput>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { IdempotencyKey, IntelId, IsoDateTime } from "./contract.js";
|
|
3
|
+
// One column of a board. `terminal` is what "done" means here — a rule about the column rather than
|
|
4
|
+
// a magic status name, so an installation may call it "Shipped" or "Abgerechnet" without anything
|
|
5
|
+
// downstream having to know the word.
|
|
6
|
+
export const BoardColumn = z.strictObject({
|
|
7
|
+
id: z.string().min(1).max(60).describe("Stable key stored on every task in this column."),
|
|
8
|
+
title: z.string().min(1).max(80).describe("What the column is called on screen."),
|
|
9
|
+
terminal: z
|
|
10
|
+
.boolean()
|
|
11
|
+
.default(false)
|
|
12
|
+
.describe("Whether a task in this column counts as finished. More than one column may be."),
|
|
13
|
+
});
|
|
14
|
+
// One card, as the board view needs it: everything to draw and sort by, and NOTHING from R2. The
|
|
15
|
+
// body is fetched per task through `node_version_get` when somebody opens one.
|
|
16
|
+
//
|
|
17
|
+
// ⚠️ `position` is a float, not an index. Dropping a card between two neighbours is then the
|
|
18
|
+
// midpoint of the two, and no other row is written. With integers every drop would renumber
|
|
19
|
+
// everything below it, and two people dropping at once would fight over rows neither touched.
|
|
20
|
+
export const BoardTask = z.strictObject({
|
|
21
|
+
id: IntelId.describe("The card's node id — its address everywhere else in Intel."),
|
|
22
|
+
title: z.string().min(1).max(240).describe("What the card says."),
|
|
23
|
+
status: z.string().min(1).max(60).describe("Which column it sits in."),
|
|
24
|
+
assigneeId: z.string().min(1).nullable(),
|
|
25
|
+
labels: z.array(z.string().min(1).max(40)),
|
|
26
|
+
startDate: IsoDateTime.nullable(),
|
|
27
|
+
dueDate: IsoDateTime.nullable(),
|
|
28
|
+
dependsOn: IntelId.nullable(),
|
|
29
|
+
position: z.number(),
|
|
30
|
+
archivedAt: IsoDateTime.nullable(),
|
|
31
|
+
});
|
|
32
|
+
// ⚠️ Every filter here is a COLUMN in `board_tasks`, and that is the whole reason the fields are not
|
|
33
|
+
// in the body. A filter the application applies after reading has already fetched the rows — over
|
|
34
|
+
// the wire, into memory, past the point where leaving them out would have helped.
|
|
35
|
+
export const BoardTaskFilter = z.strictObject({
|
|
36
|
+
status: z
|
|
37
|
+
.string()
|
|
38
|
+
.min(1)
|
|
39
|
+
.max(60)
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Only tasks in this column. Omit for every column."),
|
|
42
|
+
assigneeId: z
|
|
43
|
+
.string()
|
|
44
|
+
.min(1)
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Only tasks assigned to this Gate principal. An agent is not a special case here."),
|
|
47
|
+
dueBefore: IsoDateTime.optional().describe("Only tasks due strictly before this moment. Tasks without a due date never match."),
|
|
48
|
+
dependsOn: IntelId.optional().describe("Only tasks waiting for this node — what `board_get` answers when you ask what one thing blocks."),
|
|
49
|
+
includeArchived: z
|
|
50
|
+
.boolean()
|
|
51
|
+
.default(false)
|
|
52
|
+
.describe("Include archived tasks beside the live ones instead of hiding them."),
|
|
53
|
+
});
|
|
54
|
+
export const BoardGetInput = BoardTaskFilter.extend({
|
|
55
|
+
boardId: IntelId.describe("The board node to read. Must be a node of kind `board`."),
|
|
56
|
+
});
|
|
57
|
+
// One answer for the whole board, not one per card.
|
|
58
|
+
export const BoardView = z.strictObject({
|
|
59
|
+
boardId: IntelId,
|
|
60
|
+
title: z.string().min(1).max(240),
|
|
61
|
+
columns: z.array(BoardColumn),
|
|
62
|
+
tasks: z.array(BoardTask),
|
|
63
|
+
});
|
|
64
|
+
export const BoardUpdateInput = z.strictObject({
|
|
65
|
+
boardId: IntelId.describe("The board node whose columns are being set."),
|
|
66
|
+
columns: z
|
|
67
|
+
.array(BoardColumn)
|
|
68
|
+
.min(1)
|
|
69
|
+
.describe("The complete new column list, in order. Columns are replaced, not merged."),
|
|
70
|
+
idempotencyKey: IdempotencyKey,
|
|
71
|
+
});
|
|
72
|
+
export const BoardTaskCreateInput = z.strictObject({
|
|
73
|
+
boardId: IntelId.describe("The board the task is filed under. It becomes the task's parent."),
|
|
74
|
+
title: z.string().min(1).max(240).describe("What the card says on the board."),
|
|
75
|
+
// ⚠️ Optional, and absent means the FIRST column rather than an error. A caller who does not care
|
|
76
|
+
// where a task starts should not have to read the board first — and a task with no status would
|
|
77
|
+
// be a card no view can draw.
|
|
78
|
+
status: z
|
|
79
|
+
.string()
|
|
80
|
+
.min(1)
|
|
81
|
+
.max(60)
|
|
82
|
+
.optional()
|
|
83
|
+
.describe("Which column to file it in. Omit for the board's first column."),
|
|
84
|
+
assigneeId: z
|
|
85
|
+
.string()
|
|
86
|
+
.min(1)
|
|
87
|
+
.nullable()
|
|
88
|
+
.default(null)
|
|
89
|
+
.describe("Who it is for, as a Gate principal id. An agent is not a special case."),
|
|
90
|
+
labels: z
|
|
91
|
+
.array(z.string().min(1).max(40))
|
|
92
|
+
.default([])
|
|
93
|
+
.describe("Free-form tags. They are filtered on the board, not in search."),
|
|
94
|
+
startDate: IsoDateTime.nullable()
|
|
95
|
+
.default(null)
|
|
96
|
+
.describe("When work on it should begin. Only the timeline view draws it."),
|
|
97
|
+
dueDate: IsoDateTime.nullable()
|
|
98
|
+
.default(null)
|
|
99
|
+
.describe("When it is due. A card without one never matches a due-before filter."),
|
|
100
|
+
dependsOn: IntelId.nullable()
|
|
101
|
+
.default(null)
|
|
102
|
+
.describe("A node this task waits for. Any node, not only another task."),
|
|
103
|
+
idempotencyKey: IdempotencyKey,
|
|
104
|
+
});
|
|
105
|
+
// ⚠️ Moving a card IS this call: `status` and `position` together. There is deliberately no
|
|
106
|
+
// `board_task_move` — it would be a second way to write one row, and a model reading `tools/list`
|
|
107
|
+
// would have to guess which of the two applies.
|
|
108
|
+
//
|
|
109
|
+
// Every field is optional and absent means "leave it": a drag sends two fields, a rename sends one.
|
|
110
|
+
// `null` is a value where the column is nullable, so clearing a due date is `dueDate: null` and not
|
|
111
|
+
// its absence.
|
|
112
|
+
export const BoardTaskUpdateInput = z.strictObject({
|
|
113
|
+
taskId: IntelId.describe("The card to change, by its node id."),
|
|
114
|
+
title: z
|
|
115
|
+
.string()
|
|
116
|
+
.min(1)
|
|
117
|
+
.max(240)
|
|
118
|
+
.optional()
|
|
119
|
+
.describe("Refused on purpose: a card's title lives on the node. Rename it with node_update."),
|
|
120
|
+
status: z.string().min(1).max(60).optional().describe("The column to move it to."),
|
|
121
|
+
position: z
|
|
122
|
+
.number()
|
|
123
|
+
.optional()
|
|
124
|
+
.describe("Where in the column. Use the midpoint between the two neighbours it lands between."),
|
|
125
|
+
assigneeId: z
|
|
126
|
+
.string()
|
|
127
|
+
.min(1)
|
|
128
|
+
.nullable()
|
|
129
|
+
.optional()
|
|
130
|
+
.describe("Who it is for. `null` unassigns it; leaving it out keeps whoever has it."),
|
|
131
|
+
labels: z
|
|
132
|
+
.array(z.string().min(1).max(40))
|
|
133
|
+
.optional()
|
|
134
|
+
.describe("The complete new tag list. Tags are replaced, not merged."),
|
|
135
|
+
startDate: IsoDateTime.nullable()
|
|
136
|
+
.optional()
|
|
137
|
+
.describe("When work should begin. `null` clears it."),
|
|
138
|
+
dueDate: IsoDateTime.nullable().optional().describe("When it is due. `null` clears it."),
|
|
139
|
+
dependsOn: IntelId.nullable()
|
|
140
|
+
.optional()
|
|
141
|
+
.describe("A node this card waits for. `null` clears the dependency."),
|
|
142
|
+
idempotencyKey: IdempotencyKey,
|
|
143
|
+
});
|
|
@@ -57,11 +57,30 @@ export declare const BundleManifestEntry: z.ZodObject<{
|
|
|
57
57
|
}>>;
|
|
58
58
|
}, z.core.$strict>;
|
|
59
59
|
export type BundleManifestEntry = z.infer<typeof BundleManifestEntry>;
|
|
60
|
+
/**
|
|
61
|
+
* What an export leaves out on purpose, named so a bundle says it rather than a reader guessing:
|
|
62
|
+
* version history, grants/shares, flow runs, and archived nodes are not in any bundle (#136).
|
|
63
|
+
*
|
|
64
|
+
* ⚠️ `unpublished-flow-changes` is the FIFTH, and it is the one exception to ADR-0006's own
|
|
65
|
+
* headline (#585). A bundle carries the current state of everything — except a flow that has been
|
|
66
|
+
* published, which travels as its PUBLISHED graph. Edits made after that publication are in no
|
|
67
|
+
* bundle, and they are not history: they are the newest state there is. The word exists because the
|
|
68
|
+
* loss is only acceptable while it is named, and `version-history` does not name it — a reader who
|
|
69
|
+
* saw only that word would expect the newest graph and get one that is deliberately older.
|
|
70
|
+
*
|
|
71
|
+
* ⚠️ These are WIRE values: an older reader refuses a bundle naming an exclusion it does not know,
|
|
72
|
+
* the same way it would refuse an unknown `kind`. The enum grows only for something an installation
|
|
73
|
+
* genuinely leaves behind, never as a place to note a nicety (ADR-0006, #433). Growing it costs the
|
|
74
|
+
* direction nobody migrates in — a bundle written HERE is refused by an installation older than
|
|
75
|
+
* this line, while every bundle written before it still parses, which is the direction 0.22.0's
|
|
76
|
+
* rebuild actually runs.
|
|
77
|
+
*/
|
|
60
78
|
export declare const BundleExclusion: z.ZodEnum<{
|
|
61
79
|
"version-history": "version-history";
|
|
62
80
|
grants: "grants";
|
|
63
81
|
"flow-runs": "flow-runs";
|
|
64
82
|
"archived-nodes": "archived-nodes";
|
|
83
|
+
"unpublished-flow-changes": "unpublished-flow-changes";
|
|
65
84
|
}>;
|
|
66
85
|
export type BundleExclusion = z.infer<typeof BundleExclusion>;
|
|
67
86
|
export declare const BundleManifest: z.ZodObject<{
|
|
@@ -92,13 +111,37 @@ export declare const BundleManifest: z.ZodObject<{
|
|
|
92
111
|
grants: "grants";
|
|
93
112
|
"flow-runs": "flow-runs";
|
|
94
113
|
"archived-nodes": "archived-nodes";
|
|
114
|
+
"unpublished-flow-changes": "unpublished-flow-changes";
|
|
95
115
|
}>>;
|
|
96
116
|
}, z.core.$strict>;
|
|
97
117
|
export type BundleManifest = z.infer<typeof BundleManifest>;
|
|
118
|
+
/**
|
|
119
|
+
* What one import made. Import always creates new nodes — no merge, no overwrite, no restored IDs
|
|
120
|
+
* (#137, phase 1) — so the answer is counts and the new roots, never a diff. `replayed` marks the
|
|
121
|
+
* idempotent second answer to the same key: nothing was created twice.
|
|
122
|
+
*
|
|
123
|
+
* ⚠️ `excluded` is what the IMPORT knows about itself, never what the bundle claimed (ADR-0006,
|
|
124
|
+
* #433). A subtree moved between installations arrives with one version per node, no grants and no
|
|
125
|
+
* runs, and until now nothing said so at the moment somebody could still act on it — the word stood
|
|
126
|
+
* only in a `manifest.json` inside the zip that had already been written.
|
|
127
|
+
*
|
|
128
|
+
* It is deliberately NOT read back out of that manifest. A hand-written bundle saying `excluded: []`
|
|
129
|
+
* would then make the import report that nothing was left behind, and the import would launder
|
|
130
|
+
* somebody else's claim into an answer that sounds like its own — the trap `absence` is bound
|
|
131
|
+
* against in `BundleManifestEntry` above (#534, #560). The five exclusions hold for every import
|
|
132
|
+
* this build performs, with a manifest or from a naked folder, so this is a constant of the code.
|
|
133
|
+
*/
|
|
98
134
|
export declare const BundleImportResult: z.ZodObject<{
|
|
99
135
|
nodes: z.ZodNumber;
|
|
100
136
|
flows: z.ZodNumber;
|
|
101
137
|
rootNodeIds: z.ZodArray<z.ZodString>;
|
|
102
138
|
replayed: z.ZodBoolean;
|
|
139
|
+
excluded: z.ZodArray<z.ZodEnum<{
|
|
140
|
+
"version-history": "version-history";
|
|
141
|
+
grants: "grants";
|
|
142
|
+
"flow-runs": "flow-runs";
|
|
143
|
+
"archived-nodes": "archived-nodes";
|
|
144
|
+
"unpublished-flow-changes": "unpublished-flow-changes";
|
|
145
|
+
}>>;
|
|
103
146
|
}, z.core.$strict>;
|
|
104
147
|
export type BundleImportResult = z.infer<typeof BundleImportResult>;
|
package/dist/contract/bundle.js
CHANGED
|
@@ -79,9 +79,31 @@ export const BundleManifestEntry = z
|
|
|
79
79
|
message: "Only a table or attachment entry may declare an absence",
|
|
80
80
|
path: ["absence"],
|
|
81
81
|
});
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
/**
|
|
83
|
+
* What an export leaves out on purpose, named so a bundle says it rather than a reader guessing:
|
|
84
|
+
* version history, grants/shares, flow runs, and archived nodes are not in any bundle (#136).
|
|
85
|
+
*
|
|
86
|
+
* ⚠️ `unpublished-flow-changes` is the FIFTH, and it is the one exception to ADR-0006's own
|
|
87
|
+
* headline (#585). A bundle carries the current state of everything — except a flow that has been
|
|
88
|
+
* published, which travels as its PUBLISHED graph. Edits made after that publication are in no
|
|
89
|
+
* bundle, and they are not history: they are the newest state there is. The word exists because the
|
|
90
|
+
* loss is only acceptable while it is named, and `version-history` does not name it — a reader who
|
|
91
|
+
* saw only that word would expect the newest graph and get one that is deliberately older.
|
|
92
|
+
*
|
|
93
|
+
* ⚠️ These are WIRE values: an older reader refuses a bundle naming an exclusion it does not know,
|
|
94
|
+
* the same way it would refuse an unknown `kind`. The enum grows only for something an installation
|
|
95
|
+
* genuinely leaves behind, never as a place to note a nicety (ADR-0006, #433). Growing it costs the
|
|
96
|
+
* direction nobody migrates in — a bundle written HERE is refused by an installation older than
|
|
97
|
+
* this line, while every bundle written before it still parses, which is the direction 0.22.0's
|
|
98
|
+
* rebuild actually runs.
|
|
99
|
+
*/
|
|
100
|
+
export const BundleExclusion = z.enum([
|
|
101
|
+
"version-history",
|
|
102
|
+
"grants",
|
|
103
|
+
"flow-runs",
|
|
104
|
+
"archived-nodes",
|
|
105
|
+
"unpublished-flow-changes",
|
|
106
|
+
]);
|
|
85
107
|
export const BundleManifest = z.strictObject({
|
|
86
108
|
version: z.literal(1),
|
|
87
109
|
exportedAt: IsoDateTime,
|
|
@@ -92,12 +114,26 @@ export const BundleManifest = z.strictObject({
|
|
|
92
114
|
excluded: z.array(BundleExclusion),
|
|
93
115
|
});
|
|
94
116
|
// ── Bundle import (#137) ────────────────────────────────────────────────────────────────────────
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
/**
|
|
118
|
+
* What one import made. Import always creates new nodes — no merge, no overwrite, no restored IDs
|
|
119
|
+
* (#137, phase 1) — so the answer is counts and the new roots, never a diff. `replayed` marks the
|
|
120
|
+
* idempotent second answer to the same key: nothing was created twice.
|
|
121
|
+
*
|
|
122
|
+
* ⚠️ `excluded` is what the IMPORT knows about itself, never what the bundle claimed (ADR-0006,
|
|
123
|
+
* #433). A subtree moved between installations arrives with one version per node, no grants and no
|
|
124
|
+
* runs, and until now nothing said so at the moment somebody could still act on it — the word stood
|
|
125
|
+
* only in a `manifest.json` inside the zip that had already been written.
|
|
126
|
+
*
|
|
127
|
+
* It is deliberately NOT read back out of that manifest. A hand-written bundle saying `excluded: []`
|
|
128
|
+
* would then make the import report that nothing was left behind, and the import would launder
|
|
129
|
+
* somebody else's claim into an answer that sounds like its own — the trap `absence` is bound
|
|
130
|
+
* against in `BundleManifestEntry` above (#534, #560). The five exclusions hold for every import
|
|
131
|
+
* this build performs, with a manifest or from a naked folder, so this is a constant of the code.
|
|
132
|
+
*/
|
|
98
133
|
export const BundleImportResult = z.strictObject({
|
|
99
134
|
nodes: z.number().int().nonnegative(),
|
|
100
135
|
flows: z.number().int().nonnegative(),
|
|
101
136
|
rootNodeIds: z.array(IntelId),
|
|
102
137
|
replayed: z.boolean(),
|
|
138
|
+
excluded: z.array(BundleExclusion),
|
|
103
139
|
});
|
|
@@ -38,6 +38,38 @@ export declare const IdempotencyKey: z.ZodString;
|
|
|
38
38
|
export declare function baseVersion(rule: string): z.ZodUnion<readonly [z.ZodString, z.ZodNull]>;
|
|
39
39
|
export declare const UI_LANGUAGES: readonly ["en", "de", "es"];
|
|
40
40
|
export type UiLanguage = (typeof UI_LANGUAGES)[number];
|
|
41
|
+
/**
|
|
42
|
+
* A set of things the reader is only partly entitled to see: the ones they may see BY NAME, the
|
|
43
|
+
* rest as a NUMBER (ADR-0004 §3). Never the titles of the rest, in any field, ever — a warning or a
|
|
44
|
+
* refusal must not become a way of reading the tree.
|
|
45
|
+
*
|
|
46
|
+
* ⚠️ It lives here rather than in `share.ts` because two domains state it: a grant says what it
|
|
47
|
+
* does not reach (`UnreadableNodes`), and a refusal says who is still calling in
|
|
48
|
+
* (`ProblemDetails.callers`, #448). `contract.ts` may not import from `share.ts` — the graph
|
|
49
|
+
* between these files has to stay acyclic — and a copy would be a second place for one rule to
|
|
50
|
+
* drift, which is what `IdempotencyKey` and `baseVersion` above exist against.
|
|
51
|
+
*/
|
|
52
|
+
export declare const NamedOrCounted: z.ZodObject<{
|
|
53
|
+
titles: z.ZodArray<z.ZodString>;
|
|
54
|
+
hidden: z.ZodNumber;
|
|
55
|
+
}, z.core.$strict>;
|
|
56
|
+
export type NamedOrCounted = z.infer<typeof NamedOrCounted>;
|
|
57
|
+
/**
|
|
58
|
+
* ⚠️ `callers` is the one member here that is not about every problem, and it is deliberate (#448).
|
|
59
|
+
* RFC 9457 allows extension members for exactly this: `folder_execute_in_use` refuses to narrow a
|
|
60
|
+
* library folder while flows from outside still call into it, and the CALLERS are the only thing
|
|
61
|
+
* that makes the refusal actionable. They used to exist only inside `detail` — an English sentence
|
|
62
|
+
* built on the server — so a German or Spanish surface could do nothing but print it verbatim, and
|
|
63
|
+
* no surface could shorten it or link the titles.
|
|
64
|
+
*
|
|
65
|
+
* The split is the point: the server decides WHAT is named and what is only counted, because that
|
|
66
|
+
* is an authorization answer nobody else can give; the surface decides how the sentence READS,
|
|
67
|
+
* because that is a language answer no server can give.
|
|
68
|
+
*
|
|
69
|
+
* `detail` keeps its sentence rather than emptying out — MCP hands a model prose and has nothing to
|
|
70
|
+
* formulate with, and an empty `detail` beside a new field would be the worst of the three states.
|
|
71
|
+
* It is absent on every other problem, so a reader must not treat its presence as guaranteed.
|
|
72
|
+
*/
|
|
41
73
|
export declare const ProblemDetails: z.ZodObject<{
|
|
42
74
|
type: z.ZodString;
|
|
43
75
|
status: z.ZodNumber;
|
|
@@ -45,6 +77,10 @@ export declare const ProblemDetails: z.ZodObject<{
|
|
|
45
77
|
detail: z.ZodOptional<z.ZodString>;
|
|
46
78
|
instance: z.ZodOptional<z.ZodString>;
|
|
47
79
|
code: z.ZodOptional<z.ZodString>;
|
|
80
|
+
callers: z.ZodOptional<z.ZodObject<{
|
|
81
|
+
titles: z.ZodArray<z.ZodString>;
|
|
82
|
+
hidden: z.ZodNumber;
|
|
83
|
+
}, z.core.$strict>>;
|
|
48
84
|
}, z.core.$strict>;
|
|
49
85
|
export type ProblemDetails = z.infer<typeof ProblemDetails>;
|
|
50
86
|
export declare const SessionUser: z.ZodObject<{
|
|
@@ -57,6 +57,37 @@ export function baseVersion(rule) {
|
|
|
57
57
|
// `i18n.unit.ts` compares it against the catalogs actually built in; a language listed here without
|
|
58
58
|
// a file gives a red run there instead of a UI that starts on a catalog which does not exist.
|
|
59
59
|
export const UI_LANGUAGES = ["en", "de", "es"];
|
|
60
|
+
/**
|
|
61
|
+
* A set of things the reader is only partly entitled to see: the ones they may see BY NAME, the
|
|
62
|
+
* rest as a NUMBER (ADR-0004 §3). Never the titles of the rest, in any field, ever — a warning or a
|
|
63
|
+
* refusal must not become a way of reading the tree.
|
|
64
|
+
*
|
|
65
|
+
* ⚠️ It lives here rather than in `share.ts` because two domains state it: a grant says what it
|
|
66
|
+
* does not reach (`UnreadableNodes`), and a refusal says who is still calling in
|
|
67
|
+
* (`ProblemDetails.callers`, #448). `contract.ts` may not import from `share.ts` — the graph
|
|
68
|
+
* between these files has to stay acyclic — and a copy would be a second place for one rule to
|
|
69
|
+
* drift, which is what `IdempotencyKey` and `baseVersion` above exist against.
|
|
70
|
+
*/
|
|
71
|
+
export const NamedOrCounted = z.strictObject({
|
|
72
|
+
titles: z.array(z.string().min(1).max(240)),
|
|
73
|
+
hidden: z.number().int().nonnegative(),
|
|
74
|
+
});
|
|
75
|
+
/**
|
|
76
|
+
* ⚠️ `callers` is the one member here that is not about every problem, and it is deliberate (#448).
|
|
77
|
+
* RFC 9457 allows extension members for exactly this: `folder_execute_in_use` refuses to narrow a
|
|
78
|
+
* library folder while flows from outside still call into it, and the CALLERS are the only thing
|
|
79
|
+
* that makes the refusal actionable. They used to exist only inside `detail` — an English sentence
|
|
80
|
+
* built on the server — so a German or Spanish surface could do nothing but print it verbatim, and
|
|
81
|
+
* no surface could shorten it or link the titles.
|
|
82
|
+
*
|
|
83
|
+
* The split is the point: the server decides WHAT is named and what is only counted, because that
|
|
84
|
+
* is an authorization answer nobody else can give; the surface decides how the sentence READS,
|
|
85
|
+
* because that is a language answer no server can give.
|
|
86
|
+
*
|
|
87
|
+
* `detail` keeps its sentence rather than emptying out — MCP hands a model prose and has nothing to
|
|
88
|
+
* formulate with, and an empty `detail` beside a new field would be the worst of the three states.
|
|
89
|
+
* It is absent on every other problem, so a reader must not treat its presence as guaranteed.
|
|
90
|
+
*/
|
|
60
91
|
export const ProblemDetails = z.strictObject({
|
|
61
92
|
type: z.string(),
|
|
62
93
|
status: z.number().int().min(400).max(599),
|
|
@@ -64,6 +95,7 @@ export const ProblemDetails = z.strictObject({
|
|
|
64
95
|
detail: z.string().optional(),
|
|
65
96
|
instance: z.string().optional(),
|
|
66
97
|
code: z.string().optional(),
|
|
98
|
+
callers: NamedOrCounted.optional(),
|
|
67
99
|
});
|
|
68
100
|
// Who the caller is, as Gate resolved it from the bearer: no token, and no capability list.
|
|
69
101
|
//
|
|
@@ -223,8 +223,8 @@ export declare const CompleteFlowRunStepInput: z.ZodObject<{
|
|
|
223
223
|
}, z.core.$strict>;
|
|
224
224
|
export type CompleteFlowRunStepInput = z.infer<typeof CompleteFlowRunStepInput>;
|
|
225
225
|
export declare const FlowRunTrigger: z.ZodEnum<{
|
|
226
|
-
subflow: "subflow";
|
|
227
226
|
manual: "manual";
|
|
227
|
+
subflow: "subflow";
|
|
228
228
|
}>;
|
|
229
229
|
export type FlowRunTrigger = z.infer<typeof FlowRunTrigger>;
|
|
230
230
|
export declare const FlowRunFailure: z.ZodObject<{
|
|
@@ -246,8 +246,8 @@ export declare const FlowRunSummary: z.ZodObject<{
|
|
|
246
246
|
cancelled: "cancelled";
|
|
247
247
|
}>;
|
|
248
248
|
trigger: z.ZodEnum<{
|
|
249
|
-
subflow: "subflow";
|
|
250
249
|
manual: "manual";
|
|
250
|
+
subflow: "subflow";
|
|
251
251
|
}>;
|
|
252
252
|
startedAt: z.ZodISODateTime;
|
|
253
253
|
completedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
@@ -282,8 +282,8 @@ export declare const FlowRunList: z.ZodObject<{
|
|
|
282
282
|
cancelled: "cancelled";
|
|
283
283
|
}>;
|
|
284
284
|
trigger: z.ZodEnum<{
|
|
285
|
-
subflow: "subflow";
|
|
286
285
|
manual: "manual";
|
|
286
|
+
subflow: "subflow";
|
|
287
287
|
}>;
|
|
288
288
|
startedAt: z.ZodISODateTime;
|
|
289
289
|
completedAt: z.ZodNullable<z.ZodISODateTime>;
|
package/dist/contract/flow.d.ts
CHANGED
|
@@ -947,7 +947,9 @@ export declare const RelationNodeKind: z.ZodEnum<{
|
|
|
947
947
|
document: "document";
|
|
948
948
|
table: "table";
|
|
949
949
|
attachment: "attachment";
|
|
950
|
+
board: "board";
|
|
950
951
|
flow: "flow";
|
|
952
|
+
task: "task";
|
|
951
953
|
}>;
|
|
952
954
|
export type RelationNodeKind = z.infer<typeof RelationNodeKind>;
|
|
953
955
|
export declare const RelationNode: z.ZodObject<{
|
|
@@ -957,7 +959,9 @@ export declare const RelationNode: z.ZodObject<{
|
|
|
957
959
|
document: "document";
|
|
958
960
|
table: "table";
|
|
959
961
|
attachment: "attachment";
|
|
962
|
+
board: "board";
|
|
960
963
|
flow: "flow";
|
|
964
|
+
task: "task";
|
|
961
965
|
}>;
|
|
962
966
|
title: z.ZodString;
|
|
963
967
|
inScope: z.ZodBoolean;
|
|
@@ -1007,7 +1011,9 @@ export declare const RelationGraph: z.ZodObject<{
|
|
|
1007
1011
|
document: "document";
|
|
1008
1012
|
table: "table";
|
|
1009
1013
|
attachment: "attachment";
|
|
1014
|
+
board: "board";
|
|
1010
1015
|
flow: "flow";
|
|
1016
|
+
task: "task";
|
|
1011
1017
|
}>;
|
|
1012
1018
|
title: z.ZodString;
|
|
1013
1019
|
inScope: z.ZodBoolean;
|
package/dist/contract/flow.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { baseVersion, IdempotencyKey, IntelId, IsoDateTime, LinkConfiguration, } from "./contract.js";
|
|
3
|
+
import { NodeKind } from "./node.js";
|
|
3
4
|
import { serverOf, ToolName, ToolServerHandle } from "./tool.js";
|
|
4
5
|
export const FlowNodeId = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$/);
|
|
5
6
|
export const FlowPosition = z.strictObject({ x: z.number().finite(), y: z.number().finite() });
|
|
@@ -462,7 +463,13 @@ export const FlowPublishPreview = z.strictObject({
|
|
|
462
463
|
// What accesses what, for one level of the shared tree (#19). A folder answers it for its contents,
|
|
463
464
|
// a single flow for itself. Documents and flows are two kinds of thing that share one tree
|
|
464
465
|
// (ADR-0004 §1), so the graph carries both and says which of them it is.
|
|
465
|
-
|
|
466
|
+
//
|
|
467
|
+
// ⚠️ **DERIVED from `NodeKind`, not written out beside it** (#376). It was a hand-kept copy until
|
|
468
|
+
// D66 added two kinds, and the copy did not follow — the graph would have gone on answering about
|
|
469
|
+
// four kinds while the tree held six, and nothing would have said so. That is the same failure
|
|
470
|
+
// `check:boundaries` refuses elsewhere; here the extra member `flow` had kept it out of the
|
|
471
|
+
// checker's reach.
|
|
472
|
+
export const RelationNodeKind = z.enum([...NodeKind.options, "flow"]);
|
|
466
473
|
export const RelationNode = z.strictObject({
|
|
467
474
|
id: IntelId,
|
|
468
475
|
kind: RelationNodeKind,
|
package/dist/contract/node.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare const NodeKind: z.ZodEnum<{
|
|
|
4
4
|
document: "document";
|
|
5
5
|
table: "table";
|
|
6
6
|
attachment: "attachment";
|
|
7
|
+
board: "board";
|
|
8
|
+
task: "task";
|
|
7
9
|
}>;
|
|
8
10
|
export type NodeKind = z.infer<typeof NodeKind>;
|
|
9
11
|
export declare const Node: z.ZodObject<{
|
|
@@ -14,6 +16,8 @@ export declare const Node: z.ZodObject<{
|
|
|
14
16
|
document: "document";
|
|
15
17
|
table: "table";
|
|
16
18
|
attachment: "attachment";
|
|
19
|
+
board: "board";
|
|
20
|
+
task: "task";
|
|
17
21
|
}>;
|
|
18
22
|
title: z.ZodString;
|
|
19
23
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -67,6 +71,8 @@ export declare const CreateNodeInput: z.ZodObject<{
|
|
|
67
71
|
document: "document";
|
|
68
72
|
table: "table";
|
|
69
73
|
attachment: "attachment";
|
|
74
|
+
board: "board";
|
|
75
|
+
task: "task";
|
|
70
76
|
}>;
|
|
71
77
|
title: z.ZodString;
|
|
72
78
|
description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
@@ -133,6 +139,8 @@ export declare const NodeList: z.ZodObject<{
|
|
|
133
139
|
document: "document";
|
|
134
140
|
table: "table";
|
|
135
141
|
attachment: "attachment";
|
|
142
|
+
board: "board";
|
|
143
|
+
task: "task";
|
|
136
144
|
}>;
|
|
137
145
|
title: z.ZodString;
|
|
138
146
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -172,6 +180,8 @@ export declare const NodeDocument: z.ZodObject<{
|
|
|
172
180
|
document: "document";
|
|
173
181
|
table: "table";
|
|
174
182
|
attachment: "attachment";
|
|
183
|
+
board: "board";
|
|
184
|
+
task: "task";
|
|
175
185
|
}>;
|
|
176
186
|
title: z.ZodString;
|
|
177
187
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -208,6 +218,8 @@ export declare const NodeAttachment: z.ZodObject<{
|
|
|
208
218
|
document: "document";
|
|
209
219
|
table: "table";
|
|
210
220
|
attachment: "attachment";
|
|
221
|
+
board: "board";
|
|
222
|
+
task: "task";
|
|
211
223
|
}>;
|
|
212
224
|
title: z.ZodString;
|
|
213
225
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -244,6 +256,8 @@ export declare const NodeTable: z.ZodObject<{
|
|
|
244
256
|
document: "document";
|
|
245
257
|
table: "table";
|
|
246
258
|
attachment: "attachment";
|
|
259
|
+
board: "board";
|
|
260
|
+
task: "task";
|
|
247
261
|
}>;
|
|
248
262
|
title: z.ZodString;
|
|
249
263
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -266,8 +280,8 @@ export declare const NodeLinkRelation: z.ZodEnum<{
|
|
|
266
280
|
}>;
|
|
267
281
|
export type NodeLinkRelation = z.infer<typeof NodeLinkRelation>;
|
|
268
282
|
export declare const NodeLinkOrigin: z.ZodEnum<{
|
|
269
|
-
manual: "manual";
|
|
270
283
|
text: "text";
|
|
284
|
+
manual: "manual";
|
|
271
285
|
}>;
|
|
272
286
|
export type NodeLinkOrigin = z.infer<typeof NodeLinkOrigin>;
|
|
273
287
|
export declare const NodeLink: z.ZodObject<{
|
|
@@ -281,8 +295,8 @@ export declare const NodeLink: z.ZodObject<{
|
|
|
281
295
|
implements: "implements";
|
|
282
296
|
}>;
|
|
283
297
|
origin: z.ZodEnum<{
|
|
284
|
-
manual: "manual";
|
|
285
298
|
text: "text";
|
|
299
|
+
manual: "manual";
|
|
286
300
|
}>;
|
|
287
301
|
label: z.ZodNullable<z.ZodString>;
|
|
288
302
|
createdBy: z.ZodString;
|
|
@@ -301,8 +315,8 @@ export declare const NodeLinkList: z.ZodObject<{
|
|
|
301
315
|
implements: "implements";
|
|
302
316
|
}>;
|
|
303
317
|
origin: z.ZodEnum<{
|
|
304
|
-
manual: "manual";
|
|
305
318
|
text: "text";
|
|
319
|
+
manual: "manual";
|
|
306
320
|
}>;
|
|
307
321
|
label: z.ZodNullable<z.ZodString>;
|
|
308
322
|
createdBy: z.ZodString;
|
|
@@ -340,6 +354,8 @@ export declare const NodeGraph: z.ZodObject<{
|
|
|
340
354
|
document: "document";
|
|
341
355
|
table: "table";
|
|
342
356
|
attachment: "attachment";
|
|
357
|
+
board: "board";
|
|
358
|
+
task: "task";
|
|
343
359
|
}>;
|
|
344
360
|
title: z.ZodString;
|
|
345
361
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -360,8 +376,8 @@ export declare const NodeGraph: z.ZodObject<{
|
|
|
360
376
|
implements: "implements";
|
|
361
377
|
}>;
|
|
362
378
|
origin: z.ZodEnum<{
|
|
363
|
-
manual: "manual";
|
|
364
379
|
text: "text";
|
|
380
|
+
manual: "manual";
|
|
365
381
|
}>;
|
|
366
382
|
label: z.ZodNullable<z.ZodString>;
|
|
367
383
|
createdBy: z.ZodString;
|
|
@@ -392,8 +408,8 @@ export declare const NodeCitation: z.ZodObject<{
|
|
|
392
408
|
freshness: z.ZodISODateTime;
|
|
393
409
|
score: z.ZodNumber;
|
|
394
410
|
match: z.ZodEnum<{
|
|
395
|
-
semantic: "semantic";
|
|
396
411
|
lexical: "lexical";
|
|
412
|
+
semantic: "semantic";
|
|
397
413
|
hybrid: "hybrid";
|
|
398
414
|
}>;
|
|
399
415
|
}, z.core.$strict>;
|
|
@@ -408,8 +424,8 @@ export declare const SearchResult: z.ZodObject<{
|
|
|
408
424
|
freshness: z.ZodISODateTime;
|
|
409
425
|
score: z.ZodNumber;
|
|
410
426
|
match: z.ZodEnum<{
|
|
411
|
-
semantic: "semantic";
|
|
412
427
|
lexical: "lexical";
|
|
428
|
+
semantic: "semantic";
|
|
413
429
|
hybrid: "hybrid";
|
|
414
430
|
}>;
|
|
415
431
|
}, z.core.$strict>>;
|
package/dist/contract/node.js
CHANGED
|
@@ -4,17 +4,27 @@ import { baseVersion, IdempotencyKey, IntelId, IsoDateTime } from "./contract.js
|
|
|
4
4
|
// (those stay behind each door, where `/session` deliberately does not carry them). `agentRuntime`
|
|
5
5
|
// says whether an agent Worker is bound at all (#190): without it the UI offers no "New agent" and
|
|
6
6
|
// an agent node explains itself instead of rendering views that could only end in a 503.
|
|
7
|
-
// The fourth kind is `table` (#40)
|
|
7
|
+
// The fourth kind is `table` (#40); `board` and `task` are the fifth and sixth (**D66**, #376).
|
|
8
8
|
// Each is a kind of node, not a kind of thing: it hangs in the same folder tree, inherits the same
|
|
9
9
|
// folder grants, carries the same immutable versions and the same R2 body as a document
|
|
10
|
-
// (ADR-0004 §1
|
|
10
|
+
// (ADR-0004 §1). Only the media type and the operations below differ. `agent` is NOT among them —
|
|
11
|
+
// D65 moved agents out of Intel entirely (ADR-0007).
|
|
11
12
|
//
|
|
12
|
-
// ⚠️
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
|
|
13
|
+
// ⚠️ **The sentence that stood here said the opposite, and it was right for its day.** Until
|
|
14
|
+
// 2026-08-20 this comment read *"a board is one node carrying its tasks and not a folder that only
|
|
15
|
+
// tasks may live in (#285)"*. D66 reverses it, and the reason is not taste:
|
|
16
|
+
//
|
|
17
|
+
// * **The tree has to hide `task` on EVERY level query.** As a kind that is a condition on a
|
|
18
|
+
// column already in the statement; as a `document` plus a side-table row it would be a join on
|
|
19
|
+
// the hottest path. And with tasks hidden a board has no visible children, so the chevron falls
|
|
20
|
+
// away with no rule of its own.
|
|
21
|
+
// * **`audit_list` exists since #620.** A task that is a node makes "task assigned to Paul" an
|
|
22
|
+
// event `anchrd/signals` can pick up. Inside one board's content every change looks the same
|
|
23
|
+
// from outside — "the board changed" — and nothing can act on it.
|
|
24
|
+
//
|
|
25
|
+
// ⚠️ What did NOT change: `status`, `assignee`, the dates and the ordering live in `board_tasks`,
|
|
26
|
+
// not on the node. They are filter columns and would stand empty on every other kind.
|
|
27
|
+
export const NodeKind = z.enum(["folder", "document", "attachment", "table", "board", "task"]);
|
|
18
28
|
export const Node = z.strictObject({
|
|
19
29
|
id: IntelId,
|
|
20
30
|
parentId: IntelId.nullable(),
|
|
@@ -170,7 +180,13 @@ export const PurgeNodeInput = z.strictObject({
|
|
|
170
180
|
nodeId: IntelId.describe("Node to delete for good. It must already be archived — a living node has no path into nothing."),
|
|
171
181
|
idempotencyKey: IdempotencyKey,
|
|
172
182
|
});
|
|
173
|
-
|
|
183
|
+
// The question `PurgeNodeInput` cannot be asked afterwards: what goes with it, while it is all
|
|
184
|
+
// still there to be counted. Described since #586, because the count reached MCP that day — and a
|
|
185
|
+
// surface that may delete without being able to look first is the state `destructive.md` calls a
|
|
186
|
+
// confirmation that cannot name what disappears.
|
|
187
|
+
export const PurgeNodePreviewInput = z.strictObject({
|
|
188
|
+
nodeId: IntelId.describe("Archived node a purge would delete. Answers how many items would go with it and how many documents link to it from outside, and changes nothing. A node that is not archived is refused here for the same reason node_purge refuses it."),
|
|
189
|
+
});
|
|
174
190
|
export const PurgeNodePreview = z.strictObject({
|
|
175
191
|
inboundLinks: z.number().int().nonnegative(),
|
|
176
192
|
totalItems: z.number().int().positive(),
|
package/dist/contract/share.d.ts
CHANGED
|
@@ -24,6 +24,14 @@ export declare const ListFlowGrantsInput: z.ZodObject<{
|
|
|
24
24
|
flowId: z.ZodString;
|
|
25
25
|
}, z.core.$strict>;
|
|
26
26
|
export type ListFlowGrantsInput = z.infer<typeof ListFlowGrantsInput>;
|
|
27
|
+
export declare const ListEffectiveAccessInput: z.ZodObject<{
|
|
28
|
+
resourceId: z.ZodString;
|
|
29
|
+
}, z.core.$strict>;
|
|
30
|
+
export type ListEffectiveAccessInput = z.infer<typeof ListEffectiveAccessInput>;
|
|
31
|
+
export declare const ListFlowEffectiveAccessInput: z.ZodObject<{
|
|
32
|
+
flowId: z.ZodString;
|
|
33
|
+
}, z.core.$strict>;
|
|
34
|
+
export type ListFlowEffectiveAccessInput = z.infer<typeof ListFlowEffectiveAccessInput>;
|
|
27
35
|
export declare const ResourceGrant: z.ZodObject<{
|
|
28
36
|
id: z.ZodString;
|
|
29
37
|
resourceId: z.ZodString;
|
package/dist/contract/share.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { IdempotencyKey, IntelId, IsoDateTime } from "./contract.js";
|
|
2
|
+
import { IdempotencyKey, IntelId, IsoDateTime, NamedOrCounted } from "./contract.js";
|
|
3
3
|
// ⚠️ There is no `ContextPolicy`, and it is not coming back in this shape (#76). It said whether a
|
|
4
4
|
// document should be pinned into a context, be found by relevance, or be named explicitly — an
|
|
5
5
|
// instruction to a retrieval Intel does not perform. Intel hands out references and the agent
|
|
@@ -23,6 +23,21 @@ export const ListGrantsInput = z.strictObject({
|
|
|
23
23
|
export const ListFlowGrantsInput = z.strictObject({
|
|
24
24
|
flowId: IntelId.describe("Flow whose direct grants to list. Access inherited from the folder it is filed in is not a grant on this flow and is not listed here."),
|
|
25
25
|
});
|
|
26
|
+
// ⚠️ A DIFFERENT question from the two above, not a fuller answer to them (#586). The `*GrantsInput`
|
|
27
|
+
// pair asks what sits ON this one resource; these two ask who REACHES it once inheritance is
|
|
28
|
+
// resolved — every grant along the folders above plus the owners, who need no grant row at all. On
|
|
29
|
+
// the everyday resource, whose access comes from the folder it is filed in, the first answer is
|
|
30
|
+
// empty and this one is not, so a caller that reaches for the wrong one is told "nobody" about
|
|
31
|
+
// something half the organization can open.
|
|
32
|
+
//
|
|
33
|
+
// Two inputs rather than one widened `resourceId`, for the reason the pair above gives: the id
|
|
34
|
+
// names a different table, and the queries behind them are two statements over two sets of tables.
|
|
35
|
+
export const ListEffectiveAccessInput = z.strictObject({
|
|
36
|
+
resourceId: IntelId.describe("Node to answer for. The answer crosses the folders above it and names owners as well as grants, so it is not the list node_grant_list gives."),
|
|
37
|
+
});
|
|
38
|
+
export const ListFlowEffectiveAccessInput = z.strictObject({
|
|
39
|
+
flowId: IntelId.describe("Flow to answer for. The answer includes what the folder it is filed in passes down and names owners as well as grants, so it is not the list flow_grant_list gives."),
|
|
40
|
+
});
|
|
26
41
|
export const ResourceGrant = z.strictObject({
|
|
27
42
|
id: IntelId,
|
|
28
43
|
resourceId: IntelId,
|
|
@@ -71,10 +86,11 @@ export const RevokeFlowGrantInput = z.strictObject({
|
|
|
71
86
|
//
|
|
72
87
|
// ⚠️ `titles` holds only the documents the sharer may see; everything else is in `hidden` as a
|
|
73
88
|
// number. A warning must not become a way of reading titles out of the tree.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
//
|
|
90
|
+
// It IS `NamedOrCounted` — one schema, under the name this domain calls it by. The shape moved to
|
|
91
|
+
// `contract.ts` when a refusal started carrying it too (#448); it is not restated here, because two
|
|
92
|
+
// declarations of one rule are two places for it to drift.
|
|
93
|
+
export const UnreadableNodes = NamedOrCounted;
|
|
78
94
|
// The grant is in the answer, so the warning cannot be mistaken for a refusal: it is written first
|
|
79
95
|
// and described afterwards. Blocking would force everyone who uses a central policy document to
|
|
80
96
|
// duplicate it, which is the opposite of what one tree is for (ADR-0004 §4).
|
package/dist/contract/table.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export declare const AppendTableRowsResult: z.ZodObject<{
|
|
|
28
28
|
document: "document";
|
|
29
29
|
table: "table";
|
|
30
30
|
attachment: "attachment";
|
|
31
|
+
board: "board";
|
|
32
|
+
task: "task";
|
|
31
33
|
}>;
|
|
32
34
|
title: z.ZodString;
|
|
33
35
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -75,6 +77,8 @@ export declare const UpdateTableRowsResult: z.ZodObject<{
|
|
|
75
77
|
document: "document";
|
|
76
78
|
table: "table";
|
|
77
79
|
attachment: "attachment";
|
|
80
|
+
board: "board";
|
|
81
|
+
task: "task";
|
|
78
82
|
}>;
|
|
79
83
|
title: z.ZodString;
|
|
80
84
|
description: z.ZodNullable<z.ZodString>;
|
|
@@ -118,6 +122,8 @@ export declare const DeleteTableRowsResult: z.ZodObject<{
|
|
|
118
122
|
document: "document";
|
|
119
123
|
table: "table";
|
|
120
124
|
attachment: "attachment";
|
|
125
|
+
board: "board";
|
|
126
|
+
task: "task";
|
|
121
127
|
}>;
|
|
122
128
|
title: z.ZodString;
|
|
123
129
|
description: z.ZodNullable<z.ZodString>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anchrd/intel-contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -16,6 +16,14 @@
|
|
|
16
16
|
"types": "./dist/contract/contract.d.ts",
|
|
17
17
|
"default": "./dist/contract/contract.js"
|
|
18
18
|
},
|
|
19
|
+
"./audit": {
|
|
20
|
+
"types": "./dist/contract/audit.d.ts",
|
|
21
|
+
"default": "./dist/contract/audit.js"
|
|
22
|
+
},
|
|
23
|
+
"./board": {
|
|
24
|
+
"types": "./dist/contract/board.d.ts",
|
|
25
|
+
"default": "./dist/contract/board.js"
|
|
26
|
+
},
|
|
19
27
|
"./bundle": {
|
|
20
28
|
"types": "./dist/contract/bundle.d.ts",
|
|
21
29
|
"default": "./dist/contract/bundle.js"
|